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);
        }
Exemple #2
0
        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);
            }
        }
Exemple #3
0
        /// <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);
        }
Exemple #4
0
        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);
        }
Exemple #5
0
        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);
        }
Exemple #6
0
        /// <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);
        }
Exemple #7
0
        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);
            }
        }
Exemple #8
0
        /// <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));
                }
            }
        }
Exemple #9
0
        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);
        }
Exemple #11
0
 internal static void GetContentForPattern(ContentItemCollection collection, PatternSet pattern, IList <ContentItemGroup> itemGroups)
 {
     collection.PopulateItemGroups(pattern, itemGroups);
 }
Exemple #12
0
        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;
        }
Exemple #13
0
        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();
        }
Exemple #16
0
        /// <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);
        }
Exemple #18
0
        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);
        }
Exemple #19
0
        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;
        }
Exemple #20
0
        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));
        }