| File: BuildIntegration\BuildIntegratedRestoreUtility.cs | Web Access |
| Project: src\nuget-client\src\NuGet.Core\NuGet.PackageManagement\NuGet.PackageManagement.csproj (NuGet.PackageManagement) |
// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. #nullable disable using System; using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; using NuGet.Commands; using NuGet.LibraryModel; using NuGet.Packaging; using NuGet.Packaging.Core; using NuGet.ProjectManagement; using NuGet.ProjectManagement.Projects; using NuGet.ProjectModel; using NuGet.Shared; namespace NuGet.PackageManagement { /// <summary> /// Helper class for calling the RestoreCommand /// </summary> public static class BuildIntegratedRestoreUtility { public static async Task ExecuteInitPs1ScriptsAsync( BuildIntegratedNuGetProject project, IEnumerable<PackageIdentity> packages, FallbackPackagePathResolver pathResolver, INuGetProjectContext projectContext, CancellationToken token) { // Find all dependencies in sorted order var sortedPackages = await BuildIntegratedProjectUtility.GetOrderedProjectPackageDependencies(project); // Keep track of the packages that need to be executed. var packagesToExecute = new HashSet<PackageIdentity>(packages, PackageIdentity.Comparer); // Use the ordered packages to run init.ps1 for the specified packages. foreach (var package in sortedPackages) { if (packagesToExecute.Remove(package)) { var packageInstallPath = pathResolver.GetPackageDirectory(package.Id, package.Version); if (packageInstallPath == null) { continue; } await project .ProjectServices .ScriptService .ExecutePackageInitScriptAsync( package, packageInstallPath, projectContext, throwOnFailure: false, token: token); } } } /// <summary> /// Find all packages added to <paramref name="updatedLockFile"/>. /// </summary> public static IReadOnlyList<PackageIdentity> GetAddedPackages( LockFile originalLockFile, LockFile updatedLockFile) { IEnumerable<PackageIdentity> updatedPackages; if (updatedLockFile != null) { updatedPackages = updatedLockFile .Targets .SelectMany(target => target.Libraries) .Where(library => library.Type == LibraryType.Package) .Select(library => new PackageIdentity(library.Name, library.Version)); } else { updatedPackages = Enumerable.Empty<PackageIdentity>(); } IEnumerable<PackageIdentity> originalPackages; if (originalLockFile != null) { originalPackages = originalLockFile .Targets .SelectMany(target => target.Libraries) .Where(library => library.Type == LibraryType.Package) .Select(library => new PackageIdentity(library.Name, library.Version)); } else { originalPackages = Enumerable.Empty<PackageIdentity>(); } var results = updatedPackages .Except(originalPackages, PackageIdentity.Comparer) .ToList(); return results; } /// <summary> /// Find the list of parent projects which directly or indirectly reference the child project. /// </summary> public static IReadOnlyList<BuildIntegratedNuGetProject> GetParentProjectsInClosure( IReadOnlyList<BuildIntegratedNuGetProject> projects, BuildIntegratedNuGetProject target, DependencyGraphSpec cache) { if (projects == null) { throw new ArgumentNullException(nameof(projects)); } if (target == null) { throw new ArgumentNullException(nameof(target)); } if (cache == null) { throw new ArgumentNullException(nameof(cache)); } var listOfParents = cache.GetParents(target.MSBuildProjectPath); var parentNuGetprojects = new HashSet<BuildIntegratedNuGetProject>(); foreach (var parent in listOfParents) { // do not count the target as a parent var nugetProject = projects.FirstOrDefault(r => r.MSBuildProjectPath == parent); if (nugetProject != null && !nugetProject.Equals(target)) { parentNuGetprojects.Add(nugetProject); } } // sort parents by path to make this more deterministic during restores return parentNuGetprojects .OrderBy(parent => parent.MSBuildProjectPath, StringComparer.Ordinal) .ToList(); } public static void UpdatePackageReferenceMetadata( LockFile lockFile, FallbackPackagePathResolver pathResolver, PackageIdentity package) { var info = pathResolver.GetPackageInfo(package.Id, package.Version); if (info == null) { // don't do anything if package was not resolved on disk return; } var nuspecFilePath = info.PathResolver.GetManifestFilePath(package.Id, package.Version); var nuspecReader = new NuspecReader(nuspecFilePath); var developmentDependency = nuspecReader.GetDevelopmentDependency(); if (developmentDependency) { for (var i = 0; i < lockFile.PackageSpec.TargetFrameworks.Count; i++) { var frameworkInfo = lockFile.PackageSpec.TargetFrameworks[i]; var index = frameworkInfo.Dependencies.FirstIndex(dep => dep.Name.Equals(package.Id, StringComparison.OrdinalIgnoreCase)); var dependency = frameworkInfo.Dependencies[index]; if (dependency.SuppressParent == LibraryIncludeFlagUtils.DefaultSuppressParent && dependency.IncludeType == LibraryIncludeFlags.All) { var includeType = LibraryIncludeFlags.All & ~LibraryIncludeFlags.Compile; dependency = new LibraryDependency(dependency) { IncludeType = includeType, SuppressParent = LibraryIncludeFlags.All }; var newDependencies = frameworkInfo.Dependencies.SetItem(index, dependency); lockFile.PackageSpec.TargetFrameworks[i] = new TargetFrameworkInformation(frameworkInfo) { Dependencies = newDependencies }; // update lock file target libraries foreach (var target in lockFile.Targets .Where(t => EqualityUtility.EqualsWithNullCheck(t.TargetFramework, frameworkInfo.FrameworkName))) { var targetLibrary = target.GetTargetLibrary(package.Id); if (targetLibrary != null) { LockFileUtils.ExcludeItems(targetLibrary, includeType); } } } } } } } }