/// <summary>
        /// Install package by Identity
        /// </summary>
        /// <param name="project"></param>
        /// <param name="identity"></param>
        /// <param name="resolutionContext"></param>
        /// <param name="projectContext"></param>
        /// <param name="isPreview"></param>
        /// <param name="isForce"></param>
        /// <param name="uninstallContext"></param>
        /// <returns></returns>
        protected async Task InstallPackageByIdentityAsync(NuGetProject project, PackageIdentity identity, ResolutionContext resolutionContext, INuGetProjectContext projectContext, bool isPreview, bool isForce = false, UninstallationContext uninstallContext = null)
        {
            List<NuGetProjectAction> actions = new List<NuGetProjectAction>();
            // For Install-Package -Force
            if (isForce)
            {
                PackageReference installedReference = project.GetInstalledPackagesAsync(CancellationToken.None).Result.Where(p =>
                    StringComparer.OrdinalIgnoreCase.Equals(identity.Id, p.PackageIdentity.Id)).FirstOrDefault();
                if (installedReference != null)
                {
                    actions.AddRange(await PackageManager.PreviewUninstallPackageAsync(project, installedReference.PackageIdentity, uninstallContext, projectContext, CancellationToken.None));
                }
                NuGetProjectAction installAction = NuGetProjectAction.CreateInstallProjectAction(identity, ActiveSourceRepository);
                actions.Add(installAction);
            }
            else
            {
                actions.AddRange(await PackageManager.PreviewInstallPackageAsync(project, identity, resolutionContext, projectContext, ActiveSourceRepository, null, CancellationToken.None));
            }

            if (isPreview)
            {
                PreviewNuGetPackageActions(actions);
            }
            else
            {
                await PackageManager.ExecuteNuGetProjectActionsAsync(project, actions, this, CancellationToken.None);
            }
        }
 private PackageReference GetInstalledPackage(NuGetProject project, string id)
 {
     var installedPackagesTask = project.GetInstalledPackagesAsync(CancellationToken.None);
     installedPackagesTask.Wait();
     var installedPackage = installedPackagesTask.Result
         .Where(p => StringComparer.OrdinalIgnoreCase.Equals(p.PackageIdentity.Id, id))
         .FirstOrDefault();
     return installedPackage;
 }
        protected virtual bool EnablePackageRestore(NuGetProject nuGetProject)
        {
            var installedPackages = nuGetProject.GetInstalledPackagesAsync(CancellationToken.None).Result;
            if(!installedPackages.Any())
            {
                return true;
            }

            return false;
        }
        /// <summary>
        /// Gives the preview as a list of NuGetProjectActions that will be performed to install <param name="packageId"></param> into <param name="nuGetProject"></param>
        /// <param name="resolutionContext"></param> and <param name="nuGetProjectContext"></param> are used in the process
        /// </summary>
        public async Task<IEnumerable<NuGetProjectAction>> PreviewInstallPackageAsync(NuGetProject nuGetProject, string packageId,
            ResolutionContext resolutionContext, INuGetProjectContext nuGetProjectContext,
            SourceRepository primarySourceRepository, IEnumerable<SourceRepository> secondarySources, CancellationToken token)
        {
            if (nuGetProject == null)
            {
                throw new ArgumentNullException("nuGetProject");
            }

            if (packageId == null)
            {
                throw new ArgumentNullException("packageId");
            }

            if (resolutionContext == null)
            {
                throw new ArgumentNullException("resolutionContext");
            }

            if (nuGetProjectContext == null)
            {
                throw new ArgumentNullException("nuGetProjectContext");
            }
            // Step-1 : Get latest version for packageId
            var latestVersion = await GetLatestVersionAsync(packageId, resolutionContext, primarySourceRepository, token);

            if (latestVersion == null)
            {
                throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, Strings.UnknownPackage, packageId));
            }

            var projectInstalledPackageReferences = await nuGetProject.GetInstalledPackagesAsync(token);
            var installedPackageReference = projectInstalledPackageReferences.Where(pr => StringComparer.OrdinalIgnoreCase.Equals(pr.PackageIdentity.Id, packageId)).FirstOrDefault();
            if(installedPackageReference != null && installedPackageReference.PackageIdentity.Version > latestVersion)
            {
                throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, Strings.NewerVersionAlreadyReferenced, packageId));
            }

            // Step-2 : Call InstallPackage(project, packageIdentity)
            return await PreviewInstallPackageAsync(nuGetProject, new PackageIdentity(packageId, latestVersion), resolutionContext,
                nuGetProjectContext, primarySourceRepository, secondarySources, token);
        }
Example #5
0
        private async Task EmitNuGetProjectAsync(EnvDTEProject vsProject, NuGetProject nuGetProject)
        {
            // Get the project details.
            var projectUniqueName = nuGetProject.GetMetadata <string>(NuGetProjectMetadataKeys.UniqueName);
            var projectId         = Guid.Empty;

            try
            {
                projectId = await ThreadHelper.JoinableTaskFactory.RunAsync(async delegate
                {
                    await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();

                    // Get the project ID.
                    var vsHierarchyItem = VsHierarchyUtility.GetHierarchyItemForProject(vsProject);
                    Guid id;
                    if (!vsHierarchyItem.TryGetProjectId(out id))
                    {
                        id = Guid.Empty;
                    }

                    return(id);
                });
            }
            catch (Exception ex)
            {
                var message =
                    $"Failed to get project name or project ID. Exception:" +
                    Environment.NewLine +
                    ex.ToString();

                ActivityLog.LogWarning(ExceptionHelper.LogEntrySource, message);
                Debug.Fail(message);

                return;
            }

            // Emit the project information.
            try
            {
                var projectType = NuGetProjectType.Unknown;
                if (nuGetProject is MSBuildNuGetProject)
                {
                    projectType = NuGetProjectType.PackagesConfig;
                }
                else if (nuGetProject is BuildIntegratedNuGetProject)
                {
                    projectType = NuGetProjectType.UwpProjectJson;
                }
                else if (nuGetProject is ProjectKNuGetProjectBase)
                {
                    projectType = NuGetProjectType.XProjProjectJson;
                }

                var projectInformation = new ProjectInformation(
                    NuGetVersion.Value,
                    projectId,
                    projectType);

                _nuGetTelemetryService.EmitProjectInformation(projectInformation);
            }
            catch (Exception ex)
            {
                var message =
                    $"Failed to emit project information for project '{projectUniqueName}'. Exception:" +
                    Environment.NewLine +
                    ex.ToString();

                ActivityLog.LogWarning(ExceptionHelper.LogEntrySource, message);
                Debug.Fail(message);
            }

            // Emit the project dependency statistics.
            try
            {
                var installedPackages = await nuGetProject.GetInstalledPackagesAsync(CancellationToken.None);

                var installedPackagesCount = installedPackages.Count();

                var projectDependencyStatistics = new ProjectDependencyStatistics(
                    NuGetVersion.Value,
                    projectId,
                    installedPackagesCount);

                _nuGetTelemetryService.EmitProjectDependencyStatistics(projectDependencyStatistics);
            }
            catch (Exception ex)
            {
                var message =
                    $"Failed to emit project dependency statistics for project '{projectUniqueName}'. Exception:" +
                    Environment.NewLine +
                    ex.ToString();

                ActivityLog.LogWarning(message, ExceptionHelper.LogEntrySource);
                Debug.Fail(message);
            }
        }
Example #6
0
        async Task <bool> ProjectHasPrereleasePackages(CancellationToken cancellationToken)
        {
            packageReferences = await project.GetInstalledPackagesAsync(cancellationToken);

            return(packageReferences.Any(packageReference => packageReference.PackageIdentity.Version.IsPrerelease));
        }
        private async Task<IEnumerable<NuGetProjectAction>> PreviewUninstallPackageAsyncPrivate(NuGetProject nuGetProject, PackageReference packageReference,
            UninstallationContext uninstallationContext, INuGetProjectContext nuGetProjectContext, CancellationToken token)
        {
            if(SolutionManager == null)
            {
                throw new InvalidOperationException(Strings.SolutionManagerNotAvailableForUninstall);
            }

            if (nuGetProject is ProjectManagement.Projects.ProjectKNuGetProjectBase)
            {
                var action = NuGetProjectAction.CreateUninstallProjectAction(packageReference.PackageIdentity);
                return new NuGetProjectAction[] { action };
            }

            // Step-1 : Get the metadata resources from "packages" folder or custom repository path
            var packageIdentity = packageReference.PackageIdentity;
            var packageReferenceTargetFramework = packageReference.TargetFramework;
            nuGetProjectContext.Log(MessageLevel.Info, Strings.AttemptingToGatherDependencyInfo, packageIdentity, packageReferenceTargetFramework);

            // TODO: IncludePrerelease is a big question mark
            var installedPackageIdentities = (await nuGetProject.GetInstalledPackagesAsync(token)).Select(pr => pr.PackageIdentity);
            var dependencyInfoFromPackagesFolder = await GetDependencyInfoFromPackagesFolder(installedPackageIdentities,
                packageReferenceTargetFramework, includePrerelease: true);

            nuGetProjectContext.Log(MessageLevel.Info, Strings.ResolvingActionsToUninstallPackage, packageIdentity);
            // Step-2 : Determine if the package can be uninstalled based on the metadata resources
            var packagesToBeUninstalled = UninstallResolver.GetPackagesToBeUninstalled(packageIdentity, dependencyInfoFromPackagesFolder, installedPackageIdentities, uninstallationContext);

            var nuGetProjectActions = packagesToBeUninstalled.Select(p => NuGetProjectAction.CreateUninstallProjectAction(p));

            nuGetProjectContext.Log(MessageLevel.Info, Strings.ResolvedActionsToUninstallPackage, packageIdentity);
            return nuGetProjectActions;
        }
        public async Task<IEnumerable<NuGetProjectAction>> PreviewInstallPackageAsync(NuGetProject nuGetProject, PackageIdentity packageIdentity,
            ResolutionContext resolutionContext, INuGetProjectContext nuGetProjectContext,
            IEnumerable<SourceRepository> primarySources, IEnumerable<SourceRepository> secondarySources,
            CancellationToken token)
        {
            if(nuGetProject == null)
            {
                throw new ArgumentNullException("nuGetProject");
            }

            if (packageIdentity == null)
            {
                throw new ArgumentNullException("packageIdentity");
            }

            if(resolutionContext == null)
            {
                throw new ArgumentNullException("resolutionContext");
            }

            if(nuGetProjectContext == null)
            {
                throw new ArgumentNullException("nuGetProjectContext");
            }

            if (primarySources == null)
            {
                throw new ArgumentNullException("primarySources");
            }

            if (secondarySources == null)
            {
                secondarySources = SourceRepositoryProvider.GetRepositories().Where(e => e.PackageSource.IsEnabled);
            }

            if(!primarySources.Any())
            {
                throw new ArgumentException("primarySources");
            }

            if(packageIdentity.Version == null)
            {
                throw new ArgumentNullException("packageIdentity.Version");
            }

            // TODO: BUGBUG: HACK: Multiple primary repositories is mainly intended for nuget.exe at the moment
            // The following special case for ProjectK is not correct, if they used nuget.exe
            // and multiple repositories in the -Source switch
            if (nuGetProject is ProjectManagement.Projects.ProjectKNuGetProjectBase)
            {
                var action = NuGetProjectAction.CreateInstallProjectAction(packageIdentity, primarySources.First());
                return new NuGetProjectAction[] { action };
            }

            var projectInstalledPackageReferences = await nuGetProject.GetInstalledPackagesAsync(token);
            var oldListOfInstalledPackages = projectInstalledPackageReferences.Select(p => p.PackageIdentity);
            if(oldListOfInstalledPackages.Any(p => p.Equals(packageIdentity)))
            {
                string projectName;
                nuGetProject.TryGetMetadata<string>(NuGetProjectMetadataKeys.Name, out projectName);
                throw new InvalidOperationException(String.Format(NuGet.ProjectManagement.Strings.PackageAlreadyExistsInProject, packageIdentity, projectName ?? String.Empty));
            }

            List<NuGetProjectAction> nuGetProjectActions = new List<NuGetProjectAction>();
            // TODO: these sources should be ordered
            // TODO: search in only the active source but allow dependencies to come from other sources?

            var effectiveSources = GetEffectiveSources(primarySources, secondarySources);
            
            if (resolutionContext.DependencyBehavior != DependencyBehavior.Ignore)
            {
                try
                {
                    bool downgradeAllowed = false;
                    var packageTargetsForResolver = new HashSet<PackageIdentity>(oldListOfInstalledPackages, PackageIdentity.Comparer);
                    // Note: resolver needs all the installed packages as targets too. And, metadata should be gathered for the installed packages as well
                    var installedPackageWithSameId = packageTargetsForResolver.Where(p => p.Id.Equals(packageIdentity.Id, StringComparison.OrdinalIgnoreCase)).FirstOrDefault();
                    if(installedPackageWithSameId != null)
                    {
                        packageTargetsForResolver.Remove(installedPackageWithSameId);
                        if(installedPackageWithSameId.Version > packageIdentity.Version)
                        {
                            // Looks like the installed package is of higher version than one being installed. So, we take it that downgrade is allowed
                            downgradeAllowed = true;
                        }
                    }
                    packageTargetsForResolver.Add(packageIdentity);

                    // Step-1 : Get metadata resources using gatherer
                    var targetFramework = nuGetProject.GetMetadata<NuGetFramework>(NuGetProjectMetadataKeys.TargetFramework);
                    nuGetProjectContext.Log(MessageLevel.Info, Strings.AttemptingToGatherDependencyInfo, packageIdentity, targetFramework);

                    var primaryPackages = new List<PackageIdentity>() { packageIdentity };

                    // If any targets are prerelease we should gather with prerelease on and filter afterwards
                    bool includePrereleaseInGather = resolutionContext.IncludePrerelease || (packageTargetsForResolver.Any(p => (p.HasVersion && p.Version.IsPrerelease)));
                    ResolutionContext contextForGather = new ResolutionContext(resolutionContext.DependencyBehavior, includePrereleaseInGather, resolutionContext.IncludeUnlisted);

                    var availablePackageDependencyInfoWithSourceSet = await ResolverGather.GatherPackageDependencyInfo(contextForGather,
                        primaryPackages,
                        packageTargetsForResolver,
                        targetFramework,
                        primarySources,
                        effectiveSources,
                        token);

                    if (!availablePackageDependencyInfoWithSourceSet.Any())
                    {
                        throw new InvalidOperationException(String.Format(Strings.UnableToGatherDependencyInfo, packageIdentity));
                    }

                    // Prune the results down to only what we would allow to be installed

                    // Keep only the target package we are trying to install for that Id
                    IEnumerable<SourceDependencyInfo> prunedAvailablePackages = PrunePackageTree.RemoveAllVersionsForIdExcept(availablePackageDependencyInfoWithSourceSet, packageIdentity);

                    if (!resolutionContext.IncludePrerelease)
                    {
                        prunedAvailablePackages = PrunePackageTree.PrunePreleaseForStableTargets(prunedAvailablePackages, packageTargetsForResolver);
                    }

                    // Remove versions that do not satisfy 'allowedVersions' attribute in packages.config, if any
                    prunedAvailablePackages = PrunePackageTree.PruneDisallowedVersions(prunedAvailablePackages, projectInstalledPackageReferences);

                    // TODO: prune down level packages?

                    // Step-2 : Call IPackageResolver.Resolve to get new list of installed packages
                    // TODO: Consider using IPackageResolver once it is extensible
                    var packageResolver = new PackageResolver(resolutionContext.DependencyBehavior);
                    nuGetProjectContext.Log(MessageLevel.Info, Strings.AttemptingToResolveDependencies, packageIdentity, resolutionContext.DependencyBehavior);

                    // Note: resolver prefers installed package versions if the satisfy the dependency version constraints
                    // So, since we want an exact version of a package, create a new list of installed packages where the packageIdentity being installed
                    // is present after removing the one with the same id
                    var preferredPackageReferences = new List<PackageReference>(projectInstalledPackageReferences.Where(pr =>
                        !pr.PackageIdentity.Id.Equals(packageIdentity.Id, StringComparison.OrdinalIgnoreCase)));
                    preferredPackageReferences.Add(new PackageReference(packageIdentity, targetFramework));

                    IEnumerable<PackageIdentity> newListOfInstalledPackages = packageResolver.Resolve(packageTargetsForResolver,
                        prunedAvailablePackages,
                        preferredPackageReferences,
                        token);
                    if (newListOfInstalledPackages == null)
                    {
                        throw new InvalidOperationException(String.Format(Strings.UnableToResolveDependencyInfo, packageIdentity, resolutionContext.DependencyBehavior));
                    }

                    // Step-3 : Get the list of nuGetProjectActions to perform, install/uninstall on the nugetproject
                    // based on newPackages obtained in Step-2 and project.GetInstalledPackages                    

                    nuGetProjectContext.Log(MessageLevel.Info, Strings.ResolvingActionsToInstallPackage, packageIdentity);
                    var newPackagesToUninstall = new List<PackageIdentity>();
                    foreach(var oldInstalledPackage in oldListOfInstalledPackages)
                    {
                        var newPackageWithSameId = newListOfInstalledPackages
                            .Where(np => oldInstalledPackage.Id.Equals(np.Id, StringComparison.OrdinalIgnoreCase) &&
                            !oldInstalledPackage.Version.Equals(np.Version)).FirstOrDefault();

                        if(newPackageWithSameId != null)
                        {
                            if(!downgradeAllowed && oldInstalledPackage.Version > newPackageWithSameId.Version)
                            {
                                throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, Strings.NewerVersionAlreadyReferenced, newPackageWithSameId.Id));
                            }
                            newPackagesToUninstall.Add(oldInstalledPackage);
                        }
                    }
                    var newPackagesToInstall = newListOfInstalledPackages.Where(p => !oldListOfInstalledPackages.Contains(p));

                    foreach (PackageIdentity newPackageToUninstall in newPackagesToUninstall)
                    {
                        nuGetProjectActions.Add(NuGetProjectAction.CreateUninstallProjectAction(newPackageToUninstall));
                    }

                    var comparer = PackageIdentity.Comparer;

                    foreach (PackageIdentity newPackageToInstall in newPackagesToInstall)
                    {
                        // find the package match based on identity
                        SourceDependencyInfo sourceDepInfo = prunedAvailablePackages.Where(p => comparer.Equals(p, newPackageToInstall)).SingleOrDefault();

                        if (sourceDepInfo == null)
                        {
                            // this really should never happen
                            throw new InvalidOperationException(String.Format(Strings.PackageNotFound, packageIdentity));
                        }

                        nuGetProjectActions.Add(NuGetProjectAction.CreateInstallProjectAction(newPackageToInstall, sourceDepInfo.Source));
                    }
                }
                catch (InvalidOperationException)
                {
                    throw;
                }
                catch (AggregateException aggregateEx)
                {
                    throw new InvalidOperationException(aggregateEx.Message, aggregateEx);
                }
                catch (Exception ex)
                {
                    if (String.IsNullOrEmpty(ex.Message))
                    {
                        throw new InvalidOperationException(String.Format(Strings.PackageCouldNotBeInstalled, packageIdentity), ex);
                    }
                    else
                    {
                        throw new InvalidOperationException(ex.Message, ex);
                    }
                }
            }
            else
            {
                var sourceRepository = await GetSourceRepository(packageIdentity, effectiveSources);
                nuGetProjectActions.Add(NuGetProjectAction.CreateInstallProjectAction(packageIdentity, sourceRepository));
            }

            nuGetProjectContext.Log(MessageLevel.Info, Strings.ResolvedActionsToInstallPackage, packageIdentity);
            return nuGetProjectActions;
        }
        /// <summary>
        /// Install package by Id
        /// </summary>
        /// <param name="project"></param>
        /// <param name="packageId"></param>
        /// <param name="resolutionContext"></param>
        /// <param name="projectContext"></param>
        /// <param name="isPreview"></param>
        /// <param name="isForce"></param>
        /// <param name="uninstallContext"></param>
        /// <returns></returns>
        protected async Task InstallPackageByIdAsync(NuGetProject project, string packageId, ResolutionContext resolutionContext, INuGetProjectContext projectContext, bool isPreview, bool isForce = false, UninstallationContext uninstallContext = null)
        {
            List<NuGetProjectAction> actions = new List<NuGetProjectAction>();
            // For Install-Package -Force
            if (isForce)
            {
                PackageReference installedReference = project.GetInstalledPackagesAsync(CancellationToken.None).Result.Where(p =>
                    StringComparer.OrdinalIgnoreCase.Equals(packageId, p.PackageIdentity.Id)).FirstOrDefault();
                if (installedReference != null)
                {
                    actions.AddRange(await PackageManager.PreviewUninstallPackageAsync(project, packageId, uninstallContext, projectContext, CancellationToken.None));
                }
                NuGetVersion nVersion = PowerShellCmdletsUtility.GetLastestVersionForPackageId(ActiveSourceRepository, packageId, project, resolutionContext.IncludePrerelease);
                if (nVersion != null)
                {
                    PackageIdentity identityToInstall = new PackageIdentity(packageId, nVersion);
                    NuGetProjectAction installAction = NuGetProjectAction.CreateInstallProjectAction(identityToInstall, ActiveSourceRepository);
                    actions.Add(installAction);
                }
            }
            else
            {
                actions.AddRange(await PackageManager.PreviewInstallPackageAsync(project, packageId, resolutionContext, projectContext, ActiveSourceRepository, null, CancellationToken.None));
            }

            if (isPreview)
            {
                PreviewNuGetPackageActions(actions);
            }
            else
            {
                await PackageManager.ExecuteNuGetProjectActionsAsync(project, actions, this, CancellationToken.None);
            }
        }
 /// <summary>
 /// Get a list of package identities with installed package Ids but null versions
 /// </summary>
 /// <param name="project"></param>
 /// <returns></returns>
 private async Task<IEnumerable<string>> GeneratePackageIdListForUpdate(NuGetProject project, CancellationToken token)
 {
     IEnumerable<string> packageIds = (await project.GetInstalledPackagesAsync(token)).Select(v => v.PackageIdentity.Id);
     return packageIds;
 }
        /// <summary>
        /// Preview update actions for single package
        /// </summary>
        /// <param name="project"></param>
        /// <returns></returns>
        private async Task PreviewAndExecuteUpdateActionsforSinglePackage(NuGetProject project)
        {
            var token = CancellationToken.None;
            PackageReference installedPackage = (await project.GetInstalledPackagesAsync(token))
                .Where(p => string.Equals(p.PackageIdentity.Id, Id, StringComparison.OrdinalIgnoreCase)).FirstOrDefault();

            // If package Id exists in Packages folder but is not actually installed to the current project, throw.
            if (installedPackage == null)
            {
                Log(MessageLevel.Error, string.Format(Resources.PackageNotInstalledInAnyProject, Id));
            }
            else
            {
                // If -Version switch is specified
                if (!string.IsNullOrEmpty(Version))
                {
                    PackageIdentity update = GetUpdatePackageIdentityWhenVersionSpecified(project, installedPackage);
                    if (update != null)
                    {
                        // Update by package identity
                        await InstallPackageByIdentityAsync(project, update, ResolutionContext, this, WhatIf.IsPresent, Reinstall.IsPresent, UninstallContext);
                    }
                    else
                    {
                        Log(MessageLevel.Info, string.Format(Resources.Cmdlet_NoPackageUpdates, project.GetMetadata<string>(NuGetProjectMetadataKeys.Name)));
                    }
                }
                else
                {
                    if (Reinstall.IsPresent)
                    {
                        // Update-Package Id -Reinstall
                        PackageIdentity identity = installedPackage.PackageIdentity;
                        await InstallPackageByIdentityAsync(project, identity, ResolutionContext, this, WhatIf.IsPresent, Reinstall.IsPresent, UninstallContext);
                    }
                    else
                    {
                        // Update-Package Id
                        NormalizePackageId(project);
                        NuGetVersion latestVersion = PowerShellCmdletsUtility.GetLastestVersionForPackageId(ActiveSourceRepository, Id, project, _allowPrerelease);
                        if (latestVersion > installedPackage.PackageIdentity.Version)
                        {
                            await InstallPackageByIdAsync(project, Id, ResolutionContext, this, WhatIf.IsPresent, Reinstall.IsPresent, UninstallContext);
                        }
                        else
                        {
                            Log(MessageLevel.Info, string.Format(Resources.Cmdlet_NoPackageUpdates, project.GetMetadata<string>(NuGetProjectMetadataKeys.Name)));
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Preview update actions for all packages
        /// </summary>
        /// <param name="project"></param>
        /// <returns></returns>
        private async Task PreviewAndExecuteUpdateActionsforAllPackages(NuGetProject project)
        {
            var token = CancellationToken.None;
            IEnumerable<NuGetProjectAction> actions = Enumerable.Empty<NuGetProjectAction>();

            // Get the list of package ids or identities to be updated for PackageManager
            if (Reinstall.IsPresent)
            {
                // Update-Package -Reinstall -> get list of installed package identities
                IEnumerable<PackageIdentity> identitiesToUpdate = Enumerable.Empty<PackageIdentity>();
                identitiesToUpdate = (await project.GetInstalledPackagesAsync(token)).Select(v => v.PackageIdentity);
                // Preview Update-Package -Reinstall actions
                actions = await PackageManager.PreviewReinstallPackagesAsync(identitiesToUpdate, project, ResolutionContext,
                this, ActiveSourceRepository, null, token);
            }
            else
            {
                // Update-Package -> get list of installed package ids
                IEnumerable<string> idsToUpdate = Enumerable.Empty<string>();
                idsToUpdate = await GeneratePackageIdListForUpdate(project, token);
                // Preview Update-Package actions
                actions = await PackageManager.PreviewUpdatePackagesAsync(idsToUpdate, project, ResolutionContext,
                this, ActiveSourceRepository, null, token);
            }

            if (actions.Any())
            {
                if (WhatIf.IsPresent)
                {
                    // For -WhatIf, only preview the actions
                    PreviewNuGetPackageActions(actions);
                }
                else
                {
                    if (Reinstall.IsPresent)
                    {
                        var uninstallActions = actions.Where(a => a.NuGetProjectActionType == NuGetProjectActionType.Uninstall);
                        var installActions = actions.Where(a => a.NuGetProjectActionType == NuGetProjectActionType.Install);

                        // Execute uninstall actions first to ensure that the package is completely uninstalled even from packages folder
                        await PackageManager.ExecuteNuGetProjectActionsAsync(project, uninstallActions, this, CancellationToken.None);

                        // Execute install actions now
                        await PackageManager.ExecuteNuGetProjectActionsAsync(project, installActions, this, CancellationToken.None);
                    }
                    else
                    {
                        // Execute project actions by Package Manager
                        await PackageManager.ExecuteNuGetProjectActionsAsync(project, actions, this, CancellationToken.None);
                    }
                }
            }
            else
            {
                Log(MessageLevel.Info, string.Format(Resources.Cmdlet_NoPackageUpdates, project.GetMetadata<string>(NuGetProjectMetadataKeys.Name)));
            }
        }
 protected virtual Task <IEnumerable <PackageReference> > GetInstalledPackagesAsync(CancellationTokenSource tokenSource)
 {
     return(nugetProject.GetInstalledPackagesAsync(tokenSource.Token));
 }
Example #14
0
        /// <summary>
        /// Get a list of package identities with installed package Ids but null versions
        /// </summary>
        /// <param name="project"></param>
        /// <returns></returns>
        private async Task <IEnumerable <string> > GeneratePackageIdListForUpdate(NuGetProject project, CancellationToken token)
        {
            IEnumerable <string> packageIds = (await project.GetInstalledPackagesAsync(token)).Select(v => v.PackageIdentity.Id);

            return(packageIds);
        }
        public async Task<IEnumerable<NuGetProjectAction>> PreviewReinstallPackagesAsync(IEnumerable<PackageIdentity> packagesToInstall, NuGetProject nuGetProject,
            ResolutionContext resolutionContext, INuGetProjectContext nuGetProjectContext,
            SourceRepository primarySourceRepository, IEnumerable<SourceRepository> secondarySources,
            CancellationToken token)
        {
            if(packagesToInstall == null)
            {
                throw new ArgumentNullException("packagesToInstall");
            }

            if (nuGetProject == null)
            {
                throw new ArgumentNullException("nuGetProject");
            }

            if (resolutionContext == null)
            {
                throw new ArgumentNullException("resolutionContext");
            }

            if (nuGetProjectContext == null)
            {
                throw new ArgumentNullException("nuGetProjectContext");
            }

            if(packagesToInstall.Any(p => p.Version == null))
            {
                throw new ArgumentException("packagesToInstall");
            }

            if (primarySourceRepository == null)
            {
                throw new ArgumentNullException("primarySourceRepository");
            }
            var primarySources = new List<SourceRepository>() { primarySourceRepository };

            if (secondarySources == null)
            {
                secondarySources = SourceRepositoryProvider.GetRepositories().Where(e => e.PackageSource.IsEnabled);
            }

            var projectInstalledPackageReferences = await nuGetProject.GetInstalledPackagesAsync(token);
            var oldListOfInstalledPackages = projectInstalledPackageReferences.Select(p => p.PackageIdentity);

            // Note: resolver needs all the installed packages as targets too. And, metadata should be gathered for the installed packages as well
            var packageTargetsForResolver = new HashSet<PackageIdentity>(oldListOfInstalledPackages, PackageIdentity.Comparer);
            foreach(var packageToInstall in packagesToInstall)
            {
                packageTargetsForResolver.Add(packageToInstall);
            }

            List<NuGetProjectAction> nuGetProjectActions = new List<NuGetProjectAction>();
            // TODO: these sources should be ordered
            // TODO: search in only the active source but allow dependencies to come from other sources?

            var effectiveSources = GetEffectiveSources(primarySources, secondarySources);

            try
            {
                // If any targets are prerelease we should gather with prerelease on and filter afterwards
                bool includePrereleaseInGather = resolutionContext.IncludePrerelease || (packageTargetsForResolver.Any(p => (p.HasVersion && p.Version.IsPrerelease)));
                ResolutionContext contextForGather = new ResolutionContext(resolutionContext.DependencyBehavior, includePrereleaseInGather, resolutionContext.IncludeUnlisted);

                // Step-1 : Get metadata resources using gatherer
                var targetFramework = nuGetProject.GetMetadata<NuGetFramework>(NuGetProjectMetadataKeys.TargetFramework);
                nuGetProjectContext.Log(MessageLevel.Info, Strings.AttemptingToGatherDependencyInfoForMultiplePackages, targetFramework);
                var availablePackageDependencyInfoWithSourceSet = await ResolverGather.GatherPackageDependencyInfo(contextForGather,
                    packagesToInstall,
                    packageTargetsForResolver,
                    targetFramework,
                    primarySources,
                    effectiveSources,
                    token);

                if (!availablePackageDependencyInfoWithSourceSet.Any())
                {
                    throw new InvalidOperationException(Strings.UnableToGatherDependencyInfoForMultiplePackages);
                }

                // Prune the results down to only what we would allow to be installed
                IEnumerable<SourceDependencyInfo> prunedAvailablePackages = availablePackageDependencyInfoWithSourceSet;

                // Keep only the target package we are trying to install for that Id
                foreach (var packageIdentity in packagesToInstall)
                {
                    prunedAvailablePackages = PrunePackageTree.RemoveAllVersionsForIdExcept(prunedAvailablePackages, packageIdentity);
                }

                if (!resolutionContext.IncludePrerelease)
                {
                    prunedAvailablePackages = PrunePackageTree.PrunePreleaseForStableTargets(prunedAvailablePackages, packageTargetsForResolver);
                }

                // TODO: prune down level packages?

                // Remove versions that do not satisfy 'allowedVersions' attribute in packages.config, if any
                prunedAvailablePackages = PrunePackageTree.PruneDisallowedVersions(prunedAvailablePackages, projectInstalledPackageReferences);

                // Step-2 : Call IPackageResolver.Resolve to get new list of installed packages                
                // TODO: Consider using IPackageResolver once it is extensible
                var packageResolver = new PackageResolver(resolutionContext.DependencyBehavior);
                nuGetProjectContext.Log(MessageLevel.Info, Strings.AttemptingToResolveDependenciesForMultiplePackages);

                IEnumerable<PackageIdentity> newListOfInstalledPackages = packageResolver.Resolve(packageTargetsForResolver,
                    prunedAvailablePackages,
                    projectInstalledPackageReferences,
                    token);
                if (newListOfInstalledPackages == null)
                {
                    throw new InvalidOperationException(Strings.UnableToResolveDependencyInfoForMultiplePackages);
                }

                var packagesInDependencyOrder = (await GetInstalledPackagesInDependencyOrder(nuGetProject,
                    nuGetProjectContext, token)).Reverse();

                foreach(var package in packagesInDependencyOrder)
                {
                    nuGetProjectActions.Add(NuGetProjectAction.CreateUninstallProjectAction(package));
                }

                var comparer = PackageIdentity.Comparer;
                foreach (PackageIdentity newPackageToInstall in newListOfInstalledPackages)
                {
                    // find the package match based on identity
                    SourceDependencyInfo sourceDepInfo = availablePackageDependencyInfoWithSourceSet.Where(p => comparer.Equals(p, newPackageToInstall)).SingleOrDefault();

                    if (sourceDepInfo == null)
                    {
                        // this really should never happen
                        throw new InvalidOperationException(String.Format(Strings.PackageNotFound, newPackageToInstall));
                    }

                    nuGetProjectActions.Add(NuGetProjectAction.CreateInstallProjectAction(newPackageToInstall, sourceDepInfo.Source));
                }
            }
            catch(InvalidOperationException)
            {
                throw;
            }
            catch (AggregateException aggregateEx)
            {
                throw new InvalidOperationException(aggregateEx.Message, aggregateEx);
            }
            catch (Exception ex)
            {
                if(String.IsNullOrEmpty(ex.Message))
                {
                    throw new InvalidOperationException(Strings.PackagesCouldNotBeInstalled, ex);
                }
                else
                {
                    throw new InvalidOperationException(ex.Message, ex);
                }                
            }
            return nuGetProjectActions;
        }
        public async Task<IEnumerable<PackageIdentity>> GetInstalledPackagesInDependencyOrder(NuGetProject nuGetProject,
            INuGetProjectContext nuGetProjectContext,
            CancellationToken token)
        {
            var targetFramework = nuGetProject.GetMetadata<NuGetFramework>(NuGetProjectMetadataKeys.TargetFramework);
            var installedPackages = await nuGetProject.GetInstalledPackagesAsync(token);
            var installedPackageIdentities = installedPackages.Select(pr => pr.PackageIdentity);
            var dependencyInfoFromPackagesFolder = await GetDependencyInfoFromPackagesFolder(installedPackageIdentities,
                targetFramework, includePrerelease: true);

            var packageResolver = new PackageResolver(DependencyBehavior.Lowest);
            return packageResolver.Resolve(installedPackageIdentities, dependencyInfoFromPackagesFolder, installedPackages, token);
        }
Example #17
0
 public async Task <IEnumerable <PackageReference> > GetMissingPackages(NuGetProject nuGetProject, CancellationToken token)
 {
     return(GetMissingPackages(await nuGetProject.GetInstalledPackagesAsync(token)));
 }
        /// <summary>
        /// Gives the preview as a list of NuGetProjectActions that will be performed to uninstall <param name="packageId"></param> into <param name="nuGetProject"></param>
        /// <param name="uninstallationContext"></param> and <param name="nuGetProjectContext"></param> are used in the process
        /// </summary>
        public async Task<IEnumerable<NuGetProjectAction>> PreviewUninstallPackageAsync(NuGetProject nuGetProject, PackageIdentity packageIdentity,
            UninstallationContext uninstallationContext, INuGetProjectContext nuGetProjectContext, CancellationToken token)
        {
            if (nuGetProject == null)
            {
                throw new ArgumentNullException("nuGetProject");
            }

            if (packageIdentity == null)
            {
                throw new ArgumentNullException("packageIdentity");
            }

            if (uninstallationContext == null)
            {
                throw new ArgumentNullException("uninstallationContext");
            }

            if (nuGetProjectContext == null)
            {
                throw new ArgumentNullException("nuGetProjectContext");
            }

            // Step-1: Get the packageIdentity corresponding to packageId and check if it exists to be uninstalled
            var installedPackages = await nuGetProject.GetInstalledPackagesAsync(token);
            PackageReference packageReference = installedPackages
                .Where(pr => pr.PackageIdentity.Equals(packageIdentity)).FirstOrDefault();
            if (packageReference == null || packageReference.PackageIdentity == null)
            {
                throw new ArgumentException(String.Format(Strings.PackageToBeUninstalledCouldNotBeFound,
                    packageIdentity.Id, nuGetProject.GetMetadata<string>(NuGetProjectMetadataKeys.Name)));
            }

            return await PreviewUninstallPackageAsyncPrivate(nuGetProject, packageReference, uninstallationContext, nuGetProjectContext, token);
        }
 public async Task<IEnumerable<PackageReference>> GetMissingPackages(NuGetProject nuGetProject, CancellationToken token)
 {
     return GetMissingPackages(await nuGetProject.GetInstalledPackagesAsync(token));
 }
 protected virtual Task GetPackagesInstalledInProject()
 {
     return(nugetProject
            .GetInstalledPackagesAsync(CancellationToken.None)
            .ContinueWith(task => OnReadInstalledPackages(task), TaskScheduler.FromCurrentSynchronizationContext()));
 }
 /// <summary>
 /// Restore missing packages for a project in the solution
 /// </summary>
 /// <param name="nuGetProject"></param>
 /// <returns></returns>
 public async virtual Task<bool> RestoreMissingPackagesAsync(NuGetProject nuGetProject, CancellationToken token)
 {
     if(nuGetProject == null)
     {
         throw new ArgumentNullException("nuGetProject");
     }
     return await RestoreMissingPackagesAsync(await nuGetProject.GetInstalledPackagesAsync(token), token);
 }
        public static async Task <ProjectTelemetryEvent> GetProjectTelemetryEventAsync(NuGetProject nuGetProject)
        {
            // Get the project details.
            var projectUniqueName = nuGetProject.GetMetadata <string>(NuGetProjectMetadataKeys.UniqueName);

            // Emit the project information.
            try
            {
                var projectId = nuGetProject.GetMetadata <string>(NuGetProjectMetadataKeys.ProjectId);

                // Get project type.
                var projectType = NuGetProjectType.Unknown;
                if (nuGetProject is MSBuildNuGetProject)
                {
                    projectType = NuGetProjectType.PackagesConfig;
                }
#if VS15
                else if (nuGetProject is NetCorePackageReferenceProject)
                {
                    projectType = NuGetProjectType.CPSBasedPackageRefs;
                }
                else if (nuGetProject is LegacyPackageReferenceProject)
                {
                    projectType = NuGetProjectType.LegacyProjectSystemWithPackageRefs;
                }
#endif
                else if (nuGetProject is ProjectJsonNuGetProject)
                {
                    projectType = NuGetProjectType.UwpProjectJson;
                }
                else if (nuGetProject is ProjectKNuGetProjectBase)
                {
                    projectType = NuGetProjectType.XProjProjectJson;
                }

                // Get package count - don't attempt to get the project.json package count, because it fails on PCL project creation due to concurrency issue
                var installedPackagesCount =
                    projectType == NuGetProjectType.UwpProjectJson ?
                    0 :
                    (await nuGetProject.GetInstalledPackagesAsync(CancellationToken.None)).Count();

                var isUpgradable = await NuGetProjectUpgradeUtility.IsNuGetProjectUpgradeableAsync(nuGetProject);

                return(new ProjectTelemetryEvent(
                           NuGetVersion.Value,
                           projectId,
                           projectType,
                           installedPackagesCount,
                           isUpgradable));
            }
            catch (Exception ex)
            {
                var message =
                    $"Failed to emit project information for project '{projectUniqueName}'. Exception:" +
                    Environment.NewLine +
                    ex.ToString();

                ActivityLog.LogWarning(ExceptionHelper.LogEntrySource, message);
                Debug.Fail(message);
                return(null);
            }
        }
 private bool IsInstalled(NuGetProject project, string id)
 {
     var installedPackagesTask = project.GetInstalledPackagesAsync(CancellationToken.None);
     installedPackagesTask.Wait();
     var installed = installedPackagesTask.Result
         .Where(p => StringComparer.OrdinalIgnoreCase.Equals(p.PackageIdentity.Id, id));
     return installed.Any();
 }