/// <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(); }
/// <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); } }
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); }
private ResolverGather(GatherContext context) { _context = context; _maxDegreeOfParallelism = PackageManagementConstants.DefaultMaxDegreeOfParallelism; RequestTimeout = PackageManagementConstants.DefaultRequestTimeout; _workerTasks = new List <Task <GatherResult> >(_maxDegreeOfParallelism); _cache = _context.ResolutionContext?.GatherCache; }
/// <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); }
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(); }
/// <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(); }
/// <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); }
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); }
/// <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); } }
/// <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); } }
/// <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); } }