Пример #1
0
        public async Task NuGetv3LocalRepository_FindPackagesById_UsesProvidedIdCase()
        {
            // Arrange
            using (var workingDir = TestDirectory.Create())
            {
                var id     = "Foo";
                var target = new NuGetv3LocalRepository(workingDir);
                await SimpleTestPackageUtility.CreateFolderFeedV3(
                    workingDir,
                    PackageSaveMode.Defaultv3,
                    new SimpleTestPackageContext("foo", "1.0.0"));

                // Act
                var packages = target.FindPackagesById(id);

                // Assert
                Assert.Equal(1, packages.Count());
                Assert.Equal(id, packages.ElementAt(0).Id);
                Assert.Equal("1.0.0", packages.ElementAt(0).Version.ToNormalizedString());
            }
        }
Пример #2
0
        private void WriteLockFile(string projectLockFilePath, HashSet <Library> graphItems, NuGetv3LocalRepository repository)
        {
            var excludes = new[] { ".nuspec", ".nupkg", ".sha512" };

            var lockFile = new LockFile();

            lockFile.Islocked = false;
            foreach (var item in graphItems.OrderBy(x => x.Name))
            {
                var package = repository.FindPackagesById(item.Name).FirstOrDefault(p => p.Version == item.Version);

                if (package != null)
                {
                    NuspecReader nuspecReader = null;
                    using (var stream = File.OpenRead(package.ManifestPath))
                    {
                        nuspecReader = new NuspecReader(stream);
                    }

                    var library = new LockFileLibrary();
                    library.Name    = item.Name;
                    library.Version = item.Version;
                    library.FrameworkReferenceGroups = nuspecReader.GetFrameworkReferenceGroups().ToList();
                    library.ReferenceGroups          = nuspecReader.GetReferenceGroups().ToList();
                    library.DependencyGroups         = nuspecReader.GetDependencyGroups().ToList();
                    library.Files = Directory.EnumerateFiles(package.ExpandedPath, "*.*", SearchOption.AllDirectories)
                                    .Where(path => !excludes.Contains(Path.GetExtension(path)))
                                    .Select(path => path.Substring(package.ExpandedPath.Length).TrimStart(Path.DirectorySeparatorChar).Replace(Path.DirectorySeparatorChar, '/'))
                                    .ToList();

                    lockFile.Libraries.Add(library);
                }
            }

            var lockFileFormat = new LockFileFormat();

            lockFileFormat.Write(projectLockFilePath, lockFile);
        }
Пример #3
0
        private Task <RestoreTargetGraph[]> WalkRuntimeDependencies(LibraryRange projectRange, RestoreTargetGraph graph, RuntimeGraph projectRuntimeGraph, RemoteDependencyWalker walker, RemoteWalkContext context, NuGetv3LocalRepository localRepository)
        {
            // Load runtime specs
            _log.LogVerbose("Scanning packages for runtime.json files...");
            var runtimeGraph = projectRuntimeGraph;

            graph.Graph.ForEach(node =>
            {
                var match = node?.Item?.Data?.Match;
                if (match == null)
                {
                    return;
                }

                // Locate the package in the local repository
                var package = localRepository.FindPackagesById(match.Library.Name).FirstOrDefault(p => p.Version == match.Library.Version);
                if (package != null)
                {
                    var nextGraph = LoadRuntimeGraph(package);
                    if (nextGraph != null)
                    {
                        _log.LogVerbose($"Merging in runtimes defined in {match.Library}");
                        runtimeGraph = RuntimeGraph.Merge(runtimeGraph, nextGraph);
                    }
                }
            });

            var resultGraphs = new List <Task <RestoreTargetGraph> >();

            foreach (var runtimeName in projectRuntimeGraph.Runtimes.Keys)
            {
                _log.LogInformation($"Restoring packages for {graph.Framework} on {runtimeName}");
                resultGraphs.Add(WalkDependencies(projectRange, graph.Framework, runtimeName, runtimeGraph, walker, context));
            }

            return(Task.WhenAll(resultGraphs));
        }
Пример #4
0
        private LocalPackageInfo FindCandidate(string name, VersionRange versionRange)
        {
            var packages = _repository.FindPackagesById(name);

            return(packages.FindBestMatch(versionRange, info => info?.Version));
        }
Пример #5
0
        private LockFile CreateLockFile(PackageSpec project, List <RestoreTargetGraph> targetGraphs, NuGetv3LocalRepository repository)
        {
            var lockFile = new LockFile();

            using (var sha512 = SHA512.Create())
            {
                foreach (var item in targetGraphs.SelectMany(g => g.Flattened).Distinct().OrderBy(x => x.Data.Match.Library))
                {
                    var library     = item.Data.Match.Library;
                    var packageInfo = repository.FindPackagesById(library.Name)
                                      .FirstOrDefault(p => p.Version == library.Version);

                    if (packageInfo == null)
                    {
                        continue;
                    }

                    var lockFileLib = CreateLockFileLibrary(
                        packageInfo,
                        sha512,
                        correctedPackageName: library.Name);

                    lockFile.Libraries.Add(lockFileLib);
                }
            }

            // Use empty string as the key of dependencies shared by all frameworks
            lockFile.ProjectFileDependencyGroups.Add(new ProjectFileDependencyGroup(
                                                         string.Empty,
                                                         project.Dependencies.Select(x => x.LibraryRange.ToString())));

            foreach (var frameworkInfo in project.TargetFrameworks)
            {
                lockFile.ProjectFileDependencyGroups.Add(new ProjectFileDependencyGroup(
                                                             frameworkInfo.FrameworkName.ToString(),
                                                             frameworkInfo.Dependencies.Select(x => x.LibraryRange.ToString())));
            }

            // Add the targets
            foreach (var targetGraph in targetGraphs)
            {
                var target = new LockFileTarget();
                target.TargetFramework   = targetGraph.Framework;
                target.RuntimeIdentifier = targetGraph.RuntimeIdentifier;

                foreach (var library in targetGraph.Flattened.Select(g => g.Key).OrderBy(x => x))
                {
                    var packageInfo = repository.FindPackagesById(library.Name)
                                      .FirstOrDefault(p => p.Version == library.Version);

                    if (packageInfo == null)
                    {
                        continue;
                    }

                    var targetLibrary = CreateLockFileTargetLibrary(
                        packageInfo,
                        targetGraph,
                        new DefaultPackagePathResolver(repository.RepositoryRoot),
                        correctedPackageName: library.Name);

                    target.Libraries.Add(targetLibrary);
                }

                lockFile.Targets.Add(target);
            }

            return(lockFile);
        }
Пример #6
0
        public LockFile CreateLockFile(
            LockFile previousLockFile,
            PackageSpec project,
            IEnumerable <RestoreTargetGraph> targetGraphs,
            NuGetv3LocalRepository repository,
            RemoteWalkContext context,
            IEnumerable <ToolRestoreResult> toolRestoreResults)
        {
            var lockFile = new LockFile();

            lockFile.Version = _lockFileVersion;

            var resolver          = new VersionFolderPathResolver(repository.RepositoryRoot);
            var previousLibraries = previousLockFile?.Libraries.ToDictionary(l => Tuple.Create <string, NuGetVersion>(l.Name, l.Version));

            // Use empty string as the key of dependencies shared by all frameworks
            lockFile.ProjectFileDependencyGroups.Add(new ProjectFileDependencyGroup(
                                                         string.Empty,
                                                         project.Dependencies
                                                         .Select(group => group.LibraryRange.ToLockFileDependencyGroupString())
                                                         .OrderBy(group => group, StringComparer.Ordinal)));

            foreach (var frameworkInfo in project.TargetFrameworks
                     .OrderBy(framework => framework.FrameworkName.ToString(),
                              StringComparer.Ordinal))
            {
                lockFile.ProjectFileDependencyGroups.Add(new ProjectFileDependencyGroup(
                                                             frameworkInfo.FrameworkName.ToString(),
                                                             frameworkInfo.Dependencies
                                                             .Select(x => x.LibraryRange.ToLockFileDependencyGroupString())
                                                             .OrderBy(dependency => dependency, StringComparer.Ordinal)));
            }

            // Record all libraries used
            foreach (var item in targetGraphs.SelectMany(g => g.Flattened).Distinct()
                     .OrderBy(x => x.Data.Match.Library))
            {
                var library = item.Data.Match.Library;

                if (project.Name.Equals(library.Name, StringComparison.OrdinalIgnoreCase))
                {
                    // Do not include the project itself as a library.
                    continue;
                }

                if (library.Type == LibraryType.Project || library.Type == LibraryType.ExternalProject)
                {
                    // Project
                    LocalMatch localMatch = (LocalMatch)item.Data.Match;

                    var projectLib = new LockFileLibrary()
                    {
                        Name    = library.Name,
                        Version = library.Version,
                        Type    = LibraryType.Project,
                    };

                    // Set the relative path if a path exists
                    // For projects without project.json this will be empty
                    if (!string.IsNullOrEmpty(localMatch.LocalLibrary.Path))
                    {
                        projectLib.Path = PathUtility.GetRelativePath(
                            project.FilePath,
                            localMatch.LocalLibrary.Path,
                            '/');
                    }

                    // The msbuild project path if it exists
                    object msbuildPath;
                    if (localMatch.LocalLibrary.Items.TryGetValue(KnownLibraryProperties.MSBuildProjectPath, out msbuildPath))
                    {
                        var msbuildRelativePath = PathUtility.GetRelativePath(
                            project.FilePath,
                            (string)msbuildPath,
                            '/');

                        projectLib.MSBuildProject = msbuildRelativePath;
                    }

                    lockFile.Libraries.Add(projectLib);
                }
                else if (library.Type == LibraryType.Package)
                {
                    // Packages
                    var packageInfo = repository.FindPackagesById(library.Name)
                                      .FirstOrDefault(p => p.Version == library.Version);

                    if (packageInfo == null)
                    {
                        continue;
                    }

                    var sha512 = File.ReadAllText(resolver.GetHashPath(packageInfo.Id, packageInfo.Version));

                    LockFileLibrary previousLibrary = null;
                    previousLibraries?.TryGetValue(Tuple.Create(library.Name, library.Version), out previousLibrary);

                    var lockFileLib = previousLibrary;

                    // If we have the same library in the lock file already, use that.
                    if (previousLibrary == null || previousLibrary.Sha512 != sha512)
                    {
                        var path = resolver.GetPackageDirectory(packageInfo.Id, packageInfo.Version);
                        path = PathUtility.GetPathWithForwardSlashes(path);

                        lockFileLib = CreateLockFileLibrary(
                            packageInfo,
                            sha512,
                            path,
                            correctedPackageName: library.Name);
                    }
                    else if (Path.DirectorySeparatorChar != LockFile.DirectorySeparatorChar)
                    {
                        // Fix slashes for content model patterns
                        lockFileLib.Files = lockFileLib.Files
                                            .Select(p => p.Replace(Path.DirectorySeparatorChar, LockFile.DirectorySeparatorChar))
                                            .ToList();
                    }

                    lockFile.Libraries.Add(lockFileLib);

                    var packageIdentity = new PackageIdentity(lockFileLib.Name, lockFileLib.Version);
                    context.PackageFileCache.TryAdd(packageIdentity, lockFileLib.Files);
                }
            }

            var libraries = lockFile.Libraries.ToDictionary(lib => Tuple.Create(lib.Name, lib.Version));

            var warnForImports        = project.TargetFrameworks.Any(framework => framework.Warn);
            var librariesWithWarnings = new HashSet <LibraryIdentity>();

            // Add the targets
            foreach (var targetGraph in targetGraphs
                     .OrderBy(graph => graph.Framework.ToString(), StringComparer.Ordinal)
                     .ThenBy(graph => graph.RuntimeIdentifier, StringComparer.Ordinal))
            {
                var target = new LockFileTarget();
                target.TargetFramework   = targetGraph.Framework;
                target.RuntimeIdentifier = targetGraph.RuntimeIdentifier;

                var flattenedFlags = IncludeFlagUtils.FlattenDependencyTypes(_includeFlagGraphs, project, targetGraph);

                var fallbackFramework     = target.TargetFramework as FallbackFramework;
                var warnForImportsOnGraph = warnForImports && fallbackFramework != null;

                foreach (var graphItem in targetGraph.Flattened.OrderBy(x => x.Key))
                {
                    var library = graphItem.Key;

                    if (library.Type == LibraryType.Project || library.Type == LibraryType.ExternalProject)
                    {
                        if (project.Name.Equals(library.Name, StringComparison.OrdinalIgnoreCase))
                        {
                            // Do not include the project itself as a library.
                            continue;
                        }

                        var localMatch = (LocalMatch)graphItem.Data.Match;

                        // Target framework information is optional and may not exist for csproj projects
                        // that do not have a project.json file.
                        string projectFramework = null;
                        object frameworkInfoObject;
                        if (localMatch.LocalLibrary.Items.TryGetValue(
                                KnownLibraryProperties.TargetFrameworkInformation,
                                out frameworkInfoObject))
                        {
                            // Retrieve the resolved framework name, if this is null it means that the
                            // project is incompatible. This is marked as Unsupported.
                            var targetFrameworkInformation = (TargetFrameworkInformation)frameworkInfoObject;
                            projectFramework = targetFrameworkInformation.FrameworkName?.DotNetFrameworkName
                                               ?? NuGetFramework.UnsupportedFramework.DotNetFrameworkName;
                        }

                        // Create the target entry
                        var lib = new LockFileTargetLibrary()
                        {
                            Name      = library.Name,
                            Version   = library.Version,
                            Type      = LibraryType.Project,
                            Framework = projectFramework,

                            // Find all dependencies which would be in the nuspec
                            // Include dependencies with no constraints, or package/project/external
                            // Exclude suppressed dependencies, the top level project is not written
                            // as a target so the node depth does not matter.
                            Dependencies = graphItem.Data.Dependencies
                                           .Where(
                                d => (d.LibraryRange.TypeConstraintAllowsAnyOf(
                                          LibraryDependencyTarget.PackageProjectExternal)) &&
                                d.SuppressParent != LibraryIncludeFlags.All)
                                           .Select(d => GetDependencyVersionRange(d))
                                           .ToList()
                        };

                        object compileAssetObject;
                        if (localMatch.LocalLibrary.Items.TryGetValue(
                                KnownLibraryProperties.CompileAsset,
                                out compileAssetObject))
                        {
                            var item = new LockFileItem((string)compileAssetObject);
                            lib.CompileTimeAssemblies.Add(item);
                            lib.RuntimeAssemblies.Add(item);
                        }

                        // Add frameworkAssemblies for projects
                        object frameworkAssembliesObject;
                        if (localMatch.LocalLibrary.Items.TryGetValue(
                                KnownLibraryProperties.FrameworkAssemblies,
                                out frameworkAssembliesObject))
                        {
                            lib.FrameworkAssemblies.AddRange((List <string>)frameworkAssembliesObject);
                        }

                        target.Libraries.Add(lib);
                        continue;
                    }
                    else if (library.Type == LibraryType.Package)
                    {
                        var packageInfo = repository.FindPackagesById(library.Name)
                                          .FirstOrDefault(p => p.Version == library.Version);

                        if (packageInfo == null)
                        {
                            continue;
                        }

                        // include flags
                        LibraryIncludeFlags includeFlags;
                        if (!flattenedFlags.TryGetValue(library.Name, out includeFlags))
                        {
                            includeFlags = ~LibraryIncludeFlags.ContentFiles;
                        }

                        var targetLibrary = LockFileUtils.CreateLockFileTargetLibrary(
                            libraries[Tuple.Create(library.Name, library.Version)],
                            packageInfo,
                            targetGraph,
                            resolver,
                            correctedPackageName: library.Name,
                            dependencyType: includeFlags,
                            targetFrameworkOverride: null,
                            dependencies: graphItem.Data.Dependencies);

                        target.Libraries.Add(targetLibrary);

                        // Log warnings if the target library used the fallback framework
                        if (warnForImportsOnGraph && !librariesWithWarnings.Contains(library))
                        {
                            var nonFallbackFramework = new NuGetFramework(fallbackFramework);

                            var targetLibraryWithoutFallback = LockFileUtils.CreateLockFileTargetLibrary(
                                libraries[Tuple.Create(library.Name, library.Version)],
                                packageInfo,
                                targetGraph,
                                resolver,
                                correctedPackageName: library.Name,
                                targetFrameworkOverride: nonFallbackFramework,
                                dependencyType: includeFlags,
                                dependencies: graphItem.Data.Dependencies);

                            if (!targetLibrary.Equals(targetLibraryWithoutFallback))
                            {
                                var libraryName = $"{library.Name} {library.Version}";
                                _logger.LogWarning(string.Format(CultureInfo.CurrentCulture, Strings.Log_ImportsFallbackWarning, libraryName, String.Join(", ", fallbackFramework.Fallback), nonFallbackFramework));

                                // only log the warning once per library
                                librariesWithWarnings.Add(library);
                            }
                        }
                    }
                }

                lockFile.Targets.Add(target);
            }

            PopulateProjectFileToolGroups(project, lockFile);

            PopulateTools(toolRestoreResults, lockFile);

            return(lockFile);
        }
Пример #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);
            }
        }