Esempio n. 1
0
        public void ContentFiles_Empty()
        {
            // Arrange
            var conventions = new ManagedCodeConventions(
                new RuntimeGraph(
                    new List <CompatibilityProfile>()
            {
                new CompatibilityProfile("net46.app")
            }));

            var criteria = conventions.Criteria.ForFramework(NuGetFramework.Parse("net46"));

            var collection = new ContentItemCollection();

            collection.Load(new string[]
            {
                // empty
            });

            // Act
            var contentFileGroups = collection.FindItemGroups(conventions.Patterns.ContentFiles);

            // Assert
            Assert.Equal(0, contentFileGroups.Count());
        }
Esempio n. 2
0
        public void ContentFiles_InvalidPaths()
        {
            // Arrange
            var conventions = new ManagedCodeConventions(
                new RuntimeGraph(
                    new List <CompatibilityProfile>()
            {
                new CompatibilityProfile("net46.app")
            }));

            var criteria = conventions.Criteria.ForFramework(NuGetFramework.Parse("net46"));

            var collection = new ContentItemCollection();

            collection.Load(new string[]
            {
                "contentFiles/any/config1.xml",
                "contentFiles/in.valid/net45/config2.xml",
                "contentFiles/any/config3.xml",
                "contentFiles/config4.xml",
                "contentFiles",
                "contentFiles/+/uap10.0.0/config6.xml"
            });

            // Act
            var contentFileGroups = collection.FindItemGroups(conventions.Patterns.ContentFiles);

            // Assert
            Assert.Equal(0, contentFileGroups.Count());
        }
Esempio n. 3
0
        private static List <LockFileRuntimeTarget> GetRuntimeTargetLockFileItems(
            ContentItemCollection contentItems,
            NuGetFramework framework,
            LibraryIncludeFlags dependencyType,
            LibraryIncludeFlags groupType,
            PatternSet patternSet,
            string assetType,
            MaccatalystFallback maccatalystFallback)
        {
            var groups = contentItems.FindItemGroups(patternSet).ToList();

            var groupsForFramework = GetContentGroupsForFramework(
                framework,
                groups,
                ManagedCodeConventions.PropertyNames.RuntimeIdentifier,
                maccatalystFallback);

            var items = GetRuntimeTargetItems(groupsForFramework, assetType);

            if ((dependencyType & groupType) == LibraryIncludeFlags.None)
            {
                ClearIfExists <LockFileRuntimeTarget>(items);
            }

            return(items);
        }
Esempio n. 4
0
        public void ContentModel_ContentFilesAnyMapsToAny()
        {
            // Arrange
            var conventions = new ManagedCodeConventions(
                new RuntimeGraph(
                    new List <CompatibilityProfile>()
            {
                new CompatibilityProfile("net46.app")
            }));

            var collection = new ContentItemCollection();

            collection.Load(new string[]
            {
                "contentFiles/any/any/a.txt",
            });

            // Act
            var groups = collection.FindItemGroups(conventions.Patterns.ContentFiles)
                         .OrderBy(group => ((NuGetFramework)group.Properties["tfm"]).GetShortFolderName())
                         .ToList();

            // Assert
            Assert.Equal(1, groups.Count);
            Assert.Equal(NuGetFramework.AnyFramework, (NuGetFramework)groups[0].Properties["tfm"]);
        }
        public void ContentModel_BuildNoFilesAtRootNoAnyGroup()
        {
            // Arrange
            var conventions = new ManagedCodeConventions(
                new RuntimeGraph(
                    new List <CompatibilityProfile>()
            {
                new CompatibilityProfile("net46.app")
            }));

            var collection = new ContentItemCollection();

            collection.Load(new string[]
            {
                "build/net46/packageA.targets",
                "build/net45/packageA.targets",
                "build/net35/packageA.targets",
                "build/net20/packageA.targets",
                "build/uap10.0/packageA.targets",
            });

            // Act
            var groups = collection.FindItemGroups(conventions.Patterns.MSBuildFiles)
                         .Select(group => ((NuGetFramework)group.Properties["tfm"]))
                         .ToList();

            // Assert
            Assert.Equal(0, groups.Count(framework => framework == NuGetFramework.AnyFramework));
        }
        public void ContentModel_BuildAnyFolderTreatedAsDotNet()
        {
            // Arrange
            var conventions = new ManagedCodeConventions(
                new RuntimeGraph(
                    new List <CompatibilityProfile>()
            {
                new CompatibilityProfile("net46.app")
            }));

            var collection = new ContentItemCollection();

            collection.Load(new string[]
            {
                "build/any/packageA.targets"
            });

            // Act
            var framework = collection.FindItemGroups(conventions.Patterns.MSBuildFiles)
                            .Select(group => ((NuGetFramework)group.Properties["tfm"]))
                            .Single();

            // Assert
            Assert.Equal(".NETPlatform", framework.Framework);
        }
        public void ContentModel_BuildRootFolderRandomFiles()
        {
            // Arrange
            var conventions = new ManagedCodeConventions(
                new RuntimeGraph(
                    new List <CompatibilityProfile>()
            {
                new CompatibilityProfile("net46.app")
            }));

            var collection = new ContentItemCollection();

            collection.Load(new string[]
            {
                "build/config.xml",
                "build/net45/task.dll",
                "build/net45/task.targets",
                "build/net45/task.props",
            });

            // Act
            var groups = collection.FindItemGroups(conventions.Patterns.MSBuildFiles);

            // Assert
            Assert.Equal(1, groups.Count());
            Assert.Equal(NuGetFramework.Parse("net45"), groups.First().Properties["tfm"] as NuGetFramework);
        }
Esempio n. 8
0
        public void ContentModel_ResourcesAnyMapsToDotnet()
        {
            // Arrange
            var conventions = new ManagedCodeConventions(
                new RuntimeGraph(
                    new List <CompatibilityProfile>()
            {
                new CompatibilityProfile("net46.app")
            }));

            var collection = new ContentItemCollection();

            collection.Load(new string[]
            {
                "lib/any/en-us/a.resources.dll",
            });

            // Act
            var groups = collection.FindItemGroups(conventions.Patterns.ResourceAssemblies)
                         .OrderBy(group => ((NuGetFramework)group.Properties["tfm"]).GetShortFolderName())
                         .ToList();

            // Assert
            Assert.Equal(1, groups.Count);
            Assert.Equal(FrameworkConstants.CommonFrameworks.DotNet, (NuGetFramework)groups[0].Properties["tfm"]);
        }
        public void ContentModel_AnyTFMDefaultsToAnyandAnyRIDisAnyRID()
        {
            // Arrange
            var conventions = new ManagedCodeConventions(
                new RuntimeGraph(
                    new List <CompatibilityProfile>()
            {
                new CompatibilityProfile("net46.app")
            }));

            var collection = new ContentItemCollection();
            var rid        = "any";

            collection.Load(new string[]
            {
                $"tools/any/{rid}/a.dll",
            });

            // Act
            var groups = collection.FindItemGroups(conventions.Patterns.ToolsAssemblies)
                         .ToList();

            // Assert
            Assert.Equal(1, groups.Count);
            Assert.Equal(NuGetFramework.AnyFramework, (NuGetFramework)groups.First().Properties["tfm"]);
            Assert.Equal(rid, groups.First().Properties["rid"]);
        }
        public void ContentModel_NoTFMAndRuntimeIdentifierNoMatch()
        {
            // Arrange
            var conventions = new ManagedCodeConventions(
                new RuntimeGraph(
                    new List <CompatibilityProfile>()
            {
                new CompatibilityProfile("net46.app")
            }));

            var collection = new ContentItemCollection();

            collection.Load(new string[]
            {
                "tools/a.dll",
            });

            // Act
            var groups = collection.FindItemGroups(conventions.Patterns.ToolsAssemblies)
                         .Select(group => ((NuGetFramework)group.Properties["tfm"]))
                         .ToList();

            // Assert
            Assert.Equal(0, groups.Count);
        }
Esempio n. 11
0
        private static HashSet <FrameworkRuntimePair> GetAvailableFrameworkRuntimePairs(CompatibilityData compatibilityData, RestoreTargetGraph graph)
        {
            var available = new HashSet <FrameworkRuntimePair>();

            var contentItems = new ContentItemCollection();

            contentItems.Load(compatibilityData.Files);


            if (compatibilityData.TargetLibrary.PackageType.Contains(PackageType.DotnetTool))
            {
                foreach (var group in contentItems.FindItemGroups(graph.Conventions.Patterns.ToolsAssemblies))
                {
                    group.Properties.TryGetValue(ManagedCodeConventions.PropertyNames.RuntimeIdentifier, out var ridObj);
                    group.Properties.TryGetValue(ManagedCodeConventions.PropertyNames.TargetFrameworkMoniker, out var tfmObj);

                    var tfm = tfmObj as NuGetFramework;
                    var rid = ridObj as string;
                    if (tfm?.IsSpecificFramework == true)
                    {
                        available.Add(new FrameworkRuntimePair(tfm, rid));
                    }
                }
            }

            return(available);
        }
Esempio n. 12
0
        public void ContentModel_LibRootAndTFM()
        {
            // Arrange
            var conventions = new ManagedCodeConventions(
                new RuntimeGraph(
                    new List <CompatibilityProfile>()
            {
                new CompatibilityProfile("net46.app")
            }));

            var collection = new ContentItemCollection();

            collection.Load(new string[]
            {
                "lib/net46/a.dll",
                "lib/a.dll",
            });

            // Act
            var groups = collection.FindItemGroups(conventions.Patterns.RuntimeAssemblies)
                         .OrderBy(group => ((NuGetFramework)group.Properties["tfm"]).GetShortFolderName())
                         .ToList();

            // Assert
            Assert.Equal(2, groups.Count);
            Assert.Equal(NuGetFramework.Parse("net"), groups[0].Properties["tfm"]);
            Assert.Equal(NuGetFramework.Parse("net46"), groups[1].Properties["tfm"]);
        }
Esempio n. 13
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);
        }
Esempio n. 14
0
        private static List <NuGetFramework> GetPackageFrameworks(
            CompatibilityData compatibilityData,
            RestoreTargetGraph graph)
        {
            var available = new HashSet <NuGetFramework>();

            var contentItems = new ContentItemCollection();

            contentItems.Load(compatibilityData.Files);

            var patterns = new[]
            {
                graph.Conventions.Patterns.ResourceAssemblies,
                graph.Conventions.Patterns.CompileRefAssemblies,
                graph.Conventions.Patterns.RuntimeAssemblies,
                graph.Conventions.Patterns.EmbedAssemblies,
                graph.Conventions.Patterns.ContentFiles
            };

            foreach (var pattern in patterns)
            {
                foreach (var group in contentItems.FindItemGroups(pattern))
                {
                    // lib/net45/subfolder/a.dll will be returned as a group with zero items since sub
                    // folders are not allowed. Completely empty groups are not compatible, a group with
                    // _._ would contain _._ as an item.
                    if (group.Items.Count > 0)
                    {
                        group.Properties.TryGetValue(ManagedCodeConventions.PropertyNames.RuntimeIdentifier, out var ridObj);
                        group.Properties.TryGetValue(ManagedCodeConventions.PropertyNames.TargetFrameworkMoniker, out var tfmObj);

                        var tfm = tfmObj as NuGetFramework;

                        // RID specific items should be ignored here since they are only used in the runtime assembly check
                        if (ridObj == null && tfm?.IsSpecificFramework == true)
                        {
                            available.Add(tfm);
                        }
                    }
                }
            }

            return(available.ToList());
        }
Esempio n. 15
0
        public void ContentFiles_BasicContentModelCheck()
        {
            // Arrange
            var conventions = new ManagedCodeConventions(
                new RuntimeGraph(
                    new List <CompatibilityProfile>()
            {
                new CompatibilityProfile("net46.app")
            }));

            var criteria = conventions.Criteria.ForFramework(NuGetFramework.Parse("net46"));

            var collection = new ContentItemCollection();

            collection.Load(new string[]
            {
                "contentFiles/any/net45/config1.xml",
                "contentFiles/cs/net45/config2.xml",
                "contentFiles/vb/net45/config3.xml",
                "contentFiles/any/uap/config4.xml",
                "contentFiles/cs/uap/config5.xml",
                "contentFiles/vb/uap/config6.xml"
            });

            // Act
            var contentFileGroups = collection.FindItemGroups(conventions.Patterns.ContentFiles);

            // Assert
            Assert.Equal(6, contentFileGroups.Count());

            Assert.Equal("any|cs|vb", string.Join("|",
                                                  contentFileGroups.Select(group =>
                                                                           group.Properties[ManagedCodeConventions.PropertyNames.CodeLanguage])
                                                  .Distinct()
                                                  .OrderBy(s => s)));

            Assert.Equal("net45|uap", string.Join("|",
                                                  contentFileGroups.Select(group =>
                                                                           group.Properties[ManagedCodeConventions.PropertyNames.TargetFrameworkMoniker] as NuGetFramework)
                                                  .Select(f => f.GetShortFolderName())
                                                  .Distinct()
                                                  .OrderBy(s => s)));
        }
        public void ContentModel_BuildNoFilesAtRoot()
        {
            // Arrange
            var conventions = new ManagedCodeConventions(
                new RuntimeGraph(
                    new List <CompatibilityProfile>()
            {
                new CompatibilityProfile("net46.app")
            }));

            var collection = new ContentItemCollection();

            collection.Load(new string[]
            {
                "build/net46/packageA.targets",
                "build/net45/packageA.targets",
                "build/net35/packageA.targets",
                "build/net20/packageA.targets",
                "build/uap10.0/packageA.targets",
            });

            // Act
            var groups = collection.FindItemGroups(conventions.Patterns.MSBuildFiles)
                         .OrderBy(group => ((NuGetFramework)group.Properties["tfm"]).GetShortFolderName())
                         .ToList();

            // Assert
            Assert.Equal(5, groups.Count());
            Assert.Equal(NuGetFramework.Parse("net20"), groups[0].Properties["tfm"] as NuGetFramework);
            Assert.Equal(NuGetFramework.Parse("net35"), groups[1].Properties["tfm"] as NuGetFramework);
            Assert.Equal(NuGetFramework.Parse("net45"), groups[2].Properties["tfm"] as NuGetFramework);
            Assert.Equal(NuGetFramework.Parse("net46"), groups[3].Properties["tfm"] as NuGetFramework);
            Assert.Equal(NuGetFramework.Parse("uap10.0"), groups[4].Properties["tfm"] as NuGetFramework);

            Assert.Equal("build/net20/packageA.targets", groups[0].Items.Single().Path);
            Assert.Equal("build/net35/packageA.targets", groups[1].Items.Single().Path);
            Assert.Equal("build/net45/packageA.targets", groups[2].Items.Single().Path);
            Assert.Equal("build/net46/packageA.targets", groups[3].Items.Single().Path);
            Assert.Equal("build/uap10.0/packageA.targets", groups[4].Items.Single().Path);
        }
Esempio n. 17
0
        private static List <NuGetFramework> GetPackageFrameworks(
            CompatibilityData compatibilityData,
            RestoreTargetGraph graph)
        {
            var available = new HashSet <NuGetFramework>();

            var contentItems = new ContentItemCollection();

            contentItems.Load(compatibilityData.Files);

            var patterns = new[]
            {
                graph.Conventions.Patterns.ResourceAssemblies,
                graph.Conventions.Patterns.CompileRefAssemblies,
                graph.Conventions.Patterns.RuntimeAssemblies,
                graph.Conventions.Patterns.ContentFiles
            };

            foreach (var pattern in patterns)
            {
                foreach (var group in contentItems.FindItemGroups(pattern))
                {
                    object tfmObj = null;
                    object ridObj = null;
                    group.Properties.TryGetValue(ManagedCodeConventions.PropertyNames.RuntimeIdentifier, out ridObj);
                    group.Properties.TryGetValue(ManagedCodeConventions.PropertyNames.TargetFrameworkMoniker, out tfmObj);

                    NuGetFramework tfm = tfmObj as NuGetFramework;

                    // RID specific items should be ignored here since they are only used in the runtime assem check
                    if (ridObj == null && tfm?.IsSpecificFramework == true)
                    {
                        available.Add(tfm);
                    }
                }
            }

            return(available.ToList());
        }
Esempio n. 18
0
        public void ContentFiles_BasicContentModelSubFolders()
        {
            // Arrange
            var conventions = new ManagedCodeConventions(
                new RuntimeGraph(
                    new List <CompatibilityProfile>()
            {
                new CompatibilityProfile("net46.app")
            }));

            var criteria = conventions.Criteria.ForFramework(NuGetFramework.Parse("net46"));

            var collection = new ContentItemCollection();

            collection.Load(new string[]
            {
                "contentFiles/any/net45/config1.xml",
                "contentFiles/any/net45/folder/a/b/c/config2.xml",
            });

            // Act
            var contentFileGroups = collection.FindItemGroups(conventions.Patterns.ContentFiles);

            // Assert
            Assert.Equal(1, contentFileGroups.Count());
            Assert.Equal(2, contentFileGroups.Single().Items.Count);

            Assert.Equal("any", contentFileGroups.Select(group =>
                                                         (string)group.Properties[ManagedCodeConventions.PropertyNames.CodeLanguage])
                         .Single());

            Assert.Equal("contentFiles/any/net45/config1.xml|contentFiles/any/net45/folder/a/b/c/config2.xml",
                         string.Join("|",
                                     contentFileGroups.SelectMany(group => group.Items)
                                     .Select(item => item.Path)
                                     .OrderBy(s => s)));
        }
        public void ContentModel_Net46TFMAndAnyRIDisAnyRID()
        {
            // Arrange
            var conventions = new ManagedCodeConventions(
                new RuntimeGraph(
                    new List <CompatibilityProfile>()
            {
                new CompatibilityProfile("net46.app")
            }));

            var collection = new ContentItemCollection();
            var rid        = "any";

            collection.Load(new string[]
            {
                $"tools/net46/{rid}/a.dll",
            });

            // Arrange
            var criteria = conventions.Criteria.ForFrameworkAndRuntime(NuGetFramework.Parse("net46"), rid);

            // Act
            var group = collection.FindBestItemGroup(criteria, conventions.Patterns.ToolsAssemblies);

            // Assert
            Assert.Equal(FrameworkConstants.CommonFrameworks.Net46, (NuGetFramework)group.Properties["tfm"]);
            Assert.Equal(rid, group.Properties["rid"]);

            // Act
            var groups = collection.FindItemGroups(conventions.Patterns.ToolsAssemblies)
                         .ToList();

            // Assert
            Assert.Equal(1, groups.Count);
            Assert.Equal(FrameworkConstants.CommonFrameworks.Net46, (NuGetFramework)groups.First().Properties["tfm"]);
            Assert.Equal(rid, groups.First().Properties["rid"]);
        }
Esempio n. 20
0
 internal static IEnumerable <ContentItemGroup> GetContentForPattern(ContentItemCollection collection, PatternSet pattern)
 {
     return(collection.FindItemGroups(pattern));
 }
Esempio n. 21
0
        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
            var compileGroup = GetLockFileItems(
                orderedCriteria,
                contentItems,
                targetGraph.Conventions.Patterns.CompileAssemblies,
                targetGraph.Conventions.Patterns.RuntimeAssemblies);

            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);

            // 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
            if ((dependencyType & LibraryIncludeFlags.Runtime) == LibraryIncludeFlags.None)
            {
                ClearIfExists(lockFileLib.RuntimeAssemblies);
                lockFileLib.FrameworkAssemblies.Clear();
                lockFileLib.ResourceAssemblies.Clear();
            }

            if ((dependencyType & LibraryIncludeFlags.Compile) == LibraryIncludeFlags.None)
            {
                ClearIfExists(lockFileLib.CompileTimeAssemblies);
            }

            if ((dependencyType & LibraryIncludeFlags.Native) == LibraryIncludeFlags.None)
            {
                ClearIfExists(lockFileLib.NativeLibraries);
            }

            if ((dependencyType & LibraryIncludeFlags.ContentFiles) == LibraryIncludeFlags.None &&
                GroupHasNonEmptyItems(lockFileLib.ContentFiles))
            {
                // Empty lock file items still need lock file properties for language, action, and output.
                lockFileLib.ContentFiles.Clear();
                lockFileLib.ContentFiles.Add(ContentFileUtils.CreateEmptyItem());
            }

            return(lockFileLib);
        }
        public NugetRepositoryEntry ResolveGroups(LocalPackageSourceInfo localPackageSourceInfo)
        {
            var collection = new ContentItemCollection();

            collection.Load(localPackageSourceInfo.Package.Files);
            var allPackageDependencyGroups = localPackageSourceInfo.Package.Nuspec.GetDependencyGroups().ToArray();
            var frameworkReferenceGroups   = localPackageSourceInfo.Package.Nuspec.GetFrameworkRefGroups().ToArray();

            var entry = new NugetRepositoryEntry(localPackageSourceInfo);

            foreach (var target in _targets)
            {
                SelectionCriteria criteria = _conventions.Criteria.ForFrameworkAndRuntime(target.Framework, target.RuntimeIdentifier);

                // The nunit3testadapter package publishes dll's in build/
                var buildAssemblies = new PatternSet(_conventions.Properties, new[]
                {
                    new PatternDefinition("build/{tfm}/{any?}"),
                    new PatternDefinition("build/{assembly?}")
                }, new[]
                {
                    new PatternDefinition("build/{tfm}/{assembly}"),
                    new PatternDefinition("build/{assembly}")
                });

                // shipped debug binaries
                var netcoreappdebugAssemblies = new PatternSet(_conventions.Properties, new[]
                {
                    new PatternDefinition("netcoreappdebug/{tfm}/{any?}"),
                    new PatternDefinition("netcoreappdebug/{assembly?}")
                }, new[]
                {
                    new PatternDefinition("netcoreappdebug/{tfm}/{assembly}"),
                    new PatternDefinition("netcoreappdebug/{assembly}")
                });

                // The analyzer dll's are published in analyzers/ or analyzers/dotnet/cs/
                var analyzerAssemblies = new PatternSet(_conventions.Properties, new []
                {
                    new PatternDefinition("analyzers/dotnet/cs/{assembly?}"),
                    new PatternDefinition("analyzers/{assembly?}")
                }, new []
                {
                    new PatternDefinition("analyzers/dotnet/cs/{assembly}"),
                    new PatternDefinition("analyzers/{assembly}")
                });

                AddIfNotNull(entry.RefItemGroups, target.Framework,
                             collection.FindBestItemGroup(criteria,
                                                          _conventions.Patterns.CompileRefAssemblies,
                                                          _conventions.Patterns.CompileLibAssemblies)
                             ?.Items);

                AddIfNotNull(entry.RuntimeItemGroups, target.Framework,
                             collection.FindBestItemGroup(criteria,
                                                          _conventions.Patterns.RuntimeAssemblies,
                                                          _conventions.Patterns.NativeLibraries,
                                                          buildAssemblies)
                             ?.Items.Where(IsDll));

                AddIfNotNull(entry.DebugRuntimeItemGroups, target.Framework,
                             collection.FindItemGroups(netcoreappdebugAssemblies)
                             .SingleOrDefault()
                             ?.Items.Where(IsDll));

                AddIfNotNull(entry.ContentFileGroups, target.Framework,
                             collection.FindBestItemGroup(criteria,
                                                          _conventions.Patterns.ContentFiles)
                             ?.Items);

                AddIfNotNull(entry.AnalyzerItemGroups, target.Framework,
                             collection.FindItemGroups(analyzerAssemblies)
                             .SingleOrDefault()
                             ?.Items);

                // Merge FrameworkReferences with normal PackageReferences
                var dependencies = NuGetFrameworkUtility.GetNearest(allPackageDependencyGroups, target.Framework);
                var frameworks   = NuGetFrameworkUtility.GetNearest(frameworkReferenceGroups, target.Framework);

                if (dependencies != null || frameworks != null)
                {
                    entry.DependencyGroups.Add(new PackageDependencyGroup(
                                                   dependencies?.TargetFramework ?? frameworks?.TargetFramework,
                                                   new[]
                    {
                        frameworks?.FrameworkReferences.Select(FrameworkDependencyResolver.ConvertToDependency),
                        dependencies?.Packages,
                    }
                                                   .SelectMany(v => v ?? Array.Empty <PackageDependency>())));
                }
            }

            return(entry);
        private MSBuildRestoreResult RestoreMSBuildFiles(PackageSpec project,
                                                         IEnumerable <RestoreTargetGraph> targetGraphs,
                                                         NuGetv3LocalRepository repository,
                                                         RemoteWalkContext context)
        {
            // Get the project graph
            var projectFrameworks = project.TargetFrameworks.Select(f => f.FrameworkName).ToList();

            // Non-Msbuild projects should skip targets and treat it as success
            if (!context.IsMsBuildBased)
            {
                return(new MSBuildRestoreResult(project.Name, project.BaseDirectory, success: true));
            }

            // Invalid msbuild projects should write out an msbuild error target
            if (projectFrameworks.Count != 1 ||
                !targetGraphs.Any())
            {
                return(new MSBuildRestoreResult(project.Name, project.BaseDirectory, success: false));
            }

            // Gather props and targets to write out
            var graph = targetGraphs
                        .Single(g => g.Framework.Equals(projectFrameworks[0]) && string.IsNullOrEmpty(g.RuntimeIdentifier));

            var pathResolver = new VersionFolderPathResolver(repository.RepositoryRoot);

            var flattenedFlags = IncludeFlagUtils.FlattenDependencyTypes(_includeFlagGraphs, _request.Project, graph);

            var targets = new List <string>();
            var props   = new List <string>();

            foreach (var library in graph.Flattened
                     .Distinct()
                     .OrderBy(g => g.Data.Match.Library))
            {
                var includeLibrary = true;

                LibraryIncludeFlags libraryFlags;
                if (flattenedFlags.TryGetValue(library.Key.Name, out libraryFlags))
                {
                    includeLibrary = libraryFlags.HasFlag(LibraryIncludeFlags.Build);
                }

                // Skip libraries that do not include build files such as transitive packages
                if (includeLibrary)
                {
                    var            packageIdentity = new PackageIdentity(library.Key.Name, library.Key.Version);
                    IList <string> packageFiles;
                    context.PackageFileCache.TryGetValue(packageIdentity, out packageFiles);

                    if (packageFiles != null)
                    {
                        var contentItemCollection = new ContentItemCollection();
                        contentItemCollection.Load(packageFiles);

                        // Find MSBuild thingies
                        var groups = contentItemCollection.FindItemGroups(graph.Conventions.Patterns.MSBuildFiles);

                        // Find the nearest msbuild group, this can include the root level Any group.
                        var buildItems = NuGetFrameworkUtility.GetNearest(
                            groups,
                            graph.Framework,
                            group =>
                            group.Properties[ManagedCodeConventions.PropertyNames.TargetFrameworkMoniker]
                            as NuGetFramework);

                        if (buildItems != null)
                        {
                            // We need to additionally filter to items that are named "{packageId}.targets" and "{packageId}.props"
                            // Filter by file name here and we'll filter by extension when we add things to the lists.
                            var items = buildItems.Items
                                        .Where(item =>
                                               Path.GetFileNameWithoutExtension(item.Path)
                                               .Equals(library.Key.Name, StringComparison.OrdinalIgnoreCase))
                                        .ToList();

                            targets.AddRange(items
                                             .Where(c => Path.GetExtension(c.Path).Equals(".targets", StringComparison.OrdinalIgnoreCase))
                                             .Select(c =>
                                                     Path.Combine(pathResolver.GetPackageDirectory(library.Key.Name, library.Key.Version),
                                                                  c.Path.Replace('/', Path.DirectorySeparatorChar))));

                            props.AddRange(items
                                           .Where(c => Path.GetExtension(c.Path).Equals(".props", StringComparison.OrdinalIgnoreCase))
                                           .Select(c =>
                                                   Path.Combine(pathResolver.GetPackageDirectory(library.Key.Name, library.Key.Version),
                                                                c.Path.Replace('/', Path.DirectorySeparatorChar))));
                        }
                    }
                }
            }

            return(new MSBuildRestoreResult(project.Name, project.BaseDirectory, repository.RepositoryRoot, props, targets));
        }
        /// <summary>
        /// This method combines the logic used in restore operations to make a determination about the TFM supported by the package.
        /// We have curated a set of compatibility requirements for our needs in NuGet.org. The client logic can be found here:
        /// https://github.com/NuGet/NuGet.Client/blob/63255047fe7052cc33b763356ff995d9166f719e/src/NuGet.Core/NuGet.Commands/RestoreCommand/CompatibilityChecker.cs#L252-L294
        /// https://github.com/NuGet/NuGet.Client/blob/63255047fe7052cc33b763356ff995d9166f719e/src/NuGet.Core/NuGet.Commands/RestoreCommand/CompatibilityChecker.cs#L439-L442
        /// ...and our combination of these elements is below.
        /// The logic is essentially this:
        /// - Determine whether we're looking at a tools package. In this case we will use tools "pattern sets" (collections of file patterns
        ///   defined in <see cref="ManagedCodeConventions" />) to assess which frameworks are targeted by the package.
        /// - If this isn't a tools package, we look for build-time, runtime, content and resource file patterns
        /// For added details on the various cases, see unit tests targeting this method.
        /// </summary>
        public virtual IEnumerable <NuGetFramework> GetSupportedFrameworks(NuspecReader nuspecReader, IList <string> packageFiles)
        {
            var supportedTFMs = Enumerable.Empty <NuGetFramework>();

            if (packageFiles != null && packageFiles.Any() && nuspecReader != null)
            {
                // Setup content items for analysis
                var items = new ContentItemCollection();
                items.Load(packageFiles);
                var runtimeGraph = new RuntimeGraph();
                var conventions  = new ManagedCodeConventions(runtimeGraph);

                // Let's test for tools packages first--they're a special case
                var groups       = Enumerable.Empty <ContentItemGroup>();
                var packageTypes = nuspecReader.GetPackageTypes();
                if (packageTypes.Count == 1 && (packageTypes[0] == PackageType.DotnetTool ||
                                                packageTypes[0] == PackageType.DotnetCliTool))
                {
                    // Only a package that is a tool package (and nothing else) will be matched against tools pattern set
                    groups = items.FindItemGroups(conventions.Patterns.ToolsAssemblies);
                }
                else
                {
                    // Gather together a list of pattern sets indicating the kinds of packages we wish to evaluate
                    var patterns = new[]
                    {
                        conventions.Patterns.CompileRefAssemblies,
                        conventions.Patterns.CompileLibAssemblies,
                        conventions.Patterns.RuntimeAssemblies,
                        conventions.Patterns.ContentFiles,
                        conventions.Patterns.ResourceAssemblies,
                    };

                    // Add MSBuild to this list, but we need to ensure we have package assets before they make the cut.
                    // A series of files in the right places won't matter if there's no {id}.props|targets.
                    var msbuildPatterns = new[]
                    {
                        conventions.Patterns.MSBuildFiles,
                        conventions.Patterns.MSBuildMultiTargetingFiles,
                    };

                    // We'll create a set of "groups" --these are content items which satisfy file pattern sets
                    var standardGroups = patterns
                                         .SelectMany(p => items.FindItemGroups(p));

                    // Filter out MSBuild assets that don't match the package ID and append to groups we already have
                    var packageId     = nuspecReader.GetId();
                    var msbuildGroups = msbuildPatterns
                                        .SelectMany(p => items.FindItemGroups(p))
                                        .Where(g => HasBuildItemsForPackageId(g.Items, packageId));
                    groups = standardGroups.Concat(msbuildGroups);
                }

                // Now that we have a collection of groups which have made it through the pattern set filter, let's transform them into TFMs
                supportedTFMs = groups
                                .SelectMany(p => p.Properties)
                                .Where(pair => pair.Key == ManagedCodeConventions.PropertyNames.TargetFrameworkMoniker)
                                .Select(pair => pair.Value)
                                .Cast <NuGetFramework>()
                                .Distinct();
            }

            return(supportedTFMs);
        }