public void Dispose() { this.sourceRepository = null; this.sourceCacheContext?.Dispose(); this.sourceCacheContext = null; }
private async Task <IEnumerable <PackageInfo> > FindPackagesByIdAsyncCore( string id, SourceCacheContext cacheContext, ILogger logger, CancellationToken cancellationToken) { for (var retry = 0; retry < 3; ++retry) { var relativeUri = _queryBuilder.BuildFindPackagesByIdUri(id).TrimStart('/'); var uri = _baseUri + relativeUri; var httpSourceCacheContext = HttpSourceCacheContext.Create(cacheContext, retry); try { var results = new List <PackageInfo>(); var uris = new HashSet <string>(StringComparer.OrdinalIgnoreCase); uris.Add(uri); var page = 1; var paging = true; while (paging) { // TODO: Pages for a package ID are cached separately. // So we will get inaccurate data when a page shrinks. // However, (1) In most cases the pages grow rather than shrink; // (2) cache for pages is valid for only 30 min. // So we decide to leave current logic and observe. paging = await _httpSource.GetAsync( new HttpSourceCachedRequest( uri, $"list_{id.ToLowerInvariant()}_page{page}", httpSourceCacheContext) { AcceptHeaderValues = { new MediaTypeWithQualityHeaderValue("application/atom+xml"), new MediaTypeWithQualityHeaderValue("application/xml") }, EnsureValidContents = stream => HttpStreamValidation.ValidateXml(uri, stream), MaxTries = 1 }, async httpSourceResult => { if (httpSourceResult.Status == HttpSourceResultStatus.NoContent) { // Team city returns 204 when no versions of the package exist // This should result in an empty list and we should not try to // read the stream as xml. return(false); } var doc = await V2FeedParser.LoadXmlAsync(httpSourceResult.Stream); var result = doc.Root .Elements(_xnameEntry) .Select(x => BuildModel(id, x)) .Where(x => x != null); results.AddRange(result); // Find the next url for continuation var nextUri = V2FeedParser.GetNextUrl(doc); // Stop if there's nothing else to GET if (string.IsNullOrEmpty(nextUri)) { return(false); } // check for any duplicate url and error out if (!uris.Add(nextUri)) { throw new FatalProtocolException(string.Format( CultureInfo.CurrentCulture, Strings.Protocol_duplicateUri, nextUri)); } uri = nextUri; page++; return(true); }, logger, cancellationToken); } return(results); } catch (Exception ex) when(retry < 2) { var message = string.Format(CultureInfo.CurrentCulture, Strings.Log_RetryingFindPackagesById, nameof(FindPackagesByIdAsyncCore), uri) + Environment.NewLine + ExceptionUtilities.DisplayMessage(ex); logger.LogMinimal(message); } catch (Exception ex) when(retry == 2) { var message = string.Format( CultureInfo.CurrentCulture, Strings.Log_FailedToRetrievePackage, id, uri); throw new FatalProtocolException(message, ex); } } return(null); }
private async Task <RestoreSummary> PerformNuGetV2RestoreAsync(PackageRestoreInputs packageRestoreInputs) { ReadSettings(packageRestoreInputs); var packagesFolderPath = GetPackagesFolder(packageRestoreInputs); var sourceRepositoryProvider = new CommandLineSourceRepositoryProvider(SourceProvider); var nuGetPackageManager = new NuGetPackageManager(sourceRepositoryProvider, Settings, packagesFolderPath); var installedPackageReferences = new HashSet <Packaging.PackageReference>(new PackageReferenceComparer()); if (packageRestoreInputs.RestoringWithSolutionFile) { installedPackageReferences.AddRange(packageRestoreInputs .PackagesConfigFiles .SelectMany(file => GetInstalledPackageReferences(file, allowDuplicatePackageIds: true))); } else if (packageRestoreInputs.PackagesConfigFiles.Count > 0) { // By default the PackageReferenceFile does not throw // if the file does not exist at the specified path. // So we'll need to verify that the file exists. Debug.Assert(packageRestoreInputs.PackagesConfigFiles.Count == 1, "Only one packages.config file is allowed to be specified " + "at a time when not performing solution restore."); var packageReferenceFile = packageRestoreInputs.PackagesConfigFiles[0]; if (!File.Exists(packageReferenceFile)) { var message = string.Format( CultureInfo.CurrentCulture, LocalizedResourceManager.GetString("RestoreCommandFileNotFound"), packageReferenceFile); throw new InvalidOperationException(message); } installedPackageReferences.AddRange( GetInstalledPackageReferences(packageReferenceFile, allowDuplicatePackageIds: true)); } // EffectivePackageSaveMode is None when -PackageSaveMode is not provided by the user. None is treated as // Defaultv3 for V3 restore and should be treated as Defaultv2 for V2 restore. This is the case in the // actual V2 restore flow and should match in this preliminary missing packages check. var packageSaveMode = EffectivePackageSaveMode == Packaging.PackageSaveMode.None ? Packaging.PackageSaveMode.Defaultv2 : EffectivePackageSaveMode; var missingPackageReferences = installedPackageReferences.Where(reference => !nuGetPackageManager.PackageExistsInPackagesFolder(reference.PackageIdentity, packageSaveMode)).ToArray(); if (missingPackageReferences.Length == 0) { var message = string.Format( CultureInfo.CurrentCulture, LocalizedResourceManager.GetString("InstallCommandNothingToInstall"), "packages.config"); Console.LogMinimal(message); return(new RestoreSummary(true)); } var packageRestoreData = missingPackageReferences.Select(reference => new PackageRestoreData( reference, new[] { packageRestoreInputs.RestoringWithSolutionFile ? packageRestoreInputs.DirectoryOfSolutionFile : packageRestoreInputs.PackagesConfigFiles[0] }, isMissing: true)); var packageSources = GetPackageSources(Settings); var repositories = packageSources .Select(sourceRepositoryProvider.CreateRepository) .ToArray(); var installCount = 0; var failedEvents = new ConcurrentQueue <PackageRestoreFailedEventArgs>(); var packageRestoreContext = new PackageRestoreContext( nuGetPackageManager, packageRestoreData, CancellationToken.None, packageRestoredEvent: (sender, args) => { Interlocked.Add(ref installCount, args.Restored ? 1 : 0); }, packageRestoreFailedEvent: (sender, args) => { failedEvents.Enqueue(args); }, sourceRepositories: repositories, maxNumberOfParallelTasks: DisableParallelProcessing ? 1 : PackageManagementConstants.DefaultMaxDegreeOfParallelism); CheckRequireConsent(); var collectorLogger = new RestoreCollectorLogger(Console); var projectContext = new ConsoleProjectContext(collectorLogger) { PackageExtractionContext = new PackageExtractionContext(collectorLogger) }; if (EffectivePackageSaveMode != Packaging.PackageSaveMode.None) { projectContext.PackageExtractionContext.PackageSaveMode = EffectivePackageSaveMode; } using (var cacheContext = new SourceCacheContext()) { cacheContext.NoCache = NoCache; cacheContext.DirectDownload = DirectDownload; var downloadContext = new PackageDownloadContext(cacheContext, packagesFolderPath, DirectDownload); var result = await PackageRestoreManager.RestoreMissingPackagesAsync( packageRestoreContext, projectContext, downloadContext); if (downloadContext.DirectDownload) { GetDownloadResultUtility.CleanUpDirectDownloads(downloadContext); } return(new RestoreSummary( result.Restored, "packages.config projects", Settings.Priority.Select(x => Path.Combine(x.Root, x.FileName)), packageSources.Select(x => x.Source), installCount, collectorLogger.Errors.Concat(failedEvents.Select(e => new RestoreLogMessage(LogLevel.Error, e.Exception.Message))))); } }
static void AnalyzePackage( string packageId, string version, string framework, //ILogger logger, PackageSourceEnvironment packageSourceEnvironment) { var rootPackageIdentity = new PackageIdentity(packageId, NuGetVersion.Parse(version)); var rootNuGetFramework = NuGetFramework.ParseFolder(framework); // If configFileName is null, the user specific settings file is %AppData%\NuGet\NuGet.config. // After that, the machine wide settings files are added (c:\programdata\NuGet\Config\*.config). //var settings = Settings.LoadDefaultSettings(root: null, configFileName: null, machineWideSettings: null); //var sourceRepositoryProvider = new SourceRepositoryProvider(settings, Repository.Provider.GetCoreV3()); // TODO: Configure packageSources from external config // TODO: Use environment variables for MyGet username/password!!!!!! // TODO: Make 3 different environments // 1. MyGetCi // 2. MyGet // 3. Brf string username = null, password = null; if (packageSourceEnvironment == PackageSourceEnvironment.MyGetCi || packageSourceEnvironment == PackageSourceEnvironment.MyGet) { username = Environment.GetEnvironmentVariable("MYGET_USERNAME"); if (string.IsNullOrEmpty(username)) { username = "******"; } password = Environment.GetEnvironmentVariable("MYGET_PASSWORD"); if (string.IsNullOrEmpty(password)) { throw new InvalidOperationException("Missing MYGET_PASSWORD environment variable."); } } PackageSourceProvider packageSourceProvider; switch (packageSourceEnvironment) { case PackageSourceEnvironment.MyGetCi: packageSourceProvider = new PackageSourceProvider(NullSettings.Instance, new [] { CreatePackageSource("https://api.nuget.org/v3/index.json", "NuGet.org v3"), CreatePackageSource("https://www.myget.org/F/maxfire-ci/api/v3/index.json", "MaxfireCi"), CreateAuthenticatedPackageSource("https://www.myget.org/F/brf-ci/api/v3/index.json", "BrfCiMyGet", username, password) }); break; case PackageSourceEnvironment.MyGet: packageSourceProvider = new PackageSourceProvider(NullSettings.Instance, new [] { CreatePackageSource("https://api.nuget.org/v3/index.json", "NuGet.org v3"), CreateAuthenticatedPackageSource("https://www.myget.org/F/brf/api/v3/index.json", "BrfMyGet", username, password) }); break; case PackageSourceEnvironment.Brf: packageSourceProvider = new PackageSourceProvider(NullSettings.Instance, new [] { CreatePackageSource("https://api.nuget.org/v3/index.json", "NuGet.org v3"), CreatePackageSource("http://pr-nuget/nuget", "Brf", protocolVersion: 2) }); break; case PackageSourceEnvironment.NugetOrg: default: packageSourceProvider = new PackageSourceProvider(NullSettings.Instance, new [] { CreatePackageSource("https://api.nuget.org/v3/index.json", "NuGet.org v3") }); break; } var sourceRepositoryProvider = new SourceRepositoryProvider(packageSourceProvider, Repository.Provider.GetCoreV3()); Console.WriteLine("Feeds used:"); foreach (var packageSource in packageSourceProvider.LoadPackageSources()) { Console.WriteLine($" {packageSource}"); } Console.WriteLine(); //var nugetLogger = logger.AsNuGetLogger(); var nugetLogger = NullLogger.Instance; var tmpDirToRestoreTo = Path.Combine(Path.GetTempPath(), "packages"); using (var cacheContext = new SourceCacheContext { NoCache = true }) { var repositories = sourceRepositoryProvider.GetRepositories(); var resolvedPackages = new ConcurrentDictionary <PackageIdentity, SourcePackageDependencyInfo>(PackageIdentityComparer.Default); // Builds transitive closure // TODO: is Wait okay? ResolvePackageDependencies(rootPackageIdentity, rootNuGetFramework, cacheContext, nugetLogger, repositories, resolvedPackages).Wait(); var resolverContext = new PackageResolverContext( DependencyBehavior.Lowest, targetIds: new[] { packageId }, availablePackages: new HashSet <SourcePackageDependencyInfo>(resolvedPackages.Values), packageSources: sourceRepositoryProvider.GetRepositories().Select(s => s.PackageSource), log: nugetLogger, requiredPackageIds: Enumerable.Empty <string>(), packagesConfig: Enumerable.Empty <PackageReference>(), preferredVersions: Enumerable.Empty <PackageIdentity>()); var resolver = new PackageResolver(); List <SourcePackageDependencyInfo> prunedPackages; //try //{ prunedPackages = resolver.Resolve(resolverContext, CancellationToken.None) .Select(id => resolvedPackages[id]).ToList(); //} //catch (Exception ex) //{ // Console.WriteLine($"ERROR: {ex.Message}"); // return; //} Console.WriteLine($"root package identity: {rootPackageIdentity}"); Console.WriteLine($"root target framework: {rootNuGetFramework.DotNetFrameworkName} ({rootNuGetFramework.GetShortFolderName()})"); Console.WriteLine(); var packageNodes = new Dictionary <string, PackageReferenceNode>(StringComparer.OrdinalIgnoreCase); //var builder = new DependencyGraph.Builder(rootNode); // TODO: problem that the graph is flattened!!!!! // TODO: Should we inspect the items (assemblies of each package). remember meta-packages contain other packages // TODO: dependencies are important Console.WriteLine("Vertices of dependency package graph:"); Console.WriteLine(); PackageReferenceNode rootPackage = null; // resolve contained assemblies of packages foreach (SourcePackageDependencyInfo target in prunedPackages) { //target.Id //target.Version //target.Dependencies // TODO: --no-cache, --packages $tmpDirToRestoreTo var downloadResource = target.Source.GetResource <DownloadResource>(); // TODO: .Result of Async var downloadResult = downloadResource.GetDownloadResourceResultAsync( new PackageIdentity(target.Id, target.Version), new PackageDownloadContext(cacheContext, directDownloadDirectory: tmpDirToRestoreTo, directDownload: true), SettingsUtility.GetGlobalPackagesFolder(NullSettings.Instance), nugetLogger, CancellationToken.None).Result; // items in lib folder of target (a package is a collection of assemblies) var packageReader = downloadResult.PackageReader; if (packageReader == null) { downloadResult.PackageStream.Seek(0, SeekOrigin.Begin); packageReader = new PackageArchiveReader(downloadResult.PackageStream); } var libItems = packageReader.GetLibItems(); NuGetFramework nearest = libItems.Select(x => x.TargetFramework).GetNearestFrameworkMatching(rootNuGetFramework); // assembly references is a sequence of assembly names (file name including the extension) var assemblyReferences = libItems .Where(group => group.TargetFramework.Equals(nearest)) .SelectMany(group => group.Items) .Where(itemRelativePath => Path.GetExtension(itemRelativePath).Equals(".dll", StringComparison.OrdinalIgnoreCase)) .Select(Path.GetFileName); //.Select(assemblyName => new AssemblyReferenceNode(assemblyName)); // we do not include assembly references in the graph // TODO we ignore framework references in nuspec (only used by MS) //var frameworkItems = packageReader.GetFrameworkItems(); //nearest = reducer.GetNearest(nugetFramework, frameworkItems.Select(x => x.TargetFramework)); //// TODO: Why not use Path.GetFileName here? //var frameworkAssemblyReferences = frameworkItems // .Where(@group => @group.TargetFramework.Equals(nearest)) // .SelectMany(@group => @group.Items) // .Select(Path.GetFileName); // Why // //.Select(assemblyName => new AssemblyReferenceNode(assemblyName)); // we do not include assembly references in the graph //assemblyReferences = assemblyReferences.Concat(frameworkAssemblyReferences); var packageReferenceNode = new PackageReferenceNode(target.Id, target.Version.ToString(), nearest.DotNetFrameworkName, nearest.GetShortFolderName(), assemblyReferences); if (rootPackageIdentity.Equals(new PackageIdentity(target.Id, target.Version))) { if (rootPackage != null) { throw new InvalidOperationException("UNEXPECTED: Root package should be unique."); } rootPackage = packageReferenceNode; } Console.WriteLine($" {packageReferenceNode}"); //builder.WithNode(packageReferenceNode); //builder.WithNodes(assemblyReferences); // TODO: Target package has edges to assembly nodes //builder.WithEdges(assemblyReferences.Select(x => new Edge(packageReferenceNode, x))); // TODO: Pack2Pack reference (directed vertex) packageNodes.Add(target.Id, packageReferenceNode); } Console.WriteLine(); // NOTE: We have transitive closure so all references are resolved!!!! // NOTE: The relation is A 'depends on' B shown like A ---> B // NOTE: The inverse relation is 'used by'.... // TODO: How to represent digraph (DAG) // TODO: How to represent the topological order (evaluation order, traversal order) // TODO: A directed acyclic graph (DAG) with a single root is not a tree!!!!! // NOTE: Both trees and DAGs are connected, directed, rooted, and have no cycles // so this means that starting from any node and going up the parents you will // eventually work your way up to the top (root). // However, since DAG nodes have multiple parents, there will be multiple paths // on the way up (that eventually merge). This is like GIT history (DAG) // Another way to see it is Tree is like single class inheritance, and DAG is like multiple class inheritance. // A (successor, downstream, core) package can be depended on by many (predecessor, upstream) packages Console.WriteLine("Edges of dependency package graph:"); Console.WriteLine(); // resolve dependencies of packages foreach (SourcePackageDependencyInfo target in prunedPackages) { // TODO: predecessor node in dependency package graph PackageReferenceNode sourceNode = packageNodes[target.Id]; // traverse all dependencies of nuspec foreach (PackageDependency dependency in target.Dependencies) { //dependency.Id //dependency.VersionRange // resolved dependency of sourceNode PackageReferenceNode targetNode = packageNodes[dependency.Id]; //targetNode.PackageId //targetNode.Type (package) //targetNode.Version // labeled edge //new Edge(sourceNode, targetNode, x.VersionRange.ToString()) Console.WriteLine($" {sourceNode}---{dependency.VersionRange}---->{targetNode}"); } // TODO: directed edge with label of version range for each successor node (successor node carries resolved version) //builder.WithEdges(target.Dependencies.Select(x => // new Edge(sourceNode, packageNodes[x.Id], x.VersionRange.ToString()))); } Console.WriteLine(); Console.WriteLine($"root package: {rootPackage}"); //return builder.Build(); } }
public async Task FindPackage_WhenNoPackageSourceMappingIsEnabledForAPackage_Fails() { // Arrange const string packageX = "x", version = "1.0.0-beta.1"; var range = new LibraryRange(packageX, VersionRange.Parse(version), LibraryDependencyTarget.Package); var cacheContext = new SourceCacheContext(); var testLogger = new TestLogger(); var framework = NuGetFramework.Parse("net45"); var token = CancellationToken.None; var edge = new GraphEdge <RemoteResolveResult>(null, null, null); var actualIdentity = new LibraryIdentity(packageX, NuGetVersion.Parse(version), LibraryType.Package); var dependencies = new[] { new LibraryDependency() { LibraryRange = new LibraryRange("y", VersionRange.All, LibraryDependencyTarget.Package) } }; var dependencyInfo = LibraryDependencyInfo.Create(actualIdentity, framework, dependencies); var downloadCount = 0; //package source mapping configuration Dictionary <string, IReadOnlyList <string> > patterns = new(); patterns.Add("source2", new List <string>() { "z" }); patterns.Add("source1", new List <string>() { "y" }); PackageSourceMapping sourceMappingConfiguration = new(patterns); var context = new RemoteWalkContext(cacheContext, sourceMappingConfiguration, testLogger); // Source1 returns 1.0.0-beta.1 var remoteProvider = new Mock <IRemoteDependencyProvider>(); remoteProvider.Setup(e => e.FindLibraryAsync(range, It.IsAny <NuGetFramework>(), It.IsAny <SourceCacheContext>(), testLogger, token)) .ReturnsAsync(actualIdentity); remoteProvider.SetupGet(e => e.IsHttp).Returns(true); remoteProvider.SetupGet(e => e.Source).Returns(new PackageSource("source1")); remoteProvider.Setup(e => e.GetDependenciesAsync(It.IsAny <LibraryIdentity>(), It.IsAny <NuGetFramework>(), It.IsAny <SourceCacheContext>(), testLogger, token)) .ReturnsAsync(dependencyInfo) .Callback(() => ++ downloadCount); context.RemoteLibraryProviders.Add(remoteProvider.Object); // Source2 returns 1.0.0-beta.1 var remoteProvider2 = new Mock <IRemoteDependencyProvider>(); remoteProvider2.Setup(e => e.FindLibraryAsync(range, It.IsAny <NuGetFramework>(), It.IsAny <SourceCacheContext>(), testLogger, token)) .ReturnsAsync(actualIdentity); remoteProvider2.SetupGet(e => e.IsHttp).Returns(true); remoteProvider2.SetupGet(e => e.Source).Returns(new PackageSource("source2")); remoteProvider2.Setup(e => e.GetDependenciesAsync(It.IsAny <LibraryIdentity>(), It.IsAny <NuGetFramework>(), It.IsAny <SourceCacheContext>(), testLogger, token)) .ReturnsAsync(dependencyInfo) .Callback(() => ++ downloadCount); context.RemoteLibraryProviders.Add(remoteProvider2.Object); // Act var result = await ResolverUtility.FindLibraryEntryAsync(range, framework, null, context, token); Assert.Equal(0, downloadCount); Assert.Equal(0, testLogger.Errors); Assert.Equal(1, testLogger.DebugMessages.Count); testLogger.DebugMessages.TryPeek(out string message); Assert.Equal($"Package source mapping match not found for package ID '{packageX}'.", message); }
public async Task LocalDownloadResource_PackageIsReturnedNonNormalizedAsync() { using (var root = TestDirectory.Create()) { // Arrange var testLogger = new TestLogger(); var packageA1 = new SimpleTestPackageContext() { Id = "a", Version = "1.0" }; var packageA2 = new SimpleTestPackageContext() { Id = "a", Version = "1.0.0" }; var packageA3 = new SimpleTestPackageContext() { Id = "a", Version = "1.0.0.0" }; var packageContexts = new SimpleTestPackageContext[] { packageA1, packageA2, packageA3 }; await SimpleTestPackageUtility.CreatePackagesAsync(root, packageContexts); string packagesFolder = null; // This is unused by the implementation. var localResource = new FindLocalPackagesResourceV2(root); var resource = new LocalDownloadResource(localResource); // Act using (var cacheContext = new SourceCacheContext()) { var downloadContext = new PackageDownloadContext(cacheContext); using (var result1 = await resource.GetDownloadResourceResultAsync( packageA1.Identity, downloadContext, packagesFolder, testLogger, CancellationToken.None)) using (var result2 = await resource.GetDownloadResourceResultAsync( packageA2.Identity, downloadContext, packagesFolder, testLogger, CancellationToken.None)) using (var result3 = await resource.GetDownloadResourceResultAsync( packageA3.Identity, downloadContext, packagesFolder, testLogger, CancellationToken.None)) { // Assert Assert.Equal("1.0", result1.PackageReader.GetIdentity().Version.ToString()); Assert.Equal("1.0.0", result2.PackageReader.GetIdentity().Version.ToString()); Assert.Equal("1.0.0.0", result3.PackageReader.GetIdentity().Version.ToString()); } } } }
private IEnumerable <PSResourceInfo> FindFromPackageSourceSearchAPI( string repositoryName, string pkgName, PackageSearchResource pkgSearchResource, PackageMetadataResource pkgMetadataResource, SearchFilter searchFilter, SourceCacheContext sourceContext) { List <IPackageSearchMetadata> foundPackagesMetadata = new List <IPackageSearchMetadata>(); // filter by param: Name if (!pkgName.Contains("*")) { // case: searching for specific package name i.e "Carbon" IEnumerable <IPackageSearchMetadata> retrievedPkgs = null; try { // GetMetadataAsync() API returns all versions for a specific non-wildcard package name // For PSGallery GetMetadataAsync() API returns both Script and Module resources by checking only the Modules endpoint retrievedPkgs = pkgMetadataResource.GetMetadataAsync( packageId: pkgName, includePrerelease: _prerelease, includeUnlisted: false, sourceCacheContext: sourceContext, log: NullLogger.Instance, token: _cancellationToken).GetAwaiter().GetResult(); } catch (HttpRequestException ex) { Utils.WriteVerboseOnCmdlet(_cmdletPassedIn, "FindHelper MetadataAsync: error receiving package: " + ex.Message); if ((String.Equals(repositoryName, _psGalleryRepoName, StringComparison.InvariantCultureIgnoreCase) || String.Equals(repositoryName, _psGalleryScriptsRepoName, StringComparison.InvariantCultureIgnoreCase))) { _cmdletPassedIn.WriteWarning(String.Format("Error receiving package from PSGallery. To check if this is due to a PSGallery outage check: https://aka.ms/psgallerystatus . Specific error: {0}", ex.Message)); } } catch (Exception e) { Utils.WriteVerboseOnCmdlet(_cmdletPassedIn, "FindHelper MetadataAsync: error receiving package: " + e.Message); } if (retrievedPkgs == null || retrievedPkgs.Count() == 0) { _cmdletPassedIn.WriteVerbose(string.Format("'{0}' could not be found in repository '{1}'", pkgName, repositoryName)); yield break; } foundPackagesMetadata.AddRange(retrievedPkgs.ToList()); _pkgsLeftToFind.Remove(pkgName); } else { if (_isADOFeedRepository) { _cmdletPassedIn.WriteError(new ErrorRecord( new ArgumentException(String.Format("Searching through ADOFeed with wildcard in Name is not supported, so {0} repository will be skipped.", repositoryName)), "CannotSearchADOFeedWithWildcardName", ErrorCategory.InvalidArgument, this)); yield break; } // case: searching for name containing wildcard i.e "Carbon.*" IEnumerable <IPackageSearchMetadata> wildcardPkgs = null; try { _cmdletPassedIn.WriteVerbose("searching with name: " + pkgName); // SearchAsync() API returns the latest version only for all packages that match the wild-card name wildcardPkgs = pkgSearchResource.SearchAsync( searchTerm: pkgName, filters: searchFilter, skip: 0, take: SearchAsyncMaxTake, log: NullLogger.Instance, cancellationToken: _cancellationToken).GetAwaiter().GetResult(); if (wildcardPkgs.Count() > SearchAsyncMaxReturned) { // get the rest of the packages wildcardPkgs = wildcardPkgs.Concat(pkgSearchResource.SearchAsync( searchTerm: pkgName, filters: searchFilter, skip: SearchAsyncMaxTake, take: GalleryMax, log: NullLogger.Instance, cancellationToken: _cancellationToken).GetAwaiter().GetResult()); } } catch (HttpRequestException ex) { Utils.WriteVerboseOnCmdlet(_cmdletPassedIn, "FindHelper SearchAsync: error receiving package: " + ex.Message); if ((String.Equals(repositoryName, _psGalleryRepoName, StringComparison.InvariantCultureIgnoreCase) || String.Equals(repositoryName, _psGalleryScriptsRepoName, StringComparison.InvariantCultureIgnoreCase))) { _cmdletPassedIn.WriteWarning(String.Format("Error receiving package from PSGallery. To check if this is due to a PSGallery outage check: https://aka.ms/psgallerystatus . Specific error: {0}", ex.Message)); } yield break; } catch (Exception e) { Utils.WriteVerboseOnCmdlet(_cmdletPassedIn, "FindHelper SearchAsync: error receiving package: " + e.Message); yield break; } // filter additionally because NuGet wildcard search API returns more than we need // perhaps validate in Find-PSResource, and use debugassert here? WildcardPattern nameWildcardPattern = new WildcardPattern(pkgName, WildcardOptions.IgnoreCase); foundPackagesMetadata.AddRange(wildcardPkgs.Where( p => nameWildcardPattern.IsMatch(p.Identity.Id)).ToList()); // if the Script Uri endpoint still needs to be searched, don't remove the wildcard name from _pkgsLeftToFind // PSGallery + Type == null -> M, S // PSGallery + Type == M -> M // PSGallery + Type == S -> S (but PSGallery would be skipped early on, only PSGalleryScripts would be checked) // PSGallery + Type == C -> M // PSGallery + Type == D -> M bool needToCheckPSGalleryScriptsRepo = String.Equals(repositoryName, _psGalleryRepoName, StringComparison.InvariantCultureIgnoreCase) && _type == ResourceType.None; if (foundPackagesMetadata.Any() && !needToCheckPSGalleryScriptsRepo) { _pkgsLeftToFind.Remove(pkgName); } } if (foundPackagesMetadata.Count == 0) { // no need to attempt to filter further _cmdletPassedIn.WriteVerbose("no packages found"); yield break; } // filter by param: Version if (_version == null) { // return latest version for each package foundPackagesMetadata = foundPackagesMetadata.GroupBy( p => p.Identity.Id, StringComparer.InvariantCultureIgnoreCase).Select( x => x.OrderByDescending( p => p.Identity.Version, VersionComparer.VersionRelease).FirstOrDefault()).ToList(); } else { if (!Utils.TryParseVersionOrVersionRange(_version, out VersionRange versionRange)) { _cmdletPassedIn.WriteError(new ErrorRecord( new ArgumentException("Argument for -Version parameter is not in the proper format"), "IncorrectVersionFormat", ErrorCategory.InvalidArgument, this)); yield break; } // at this point, version should be parsed successfully, into allVersions (null or "*") or versionRange (specific or range) if (pkgName.Contains("*")) { // -Name containing wc with Version "*", or specific range // at this point foundPackagesMetadata contains latest version for each package, get list of distinct // package names and get all versions for each name, this is due to the SearchAsync and GetMetadataAsync() API restrictions ! List <IPackageSearchMetadata> allPkgsAllVersions = new List <IPackageSearchMetadata>(); foreach (string n in foundPackagesMetadata.Select(p => p.Identity.Id).Distinct(StringComparer.InvariantCultureIgnoreCase)) { // get all versions for this package allPkgsAllVersions.AddRange(pkgMetadataResource.GetMetadataAsync(n, _prerelease, false, sourceContext, NullLogger.Instance, _cancellationToken).GetAwaiter().GetResult().ToList()); } foundPackagesMetadata = allPkgsAllVersions; if (versionRange == VersionRange.All) // Version = "*" { foundPackagesMetadata = foundPackagesMetadata.GroupBy( p => p.Identity.Id, StringComparer.InvariantCultureIgnoreCase).SelectMany( x => x.OrderByDescending( p => p.Identity.Version, VersionComparer.VersionRelease)).ToList(); } else // Version range { foundPackagesMetadata = foundPackagesMetadata.Where( p => versionRange.Satisfies(p.Identity.Version)).GroupBy( p => p.Identity.Id, StringComparer.InvariantCultureIgnoreCase).SelectMany( x => x.OrderByDescending( p => p.Identity.Version, VersionComparer.VersionRelease)).ToList(); } } else // name doesn't contain wildcards { // for non wildcard names, NuGet GetMetadataAsync() API is which returns all versions for that package ordered descendingly if (versionRange != VersionRange.All) // Version range { foundPackagesMetadata = foundPackagesMetadata.Where( p => versionRange.Satisfies( p.Identity.Version, VersionComparer.VersionRelease)).OrderByDescending( p => p.Identity.Version).ToList(); } } } foreach (IPackageSearchMetadata pkg in foundPackagesMetadata) { if (!PSResourceInfo.TryConvert( metadataToParse: pkg, psGetInfo: out PSResourceInfo currentPkg, repositoryName: repositoryName, type: _type, errorMsg: out string errorMsg)) { _cmdletPassedIn.WriteError(new ErrorRecord( new PSInvalidOperationException("Error parsing IPackageSearchMetadata to PSResourceInfo with message: " + errorMsg), "IPackageSearchMetadataToPSResourceInfoParsingError", ErrorCategory.InvalidResult, this)); yield break; } if (_type != ResourceType.None) { if (_type == ResourceType.Command && !currentPkg.Type.HasFlag(ResourceType.Command)) { continue; } if (_type == ResourceType.DscResource && !currentPkg.Type.HasFlag(ResourceType.DscResource)) { continue; } } // Only going to go in here for the main package, resolve Type and Tag requirements if any, and then find dependencies if (_tag == null || (_tag != null && IsTagMatch(currentPkg))) { yield return(currentPkg); if (_includeDependencies) { foreach (PSResourceInfo pkgDep in FindDependencyPackages(currentPkg, pkgMetadataResource, sourceContext)) { yield return(pkgDep); } } } } }
public virtual NuGetPackage InstallPackage(string packageName, string version, string targetDirectory) { if (!Directory.Exists(targetDirectory)) { Directory.CreateDirectory(targetDirectory); } var packageVersion = NuGetVersion.Parse(version); var nuGetFramework = NuGetFramework.AnyFramework; var settings = Settings.LoadDefaultSettings(root: null); var sourceRepositoryProvider = new SourceRepositoryProvider( new PackageSourceProvider(settings), Repository.Provider.GetCoreV3()); using (var cacheContext = new SourceCacheContext()) { var repositories = sourceRepositoryProvider.GetRepositories(); var availablePackages = new HashSet <SourcePackageDependencyInfo>(PackageIdentityComparer.Default); GetPackageDependencies( new PackageIdentity(packageName, packageVersion), nuGetFramework, cacheContext, NullLogger.Instance, repositories, availablePackages); var resolverContext = new PackageResolverContext( DependencyBehavior.Lowest, new[] { packageName }, Enumerable.Empty <string>(), Enumerable.Empty <PackageReference>(), Enumerable.Empty <PackageIdentity>(), availablePackages, sourceRepositoryProvider.GetRepositories().Select(s => s.PackageSource), NullLogger.Instance); var resolver = new PackageResolver(); var packagesToInstall = resolver.Resolve(resolverContext, CancellationToken.None) .Select(p => availablePackages.Single(x => PackageIdentityComparer.Default.Equals(x, p))); var packagePathResolver = new PackagePathResolver(Path.GetFullPath(targetDirectory)); var packageExtractionContext = new PackageExtractionContext( PackageSaveMode.Nuspec | PackageSaveMode.Files | PackageSaveMode.Nupkg, XmlDocFileSaveMode.None, ClientPolicyContext.GetClientPolicy(settings, NullLogger.Instance), NullLogger.Instance); var downloadContext = new PackageDownloadContext(cacheContext); foreach (var packageToInstall in packagesToInstall) { var installedPath = packagePathResolver.GetInstalledPath(packageToInstall); if (installedPath != null) { continue; } var downloadResource = packageToInstall.Source .GetResourceAsync <DownloadResource>(CancellationToken.None).GetAwaiter().GetResult(); var downloadResult = downloadResource.GetDownloadResourceResultAsync( packageToInstall, downloadContext, SettingsUtility.GetGlobalPackagesFolder(settings), NullLogger.Instance, CancellationToken.None).GetAwaiter().GetResult(); PackageExtractor.ExtractPackageAsync( downloadResult.PackageSource, downloadResult.PackageStream, packagePathResolver, packageExtractionContext, CancellationToken.None).GetAwaiter().GetResult(); } } return(new NuGetPackage(Path.Combine(targetDirectory, $"{packageName}.{version}"))); }
public static (RestoreRequest, RestoreResult) Restore(ILogger logger, NuGetFramework nugetFramework, string runtimeIdentifier, string packageName, VersionRange versionRange) { var settings = NuGet.Configuration.Settings.LoadDefaultSettings(null); var assemblies = new List <string>(); var projectPath = Path.Combine("StrideNugetResolver.json"); var spec = new PackageSpec() { Name = Path.GetFileNameWithoutExtension(projectPath), // make sure this package never collides with a dependency FilePath = projectPath, Dependencies = new List <LibraryDependency>() { new LibraryDependency { LibraryRange = new LibraryRange(packageName, versionRange, LibraryDependencyTarget.Package), } }, TargetFrameworks = { new TargetFrameworkInformation { FrameworkName = nugetFramework, } }, RestoreMetadata = new ProjectRestoreMetadata { ProjectPath = projectPath, ProjectName = Path.GetFileNameWithoutExtension(projectPath), ProjectStyle = ProjectStyle.PackageReference, ProjectUniqueName = projectPath, OutputPath = Path.Combine(Path.GetTempPath(), $"StrideNugetResolver-{packageName}-{versionRange.MinVersion.ToString()}-{nugetFramework.GetShortFolderName()}-{runtimeIdentifier}"), OriginalTargetFrameworks = new[] { nugetFramework.GetShortFolderName() }, ConfigFilePaths = settings.GetConfigFilePaths(), PackagesPath = SettingsUtility.GetGlobalPackagesFolder(settings), Sources = SettingsUtility.GetEnabledSources(settings).ToList(), FallbackFolders = SettingsUtility.GetFallbackPackageFolders(settings).ToList() }, RuntimeGraph = new RuntimeGraph(new[] { new RuntimeDescription(runtimeIdentifier) }), }; using (var context = new SourceCacheContext()) { context.IgnoreFailedSources = true; var dependencyGraphSpec = new DependencyGraphSpec(); dependencyGraphSpec.AddProject(spec); dependencyGraphSpec.AddRestore(spec.RestoreMetadata.ProjectUniqueName); IPreLoadedRestoreRequestProvider requestProvider = new DependencyGraphSpecRequestProvider(new RestoreCommandProvidersCache(), dependencyGraphSpec); var restoreArgs = new RestoreArgs { AllowNoOp = true, CacheContext = context, CachingSourceProvider = new CachingSourceProvider(new PackageSourceProvider(settings)), Log = logger, }; // Create requests from the arguments var requests = requestProvider.CreateRequests(restoreArgs).Result; // Restore the packages for (int tryCount = 0; tryCount < 2; ++tryCount) { try { var results = RestoreRunner.RunWithoutCommit(requests, restoreArgs).Result; // Commit results so that noop cache works next time foreach (var result in results) { result.Result.CommitAsync(logger, CancellationToken.None).Wait(); } var mainResult = results.First(); return(mainResult.SummaryRequest.Request, mainResult.Result); } catch (Exception e) when(e is UnauthorizedAccessException || e is IOException) { // If we have an unauthorized access exception, it means assemblies are locked by running Stride process // During first try, kill some known harmless processes, and try again if (tryCount == 1) { throw; } foreach (var process in new[] { "Stride.ConnectionRouter" }.SelectMany(Process.GetProcessesByName)) { try { if (process.Id != Process.GetCurrentProcess().Id) { process.Kill(); process.WaitForExit(); } } catch (Exception) { } } } } throw new InvalidOperationException("Unreachable code"); } }
public IEnumerable <PSResourceInfo> SearchFromRepository( string repositoryName, Uri repositoryUrl) { PackageSearchResource resourceSearch; PackageMetadataResource resourceMetadata; SearchFilter filter; SourceCacheContext context; // file based Uri scheme if (repositoryUrl.Scheme == Uri.UriSchemeFile) { FindLocalPackagesResourceV2 localResource = new FindLocalPackagesResourceV2(repositoryUrl.ToString()); resourceSearch = new LocalPackageSearchResource(localResource); resourceMetadata = new LocalPackageMetadataResource(localResource); filter = new SearchFilter(_prerelease); context = new SourceCacheContext(); foreach (PSResourceInfo pkg in SearchAcrossNamesInRepository( repositoryName: repositoryName, pkgSearchResource: resourceSearch, pkgMetadataResource: resourceMetadata, searchFilter: filter, sourceContext: context)) { yield return(pkg); } yield break; } // check if ADOFeed- for which searching for Name with wildcard has a different logic flow if (repositoryUrl.ToString().Contains("pkgs.visualstudio.com")) { _isADOFeedRepository = true; } // HTTP, HTTPS, FTP Uri schemes (only other Uri schemes allowed by RepositorySettings.Read() API) PackageSource source = new PackageSource(repositoryUrl.ToString()); if (_credential != null) { string password = new NetworkCredential(string.Empty, _credential.Password).Password; source.Credentials = PackageSourceCredential.FromUserInput(repositoryUrl.ToString(), _credential.UserName, password, true, null); _cmdletPassedIn.WriteVerbose("credential successfully set for repository: " + repositoryName); } // GetCoreV3() API is able to handle V2 and V3 repository endpoints var provider = FactoryExtensionsV3.GetCoreV3(NuGet.Protocol.Core.Types.Repository.Provider); SourceRepository repository = new SourceRepository(source, provider); resourceSearch = null; resourceMetadata = null; try { resourceSearch = repository.GetResourceAsync <PackageSearchResource>().GetAwaiter().GetResult(); resourceMetadata = repository.GetResourceAsync <PackageMetadataResource>().GetAwaiter().GetResult(); } catch (Exception e) { Utils.WriteVerboseOnCmdlet(_cmdletPassedIn, "Error retrieving resource from repository: " + e.Message); } if (resourceSearch == null || resourceMetadata == null) { yield break; } filter = new SearchFilter(_prerelease); context = new SourceCacheContext(); foreach (PSResourceInfo pkg in SearchAcrossNamesInRepository( repositoryName: repositoryName, pkgSearchResource: resourceSearch, pkgMetadataResource: resourceMetadata, searchFilter: filter, sourceContext: context)) { yield return(pkg); } }
public async Task PreProcess(string directive, ScriptExecutionContext context, Action <string> logger) { var actionLogger = new NugetLogger(logger); var nugetDirective = NugetPreProcessorDirective.Parse(directive); string frameworkName = Assembly.GetEntryAssembly() !.GetCustomAttributes(true) .OfType <System.Runtime.Versioning.TargetFrameworkAttribute>() .Select(x => x.FrameworkName) .FirstOrDefault() !; NuGetFramework framework = frameworkName == null ? NuGetFramework.AnyFramework : NuGetFramework.ParseFrameworkName(frameworkName, new DefaultFrameworkNameProvider()); using var cache = new SourceCacheContext(); var packagesPath = Path.Combine(Path.GetTempPath(), "packages"); await CreateEmptyNugetConfig(packagesPath, nugetDirective.FeedUrl); var settings = Settings.LoadImmutableSettingsGivenConfigPaths(new[] { Path.Combine(packagesPath, "empty.config") }, new SettingsLoadingContext()); var availablePackages = new HashSet <SourcePackageDependencyInfo>(PackageIdentityComparer.Default); #pragma warning disable CS0618 // Type or member is obsolete var repositoryProvider = new SourceRepositoryProvider(settings, Repository.Provider.GetCoreV3()); #pragma warning restore CS0618 // Type or member is obsolete var repository = repositoryProvider.GetRepositories().FirstOrDefault(); var packageMetadataResource = await repository.GetResourceAsync <PackageMetadataResource>(CancellationToken.None); var searchMetadata = await packageMetadataResource.GetMetadataAsync( nugetDirective.PackageId, includePrerelease : false, includeUnlisted : false, cache, actionLogger, CancellationToken.None); if (!searchMetadata.Any()) { throw new NuGetResolverException($"Unable to resolve nuget package with id {nugetDirective.PackageId}"); } var latest = searchMetadata.OrderByDescending(a => a.Identity.Version).FirstOrDefault(); if (latest is null) { throw new NuGetResolverException($"Unable to resolve nuget package with id {nugetDirective.PackageId}"); } var packageId = latest.Identity; var dependencyResource = await repository.GetResourceAsync <DependencyInfoResource>(); await GetPackageDependencies( packageId, framework, cache, repository, dependencyResource, availablePackages, actionLogger); var resolverContext = new PackageResolverContext( DependencyBehavior.Lowest, new[] { nugetDirective.PackageId }, Enumerable.Empty <string>(), Enumerable.Empty <PackageReference>(), Enumerable.Empty <PackageIdentity>(), availablePackages, new[] { repository.PackageSource }, actionLogger); var resolver = new PackageResolver(); var toInstall = resolver.Resolve(resolverContext, CancellationToken.None) .Select(a => availablePackages.Single(b => PackageIdentityComparer.Default.Equals(b, a))); var pathResolver = new PackagePathResolver(packagesPath); var extractionContext = new PackageExtractionContext( PackageSaveMode.Defaultv3, XmlDocFileSaveMode.None, ClientPolicyContext.GetClientPolicy(settings, actionLogger), actionLogger); var libraries = new List <string>(); var frameworkReducer = new FrameworkReducer(); var downloadResource = await repository.GetResourceAsync <DownloadResource>(CancellationToken.None); foreach (var package in toInstall) { libraries.AddRange(await Install(downloadResource, package, pathResolver, extractionContext, frameworkReducer, framework, packagesPath, actionLogger)); } foreach (var path in libraries) { var assembly = Assembly.LoadFrom(path); if (context.TryAddReferenceAssembly(assembly)) { foreach (var ns in assembly.GetTypes().Select(a => a.Namespace).Distinct()) { context.AddImport(ns); } } } }
public static RestoreCommandProviders Create( string globalFolderPath, IEnumerable <string> fallbackPackageFolderPaths, IEnumerable <SourceRepository> sources, SourceCacheContext cacheContext, LocalPackageFileCache packageFileCache, ILogger log) { var isFallbackFolder = false; var globalPackages = new NuGetv3LocalRepository(globalFolderPath, packageFileCache, isFallbackFolder); var globalPackagesSource = Repository.Factory.GetCoreV3(globalFolderPath, FeedType.FileSystemV3); var localProviders = new List <IRemoteDependencyProvider>() { // Do not throw or warn for global cache new SourceRepositoryDependencyProvider( globalPackagesSource, log, cacheContext, ignoreFailedSources: true, ignoreWarning: true, fileCache: packageFileCache, isFallbackFolderSource: isFallbackFolder) }; // Add fallback sources as local providers also var fallbackPackageFolders = new List <NuGetv3LocalRepository>(); isFallbackFolder = true; foreach (var path in fallbackPackageFolderPaths) { var fallbackRepository = new NuGetv3LocalRepository(path, packageFileCache, isFallbackFolder); var fallbackSource = Repository.Factory.GetCoreV3(path, FeedType.FileSystemV3); var provider = new SourceRepositoryDependencyProvider( fallbackSource, log, cacheContext, ignoreFailedSources: false, ignoreWarning: false, fileCache: packageFileCache, isFallbackFolderSource: isFallbackFolder); fallbackPackageFolders.Add(fallbackRepository); localProviders.Add(provider); } isFallbackFolder = false; var remoteProviders = new List <IRemoteDependencyProvider>(); foreach (var source in sources) { var provider = new SourceRepositoryDependencyProvider( source, log, cacheContext, cacheContext.IgnoreFailedSources, ignoreWarning: false, fileCache: packageFileCache, isFallbackFolderSource: isFallbackFolder); remoteProviders.Add(provider); } return(new RestoreCommandProviders( globalPackages, fallbackPackageFolders, localProviders, remoteProviders, packageFileCache)); }
private static void Run(CommandLineApplication cmd, HttpSource httpSource, ILogger consoleLog) { cmd.Description = "Mirror nupkgs to a folder."; var output = cmd.Option("-o|--output", "Output directory for nupkgs.", CommandOptionType.SingleValue); var folderFormat = cmd.Option("--folder-format", "Output folder format. Defaults to v3. Options: (v2|v3)", CommandOptionType.SingleValue); var ignoreErrors = cmd.Option("--ignore-errors", "Continue on errors.", CommandOptionType.NoValue); var delay = cmd.Option("--delay", "Avoid downloading the very latest packages on the feed to avoid errors. This value is in minutes. Default: 10", CommandOptionType.SingleValue); var maxThreadsOption = cmd.Option("--max-threads", "Maximum number of concurrent downloads. Default: 8", CommandOptionType.SingleValue); var verbose = cmd.Option("--verbose", "Output additional network information.", CommandOptionType.NoValue); var includeIdOption = cmd.Option("-i|--include-id", "Include only these package ids or wildcards. May be provided multiple times.", CommandOptionType.MultipleValue); var excludeIdOption = cmd.Option("-e|--exclude-id", "Exclude these package ids or wildcards. May be provided multiple times.", CommandOptionType.MultipleValue); var additionalOutput = cmd.Option("--additional-output", "Additional output directory for nupkgs. The output path with the most free space will be used.", CommandOptionType.MultipleValue); var onlyLatestVersion = cmd.Option("--latest-only", "Include only the latest version of that package in the result", CommandOptionType.NoValue); var onlyStableVersion = cmd.Option("--stable-only", "Include only stable versions of that package in the result", CommandOptionType.NoValue); var startOption = cmd.Option("--start", "Beginning of the commit time range. Packages commited AFTER this time will be included. (The cursor value will not be used with this option.)", CommandOptionType.SingleValue); var endOption = cmd.Option("--end", "End of the commit time range. Packages commited at this time will be included.", CommandOptionType.SingleValue); var argRoot = cmd.Argument( "[root]", "V3 feed index.json URI", multipleValues: false); cmd.HelpOption(Constants.HelpOption); cmd.OnExecute(async() => { var timer = new Stopwatch(); timer.Start(); if (string.IsNullOrEmpty(argRoot.Value)) { throw new ArgumentException("Provide the full http url to a v3 nuget feed."); } var index = new Uri(argRoot.Value); if (!index.AbsolutePath.EndsWith("/index.json", StringComparison.OrdinalIgnoreCase)) { throw new ArgumentException($"Invalid feed url: '{argRoot.Value}'. Provide the full http url to a v3 nuget feed. For nuget.org use: https://api.nuget.org/v3/index.json"); } // Create root var outputPath = Directory.GetCurrentDirectory(); if (output.HasValue()) { outputPath = output.Value(); } var tmpCachePath = Path.Combine(outputPath, ".tmp"); var storagePaths = new HashSet <DirectoryInfo>() { new DirectoryInfo(outputPath) }; if (additionalOutput.Values?.Any() == true) { storagePaths.UnionWith(additionalOutput.Values.Select(e => new DirectoryInfo(e))); } // Create all output folders foreach (var path in storagePaths) { path.Create(); } var delayTime = TimeSpan.FromMinutes(10); if (delay.HasValue()) { if (int.TryParse(delay.Value(), out int x)) { var delayMinutes = Math.Max(0, x); delayTime = TimeSpan.FromMinutes(delayMinutes); } else { throw new ArgumentException("Invalid --delay value. This must be an integer."); } } var maxThreads = 8; if (maxThreadsOption.HasValue()) { if (int.TryParse(maxThreadsOption.Value(), out int x)) { maxThreads = Math.Max(1, x); } else { throw new ArgumentException("Invalid --max-threads value. This must be an integer."); } } var batchSize = 64; var outputRoot = new DirectoryInfo(outputPath); var outputFilesInfo = new FileInfo(Path.Combine(outputRoot.FullName, "updatedFiles.txt")); FileUtility.Delete(outputFilesInfo.FullName); var useV3Format = true; if (folderFormat.HasValue()) { switch (folderFormat.Value().ToLowerInvariant()) { case "v2": useV3Format = false; break; case "v3": useV3Format = true; break; default: throw new ArgumentException($"Invalid {folderFormat.LongName} value: '{folderFormat.Value()}'."); } } DateTimeOffset start, end; if (startOption.HasValue()) { start = DateTimeOffset.Parse(startOption.Value()); } else { start = MirrorUtility.LoadCursor(outputRoot); } if (endOption.HasValue()) { end = DateTimeOffset.Parse(endOption.Value()); } else { end = DateTimeOffset.UtcNow.Subtract(delayTime); } var token = CancellationToken.None; var mode = DownloadMode.OverwriteIfNewer; var errorLogPath = Path.Combine(outputPath, "lastRunErrors.txt"); FileUtility.Delete(errorLogPath); // Loggers // source -> deep -> file -> Console var log = new FileLogger(consoleLog, LogLevel.Error, errorLogPath); var deepLogger = new FilterLogger(log, LogLevel.Error); // Init log.LogInformation($"Mirroring {index.AbsoluteUri} -> {outputPath}"); var formatName = useV3Format ? "{id}/{version}/{id}.{version}.nupkg" : "{id}/{id}.{version}.nupkg"; log.LogInformation($"Folder format:\t{formatName}"); log.LogInformation($"Cursor:\t\t{Path.Combine(outputPath, "cursor.json")}"); log.LogInformation($"Change log:\t{outputFilesInfo.FullName}"); log.LogInformation($"Error log:\t{errorLogPath}"); log.LogInformation("Range start:\t" + start.ToString("o")); log.LogInformation("Range end:\t" + end.ToString("o")); log.LogInformation($"Batch size:\t{batchSize}"); log.LogInformation($"Threads:\t{maxThreads}"); // CatalogReader using (var cacheContext = new SourceCacheContext()) { cacheContext.SetTempRoot(tmpCachePath); using (var catalogReader = new CatalogReader(index, httpSource, cacheContext, TimeSpan.Zero, deepLogger)) { // Clear old cache files catalogReader.ClearCache(); // Find the most recent entry for each package in the range // Order by oldest first IEnumerable <CatalogEntry> entryQuery = (await catalogReader .GetFlattenedEntriesAsync(start, end, token)); // Remove all but includes if given if (includeIdOption.HasValue()) { var regex = includeIdOption.Values.Select(s => PatternUtils.WildcardToRegex(s, ignoreCase: true)).ToArray(); entryQuery = entryQuery.Where(e => regex.Any(r => r.IsMatch(e.Id))); } // Remove all excludes if given if (excludeIdOption.HasValue()) { var regex = excludeIdOption.Values.Select(s => PatternUtils.WildcardToRegex(s, ignoreCase: true)).ToArray(); entryQuery = entryQuery.Where(e => regex.All(r => !r.IsMatch(e.Id))); } // Exclude pre-release if (onlyStableVersion.HasValue()) { entryQuery = entryQuery.Where(e => !e.Version.IsPrerelease); } // Latest version only if (onlyLatestVersion.HasValue()) { entryQuery = entryQuery.GroupBy(x => x.Id, StringComparer.OrdinalIgnoreCase) .Select(y => y.OrderByDescending(z => z.Version) .First()); } var toProcess = new Queue <CatalogEntry>(entryQuery.OrderBy(e => e.CommitTimeStamp)); log.LogInformation($"Catalog entries found: {toProcess.Count}"); var done = new List <CatalogEntry>(batchSize); var complete = 0; var total = toProcess.Count; var totalDownloads = 0; // Download files var tasks = new List <Task <NupkgResult> >(maxThreads); var batchTimersMax = 20; var batchTimers = new Queue <Tuple <Stopwatch, int> >(batchTimersMax); // Download with throttling while (toProcess.Count > 0) { // Create batches var batch = new Queue <CatalogEntry>(batchSize); var files = new List <string>(); var batchTimer = new Stopwatch(); batchTimer.Start(); while (toProcess.Count > 0 && batch.Count < batchSize) { batch.Enqueue(toProcess.Dequeue()); } while (batch.Count > 0) { if (tasks.Count == maxThreads) { await CompleteTaskAsync(files, tasks, done); } var entry = batch.Dequeue(); Func <CatalogEntry, Task <FileInfo> > getNupkg = null; if (useV3Format) { getNupkg = (e) => DownloadNupkgV3Async(e, storagePaths, mode, log, deepLogger, token); } else { getNupkg = (e) => DownloadNupkgV2Async(e, storagePaths, mode, log, token); } // Queue download task tasks.Add(Task.Run(async() => await RunWithRetryAsync(entry, ignoreErrors.HasValue(), getNupkg, log, token))); } // Wait for all batch downloads while (tasks.Count > 0) { await CompleteTaskAsync(files, tasks, done); } files = files.Where(e => e != null).ToList(); // Write out new files using (var newFileWriter = new StreamWriter(new FileStream(outputFilesInfo.FullName, FileMode.Append, FileAccess.Write))) { foreach (var file in files) { newFileWriter.WriteLine(file); } } complete += done.Count; totalDownloads += files.Count; batchTimer.Stop(); batchTimers.Enqueue(new Tuple <Stopwatch, int>(batchTimer, done.Count)); while (batchTimers.Count > batchTimersMax) { batchTimers.Dequeue(); } // Update cursor var newestCommit = GetNewestCommit(done, toProcess); if (newestCommit != null) { log.LogMinimal($"================[batch complete]================"); log.LogMinimal($"Processed:\t\t{complete} / {total}"); log.LogMinimal($"Batch downloads:\t{files.Count}"); log.LogMinimal($"Batch time:\t\t{batchTimer.Elapsed}"); log.LogMinimal($"Updating cursor.json:\t{newestCommit.Value.ToString("o")}"); var rate = batchTimers.Sum(e => e.Item1.Elapsed.TotalSeconds) / Math.Max(1, batchTimers.Sum(e => e.Item2)); var timeLeft = TimeSpan.FromSeconds(rate * (total - complete)); var timeLeftString = string.Empty; if (timeLeft.TotalHours >= 1) { timeLeftString = $"{(int)timeLeft.TotalHours} hours"; } else if (timeLeft.TotalMinutes >= 1) { timeLeftString = $"{(int)timeLeft.TotalMinutes} minutes"; } else { timeLeftString = $"{(int)timeLeft.TotalSeconds} seconds"; } log.LogMinimal($"Estimated time left:\t{timeLeftString}"); log.LogMinimal($"================================================"); MirrorUtility.SaveCursor(outputRoot, newestCommit.Value); } done.Clear(); // Free up space catalogReader.ClearCache(); } // Set cursor to end time MirrorUtility.SaveCursor(outputRoot, end); timer.Stop(); var plural = totalDownloads == 1 ? "" : "s"; log.LogMinimal($"Downloaded {totalDownloads} nupkg{plural} in {timer.Elapsed.ToString()}."); } } return(0); }); }
private async Task <int> RunUpdateAsync( string documentPath, XDocument document, SourceRepository sourceRepository) { var packageMetadataResource = await sourceRepository.GetResourceAsync <PackageMetadataResource>(); var logger = new Logger(Error, Out); var hasChanged = false; using (var cacheContext = new SourceCacheContext { NoCache = true }) { var versionAttribute = document.Root.Attribute("Version"); hasChanged = await TryUpdateVersionAsync( versionAttribute, "Microsoft.AspNetCore.App", packageMetadataResource, logger, cacheContext); foreach (var package in document.Root.Descendants("Package")) { var id = package.Attribute("Id").Value; versionAttribute = package.Attribute("Version"); var attributeChanged = await TryUpdateVersionAsync( versionAttribute, id, packageMetadataResource, logger, cacheContext); hasChanged |= attributeChanged; } } if (hasChanged) { await Out.WriteLineAsync($"Updating {documentPath}."); var settings = new XmlWriterSettings { Async = true, CheckCharacters = true, CloseOutput = false, Encoding = Encoding.UTF8, Indent = true, IndentChars = " ", NewLineOnAttributes = false, OmitXmlDeclaration = true, WriteEndDocumentOnClose = true, }; using (var stream = File.OpenWrite(documentPath)) { using (var writer = XmlWriter.Create(stream, settings)) { await document.SaveAsync(writer, CancellationToken.None); } } } else { await Out.WriteLineAsync("No new versions found"); } return(0); }
private void FindDependencyPackagesHelper( PSResourceInfo currentPkg, List <PSResourceInfo> thoseToAdd, PackageMetadataResource packageMetadataResource, SourceCacheContext sourceCacheContext ) { foreach (var dep in currentPkg.Dependencies) { IEnumerable <IPackageSearchMetadata> depPkgs = packageMetadataResource.GetMetadataAsync( packageId: dep.Name, includePrerelease: _prerelease, includeUnlisted: false, sourceCacheContext: sourceCacheContext, log: NullLogger.Instance, token: _cancellationToken).GetAwaiter().GetResult(); if (depPkgs.Count() > 0) { if (dep.VersionRange == VersionRange.All) { // return latest version IPackageSearchMetadata depPkgLatestVersion = depPkgs.First(); if (!PSResourceInfo.TryConvert( metadataToParse: depPkgLatestVersion, psGetInfo: out PSResourceInfo depPSResourceInfoPkg, repositoryName: currentPkg.Repository, type: currentPkg.Type, errorMsg: out string errorMsg)) { _cmdletPassedIn.WriteError(new ErrorRecord( new PSInvalidOperationException("Error parsing dependency IPackageSearchMetadata to PSResourceInfo with message: " + errorMsg), "DependencyIPackageSearchMetadataToPSResourceInfoParsingError", ErrorCategory.InvalidResult, this)); } thoseToAdd.Add(depPSResourceInfoPkg); FindDependencyPackagesHelper(depPSResourceInfoPkg, thoseToAdd, packageMetadataResource, sourceCacheContext); } else { List <IPackageSearchMetadata> pkgVersionsInRange = depPkgs.Where( p => dep.VersionRange.Satisfies( p.Identity.Version, VersionComparer.VersionRelease)).OrderByDescending( p => p.Identity.Version).ToList(); if (pkgVersionsInRange.Count() > 0) { IPackageSearchMetadata depPkgLatestInRange = pkgVersionsInRange.First(); if (depPkgLatestInRange != null) { if (!PSResourceInfo.TryConvert( metadataToParse: depPkgLatestInRange, psGetInfo: out PSResourceInfo depPSResourceInfoPkg, repositoryName: currentPkg.Repository, type: currentPkg.Type, errorMsg: out string errorMsg)) { _cmdletPassedIn.WriteError(new ErrorRecord( new PSInvalidOperationException("Error parsing dependency range IPackageSearchMetadata to PSResourceInfo with message: " + errorMsg), "DependencyRangeIPackageSearchMetadataToPSResourceInfoParsingError", ErrorCategory.InvalidResult, this)); } thoseToAdd.Add(depPSResourceInfoPkg); FindDependencyPackagesHelper(depPSResourceInfoPkg, thoseToAdd, packageMetadataResource, sourceCacheContext); } } } } } }
private async Task <string> DownloadWithProgress(SourceRepository sourceRepository, PackageIdentity packageIdentity) { var progressDialogText = Resources.Dialog_DownloadingPackage; if (packageIdentity.HasVersion) { progressDialogText = string.Format(CultureInfo.CurrentCulture, progressDialogText, packageIdentity.Id, packageIdentity.Version); } else { progressDialogText = string.Format(CultureInfo.CurrentCulture, progressDialogText, packageIdentity.Id, string.Empty); } string description = null; int? percent = null; var updated = false; var progressDialogLock = new object(); var progressDialog = new ProgressDialog { Text = progressDialogText, WindowTitle = Resources.Dialog_Title, ShowTimeRemaining = true, CancellationText = "Canceling download..." }; // polling for Cancel button being clicked var cts = new CancellationTokenSource(); var timer = new DispatcherTimer { Interval = TimeSpan.FromMilliseconds(200) }; timer.Tick += (o, e) => { lock (progressDialogLock) { if (progressDialog.CancellationPending) { timer.Stop(); cts.Cancel(); } else if (updated) { if (!progressDialog.IsOpen) { progressDialog.ProgressBarStyle = percent.HasValue ? ProgressBarStyle.ProgressBar : ProgressBarStyle.MarqueeProgressBar; progressDialog.ShowDialog(MainWindow.Value); } progressDialog.ReportProgress(percent.GetValueOrDefault(), null, description); updated = false; } } }; timer.Start(); try { var httpProgressProvider = new ProgressHttpHandlerResourceV3Provider(OnProgress); var additionalProviders = new[] { new Lazy <INuGetResourceProvider>(() => httpProgressProvider) }; var repository = PackageRepositoryFactory.CreateRepository(sourceRepository.PackageSource, additionalProviders); var downloadResource = await repository.GetResourceAsync <DownloadResource>(cts.Token); using (var sourceCacheContext = new SourceCacheContext() { NoCache = true }) { var context = new PackageDownloadContext(sourceCacheContext, Path.GetTempPath(), true); using (var result = await downloadResource.GetDownloadResourceResultAsync(packageIdentity, context, string.Empty, NullLogger.Instance, cts.Token)) { if (result.Status == DownloadResourceResultStatus.Cancelled) { throw new OperationCanceledException(); } if (result.Status == DownloadResourceResultStatus.NotFound) { throw new Exception(string.Format("Package '{0} {1}' not found", packageIdentity.Id, packageIdentity.Version)); } var tempFilePath = Path.GetTempFileName(); using (var fileStream = File.OpenWrite(tempFilePath)) { await result.PackageStream.CopyToAsync(fileStream); } return(tempFilePath); } } } catch (OperationCanceledException) { return(null); } catch (Exception exception) { OnError(exception); return(null); } finally { timer.Stop(); // close progress dialog when done lock (progressDialogLock) { progressDialog.Close(); progressDialog = null; } MainWindow.Value.Activate(); } void OnProgress(long bytesReceived, long?totalBytes) { if (totalBytes.HasValue) { percent = (int)((bytesReceived * 100L) / totalBytes); description = string.Format( CultureInfo.CurrentCulture, "Downloaded {0} of {1}...", FileSizeConverter.Convert(bytesReceived, typeof(string), null, CultureInfo.CurrentCulture), FileSizeConverter.Convert(totalBytes.Value, typeof(string), null, CultureInfo.CurrentCulture)); } else { percent = null; description = string.Format( CultureInfo.CurrentCulture, "Downloaded {0}...", FileSizeConverter.Convert(bytesReceived, typeof(string), null, CultureInfo.CurrentCulture)); } updated = true; } }
public async Task <PackageReaderBase> GetPackageAsync(string packageId, NuGetVersion version, bool includePrerelease, CancellationToken cancellationToken = default) { // if a version is specified, check locally, otherwise check all sources for the latest LocalPackageInfo package = null; if (version != null) { package = m_localRepository.FindPackage(packageId, version); } if (package != null) { return(await GetLocalPackageAsync(package.ZipPath, cancellationToken).ConfigureAwait(false)); } using (var context = new SourceCacheContext()) { if (version != null) { var repos = await Task.WhenAll(m_repositories.Select(async repo => { var metadata = await repo.GetResourceAsync <MetadataResource>(cancellationToken).ConfigureAwait(false); var versions = await metadata.GetVersions(packageId, includePrerelease, includeUnlisted: false, context, Logger, cancellationToken).ConfigureAwait(false); if (versions.Contains(version)) { return(repo); } return(null); })).ConfigureAwait(false); var repository = repos.FirstOrDefault(x => x != null); if (repository != null) { var packageIdentity = new PackageIdentity(packageId, version); return(await DownloadPackageAsync(context, repository, packageIdentity, cancellationToken).ConfigureAwait(false)); } } else { var repoVersions = await Task.WhenAll(m_repositories.Select(async repo => { var metadata = await repo.GetResourceAsync <MetadataResource>(cancellationToken).ConfigureAwait(false); var ver = await metadata.GetLatestVersion(packageId, includePrerelease, includeUnlisted: false, context, Logger, cancellationToken).ConfigureAwait(false); return(repository: repo, version: ver); })).ConfigureAwait(false); var(repository, latestVersion) = repoVersions.OrderByDescending(x => x.version).FirstOrDefault(); if (latestVersion != null) { var packageIdentity = new PackageIdentity(packageId, latestVersion); return(await DownloadPackageAsync(context, repository, packageIdentity, cancellationToken).ConfigureAwait(false)); } } } return(null); async Task <PackageReaderBase> DownloadPackageAsync(SourceCacheContext context, SourceRepository repository, PackageIdentity packageIdentity, CancellationToken cancellationToken) { var downloadResource = await repository.GetResourceAsync <DownloadResource>(cancellationToken).ConfigureAwait(false); var downloadResult = await downloadResource.GetDownloadResourceResultAsync( packageIdentity, new PackageDownloadContext(context), m_globalPackagesFolder, Logger, cancellationToken).ConfigureAwait(false); return(downloadResult.PackageReader); } }
public async Task FindPackage_VerifyPackageSourcesAreFilteredWhenPackageSourceMappingIsEnabled_Success() { // Arrange const string packageX = "x", packageY = "y", version = "1.0.0-beta.1", source1 = "source1", source2 = "source2"; var range = new LibraryRange(packageX, VersionRange.Parse(version), LibraryDependencyTarget.Package); var cacheContext = new SourceCacheContext(); var testLogger = new TestLogger(); var framework = NuGetFramework.Parse("net45"); var token = CancellationToken.None; var edge = new GraphEdge <RemoteResolveResult>(null, null, null); var actualIdentity = new LibraryIdentity(packageX, NuGetVersion.Parse(version), LibraryType.Package); var dependencies = new[] { new LibraryDependency() { LibraryRange = new LibraryRange(packageY, VersionRange.All, LibraryDependencyTarget.Package) } }; var dependencyInfo = LibraryDependencyInfo.Create(actualIdentity, framework, dependencies); var downloadCount = 0; //package source mapping configuration Dictionary <string, IReadOnlyList <string> > patterns = new(); patterns.Add(source2, new List <string>() { packageX }); patterns.Add(source1, new List <string>() { packageY }); PackageSourceMapping sourceMappingConfiguration = new(patterns); var context = new RemoteWalkContext(cacheContext, sourceMappingConfiguration, testLogger); // Source1 returns 1.0.0-beta.1 var remoteProvider = new Mock <IRemoteDependencyProvider>(); remoteProvider.Setup(e => e.FindLibraryAsync(range, It.IsAny <NuGetFramework>(), It.IsAny <SourceCacheContext>(), testLogger, token)) .ReturnsAsync(actualIdentity); remoteProvider.SetupGet(e => e.IsHttp).Returns(true); remoteProvider.SetupGet(e => e.Source).Returns(new PackageSource(source1)); remoteProvider.Setup(e => e.GetDependenciesAsync(It.IsAny <LibraryIdentity>(), It.IsAny <NuGetFramework>(), It.IsAny <SourceCacheContext>(), testLogger, token)) .ReturnsAsync(dependencyInfo) .Callback(() => ++ downloadCount); context.RemoteLibraryProviders.Add(remoteProvider.Object); // Source2 returns 1.0.0-beta.1 var remoteProvider2 = new Mock <IRemoteDependencyProvider>(); remoteProvider2.Setup(e => e.FindLibraryAsync(range, It.IsAny <NuGetFramework>(), It.IsAny <SourceCacheContext>(), testLogger, token)) .ReturnsAsync(actualIdentity); remoteProvider2.SetupGet(e => e.IsHttp).Returns(true); remoteProvider2.SetupGet(e => e.Source).Returns(new PackageSource(source2)); remoteProvider2.Setup(e => e.GetDependenciesAsync(It.IsAny <LibraryIdentity>(), It.IsAny <NuGetFramework>(), It.IsAny <SourceCacheContext>(), testLogger, token)) .ReturnsAsync(dependencyInfo) .Callback(() => ++ downloadCount); context.RemoteLibraryProviders.Add(remoteProvider2.Object); // Act var result = await ResolverUtility.FindLibraryEntryAsync(range, framework, null, context, token); // Assert // Verify only one download happened from the expected source i.e. source2 Assert.Equal(1, downloadCount); Assert.Equal(1, testLogger.DebugMessages.Count); testLogger.DebugMessages.TryPeek(out string message); Assert.Equal($"Package source mapping matches found for package ID '{packageX}' are: '{source2}'.", message); Assert.Equal(version, result.Key.Version.ToString()); Assert.Equal(source2, result.Data.Match.Provider.Source.Name); }
public async Task <List <IPackageSearchMetadata> > DownloadAndInstall(PackageIdentity identity) { var result = new List <IPackageSearchMetadata>(); using (var cacheContext = new SourceCacheContext()) { var repositories = SourceRepositoryProvider.GetRepositories(); var availablePackages = new HashSet <SourcePackageDependencyInfo>(PackageIdentityComparer.Default); await GetPackageDependencies(identity, cacheContext, availablePackages); var resolverContext = new PackageResolverContext( DependencyBehavior.Lowest, new[] { identity.Id }, Enumerable.Empty <string>(), Enumerable.Empty <NuGet.Packaging.PackageReference>(), Enumerable.Empty <PackageIdentity>(), availablePackages, SourceRepositoryProvider.GetRepositories().Select(s => s.PackageSource), NullLogger.Instance); var resolver = new PackageResolver(); var packagesToInstall = resolver.Resolve(resolverContext, CancellationToken.None) .Select(p => availablePackages.Single(x => PackageIdentityComparer.Default.Equals(x, p))); var packagePathResolver = new NuGet.Packaging.PackagePathResolver(Packagesfolder); var clientPolicyContext = NuGet.Packaging.Signing.ClientPolicyContext.GetClientPolicy(Settings, OpenRPAPackageManagerLogger.Instance); var packageExtractionContext = new PackageExtractionContext(PackageSaveMode.Defaultv3, XmlDocFileSaveMode.None, clientPolicyContext, OpenRPAPackageManagerLogger.Instance); var frameworkReducer = new FrameworkReducer(); foreach (var packageToInstall in packagesToInstall) { // PackageReaderBase packageReader; var installedPath = packagePathResolver.GetInstalledPath(packageToInstall); if (installedPath == null) { var downloadResource = await packageToInstall.Source.GetResourceAsync <DownloadResource>(CancellationToken.None); var downloadResult = await downloadResource.GetDownloadResourceResultAsync( packageToInstall, new PackageDownloadContext(cacheContext), NuGet.Configuration.SettingsUtility.GetGlobalPackagesFolder(Settings), NullLogger.Instance, CancellationToken.None); await PackageExtractor.ExtractPackageAsync( downloadResult.PackageSource, downloadResult.PackageStream, packagePathResolver, packageExtractionContext, CancellationToken.None); // packageReader = downloadResult.PackageReader; } //else //{ // packageReader = new PackageFolderReader(installedPath); //} InstallPackage(packageToInstall); } } return(result); }
private async Task OrderPackagesForPackagesConfigAsync( NuGetPackageManager packageManager, IDictionary <NuGetFramework, ISet <PackageIdentity> > packagesConfigInstalled, ISet <PackageIdentity> finishedPackages, IList <PackageItem> installedPackages, CancellationToken token) { token.ThrowIfCancellationRequested(); // Get the path to the Packages folder. var packagesFolderPath = packageManager.PackagesFolderSourceRepository.PackageSource.Source; var packagePathResolver = new PackagePathResolver(Path.GetFullPath(packagesFolderPath)); var packagesToSort = new HashSet <ResolverPackage>(); var resolvedPackages = new HashSet <PackageIdentity>(); var dependencyInfoResource = await packageManager .PackagesFolderSourceRepository .GetResourceAsync <DependencyInfoResource>(); using (var sourceCacheContext = new SourceCacheContext()) { // Order by the highest framework first to make this deterministic // Process each framework/id/version once to avoid duplicate work // Packages may have different dependency orders depending on the framework, but there is // no way to fully solve this across an entire solution so we make a best effort here. foreach (var framework in packagesConfigInstalled.Keys.OrderByDescending(fw => fw, new NuGetFrameworkSorter())) { foreach (var package in packagesConfigInstalled[framework]) { if (resolvedPackages.Add(package)) { var dependencyInfo = await dependencyInfoResource.ResolvePackage( package, framework, sourceCacheContext, NullLogger.Instance, token); // This will be null for unrestored packages if (dependencyInfo != null) { packagesToSort.Add(new ResolverPackage(dependencyInfo, listed: true, absent: false)); } } } } } token.ThrowIfCancellationRequested(); // Order packages by dependency order var sortedPackages = ResolverUtility.TopologicalSort(packagesToSort); foreach (var package in sortedPackages) { if (!finishedPackages.Contains(package)) { var installPath = packagePathResolver.GetInstalledPath(package); if (!string.IsNullOrEmpty(installPath)) { installedPackages.Add(new PackageItem(package, installPath)); finishedPackages.Add(package); } } } }
public DependencyGraph Analyze(string packageId, string version, string framework) { var package = new PackageIdentity(packageId, NuGetVersion.Parse(version)); var settings = Settings.LoadDefaultSettings(root: null, configFileName: null, machineWideSettings: null); var sourceRepositoryProvider = new SourceRepositoryProvider(new PackageSourceProvider(settings), Repository.Provider.GetCoreV3()); var nuGetFramework = NuGetFramework.ParseFolder(framework); var nugetLogger = _logger.AsNuGetLogger(); using (var cacheContext = new SourceCacheContext()) { var repositories = sourceRepositoryProvider.GetRepositories(); var resolvedPackages = new ConcurrentDictionary <PackageIdentity, SourcePackageDependencyInfo>(PackageIdentityComparer.Default); ResolvePackage(package, nuGetFramework, cacheContext, nugetLogger, repositories, resolvedPackages).Wait(); var availablePackages = new HashSet <SourcePackageDependencyInfo>(resolvedPackages.Values); var resolverContext = new PackageResolverContext( DependencyBehavior.Lowest, new[] { packageId }, Enumerable.Empty <string>(), Enumerable.Empty <PackageReference>(), Enumerable.Empty <PackageIdentity>(), availablePackages, sourceRepositoryProvider.GetRepositories().Select(s => s.PackageSource), nugetLogger); var resolver = new PackageResolver(); var prunedPackages = resolver.Resolve(resolverContext, CancellationToken.None) .Select(x => resolvedPackages[x]); var rootNode = new PackageReferenceNode(package.Id, package.Version.ToString()); var packageNodes = new Dictionary <string, PackageReferenceNode>(StringComparer.OrdinalIgnoreCase); var builder = new DependencyGraph.Builder(rootNode); foreach (var target in prunedPackages) { var downloadResource = target.Source.GetResource <DownloadResource>(); var downloadResult = downloadResource.GetDownloadResourceResultAsync(new PackageIdentity(target.Id, target.Version), new PackageDownloadContext(cacheContext), SettingsUtility.GetGlobalPackagesFolder(settings), nugetLogger, CancellationToken.None).Result; var libItems = downloadResult.PackageReader.GetLibItems(); var reducer = new FrameworkReducer(); var nearest = reducer.GetNearest(nuGetFramework, libItems.Select(x => x.TargetFramework)); var assemblyReferences = libItems .Where(x => x.TargetFramework.Equals(nearest)) .SelectMany(x => x.Items) .Where(x => Path.GetExtension(x).Equals(".dll", StringComparison.OrdinalIgnoreCase)) .Select(x => new AssemblyReferenceNode(Path.GetFileName(x))); var frameworkItems = downloadResult.PackageReader.GetFrameworkItems(); nearest = reducer.GetNearest(nuGetFramework, frameworkItems.Select(x => x.TargetFramework)); assemblyReferences = assemblyReferences.Concat(frameworkItems .Where(x => x.TargetFramework.Equals(nearest)) .SelectMany(x => x.Items) .Select(x => new AssemblyReferenceNode(x))); var packageReferenceNode = new PackageReferenceNode(target.Id, target.Version.ToString()); builder.WithNode(packageReferenceNode); builder.WithNodes(assemblyReferences); builder.WithEdges(assemblyReferences.Select(x => new Edge(packageReferenceNode, x))); packageNodes.Add(target.Id, packageReferenceNode); } foreach (var target in prunedPackages) { var packageReferenceNode = packageNodes[target.Id]; builder.WithEdges(target.Dependencies.Select(x => new Edge(packageReferenceNode, packageNodes[x.Id], x.VersionRange.ToString()))); } return(builder.Build()); } }
/// <summary> /// Update or reinstall all packages installed to a solution. For Update-Package or Update-Package -Reinstall. /// </summary> /// <returns></returns> private async Task UpdateOrReinstallAllPackagesAsync() { try { using (var sourceCacheContext = new SourceCacheContext()) { var resolutionContext = new ResolutionContext( GetDependencyBehavior(), _allowPrerelease, ShouldAllowDelistedPackages(), DetermineVersionConstraints(), new GatherCache(), sourceCacheContext); // if the source is explicitly specified we will use exclusively that source otherwise use ALL enabled sources var actions = await PackageManager.PreviewUpdatePackagesAsync( Projects, resolutionContext, this, PrimarySourceRepositories, PrimarySourceRepositories, Token); if (!actions.Any()) { _status = NuGetOperationStatus.NoOp; } else { _packageCount = actions.Select(action => action.PackageIdentity.Id).Distinct().Count(); } await ExecuteActions(actions, sourceCacheContext); } } catch (SignatureException ex) { // set nuget operation status to failed when an exception is thrown _status = NuGetOperationStatus.Failed; if (!string.IsNullOrEmpty(ex.Message)) { Log(ex.AsLogMessage()); } if (ex.Results != null) { var logMessages = ex.Results.SelectMany(p => p.Issues).ToList(); logMessages.ForEach(p => Log(ex.AsLogMessage())); } } catch (Exception ex) { _status = NuGetOperationStatus.Failed; Log(MessageLevel.Error, ExceptionUtilities.DisplayMessage(ex)); } finally { BlockingCollection.Add(new ExecutionCompleteMessage()); } }
public async Task Download(PackageIdentity identity) { var packagePathResolver = new NuGet.Packaging.PackagePathResolver(Packagesfolder); var installedPath = packagePathResolver.GetInstalledPath(identity); if (identity.HasVersion && !string.IsNullOrEmpty(installedPath)) { var idstring = identity.Id + "." + identity.Version; if (installedPath.Contains(idstring)) { return; } } var result = new List <IPackageSearchMetadata>(); using (var cacheContext = new SourceCacheContext()) { var repositories = SourceRepositoryProvider.GetRepositories(); var availablePackages = new HashSet <SourcePackageDependencyInfo>(PackageIdentityComparer.Default); await GetPackageWithoutDependencies(identity, cacheContext, availablePackages); var resolverContext = new PackageResolverContext( DependencyBehavior.Lowest, new[] { identity.Id }, Enumerable.Empty <string>(), Enumerable.Empty <NuGet.Packaging.PackageReference>(), Enumerable.Empty <PackageIdentity>(), availablePackages, SourceRepositoryProvider.GetRepositories().Select(s => s.PackageSource), Logger); var packageToInstall = availablePackages.Where(p => p.Id == identity.Id).FirstOrDefault(); // var packagePathResolver = new NuGet.Packaging.PackagePathResolver(Packagesfolder); var clientPolicyContext = NuGet.Packaging.Signing.ClientPolicyContext.GetClientPolicy(Settings, Logger); var packageExtractionContext = new PackageExtractionContext(PackageSaveMode.Defaultv3, XmlDocFileSaveMode.None, clientPolicyContext, Logger); var frameworkReducer = new FrameworkReducer(); // PackageReaderBase packageReader; installedPath = packagePathResolver.GetInstalledPath(packageToInstall); //if (installedPath == null) //{ var downloadResource = await packageToInstall.Source.GetResourceAsync <DownloadResource>(CancellationToken.None); var downloadResult = await downloadResource.GetDownloadResourceResultAsync( packageToInstall, new PackageDownloadContext(cacheContext), NuGet.Configuration.SettingsUtility.GetGlobalPackagesFolder(Settings), Logger, CancellationToken.None); await PackageExtractor.ExtractPackageAsync( downloadResult.PackageSource, downloadResult.PackageStream, packagePathResolver, packageExtractionContext, CancellationToken.None); // packageReader = downloadResult.PackageReader; // } //else //{ // packageReader = new PackageFolderReader(installedPath); //} } return; }
public override async Task ExecuteCommandAsync() { if (DisableParallelProcessing) { HttpSourceResourceProvider.Throttle = SemaphoreSlimThrottle.CreateBinarySemaphore(); } CalculateEffectivePackageSaveMode(); var restoreSummaries = new List <RestoreSummary>(); _msbuildDirectory = MsBuildUtility.GetMsBuildDirectoryFromMsBuildPath(MSBuildPath, MSBuildVersion, Console); if (!string.IsNullOrEmpty(SolutionDirectory)) { SolutionDirectory = Path.GetFullPath(SolutionDirectory); } var restoreInputs = await DetermineRestoreInputsAsync(); var hasPackagesConfigFiles = restoreInputs.PackagesConfigFiles.Count > 0; var hasProjectJsonOrPackageReferences = restoreInputs.RestoreV3Context.Inputs.Any(); if (!hasPackagesConfigFiles && !hasProjectJsonOrPackageReferences) { Console.LogMinimal(LocalizedResourceManager.GetString(restoreInputs.RestoringWithSolutionFile ? "SolutionRestoreCommandNoPackagesConfigOrProjectJson" : "ProjectRestoreCommandNoPackagesConfigOrProjectJson")); return; } // packages.config if (hasPackagesConfigFiles) { var v2RestoreResult = await PerformNuGetV2RestoreAsync(restoreInputs); restoreSummaries.Add(v2RestoreResult); } // project.json and PackageReference if (hasProjectJsonOrPackageReferences) { // Read the settings outside of parallel loops. ReadSettings(restoreInputs); // Check if we can restore based on the nuget.config settings CheckRequireConsent(); using (var cacheContext = new SourceCacheContext()) { cacheContext.NoCache = NoCache; cacheContext.DirectDownload = DirectDownload; var restoreContext = restoreInputs.RestoreV3Context; var providerCache = new RestoreCommandProvidersCache(); // Add restore args to the restore context restoreContext.CacheContext = cacheContext; restoreContext.DisableParallel = DisableParallelProcessing; restoreContext.AllowNoOp = !Force; // if force, no-op is not allowed restoreContext.ConfigFile = ConfigFile; restoreContext.MachineWideSettings = MachineWideSettings; restoreContext.Log = Console; restoreContext.CachingSourceProvider = GetSourceRepositoryProvider(); var packageSaveMode = EffectivePackageSaveMode; if (packageSaveMode != Packaging.PackageSaveMode.None) { restoreContext.PackageSaveMode = EffectivePackageSaveMode; } // Providers // Use the settings loaded above in ReadSettings(restoreInputs) if (restoreInputs.ProjectReferenceLookup.Restore.Count > 0) { // Remove input list, everything has been loaded already restoreContext.Inputs.Clear(); restoreContext.PreLoadedRequestProviders.Add(new DependencyGraphSpecRequestProvider( providerCache, restoreInputs.ProjectReferenceLookup)); } else { // Allow an external .dg file restoreContext.RequestProviders.Add(new DependencyGraphFileRequestProvider(providerCache)); } // Run restore var v3Summaries = await RestoreRunner.RunAsync(restoreContext); restoreSummaries.AddRange(v3Summaries); } } // Summaries RestoreSummary.Log(Console, restoreSummaries, logErrors: true); if (restoreSummaries.Any(x => !x.Success)) { throw new ExitCodeException(exitCode: 1); } }
public static async Task Main() { var packageId = "cake.nuget"; var packageVersion = NuGetVersion.Parse("0.30.0"); var nuGetFramework = NuGetFramework.ParseFolder("net46"); var settings = Settings.LoadDefaultSettings(root: null); var packageSourceProvider = new PackageSourceProvider( settings, new PackageSource[] { new PackageSource("https://api.nuget.org/v3/index.json") }); var sourceRepositoryProvider = new SourceRepositoryProvider(packageSourceProvider, Repository.Provider.GetCoreV3()); using (var cacheContext = new SourceCacheContext()) { var repositories = sourceRepositoryProvider.GetRepositories(); var availablePackages = new HashSet <SourcePackageDependencyInfo>(PackageIdentityComparer.Default); await GetPackageDependencies( new PackageIdentity(packageId, packageVersion), nuGetFramework, cacheContext, NullLogger.Instance, repositories, availablePackages); var resolverContext = new PackageResolverContext( DependencyBehavior.Lowest, new[] { packageId }, Enumerable.Empty <string>(), Enumerable.Empty <PackageReference>(), Enumerable.Empty <PackageIdentity>(), availablePackages, sourceRepositoryProvider.GetRepositories().Select(s => s.PackageSource), NullLogger.Instance); var resolver = new PackageResolver(); var packagesToInstall = resolver.Resolve(resolverContext, CancellationToken.None) .Select(p => availablePackages.Single(x => PackageIdentityComparer.Default.Equals(x, p))); var packagePathResolver = new PackagePathResolver(Path.GetFullPath("packages")); var packageExtractionContext = new PackageExtractionContext( PackageSaveMode.Defaultv3, XmlDocFileSaveMode.None, ClientPolicyContext.GetClientPolicy(settings, NullLogger.Instance), NullLogger.Instance); var frameworkReducer = new FrameworkReducer(); foreach (var packageToInstall in packagesToInstall) { PackageReaderBase packageReader; var installedPath = packagePathResolver.GetInstalledPath(packageToInstall); if (installedPath == null) { var downloadResource = await packageToInstall.Source.GetResourceAsync <DownloadResource>(CancellationToken.None); var downloadResult = await downloadResource.GetDownloadResourceResultAsync( packageToInstall, new PackageDownloadContext(cacheContext), SettingsUtility.GetGlobalPackagesFolder(settings), NullLogger.Instance, CancellationToken.None); await PackageExtractor.ExtractPackageAsync( downloadResult.PackageSource, downloadResult.PackageStream, packagePathResolver, packageExtractionContext, CancellationToken.None); packageReader = downloadResult.PackageReader; } else { packageReader = new PackageFolderReader(installedPath); } var libItems = packageReader.GetLibItems(); var nearest = frameworkReducer.GetNearest(nuGetFramework, libItems.Select(x => x.TargetFramework)); Console.WriteLine(string.Join("\n", libItems .Where(x => x.TargetFramework.Equals(nearest)) .SelectMany(x => x.Items))); var frameworkItems = packageReader.GetFrameworkItems(); nearest = frameworkReducer.GetNearest(nuGetFramework, frameworkItems.Select(x => x.TargetFramework)); Console.WriteLine(string.Join("\n", frameworkItems .Where(x => x.TargetFramework.Equals(nearest)) .SelectMany(x => x.Items))); } } async Task GetPackageDependencies(PackageIdentity package, NuGetFramework framework, SourceCacheContext cacheContext, ILogger logger, IEnumerable <SourceRepository> repositories, ISet <SourcePackageDependencyInfo> availablePackages) { if (availablePackages.Contains(package)) { 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> /// Asynchronously copies a .nupkg to a stream. /// </summary> /// <param name="id">A package ID.</param> /// <param name="version">A package version.</param> /// <param name="destination">A destination stream.</param> /// <param name="cacheContext">A source cache context.</param> /// <param name="logger">A logger.</param> /// <param name="cancellationToken">A cancellation token.</param> /// <returns>A task that represents the asynchronous operation. /// The task result (<see cref="Task{TResult}.Result" />) returns an /// <see cref="bool" /> indicating whether or not the .nupkg file was copied.</returns> /// <exception cref="ArgumentException">Thrown if <paramref name="id" /> /// is either <c>null</c> or an empty string.</exception> /// <exception cref="ArgumentNullException">Thrown if <paramref name="version" /> <c>null</c>.</exception> /// <exception cref="ArgumentNullException">Thrown if <paramref name="destination" /> <c>null</c>.</exception> /// <exception cref="ArgumentNullException">Thrown if <paramref name="cacheContext" /> <c>null</c>.</exception> /// <exception cref="ArgumentNullException">Thrown if <paramref name="logger" /> <c>null</c>.</exception> /// <exception cref="OperationCanceledException">Thrown if <paramref name="cancellationToken" /> /// is cancelled.</exception> public override async Task <bool> CopyNupkgToStreamAsync( string id, NuGetVersion version, Stream destination, SourceCacheContext cacheContext, ILogger logger, CancellationToken cancellationToken) { if (string.IsNullOrEmpty(id)) { throw new ArgumentException(Strings.ArgumentCannotBeNullOrEmpty, nameof(id)); } if (version == null) { throw new ArgumentNullException(nameof(version)); } if (destination == null) { throw new ArgumentNullException(nameof(destination)); } if (cacheContext == null) { throw new ArgumentNullException(nameof(cacheContext)); } if (logger == null) { throw new ArgumentNullException(nameof(logger)); } var stopwatch = Stopwatch.StartNew(); try { cancellationToken.ThrowIfCancellationRequested(); var info = GetPackageInfo(id, version, cacheContext, logger); if (info != null) { using (var fileStream = File.OpenRead(info.Path)) { await fileStream.CopyToAsync(destination, cancellationToken); ProtocolDiagnostics.RaiseEvent(new ProtocolDiagnosticNupkgCopiedEvent(_source, destination.Length)); return(true); } } return(false); } finally { ProtocolDiagnostics.RaiseEvent(new ProtocolDiagnosticResourceEvent( _source, ResourceTypeName, ThisTypeName, nameof(CopyNupkgToStreamAsync), stopwatch.Elapsed)); } }
private async Task PerformV2RestoreAsync(string packagesConfigFilePath, string installPath) { var sourceRepositoryProvider = GetSourceRepositoryProvider(); var nuGetPackageManager = new NuGetPackageManager(sourceRepositoryProvider, Settings, installPath, ExcludeVersion); var installedPackageReferences = GetInstalledPackageReferences( packagesConfigFilePath, allowDuplicatePackageIds: true); var packageRestoreData = installedPackageReferences.Select(reference => new PackageRestoreData( reference, new[] { packagesConfigFilePath }, isMissing: true)); var packageSources = GetPackageSources(Settings); Console.PrintPackageSources(packageSources); var failedEvents = new ConcurrentQueue <PackageRestoreFailedEventArgs>(); var packageRestoreContext = new PackageRestoreContext( nuGetPackageManager, packageRestoreData, CancellationToken.None, packageRestoredEvent: null, packageRestoreFailedEvent: (sender, args) => { failedEvents.Enqueue(args); }, sourceRepositories: packageSources.Select(sourceRepositoryProvider.CreateRepository), maxNumberOfParallelTasks: DisableParallelProcessing ? 1 : PackageManagementConstants.DefaultMaxDegreeOfParallelism, logger: Console); var packageSaveMode = Packaging.PackageSaveMode.Defaultv2; if (EffectivePackageSaveMode != Packaging.PackageSaveMode.None) { packageSaveMode = EffectivePackageSaveMode; } var missingPackageReferences = installedPackageReferences.Where(reference => !nuGetPackageManager.PackageExistsInPackagesFolder(reference.PackageIdentity, packageSaveMode)).Any(); if (!missingPackageReferences) { var message = string.Format( CultureInfo.CurrentCulture, LocalizedResourceManager.GetString("InstallCommandNothingToInstall"), packagesConfigFilePath); Console.LogMinimal(message); } using (var cacheContext = new SourceCacheContext()) { cacheContext.NoCache = NoCache; cacheContext.DirectDownload = DirectDownload; var clientPolicyContext = ClientPolicyContext.GetClientPolicy(Settings, Console); var projectContext = new ConsoleProjectContext(Console) { PackageExtractionContext = new PackageExtractionContext( packageSaveMode, PackageExtractionBehavior.XmlDocFileSaveMode, clientPolicyContext, Console) }; var packageSourceMapping = PackageSourceMapping.GetPackageSourceMapping(Settings); var downloadContext = new PackageDownloadContext(cacheContext, installPath, DirectDownload, packageSourceMapping) { ClientPolicyContext = clientPolicyContext }; var result = await PackageRestoreManager.RestoreMissingPackagesAsync( packageRestoreContext, projectContext, downloadContext); if (downloadContext.DirectDownload) { GetDownloadResultUtility.CleanUpDirectDownloads(downloadContext); } // Use failure count to determine errors. result.Restored will be false for noop restores. if (failedEvents.Count > 0) { // Log errors if they exist foreach (var message in failedEvents.Select(e => new RestoreLogMessage(LogLevel.Error, NuGetLogCode.Undefined, e.Exception.Message))) { await Console.LogAsync(message); } throw new ExitCodeException(1); } } }
private async Task UpdatePackagesAsync(MSBuildProjectSystem project, string packagesDirectory) { var sourceRepositoryProvider = GetSourceRepositoryProvider(); var packageManager = new NuGetPackageManager(sourceRepositoryProvider, Settings, packagesDirectory); var nugetProject = new MSBuildNuGetProject(project, packagesDirectory, project.ProjectFullPath); if (!nugetProject.PackagesConfigNuGetProject.PackagesConfigExists()) { throw new CommandException(LocalizedResourceManager.GetString("NoPackagesConfig")); } var versionConstraints = Safe ? VersionConstraints.ExactMajor | VersionConstraints.ExactMinor : VersionConstraints.None; var projectActions = new List <NuGetProjectAction>(); using (var sourceCacheContext = new SourceCacheContext()) { var resolutionContext = new ResolutionContext( Resolver.DependencyBehavior.Highest, Prerelease, includeUnlisted: false, versionConstraints: versionConstraints, gatherCache: new GatherCache(), sourceCacheContext: sourceCacheContext); var packageSources = GetPackageSources(); Console.PrintPackageSources(packageSources); var sourceRepositories = packageSources.Select(sourceRepositoryProvider.CreateRepository); if (Id.Count > 0) { var targetIds = new HashSet <string>(Id, StringComparer.OrdinalIgnoreCase); var installed = await nugetProject.GetInstalledPackagesAsync(CancellationToken.None); // If -Id has been specified and has exactly one package, use the explicit version requested var targetVersion = Version != null && Id != null && Id.Count == 1 ? new NuGetVersion(Version) : null; var targetIdentities = installed .Select(pr => pr.PackageIdentity.Id) .Where(id => targetIds.Contains(id)) .Select(id => new PackageIdentity(id, targetVersion)) .ToList(); if (targetIdentities.Any()) { var actions = await packageManager.PreviewUpdatePackagesAsync( targetIdentities, new[] { nugetProject }, resolutionContext, project.NuGetProjectContext, sourceRepositories, Enumerable.Empty <SourceRepository>(), CancellationToken.None); projectActions.AddRange(actions); } } else { var actions = await packageManager.PreviewUpdatePackagesAsync( new[] { nugetProject }, resolutionContext, project.NuGetProjectContext, sourceRepositories, Enumerable.Empty <SourceRepository>(), CancellationToken.None); projectActions.AddRange(actions); } await packageManager.ExecuteNuGetProjectActionsAsync( nugetProject, projectActions, project.NuGetProjectContext, sourceCacheContext, CancellationToken.None); } project.Save(); }
private async Task InstallPackageAsync( string packageId, NuGetVersion version, string installPath) { if (version == null) { // Avoid searching for the highest version in the global packages folder, // it needs to come from the feeds instead. Once found it may come from // the global packages folder unless NoCache is true. ExcludeCacheAsSource = true; } var framework = GetTargetFramework(); // Create the project and set the framework if available. var project = new InstallCommandProject( root: installPath, packagePathResolver: new PackagePathResolver(installPath, !ExcludeVersion), targetFramework: framework); var sourceRepositoryProvider = GetSourceRepositoryProvider(); var packageManager = new NuGetPackageManager(sourceRepositoryProvider, Settings, installPath); var packageSources = GetPackageSources(Settings); var primaryRepositories = packageSources.Select(sourceRepositoryProvider.CreateRepository); Console.PrintPackageSources(packageSources); var allowPrerelease = Prerelease || (version != null && version.IsPrerelease); var dependencyBehavior = DependencyBehaviorHelper.GetDependencyBehavior(DependencyBehavior.Lowest, DependencyVersion, Settings); using (var sourceCacheContext = new SourceCacheContext()) { var resolutionContext = new ResolutionContext( dependencyBehavior, includePrelease: allowPrerelease, includeUnlisted: false, versionConstraints: VersionConstraints.None, gatherCache: new GatherCache(), sourceCacheContext: sourceCacheContext); if (version == null) { // Write out a helpful message before the http messages are shown Console.Log(LogLevel.Minimal, string.Format( CultureInfo.CurrentCulture, LocalizedResourceManager.GetString("InstallPackageMessage"), packageId, installPath)); // Find the latest version using NuGetPackageManager var resolvePackage = await NuGetPackageManager.GetLatestVersionAsync( packageId, project, resolutionContext, primaryRepositories, Console, CancellationToken.None); if (resolvePackage == null || resolvePackage.LatestVersion == null) { var message = string.Format( CultureInfo.CurrentCulture, LocalizedResourceManager.GetString("InstallCommandUnableToFindPackage"), packageId); throw new CommandException(message); } version = resolvePackage.LatestVersion; } // Get a list of packages already in the folder. var installedPackages = await project.GetFolderPackagesAsync(CancellationToken.None); // Find existing versions of the package var alreadyInstalledVersions = new HashSet <NuGetVersion>(installedPackages .Where(e => StringComparer.OrdinalIgnoreCase.Equals(packageId, e.PackageIdentity.Id)) .Select(e => e.PackageIdentity.Version)); var packageIdentity = new PackageIdentity(packageId, version); var PackageSaveMode = Packaging.PackageSaveMode.Defaultv2; if (EffectivePackageSaveMode != Packaging.PackageSaveMode.None) { PackageSaveMode = EffectivePackageSaveMode; } // Check if the package already exists or a higher version exists already. var skipInstall = project.PackageExists(packageIdentity, PackageSaveMode); // For SxS allow other versions to install. For non-SxS skip if a higher version exists. skipInstall |= (ExcludeVersion && alreadyInstalledVersions.Any(e => e >= version)); if (skipInstall) { var message = string.Format( CultureInfo.CurrentCulture, LocalizedResourceManager.GetString("InstallCommandPackageAlreadyExists"), packageIdentity); Console.LogMinimal(message); } else { var clientPolicyContext = ClientPolicyContext.GetClientPolicy(Settings, Console); var projectContext = new ConsoleProjectContext(Console) { PackageExtractionContext = new PackageExtractionContext( PackageSaveMode, PackageExtractionBehavior.XmlDocFileSaveMode, clientPolicyContext, Console) }; resolutionContext.SourceCacheContext.NoCache = NoCache; resolutionContext.SourceCacheContext.DirectDownload = DirectDownload; var packageSourceMapping = PackageSourceMapping.GetPackageSourceMapping(Settings); var downloadContext = new PackageDownloadContext(resolutionContext.SourceCacheContext, installPath, DirectDownload, packageSourceMapping) { ClientPolicyContext = clientPolicyContext }; await packageManager.InstallPackageAsync( project, packageIdentity, resolutionContext, projectContext, downloadContext, primaryRepositories, Enumerable.Empty <SourceRepository>(), CancellationToken.None); if (downloadContext.DirectDownload) { GetDownloadResultUtility.CleanUpDirectDownloads(downloadContext); } } } }
async Task RestorePackagesAsync( IEnumerable <InteractivePackage> packages, SourceCacheContext cacheContext, CancellationToken cancellationToken) { var restoreContext = new RestoreArgs { CacheContext = cacheContext, Log = Logger, }; // NOTE: This path is typically empty. It could in theory contain nuget.config settings // files, but really we just use it to satisfy nuget API that requires paths, // even when they are never used. var rootPath = packageConfigDirectory; var globalPath = restoreContext.GetEffectiveGlobalPackagesFolder(rootPath, settings); var fallbackPaths = restoreContext.GetEffectiveFallbackPackageFolders(settings); var providerCache = new RestoreCommandProvidersCache(); var restoreProviders = providerCache.GetOrCreate( globalPath, fallbackPaths, SourceRepositories, cacheContext, Logger); // Set up a project spec similar to what you would see in a project.json. // This is sufficient for the dependency graph work done within RestoreCommand. // TODO: XF version pinning during restore? var targetFrameworkInformation = new TargetFrameworkInformation { FrameworkName = TargetFramework, Dependencies = packages.Select(ToLibraryDependency).ToList(), }; var projectSpec = new PackageSpec(new [] { targetFrameworkInformation }) { Name = project.Name, FilePath = rootPath, }; var restoreRequest = new RestoreRequest(projectSpec, restoreProviders, cacheContext, Logger); var restoreCommand = new RestoreCommand(restoreRequest); var result = await restoreCommand.ExecuteAsync(cancellationToken); if (!result.Success) { return; } project.ResetInstallationContext(); // As with installation, restore simply ensures that packages are present in the user's // global package cache. We reference them out of there just like .NET core projects do. // // All resolved packages, including the explicit inputs and their dependencies, are // available as LockFileLibrary instances. foreach (var library in result.LockFile.Libraries) { project.InstallationContext.AddInstalledPackage( GetInteractivePackageFromLibrary(library, project, packages)); } installedPackages = project.InstallationContext.InstalledPackages; UpdateInstalledPackages(); }
public static void Register( CommandLineApplication cmdApp, CommandOutputLogger log) { cmdApp.Command("restore", (Action<CommandLineApplication>)(restore => { restore.Description = "Restores packages for a project and writes a lock file."; restore.HelpOption(XPlatUtility.HelpOption); var sources = restore.Option( "-s|--source <source>", "Specifies a NuGet package source to use during the restore.", CommandOptionType.MultipleValue); var packagesDirectory = restore.Option( "--packages <packagesDirectory>", "Directory to install packages in.", CommandOptionType.SingleValue); var disableParallel = restore.Option( "--disable-parallel", "Disables restoring multiple projects in parallel.", CommandOptionType.NoValue); var fallBack = restore.Option( "-f|--fallbacksource <FEED>", "A list of packages sources to use as a fallback.", CommandOptionType.MultipleValue); var runtime = restore.Option( "--runtime <RID>", "List of runtime identifiers to restore for.", CommandOptionType.MultipleValue); var configFile = restore.Option( "--configfile <file>", "The NuGet configuration file to use.", CommandOptionType.SingleValue); var noCache = restore.Option( "--no-cache", "Do not cache packages and http requests.", CommandOptionType.NoValue); var verbosity = restore.Option( XPlatUtility.VerbosityOption, "The verbosity of logging to use. Allowed values: Debug, Verbose, Information, Minimal, Warning, Error.", CommandOptionType.SingleValue); var argRoot = restore.Argument( "[root]", "List of projects and project folders to restore. Each value can be: a path to a project.json or global.json file, or a folder to recursively search for project.json files.", multipleValues: true); restore.OnExecute(async () => { var logLevel = XPlatUtility.GetLogLevel(verbosity); log.SetLogLevel(logLevel); using (var cacheContext = new SourceCacheContext()) { cacheContext.NoCache = noCache.HasValue(); var providerCache = new RestoreCommandProvidersCache(); // Ordered request providers var providers = new List<IRestoreRequestProvider>(); providers.Add(new MSBuildP2PRestoreRequestProvider(providerCache)); providers.Add(new ProjectJsonRestoreRequestProvider(providerCache)); var restoreContext = new RestoreArgs() { CacheContext = cacheContext, LockFileVersion = LockFileFormat.Version, ConfigFileName = configFile.HasValue() ? configFile.Value() : null, DisableParallel = true, GlobalPackagesFolder = packagesDirectory.HasValue() ? packagesDirectory.Value() : null, Inputs = new List<string>(argRoot.Values), Log = log, MachineWideSettings = new CommandLineXPlatMachineWideSetting(), RequestProviders = providers, Sources = sources.Values, FallbackSources = fallBack.Values, CachingSourceProvider = _sourceProvider }; restoreContext.Runtimes.UnionWith(runtime.Values); var restoreSummaries = await RestoreRunner.Run(restoreContext); // Summary RestoreSummary.Log(log, restoreSummaries, logLevel < LogLevel.Minimal); return restoreSummaries.All(x => x.Success) ? 0 : 1; } }); })); }