private static IList <CompatibilityCheckResult> VerifyCompatibility( PackageSpec project, Dictionary <RestoreTargetGraph, Dictionary <string, LibraryIncludeFlags> > includeFlagGraphs, IReadOnlyList <NuGetv3LocalRepository> localRepositories, LockFile lockFile, IEnumerable <RestoreTargetGraph> graphs, bool validateRuntimeAssets, ILogger logger) { // Scan every graph for compatibility, as long as there were no unresolved packages var checkResults = new List <CompatibilityCheckResult>(); if (graphs.All(g => !g.Unresolved.Any())) { var checker = new CompatibilityChecker(localRepositories, lockFile, validateRuntimeAssets, logger); foreach (var graph in graphs) { logger.LogVerbose(string.Format(CultureInfo.CurrentCulture, Strings.Log_CheckingCompatibility, graph.Name)); var includeFlags = IncludeFlagUtils.FlattenDependencyTypes(includeFlagGraphs, project, graph); var res = checker.Check(graph, includeFlags); checkResults.Add(res); if (res.Success) { logger.LogVerbose(string.Format(CultureInfo.CurrentCulture, Strings.Log_PackagesAndProjectsAreCompatible, graph.Name)); } else { // Get error counts on a project vs package basis var projectCount = res.Issues.Count(issue => issue.Type == CompatibilityIssueType.ProjectIncompatible); var packageCount = res.Issues.Count(issue => issue.Type != CompatibilityIssueType.ProjectIncompatible); // Log a summary with compatibility error counts if (projectCount > 0) { logger.LogError( string.Format(CultureInfo.CurrentCulture, Strings.Log_ProjectsIncompatible, graph.Name)); logger.LogDebug($"Incompatible projects: {projectCount}"); } if (packageCount > 0) { logger.LogError( string.Format(CultureInfo.CurrentCulture, Strings.Log_PackagesIncompatible, graph.Name)); logger.LogDebug($"Incompatible packages: {packageCount}"); } } } } return(checkResults); }
private static async Task <IList <CompatibilityCheckResult> > VerifyCompatibilityAsync( PackageSpec project, Dictionary <RestoreTargetGraph, Dictionary <string, LibraryIncludeFlags> > includeFlagGraphs, IReadOnlyList <NuGetv3LocalRepository> localRepositories, LockFile lockFile, IEnumerable <RestoreTargetGraph> graphs, bool validateRuntimeAssets, ILogger logger) { // Scan every graph for compatibility, as long as there were no unresolved packages var checkResults = new List <CompatibilityCheckResult>(); if (graphs.All(g => !g.Unresolved.Any())) { var checker = new CompatibilityChecker(localRepositories, lockFile, validateRuntimeAssets, logger); foreach (var graph in graphs) { // Don't do compat checks for the ridless graph of DotnetTooReference restore. Everything relevant will be caught in the graph with the rid if (!(ProjectStyle.DotnetToolReference == project.RestoreMetadata?.ProjectStyle && string.IsNullOrEmpty(graph.RuntimeIdentifier))) { await logger.LogAsync(LogLevel.Verbose, string.Format(CultureInfo.CurrentCulture, Strings.Log_CheckingCompatibility, graph.Name)); var includeFlags = IncludeFlagUtils.FlattenDependencyTypes(includeFlagGraphs, project, graph); var res = await checker.CheckAsync(graph, includeFlags, project); checkResults.Add(res); if (res.Success) { await logger.LogAsync(LogLevel.Verbose, string.Format(CultureInfo.CurrentCulture, Strings.Log_PackagesAndProjectsAreCompatible, graph.Name)); } else { // Get error counts on a project vs package basis var projectCount = res.Issues.Count(issue => issue.Type == CompatibilityIssueType.ProjectIncompatible); var packageCount = res.Issues.Count(issue => issue.Type != CompatibilityIssueType.ProjectIncompatible); // Log a summary with compatibility error counts if (projectCount > 0) { await logger.LogAsync(LogLevel.Debug, $"Incompatible projects: {projectCount}"); } if (packageCount > 0) { await logger.LogAsync(LogLevel.Debug, $"Incompatible packages: {packageCount}"); } } } else { await logger.LogAsync(LogLevel.Verbose, string.Format(CultureInfo.CurrentCulture, Strings.Log_SkippingCompatibiilityCheckOnRidlessGraphForDotnetToolReferenceProject, graph.Name)); } } } return(checkResults); }
public LockFile CreateLockFile(LockFile previousLockFile, PackageSpec project, IEnumerable <RestoreTargetGraph> targetGraphs, IReadOnlyList <NuGetv3LocalRepository> localRepositories, RemoteWalkContext context) { 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 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 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); } } } var libraries = lockFile.Libraries.ToDictionary(lib => Tuple.Create(lib.Name, lib.Version)); var librariesWithWarnings = new HashSet <LibraryIdentity>(); var rootProjectStyle = project.RestoreMetadata?.ProjectStyle ?? ProjectStyle.Unknown; // Cache package data and selection criteria across graphs. var builderCache = new LockFileBuilderCache(); // 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); 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, cache: builderCache); 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( libraries[Tuple.Create(library.Name, library.Version)], package, targetGraph, targetFrameworkOverride: nonFallbackFramework, dependencyType: includeFlags, dependencies: graphItem.Data.Dependencies, cache: builderCache); 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); } } } } 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 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); }
private MSBuildRestoreResult RestoreMSBuildFiles(PackageSpec project, IEnumerable <RestoreTargetGraph> targetGraphs, NuGetv3LocalRepository repository, RemoteWalkContext context) { // Get the project graph var projectFrameworks = project.TargetFrameworks.Select(f => f.FrameworkName).ToList(); // Non-Msbuild projects should skip targets and treat it as success if (!context.IsMsBuildBased) { return(new MSBuildRestoreResult(project.Name, project.BaseDirectory, success: true)); } // Invalid msbuild projects should write out an msbuild error target if (projectFrameworks.Count != 1 || !targetGraphs.Any()) { return(new MSBuildRestoreResult(project.Name, project.BaseDirectory, success: false)); } // Gather props and targets to write out var graph = targetGraphs .Single(g => g.Framework.Equals(projectFrameworks[0]) && string.IsNullOrEmpty(g.RuntimeIdentifier)); var pathResolver = new VersionFolderPathResolver(repository.RepositoryRoot); var flattenedFlags = IncludeFlagUtils.FlattenDependencyTypes(_includeFlagGraphs, _request.Project, graph); var targets = new List <string>(); var props = new List <string>(); foreach (var library in graph.Flattened .Distinct() .OrderBy(g => g.Data.Match.Library)) { var includeLibrary = true; LibraryIncludeFlags libraryFlags; if (flattenedFlags.TryGetValue(library.Key.Name, out libraryFlags)) { includeLibrary = libraryFlags.HasFlag(LibraryIncludeFlags.Build); } // Skip libraries that do not include build files such as transitive packages if (includeLibrary) { var packageIdentity = new PackageIdentity(library.Key.Name, library.Key.Version); IList <string> packageFiles; context.PackageFileCache.TryGetValue(packageIdentity, out packageFiles); if (packageFiles != null) { var contentItemCollection = new ContentItemCollection(); contentItemCollection.Load(packageFiles); // Find MSBuild thingies var groups = contentItemCollection.FindItemGroups(graph.Conventions.Patterns.MSBuildFiles); // Find the nearest msbuild group, this can include the root level Any group. var buildItems = NuGetFrameworkUtility.GetNearest( groups, graph.Framework, group => group.Properties[ManagedCodeConventions.PropertyNames.TargetFrameworkMoniker] as NuGetFramework); if (buildItems != null) { // We need to additionally filter to items that are named "{packageId}.targets" and "{packageId}.props" // Filter by file name here and we'll filter by extension when we add things to the lists. var items = buildItems.Items .Where(item => Path.GetFileNameWithoutExtension(item.Path) .Equals(library.Key.Name, StringComparison.OrdinalIgnoreCase)) .ToList(); targets.AddRange(items .Where(c => Path.GetExtension(c.Path).Equals(".targets", StringComparison.OrdinalIgnoreCase)) .Select(c => Path.Combine(pathResolver.GetPackageDirectory(library.Key.Name, library.Key.Version), c.Path.Replace('/', Path.DirectorySeparatorChar)))); props.AddRange(items .Where(c => Path.GetExtension(c.Path).Equals(".props", StringComparison.OrdinalIgnoreCase)) .Select(c => Path.Combine(pathResolver.GetPackageDirectory(library.Key.Name, library.Key.Version), c.Path.Replace('/', Path.DirectorySeparatorChar)))); } } } } return(new MSBuildRestoreResult(project.Name, project.BaseDirectory, repository.RepositoryRoot, props, targets)); }
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); }