Пример #1
0
 public void Dispose()
 {
     this.sourceRepository = null;
     this.sourceCacheContext?.Dispose();
     this.sourceCacheContext = null;
 }
Пример #2
0
        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);
        }
Пример #3
0
        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)))));
            }
        }
Пример #4
0
        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();
            }
        }
Пример #5
0
        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);
        }
Пример #6
0
        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());
                            }
                }
            }
        }
Пример #7
0
        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);
                        }
                    }
                }
            }
        }
Пример #8
0
        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}")));
        }
Пример #9
0
        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");
            }
        }
Пример #10
0
        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);
            }
        }
Пример #11
0
        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);
                    }
                }
            }
        }
Пример #12
0
        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));
        }
Пример #13
0
        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);
            });
        }
Пример #14
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);
        }
Пример #15
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;
            }
        }
Пример #17
0
        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);
            }
        }
Пример #18
0
        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);
        }
Пример #19
0
        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);
                    }
                }
            }
        }
Пример #21
0
        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());
            }
        }
Пример #22
0
        /// <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());
            }
        }
Пример #23
0
        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;
        }
Пример #24
0
        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);
            }
        }
Пример #25
0
        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);
                    }
                }
            }
        }
Пример #26
0
        /// <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));
            }
        }
Пример #27
0
        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);
                }
            }
        }
Пример #28
0
        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();
        }
Пример #29
0
        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();
        }
Пример #31
0
        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;
                    }
                });
            }));
        }