public NuGetAssetResolver(string runtimeFile, IEnumerable<string> packageItems) { RuntimeGraph runtimeGraph = null; if (!String.IsNullOrEmpty(runtimeFile)) { runtimeGraph = JsonRuntimeFormat.ReadRuntimeGraph(runtimeFile); } _conventions = new ManagedCodeConventions(runtimeGraph); _sourceItems = new ContentItemCollection(); _sourceItems.Load(packageItems); }
private static void AddContentFiles(ManagedCodeConventions managedCodeConventions, LockFileTargetLibrary lockFileLib, NuGetFramework framework, ContentItemCollection contentItems, NuspecReader nuspec) { // content v2 items List <ContentItemGroup> contentFileGroups = new(); contentItems.PopulateItemGroups(managedCodeConventions.Patterns.ContentFiles, contentFileGroups); if (contentFileGroups.Count > 0) { // Multiple groups can match the same framework, find all of them var contentFileGroupsForFramework = ContentFileUtils.GetContentGroupsForFramework( framework, contentFileGroups); lockFileLib.ContentFiles = ContentFileUtils.GetContentFileGroup( nuspec, contentFileGroupsForFramework); } }
/// <summary> /// Populate assets for a <see cref="LockFileLibrary"/>. /// </summary> private static void AddAssets( string aliases, LockFileLibrary library, LocalPackageInfo package, ManagedCodeConventions managedCodeConventions, LibraryIncludeFlags dependencyType, LockFileTargetLibrary lockFileLib, NuGetFramework framework, string runtimeIdentifier, ContentItemCollection contentItems, NuspecReader nuspec, IReadOnlyList <SelectionCriteria> orderedCriteria) { // Add framework references for desktop projects. AddFrameworkReferences(lockFileLib, framework, nuspec); // Compile // Set-up action to update the compile time items. Action <LockFileItem> applyAliases = (item) => ApplyAliases(aliases, item); // ref takes precedence over lib var compileGroup = GetLockFileItems( orderedCriteria, contentItems, applyAliases, managedCodeConventions.Patterns.CompileRefAssemblies, managedCodeConventions.Patterns.CompileLibAssemblies); lockFileLib.CompileTimeAssemblies.AddRange(compileGroup); // Runtime var runtimeGroup = GetLockFileItems( orderedCriteria, contentItems, managedCodeConventions.Patterns.RuntimeAssemblies); lockFileLib.RuntimeAssemblies.AddRange(runtimeGroup); // Embed var embedGroup = GetLockFileItems( orderedCriteria, contentItems, managedCodeConventions.Patterns.EmbedAssemblies); lockFileLib.EmbedAssemblies.AddRange(embedGroup); // Resources var resourceGroup = GetLockFileItems( orderedCriteria, contentItems, managedCodeConventions.Patterns.ResourceAssemblies); lockFileLib.ResourceAssemblies.AddRange(resourceGroup); // Native var nativeGroup = GetLockFileItems( orderedCriteria, contentItems, managedCodeConventions.Patterns.NativeLibraries); lockFileLib.NativeLibraries.AddRange(nativeGroup); // Add MSBuild files AddMSBuildAssets(library.Name, managedCodeConventions, lockFileLib, orderedCriteria, contentItems); // Add content files AddContentFiles(managedCodeConventions, lockFileLib, framework, contentItems, nuspec); // Runtime targets // These are applied only to non-RID target graphs. // They are not used for compatibility checks. AddRuntimeTargets(managedCodeConventions, dependencyType, lockFileLib, framework, runtimeIdentifier, contentItems); // COMPAT: Support lib/contract so older packages can be consumed ApplyLibContract(package, lockFileLib, framework, contentItems); // Apply filters from the <references> node in the nuspec ApplyReferenceFilter(lockFileLib, framework, nuspec); }
public static LockFileTargetLibrary CreateLockFileTargetLibrary(LockFilePackageLibrary library, IPackage package, RestoreContext context, string correctedPackageName) { var lockFileLib = new LockFileTargetLibrary { Type = "package" }; var framework = context.FrameworkName; var runtimeIdentifier = context.RuntimeName; // package.Id is read from nuspec and it might be in wrong casing. // correctedPackageName should be the package name used by dependency graph and // it has the correct casing that runtime needs during dependency resolution. lockFileLib.Name = correctedPackageName ?? package.Id; lockFileLib.Version = package.Version; var files = library.Files.Select(p => p.Replace(Path.DirectorySeparatorChar, '/')); var contentItems = new ContentItemCollection(); contentItems.Load(files); IEnumerable <PackageDependencySet> dependencySet; if (VersionUtility.GetNearest(framework, package.DependencySets, out dependencySet)) { var set = dependencySet.FirstOrDefault()?.Dependencies?.ToList(); if (set != null) { lockFileLib.Dependencies = set; } } // TODO: Remove this when we do #596 // ASP.NET Core and .NET Core 5.0 don't have framework reference assemblies if (!VersionUtility.IsPackageBased(framework)) { IEnumerable <FrameworkAssemblyReference> frameworkAssemblies; if (VersionUtility.GetNearest(framework, package.FrameworkAssemblies, out frameworkAssemblies)) { AddFrameworkReferences(lockFileLib, framework, frameworkAssemblies); } // Add framework assemblies with empty supported frameworks AddFrameworkReferences(lockFileLib, framework, package.FrameworkAssemblies.Where(f => !f.SupportedFrameworks.Any())); } var patterns = PatternDefinitions.DotNetPatterns; var criteriaBuilderWithTfm = new SelectionCriteriaBuilder(patterns.Properties.Definitions); var criteriaBuilderWithoutTfm = new SelectionCriteriaBuilder(patterns.Properties.Definitions); if (context.RuntimeSpecs != null) { foreach (var runtimeSpec in context.RuntimeSpecs) { criteriaBuilderWithTfm = criteriaBuilderWithTfm .Add["tfm", framework]["rid", runtimeSpec.Name]; criteriaBuilderWithoutTfm = criteriaBuilderWithoutTfm .Add["rid", runtimeSpec.Name]; } } criteriaBuilderWithTfm = criteriaBuilderWithTfm .Add["tfm", framework]; var criteria = criteriaBuilderWithTfm.Criteria; var compileGroup = contentItems.FindBestItemGroup(criteria, patterns.CompileTimeAssemblies, patterns.ManagedAssemblies); if (compileGroup != null) { lockFileLib.CompileTimeAssemblies = compileGroup.Items.Select(t => (LockFileItem)t.Path).ToList(); } var runtimeGroup = contentItems.FindBestItemGroup(criteria, patterns.ManagedAssemblies); if (runtimeGroup != null) { lockFileLib.RuntimeAssemblies = runtimeGroup.Items.Select(p => (LockFileItem)p.Path).ToList(); } var resourceGroup = contentItems.FindBestItemGroup(criteria, patterns.ResourceAssemblies); if (resourceGroup != null) { lockFileLib.ResourceAssemblies = resourceGroup.Items.Select(ToResourceLockFileItem).ToList(); } var nativeGroup = contentItems.FindBestItemGroup(criteriaBuilderWithoutTfm.Criteria, patterns.NativeLibraries); if (nativeGroup != null) { lockFileLib.NativeLibraries = nativeGroup.Items.Select(p => (LockFileItem)p.Path).ToList(); } // COMPAT: Support lib/contract so older packages can be consumed string contractPath = "lib/contract/" + package.Id + ".dll"; var hasContract = files.Any(path => path == contractPath); var hasLib = lockFileLib.RuntimeAssemblies.Any(); if (hasContract && hasLib && !VersionUtility.IsDesktop(framework)) { lockFileLib.CompileTimeAssemblies.Clear(); lockFileLib.CompileTimeAssemblies.Add(contractPath); } // See if there's a list of specific references defined for this target framework IEnumerable <PackageReferenceSet> referenceSets; if (VersionUtility.GetNearest(framework, package.PackageAssemblyReferences, out referenceSets)) { // Get the first compatible reference set var referenceSet = referenceSets.FirstOrDefault(); if (referenceSet != null) { // Remove all compile-time assemblies of which names do not appear in the References list lockFileLib.CompileTimeAssemblies.RemoveAll(path => path.Path.StartsWith("lib/") && !referenceSet.References.Contains(Path.GetFileName(path), StringComparer.OrdinalIgnoreCase)); } } return(lockFileLib); }
private LockFileTargetLibrary CreateLockFileTargetLibrary(LocalPackageInfo package, RestoreTargetGraph targetGraph, DefaultPackagePathResolver defaultPackagePathResolver, string correctedPackageName) { var lockFileLib = new LockFileTargetLibrary(); var framework = targetGraph.Framework; var runtimeIdentifier = targetGraph.RuntimeIdentifier; // package.Id is read from nuspec and it might be in wrong casing. // correctedPackageName should be the package name used by dependency graph and // it has the correct casing that runtime needs during dependency resolution. lockFileLib.Name = correctedPackageName ?? package.Id; lockFileLib.Version = package.Version; IList <string> files; var contentItems = new ContentItemCollection(); HashSet <string> referenceFilter = null; using (var nupkgStream = File.OpenRead(package.ZipPath)) { var packageReader = new PackageReader(nupkgStream); files = packageReader.GetFiles().Select(p => p.Replace(Path.DirectorySeparatorChar, '/')).ToList(); contentItems.Load(files); var dependencySet = packageReader.GetPackageDependencies().GetNearest(framework); if (dependencySet != null) { var set = dependencySet.Packages; if (set != null) { lockFileLib.Dependencies = set.ToList(); } } var referenceSet = packageReader.GetReferenceItems().GetNearest(framework); if (referenceSet != null) { referenceFilter = new HashSet <string>(referenceSet.Items, StringComparer.OrdinalIgnoreCase); } // TODO: Remove this when we do #596 // ASP.NET Core isn't compatible with generic PCL profiles if (!string.Equals(framework.Framework, FrameworkConstants.FrameworkIdentifiers.AspNetCore, StringComparison.OrdinalIgnoreCase) && !string.Equals(framework.Framework, FrameworkConstants.FrameworkIdentifiers.DnxCore, StringComparison.OrdinalIgnoreCase)) { var frameworkAssemblies = packageReader.GetFrameworkItems().GetNearest(framework); if (frameworkAssemblies != null) { foreach (var assemblyReference in frameworkAssemblies.Items) { lockFileLib.FrameworkAssemblies.Add(assemblyReference); } } } } var nativeCriteria = targetGraph.Conventions.Criteria.ForRuntime(targetGraph.RuntimeIdentifier); var managedCriteria = targetGraph.Conventions.Criteria.ForFrameworkAndRuntime(framework, targetGraph.RuntimeIdentifier); var compileGroup = contentItems.FindBestItemGroup(managedCriteria, targetGraph.Conventions.Patterns.CompileAssemblies, targetGraph.Conventions.Patterns.RuntimeAssemblies); if (compileGroup != null) { lockFileLib.CompileTimeAssemblies = compileGroup.Items.Select(t => t.Path).ToList(); } var runtimeGroup = contentItems.FindBestItemGroup(managedCriteria, targetGraph.Conventions.Patterns.RuntimeAssemblies); if (runtimeGroup != null) { lockFileLib.RuntimeAssemblies = runtimeGroup.Items.Select(p => p.Path).ToList(); } var nativeGroup = contentItems.FindBestItemGroup(nativeCriteria, targetGraph.Conventions.Patterns.NativeLibraries); if (nativeGroup != null) { lockFileLib.NativeLibraries = nativeGroup.Items.Select(p => p.Path).ToList(); } // COMPAT: Support lib/contract so older packages can be consumed string contractPath = "lib/contract/" + package.Id + ".dll"; var hasContract = files.Any(path => path == contractPath); var hasLib = lockFileLib.RuntimeAssemblies.Any(); if (hasContract && hasLib && !framework.IsDesktop()) { lockFileLib.CompileTimeAssemblies.Clear(); lockFileLib.CompileTimeAssemblies.Add(contractPath); } // Apply filters from the <references> node in the nuspec if (referenceFilter != null) { // Remove anything that starts with "lib/" and is NOT specified in the reference filter. // runtimes/* is unaffected (it doesn't start with lib/) lockFileLib.RuntimeAssemblies = lockFileLib.RuntimeAssemblies.Where(p => !p.StartsWith("lib/") || referenceFilter.Contains(p)).ToList(); lockFileLib.CompileTimeAssemblies = lockFileLib.CompileTimeAssemblies.Where(p => !p.StartsWith("lib/") || referenceFilter.Contains(p)).ToList(); } return(lockFileLib); }
/// <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); }
private void WriteTargetsAndProps(PackageSpec project, List <RestoreTargetGraph> targetGraphs, NuGetv3LocalRepository repository) { // Get the runtime-independent graphs var tfmGraphs = targetGraphs.Where(g => string.IsNullOrEmpty(g.RuntimeIdentifier)).ToList(); if (tfmGraphs.Count > 1) { var name = $"{project.Name}.nuget.targets"; var path = Path.Combine(project.BaseDirectory, name); _log.LogInformation($"Generating MSBuild file {name}"); GenerateMSBuildErrorFile(path); return; } var graph = tfmGraphs[0]; var pathResolver = new DefaultPackagePathResolver(repository.RepositoryRoot); var targets = new List <string>(); var props = new List <string>(); foreach (var library in graph.Flattened.Distinct().OrderBy(g => g.Data.Match.Library)) { var package = repository.FindPackagesById(library.Key.Name).FirstOrDefault(p => p.Version == library.Key.Version); if (package != null) { var criteria = graph.Conventions.Criteria.ForFramework(graph.Framework); var contentItemCollection = new ContentItemCollection(); using (var nupkgStream = File.OpenRead(package.ZipPath)) { var reader = new PackageReader(nupkgStream); contentItemCollection.Load(reader.GetFiles()); } // Find MSBuild thingies var buildItems = contentItemCollection.FindBestItemGroup(criteria, graph.Conventions.Patterns.MSBuildFiles); 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(package.Id, StringComparison.OrdinalIgnoreCase)) .ToList(); targets.AddRange(items .Select(c => c.Path) .Where(path => Path.GetExtension(path).Equals(".targets", StringComparison.OrdinalIgnoreCase)) .Select(path => Path.Combine(pathResolver.GetPackageDirectory(package.Id, package.Version), path.Replace('/', Path.DirectorySeparatorChar)))); props.AddRange(items .Select(c => c.Path) .Where(path => Path.GetExtension(path).Equals(".props", StringComparison.OrdinalIgnoreCase)) .Select(path => Path.Combine(pathResolver.GetPackageDirectory(package.Id, package.Version), path.Replace('/', Path.DirectorySeparatorChar)))); } } } // Generate the files as needed var targetsName = $"{project.Name}.nuget.targets"; var propsName = $"{project.Name}.nuget.props"; var targetsPath = Path.Combine(project.BaseDirectory, targetsName); var propsPath = Path.Combine(project.BaseDirectory, propsName); if (targets.Any()) { _log.LogInformation($"Generating MSBuild file {targetsName}"); GenerateImportsFile(repository, targetsPath, targets); } else if (File.Exists(targetsPath)) { File.Delete(targetsPath); } if (props.Any()) { _log.LogInformation($"Generating MSBuild file {propsName}"); GenerateImportsFile(repository, propsPath, props); } else if (File.Exists(propsPath)) { File.Delete(propsPath); } }
/// <summary> /// COMPAT: Support lib/contract so older packages can be consumed /// </summary> private static void ApplyLibContract(LocalPackageInfo package, LockFileTargetLibrary lockFileLib, NuGetFramework framework, ContentItemCollection contentItems) { if (contentItems.HasContract && lockFileLib.RuntimeAssemblies.Count > 0 && !framework.IsDesktop()) { var contractPath = "lib/contract/" + package.Id + ".dll"; if (package.Files.Any(path => path == contractPath)) { lockFileLib.CompileTimeAssemblies.Clear(); lockFileLib.CompileTimeAssemblies.Add(new LockFileItem(contractPath)); } } }
internal static IEnumerable <PackagingLogMessage> ValidateFiles(IEnumerable <string> files) { var set = new HashSet <string>(StringComparer.OrdinalIgnoreCase); foreach (var file in files.Select(t => PathUtility.GetPathWithDirectorySeparator(t))) { set.Add(file); } var managedCodeConventions = new ManagedCodeConventions(new RuntimeGraph()); var collection = new ContentItemCollection(); collection.Load(set.Select(path => path.Replace('\\', '/')).ToArray()); var patterns = managedCodeConventions.Patterns; var frameworkPatterns = new List <PatternSet>() { patterns.RuntimeAssemblies, patterns.CompileRefAssemblies, patterns.CompileLibAssemblies, patterns.NativeLibraries, patterns.ResourceAssemblies, patterns.MSBuildFiles, patterns.ContentFiles, patterns.ToolsAssemblies, patterns.EmbedAssemblies, patterns.MSBuildTransitiveFiles }; var warnPaths = new HashSet <string>(); List <ContentItemGroup> targetedItemGroups = new(); foreach (var pattern in frameworkPatterns) { targetedItemGroups.Clear(); ContentExtractor.GetContentForPattern(collection, pattern, targetedItemGroups); foreach (ContentItemGroup group in targetedItemGroups) { foreach (ContentItem item in group.Items) { var exists = item.Properties.TryGetValue("tfm_raw", out var frameworkRaw); string frameworkString = (string)frameworkRaw; if (!exists || string.IsNullOrEmpty(frameworkString)) { continue; } if (!FrameworkVersionHasDesiredDots(frameworkString)) { warnPaths.Add(item.Path); } } } } var messages = new List <PackagingLogMessage>(); if (warnPaths.Count > 0) { messages.Add( PackagingLogMessage.CreateWarning( string.Format(CultureInfo.CurrentCulture, AnalysisResources.InvalidUndottedFrameworkInFilesWarning, string.Join(", ", warnPaths)), NuGetLogCode.NU5501 ) ); } return(messages); }
public static LockFileTargetLibrary CreateLockFileTargetLibrary( LockFileLibrary library, LocalPackageInfo package, RestoreTargetGraph targetGraph, LibraryIncludeFlags dependencyType, NuGetFramework targetFrameworkOverride, IEnumerable <LibraryDependency> dependencies) { var lockFileLib = new LockFileTargetLibrary(); var framework = targetFrameworkOverride ?? targetGraph.Framework; var runtimeIdentifier = targetGraph.RuntimeIdentifier; lockFileLib.Name = package.Id; lockFileLib.Version = package.Version; lockFileLib.Type = LibraryType.Package; IList <string> files; var contentItems = new ContentItemCollection(); HashSet <string> referenceFilter = null; // If the previous LockFileLibrary was given, use that to find the file list. Otherwise read the nupkg. if (library == null) { using (var packageReader = new PackageFolderReader(package.ExpandedPath)) { if (Path.DirectorySeparatorChar != LockFile.DirectorySeparatorChar) { files = packageReader .GetFiles() .Select(p => p.Replace(Path.DirectorySeparatorChar, LockFile.DirectorySeparatorChar)) .ToList(); } else { files = packageReader .GetFiles() .ToList(); } } } else { if (Path.DirectorySeparatorChar != LockFile.DirectorySeparatorChar) { files = library.Files.Select(p => p.Replace(Path.DirectorySeparatorChar, LockFile.DirectorySeparatorChar)).ToList(); } else { files = library.Files; } } contentItems.Load(files); // This will throw an appropriate error if the nuspec is missing var nuspec = package.Nuspec; if (dependencies == null) { var dependencySet = nuspec .GetDependencyGroups() .GetNearest(framework); if (dependencySet != null) { var set = dependencySet.Packages; if (set != null) { lockFileLib.Dependencies = set.ToList(); } } } else { // Filter the dependency set down to packages and projects. // Framework references will not be displayed lockFileLib.Dependencies = dependencies .Where(ld => ld.LibraryRange.TypeConstraintAllowsAnyOf(LibraryDependencyTarget.PackageProjectExternal)) .Select(ld => new PackageDependency(ld.Name, ld.LibraryRange.VersionRange)) .ToList(); } var referenceSet = nuspec.GetReferenceGroups().GetNearest(framework); if (referenceSet != null) { referenceFilter = new HashSet <string>(referenceSet.Items, StringComparer.OrdinalIgnoreCase); } // Exclude framework references for package based frameworks. if (!framework.IsPackageBased) { var frameworkAssemblies = nuspec.GetFrameworkReferenceGroups().GetNearest(framework); if (frameworkAssemblies != null) { foreach (var assemblyReference in frameworkAssemblies.Items) { lockFileLib.FrameworkAssemblies.Add(assemblyReference); } } } // 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, framework); // Compile // ref takes precedence over lib var compileGroup = GetLockFileItems( orderedCriteria, contentItems, targetGraph.Conventions.Patterns.CompileRefAssemblies, targetGraph.Conventions.Patterns.CompileLibAssemblies); lockFileLib.CompileTimeAssemblies.AddRange(compileGroup); // Runtime var runtimeGroup = GetLockFileItems( orderedCriteria, contentItems, targetGraph.Conventions.Patterns.RuntimeAssemblies); lockFileLib.RuntimeAssemblies.AddRange(runtimeGroup); // Resources var resourceGroup = GetLockFileItems( orderedCriteria, contentItems, targetGraph.Conventions.Patterns.ResourceAssemblies); lockFileLib.ResourceAssemblies.AddRange(resourceGroup); // Native var nativeGroup = GetLockFileItems( orderedCriteria, contentItems, targetGraph.Conventions.Patterns.NativeLibraries); lockFileLib.NativeLibraries.AddRange(nativeGroup); // Build var buildGroup = GetLockFileItems( orderedCriteria, contentItems, targetGraph.Conventions.Patterns.MSBuildFiles); lockFileLib.Build.AddRange(GetBuildItemsForPackageId(buildGroup, library.Name)); // Build multi targeting var buildMultiTargetingGroup = GetLockFileItems( orderedCriteria, contentItems, targetGraph.Conventions.Patterns.MSBuildMultiTargetingFiles); lockFileLib.BuildMultiTargeting.AddRange(GetBuildItemsForPackageId(buildMultiTargetingGroup, library.Name)); // content v2 items var contentFileGroups = contentItems.FindItemGroups(targetGraph.Conventions.Patterns.ContentFiles); // Multiple groups can match the same framework, find all of them var contentFileGroupsForFramework = ContentFileUtils.GetContentGroupsForFramework( lockFileLib, framework, contentFileGroups); lockFileLib.ContentFiles = ContentFileUtils.GetContentFileGroup( framework, nuspec, contentFileGroupsForFramework); // Runtime targets // These are applied only to non-RID target graphs. // They are not used for compatibility checks. if (string.IsNullOrEmpty(runtimeIdentifier)) { // Runtime targets contain all the runtime specific assets // that could be contained in the runtime specific target graphs. // These items are contained in a flat list and have additional properties // for the RID and lock file section the assembly would belong to. var runtimeTargetItems = new List <LockFileRuntimeTarget>(); // Runtime runtimeTargetItems.AddRange(GetRuntimeTargetLockFileItems( contentItems, framework, dependencyType, LibraryIncludeFlags.Runtime, targetGraph.Conventions.Patterns.RuntimeAssemblies, "runtime")); // Resource runtimeTargetItems.AddRange(GetRuntimeTargetLockFileItems( contentItems, framework, dependencyType, LibraryIncludeFlags.Runtime, targetGraph.Conventions.Patterns.ResourceAssemblies, "resource")); // Native runtimeTargetItems.AddRange(GetRuntimeTargetLockFileItems( contentItems, framework, dependencyType, LibraryIncludeFlags.Native, targetGraph.Conventions.Patterns.NativeLibraries, "native")); lockFileLib.RuntimeTargets = runtimeTargetItems; } // COMPAT: Support lib/contract so older packages can be consumed var contractPath = "lib/contract/" + package.Id + ".dll"; var hasContract = files.Any(path => path == contractPath); var hasLib = lockFileLib.RuntimeAssemblies.Any(); if (hasContract && hasLib && !framework.IsDesktop()) { lockFileLib.CompileTimeAssemblies.Clear(); lockFileLib.CompileTimeAssemblies.Add(new LockFileItem(contractPath)); } // Apply filters from the <references> node in the nuspec if (referenceFilter != null) { // Remove anything that starts with "lib/" and is NOT specified in the reference filter. // runtimes/* is unaffected (it doesn't start with lib/) lockFileLib.RuntimeAssemblies = lockFileLib.RuntimeAssemblies.Where(p => !p.Path.StartsWith("lib/") || referenceFilter.Contains(Path.GetFileName(p.Path))).ToList(); lockFileLib.CompileTimeAssemblies = lockFileLib.CompileTimeAssemblies.Where(p => !p.Path.StartsWith("lib/") || referenceFilter.Contains(Path.GetFileName(p.Path))).ToList(); } // Exclude items ExcludeItems(lockFileLib, dependencyType); return(lockFileLib); }
internal static void GetContentForPattern(ContentItemCollection collection, PatternSet pattern, IList <ContentItemGroup> itemGroups) { collection.PopulateItemGroups(pattern, itemGroups); }
private LockFileTargetLibrary CreateLockFileTargetLibrary(LocalPackageInfo package, RestoreTargetGraph targetGraph, DefaultPackagePathResolver defaultPackagePathResolver, string correctedPackageName) { var lockFileLib = new LockFileTargetLibrary(); var framework = targetGraph.Framework; var runtimeIdentifier = targetGraph.RuntimeIdentifier; // package.Id is read from nuspec and it might be in wrong casing. // correctedPackageName should be the package name used by dependency graph and // it has the correct casing that runtime needs during dependency resolution. lockFileLib.Name = correctedPackageName ?? package.Id; lockFileLib.Version = package.Version; IList<string> files; var contentItems = new ContentItemCollection(); HashSet<string> referenceFilter = null; using (var nupkgStream = File.OpenRead(package.ZipPath)) { var packageReader = new PackageReader(nupkgStream); files = packageReader.GetFiles().Select(p => p.Replace(Path.DirectorySeparatorChar, '/')).ToList(); contentItems.Load(files); var dependencySet = packageReader.GetPackageDependencies().GetNearest(framework); if (dependencySet != null) { var set = dependencySet.Packages; if (set != null) { lockFileLib.Dependencies = set.ToList(); } } var referenceSet = packageReader.GetReferenceItems().GetNearest(framework); if (referenceSet != null) { referenceFilter = new HashSet<string>(referenceSet.Items, StringComparer.OrdinalIgnoreCase); } // TODO: Remove this when we do #596 // ASP.NET Core isn't compatible with generic PCL profiles if (!string.Equals(framework.Framework, FrameworkConstants.FrameworkIdentifiers.AspNetCore, StringComparison.OrdinalIgnoreCase) && !string.Equals(framework.Framework, FrameworkConstants.FrameworkIdentifiers.DnxCore, StringComparison.OrdinalIgnoreCase)) { var frameworkAssemblies = packageReader.GetFrameworkItems().GetNearest(framework); if (frameworkAssemblies != null) { foreach (var assemblyReference in frameworkAssemblies.Items) { lockFileLib.FrameworkAssemblies.Add(assemblyReference); } } } } var nativeCriteria = targetGraph.Conventions.Criteria.ForRuntime(targetGraph.RuntimeIdentifier); var managedCriteria = targetGraph.Conventions.Criteria.ForFrameworkAndRuntime(framework, targetGraph.RuntimeIdentifier); var compileGroup = contentItems.FindBestItemGroup(managedCriteria, targetGraph.Conventions.Patterns.CompileAssemblies, targetGraph.Conventions.Patterns.RuntimeAssemblies); if (compileGroup != null) { lockFileLib.CompileTimeAssemblies = compileGroup.Items.Select(t => new LockFileItem(t.Path)).ToList(); } var runtimeGroup = contentItems.FindBestItemGroup(managedCriteria, targetGraph.Conventions.Patterns.RuntimeAssemblies); if (runtimeGroup != null) { lockFileLib.RuntimeAssemblies = runtimeGroup.Items.Select(p => new LockFileItem(p.Path)).ToList(); } var resourceGroup = contentItems.FindBestItemGroup(managedCriteria, targetGraph.Conventions.Patterns.ResourceAssemblies); if (resourceGroup != null) { lockFileLib.ResourceAssemblies = resourceGroup.Items.Select(ToResourceLockFileItem).ToList(); } var nativeGroup = contentItems.FindBestItemGroup(nativeCriteria, targetGraph.Conventions.Patterns.NativeLibraries); if (nativeGroup != null) { lockFileLib.NativeLibraries = nativeGroup.Items.Select(p => new LockFileItem(p.Path)).ToList(); } // COMPAT: Support lib/contract so older packages can be consumed var contractPath = "lib/contract/" + package.Id + ".dll"; var hasContract = files.Any(path => path == contractPath); var hasLib = lockFileLib.RuntimeAssemblies.Any(); if (hasContract && hasLib && !framework.IsDesktop()) { lockFileLib.CompileTimeAssemblies.Clear(); lockFileLib.CompileTimeAssemblies.Add(new LockFileItem(contractPath)); } // Apply filters from the <references> node in the nuspec if (referenceFilter != null) { // Remove anything that starts with "lib/" and is NOT specified in the reference filter. // runtimes/* is unaffected (it doesn't start with lib/) lockFileLib.RuntimeAssemblies = lockFileLib.RuntimeAssemblies.Where(p => !p.Path.StartsWith("lib/") || referenceFilter.Contains(p.Path)).ToList(); lockFileLib.CompileTimeAssemblies = lockFileLib.CompileTimeAssemblies.Where(p => !p.Path.StartsWith("lib/") || referenceFilter.Contains(p.Path)).ToList(); } return lockFileLib; }
private void WriteTargetsAndProps(PackageSpec project, List<RestoreTargetGraph> targetGraphs, NuGetv3LocalRepository repository) { // Get the runtime-independent graphs var tfmGraphs = targetGraphs.Where(g => string.IsNullOrEmpty(g.RuntimeIdentifier)).ToList(); if (tfmGraphs.Count > 1) { var name = $"{project.Name}.nuget.targets"; var path = Path.Combine(project.BaseDirectory, name); _log.LogInformation($"Generating MSBuild file {name}"); GenerateMSBuildErrorFile(path); return; } var graph = tfmGraphs[0]; var pathResolver = new DefaultPackagePathResolver(repository.RepositoryRoot); var targets = new List<string>(); var props = new List<string>(); foreach (var library in graph.Flattened.Distinct().OrderBy(g => g.Data.Match.Library)) { var package = repository.FindPackagesById(library.Key.Name).FirstOrDefault(p => p.Version == library.Key.Version); if (package != null) { var criteria = graph.Conventions.Criteria.ForFramework(graph.Framework); var contentItemCollection = new ContentItemCollection(); using (var nupkgStream = File.OpenRead(package.ZipPath)) { var reader = new PackageReader(nupkgStream); contentItemCollection.Load(reader.GetFiles()); } // Find MSBuild thingies var buildItems = contentItemCollection.FindBestItemGroup(criteria, graph.Conventions.Patterns.MSBuildFiles); 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(package.Id, StringComparison.OrdinalIgnoreCase)) .ToList(); targets.AddRange(items .Select(c => c.Path) .Where(path => Path.GetExtension(path).Equals(".targets", StringComparison.OrdinalIgnoreCase)) .Select(path => Path.Combine(pathResolver.GetPackageDirectory(package.Id, package.Version), path.Replace('/', Path.DirectorySeparatorChar)))); props.AddRange(items .Select(c => c.Path) .Where(path => Path.GetExtension(path).Equals(".props", StringComparison.OrdinalIgnoreCase)) .Select(path => Path.Combine(pathResolver.GetPackageDirectory(package.Id, package.Version), path.Replace('/', Path.DirectorySeparatorChar)))); } } } // Generate the files as needed var targetsName = $"{project.Name}.nuget.targets"; var propsName = $"{project.Name}.nuget.props"; var targetsPath = Path.Combine(project.BaseDirectory, targetsName); var propsPath = Path.Combine(project.BaseDirectory, propsName); if (targets.Any()) { _log.LogInformation($"Generating MSBuild file {targetsName}"); GenerateImportsFile(repository, targetsPath, targets); } else if (File.Exists(targetsPath)) { File.Delete(targetsPath); } if (props.Any()) { _log.LogInformation($"Generating MSBuild file {propsName}"); GenerateImportsFile(repository, propsPath, props); } else if (File.Exists(propsPath)) { File.Delete(propsPath); } }
private static IEnumerable <ContentItemGroup> GetContentForPattern(ContentItemCollection collection, PatternSet pattern) { return(collection.FindItemGroups(pattern)); }
public static IEnumerable<string> GetAssembliesForFramework(FrameworkName framework, IPackage package, IEnumerable<string> packageAssemblies) { var patterns = PatternDefinitions.DotNetPatterns; if (packageAssemblies == null) { return null; } var files = packageAssemblies.Select(p => p.Replace(Path.DirectorySeparatorChar, '/')).ToList(); var contentItems = new ContentItemCollection(); contentItems.Load(files); var criteriaBuilderWithTfm = new SelectionCriteriaBuilder(patterns.Properties.Definitions); criteriaBuilderWithTfm = criteriaBuilderWithTfm .Add["tfm", framework]; var criteria = criteriaBuilderWithTfm.Criteria; var allReferencesGroup = contentItems.FindBestItemGroup(criteria, patterns.CompileTimeAssemblies, patterns.ManagedAssemblies); List<string> allReferencesGroupAssemblies = null; if (allReferencesGroup != null) { allReferencesGroupAssemblies = allReferencesGroup.Items.Select(t => t.Path).ToList(); } if (allReferencesGroupAssemblies == null) { return null; } IEnumerable<string> oldLibGroupAssemblies = null; var oldLibGroup = contentItems.FindBestItemGroup(criteria, patterns.ManagedAssemblies); if (oldLibGroup != null) { oldLibGroupAssemblies = oldLibGroup.Items.Select(p => p.Path).ToList(); } // COMPAT: Support lib/contract so older packages can be consumed string contractPath = "lib/contract/" + package.Id + ".dll"; var hasContract = files.Any(path => contractPath.Equals(path, StringComparison.OrdinalIgnoreCase)); var hasLib = oldLibGroupAssemblies != null && oldLibGroupAssemblies.Any(); if (hasContract && hasLib && !DnxVersionUtility.IsDesktop(framework)) { allReferencesGroupAssemblies.Clear(); allReferencesGroupAssemblies.Add(contractPath); } // See if there's a list of specific references defined for this target framework IEnumerable<PackageReferenceSet> referenceSets; if (DnxVersionUtility.GetNearest(framework, package.PackageAssemblyReferences.ToList(), out referenceSets)) { // Get the first compatible reference set var referenceSet = referenceSets.FirstOrDefault(); if (referenceSet != null) { // Remove all assemblies of which names do not appear in the References list allReferencesGroupAssemblies.RemoveAll(path => path.StartsWith("lib/") && !referenceSet.References.Contains(Path.GetFileName(path), StringComparer.OrdinalIgnoreCase)); } } return allReferencesGroupAssemblies.Select(p => p.Replace('/', Path.DirectorySeparatorChar)).ToList(); }
/// <summary> /// Populate assets for a <see cref="LockFileLibrary"/>. /// </summary> private static void AddAssets( LockFileLibrary library, LocalPackageInfo package, RestoreTargetGraph targetGraph, LibraryIncludeFlags dependencyType, LockFileTargetLibrary lockFileLib, NuGetFramework framework, string runtimeIdentifier, IList <string> files, ContentItemCollection contentItems, NuspecReader nuspec, IReadOnlyList <SelectionCriteria> orderedCriteria) { // Add framework references for desktop projects. AddFrameworkReferences(lockFileLib, framework, nuspec); // Compile // ref takes precedence over lib var compileGroup = GetLockFileItems( orderedCriteria, contentItems, targetGraph.Conventions.Patterns.CompileRefAssemblies, targetGraph.Conventions.Patterns.CompileLibAssemblies); lockFileLib.CompileTimeAssemblies.AddRange(compileGroup); // Runtime var runtimeGroup = GetLockFileItems( orderedCriteria, contentItems, targetGraph.Conventions.Patterns.RuntimeAssemblies); lockFileLib.RuntimeAssemblies.AddRange(runtimeGroup); // Resources var resourceGroup = GetLockFileItems( orderedCriteria, contentItems, targetGraph.Conventions.Patterns.ResourceAssemblies); lockFileLib.ResourceAssemblies.AddRange(resourceGroup); // Native var nativeGroup = GetLockFileItems( orderedCriteria, contentItems, targetGraph.Conventions.Patterns.NativeLibraries); lockFileLib.NativeLibraries.AddRange(nativeGroup); // Build var buildGroup = GetLockFileItems( orderedCriteria, contentItems, targetGraph.Conventions.Patterns.MSBuildFiles); lockFileLib.Build.AddRange(GetBuildItemsForPackageId(buildGroup, library.Name)); // Build multi targeting var buildMultiTargetingGroup = GetLockFileItems( orderedCriteria, contentItems, targetGraph.Conventions.Patterns.MSBuildMultiTargetingFiles); lockFileLib.BuildMultiTargeting.AddRange(GetBuildItemsForPackageId(buildMultiTargetingGroup, library.Name)); // Add content files AddContentFiles(targetGraph, lockFileLib, framework, contentItems, nuspec); // Runtime targets // These are applied only to non-RID target graphs. // They are not used for compatibility checks. AddRuntimeTargets(targetGraph, dependencyType, lockFileLib, framework, runtimeIdentifier, contentItems); // COMPAT: Support lib/contract so older packages can be consumed ApplyLibContract(package, lockFileLib, framework, files); // Apply filters from the <references> node in the nuspec ApplyReferenceFilter(lockFileLib, framework, nuspec); }
public void AddPackageItems(string packageId, IEnumerable<string> packageItems) { if (!_packages.ContainsKey(packageId)) { _packages[packageId] = new ContentItemCollection(); } _packages[packageId].Load(packageItems); }
private static void AddContentFiles(RestoreTargetGraph targetGraph, LockFileTargetLibrary lockFileLib, NuGetFramework framework, ContentItemCollection contentItems, NuspecReader nuspec) { // content v2 items var contentFileGroups = contentItems.FindItemGroups(targetGraph.Conventions.Patterns.ContentFiles); // Multiple groups can match the same framework, find all of them var contentFileGroupsForFramework = ContentFileUtils.GetContentGroupsForFramework( lockFileLib, framework, contentFileGroups); lockFileLib.ContentFiles = ContentFileUtils.GetContentFileGroup( framework, nuspec, contentFileGroupsForFramework); }
public static LockFileTargetLibrary CreateLockFileTargetLibrary(LockFileLibrary library, IPackage package, RestoreContext context, string correctedPackageName) { var lockFileLib = new LockFileTargetLibrary(); var framework = context.FrameworkName; var runtimeIdentifier = context.RuntimeName; // package.Id is read from nuspec and it might be in wrong casing. // correctedPackageName should be the package name used by dependency graph and // it has the correct casing that runtime needs during dependency resolution. lockFileLib.Name = correctedPackageName ?? package.Id; lockFileLib.Version = package.Version; var files = library.Files.Select(p => p.Replace(Path.DirectorySeparatorChar, '/')); var contentItems = new ContentItemCollection(); contentItems.Load(files); IEnumerable<PackageDependencySet> dependencySet; if (VersionUtility.GetNearest(framework, package.DependencySets, out dependencySet)) { var set = dependencySet.FirstOrDefault()?.Dependencies?.ToList(); if (set != null) { lockFileLib.Dependencies = set; } } // TODO: Remove this when we do #596 // ASP.NET Core and .NET Core 5.0 don't have framework reference assemblies if (!VersionUtility.IsPackageBased(framework)) { IEnumerable<FrameworkAssemblyReference> frameworkAssemblies; if (VersionUtility.GetNearest(framework, package.FrameworkAssemblies, out frameworkAssemblies)) { AddFrameworkReferences(lockFileLib, framework, frameworkAssemblies); } // Add framework assemblies with empty supported frameworks AddFrameworkReferences(lockFileLib, framework, package.FrameworkAssemblies.Where(f => !f.SupportedFrameworks.Any())); } var patterns = PatternDefinitions.DotNetPatterns; var criteriaBuilderWithTfm = new SelectionCriteriaBuilder(patterns.Properties.Definitions); var criteriaBuilderWithoutTfm = new SelectionCriteriaBuilder(patterns.Properties.Definitions); if (context.RuntimeSpecs != null) { foreach (var runtimeSpec in context.RuntimeSpecs) { criteriaBuilderWithTfm = criteriaBuilderWithTfm .Add["tfm", framework]["rid", runtimeSpec.Name]; criteriaBuilderWithoutTfm = criteriaBuilderWithoutTfm .Add["rid", runtimeSpec.Name]; } } criteriaBuilderWithTfm = criteriaBuilderWithTfm .Add["tfm", framework]; var criteria = criteriaBuilderWithTfm.Criteria; var compileGroup = contentItems.FindBestItemGroup(criteria, patterns.CompileTimeAssemblies, patterns.ManagedAssemblies); if (compileGroup != null) { lockFileLib.CompileTimeAssemblies = compileGroup.Items.Select(t => (LockFileItem)t.Path).ToList(); } var runtimeGroup = contentItems.FindBestItemGroup(criteria, patterns.ManagedAssemblies); if (runtimeGroup != null) { lockFileLib.RuntimeAssemblies = runtimeGroup.Items.Select(p => (LockFileItem)p.Path).ToList(); } var resourceGroup = contentItems.FindBestItemGroup(criteria, patterns.ResourceAssemblies); if (resourceGroup != null) { lockFileLib.ResourceAssemblies = resourceGroup.Items.Select(ToResourceLockFileItem).ToList(); } var nativeGroup = contentItems.FindBestItemGroup(criteriaBuilderWithoutTfm.Criteria, patterns.NativeLibraries); if (nativeGroup != null) { lockFileLib.NativeLibraries = nativeGroup.Items.Select(p => (LockFileItem)p.Path).ToList(); } // COMPAT: Support lib/contract so older packages can be consumed string contractPath = "lib/contract/" + package.Id + ".dll"; var hasContract = files.Any(path => path == contractPath); var hasLib = lockFileLib.RuntimeAssemblies.Any(); if (hasContract && hasLib && !VersionUtility.IsDesktop(framework)) { lockFileLib.CompileTimeAssemblies.Clear(); lockFileLib.CompileTimeAssemblies.Add(contractPath); } // See if there's a list of specific references defined for this target framework IEnumerable<PackageReferenceSet> referenceSets; if (VersionUtility.GetNearest(framework, package.PackageAssemblyReferences, out referenceSets)) { // Get the first compatible reference set var referenceSet = referenceSets.FirstOrDefault(); if (referenceSet != null) { // Remove all assemblies of which names do not appear in the References list lockFileLib.RuntimeAssemblies.RemoveAll(path => path.Path.StartsWith("lib/") && !referenceSet.References.Contains(Path.GetFileName(path), StringComparer.OrdinalIgnoreCase)); lockFileLib.CompileTimeAssemblies.RemoveAll(path => path.Path.StartsWith("lib/") && !referenceSet.References.Contains(Path.GetFileName(path), StringComparer.OrdinalIgnoreCase)); } } return lockFileLib; }
private MSBuildRestoreResult RestoreMSBuildFiles(PackageSpec project, IEnumerable <RestoreTargetGraph> targetGraphs, IReadOnlyList <NuGetv3LocalRepository> repositories, 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 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(); var packageInfo = NuGetv3LocalRepositoryUtility.GetPackage(repositories, library.Key.Name, library.Key.Version); var pathResolver = packageInfo.Repository.PathResolver; targets.AddRange(items .Where(c => Path.GetExtension(c.Path).Equals(".targets", StringComparison.OrdinalIgnoreCase)) .Select(c => Path.Combine(pathResolver.GetInstallPath(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.GetInstallPath(library.Key.Name, library.Key.Version), c.Path.Replace('/', Path.DirectorySeparatorChar)))); } } } } // Targets files contain a macro for the repository root. If only the user package folder was used // allow a replacement. If fallback folders were used the macro cannot be applied. // Do not use macros for fallback folders. Use only the first repository which is the user folder. var repositoryRoot = repositories.First().RepositoryRoot; return(new MSBuildRestoreResult(project.Name, project.BaseDirectory, repositoryRoot, props, targets)); }