Пример #1
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).ToList();

            if (contentFileGroups.Count > 0)
            {
                // 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);
            }
        }
Пример #2
0
        private IReadOnlyList <RuntimeAssetGroup> CreateNativeLibraryGroups(LockFileTargetLibrary export)
        {
            List <RuntimeAssetGroup> nativeGroups = new List <RuntimeAssetGroup>();

            nativeGroups.Add(
                new RuntimeAssetGroup(
                    string.Empty,
                    export.NativeLibraries.FilterPlaceHolderFiles().Select(a => a.Path)));

            foreach (var runtimeTargetsGroup in export.GetRuntimeTargetsGroups("native"))
            {
                nativeGroups.Add(
                    new RuntimeAssetGroup(
                        runtimeTargetsGroup.Key,
                        runtimeTargetsGroup.Select(t => t.Path)));
            }

            return(nativeGroups);
        }
Пример #3
0
        public void HasCompileTimePlaceholderReturnsFalseIfEmpty()
        {
            var provider = new PackageDependencyProvider("/foo/packages", new FrameworkReferenceResolver("/foo/references"));
            var package  = new LockFilePackageLibrary();

            package.Name    = "Something";
            package.Version = NuGetVersion.Parse("1.0.0");

            var target = new LockFileTargetLibrary();

            target.Name    = "Something";
            target.Version = package.Version;

            var p1 = provider.GetDescription(NuGetFramework.Parse("net46"), package, target);

            Assert.False(p1.HasCompileTimePlaceholder);
            Assert.Equal(0, p1.CompileTimeAssemblies.Count());
            Assert.Equal(0, p1.RuntimeAssemblies.Count());
        }
Пример #4
0
        /// <summary>
        /// Get all content groups that have the nearest TxM
        /// </summary>
        internal static List <ContentItemGroup> GetContentGroupsForFramework(
            LockFileTargetLibrary lockFileLib,
            NuGetFramework framework,
            IEnumerable <ContentItemGroup> contentGroups)
        {
            var groups = new List <ContentItemGroup>();

            // Group by content by code language and find the nearest TxM under each language.
            var groupsByLanguage = new Dictionary <string, List <ContentItemGroup> >(StringComparer.OrdinalIgnoreCase);

            foreach (var group in contentGroups)
            {
                var codeLanguage = (string)group.Properties[ManagedCodeConventions.PropertyNames.CodeLanguage];

                List <ContentItemGroup> index;
                if (!groupsByLanguage.TryGetValue(codeLanguage, out index))
                {
                    index = new List <ContentItemGroup>(1);
                    groupsByLanguage.Add(codeLanguage, index);
                }

                index.Add(group);
            }

            // Find the nearest TxM within each language
            foreach (var codeLanguagePair in groupsByLanguage)
            {
                var languageGroups = codeLanguagePair.Value;

                var nearestGroup = NuGetFrameworkUtility.GetNearest <ContentItemGroup>(languageGroups, framework,
                                                                                       group =>
                                                                                       (NuGetFramework)group.Properties[ManagedCodeConventions.PropertyNames.TargetFrameworkMoniker]);

                // If a compatible group exists within the code language add it to the results
                if (nearestGroup != null)
                {
                    groups.Add(nearestGroup);
                }
            }

            return(groups);
        }
Пример #5
0
        private static void AddMSBuildAssets(
            LockFileLibrary library,
            RestoreTargetGraph targetGraph,
            LockFileTargetLibrary lockFileLib,
            IReadOnlyList <SelectionCriteria> orderedCriteria,
            ContentItemCollection contentItems,
            MaccatalystFallback maccatalystFallback)
        {
            // Build Transitive
            var btGroup = GetLockFileItems(
                orderedCriteria,
                contentItems,
                maccatalystFallback,
                targetGraph.Conventions.Patterns.MSBuildTransitiveFiles);

            var filteredBTGroup = GetBuildItemsForPackageId(btGroup, library.Name);

            lockFileLib.Build.AddRange(filteredBTGroup);

            // Build
            var buildGroup = GetLockFileItems(
                orderedCriteria,
                contentItems,
                maccatalystFallback,
                targetGraph.Conventions.Patterns.MSBuildFiles);

            // filter any build asset already being added as part of build transitive
            var filteredBuildGroup = GetBuildItemsForPackageId(buildGroup, library.Name).
                                     Where(buildItem => !filteredBTGroup.Any(
                                               btItem => Path.GetFileName(btItem.Path).Equals(Path.GetFileName(buildItem.Path), StringComparison.OrdinalIgnoreCase)));

            lockFileLib.Build.AddRange(filteredBuildGroup);

            // Build multi targeting
            var buildMultiTargetingGroup = GetLockFileItems(
                orderedCriteria,
                contentItems,
                maccatalystFallback,
                targetGraph.Conventions.Patterns.MSBuildMultiTargetingFiles);

            lockFileLib.BuildMultiTargeting.AddRange(GetBuildItemsForPackageId(buildMultiTargetingGroup, library.Name));
        }
Пример #6
0
        private void GetFileDependencies(LockFileTargetLibrary package, string targetName)
        {
            string packageId = $"{package.Name}/{package.Version.ToNormalizedString()}";

            // for each type of file group
            foreach (var fileGroup in (FileGroup[])Enum.GetValues(typeof(FileGroup)))
            {
                var filePathList = fileGroup.GetFilePathAndProperties(package);
                foreach (var entry in filePathList)
                {
                    string filePath = entry.Item1;
                    IDictionary <string, string> properties = entry.Item2;

                    if (NuGetUtils.IsPlaceholderFile(filePath))
                    {
                        continue;
                    }

                    var fileKey = $"{packageId}/{filePath}";
                    var item    = new TaskItem(fileKey);
                    item.SetMetadata(MetadataKeys.FileGroup, fileGroup.ToString());
                    item.SetMetadata(MetadataKeys.ParentTarget, targetName); // Foreign Key
                    item.SetMetadata(MetadataKeys.ParentPackage, packageId); // Foreign Key

                    if (fileGroup == FileGroup.FrameworkAssembly)
                    {
                        // NOTE: the path provided for framework assemblies is the name of the framework reference
                        item.SetMetadata("FrameworkAssembly", filePath);
                    }

                    foreach (var property in properties)
                    {
                        item.SetMetadata(property.Key, property.Value);
                    }

                    _fileDependencies.Add(item);

                    // map each file key to a Type metadata value
                    SaveFileKeyType(fileKey, fileGroup);
                }
            }
        }
Пример #7
0
        public void Equals_WithRuntimeAssembliesAndRelatedFiles(string left, string right, bool expected)
        {
            string[] leftParts           = left.Trim().Split(' ');
            var      leftRuntimeAssembly = new LockFileItem(leftParts[0]);

            if (leftParts.Length > 1)
            {
                leftRuntimeAssembly.Properties.Add("related", leftParts[1]);
            }
            var leftSide = new LockFileTargetLibrary()
            {
                RuntimeAssemblies = new List <LockFileItem>()
                {
                    leftRuntimeAssembly
                }
            };

            string[] rightParts           = right.Split(' ');
            var      rightRuntimeAssembly = new LockFileItem(rightParts[0]);

            if (rightParts.Length > 1)
            {
                rightRuntimeAssembly.Properties.Add("related", rightParts[1]);
            }
            var rightSide = new LockFileTargetLibrary()
            {
                RuntimeAssemblies = new List <LockFileItem>()
                {
                    rightRuntimeAssembly
                }
            };

            // Act & Assert
            if (expected)
            {
                leftSide.Should().Be(rightSide);
            }
            else
            {
                leftSide.Should().NotBe(rightSide);
            }
        }
Пример #8
0
        private static IEnumerable <String> GetSuitableFiles(
            NuGetFramework thisFramework,
            Lazy <RuntimeGraph> runtimeGraph,
            String runtimeIdentifier,
            LockFileTargetLibrary targetLibrary,
            Lazy <IDictionary <String, LockFileLibrary> > libraries
            )
        {
            var retVal = NuGetUtility.GetRuntimeAssembliesDelegate(runtimeGraph, runtimeIdentifier, targetLibrary, libraries);

            if (!retVal.Any() && libraries.Value.TryGetValue(targetLibrary.Name, out var lib))
            {
                // targetLibrary does not list stuff like build/net45/someassembly.dll
                // So let's do manual matching
                var fwGroups = lib.Files.Where(f =>
                {
                    return(f.StartsWith(PackagingConstants.Folders.Build, StringComparison.OrdinalIgnoreCase) &&
                           PackageHelper.IsAssembly(f) &&
                           Path.GetDirectoryName(f).Length > PackagingConstants.Folders.Build.Length + 1);
                }).GroupBy(f =>
                {
                    try
                    {
                        return(NuGetFramework.ParseFolder(f.Split('/')[1]));
                    }
                    catch
                    {
                        return(null);
                    }
                })
                               .Where(g => g.Key != null)
                               .Select(g => new FrameworkSpecificGroup(g.Key, g));

                var matchingGroup = NuGetFrameworkUtility.GetNearest(
                    fwGroups,
                    thisFramework,
                    g => g.TargetFramework);
                retVal = matchingGroup?.Items;
            }

            return(retVal);
        }
Пример #9
0
        public ToolRestoreResult(
            string toolName,
            bool success,
            LockFileTarget lockFileTarget,
            LockFileTargetLibrary fileTargetLibrary,
            string lockFilePath,
            LockFile lockFile,
            LockFile previousLockFile)
        {
            ToolName          = toolName;
            Success           = success;
            LockFileTarget    = lockFileTarget;
            FileTargetLibrary = fileTargetLibrary;
            LockFilePath      = lockFilePath;
            LockFile          = lockFile;
            PreviousLockFile  = previousLockFile;

            // "locked" property is not supported on tools
            RelockFile = false;
        }
Пример #10
0
 public TargetLibraryWithAssets(
     LibraryIdentity libraryIdentity,
     string sha512,
     string path,
     LockFileTargetLibrary lockFileLibrary,
     IEnumerable <ProjectLibraryDependency> dependencies,
     bool compatible,
     bool resolved,
     NuGetFramework framework = null)
     : base(
         libraryIdentity,
         sha512,
         path,
         dependencies: dependencies,
         framework: null,
         resolved: resolved,
         compatible: compatible)
 {
     TargetLibrary = lockFileLibrary;
 }
Пример #11
0
        private static Dependency ReportDependency(LockFileTargetLibrary projectLibrary, LockFileTarget lockFileTargetFramework, int indentLevel, Dependency dependency = null)
        {
            if (projectLibrary == null)
                return null;

            if (indentLevel == 1)
                dependency = new Dependency(projectLibrary.Name, projectLibrary.Version.OriginalVersion);

            // stringBuilder.Append(new string(' ', indentLevel * 2));
            // stringBuilder.AppendLine($"{projectLibrary.Name}, v{projectLibrary.Version}");

            foreach (var childDependency in projectLibrary.Dependencies)
            {
                var childLibrary = lockFileTargetFramework.Libraries.FirstOrDefault(library => library.Name == childDependency.Id);
                dependency.Children.Add(new Dependency(childDependency.Id, childDependency.VersionRange.MinVersion.OriginalVersion) { Parent = dependency.Name });
                ReportDependency(childLibrary, lockFileTargetFramework, indentLevel + 1, dependency);
            }

            return dependency;
        }
        public void HashCode_WithPackageType_IsIgnored()
        {
            var leftSide = new LockFileTargetLibrary()
            {
                PackageType = new List <PackageType>()
                {
                    PackageType.Dependency
                }
            };

            var rightSide = new LockFileTargetLibrary()
            {
                PackageType = new List <PackageType>()
                {
                    PackageType.DotnetCliTool
                }
            };

            leftSide.GetHashCode().Should().Be(rightSide.GetHashCode());
        }
Пример #13
0
        private static void AddFrameworkReferences(LockFileTargetLibrary lockFileLib, FrameworkName framework, IEnumerable <FrameworkAssemblyReference> frameworkAssemblies)
        {
            foreach (var assemblyReference in frameworkAssemblies)
            {
                if (!assemblyReference.SupportedFrameworks.Any() &&
                    !VersionUtility.IsDesktop(framework))
                {
                    // REVIEW: This isn't 100% correct since none *can* mean
                    // any in theory, but in practice it means .NET full reference assembly
                    // If there's no supported target frameworks and we're not targeting
                    // the desktop framework then skip it.

                    // To do this properly we'll need all reference assemblies supported
                    // by each supported target framework which isn't always available.
                    continue;
                }

                lockFileLib.FrameworkAssemblies.Add(assemblyReference.AssemblyName);
            }
        }
Пример #14
0
        private static void AddToolsAssets(LockFileLibrary library,
                                           LocalPackageInfo package,
                                           RestoreTargetGraph targetGraph,
                                           LibraryIncludeFlags dependencyType,
                                           LockFileTargetLibrary lockFileLib,
                                           NuGetFramework framework,
                                           string runtimeIdentifier,
                                           ContentItemCollection contentItems,
                                           NuspecReader nuspec,
                                           IReadOnlyList <SelectionCriteria> orderedCriteria,
                                           MaccatalystFallback maccatalystFallback)
        {
            var toolsGroup = GetLockFileItems(
                orderedCriteria,
                contentItems,
                maccatalystFallback,
                targetGraph.Conventions.Patterns.ToolsAssemblies);

            lockFileLib.ToolsAssemblies.AddRange(toolsGroup);
        }
Пример #15
0
        private string GetCommandFilePath(
            LockFile lockFile,
            LockFileTargetLibrary toolLibrary,
            LockFileItem runtimeAssembly)
        {
            var packageDirectory = lockFile.GetPackageDirectory(toolLibrary);

            if (packageDirectory == null)
            {
                throw new GracefulException(string.Format(
                                                LocalizableStrings.CommandAssembliesNotFound,
                                                toolLibrary.Name));
            }

            var filePath = Path.Combine(
                packageDirectory,
                PathUtility.GetPathWithDirectorySeparator(runtimeAssembly.Path));

            return(filePath);
        }
Пример #16
0
 public PackageDescription(
     string path,
     string hashPath,
     LockFilePackageLibrary package,
     LockFileTargetLibrary lockFileLibrary,
     IEnumerable <LibraryRange> dependencies,
     bool compatible,
     bool resolved)
     : base(
         new LibraryIdentity(package.Name, package.Version, LibraryType.Package),
         "sha512-" + package.Sha512,
         path,
         lockFileLibrary,
         dependencies,
         resolved: resolved,
         compatible: compatible,
         framework: null)
 {
     HashPath       = hashPath;
     PackageLibrary = package;
 }
Пример #17
0
        /// <summary>
        /// Apply filters from the references node in the nuspec.
        /// </summary>
        private static void ApplyReferenceFilter(LockFileTargetLibrary lockFileLib, NuGetFramework framework, NuspecReader nuspec)
        {
            if (lockFileLib.CompileTimeAssemblies.Count > 0 || lockFileLib.RuntimeAssemblies.Count > 0)
            {
                var groups = nuspec.GetReferenceGroups().ToList();

                if (groups.Count > 0)
                {
                    var referenceSet = groups.GetNearest(framework);
                    if (referenceSet != null)
                    {
                        var referenceFilter = new HashSet <string>(referenceSet.Items, StringComparer.OrdinalIgnoreCase);

                        // 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();
                    }
                }
            }
        }
Пример #18
0
        public static bool TryCreate(LockFileTargetLibrary lockFileLibrary, [NotNullWhen(returnValue: true)] out AssetsFileTargetLibrary?library)
        {
            AssetsFileLibraryType type;

            if (lockFileLibrary.Type == "package")
            {
                type = AssetsFileLibraryType.Package;
            }
            else if (lockFileLibrary.Type == "project")
            {
                type = AssetsFileLibraryType.Project;
            }
            else
            {
                library = null;
                return(false);
            }

            library = new AssetsFileTargetLibrary(lockFileLibrary, type);
            return(true);
        }
Пример #19
0
        private ToolConfiguration DeserializeToolConfiguration(LockFileTargetLibrary library)
        {
            var dotnetToolSettings = FindItemInTargetLibrary(library, ToolSettingsFileName);

            if (dotnetToolSettings == null)
            {
                throw new ToolConfigurationException(
                          CommonLocalizableStrings.MissingToolSettingsFile);
            }

            var toolConfigurationPath =
                PackageDirectory
                .WithSubDirectories(
                    Id.ToString(),
                    library.Version.ToNormalizedString())
                .WithFile(dotnetToolSettings.Path);

            var configuration = ToolConfigurationDeserializer.Deserialize(toolConfigurationPath.Value);

            return(configuration);
        }
Пример #20
0
        private LockFileTargetLibrary ReadTargetLibrary(string property, JToken json)
        {
            var library = new LockFileTargetLibrary();

            var parts = property.Split(new[] { '/' }, 2);

            library.Name = parts[0];
            if (parts.Length == 2)
            {
                library.Version = SemanticVersion.Parse(parts[1]);
            }

            library.Dependencies          = ReadObject(json["dependencies"] as JObject, ReadPackageDependency);
            library.FrameworkAssemblies   = new HashSet <string>(ReadArray(json["frameworkAssemblies"] as JArray, ReadFrameworkAssemblyReference), StringComparer.OrdinalIgnoreCase);
            library.RuntimeAssemblies     = ReadObject(json["runtime"] as JObject, ReadFileItem);
            library.CompileTimeAssemblies = ReadObject(json["compile"] as JObject, ReadFileItem);
            library.ResourceAssemblies    = ReadObject(json["resource"] as JObject, ReadFileItem);
            library.NativeLibraries       = ReadObject(json["native"] as JObject, ReadFileItem);

            return(library);
        }
Пример #21
0
        /// <summary>
        /// Includes implicit, explicit project references
        /// listed in the Dependencies section of the lock
        /// file.
        /// </summary>
        ///
        /// <exception cref="SwitcherException"/>
        ///
        /// <remarks>
        /// Implicit dependencies mean transitive.
        /// </remarks>
        public virtual void SwitchPkgDependency(ProjectReference reference, LockFileTargetLibrary library, string absolutePath)
        {
            /*
             * References can be represented by several values in
             * an ItemGroup, for example, when included using the
             * Condition attribute.
             */

            ICollection <ProjectItem> items = reference.MsbProject.GetItemsByEvaluatedInclude(library.Name);

            // Implicit.
            if (!items.Any())
            {
                base.AddReference(reference, Type, absolutePath, new Dictionary <string, string>(2)
                {
                    { "Name", library.Name }
                });
            }
            // Explicit.
            else
            {
                /*
                 * Re-creating an item can lead to the loss
                 * of user metadata; in order to avoid this,
                 * the item is redefined.
                 */

                foreach (ProjectItem item in items)
                {
                    item.ItemType = Type.ToString();

                    item.SetMetadataValue("Temp", item.EvaluatedInclude);
                    item.SetMetadataValue("Name", item.EvaluatedInclude);

                    item.UnevaluatedInclude = absolutePath;
                }

                MessageHelper.AddMessage(reference.DteProject.UniqueName, $"Dependency: {library.Name } has been switched. Type: { Type }", TaskErrorCategory.Message);
            }
        }
Пример #22
0
        private AssetsFileTargetLibrary(LockFileTargetLibrary library, AssetsFileLibraryType type)
        {
            Name    = library.Name;
            Version = library.Version.ToNormalizedString();
            Type    = type;

            Dependencies = library.Dependencies.Select(dep => dep.Id).ToImmutableArray();

            CompileTimeAssemblies = library.CompileTimeAssemblies
                                    .Select(a => a.Path)
                                    .Where(path => path != null)
                                    .Where(path => !IsPlaceholderFile(path))
                                    .ToImmutableArray();

            FrameworkAssemblies = library.FrameworkAssemblies.ToImmutableArray();

            ContentFiles = library.ContentFiles
                           .Where(file => !IsPlaceholderFile(file.Path))
                           .Select(file => new AssetsFileTargetLibraryContentFile(file))
                           .ToImmutableArray();

            return;
        public CommandSpec CreateCommandSpecFromLibrary(
            LockFileTargetLibrary toolLibrary,
            string commandName,
            IEnumerable <string> commandArguments,
            IEnumerable <string> allowedExtensions,
            string nugetPackagesRoot,
            CommandResolutionStrategy commandResolutionStrategy,
            string depsFilePath,
            string runtimeConfigPath)
        {
            Reporter.Verbose.WriteLine($"packagedcommandspecfactory: attempting to find command {commandName} in {toolLibrary.Name}");

            var toolAssembly = toolLibrary?.RuntimeAssemblies
                               .FirstOrDefault(r => Path.GetFileNameWithoutExtension(r.Path) == commandName);

            if (toolAssembly == null)
            {
                Reporter.Verbose.WriteLine($"packagedcommandspecfactory: failed to find toolAssembly for {commandName}");

                return(null);
            }

            var commandPath = GetCommandFilePath(nugetPackagesRoot, toolLibrary, toolAssembly);

            if (!File.Exists(commandPath))
            {
                Reporter.Verbose.WriteLine($"packagedcommandspecfactory: failed to find commandPath {commandPath}");

                return(null);
            }

            return(CreateCommandSpecWrappingWithMuxerIfDll(
                       commandPath,
                       commandArguments,
                       depsFilePath,
                       commandResolutionStrategy,
                       nugetPackagesRoot,
                       runtimeConfigPath));
        }
        public void Equals_WithType(string left, string right, bool expected)
        {
            var leftSide = new LockFileTargetLibrary()
            {
                Type = left
            };

            var rightSide = new LockFileTargetLibrary()
            {
                Type = right
            };

            // Act & Assert
            if (expected)
            {
                leftSide.Should().Be(rightSide);
            }
            else
            {
                leftSide.Should().NotBe(rightSide);
            }
        }
Пример #25
0
        public ProjectContext(LockFile lockFile, LockFileTarget lockFileTarget,
                              //  Trimmed from publish output, and if there are no runtimeFrameworks, written to runtimeconfig.json
                              LockFileTargetLibrary platformLibrary,
                              //  Written to runtimeconfig.json
                              RuntimeFramework[] runtimeFrameworks,
                              bool isFrameworkDependent)
        {
            Debug.Assert(lockFile != null);
            Debug.Assert(lockFileTarget != null);
            if (isFrameworkDependent)
            {
                Debug.Assert(platformLibrary != null ||
                             (runtimeFrameworks != null && runtimeFrameworks.Any()));
            }

            _lockFile       = lockFile;
            _lockFileTarget = lockFileTarget;

            PlatformLibrary      = platformLibrary;
            RuntimeFrameworks    = runtimeFrameworks;
            IsFrameworkDependent = isFrameworkDependent;
        }
        public void HashCode_WithFrameworkReferences(string left, string right, bool expected)
        {
            var leftSide = new LockFileTargetLibrary()
            {
                FrameworkReferences = left.Split(';').Select(e => e).ToList()
            };

            var rightSide = new LockFileTargetLibrary()
            {
                FrameworkReferences = right.Split(';').Select(e => e).ToList()
            };

            // Act & Assert
            if (expected)
            {
                leftSide.GetHashCode().Should().Be(rightSide.GetHashCode());
            }
            else
            {
                leftSide.GetHashCode().Should().NotBe(rightSide.GetHashCode());
            }
        }
        public void HashCode_WithFramework(string left, string right, bool expected)
        {
            var leftSide = new LockFileTargetLibrary()
            {
                Framework = left
            };

            var rightSide = new LockFileTargetLibrary()
            {
                Framework = right
            };

            // Act & Assert
            if (expected)
            {
                leftSide.GetHashCode().Should().Be(rightSide.GetHashCode());
            }
            else
            {
                leftSide.GetHashCode().Should().NotBe(rightSide.GetHashCode());
            }
        }
        public void HashCode_WithPackageDependency(string left, string right, bool expected)
        {
            var leftSide = new LockFileTargetLibrary()
            {
                Dependencies = left.Split(';').Select(e => new PackageDependency(e, VersionRange.Parse("1.0.0"))).ToList()
            };

            var rightSide = new LockFileTargetLibrary()
            {
                Dependencies = right.Split(';').Select(e => new PackageDependency(e, VersionRange.Parse("1.0.0"))).ToList()
            };

            // Act & Assert
            if (expected)
            {
                leftSide.GetHashCode().Should().Be(rightSide.GetHashCode());
            }
            else
            {
                leftSide.GetHashCode().Should().NotBe(rightSide.GetHashCode());
            }
        }
        private IEnumerable <string> ExtractDependencies(LockFile lockFile)
        {
            // Get the libraries to import for targeting netstandard2.0
            LockFileTarget netstandardTarget = lockFile.Targets
                                               .First(p => p.TargetFramework.Framework == NetStandardFramework &&
                                                      p.TargetFramework.Version == NetStandard20);

            // Collect all DLL files from CompileTimeAssemblies from that target
            // Note that we apply File.Exists since there may be muliple paths we're searching for each file listed
            List <string> dependencies = netstandardTarget.Libraries
                                         .SelectMany(p => p.CompileTimeAssemblies.Select(q => new
            {
                Library = p,
                Path    = q.Path.Replace('/', Path.DirectorySeparatorChar)
            }))
                                         .Where(p => Path.GetExtension(p.Path) == ".dll")
                                         .SelectMany(
                _ => lockFile.PackageFolders.Select(p => p.Path),
                (dependency, folder) =>
                Path.Combine(folder, dependency.Library.Name, dependency.Library.Version.ToString(), dependency.Path)
                )
                                         .Where(File.Exists)
                                         .ToList();

            // NETStandard.Library is a bit different, it has reference assemblies in the build/netstandard2.0/ref directory
            // which are imported via a MSBuild target file in the package. So we need to emulate that behavior here.

            LockFileTargetLibrary netstandardLibrary = netstandardTarget.Libraries.First(p => p.Name == NetStandardLibrary);

            string refDirectory = lockFile.PackageFolders.Select(p => p.Path)
                                  .Select(p => Path.Combine(p, netstandardLibrary.Name, netstandardLibrary.Version.ToString()))
                                  .First(Directory.Exists);

            refDirectory = Path.Combine(refDirectory, @"build\netstandard2.0\ref");

            dependencies.AddRange(Directory.EnumerateFiles(refDirectory, "*.dll"));

            return(dependencies);
        }
        public void HashCode_WithRuntimeTargets(string left, string right, bool expected)
        {
            var leftSide = new LockFileTargetLibrary()
            {
                RuntimeTargets = left.Split(';').Select(e => new LockFileRuntimeTarget(e)).ToList()
            };

            var rightSide = new LockFileTargetLibrary()
            {
                RuntimeTargets = right.Split(';').Select(e => new LockFileRuntimeTarget(e)).ToList()
            };

            // Act & Assert
            if (expected)
            {
                leftSide.GetHashCode().Should().Be(rightSide.GetHashCode());
            }
            else
            {
                leftSide.GetHashCode().Should().NotBe(rightSide.GetHashCode());
            }
        }