private RuntimeFile CreateRuntimeFile(LockFileTargetLibrary library, LockFileItem item) { // _packageResolver will be null if _includeRuntimeFileVersions is false, hence the "?." var itemFullPath = _packageResolver?.ResolvePackageAssetPath(library, item.Path); return(CreateRuntimeFile(item.Path, itemFullPath)); }
private static void ApplyAliases(string aliases, LockFileItem item) { if (!string.IsNullOrEmpty(aliases)) { item.Properties.Add(LockFileItem.AliasesProperty, aliases); } }
public void ExportsPackageResourceAssemblies() { var enUsResource = new LockFileItem("resources/en-US/Res.dll"); enUsResource.Properties.Add("locale", "en-US"); var ruRuResource = new LockFileItem("resources/ru-RU/Res.dll"); ruRuResource.Properties.Add("locale", "ru-RU"); var description = CreateDescription( new LockFileTargetLibrary() { ResourceAssemblies = new List <LockFileItem>() { enUsResource, ruRuResource } }); var result = ExportSingle(description); result.ResourceAssemblies.Should().HaveCount(2); var asset = result.ResourceAssemblies.Should().Contain(g => g.Locale == "en-US").Subject.Asset; asset.Name.Should().Be("Res"); asset.Transform.Should().BeNull(); asset.RelativePath.Should().Be("resources/en-US/Res.dll"); asset.ResolvedPath.Should().Be(Path.Combine(PackagePath, "resources/en-US/Res.dll")); asset = result.ResourceAssemblies.Should().Contain(g => g.Locale == "ru-RU").Subject.Asset; asset.Name.Should().Be("Res"); asset.Transform.Should().BeNull(); asset.RelativePath.Should().Be("resources/ru-RU/Res.dll"); asset.ResolvedPath.Should().Be(Path.Combine(PackagePath, "resources/ru-RU/Res.dll")); }
private IReadOnlyList <RestoredCommand> GetCommands() { try { var commands = new List <RestoredCommand>(); LockFileTargetLibrary library = FindLibraryInLockFile(_lockFile.Value); ToolConfiguration configuration = _toolConfiguration.Value; LockFileItem entryPointFromLockFile = FindItemInTargetLibrary(library, configuration.ToolAssemblyEntryPoint); if (entryPointFromLockFile == null) { throw new ToolConfigurationException( string.Format( CommonLocalizableStrings.MissingToolEntryPointFile, configuration.ToolAssemblyEntryPoint, configuration.CommandName)); } // Currently only "dotnet" commands are supported commands.Add(new RestoredCommand( configuration.CommandName, "dotnet", LockFileRelativePathToFullFilePath(entryPointFromLockFile.Path, library))); return(commands); } catch (Exception ex) when(ex is UnauthorizedAccessException || ex is IOException) { throw new ToolConfigurationException( string.Format( CommonLocalizableStrings.FailedToRetrieveToolConfiguration, ex.Message), ex); } }
private string GetCommandFilePath( IEnumerable <string> packageFolders, LockFileTargetLibrary toolLibrary, LockFileItem runtimeAssembly) { var packageFoldersCount = packageFolders.Count(); var userPackageFolder = packageFoldersCount == 1 ? string.Empty : packageFolders.First(); var fallbackPackageFolders = packageFoldersCount > 1 ? packageFolders.Skip(1) : packageFolders; var packageDirectory = new FallbackPackagePathResolver(userPackageFolder, fallbackPackageFolders) .GetPackageDirectory(toolLibrary.Name, toolLibrary.Version); if (packageDirectory == null) { throw new GracefulException(string.Format( LocalizableStrings.CommandAssembliesNotFound, toolLibrary.Name)); } var filePath = Path.Combine( packageDirectory, PathUtility.GetPathWithDirectorySeparator(runtimeAssembly.Path)); return(filePath); }
private static void ApplyAliases(LibraryDependency libraryDependency, LockFileItem item) { if (!string.IsNullOrEmpty(libraryDependency?.Aliases)) { item.Properties.Add(LockFileItem.AliasesProperty, libraryDependency.Aliases); } }
/// <summary> /// Create lock file items for the best matching group. /// </summary> /// <remarks>Enumerate this once after calling.</remarks> private static IEnumerable <LockFileItem> GetLockFileItems( IReadOnlyList <SelectionCriteria> criteria, ContentItemCollection items, params PatternSet[] patterns) { // Loop through each criteria taking the first one that matches one or more items. foreach (var managedCriteria in criteria) { var group = items.FindBestItemGroup( managedCriteria, patterns); if (group != null) { foreach (var item in group.Items) { var newItem = new LockFileItem(item.Path); object locale; if (item.Properties.TryGetValue("locale", out locale)) { newItem.Properties["locale"] = (string)locale; } yield return(newItem); } // Take only the first group that has items break; } } yield break; }
/// <summary> /// Check if LockFileItem is under targetRelativePath directory. /// The path in LockFileItem is in pattern tools/TFM/RID/my/tool.dll. Tools/TFM/RID is selected by NuGet. /// And there will be only one TFM/RID combination. /// When "my/folder/of/tool/tools.dll" part under targetRelativePath "my/folder/of" or "my/folder", return true. /// </summary> internal static bool MatchesDirectoryPath(LockFileItem lockFileItem, string targetRelativePath) { string[] pathInLockFilePathInArray = SplitPathByDirectorySeparator(lockFileItem.Path); string[] targetDirectoryPathInArray = SplitPathByDirectorySeparator(targetRelativePath); return(pathInLockFilePathInArray[0] == "tools" && SubPathMatchesTargetFilePath(pathInLockFilePathInArray, targetDirectoryPathInArray)); }
/// <summary> /// Check if LockFileItem matches the targetRelativeFilePath. /// The path in LockFileItem is in pattern tools/TFM/RID/my/tool.dll. Tools/TFM/RID is selected by NuGet. /// And there will be only one TFM/RID combination. /// When "my/tools.dll" part matches exactly with the targetRelativeFilePath, return true. /// </summary> /// <param name="lockFileItem">LockFileItem from asset.json restored from temp project</param> /// <param name="targetRelativeFilePath">file path relative to tools/TFM/RID</param> internal static bool MatchesFile(LockFileItem lockFileItem, string targetRelativeFilePath) { string[] pathInLockFilePathInArray = SplitPathByDirectorySeparator(lockFileItem.Path); string[] entryPointPathInArray = SplitPathByDirectorySeparator(targetRelativeFilePath); return(entryPointPathInArray.Length >= 1 && PathInLockFileDirectoriesStartWithToolsAndFollowsTwoSubFolder( pathInLockFilePathInArray, entryPointPathInArray) && SubPathMatchesTargetFilePath(pathInLockFilePathInArray, entryPointPathInArray)); }
private ResourceAssembly CreateResourceAssembly(LockFileItem resourceAssembly) { string locale; if (!resourceAssembly.Properties.TryGetValue("locale", out locale)) { locale = null; } return(new ResourceAssembly(resourceAssembly.Path, locale)); }
private LockFileItem ReadFileItem(string property, JToken json) { var item = new LockFileItem { Path = property }; foreach (var subProperty in json.OfType <JProperty>()) { item.Properties[subProperty.Name] = subProperty.Value.Value <string>(); } return(item); }
private LockFileItem ReadFileItem(string property, JToken json) { var item = new LockFileItem { Path = PathUtility.GetPathWithDirectorySeparator(property) }; foreach (var subProperty in json.OfType <JProperty>()) { item.Properties[subProperty.Name] = subProperty.Value.Value <string>(); } return(item); }
private string GetCommandFilePath( string nugetPackagesRoot, LockFileTargetLibrary toolLibrary, LockFileItem runtimeAssembly) { var packageDirectory = new VersionFolderPathResolver(nugetPackagesRoot) .GetInstallPath(toolLibrary.Name, toolLibrary.Version); var filePath = Path.Combine( packageDirectory, PathUtility.GetPathWithDirectorySeparator(runtimeAssembly.Path)); return(filePath); }
public void Equals_WithRuntimeAssembliesAndRelatedFiles(string left, string right, bool expected) { string[] leftParts = left.Trim().Split(' '); var leftRuntimeAssembly = new LockFileItem(leftParts[0]); if (leftParts.Length > 1) { leftRuntimeAssembly.Properties.Add("related", leftParts[1]); } var leftSide = new LockFileTargetLibrary() { RuntimeAssemblies = new List <LockFileItem>() { leftRuntimeAssembly } }; string[] rightParts = right.Split(' '); var rightRuntimeAssembly = new LockFileItem(rightParts[0]); if (rightParts.Length > 1) { rightRuntimeAssembly.Properties.Add("related", rightParts[1]); } var rightSide = new LockFileTargetLibrary() { RuntimeAssemblies = new List <LockFileItem>() { rightRuntimeAssembly } }; // Act & Assert if (expected) { leftSide.Should().Be(rightSide); } else { leftSide.Should().NotBe(rightSide); } }
private string GetCommandFilePath( LockFile lockFile, LockFileTargetLibrary toolLibrary, LockFileItem runtimeAssembly) { var packageDirectory = lockFile.GetPackageDirectory(toolLibrary); if (packageDirectory == null) { throw new GracefulException(string.Format( LocalizableStrings.CommandAssembliesNotFound, toolLibrary.Name)); } var filePath = Path.Combine( packageDirectory, PathUtility.GetPathWithDirectorySeparator(runtimeAssembly.Path)); return(filePath); }
/// <summary> /// Check if LockFileItem matches the targetRelativeFilePath. /// The path in LockFileItem is in pattern tools/TFM/RID/my/tool.dll. Tools/TFM/RID is selected by NuGet. /// And there will be only one TFM/RID combination. /// When "my/tools.dll" part matches exactly with the targetRelativeFilePath, return true. /// </summary> /// <param name="lockFileItem">LockFileItem from asset.json restored from temp project</param> /// <param name="targetRelativeFilePath">file path relative to tools/TFM/RID</param> internal static bool MatchesFile(LockFileItem lockFileItem, string targetRelativeFilePath) { string[] pathInLockFilePathInArray = SplitPathByDirectorySeparator(lockFileItem.Path); string[] entryPointPathInArray = SplitPathByDirectorySeparator(targetRelativeFilePath); return(entryPointPathInArray.Length >= 1 && PathInLockFileDirectoriesStartWithToolsAndFollowsTwoSubFolder() && SubPathMatchesTargetFilePath()); bool SubPathMatchesTargetFilePath() { string[] pathAfterToolsTfmRid = pathInLockFilePathInArray.Skip(3).ToArray(); return(!pathAfterToolsTfmRid .Where((directoryOnEveryLevel, i) => directoryOnEveryLevel != entryPointPathInArray[i]) .Any()); } bool PathInLockFileDirectoriesStartWithToolsAndFollowsTwoSubFolder() { if (pathInLockFilePathInArray.Length - entryPointPathInArray.Length != 3) { return(false); } if (pathInLockFilePathInArray[0] != "tools") { return(false); } return(true); } string[] SplitPathByDirectorySeparator(string path) { return(path.Split('\\', '/')); } }
public static bool IsPlaceholderFile(this LockFileItem item) => NuGetUtils.IsPlaceholderFile(item.Path);
private static string GetAbsolutePath(this Lazy <LocalPackageSourceInfo> package, LockFileItem item) { return(Path.Combine(package.Value.Package.ExpandedPath, LockFileUtils.ToDirectorySeparator(item.Path))); }
public LockFile CreateLockFile( LockFile previousLockFile, PackageSpec project, IEnumerable <RestoreTargetGraph> targetGraphs, NuGetv3LocalRepository repository, RemoteWalkContext context, IEnumerable <ToolRestoreResult> toolRestoreResults) { var lockFile = new LockFile(); lockFile.Version = _lockFileVersion; var resolver = new VersionFolderPathResolver(repository.RepositoryRoot); var previousLibraries = previousLockFile?.Libraries.ToDictionary(l => Tuple.Create <string, NuGetVersion>(l.Name, l.Version)); // Use empty string as the key of dependencies shared by all frameworks lockFile.ProjectFileDependencyGroups.Add(new ProjectFileDependencyGroup( string.Empty, project.Dependencies .Select(group => group.LibraryRange.ToLockFileDependencyGroupString()) .OrderBy(group => group, StringComparer.Ordinal))); foreach (var frameworkInfo in project.TargetFrameworks .OrderBy(framework => framework.FrameworkName.ToString(), StringComparer.Ordinal)) { lockFile.ProjectFileDependencyGroups.Add(new ProjectFileDependencyGroup( frameworkInfo.FrameworkName.ToString(), frameworkInfo.Dependencies .Select(x => x.LibraryRange.ToLockFileDependencyGroupString()) .OrderBy(dependency => dependency, StringComparer.Ordinal))); } // Record all libraries used foreach (var item in targetGraphs.SelectMany(g => g.Flattened).Distinct() .OrderBy(x => x.Data.Match.Library)) { var library = item.Data.Match.Library; if (project.Name.Equals(library.Name, StringComparison.OrdinalIgnoreCase)) { // Do not include the project itself as a library. continue; } if (library.Type == LibraryType.Project || library.Type == LibraryType.ExternalProject) { // Project LocalMatch localMatch = (LocalMatch)item.Data.Match; var projectLib = new LockFileLibrary() { Name = library.Name, Version = library.Version, Type = LibraryType.Project, }; // Set the relative path if a path exists // For projects without project.json this will be empty if (!string.IsNullOrEmpty(localMatch.LocalLibrary.Path)) { projectLib.Path = PathUtility.GetRelativePath( project.FilePath, localMatch.LocalLibrary.Path, '/'); } // The msbuild project path if it exists object msbuildPath; if (localMatch.LocalLibrary.Items.TryGetValue(KnownLibraryProperties.MSBuildProjectPath, out msbuildPath)) { var msbuildRelativePath = PathUtility.GetRelativePath( project.FilePath, (string)msbuildPath, '/'); projectLib.MSBuildProject = msbuildRelativePath; } lockFile.Libraries.Add(projectLib); } else if (library.Type == LibraryType.Package) { // Packages var packageInfo = repository.FindPackagesById(library.Name) .FirstOrDefault(p => p.Version == library.Version); if (packageInfo == null) { continue; } var sha512 = File.ReadAllText(resolver.GetHashPath(packageInfo.Id, packageInfo.Version)); LockFileLibrary previousLibrary = null; previousLibraries?.TryGetValue(Tuple.Create(library.Name, library.Version), out previousLibrary); var lockFileLib = previousLibrary; // If we have the same library in the lock file already, use that. if (previousLibrary == null || previousLibrary.Sha512 != sha512) { var path = resolver.GetPackageDirectory(packageInfo.Id, packageInfo.Version); path = PathUtility.GetPathWithForwardSlashes(path); lockFileLib = CreateLockFileLibrary( packageInfo, sha512, path, correctedPackageName: library.Name); } else if (Path.DirectorySeparatorChar != LockFile.DirectorySeparatorChar) { // Fix slashes for content model patterns lockFileLib.Files = lockFileLib.Files .Select(p => p.Replace(Path.DirectorySeparatorChar, LockFile.DirectorySeparatorChar)) .ToList(); } lockFile.Libraries.Add(lockFileLib); var packageIdentity = new PackageIdentity(lockFileLib.Name, lockFileLib.Version); context.PackageFileCache.TryAdd(packageIdentity, lockFileLib.Files); } } var libraries = lockFile.Libraries.ToDictionary(lib => Tuple.Create(lib.Name, lib.Version)); var warnForImports = project.TargetFrameworks.Any(framework => framework.Warn); var librariesWithWarnings = new HashSet <LibraryIdentity>(); // Add the targets foreach (var targetGraph in targetGraphs .OrderBy(graph => graph.Framework.ToString(), StringComparer.Ordinal) .ThenBy(graph => graph.RuntimeIdentifier, StringComparer.Ordinal)) { var target = new LockFileTarget(); target.TargetFramework = targetGraph.Framework; target.RuntimeIdentifier = targetGraph.RuntimeIdentifier; var flattenedFlags = IncludeFlagUtils.FlattenDependencyTypes(_includeFlagGraphs, project, targetGraph); var fallbackFramework = target.TargetFramework as FallbackFramework; var warnForImportsOnGraph = warnForImports && fallbackFramework != null; foreach (var graphItem in targetGraph.Flattened.OrderBy(x => x.Key)) { var library = graphItem.Key; if (library.Type == LibraryType.Project || library.Type == LibraryType.ExternalProject) { if (project.Name.Equals(library.Name, StringComparison.OrdinalIgnoreCase)) { // Do not include the project itself as a library. continue; } var localMatch = (LocalMatch)graphItem.Data.Match; // Target framework information is optional and may not exist for csproj projects // that do not have a project.json file. string projectFramework = null; object frameworkInfoObject; if (localMatch.LocalLibrary.Items.TryGetValue( KnownLibraryProperties.TargetFrameworkInformation, out frameworkInfoObject)) { // Retrieve the resolved framework name, if this is null it means that the // project is incompatible. This is marked as Unsupported. var targetFrameworkInformation = (TargetFrameworkInformation)frameworkInfoObject; projectFramework = targetFrameworkInformation.FrameworkName?.DotNetFrameworkName ?? NuGetFramework.UnsupportedFramework.DotNetFrameworkName; } // Create the target entry var lib = new LockFileTargetLibrary() { Name = library.Name, Version = library.Version, Type = LibraryType.Project, Framework = projectFramework, // Find all dependencies which would be in the nuspec // Include dependencies with no constraints, or package/project/external // Exclude suppressed dependencies, the top level project is not written // as a target so the node depth does not matter. Dependencies = graphItem.Data.Dependencies .Where( d => (d.LibraryRange.TypeConstraintAllowsAnyOf( LibraryDependencyTarget.PackageProjectExternal)) && d.SuppressParent != LibraryIncludeFlags.All) .Select(d => GetDependencyVersionRange(d)) .ToList() }; object compileAssetObject; if (localMatch.LocalLibrary.Items.TryGetValue( KnownLibraryProperties.CompileAsset, out compileAssetObject)) { var item = new LockFileItem((string)compileAssetObject); lib.CompileTimeAssemblies.Add(item); lib.RuntimeAssemblies.Add(item); } // Add frameworkAssemblies for projects object frameworkAssembliesObject; if (localMatch.LocalLibrary.Items.TryGetValue( KnownLibraryProperties.FrameworkAssemblies, out frameworkAssembliesObject)) { lib.FrameworkAssemblies.AddRange((List <string>)frameworkAssembliesObject); } target.Libraries.Add(lib); continue; } else if (library.Type == LibraryType.Package) { var packageInfo = repository.FindPackagesById(library.Name) .FirstOrDefault(p => p.Version == library.Version); if (packageInfo == null) { continue; } // include flags LibraryIncludeFlags includeFlags; if (!flattenedFlags.TryGetValue(library.Name, out includeFlags)) { includeFlags = ~LibraryIncludeFlags.ContentFiles; } var targetLibrary = LockFileUtils.CreateLockFileTargetLibrary( libraries[Tuple.Create(library.Name, library.Version)], packageInfo, targetGraph, resolver, correctedPackageName: library.Name, dependencyType: includeFlags, targetFrameworkOverride: null, dependencies: graphItem.Data.Dependencies); target.Libraries.Add(targetLibrary); // Log warnings if the target library used the fallback framework if (warnForImportsOnGraph && !librariesWithWarnings.Contains(library)) { var nonFallbackFramework = new NuGetFramework(fallbackFramework); var targetLibraryWithoutFallback = LockFileUtils.CreateLockFileTargetLibrary( libraries[Tuple.Create(library.Name, library.Version)], packageInfo, targetGraph, resolver, correctedPackageName: library.Name, targetFrameworkOverride: nonFallbackFramework, dependencyType: includeFlags, dependencies: graphItem.Data.Dependencies); if (!targetLibrary.Equals(targetLibraryWithoutFallback)) { var libraryName = $"{library.Name} {library.Version}"; _logger.LogWarning(string.Format(CultureInfo.CurrentCulture, Strings.Log_ImportsFallbackWarning, libraryName, String.Join(", ", fallbackFramework.Fallback), nonFallbackFramework)); // only log the warning once per library librariesWithWarnings.Add(library); } } } } lockFile.Targets.Add(target); } PopulateProjectFileToolGroups(project, lockFile); PopulateTools(toolRestoreResults, lockFile); return(lockFile); }
private void AssertLockFileItemPath(string path, LockFileItem item) { Assert.NotNull(item); Assert.Equal(path, PathUtility.GetPathWithForwardSlashes(item.Path)); }
private ToolConfigurationAndExecutablePath ObtainAndReturnExecutablePathInStageFolder( string packageId, DirectoryPath stageDirectory, string packageVersion = null, FilePath?nugetconfig = null, string targetframework = null, string source = null, string verbosity = null) { if (packageId == null) { throw new ArgumentNullException(nameof(packageId)); } if (nugetconfig != null) { if (!File.Exists(nugetconfig.Value.Value)) { throw new PackageObtainException( string.Format(CommonLocalizableStrings.NuGetConfigurationFileDoesNotExist, Path.GetFullPath(nugetconfig.Value.Value))); } } if (targetframework == null) { targetframework = _bundledTargetFrameworkMoniker.Value; } var packageVersionOrPlaceHolder = new PackageVersion(packageVersion); DirectoryPath nugetSandboxDirectory = CreateNugetSandboxDirectory(packageVersionOrPlaceHolder, stageDirectory); FilePath tempProjectPath = CreateTempProject( packageId, packageVersionOrPlaceHolder, targetframework, nugetSandboxDirectory); _projectRestorer.Restore(tempProjectPath, nugetSandboxDirectory, nugetconfig, source, verbosity); if (packageVersionOrPlaceHolder.IsPlaceholder) { var concreteVersion = new DirectoryInfo( Directory.GetDirectories( nugetSandboxDirectory.WithSubDirectories(packageId).Value).Single()).Name; DirectoryPath versioned = nugetSandboxDirectory.GetParentPath().WithSubDirectories(concreteVersion); MoveToVersionedDirectory(versioned, nugetSandboxDirectory); nugetSandboxDirectory = versioned; packageVersion = concreteVersion; } LockFile lockFile = new LockFileFormat() .ReadWithLock(nugetSandboxDirectory.WithFile("project.assets.json").Value) .Result; LockFileItem dotnetToolSettings = FindAssetInLockFile(lockFile, "DotnetToolSettings.xml", packageId); if (dotnetToolSettings == null) { throw new PackageObtainException( string.Format(CommonLocalizableStrings.ToolPackageMissingSettingsFile, packageId)); } FilePath toolConfigurationPath = nugetSandboxDirectory .WithSubDirectories(packageId, packageVersion) .WithFile(dotnetToolSettings.Path); ToolConfiguration toolConfiguration = ToolConfigurationDeserializer.Deserialize(toolConfigurationPath.Value); var entryPointFromLockFile = FindAssetInLockFile(lockFile, toolConfiguration.ToolAssemblyEntryPoint, packageId); if (entryPointFromLockFile == null) { throw new PackageObtainException(string.Format(CommonLocalizableStrings.ToolPackageMissingEntryPointFile, packageId, toolConfiguration.ToolAssemblyEntryPoint)); } return(new ToolConfigurationAndExecutablePath( toolConfiguration, _toolsPath.WithSubDirectories( packageId, packageVersion, packageId, packageVersion) .WithFile(entryPointFromLockFile.Path))); }
private JProperty WriteFileItem(LockFileItem item) { return(new JProperty( item.Path, new JObject(item.Properties.Select(x => new JProperty(x.Key, x.Value))))); }