private async Task GetPackageDependencies(PackageIdentity package, NuGetFramework framework, SourceCacheContext cacheContext, NuGet.Common.ILogger logger, IEnumerable <SourceRepository> repositories, ISet <SourcePackageDependencyInfo> availablePackages) { if (availablePackages.Any(x => x.Id == package.Id)) { return; } foreach (var sourceRepository in repositories) { var dependencyInfoResource = await sourceRepository.GetResourceAsync <DependencyInfoResource>(); var dependencyInfo = await dependencyInfoResource.ResolvePackage( package, framework, cacheContext, logger, CancellationToken.None); if (dependencyInfo == null) { continue; } availablePackages.Add(dependencyInfo); foreach (var dependency in dependencyInfo.Dependencies) { await GetPackageDependencies( new PackageIdentity(dependency.Id, dependency.VersionRange.MinVersion), framework, cacheContext, logger, repositories, availablePackages); } } }
/// <summary> /// This constructor is just used for testing. /// </summary> public VsPathContextProvider( ISettings settings, IVsSolutionManager solutionManager, NuGet.Common.ILogger logger, IVsProjectAdapterProvider vsProjectAdapterProvider, Func <string, LockFile> getLockFileOrNull) { if (settings == null) { throw new ArgumentNullException(nameof(settings)); } if (solutionManager == null) { throw new ArgumentNullException(nameof(solutionManager)); } if (logger == null) { throw new ArgumentNullException(nameof(logger)); } if (vsProjectAdapterProvider == null) { throw new ArgumentNullException(nameof(vsProjectAdapterProvider)); } _settings = new Lazy <ISettings>(() => settings); _solutionManager = new Lazy <IVsSolutionManager>(() => solutionManager); _logger = new Lazy <NuGet.Common.ILogger>(() => logger); _vsProjectAdapterProvider = new Lazy <IVsProjectAdapterProvider>(() => vsProjectAdapterProvider); _getLockFileOrNull = getLockFileOrNull ?? BuildIntegratedProjectUtility.GetLockFileOrNull; }
/// <summary> /// This constructor is just used for testing. /// </summary> public VsPathContextProvider( ISettings settings, IVsSolutionManager solutionManager, NuGet.Common.ILogger logger, Func <BuildIntegratedNuGetProject, Task <LockFile> > getLockFileOrNullAsync) { if (settings == null) { throw new ArgumentNullException(nameof(settings)); } if (solutionManager == null) { throw new ArgumentNullException(nameof(solutionManager)); } if (logger == null) { throw new ArgumentNullException(nameof(logger)); } _settings = new Lazy <ISettings>(() => settings); _solutionManager = new Lazy <IVsSolutionManager>(() => solutionManager); _logger = new Lazy <NuGet.Common.ILogger>(() => logger); _getLockFileOrNullAsync = getLockFileOrNullAsync ?? BuildIntegratedProjectUtility.GetLockFileOrNull; }
public VsSolutionRestoreService( IProjectSystemCache projectSystemCache, ISolutionRestoreWorker restoreWorker, [Import("VisualStudioActivityLogger")] NuGet.Common.ILogger logger) { if (projectSystemCache == null) { throw new ArgumentNullException(nameof(projectSystemCache)); } if (restoreWorker == null) { throw new ArgumentNullException(nameof(restoreWorker)); } if (logger == null) { throw new ArgumentNullException(nameof(logger)); } _projectSystemCache = projectSystemCache; _restoreWorker = restoreWorker; _logger = logger; }
public ModulePackageManager(IModuleProject project, IMemoryCache memoryCache, PackageLockRequestManager packageLockRequestManager, IOptions <ModulePackageManagerOptions> options, ILogger <ModulePackageManager> logger) { _project = project; _memoryCache = memoryCache; _packageLockRequestManager = packageLockRequestManager; _options = options.Value; _logger = new NuGetLoggerWrapper(logger); }
public NuGetService(IHubContext <DownloadPackageHub, IDownloadPackageHubClient> hubContext, ICompressService compressService, IHostEnvironment environment, IConfiguration configuration, ILogger <NuGetService> logger) { _downloadHubContext = hubContext; _compressService = compressService; _environment = environment; _configuration = configuration; _logger = logger; // get configure value MessageFrequency = _configuration.GetValue <int>("MessageFrequency"); }
private IEnumerable <NuGetVersion> GetVersions(string packageId, string sourceUrl = "https://chocolatey.org/api/v2/") { NuGet.Common.ILogger logger = NullLogger.Instance; CancellationToken cancellationToken = CancellationToken.None; SourceCacheContext cache = new SourceCacheContext(); PackageSource ps = new PackageSource(sourceUrl); var sourceRepository = Repository.Factory.GetCoreV2(ps); FindPackageByIdResource resource = sourceRepository.GetResourceAsync <FindPackageByIdResource>().GetAwaiter().GetResult(); IEnumerable <NuGetVersion> versions = resource.GetAllVersionsAsync(packageId, cache, logger, cancellationToken).GetAwaiter().GetResult(); return(versions); }
private DownloadResourceResult DownloadFromUrl( SourcePackageDependencyInfo package, DataServicePackageRepository repository, NuGet.Common.ILogger logger, CancellationToken token) { IPackage newPackage = null; var version = SemanticVersion.Parse(package.Version.ToString()); var cacheRepository = MachineCache.Default; try { // Try finding the package in the machine cache var localPackage = cacheRepository.FindPackage(package.Id, version) as OptimizedZipPackage; // Validate the package matches the hash if (localPackage != null && localPackage.IsValid && MatchPackageHash(localPackage, package.PackageHash)) { newPackage = localPackage; } } catch { // Ignore cache failures here to match NuGet.Core // The bad package will be deleted and replaced during the download. } // If the local package does not exist in the cache download it from the source if (newPackage == null) { newPackage = DownloadToMachineCache( cacheRepository, package, repository, package.DownloadUri, logger, token); } // Read the package from the machine cache if (newPackage != null) { return(new DownloadResourceResult(newPackage.GetStream())); } return(null); }
static async Task ResolvePackageDependencies( PackageIdentity package, NuGetFramework framework, SourceCacheContext cacheContext, NuGet.Common.ILogger logger, IEnumerable <SourceRepository> repositories, ConcurrentDictionary <PackageIdentity, SourcePackageDependencyInfo> availablePackages) { if (availablePackages.ContainsKey(package)) { return; } // TODO // Avoid getting info for e.g. netstandard1.x if our framework is highest (e.g. netstandard2.0) //if (framework.IsPackageBased && // package.Id.Equals("netstandard.library", StringComparison.OrdinalIgnoreCase) && // NuGetFrameworkUtility.IsCompatibleWithFallbackCheck(framework, // NuGetFramework.Parse($"netstandard{package.Version.Major}.{package.Version.Minor}"))) //{ // return; //} foreach (var sourceRepository in repositories) { var dependencyInfoResource = await sourceRepository.GetResourceAsync <DependencyInfoResource>(); var dependencyInfo = await dependencyInfoResource.ResolvePackage( package, framework, cacheContext, logger, CancellationToken.None); if (dependencyInfo == null) { continue; } // TODO: try add should be changed to console.writeline reporting if (availablePackages.TryAdd(new PackageIdentity(dependencyInfo.Id, dependencyInfo.Version), dependencyInfo)) { await Task.WhenAll(dependencyInfo.Dependencies.Select(dependency => { // recursive traversal of graph/tree return(ResolvePackageDependencies(new PackageIdentity(dependency.Id, dependency.VersionRange.MinVersion), framework, cacheContext, logger, repositories, availablePackages)); })); } } }
private async Task <PackageInfo> GetBestMatchPackageVersionsAsync(SourceRepository repository, string packageId, VersionRange range) { ILogger logger = NullLogger.Instance; CancellationToken cancellationToken = CancellationToken.None; SourceCacheContext cache = new SourceCacheContext(); FindPackageByIdResource resource = await repository.GetResourceAsync <FindPackageByIdResource>(); IEnumerable <NuGetVersion> versions = await resource.GetAllVersionsAsync( packageId, cache, logger, cancellationToken); NuGetVersion bestMatchVersion = range.FindBestMatch(versions); return(new PackageInfo { packageId = packageId, packageVersion = bestMatchVersion }); }
public async Task <IEnumerable <string> > SearchPackageAsync(string searchPackageName, string repositoryUrl, bool includePrerelease) { ILogger logger = NullLogger.Instance; CancellationToken cancellationToken = CancellationToken.None; SourceCacheContext cache = new SourceCacheContext(); SourceRepository repository = Repository.Factory.GetCoreV3(repositoryUrl); PackageSearchResource resource = await repository.GetResourceAsync <PackageSearchResource>(); SearchFilter searchFilter = new SearchFilter(includePrerelease: includePrerelease); IEnumerable <IPackageSearchMetadata> results = await resource.SearchAsync( searchPackageName, searchFilter, skip : 0, take : 10, logger, cancellationToken); return(results.Select(x => x.Identity.Id).AsEnumerable <string>()); }
/// <summary> /// This constructor is just used for testing. /// </summary> public VsPathContextProvider( ISettings settings, IVsSolutionManager solutionManager, NuGet.Common.ILogger logger, Func <BuildIntegratedNuGetProject, Task <LockFile> > getLockFileOrNullAsync) { if (settings == null) { throw new ArgumentNullException(nameof(settings)); } if (solutionManager == null) { throw new ArgumentNullException(nameof(solutionManager)); } if (logger == null) { throw new ArgumentNullException(nameof(logger)); } _settings = new Lazy <ISettings>(() => settings); _solutionManager = new Lazy <IVsSolutionManager>(() => solutionManager); _logger = new Lazy <NuGet.Common.ILogger>(() => logger); _getLockFileOrNullAsync = getLockFileOrNullAsync ?? BuildIntegratedProjectUtility.GetLockFileOrNull; _projectContext = new Lazy <INuGetProjectContext>(() => { var projectContext = new VSAPIProjectContext(); var signedPackageVerifier = new PackageSignatureVerifier(SignatureVerificationProviderFactory.GetSignatureVerificationProviders()); var adapterLogger = new LoggerAdapter(projectContext); projectContext.PackageExtractionContext = new PackageExtractionContext( PackageSaveMode.Defaultv2, PackageExtractionBehavior.XmlDocFileSaveMode, adapterLogger, signedPackageVerifier, SignedPackageVerifierSettings.GetClientPolicy(settings, adapterLogger)); return(projectContext); }); }
public void Commit(NuGet.Common.ILogger log) { if (!Success) { var name = $"{ProjectName}.nuget.targets"; var path = Path.Combine(ProjectDirectory, name); log.LogMinimal(string.Format(CultureInfo.CurrentCulture, Strings.Log_GeneratingMsBuildFile, name)); GenerateMSBuildErrorFile(path); } else { // Generate the files as needed var targetsName = $"{ProjectName}.nuget.targets"; var propsName = $"{ProjectName}.nuget.props"; var targetsPath = Path.Combine(ProjectDirectory, targetsName); var propsPath = Path.Combine(ProjectDirectory, propsName); if (Targets.Any()) { log.LogMinimal(string.Format(CultureInfo.CurrentCulture, Strings.Log_GeneratingMsBuildFile, targetsName)); GenerateImportsFile(targetsPath, Targets); } else if (File.Exists(targetsPath)) { File.Delete(targetsPath); } if (Props.Any()) { log.LogMinimal(string.Format(CultureInfo.CurrentCulture, Strings.Log_GeneratingMsBuildFile, propsName)); GenerateImportsFile(propsPath, Props); } else if (File.Exists(propsPath)) { File.Delete(propsPath); } } }
public async Task <IEnumerable <string> > GetPackageVersionAsync(string packageId, string repositoryUrl, bool includePrerelease) { ILogger logger = NullLogger.Instance; CancellationToken cancellationToken = CancellationToken.None; SourceCacheContext cache = new SourceCacheContext(); SourceRepository repository = Repository.Factory.GetCoreV3(repositoryUrl); FindPackageByIdResource resource = await repository.GetResourceAsync <FindPackageByIdResource>(); IEnumerable <NuGetVersion> versions = await resource.GetAllVersionsAsync( packageId, cache, logger, cancellationToken); if (includePrerelease == true) { return(versions.OrderByDescending(x => x).Select(x => x.ToNormalizedString()).AsEnumerable()); } else { return(versions.Where(x => x.IsPrerelease == false).OrderByDescending(x => x).Select(x => x.ToNormalizedString()).AsEnumerable()); } }
public override Task <DownloadResourceResult> GetDownloadResourceResultAsync( PackageIdentity identity, Configuration.ISettings settings, NuGet.Common.ILogger logger, CancellationToken token) { // settings are not used here, since, global packages folder are not used for v2 sources if (identity == null) { throw new ArgumentNullException(nameof(identity)); } if (logger == null) { throw new ArgumentNullException(nameof(logger)); } string displayUri = V2Client.Source; return(Task.Run(() => { token.ThrowIfCancellationRequested(); for (int i = 0; i < 3; i++) { try { var sourcePackage = identity as SourcePackageDependencyInfo; var repository = V2Client as DataServicePackageRepository; bool isFromUri = repository != null && sourcePackage?.PackageHash != null && sourcePackage?.DownloadUri != null; if (isFromUri) { // If this is a SourcePackageDependencyInfo object with everything populated // and it is from an online source, use the machine cache and download it using the // given url. return DownloadFromUrl(sourcePackage, repository, logger, token); } else { // Look up the package from the id and version and download it. return DownloadFromIdentity(identity, V2Client, logger, token); } } catch (OperationCanceledException) { return new DownloadResourceResult(DownloadResourceResultStatus.Cancelled); } catch (IOException ex) when(ex.InnerException is SocketException && i < 2) { string message = string.Format(CultureInfo.CurrentCulture, Strings.Log_ErrorDownloading, identity, displayUri) + Environment.NewLine + ExceptionUtilities.DisplayMessage(ex); logger.LogWarning(message); } catch (Exception ex) { string message = string.Format(CultureInfo.CurrentCulture, Strings.Log_ErrorDownloading, identity, displayUri); logger.LogError(message + Environment.NewLine + ExceptionUtilities.DisplayMessage(ex)); throw new FatalProtocolException(message, ex); } } // This line cannot be reached, but the compiler doesn't understand it throw new InvalidOperationException("Can never reach here."); })); }
private IPackage DownloadToMachineCache( IPackageCacheRepository cacheRepository, PackageIdentity package, DataServicePackageRepository repository, Uri downloadUri, NuGet.Common.ILogger logger, CancellationToken token) { var packageName = new PackageNameWrapper(package); var version = SemanticVersion.Parse(package.Version.ToString()); IPackage newPackage = null; FileInfo tmpFile = null; FileStream tmpFileStream = null; // Create a v2 http client var downloadClient = new HttpClient(downloadUri) { UserAgent = UserAgent.UserAgentString }; EventHandler <ProgressEventArgs> progressHandler = (sender, progress) => { // Throw if this was canceled. This will stop the download. token.ThrowIfCancellationRequested(); }; Exception downloadException = null; Action <Stream> downloadAction = (stream) => { try { repository.PackageDownloader.ProgressAvailable += progressHandler; repository.PackageDownloader.DownloadPackage(downloadClient, packageName, stream); } catch (Exception ex) when(ex is OperationCanceledException || ex is IOException && ex.InnerException is SocketException) { // The task was canceled. To avoid writing a partial file to the machine cache // we need to clear out the current tmp file stream so that it will be ignored. stream.SetLength(0); // If the machine cache is using the physical file system we can find the // path of temp file and clean it up. Otherwise NuGet.Core will just leave the temp file. tmpFileStream = stream as FileStream; if (tmpFileStream != null) { tmpFile = new FileInfo(tmpFileStream.Name); } downloadException = ex; } catch (Exception ex) { downloadException = ex; } finally { repository.PackageDownloader.ProgressAvailable -= progressHandler; } }; // We either do not have a package available locally or they are invalid. // Download the package from the server. if (cacheRepository.InvokeOnPackage(package.Id, version, (stream) => downloadAction(stream))) { if (!token.IsCancellationRequested) { newPackage = cacheRepository.FindPackage(package.Id, version); Debug.Assert(newPackage != null); } } // After the stream is no longer in use, delete the tmp file // NuGet.Core does not properly clean these up since it does not have cancel support. if (tmpFile != null && token.IsCancellationRequested && tmpFile.Exists) { try { tmpFile.Delete(); } catch { // Ignore exceptions for tmp file clean up } } if (downloadException != null) { throw downloadException; } return(newPackage); }
private DownloadResourceResult DownloadFromIdentity( PackageIdentity identity, IPackageRepository repository, NuGet.Common.ILogger logger, CancellationToken token) { var version = SemanticVersion.Parse(identity.Version.ToString()); var dataServiceRepo = repository as DataServicePackageRepository; if (dataServiceRepo != null) { // Clone the repo to allow for concurrent calls var sourceUri = UriUtility.CreateSourceUri(dataServiceRepo.Source); dataServiceRepo = new DataServicePackageRepository(sourceUri); var package = dataServiceRepo.FindPackage(identity.Id, version); var dataServicePackage = package as DataServicePackage; if (dataServicePackage != null) { token.ThrowIfCancellationRequested(); // For online sources get the url and retrieve it with cancel support var url = dataServicePackage.DownloadUrl; var downloadedPackage = DownloadToMachineCache( MachineCache.Default, identity, dataServiceRepo, url, logger, token); if (downloadedPackage != null) { return(new DownloadResourceResult(downloadedPackage.GetStream())); } } } else { var package = repository.FindPackage(identity.Id, version); if (package != null) { // Use a folder reader for unzipped repos if (repository is UnzippedPackageRepository) { var packagePath = Path.Combine(repository.Source, identity.Id + "." + version); var directoryInfo = new DirectoryInfo(packagePath); if (directoryInfo.Exists) { return(new DownloadResourceResult( package.GetStream(), new PackageFolderReader(directoryInfo))); } } return(new DownloadResourceResult(package.GetStream())); } } return(new DownloadResourceResult(DownloadResourceResultStatus.NotFound)); }
public async Task <string> DownloadPackageAsync(string connectionID, RequestDownloadInfo requestInfo) { // cast RequestDownloadNuGetInfo info = (RequestDownloadNuGetInfo)requestInfo; // server response ServerResponse response = new ServerResponse() { payload = new Dictionary <string, string>() }; string _outputDirectory = $"{_environment.ContentRootPath}/wwwroot/{_configuration.GetValue<string>("DownloadPath")}"; // check if output directory exists if (!Directory.Exists(_outputDirectory)) { Directory.CreateDirectory(_outputDirectory); } string connectionSubName = $"nuget-{connectionID}-{DateTime.Now:yyyymmddHHmmss}"; string connectionDirectory = $"{_outputDirectory}/{connectionSubName}"; Directory.CreateDirectory(connectionDirectory); // send message response.payload.Clear(); response.payload.Add("Resource", $"{connectionSubName} created."); await _downloadHubContext.Clients.Client(connectionID).Response(response); ILogger logger = NullLogger.Instance; CancellationToken cancellationToken = CancellationToken.None; SourceCacheContext cache = new SourceCacheContext(); SourceRepository repository = Repository.Factory.GetCoreV3(info.repository); FindPackageByIdResource resource = await repository.GetResourceAsync <FindPackageByIdResource>(); // set all parent packages for (int i = 0; i < info.packageList.Count(); i++) { string packageId = info.packageList.ElementAt(i).packageId; string packageVersionValue = info.packageList.ElementAt(i).packageVersion; NuGetVersion packageVersion = new NuGetVersion(packageVersionValue); PackageInfo package = new PackageInfo { packageId = packageId, packageVersion = packageVersion }; if (package.packageVersion != null) { _downloadQueue.Enqueue(package); } else { FloatRange floatRange = null; if (info.preReleased == true) { // include pre-release floatRange = new FloatRange(NuGetVersionFloatBehavior.AbsoluteLatest); } else { // released floatRange = new FloatRange(NuGetVersionFloatBehavior.Major); } FloatRange fr = new FloatRange(NuGetVersionFloatBehavior.Major); VersionRange range = new VersionRange(floatRange: fr); package = await GetBestMatchPackageVersionsAsync(repository, packageId, range); } _downloadQueue.Enqueue(package); } // download counter int download_counter = 0; while (_downloadQueue.Count > 0) { PackageInfo package = _downloadQueue.Dequeue(); string validFileName = FileUtil.GetValidFileName(package.packageId); string packageFilePath = $"{connectionDirectory}/{validFileName}.{package.packageVersion}.nupkg"; if (_cacheDownloadedFileName.Contains($"{package.packageId}-{package.packageVersion}")) { continue; } else { _cacheDownloadedFileName.Add($"{package.packageId}-{package.packageVersion}"); } using FileStream packageStream = new FileStream(packageFilePath, FileMode.Create); await resource.CopyNupkgToStreamAsync( package.packageId, package.packageVersion, packageStream, cache, logger, cancellationToken); download_counter++; // starting if (download_counter == 1) { // send message response.payload.Clear(); response.payload.Add("DownloadCounter", $"starting..."); await _downloadHubContext.Clients.Client(connectionID).Response(response); } // check if send message is needed if (download_counter % MessageFrequency == 0) { // send message response.payload.Clear(); response.payload.Add("DownloadCounter", $"{download_counter}, {((float)download_counter / (float)(download_counter + _downloadQueue.Count)) * 100.0f}%"); await _downloadHubContext.Clients.Client(connectionID).Response(response); } Console.WriteLine($"Downloaded package {package.packageId} {package.packageVersion}"); using PackageArchiveReader packageReader = new PackageArchiveReader(packageStream); NuspecReader nuspecReader = await packageReader.GetNuspecReaderAsync(cancellationToken); Console.WriteLine($"Tags: {nuspecReader.GetTags()}"); Console.WriteLine($"Description: {nuspecReader.GetDescription()}"); using PackageArchiveReader reader = new PackageArchiveReader(packageStream); NuspecReader nuspec = reader.NuspecReader; Console.WriteLine($"ID: {nuspec.GetId()}"); Console.WriteLine($"Version: {nuspec.GetVersion()}"); Console.WriteLine($"Description: {nuspec.GetDescription()}"); Console.WriteLine($"Authors: {nuspec.GetAuthors()}"); if (info.withDependency == false) { Console.WriteLine("\nDependencies download is not need."); continue; } Console.WriteLine("\nStart download dependencies:"); foreach (var dependencyGroup in nuspec.GetDependencyGroups()) { Console.WriteLine($" - {dependencyGroup.TargetFramework.GetFrameworkString()}"); // check target framework if (!info.targetFramework.Contains("all", StringComparer.InvariantCultureIgnoreCase) && !info.targetFramework.Contains(dependencyGroup.TargetFramework.GetFrameworkString(), StringComparer.InvariantCultureIgnoreCase)) { Console.WriteLine($" -- {dependencyGroup.TargetFramework.GetFrameworkString()} not match target framework."); continue; } foreach (var dependency in dependencyGroup.Packages) { Console.WriteLine($" > {dependency.Id} {dependency.VersionRange}"); PackageInfo dependencyPackage = await GetBestMatchPackageVersionsAsync(repository, dependency.Id, dependency.VersionRange); Console.WriteLine($" -- best match version: {dependency.Id} {dependencyPackage.packageVersion}"); _downloadQueue.Enqueue(dependencyPackage); } } } // send message response.payload.Clear(); response.payload.Add("DownloadCounter", $"{download_counter}, {((float)download_counter / (float)(download_counter + _downloadQueue.Count)) * 100.0f}%"); await _downloadHubContext.Clients.Client(connectionID).Response(response); string zipFileName = $"{_outputDirectory}/{connectionSubName}.zip"; bool result = _compressService.CompressDirectory(connectionDirectory, zipFileName); if (result == true) { string readableSize = FileUtil.getFileHumanReadableSize(zipFileName); // send message response.payload.Clear(); response.payload.Add("CompressStatus", $"compressed ok, file sieze: {readableSize}."); await _downloadHubContext.Clients.Client(connectionID).Response(response); } else { // send message response.payload.Clear(); response.payload.Add("CompressStatus", $"compressed failed."); await _downloadHubContext.Clients.Client(connectionID).Response(response); } // delete directory Directory.Delete(connectionDirectory, true); return(connectionSubName); }
private async Task <PackagesContext> GetRequiredPackages(ISet <PackageIdentity> primaryPackages, ISet <PackageIdentity> targetPackages, bool downgradeAllowed, ResolutionContext resolutionContext, NuGetFramework primaryFramework, ILogger logger, CancellationToken token) { var libraryPackage = GetFramworkLibrary(primaryFramework); var gatherContext = new GatherContext { ResolutionContext = resolutionContext, PrimarySources = _project.PrimarySources, DependencySources = _project.DependencySources, PackagesFolderSource = _project.LocalSourceRepository, PrimaryTargets = primaryPackages .Select(x => targetPackages.Contains(x) ? x : new PackageIdentity(x.Id, version: null)) .ToList(), AllowDowngrades = downgradeAllowed, PrimaryFramework = primaryFramework, DependencyFramework = MazeFrameworks.MapToNetFramework(primaryFramework), Log = logger }; var primaryPackageIds = primaryPackages.Select(x => x.Id).ToHashSet(); var allPackages = await ResolverGather.GatherAsync(gatherContext, token); var frameworkRelevantPackages = primaryPackages.Where(x => allPackages.First(y => y.Equals(x)).Dependencies.Any()).ToHashSet(); var frameworkRelevantTargets = targetPackages.Where(x => allPackages.First(y => y.Equals(x)).Dependencies.Any()).ToHashSet(); //we remove all primary packages that have no dependencies for the current framework meaning they don't support this framework var availablePackages = allPackages.Where(x => !primaryPackageIds.Contains(x.Id) || x.Dependencies.Any()).ToList(); if (!availablePackages.Any()) //packages not available for this framework { return(new PackagesContext(ImmutableDictionary <PackageIdentity, SourcePackageDependencyInfo> .Empty)); } //available packages now contains all versions of the package and all versions of each depdendency (recursive) //we try to prune the results down to only what we would allow to be installed //1. remove incorrect library packages var prunedAvailablePackages = PrunePackageTreeExtensions.RemoveLibraryPackage(availablePackages, libraryPackage); //2. remove all versions of the package we want to install except the version we actually want to install // it is not a problem if other primary packages might need an update prunedAvailablePackages = PrunePackageTreeExtensions.RemoveAllVersionsForIdExcept(prunedAvailablePackages, frameworkRelevantTargets); //3. remove the downgrades of primary packages if (!downgradeAllowed) { prunedAvailablePackages = PrunePackageTreeExtensions.PruneDowngrades(prunedAvailablePackages, frameworkRelevantPackages); } //4. remove prereleases if (!resolutionContext.IncludePrerelease) { prunedAvailablePackages = PrunePackageTree.PrunePreleaseForStableTargets(prunedAvailablePackages, frameworkRelevantPackages, frameworkRelevantTargets); } /* ===> PackageResolverContext * TargetIds New packages to install or update. These will prefer the highest version. * RequiredPackageIds The required packages (primary) * PackagesConfig Only for logging * PreferredVersions Preferred versions of each package. If the package does not exist here it will use the dependency behavior, or if it is a target the highest version will be used. * AvailablePackages All available packages that should be sorted out * DependencyBehavior The behavior for resolving a package version * PackageSources Only for logging * Log Logger * ======================================================================== * Return The complete resulting list */ var resolverContext = new PackageResolverContext( resolutionContext.DependencyBehavior, targetIds: frameworkRelevantTargets.Select(x => x.Id), requiredPackageIds: frameworkRelevantPackages.Select(x => x.Id), packagesConfig: Enumerable.Empty <PackageReference>(), preferredVersions: frameworkRelevantPackages, availablePackages: prunedAvailablePackages, packageSources: Enumerable.Empty <PackageSource>(), log: logger); var packageResolver = new PackageResolver(); //all final packages (including dependencies) var packages = packageResolver.Resolve(resolverContext, token).ToList(); //that's an array var dependencyMap = packages.ToDictionary(x => x, x => availablePackages.First(y => y.Equals(x)), PackageIdentity.Comparer); //remove library package and it's dependencies because they are always loaded var foundLibraryPackage = packages.FirstOrDefault(libraryPackage.IsSameId); if (foundLibraryPackage != null) { if (!foundLibraryPackage.Version.Equals(libraryPackage.Version)) { throw new InvalidOperationException($"Invalid version of {libraryPackage} found: {foundLibraryPackage}"); } RemovePackage(foundLibraryPackage); //TODO remove package also from SourceDependencyInfo? void RemovePackage(PackageIdentity packageIdentity) { var sourceInfo = dependencyMap[packageIdentity]; dependencyMap.Remove(packageIdentity); foreach (var dependency in sourceInfo.Dependencies) { var package = dependencyMap.FirstOrDefault(x => x.Key.IsSameId(dependency)).Key; if (package != null) { RemovePackage(package); } } } } return(new PackagesContext(dependencyMap)); }
/// <summary> /// Restores a package by querying, downloading, and unzipping it without generating any other files (like project.assets.json). /// </summary> /// <param name="libraryIdentity">The <see cref="LibraryIdentity"/> of the package.</param> /// <param name="settings">The NuGet settings to use.</param> /// <param name="logger">An <see cref="ILogger"/> to use for logging.</param> /// <returns></returns> public static Task <IReadOnlyList <RestoreResultPair> > RunWithoutCommit(LibraryIdentity libraryIdentity, ISettings settings, ILogger logger) { using (var sourceCacheContext = new SourceCacheContext { IgnoreFailedSources = true, }) { var projectDirectory = Path.Combine(NuGetEnvironment.GetFolderPath(NuGetFolderPath.Temp), Guid.NewGuid().ToString("N")); var projectName = Guid.NewGuid().ToString("N"); var projectFullPath = Path.Combine(projectDirectory, $"{projectName}.proj"); // Iterate through TargetFrameworks to generate Lists required for packageSpec var frameworks = new List <TargetFrameworkInformation>(TargetFrameworks.Count); var originalTargetFrameworks = new List <string>(TargetFrameworks.Count); foreach (var tf in TargetFrameworks) { frameworks.Add(new TargetFrameworkInformation { FrameworkName = tf }); originalTargetFrameworks.Add(tf.ToString()); } // The package spec details what packages to restore var packageSpec = new PackageSpec(frameworks) { Dependencies = new List <LibraryDependency> { new LibraryDependency { LibraryRange = new LibraryRange( libraryIdentity.Name, new VersionRange( minVersion: libraryIdentity.Version, includeMinVersion: true, maxVersion: libraryIdentity.Version, includeMaxVersion: true), LibraryDependencyTarget.Package), SuppressParent = LibraryIncludeFlags.All, AutoReferenced = true, IncludeType = LibraryIncludeFlags.None, } }, RestoreMetadata = new ProjectRestoreMetadata { ProjectPath = projectFullPath, ProjectName = projectName, ProjectStyle = ProjectStyle.PackageReference, ProjectUniqueName = projectFullPath, OutputPath = projectDirectory, OriginalTargetFrameworks = originalTargetFrameworks, ConfigFilePaths = settings.GetConfigFilePaths(), PackagesPath = SettingsUtility.GetGlobalPackagesFolder(settings), Sources = SettingsUtility.GetEnabledSources(settings).AsList(), FallbackFolders = SettingsUtility.GetFallbackPackageFolders(settings).ToList() }, FilePath = projectFullPath, Name = projectName, }; var dependencyGraphSpec = new DependencyGraphSpec(); dependencyGraphSpec.AddProject(packageSpec); dependencyGraphSpec.AddRestore(packageSpec.RestoreMetadata.ProjectUniqueName); IPreLoadedRestoreRequestProvider requestProvider = new DependencyGraphSpecRequestProvider(new RestoreCommandProvidersCache(), dependencyGraphSpec); var restoreArgs = new RestoreArgs { AllowNoOp = false, CacheContext = sourceCacheContext, #pragma warning disable CS0618 // Type or member is obsolete CachingSourceProvider = new CachingSourceProvider(new PackageSourceProvider(settings, enablePackageSourcesChangedEvent: false)), #pragma warning restore CS0618 // Type or member is obsolete Log = logger, }; // Create requests from the arguments var requests = requestProvider.CreateRequests(restoreArgs).Result; // Restore the package without generating extra files return(RestoreRunner.RunWithoutCommit(requests, restoreArgs)); } }