/// <summary> /// Create a library for a project. /// </summary> public static LockFileTargetLibrary CreateLockFileTargetProject( GraphItem <RemoteResolveResult> graphItem, LibraryIdentity library, LibraryIncludeFlags dependencyType, RestoreTargetGraph targetGraph, ProjectStyle rootProjectStyle) { 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 projectLib = 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() }; if (rootProjectStyle == ProjectStyle.PackageReference) { // Add files under asset groups object filesObject; object msbuildPath; if (localMatch.LocalLibrary.Items.TryGetValue(KnownLibraryProperties.MSBuildProjectPath, out msbuildPath)) { var files = new List <ProjectRestoreMetadataFile>(); var fileLookup = new Dictionary <string, ProjectRestoreMetadataFile>(StringComparer.OrdinalIgnoreCase); // Find the project path, this is provided by the resolver var msbuildFilePathInfo = new FileInfo((string)msbuildPath); // Ensure a trailing slash for the relative path helper. var projectDir = PathUtility.EnsureTrailingSlash(msbuildFilePathInfo.Directory.FullName); // Read files from the project if they were provided. if (localMatch.LocalLibrary.Items.TryGetValue(KnownLibraryProperties.ProjectRestoreMetadataFiles, out filesObject)) { files.AddRange((List <ProjectRestoreMetadataFile>)filesObject); } var targetFrameworkShortName = targetGraph.Framework.GetShortFolderName(); var libAnyPath = $"lib/{targetFrameworkShortName}/any.dll"; if (files.Count == 0) { // If the project did not provide a list of assets, add in default ones. // These are used to detect transitive vs non-transitive project references. var absolutePath = Path.Combine(projectDir, "bin", "placeholder", $"{localMatch.Library.Name}.dll"); files.Add(new ProjectRestoreMetadataFile(libAnyPath, absolutePath)); } // Process and de-dupe files for (var i = 0; i < files.Count; i++) { var path = files[i].PackagePath; // LIBANY avoid compatibility checks and will always be used. if (LIBANY.Equals(path, StringComparison.Ordinal)) { path = libAnyPath; } if (!fileLookup.ContainsKey(path)) { fileLookup.Add(path, files[i]); } } var contentItems = new ContentItemCollection(); contentItems.Load(fileLookup.Keys); // Create an ordered list of selection criteria. Each will be applied, if the result is empty // fallback frameworks from "imports" will be tried. // These are only used for framework/RID combinations where content model handles everything. var orderedCriteria = CreateCriteria(targetGraph, targetGraph.Framework); // Compile // ref takes precedence over lib var compileGroup = GetLockFileItems( orderedCriteria, contentItems, targetGraph.Conventions.Patterns.CompileRefAssemblies, targetGraph.Conventions.Patterns.CompileLibAssemblies); projectLib.CompileTimeAssemblies.AddRange( ConvertToProjectPaths(fileLookup, projectDir, compileGroup)); // Runtime var runtimeGroup = GetLockFileItems( orderedCriteria, contentItems, targetGraph.Conventions.Patterns.RuntimeAssemblies); projectLib.RuntimeAssemblies.AddRange( ConvertToProjectPaths(fileLookup, projectDir, runtimeGroup)); } } // Add frameworkAssemblies for projects object frameworkAssembliesObject; if (localMatch.LocalLibrary.Items.TryGetValue( KnownLibraryProperties.FrameworkAssemblies, out frameworkAssembliesObject)) { projectLib.FrameworkAssemblies.AddRange((List <string>)frameworkAssembliesObject); } // Exclude items ExcludeItems(projectLib, dependencyType); return(projectLib); }
/// <summary> /// Convert MSBuild items to a DependencyGraphSpec. /// </summary> public static DependencyGraphSpec GetDependencySpec(IEnumerable <IMSBuildItem> items) { if (items == null) { throw new ArgumentNullException(nameof(items)); } // Unique names created by the MSBuild restore target are project paths, these // can be different on case-insensitive file systems for the same project file. // To workaround this unique names should be compared based on the OS. var uniqueNameComparer = PathUtility.GetStringComparerBasedOnOS(); var graphSpec = new DependencyGraphSpec(); var itemsById = new Dictionary <string, List <IMSBuildItem> >(uniqueNameComparer); var restoreSpecs = new HashSet <string>(uniqueNameComparer); var validForRestore = new HashSet <string>(uniqueNameComparer); var projectPathLookup = new Dictionary <string, string>(uniqueNameComparer); var toolItems = new List <IMSBuildItem>(); // Sort items and add restore specs foreach (var item in items) { var projectUniqueName = item.GetProperty("ProjectUniqueName"); if (item.IsType("restorespec")) { restoreSpecs.Add(projectUniqueName); } else if (!string.IsNullOrEmpty(projectUniqueName)) { List <IMSBuildItem> idItems; if (!itemsById.TryGetValue(projectUniqueName, out idItems)) { idItems = new List <IMSBuildItem>(1); itemsById.Add(projectUniqueName, idItems); } idItems.Add(item); } } // Add projects var validProjectSpecs = itemsById.Values.Select(GetPackageSpec).Where(e => e != null); foreach (var spec in validProjectSpecs) { // Keep track of all project path casings var uniqueName = spec.RestoreMetadata.ProjectUniqueName; if (uniqueName != null && !projectPathLookup.ContainsKey(uniqueName)) { projectPathLookup.Add(uniqueName, uniqueName); } var projectPath = spec.RestoreMetadata.ProjectPath; if (projectPath != null && !projectPathLookup.ContainsKey(projectPath)) { projectPathLookup.Add(projectPath, projectPath); } if (spec.RestoreMetadata.ProjectStyle == ProjectStyle.PackageReference || spec.RestoreMetadata.ProjectStyle == ProjectStyle.ProjectJson || spec.RestoreMetadata.ProjectStyle == ProjectStyle.DotnetCliTool || spec.RestoreMetadata.ProjectStyle == ProjectStyle.Standalone || spec.RestoreMetadata.ProjectStyle == ProjectStyle.DotnetToolReference) { validForRestore.Add(spec.RestoreMetadata.ProjectUniqueName); } graphSpec.AddProject(spec); } // Fix project reference casings to match the original project on case insensitive file systems. NormalizePathCasings(projectPathLookup, graphSpec); // Remove references to projects that could not be read by restore. RemoveMissingProjects(graphSpec); // Add valid projects to restore section foreach (var projectUniqueName in restoreSpecs.Intersect(validForRestore)) { graphSpec.AddRestore(projectUniqueName); } return(graphSpec); }
public LockFile CreateLockFile(LockFile previousLockFile, PackageSpec project, IEnumerable <RestoreTargetGraph> targetGraphs, IReadOnlyList <NuGetv3LocalRepository> localRepositories, RemoteWalkContext context, LockFileBuilderCache lockFileBuilderCache) { var lockFile = new LockFile() { Version = _lockFileVersion }; var previousLibraries = previousLockFile?.Libraries.ToDictionary(l => Tuple.Create(l.Name, l.Version)); if (project.RestoreMetadata?.ProjectStyle == ProjectStyle.PackageReference || project.RestoreMetadata?.ProjectStyle == ProjectStyle.DotnetToolReference) { AddProjectFileDependenciesForPackageReference(project, lockFile, targetGraphs); } else { AddProjectFileDependenciesForSpec(project, lockFile); } // Record all libraries used var libraryItems = targetGraphs .SelectMany(g => g.Flattened) // All GraphItem<RemoteResolveResult> resolved in the graph. .Distinct(GraphItemKeyComparer <RemoteResolveResult> .Instance) // Distinct list of GraphItems. Two items are equal only if the itmes' Keys are equal. .OrderBy(x => x.Data.Match.Library); foreach (var item in libraryItems) { 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 var 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 = NuGetv3LocalRepositoryUtility.GetPackage(localRepositories, library.Name, library.Version); // Add the library if it was resolved, unresolved packages are not added to the assets file. if (packageInfo != null) { var package = packageInfo.Package; var resolver = packageInfo.Repository.PathResolver; var sha512 = package.Sha512; var path = PathUtility.GetPathWithForwardSlashes(resolver.GetPackageDirectory(package.Id, package.Version)); LockFileLibrary lockFileLib = null; LockFileLibrary previousLibrary = null; if (previousLibraries?.TryGetValue(Tuple.Create(package.Id, package.Version), out previousLibrary) == true) { // Check that the previous library is still valid if (previousLibrary != null && StringComparer.Ordinal.Equals(path, previousLibrary.Path) && StringComparer.Ordinal.Equals(sha512, previousLibrary.Sha512)) { // We mutate this previous library so we must take a clone of it. This is // important because later, when deciding whether the lock file has changed, // we compare the new lock file to the previous (in-memory) lock file. lockFileLib = previousLibrary.Clone(); } } // Create a new lock file library if one doesn't exist already. if (lockFileLib == null) { lockFileLib = CreateLockFileLibrary(package, sha512, path); } // Create a new lock file library lockFile.Libraries.Add(lockFileLib); } } } Dictionary <Tuple <string, NuGetVersion>, LockFileLibrary> libraries = EnsureUniqueLockFileLibraries(lockFile); var librariesWithWarnings = new HashSet <LibraryIdentity>(); var rootProjectStyle = project.RestoreMetadata?.ProjectStyle ?? ProjectStyle.Unknown; // 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 { TargetFramework = targetGraph.Framework, RuntimeIdentifier = targetGraph.RuntimeIdentifier }; var flattenedFlags = IncludeFlagUtils.FlattenDependencyTypes(_includeFlagGraphs, project, targetGraph); // Check if warnings should be displayed for the current framework. var tfi = project.GetTargetFramework(targetGraph.Framework); bool warnForImportsOnGraph = tfi.Warn && (target.TargetFramework is FallbackFramework || target.TargetFramework is AssetTargetFallbackFramework); foreach (var graphItem in targetGraph.Flattened.OrderBy(x => x.Key)) { var library = graphItem.Key; // include flags LibraryIncludeFlags includeFlags; if (!flattenedFlags.TryGetValue(library.Name, out includeFlags)) { includeFlags = ~LibraryIncludeFlags.ContentFiles; } 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 projectLib = LockFileUtils.CreateLockFileTargetProject( graphItem, library, includeFlags, targetGraph, rootProjectStyle); target.Libraries.Add(projectLib); } else if (library.Type == LibraryType.Package) { var packageInfo = NuGetv3LocalRepositoryUtility.GetPackage(localRepositories, library.Name, library.Version); if (packageInfo == null) { continue; } var package = packageInfo.Package; var libraryDependency = tfi.Dependencies.FirstOrDefault(e => e.Name.Equals(library.Name, StringComparison.OrdinalIgnoreCase)); var targetLibrary = LockFileUtils.CreateLockFileTargetLibrary( libraryDependency?.Aliases, libraries[Tuple.Create(library.Name, library.Version)], package, targetGraph, dependencyType: includeFlags, targetFrameworkOverride: null, dependencies: graphItem.Data.Dependencies, cache: lockFileBuilderCache); target.Libraries.Add(targetLibrary); // Log warnings if the target library used the fallback framework if (warnForImportsOnGraph && !librariesWithWarnings.Contains(library)) { var nonFallbackFramework = new NuGetFramework(target.TargetFramework); var targetLibraryWithoutFallback = LockFileUtils.CreateLockFileTargetLibrary( libraryDependency?.Aliases, libraries[Tuple.Create(library.Name, library.Version)], package, targetGraph, targetFrameworkOverride: nonFallbackFramework, dependencyType: includeFlags, dependencies: graphItem.Data.Dependencies, cache: lockFileBuilderCache); if (!targetLibrary.Equals(targetLibraryWithoutFallback)) { var libraryName = DiagnosticUtility.FormatIdentity(library); var message = string.Format(CultureInfo.CurrentCulture, Strings.Log_ImportsFallbackWarning, libraryName, GetFallbackFrameworkString(target.TargetFramework), nonFallbackFramework); var logMessage = RestoreLogMessage.CreateWarning( NuGetLogCode.NU1701, message, library.Name, targetGraph.TargetGraphName); _logger.Log(logMessage); // only log the warning once per library librariesWithWarnings.Add(library); } } } } EnsureUniqueLockFileTargetLibraries(target); lockFile.Targets.Add(target); } PopulatePackageFolders(localRepositories.Select(repo => repo.RepositoryRoot).Distinct(), lockFile); AddCentralTransitiveDependencyGroupsForPackageReference(project, lockFile, targetGraphs); // Add the original package spec to the lock file. lockFile.PackageSpec = project; return(lockFile); }
public static void Log(ILogger logger, IReadOnlyList <RestoreSummary> restoreSummaries, bool logErrors = false) { if (restoreSummaries.Count == 0) { return; } var noOpCount = 0; var feedsUsed = new HashSet <string>(); var configFiles = new HashSet <string>(); var installed = new Dictionary <string, int>(restoreSummaries.Count, PathUtility.GetStringComparerBasedOnOS()); foreach (RestoreSummary restoreSummary in restoreSummaries) { if (restoreSummary.NoOpRestore) { noOpCount++; } foreach (var feed in restoreSummary.FeedsUsed) { feedsUsed.Add(feed); } foreach (var configFile in restoreSummary.ConfigFiles) { configFiles.Add(configFile); } if (!string.IsNullOrEmpty(restoreSummary.InputPath)) { if (installed.ContainsKey(restoreSummary.InputPath)) { installed[restoreSummary.InputPath] += restoreSummary.InstallCount; } else { installed[restoreSummary.InputPath] = restoreSummary.InstallCount; } } } // This should only be true by nuget exe since it does not have msbuild logger if (logErrors) { // Display the errors summary foreach (var restoreSummary in restoreSummaries) { // log errors LogErrorsToConsole( restoreSummary, string.Format(CultureInfo.CurrentCulture, Strings.Log_ErrorSummary, restoreSummary.InputPath), logger); } } // Display the information summary if (configFiles.Any()) { logger.LogInformationSummary(string.Empty); logger.LogInformationSummary(Strings.Log_ConfigFileSummary); foreach (var configFile in configFiles) { logger.LogInformationSummary($" {configFile}"); } } if (feedsUsed.Any()) { logger.LogInformationSummary(string.Empty); logger.LogInformationSummary(Strings.Log_FeedsUsedSummary); foreach (var feedUsed in feedsUsed) { logger.LogInformationSummary($" {feedUsed}"); } } if (installed.Any(i => i.Value > 0)) { logger.LogInformationSummary(string.Empty); logger.LogInformationSummary(Strings.Log_InstalledSummary); foreach (var pair in installed.Where(i => i.Value > 0)) { logger.LogInformationSummary(" " + string.Format( CultureInfo.CurrentCulture, Strings.Log_InstalledSummaryCount, pair.Value, pair.Key)); } } if (!RuntimeEnvironmentHelper.IsRunningInVisualStudio) { if (noOpCount == restoreSummaries.Count) { logger.LogMinimal(Strings.Log_AllProjectsUpToDate); } else if (noOpCount > 0) { logger.LogMinimal(string.Format(CultureInfo.CurrentCulture, Strings.Log_ProjectUpToDateSummary, noOpCount, restoreSummaries.Count)); } } }
public LockFile CreateLockFile( LockFile previousLockFile, PackageSpec project, IEnumerable <RestoreTargetGraph> targetGraphs, IReadOnlyList <NuGetv3LocalRepository> localRepositories, RemoteWalkContext context) { var lockFile = new LockFile(); lockFile.Version = _lockFileVersion; var previousLibraries = previousLockFile?.Libraries.ToDictionary(l => Tuple.Create(l.Name, l.Version)); if (project.RestoreMetadata?.ProjectStyle == ProjectStyle.PackageReference) { AddProjectFileDependenciesForNETCore(project, lockFile, targetGraphs); } else { AddProjectFileDependenciesForSpec(project, lockFile); } // 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 = NuGetv3LocalRepositoryUtility.GetPackage(localRepositories, library.Name, library.Version); if (packageInfo == null) { continue; } var package = packageInfo.Package; var resolver = packageInfo.Repository.PathResolver; LockFileLibrary previousLibrary = null; if (previousLibraries?.TryGetValue(Tuple.Create(package.Id, package.Version), out previousLibrary) == true) { // We mutate this previous library so we must take a clone of it. This is // important because later, when deciding whether the lock file has changed, // we compare the new lock file to the previous (in-memory) lock file. previousLibrary = previousLibrary.Clone(); } var sha512 = File.ReadAllText(resolver.GetHashPath(package.Id, package.Version)); var path = PathUtility.GetPathWithForwardSlashes( resolver.GetPackageDirectory(package.Id, package.Version)); var lockFileLib = previousLibrary; // If we have the same library in the lock file already, use that. if (previousLibrary == null || previousLibrary.Sha512 != sha512 || previousLibrary.Path != path) { lockFileLib = CreateLockFileLibrary( package, sha512, path); } 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>(); var rootProjectStyle = project.RestoreMetadata?.ProjectStyle ?? ProjectStyle.Unknown; // 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; // include flags LibraryIncludeFlags includeFlags; if (!flattenedFlags.TryGetValue(library.Name, out includeFlags)) { includeFlags = ~LibraryIncludeFlags.ContentFiles; } 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 projectLib = LockFileUtils.CreateLockFileTargetProject( graphItem, library, includeFlags, targetGraph, rootProjectStyle); target.Libraries.Add(projectLib); continue; } else if (library.Type == LibraryType.Package) { var packageInfo = NuGetv3LocalRepositoryUtility.GetPackage(localRepositories, library.Name, library.Version); if (packageInfo == null) { continue; } var package = packageInfo.Package; var targetLibrary = LockFileUtils.CreateLockFileTargetLibrary( libraries[Tuple.Create(library.Name, library.Version)], package, targetGraph, 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)], package, targetGraph, 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); } PopulatePackageFolders(localRepositories.Select(repo => repo.RepositoryRoot).Distinct(), lockFile); // Add the original package spec to the lock file. lockFile.PackageSpec = project; return(lockFile); }
public PackagesLockFile CreateNuGetLockFile(LockFile assetsFile) { var lockFile = new PackagesLockFile(); var libraryLookup = assetsFile.Libraries.Where(e => e.Type == LibraryType.Package) .ToDictionary(e => new PackageIdentity(e.Name, e.Version)); foreach (var target in assetsFile.Targets) { var nuGettarget = new PackagesLockFileTarget() { TargetFramework = target.TargetFramework, RuntimeIdentifier = target.RuntimeIdentifier }; var framework = assetsFile.PackageSpec.TargetFrameworks.FirstOrDefault( f => EqualityUtility.EqualsWithNullCheck(f.FrameworkName, target.TargetFramework)); var libraries = target.Libraries; // check if this is RID-based graph then only add those libraries which differ from original TFM. if (!string.IsNullOrEmpty(target.RuntimeIdentifier)) { var onlyTFM = assetsFile.Targets.First(t => EqualityUtility.EqualsWithNullCheck(t.TargetFramework, target.TargetFramework)); libraries = target.Libraries.Where(lib => !onlyTFM.Libraries.Any(tfmLib => tfmLib.Equals(lib))).ToList(); } foreach (var library in libraries.Where(e => e.Type == LibraryType.Package)) { var identity = new PackageIdentity(library.Name, library.Version); var dependency = new LockFileDependency() { Id = library.Name, ResolvedVersion = library.Version, ContentHash = libraryLookup[identity].Sha512, Dependencies = library.Dependencies }; var framework_dep = framework?.Dependencies.FirstOrDefault( dep => StringComparer.OrdinalIgnoreCase.Equals(dep.Name, library.Name)); if (framework_dep != null) { dependency.Type = PackageDependencyType.Direct; dependency.RequestedVersion = framework_dep.LibraryRange.VersionRange; } else { dependency.Type = PackageDependencyType.Transitive; } nuGettarget.Dependencies.Add(dependency); } var projectFullPaths = assetsFile.Libraries .Where(l => l.Type == LibraryType.Project || l.Type == LibraryType.ExternalProject) .ToDictionary(l => new PackageIdentity(l.Name, l.Version), l => l.MSBuildProject); foreach (var projectReference in libraries.Where(e => e.Type == LibraryType.Project || e.Type == LibraryType.ExternalProject)) { var projectIdentity = new PackageIdentity(projectReference.Name, projectReference.Version); var projectFullPath = projectFullPaths[projectIdentity]; var id = PathUtility.GetStringComparerBasedOnOS().Equals(Path.GetFileNameWithoutExtension(projectFullPath), projectReference.Name) ? projectReference.Name.ToLowerInvariant() : projectReference.Name; var dependency = new LockFileDependency() { Id = id, Dependencies = projectReference.Dependencies, Type = PackageDependencyType.Project }; nuGettarget.Dependencies.Add(dependency); } nuGettarget.Dependencies = nuGettarget.Dependencies.OrderBy(d => d.Type).ToList(); lockFile.Targets.Add(nuGettarget); } return(lockFile); }