private async Task GetPackageDependencies(PackageIdentity package,
                                                  NuGetFramework framework,
                                                  SourceCacheContext cacheContext,
                                                  NuGet.Common.ILogger logger,
                                                  IEnumerable <SourceRepository> repositories,
                                                  ISet <SourcePackageDependencyInfo> availablePackages)
        {
            if (availablePackages.Any(x => x.Id == package.Id))
            {
                return;
            }

            foreach (var sourceRepository in repositories)
            {
                var dependencyInfoResource = await sourceRepository.GetResourceAsync <DependencyInfoResource>();

                var dependencyInfo = await dependencyInfoResource.ResolvePackage(
                    package, framework, cacheContext, logger, CancellationToken.None);

                if (dependencyInfo == null)
                {
                    continue;
                }

                availablePackages.Add(dependencyInfo);
                foreach (var dependency in dependencyInfo.Dependencies)
                {
                    await GetPackageDependencies(
                        new PackageIdentity(dependency.Id, dependency.VersionRange.MinVersion),
                        framework, cacheContext, logger, repositories, availablePackages);
                }
            }
        }
예제 #2
0
        /// <summary>
        /// This constructor is just used for testing.
        /// </summary>
        public VsPathContextProvider(
            ISettings settings,
            IVsSolutionManager solutionManager,
            NuGet.Common.ILogger logger,
            IVsProjectAdapterProvider vsProjectAdapterProvider,
            Func <string, LockFile> getLockFileOrNull)
        {
            if (settings == null)
            {
                throw new ArgumentNullException(nameof(settings));
            }

            if (solutionManager == null)
            {
                throw new ArgumentNullException(nameof(solutionManager));
            }

            if (logger == null)
            {
                throw new ArgumentNullException(nameof(logger));
            }

            if (vsProjectAdapterProvider == null)
            {
                throw new ArgumentNullException(nameof(vsProjectAdapterProvider));
            }

            _settings                 = new Lazy <ISettings>(() => settings);
            _solutionManager          = new Lazy <IVsSolutionManager>(() => solutionManager);
            _logger                   = new Lazy <NuGet.Common.ILogger>(() => logger);
            _vsProjectAdapterProvider = new Lazy <IVsProjectAdapterProvider>(() => vsProjectAdapterProvider);
            _getLockFileOrNull        = getLockFileOrNull ?? BuildIntegratedProjectUtility.GetLockFileOrNull;
        }
예제 #3
0
        /// <summary>
        /// This constructor is just used for testing.
        /// </summary>
        public VsPathContextProvider(
            ISettings settings,
            IVsSolutionManager solutionManager,
            NuGet.Common.ILogger logger,
            Func <BuildIntegratedNuGetProject, Task <LockFile> > getLockFileOrNullAsync)
        {
            if (settings == null)
            {
                throw new ArgumentNullException(nameof(settings));
            }

            if (solutionManager == null)
            {
                throw new ArgumentNullException(nameof(solutionManager));
            }

            if (logger == null)
            {
                throw new ArgumentNullException(nameof(logger));
            }

            _settings               = new Lazy <ISettings>(() => settings);
            _solutionManager        = new Lazy <IVsSolutionManager>(() => solutionManager);
            _logger                 = new Lazy <NuGet.Common.ILogger>(() => logger);
            _getLockFileOrNullAsync = getLockFileOrNullAsync ?? BuildIntegratedProjectUtility.GetLockFileOrNull;
        }
예제 #4
0
        public VsSolutionRestoreService(
            IProjectSystemCache projectSystemCache,
            ISolutionRestoreWorker restoreWorker,
            [Import("VisualStudioActivityLogger")]
            NuGet.Common.ILogger logger)
        {
            if (projectSystemCache == null)
            {
                throw new ArgumentNullException(nameof(projectSystemCache));
            }

            if (restoreWorker == null)
            {
                throw new ArgumentNullException(nameof(restoreWorker));
            }

            if (logger == null)
            {
                throw new ArgumentNullException(nameof(logger));
            }

            _projectSystemCache = projectSystemCache;
            _restoreWorker      = restoreWorker;
            _logger             = logger;
        }
예제 #5
0
 public ModulePackageManager(IModuleProject project, IMemoryCache memoryCache,
                             PackageLockRequestManager packageLockRequestManager, IOptions <ModulePackageManagerOptions> options, ILogger <ModulePackageManager> logger)
 {
     _project     = project;
     _memoryCache = memoryCache;
     _packageLockRequestManager = packageLockRequestManager;
     _options = options.Value;
     _logger  = new NuGetLoggerWrapper(logger);
 }
예제 #6
0
        public NuGetService(IHubContext <DownloadPackageHub, IDownloadPackageHubClient> hubContext, ICompressService compressService, IHostEnvironment environment, IConfiguration configuration, ILogger <NuGetService> logger)
        {
            _downloadHubContext = hubContext;
            _compressService    = compressService;
            _environment        = environment;
            _configuration      = configuration;
            _logger             = logger;

            // get configure value
            MessageFrequency = _configuration.GetValue <int>("MessageFrequency");
        }
예제 #7
0
        private IEnumerable <NuGetVersion> GetVersions(string packageId, string sourceUrl = "https://chocolatey.org/api/v2/")
        {
            NuGet.Common.ILogger logger            = NullLogger.Instance;
            CancellationToken    cancellationToken = CancellationToken.None;
            SourceCacheContext   cache             = new SourceCacheContext();
            PackageSource        ps             = new PackageSource(sourceUrl);
            var sourceRepository                = Repository.Factory.GetCoreV2(ps);
            FindPackageByIdResource    resource = sourceRepository.GetResourceAsync <FindPackageByIdResource>().GetAwaiter().GetResult();
            IEnumerable <NuGetVersion> versions = resource.GetAllVersionsAsync(packageId, cache, logger, cancellationToken).GetAwaiter().GetResult();

            return(versions);
        }
        private DownloadResourceResult DownloadFromUrl(
            SourcePackageDependencyInfo package,
            DataServicePackageRepository repository,
            NuGet.Common.ILogger logger,
            CancellationToken token)
        {
            IPackage newPackage      = null;
            var      version         = SemanticVersion.Parse(package.Version.ToString());
            var      cacheRepository = MachineCache.Default;

            try
            {
                // Try finding the package in the machine cache
                var localPackage = cacheRepository.FindPackage(package.Id, version)
                                   as OptimizedZipPackage;

                // Validate the package matches the hash
                if (localPackage != null &&
                    localPackage.IsValid &&
                    MatchPackageHash(localPackage, package.PackageHash))
                {
                    newPackage = localPackage;
                }
            }
            catch
            {
                // Ignore cache failures here to match NuGet.Core
                // The bad package will be deleted and replaced during the download.
            }

            // If the local package does not exist in the cache download it from the source
            if (newPackage == null)
            {
                newPackage = DownloadToMachineCache(
                    cacheRepository,
                    package,
                    repository,
                    package.DownloadUri,
                    logger,
                    token);
            }

            // Read the package from the machine cache
            if (newPackage != null)
            {
                return(new DownloadResourceResult(newPackage.GetStream()));
            }

            return(null);
        }
예제 #9
0
        static async Task ResolvePackageDependencies(
            PackageIdentity package,
            NuGetFramework framework,
            SourceCacheContext cacheContext,
            NuGet.Common.ILogger logger,
            IEnumerable <SourceRepository> repositories,
            ConcurrentDictionary <PackageIdentity, SourcePackageDependencyInfo> availablePackages)
        {
            if (availablePackages.ContainsKey(package))
            {
                return;
            }

            // TODO
            // Avoid getting info for e.g. netstandard1.x if our framework is highest (e.g. netstandard2.0)
            //if (framework.IsPackageBased &&
            //    package.Id.Equals("netstandard.library", StringComparison.OrdinalIgnoreCase) &&
            //    NuGetFrameworkUtility.IsCompatibleWithFallbackCheck(framework,
            //        NuGetFramework.Parse($"netstandard{package.Version.Major}.{package.Version.Minor}")))
            //{
            //    return;
            //}

            foreach (var sourceRepository in repositories)
            {
                var dependencyInfoResource = await sourceRepository.GetResourceAsync <DependencyInfoResource>();

                var dependencyInfo = await dependencyInfoResource.ResolvePackage(
                    package, framework, cacheContext, logger, CancellationToken.None);

                if (dependencyInfo == null)
                {
                    continue;
                }

                // TODO: try add should be changed to console.writeline reporting
                if (availablePackages.TryAdd(new PackageIdentity(dependencyInfo.Id, dependencyInfo.Version), dependencyInfo))
                {
                    await Task.WhenAll(dependencyInfo.Dependencies.Select(dependency =>
                    {
                        // recursive traversal of graph/tree
                        return(ResolvePackageDependencies(new PackageIdentity(dependency.Id, dependency.VersionRange.MinVersion),
                                                          framework, cacheContext, logger, repositories, availablePackages));
                    }));
                }
            }
        }
예제 #10
0
        private async Task <PackageInfo> GetBestMatchPackageVersionsAsync(SourceRepository repository, string packageId, VersionRange range)
        {
            ILogger                 logger            = NullLogger.Instance;
            CancellationToken       cancellationToken = CancellationToken.None;
            SourceCacheContext      cache             = new SourceCacheContext();
            FindPackageByIdResource resource          = await repository.GetResourceAsync <FindPackageByIdResource>();

            IEnumerable <NuGetVersion> versions = await resource.GetAllVersionsAsync(
                packageId,
                cache,
                logger,
                cancellationToken);

            NuGetVersion bestMatchVersion = range.FindBestMatch(versions);

            return(new PackageInfo {
                packageId = packageId, packageVersion = bestMatchVersion
            });
        }
예제 #11
0
        public async Task <IEnumerable <string> > SearchPackageAsync(string searchPackageName, string repositoryUrl, bool includePrerelease)
        {
            ILogger               logger            = NullLogger.Instance;
            CancellationToken     cancellationToken = CancellationToken.None;
            SourceCacheContext    cache             = new SourceCacheContext();
            SourceRepository      repository        = Repository.Factory.GetCoreV3(repositoryUrl);
            PackageSearchResource resource          = await repository.GetResourceAsync <PackageSearchResource>();

            SearchFilter searchFilter = new SearchFilter(includePrerelease: includePrerelease);

            IEnumerable <IPackageSearchMetadata> results = await resource.SearchAsync(
                searchPackageName,
                searchFilter,
                skip : 0,
                take : 10,
                logger,
                cancellationToken);

            return(results.Select(x => x.Identity.Id).AsEnumerable <string>());
        }
예제 #12
0
        /// <summary>
        /// This constructor is just used for testing.
        /// </summary>
        public VsPathContextProvider(
            ISettings settings,
            IVsSolutionManager solutionManager,
            NuGet.Common.ILogger logger,
            Func <BuildIntegratedNuGetProject, Task <LockFile> > getLockFileOrNullAsync)
        {
            if (settings == null)
            {
                throw new ArgumentNullException(nameof(settings));
            }

            if (solutionManager == null)
            {
                throw new ArgumentNullException(nameof(solutionManager));
            }

            if (logger == null)
            {
                throw new ArgumentNullException(nameof(logger));
            }

            _settings               = new Lazy <ISettings>(() => settings);
            _solutionManager        = new Lazy <IVsSolutionManager>(() => solutionManager);
            _logger                 = new Lazy <NuGet.Common.ILogger>(() => logger);
            _getLockFileOrNullAsync = getLockFileOrNullAsync ?? BuildIntegratedProjectUtility.GetLockFileOrNull;

            _projectContext = new Lazy <INuGetProjectContext>(() => {
                var projectContext = new VSAPIProjectContext();

                var signedPackageVerifier = new PackageSignatureVerifier(SignatureVerificationProviderFactory.GetSignatureVerificationProviders());
                var adapterLogger         = new LoggerAdapter(projectContext);
                projectContext.PackageExtractionContext = new PackageExtractionContext(
                    PackageSaveMode.Defaultv2,
                    PackageExtractionBehavior.XmlDocFileSaveMode,
                    adapterLogger,
                    signedPackageVerifier,
                    SignedPackageVerifierSettings.GetClientPolicy(settings, adapterLogger));

                return(projectContext);
            });
        }
예제 #13
0
        public void Commit(NuGet.Common.ILogger log)
        {
            if (!Success)
            {
                var name = $"{ProjectName}.nuget.targets";
                var path = Path.Combine(ProjectDirectory, name);

                log.LogMinimal(string.Format(CultureInfo.CurrentCulture, Strings.Log_GeneratingMsBuildFile, name));
                GenerateMSBuildErrorFile(path);
            }
            else
            {
                // Generate the files as needed
                var targetsName = $"{ProjectName}.nuget.targets";
                var propsName   = $"{ProjectName}.nuget.props";
                var targetsPath = Path.Combine(ProjectDirectory, targetsName);
                var propsPath   = Path.Combine(ProjectDirectory, propsName);

                if (Targets.Any())
                {
                    log.LogMinimal(string.Format(CultureInfo.CurrentCulture, Strings.Log_GeneratingMsBuildFile, targetsName));

                    GenerateImportsFile(targetsPath, Targets);
                }
                else if (File.Exists(targetsPath))
                {
                    File.Delete(targetsPath);
                }

                if (Props.Any())
                {
                    log.LogMinimal(string.Format(CultureInfo.CurrentCulture, Strings.Log_GeneratingMsBuildFile, propsName));

                    GenerateImportsFile(propsPath, Props);
                }
                else if (File.Exists(propsPath))
                {
                    File.Delete(propsPath);
                }
            }
        }
예제 #14
0
        public async Task <IEnumerable <string> > GetPackageVersionAsync(string packageId, string repositoryUrl, bool includePrerelease)
        {
            ILogger                 logger            = NullLogger.Instance;
            CancellationToken       cancellationToken = CancellationToken.None;
            SourceCacheContext      cache             = new SourceCacheContext();
            SourceRepository        repository        = Repository.Factory.GetCoreV3(repositoryUrl);
            FindPackageByIdResource resource          = await repository.GetResourceAsync <FindPackageByIdResource>();

            IEnumerable <NuGetVersion> versions = await resource.GetAllVersionsAsync(
                packageId,
                cache,
                logger,
                cancellationToken);

            if (includePrerelease == true)
            {
                return(versions.OrderByDescending(x => x).Select(x => x.ToNormalizedString()).AsEnumerable());
            }
            else
            {
                return(versions.Where(x => x.IsPrerelease == false).OrderByDescending(x => x).Select(x => x.ToNormalizedString()).AsEnumerable());
            }
        }
        public override Task <DownloadResourceResult> GetDownloadResourceResultAsync(
            PackageIdentity identity,
            Configuration.ISettings settings,
            NuGet.Common.ILogger logger,
            CancellationToken token)
        {
            // settings are not used here, since, global packages folder are not used for v2 sources
            if (identity == null)
            {
                throw new ArgumentNullException(nameof(identity));
            }

            if (logger == null)
            {
                throw new ArgumentNullException(nameof(logger));
            }

            string displayUri = V2Client.Source;

            return(Task.Run(() =>
            {
                token.ThrowIfCancellationRequested();

                for (int i = 0; i < 3; i++)
                {
                    try
                    {
                        var sourcePackage = identity as SourcePackageDependencyInfo;
                        var repository = V2Client as DataServicePackageRepository;

                        bool isFromUri = repository != null &&
                                         sourcePackage?.PackageHash != null &&
                                         sourcePackage?.DownloadUri != null;

                        if (isFromUri)
                        {
                            // If this is a SourcePackageDependencyInfo object with everything populated
                            // and it is from an online source, use the machine cache and download it using the
                            // given url.
                            return DownloadFromUrl(sourcePackage, repository, logger, token);
                        }
                        else
                        {
                            // Look up the package from the id and version and download it.
                            return DownloadFromIdentity(identity, V2Client, logger, token);
                        }
                    }
                    catch (OperationCanceledException)
                    {
                        return new DownloadResourceResult(DownloadResourceResultStatus.Cancelled);
                    }
                    catch (IOException ex) when(ex.InnerException is SocketException && i < 2)
                    {
                        string message = string.Format(CultureInfo.CurrentCulture, Strings.Log_ErrorDownloading, identity, displayUri)
                                         + Environment.NewLine
                                         + ExceptionUtilities.DisplayMessage(ex);
                        logger.LogWarning(message);
                    }
                    catch (Exception ex)
                    {
                        string message = string.Format(CultureInfo.CurrentCulture, Strings.Log_ErrorDownloading, identity, displayUri);
                        logger.LogError(message + Environment.NewLine + ExceptionUtilities.DisplayMessage(ex));

                        throw new FatalProtocolException(message, ex);
                    }
                }

                // This line cannot be reached, but the compiler doesn't understand it
                throw new InvalidOperationException("Can never reach here.");
            }));
        }
        private IPackage DownloadToMachineCache(
            IPackageCacheRepository cacheRepository,
            PackageIdentity package,
            DataServicePackageRepository repository,
            Uri downloadUri,
            NuGet.Common.ILogger logger,
            CancellationToken token)
        {
            var      packageName = new PackageNameWrapper(package);
            var      version     = SemanticVersion.Parse(package.Version.ToString());
            IPackage newPackage  = null;

            FileInfo   tmpFile       = null;
            FileStream tmpFileStream = null;

            // Create a v2 http client
            var downloadClient = new HttpClient(downloadUri)
            {
                UserAgent = UserAgent.UserAgentString
            };

            EventHandler <ProgressEventArgs> progressHandler = (sender, progress) =>
            {
                // Throw if this was canceled. This will stop the download.
                token.ThrowIfCancellationRequested();
            };

            Exception downloadException = null;

            Action <Stream> downloadAction = (stream) =>
            {
                try
                {
                    repository.PackageDownloader.ProgressAvailable += progressHandler;

                    repository.PackageDownloader.DownloadPackage(downloadClient, packageName, stream);
                }
                catch (Exception ex) when(ex is OperationCanceledException ||
                                          ex is IOException && ex.InnerException is SocketException)
                {
                    // The task was canceled. To avoid writing a partial file to the machine cache
                    // we need to clear out the current tmp file stream so that it will be ignored.
                    stream.SetLength(0);

                    // If the machine cache is using the physical file system we can find the
                    // path of temp file and clean it up. Otherwise NuGet.Core will just leave the temp file.
                    tmpFileStream = stream as FileStream;
                    if (tmpFileStream != null)
                    {
                        tmpFile = new FileInfo(tmpFileStream.Name);
                    }

                    downloadException = ex;
                }
                catch (Exception ex)
                {
                    downloadException = ex;
                }
                finally
                {
                    repository.PackageDownloader.ProgressAvailable -= progressHandler;
                }
            };

            // We either do not have a package available locally or they are invalid.
            // Download the package from the server.
            if (cacheRepository.InvokeOnPackage(package.Id, version,
                                                (stream) => downloadAction(stream)))
            {
                if (!token.IsCancellationRequested)
                {
                    newPackage = cacheRepository.FindPackage(package.Id, version);
                    Debug.Assert(newPackage != null);
                }
            }

            // After the stream is no longer in use, delete the tmp file
            // NuGet.Core does not properly clean these up since it does not have cancel support.
            if (tmpFile != null && token.IsCancellationRequested && tmpFile.Exists)
            {
                try
                {
                    tmpFile.Delete();
                }
                catch
                {
                    // Ignore exceptions for tmp file clean up
                }
            }

            if (downloadException != null)
            {
                throw downloadException;
            }

            return(newPackage);
        }
        private DownloadResourceResult DownloadFromIdentity(
            PackageIdentity identity,
            IPackageRepository repository,
            NuGet.Common.ILogger logger,
            CancellationToken token)
        {
            var version         = SemanticVersion.Parse(identity.Version.ToString());
            var dataServiceRepo = repository as DataServicePackageRepository;

            if (dataServiceRepo != null)
            {
                // Clone the repo to allow for concurrent calls
                var sourceUri = UriUtility.CreateSourceUri(dataServiceRepo.Source);
                dataServiceRepo = new DataServicePackageRepository(sourceUri);

                var package            = dataServiceRepo.FindPackage(identity.Id, version);
                var dataServicePackage = package as DataServicePackage;

                if (dataServicePackage != null)
                {
                    token.ThrowIfCancellationRequested();

                    // For online sources get the url and retrieve it with cancel support
                    var url = dataServicePackage.DownloadUrl;

                    var downloadedPackage = DownloadToMachineCache(
                        MachineCache.Default,
                        identity,
                        dataServiceRepo,
                        url,
                        logger,
                        token);

                    if (downloadedPackage != null)
                    {
                        return(new DownloadResourceResult(downloadedPackage.GetStream()));
                    }
                }
            }
            else
            {
                var package = repository.FindPackage(identity.Id, version);

                if (package != null)
                {
                    // Use a folder reader for unzipped repos
                    if (repository is UnzippedPackageRepository)
                    {
                        var packagePath   = Path.Combine(repository.Source, identity.Id + "." + version);
                        var directoryInfo = new DirectoryInfo(packagePath);
                        if (directoryInfo.Exists)
                        {
                            return(new DownloadResourceResult(
                                       package.GetStream(),
                                       new PackageFolderReader(directoryInfo)));
                        }
                    }

                    return(new DownloadResourceResult(package.GetStream()));
                }
            }

            return(new DownloadResourceResult(DownloadResourceResultStatus.NotFound));
        }
예제 #18
0
        public async Task <string> DownloadPackageAsync(string connectionID, RequestDownloadInfo requestInfo)
        {
            // cast
            RequestDownloadNuGetInfo info = (RequestDownloadNuGetInfo)requestInfo;

            // server response
            ServerResponse response = new ServerResponse()
            {
                payload = new Dictionary <string, string>()
            };

            string _outputDirectory = $"{_environment.ContentRootPath}/wwwroot/{_configuration.GetValue<string>("DownloadPath")}";

            // check if output directory exists
            if (!Directory.Exists(_outputDirectory))
            {
                Directory.CreateDirectory(_outputDirectory);
            }

            string connectionSubName   = $"nuget-{connectionID}-{DateTime.Now:yyyymmddHHmmss}";
            string connectionDirectory = $"{_outputDirectory}/{connectionSubName}";

            Directory.CreateDirectory(connectionDirectory);

            // send message
            response.payload.Clear();
            response.payload.Add("Resource", $"{connectionSubName} created.");
            await _downloadHubContext.Clients.Client(connectionID).Response(response);

            ILogger                 logger            = NullLogger.Instance;
            CancellationToken       cancellationToken = CancellationToken.None;
            SourceCacheContext      cache             = new SourceCacheContext();
            SourceRepository        repository        = Repository.Factory.GetCoreV3(info.repository);
            FindPackageByIdResource resource          = await repository.GetResourceAsync <FindPackageByIdResource>();

            // set all parent packages
            for (int i = 0; i < info.packageList.Count(); i++)
            {
                string packageId           = info.packageList.ElementAt(i).packageId;
                string packageVersionValue = info.packageList.ElementAt(i).packageVersion;

                NuGetVersion packageVersion = new NuGetVersion(packageVersionValue);
                PackageInfo  package        = new PackageInfo {
                    packageId = packageId, packageVersion = packageVersion
                };

                if (package.packageVersion != null)
                {
                    _downloadQueue.Enqueue(package);
                }
                else
                {
                    FloatRange floatRange = null;
                    if (info.preReleased == true)
                    {
                        // include pre-release
                        floatRange = new FloatRange(NuGetVersionFloatBehavior.AbsoluteLatest);
                    }
                    else
                    {
                        // released
                        floatRange = new FloatRange(NuGetVersionFloatBehavior.Major);
                    }
                    FloatRange   fr    = new FloatRange(NuGetVersionFloatBehavior.Major);
                    VersionRange range = new VersionRange(floatRange: fr);

                    package = await GetBestMatchPackageVersionsAsync(repository, packageId, range);
                }
                _downloadQueue.Enqueue(package);
            }

            // download counter
            int download_counter = 0;

            while (_downloadQueue.Count > 0)
            {
                PackageInfo package = _downloadQueue.Dequeue();

                string validFileName   = FileUtil.GetValidFileName(package.packageId);
                string packageFilePath = $"{connectionDirectory}/{validFileName}.{package.packageVersion}.nupkg";

                if (_cacheDownloadedFileName.Contains($"{package.packageId}-{package.packageVersion}"))
                {
                    continue;
                }
                else
                {
                    _cacheDownloadedFileName.Add($"{package.packageId}-{package.packageVersion}");
                }

                using FileStream packageStream = new FileStream(packageFilePath, FileMode.Create);

                await resource.CopyNupkgToStreamAsync(
                    package.packageId,
                    package.packageVersion,
                    packageStream,
                    cache,
                    logger,
                    cancellationToken);

                download_counter++;

                // starting
                if (download_counter == 1)
                {
                    // send message
                    response.payload.Clear();
                    response.payload.Add("DownloadCounter", $"starting...");
                    await _downloadHubContext.Clients.Client(connectionID).Response(response);
                }

                // check if send message is needed
                if (download_counter % MessageFrequency == 0)
                {
                    // send message
                    response.payload.Clear();
                    response.payload.Add("DownloadCounter", $"{download_counter}, {((float)download_counter / (float)(download_counter + _downloadQueue.Count)) * 100.0f}%");
                    await _downloadHubContext.Clients.Client(connectionID).Response(response);
                }

                Console.WriteLine($"Downloaded package {package.packageId} {package.packageVersion}");

                using PackageArchiveReader packageReader = new PackageArchiveReader(packageStream);
                NuspecReader nuspecReader = await packageReader.GetNuspecReaderAsync(cancellationToken);

                Console.WriteLine($"Tags: {nuspecReader.GetTags()}");
                Console.WriteLine($"Description: {nuspecReader.GetDescription()}");

                using PackageArchiveReader reader = new PackageArchiveReader(packageStream);
                NuspecReader nuspec = reader.NuspecReader;
                Console.WriteLine($"ID: {nuspec.GetId()}");
                Console.WriteLine($"Version: {nuspec.GetVersion()}");
                Console.WriteLine($"Description: {nuspec.GetDescription()}");
                Console.WriteLine($"Authors: {nuspec.GetAuthors()}");

                if (info.withDependency == false)
                {
                    Console.WriteLine("\nDependencies download is not need.");
                    continue;
                }

                Console.WriteLine("\nStart download dependencies:");
                foreach (var dependencyGroup in nuspec.GetDependencyGroups())
                {
                    Console.WriteLine($" - {dependencyGroup.TargetFramework.GetFrameworkString()}");

                    // check target framework
                    if (!info.targetFramework.Contains("all", StringComparer.InvariantCultureIgnoreCase) &&
                        !info.targetFramework.Contains(dependencyGroup.TargetFramework.GetFrameworkString(), StringComparer.InvariantCultureIgnoreCase))
                    {
                        Console.WriteLine($" -- {dependencyGroup.TargetFramework.GetFrameworkString()} not match target framework.");
                        continue;
                    }

                    foreach (var dependency in dependencyGroup.Packages)
                    {
                        Console.WriteLine($"   > {dependency.Id} {dependency.VersionRange}");

                        PackageInfo dependencyPackage = await GetBestMatchPackageVersionsAsync(repository, dependency.Id, dependency.VersionRange);

                        Console.WriteLine($"   -- best match version: {dependency.Id} {dependencyPackage.packageVersion}");
                        _downloadQueue.Enqueue(dependencyPackage);
                    }
                }
            }

            // send message
            response.payload.Clear();
            response.payload.Add("DownloadCounter", $"{download_counter}, {((float)download_counter / (float)(download_counter + _downloadQueue.Count)) * 100.0f}%");
            await _downloadHubContext.Clients.Client(connectionID).Response(response);

            string zipFileName = $"{_outputDirectory}/{connectionSubName}.zip";
            bool   result      = _compressService.CompressDirectory(connectionDirectory, zipFileName);

            if (result == true)
            {
                string readableSize = FileUtil.getFileHumanReadableSize(zipFileName);
                // send message
                response.payload.Clear();
                response.payload.Add("CompressStatus", $"compressed ok, file sieze: {readableSize}.");
                await _downloadHubContext.Clients.Client(connectionID).Response(response);
            }
            else
            {
                // send message
                response.payload.Clear();
                response.payload.Add("CompressStatus", $"compressed failed.");
                await _downloadHubContext.Clients.Client(connectionID).Response(response);
            }

            // delete directory
            Directory.Delete(connectionDirectory, true);

            return(connectionSubName);
        }
예제 #19
0
        private async Task <PackagesContext> GetRequiredPackages(ISet <PackageIdentity> primaryPackages,
                                                                 ISet <PackageIdentity> targetPackages, bool downgradeAllowed, ResolutionContext resolutionContext,
                                                                 NuGetFramework primaryFramework, ILogger logger, CancellationToken token)
        {
            var libraryPackage = GetFramworkLibrary(primaryFramework);

            var gatherContext = new GatherContext
            {
                ResolutionContext    = resolutionContext,
                PrimarySources       = _project.PrimarySources,
                DependencySources    = _project.DependencySources,
                PackagesFolderSource = _project.LocalSourceRepository,
                PrimaryTargets       =
                    primaryPackages
                    .Select(x => targetPackages.Contains(x) ? x : new PackageIdentity(x.Id, version: null))
                    .ToList(),
                AllowDowngrades     = downgradeAllowed,
                PrimaryFramework    = primaryFramework,
                DependencyFramework = MazeFrameworks.MapToNetFramework(primaryFramework),
                Log = logger
            };

            var primaryPackageIds = primaryPackages.Select(x => x.Id).ToHashSet();

            var allPackages = await ResolverGather.GatherAsync(gatherContext, token);

            var frameworkRelevantPackages = primaryPackages.Where(x => allPackages.First(y => y.Equals(x)).Dependencies.Any()).ToHashSet();
            var frameworkRelevantTargets  = targetPackages.Where(x => allPackages.First(y => y.Equals(x)).Dependencies.Any()).ToHashSet();

            //we remove all primary packages that have no dependencies for the current framework meaning they don't support this framework
            var availablePackages = allPackages.Where(x => !primaryPackageIds.Contains(x.Id) || x.Dependencies.Any()).ToList();

            if (!availablePackages.Any()) //packages not available for this framework
            {
                return(new PackagesContext(ImmutableDictionary <PackageIdentity, SourcePackageDependencyInfo> .Empty));
            }

            //available packages now contains all versions of the package and all versions of each depdendency (recursive)
            //we try to prune the results down to only what we would allow to be installed

            //1. remove incorrect library packages
            var prunedAvailablePackages =
                PrunePackageTreeExtensions.RemoveLibraryPackage(availablePackages, libraryPackage);

            //2. remove all versions of the package we want to install except the version we actually want to install
            //   it is not a problem if other primary packages might need an update
            prunedAvailablePackages =
                PrunePackageTreeExtensions.RemoveAllVersionsForIdExcept(prunedAvailablePackages, frameworkRelevantTargets);

            //3. remove the downgrades of primary packages
            if (!downgradeAllowed)
            {
                prunedAvailablePackages =
                    PrunePackageTreeExtensions.PruneDowngrades(prunedAvailablePackages, frameworkRelevantPackages);
            }

            //4. remove prereleases
            if (!resolutionContext.IncludePrerelease)
            {
                prunedAvailablePackages =
                    PrunePackageTree.PrunePreleaseForStableTargets(prunedAvailablePackages, frameworkRelevantPackages,
                                                                   frameworkRelevantTargets);
            }

            /* ===> PackageResolverContext
             * TargetIds            New packages to install or update. These will prefer the highest version.
             * RequiredPackageIds   The required packages (primary)
             * PackagesConfig       Only for logging
             * PreferredVersions    Preferred versions of each package. If the package does not exist here it will use the dependency behavior, or if it is a target the highest version will be used.
             * AvailablePackages    All available packages that should be sorted out
             * DependencyBehavior   The behavior for resolving a package version
             * PackageSources       Only for logging
             * Log                  Logger
             * ========================================================================
             * Return               The complete resulting list
             */

            var resolverContext = new PackageResolverContext(
                resolutionContext.DependencyBehavior,
                targetIds: frameworkRelevantTargets.Select(x => x.Id),
                requiredPackageIds: frameworkRelevantPackages.Select(x => x.Id),
                packagesConfig: Enumerable.Empty <PackageReference>(),
                preferredVersions: frameworkRelevantPackages,
                availablePackages: prunedAvailablePackages,
                packageSources: Enumerable.Empty <PackageSource>(),
                log: logger);

            var packageResolver = new PackageResolver();

            //all final packages (including dependencies)
            var packages      = packageResolver.Resolve(resolverContext, token).ToList(); //that's an array
            var dependencyMap = packages.ToDictionary(x => x, x => availablePackages.First(y => y.Equals(x)),
                                                      PackageIdentity.Comparer);

            //remove library package and it's dependencies because they are always loaded
            var foundLibraryPackage = packages.FirstOrDefault(libraryPackage.IsSameId);

            if (foundLibraryPackage != null)
            {
                if (!foundLibraryPackage.Version.Equals(libraryPackage.Version))
                {
                    throw new InvalidOperationException($"Invalid version of {libraryPackage} found: {foundLibraryPackage}");
                }

                RemovePackage(foundLibraryPackage);

                //TODO remove package also from SourceDependencyInfo?

                void RemovePackage(PackageIdentity packageIdentity)
                {
                    var sourceInfo = dependencyMap[packageIdentity];

                    dependencyMap.Remove(packageIdentity);

                    foreach (var dependency in sourceInfo.Dependencies)
                    {
                        var package = dependencyMap.FirstOrDefault(x => x.Key.IsSameId(dependency)).Key;
                        if (package != null)
                        {
                            RemovePackage(package);
                        }
                    }
                }
            }

            return(new PackagesContext(dependencyMap));
        }
        /// <summary>
        /// Restores a package by querying, downloading, and unzipping it without generating any other files (like project.assets.json).
        /// </summary>
        /// <param name="libraryIdentity">The <see cref="LibraryIdentity"/> of the package.</param>
        /// <param name="settings">The NuGet settings to use.</param>
        /// <param name="logger">An <see cref="ILogger"/> to use for logging.</param>
        /// <returns></returns>
        public static Task <IReadOnlyList <RestoreResultPair> > RunWithoutCommit(LibraryIdentity libraryIdentity, ISettings settings, ILogger logger)
        {
            using (var sourceCacheContext = new SourceCacheContext
            {
                IgnoreFailedSources = true,
            })
            {
                var projectDirectory = Path.Combine(NuGetEnvironment.GetFolderPath(NuGetFolderPath.Temp), Guid.NewGuid().ToString("N"));

                var projectName = Guid.NewGuid().ToString("N");

                var projectFullPath = Path.Combine(projectDirectory, $"{projectName}.proj");

                // Iterate through TargetFrameworks to generate Lists required for packageSpec
                var frameworks = new List <TargetFrameworkInformation>(TargetFrameworks.Count);
                var originalTargetFrameworks = new List <string>(TargetFrameworks.Count);
                foreach (var tf in TargetFrameworks)
                {
                    frameworks.Add(new TargetFrameworkInformation
                    {
                        FrameworkName = tf
                    });

                    originalTargetFrameworks.Add(tf.ToString());
                }

                // The package spec details what packages to restore
                var packageSpec = new PackageSpec(frameworks)
                {
                    Dependencies = new List <LibraryDependency>
                    {
                        new LibraryDependency
                        {
                            LibraryRange = new LibraryRange(
                                libraryIdentity.Name,
                                new VersionRange(
                                    minVersion: libraryIdentity.Version,
                                    includeMinVersion: true,
                                    maxVersion: libraryIdentity.Version,
                                    includeMaxVersion: true),
                                LibraryDependencyTarget.Package),
                            SuppressParent = LibraryIncludeFlags.All,
                            AutoReferenced = true,
                            IncludeType    = LibraryIncludeFlags.None,
                        }
                    },
                    RestoreMetadata = new ProjectRestoreMetadata
                    {
                        ProjectPath              = projectFullPath,
                        ProjectName              = projectName,
                        ProjectStyle             = ProjectStyle.PackageReference,
                        ProjectUniqueName        = projectFullPath,
                        OutputPath               = projectDirectory,
                        OriginalTargetFrameworks = originalTargetFrameworks,
                        ConfigFilePaths          = settings.GetConfigFilePaths(),
                        PackagesPath             = SettingsUtility.GetGlobalPackagesFolder(settings),
                        Sources         = SettingsUtility.GetEnabledSources(settings).AsList(),
                        FallbackFolders = SettingsUtility.GetFallbackPackageFolders(settings).ToList()
                    },
                    FilePath = projectFullPath,
                    Name     = projectName,
                };

                var dependencyGraphSpec = new DependencyGraphSpec();

                dependencyGraphSpec.AddProject(packageSpec);

                dependencyGraphSpec.AddRestore(packageSpec.RestoreMetadata.ProjectUniqueName);

                IPreLoadedRestoreRequestProvider requestProvider = new DependencyGraphSpecRequestProvider(new RestoreCommandProvidersCache(), dependencyGraphSpec);

                var restoreArgs = new RestoreArgs
                {
                    AllowNoOp    = false,
                    CacheContext = sourceCacheContext,
#pragma warning disable CS0618 // Type or member is obsolete
                    CachingSourceProvider = new CachingSourceProvider(new PackageSourceProvider(settings, enablePackageSourcesChangedEvent: false)),
#pragma warning restore CS0618 // Type or member is obsolete
                    Log = logger,
                };

                // Create requests from the arguments
                var requests = requestProvider.CreateRequests(restoreArgs).Result;

                // Restore the package without generating extra files
                return(RestoreRunner.RunWithoutCommit(requests, restoreArgs));
            }
        }