/// <summary>
        /// Initializes a new instance of the <see cref="NuGetPackageInstaller"/> class.
        /// </summary>
        /// <param name="fileSystem">The file system.</param>
        /// <param name="environment">The environment.</param>
        /// <param name="contentResolver">The content resolver.</param>
        /// <param name="log">The log.</param>
        /// <param name="config">the configuration</param>
        public NuGetPackageInstaller(
            IFileSystem fileSystem,
            ICakeEnvironment environment,
            INuGetContentResolver contentResolver,
            ICakeLog log,
            ICakeConfiguration config)
        {
            _fileSystem       = fileSystem ?? throw new ArgumentNullException(nameof(fileSystem));
            _environment      = environment ?? throw new ArgumentNullException(nameof(environment));
            _contentResolver  = contentResolver ?? throw new ArgumentNullException(nameof(contentResolver));
            _log              = log ?? throw new ArgumentNullException(nameof(log));
            _config           = config ?? throw new ArgumentNullException(nameof(config));
            _currentFramework = NuGetFramework.Parse(_environment.Runtime.BuiltFramework.FullName, DefaultFrameworkNameProvider.Instance);
            _nugetLogger      = new NuGetLogger(_log);

            var nugetConfig = GetNuGetConfigPath(_environment, _config);
            var nugetConfigDirectoryPath = nugetConfig.Item1;
            var nugetConfigFilePath      = nugetConfig.Item2;

            _log.Debug(nugetConfigFilePath != null
                ? $"Found NuGet.config at: {nugetConfigFilePath}"
                : "NuGet.config not found.");

            _nugetSettings = Settings.LoadDefaultSettings(
                nugetConfigDirectoryPath.FullPath,
                nugetConfigFilePath?.GetFilename().ToString(),
                new XPlatMachineWideSetting());
            _gatherCache        = new GatherCache();
            _sourceCacheContext = new SourceCacheContext();
        }
예제 #2
0
        /// <summary>
        /// Core install method. All installs from the VS API and template wizard end up here.
        /// This does not check for already installed packages
        /// </summary>
        internal async Task InstallInternalCoreAsync(
            NuGetPackageManager packageManager,
            GatherCache gatherCache,
            NuGetProject nuGetProject,
            PackageIdentity package,
            IEnumerable <SourceRepository> sources,
            VSAPIProjectContext projectContext,
            bool includePrerelease,
            bool ignoreDependencies,
            CancellationToken token)
        {
            await TaskScheduler.Default;

            DependencyBehavior depBehavior = ignoreDependencies ? DependencyBehavior.Ignore : DependencyBehavior.Lowest;

            ResolutionContext resolution = new ResolutionContext(
                depBehavior,
                includePrerelease,
                includeUnlisted: false,
                versionConstraints: VersionConstraints.None,
                gatherCache: gatherCache);

            // install the package
            if (package.Version == null)
            {
                await packageManager.InstallPackageAsync(nuGetProject, package.Id, resolution, projectContext, sources, Enumerable.Empty <SourceRepository>(), token);
            }
            else
            {
                await packageManager.InstallPackageAsync(nuGetProject, package, resolution, projectContext, sources, Enumerable.Empty <SourceRepository>(), token);
            }
        }
예제 #3
0
        protected async Task <IReadOnlyList <ResolvedAction> > GetActionsForUpdateAsync(IEnumerable <NuGetProject> targets,
                                                                                        PackageIdentity packageIdentity,
                                                                                        INuGetProjectContext projectContext,
                                                                                        SourceCacheContext sourceCacheContext,
                                                                                        CancellationToken token)
        {
            GatherCache gatherCache = new GatherCache();

            bool includePrerelease = packageIdentity.Version.IsPrerelease;

            List <ResolvedAction> results = new List <ResolvedAction>();

            ResolutionContext resolutionContext = new ResolutionContext(_dependencyBehavior,
                                                                        includePrerelease,
                                                                        includeUnlisted: true,
                                                                        VersionConstraints.None,
                                                                        gatherCache,
                                                                        sourceCacheContext);

            try
            {
                var actions = await _packageManager.PreviewUpdatePackagesAsync(packageIdentity, targets, resolutionContext, projectContext, PrimarySourcesRepository, SecondarySourcesRepository, token);

                results.AddRange(actions.Select(a => new ResolvedAction(a.Project, a)));
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex);
                throw;
            }

            return(results);
        }
예제 #4
0
        private ResolverGather(GatherContext context)
        {
            _context = context;

            _maxDegreeOfParallelism = PackageManagementConstants.DefaultMaxDegreeOfParallelism;
            RequestTimeout          = PackageManagementConstants.DefaultRequestTimeout;

            _workerTasks = new List <Task <GatherResult> >(_maxDegreeOfParallelism);

            _cache = _context.ResolutionContext?.GatherCache;
        }
예제 #5
0
        /// <summary>
        /// Calculates the list of actions needed to perform packages updates.
        /// </summary>
        /// <param name="uiService">ui service.</param>
        /// <param name="packagesToUpdate">The list of packages to update.</param>
        /// <param name="token">Cancellation token.</param>
        /// <returns>The list of actions.</returns>
        private async Task <IReadOnlyList <ResolvedAction> > ResolveActionsForUpdate(
            INuGetUI uiService,
            List <PackageIdentity> packagesToUpdate,
            CancellationToken token)
        {
            var resolvedActions = new List <ResolvedAction>();

            // Keep a single gather cache across projects
            var gatherCache = new GatherCache();

            foreach (var project in uiService.Projects)
            {
                var installedPackages = await project.GetInstalledPackagesAsync(token);

                HashSet <string> packageIds = new HashSet <string>(StringComparer.OrdinalIgnoreCase);
                foreach (var p in installedPackages)
                {
                    packageIds.Add(p.PackageIdentity.Id);
                }

                // We need to filter out packages from packagesToUpdate that are not installed
                // in the current project. Otherwise, we'll incorrectly install a
                // package that is not installed before.
                var packagesToUpdateInProject = packagesToUpdate.Where(
                    package => packageIds.Contains(package.Id)).ToList();

                if (packagesToUpdateInProject.Any())
                {
                    var includePrerelease = packagesToUpdateInProject.Where(
                        package => package.Version.IsPrerelease).Any();

                    var resolutionContext = new ResolutionContext(
                        uiService.DependencyBehavior,
                        includePrelease: includePrerelease,
                        includeUnlisted: true,
                        versionConstraints: VersionConstraints.None,
                        gatherCache: gatherCache);

                    var actions = await _packageManager.PreviewUpdatePackagesAsync(
                        packagesToUpdateInProject,
                        project,
                        resolutionContext,
                        uiService.ProgressWindow,
                        uiService.ActiveSources,
                        uiService.ActiveSources,
                        token);

                    resolvedActions.AddRange(actions.Select(action => new ResolvedAction(project, action))
                                             .ToList());
                }
            }

            return(resolvedActions);
        }
예제 #6
0
 public NugetFolderProject(
     IFileSystem fileSystem,
     INuGetContentResolver contentResolver,
     ICakeConfiguration config,
     ICakeLog log,
     PackagePathResolver pathResolver,
     string root,
     NuGetFramework targetFramework) : base(root, pathResolver)
 {
     _fileSystem        = fileSystem ?? throw new ArgumentNullException(nameof(fileSystem));
     _contentResolver   = contentResolver ?? throw new ArgumentNullException(nameof(contentResolver));
     _config            = config ?? throw new ArgumentNullException(nameof(config));
     _log               = log ?? throw new ArgumentNullException(nameof(log));
     _pathResolver      = pathResolver ?? throw new ArgumentNullException(nameof(pathResolver));
     _installedPackages = new HashSet <PackageIdentity>();
     TargetFramework    = targetFramework ?? throw new ArgumentNullException(nameof(targetFramework));
     InternalMetadata[NuGetProjectMetadataKeys.TargetFramework] = TargetFramework;
     GatherCache = new GatherCache();
 }
예제 #7
0
 /// <summary>
 /// Initializes a new instance of the <see cref="NuGetPackageInstaller"/> class.
 /// </summary>
 /// <param name="fileSystem">The file system.</param>
 /// <param name="environment">The environment.</param>
 /// <param name="contentResolver">The content resolver.</param>
 /// <param name="log">The log.</param>
 /// <param name="config">the configuration</param>
 public NuGetPackageInstaller(
     IFileSystem fileSystem,
     ICakeEnvironment environment,
     INuGetContentResolver contentResolver,
     ICakeLog log,
     ICakeConfiguration config)
 {
     _fileSystem       = fileSystem ?? throw new ArgumentNullException(nameof(fileSystem));
     _environment      = environment ?? throw new ArgumentNullException(nameof(environment));
     _contentResolver  = contentResolver ?? throw new ArgumentNullException(nameof(contentResolver));
     _log              = log ?? throw new ArgumentNullException(nameof(log));
     _config           = config ?? throw new ArgumentNullException(nameof(config));
     _currentFramework = NuGetFramework.Parse(_environment.Runtime.TargetFramework.FullName, DefaultFrameworkNameProvider.Instance);
     _nugetLogger      = new NuGetLogger(_log);
     _nugetSettings    = Settings.LoadDefaultSettings(
         GetToolPath(),
         null,
         new XPlatMachineWideSetting());
     _gatherCache = new GatherCache();
 }
예제 #8
0
        /// <summary>
        /// Calculates the list of actions needed to perform packages updates.
        /// </summary>
        /// <param name="uiService">ui service.</param>
        /// <param name="packagesToUpdate">The list of packages to update.</param>
        /// <param name="token">Cancellation token.</param>
        /// <returns>The list of actions.</returns>
        private async Task <IReadOnlyList <ResolvedAction> > ResolveActionsForUpdateAsync(
            INuGetUI uiService,
            List <PackageIdentity> packagesToUpdate,
            CancellationToken token)
        {
            var resolvedActions = new List <ResolvedAction>();

            // Keep a single gather cache across projects
            var gatherCache = new GatherCache();

            var includePrerelease = packagesToUpdate.Where(
                package => package.Version.IsPrerelease).Any();

            using (var sourceCacheContext = new SourceCacheContext())
            {
                var resolutionContext = new ResolutionContext(
                    uiService.DependencyBehavior,
                    includePrelease: includePrerelease,
                    includeUnlisted: true,
                    versionConstraints: VersionConstraints.None,
                    gatherCache: gatherCache,
                    sourceCacheContext: sourceCacheContext);

                var secondarySources = _sourceProvider.GetRepositories().Where(e => e.PackageSource.IsEnabled);

                var actions = await _packageManager.PreviewUpdatePackagesAsync(
                    packagesToUpdate,
                    uiService.Projects,
                    resolutionContext,
                    uiService.ProjectContext,
                    uiService.ActiveSources,
                    secondarySources,
                    token);

                resolvedActions.AddRange(actions.Select(action => new ResolvedAction(action.Project, action))
                                         .ToList());
            }

            return(resolvedActions);
        }
예제 #9
0
        protected async Task <IReadOnlyList <ResolvedAction> > GetActionsForInstallAsync(IEnumerable <NuGetProject> targets,
                                                                                         PackageIdentity packageIdentity,
                                                                                         INuGetProjectContext projectContext,
                                                                                         SourceCacheContext sourceCacheContext,
                                                                                         CancellationToken token)
        {
            GatherCache gatherCache = new GatherCache();

            bool includePrerelease = packageIdentity.Version.IsPrerelease;

            List <ResolvedAction> results = new List <ResolvedAction>();

            ResolutionContext resolutionContext = new ResolutionContext(_dependencyBehavior,
                                                                        includePrerelease,
                                                                        includeUnlisted: true,
                                                                        VersionConstraints.None,
                                                                        gatherCache,
                                                                        sourceCacheContext);

            foreach (NuGetProject target in targets)
            {
                if (!((await target.GetInstalledPackagesAsync(token))?.Any(t => t.PackageIdentity.Id.Equals(packageIdentity.Id, StringComparison.InvariantCultureIgnoreCase) && t.PackageIdentity.Version == packageIdentity.Version) ?? false))
                {
                    try
                    {
                        var actions = await _packageManager.PreviewInstallPackageAsync(target, packageIdentity, resolutionContext, projectContext, PrimarySourcesRepository, SecondarySourcesRepository, token);

                        results.AddRange(actions.Select(a => new ResolvedAction(target, a)));
                    }
                    catch (Exception ex)
                    {
                        Debug.WriteLine(ex);
                        throw;
                    }
                }
            }

            return(results);
        }
예제 #10
0
        /// <summary>
        /// Installs one or more packages into the specified project.
        /// </summary>
        /// <param name="packageInstaller">The package installer service that performs the actual package installation.</param>
        /// <param name="project">The target project for installation.</param>
        /// <param name="configuration">
        /// The packages to install, where to install them from, and additional options for
        /// their installation.
        /// </param>
        /// <param name="repositorySettings">The repository settings for the packages being installed.</param>
        /// <param name="warningHandler">
        /// An action that accepts a warning message and presents it to the user, allowing
        /// execution to continue.
        /// </param>
        /// <param name="errorHandler">
        /// An action that accepts an error message and presents it to the user, allowing
        /// execution to continue.
        /// </param>
        internal async Task PerformPackageInstallAsync(
            IVsPackageInstaller packageInstaller,
            EnvDTE.Project project,
            PreinstalledPackageConfiguration configuration,
            Action <string> warningHandler,
            Action <string> errorHandler)
        {
            ThreadHelper.ThrowIfNotOnUIThread();

            string repositoryPath      = configuration.RepositoryPath;
            var    repositorySource    = new Configuration.PackageSource(repositoryPath);
            var    failedPackageErrors = new List <string>();

            // find the project
            var defaultProjectContext = new VSAPIProjectContext();
            var nuGetProject          = await _solutionManager.GetOrCreateProjectAsync(project, defaultProjectContext);

            // For BuildIntegratedNuGetProject, nuget will ignore preunzipped configuration.
            var buildIntegratedProject = nuGetProject as BuildIntegratedNuGetProject;

            var repository = (buildIntegratedProject == null && configuration.IsPreunzipped) ?
                             _sourceProvider.CreateRepository(repositorySource, FeedType.FileSystemUnzipped) :
                             _sourceProvider.CreateRepository(repositorySource);

            var repoProvider = new PreinstalledRepositoryProvider(errorHandler, _sourceProvider);

            repoProvider.AddFromSource(repository);

            var packageManager = _installer.CreatePackageManager(repoProvider);
            var gatherCache    = new GatherCache();

            var sources = repoProvider.GetRepositories().ToList();

            // store expanded node state
            var expandedNodes = await VsHierarchyUtility.GetAllExpandedNodesAsync(_solutionManager);

            try
            {
                foreach (var package in configuration.Packages)
                {
                    var packageIdentity = new PackageIdentity(package.Id, package.Version);

                    // Does the project already have this package installed?
                    if (_packageServices.IsPackageInstalled(project, package.Id))
                    {
                        // If so, is it the right version?
                        if (!_packageServices.IsPackageInstalledEx(project, package.Id, package.Version.ToNormalizedString()))
                        {
                            // No? Raise a warning (likely written to the Output window) and ignore this package.
                            warningHandler(String.Format(VsResources.PreinstalledPackages_VersionConflict, package.Id, package.Version));
                        }
                        // Yes? Just silently ignore this package!
                    }
                    else
                    {
                        try
                        {
                            if (InfoHandler != null)
                            {
                                InfoHandler(String.Format(CultureInfo.CurrentCulture, VsResources.PreinstalledPackages_PackageInstallStatus, package.Id, package.Version));
                            }

                            // Skip assembly references and disable binding redirections should be done together
                            bool disableBindingRedirects = package.SkipAssemblyReferences;

                            var projectContext = new VSAPIProjectContext(package.SkipAssemblyReferences, disableBindingRedirects);

                            // Old templates have hardcoded non-normalized paths
                            projectContext.PackageExtractionContext.UseLegacyPackageInstallPath = true;

                            // This runs from the UI thread
                            await _installer.InstallInternalCoreAsync(
                                packageManager,
                                gatherCache,
                                nuGetProject,
                                packageIdentity,
                                sources,
                                projectContext,
                                includePrerelease : false,
                                ignoreDependencies : package.IgnoreDependencies,
                                token : CancellationToken.None);
                        }
                        catch (InvalidOperationException exception)
                        {
                            failedPackageErrors.Add(package.Id + "." + package.Version + " : " + exception.Message);
                        }
                        catch (AggregateException aggregateEx)
                        {
                            var ex = aggregateEx.Flatten().InnerExceptions.FirstOrDefault();
                            if (ex is InvalidOperationException)
                            {
                                failedPackageErrors.Add(package.Id + "." + package.Version + " : " + ex.Message);
                            }
                            else
                            {
                                throw;
                            }
                        }
                    }
                }

                if (failedPackageErrors.Any())
                {
                    var errorString = new StringBuilder();
                    errorString.AppendFormat(VsResources.PreinstalledPackages_FailedToInstallPackage, repositoryPath);
                    errorString.AppendLine();
                    errorString.AppendLine();
                    errorString.Append(String.Join(Environment.NewLine, failedPackageErrors));

                    errorHandler(errorString.ToString());
                }

                // RepositorySettings = null in unit tests
                if (EnvDTEProjectInfoUtility.IsWebSite(project))
                {
                    CreateRefreshFilesInBin(
                        project,
                        repositoryPath,
                        configuration.Packages.Where(p => p.SkipAssemblyReferences));

                    CopyNativeBinariesToBin(project, repositoryPath, configuration.Packages);
                }
            }
            finally
            {
                // collapse nodes
                await VsHierarchyUtility.CollapseAllNodesAsync(_solutionManager, expandedNodes);
            }
        }
예제 #11
0
        /// <summary>
        /// Internal install method. All installs from the VS API and template wizard end up here.
        /// </summary>
        internal async Task InstallInternalAsync(
            Project project,
            List <PackageIdentity> packages,
            ISourceRepositoryProvider repoProvider,
            VSAPIProjectContext projectContext,
            bool includePrerelease,
            bool ignoreDependencies,
            CancellationToken token)
        {
            // Go off the UI thread. This may be called from the UI thread. Only switch to the UI thread where necessary
            // This method installs multiple packages and can likely take more than a few secs
            // So, go off the UI thread explicitly to improve responsiveness
            await TaskScheduler.Default;

            var gatherCache = new GatherCache();
            var sources     = repoProvider.GetRepositories().ToList();

            // store expanded node state
            IDictionary <string, ISet <VsHierarchyItem> > expandedNodes = await VsHierarchyUtility.GetAllExpandedNodesAsync(_solutionManager);

            try
            {
                DependencyBehavior depBehavior = ignoreDependencies ? DependencyBehavior.Ignore : DependencyBehavior.Lowest;

                ResolutionContext resolution = new ResolutionContext(
                    depBehavior,
                    includePrerelease,
                    includeUnlisted: false,
                    versionConstraints: VersionConstraints.None);

                var packageManager = CreatePackageManager(repoProvider);

                // find the project
                var nuGetProject = await _solutionManager.GetOrCreateProjectAsync(project, projectContext);

                // install the package
                foreach (PackageIdentity package in packages)
                {
                    // Check if the package is already installed
                    if (package.Version == null)
                    {
                        if (_packageServices.IsPackageInstalled(project, package.Id))
                        {
                            continue;
                        }
                    }
                    else
                    {
                        if (_packageServices.IsPackageInstalledEx(project, package.Id, package.Version.ToString()))
                        {
                            continue;
                        }
                    }

                    // Perform the install
                    await InstallInternalCoreAsync(
                        packageManager,
                        gatherCache,
                        nuGetProject,
                        package,
                        sources,
                        projectContext,
                        includePrerelease,
                        ignoreDependencies,
                        token);
                }
            }
            finally
            {
                // collapse nodes
                await VsHierarchyUtility.CollapseAllNodesAsync(_solutionManager, expandedNodes);
            }
        }
예제 #12
0
        /// <summary>
        /// Internal install method. All installs from the VS API and template wizard end up here.
        /// </summary>
        internal async Task InstallInternalAsync(
            Project project,
            List <PackageIdentity> packages,
            ISourceRepositoryProvider repoProvider,
            VSAPIProjectContext projectContext,
            bool includePrerelease,
            bool ignoreDependencies,
            CancellationToken token)
        {
            // Go off the UI thread. This may be called from the UI thread. Only switch to the UI thread where necessary
            // This method installs multiple packages and can likely take more than a few secs
            // So, go off the UI thread explicitly to improve responsiveness
            await TaskScheduler.Default;

            var gatherCache = new GatherCache();
            var sources     = repoProvider.GetRepositories().ToList();

            // store expanded node state
            var expandedNodes = await VsHierarchyUtility.GetAllExpandedNodesAsync();

            try
            {
                var depBehavior = ignoreDependencies ? DependencyBehavior.Ignore : DependencyBehavior.Lowest;

                var packageManager = CreatePackageManager(repoProvider);

                // find the project
                var nuGetProject = await _solutionManager.GetOrCreateProjectAsync(project, projectContext);

                var packageManagementFormat = new PackageManagementFormat(_settings);
                // 1 means PackageReference
                var preferPackageReference = packageManagementFormat.SelectedPackageManagementFormat == 1;

                // Check if default package format is set to `PackageReference` and project has no
                // package installed yet then upgrade it to `PackageReference` based project.
                if (preferPackageReference &&
                    (nuGetProject is MSBuildNuGetProject) &&
                    !(await nuGetProject.GetInstalledPackagesAsync(token)).Any() &&
                    await NuGetProjectUpgradeUtility.IsNuGetProjectUpgradeableAsync(nuGetProject, project, needsAPackagesConfig: false))
                {
                    nuGetProject = await _solutionManager.UpgradeProjectToPackageReferenceAsync(nuGetProject);
                }

                // install the package
                foreach (var package in packages)
                {
                    var installedPackageReferences = await nuGetProject.GetInstalledPackagesAsync(token);

                    // Check if the package is already installed
                    if (package.Version != null &&
                        PackageServiceUtilities.IsPackageInList(installedPackageReferences, package.Id, package.Version))
                    {
                        continue;
                    }

                    // Perform the install
                    await InstallInternalCoreAsync(
                        packageManager,
                        gatherCache,
                        nuGetProject,
                        package,
                        sources,
                        projectContext,
                        includePrerelease,
                        ignoreDependencies,
                        token);
                }
            }
            finally
            {
                // collapse nodes
                await VsHierarchyUtility.CollapseAllNodesAsync(expandedNodes);
            }
        }