Exemplo n.º 1
0
        private static string GetProjectSettingsKey(NuGetProject nuGetProject)
        {
            string projectName;

            if (!nuGetProject.TryGetMetadata(NuGetProjectMetadataKeys.Name, out projectName))
            {
                projectName = "unknown";
            }
            return("project:" + projectName);
        }
Exemplo n.º 2
0
        public static ValueTask <IProjectContextInfo> CreateAsync(NuGetProject nugetProject, CancellationToken cancellationToken)
        {
            Assumes.NotNull(nugetProject);

            if (!nugetProject.TryGetMetadata(NuGetProjectMetadataKeys.ProjectId, out string projectId))
            {
                throw new InvalidOperationException();
            }

            NuGetProjectKind projectKind  = GetProjectKind(nugetProject);
            ProjectStyle     projectStyle = nugetProject.ProjectStyle;

            return(new ValueTask <IProjectContextInfo>(new ProjectContextInfo(projectId, projectStyle, projectKind)));
        }
        public PreviewResult(
            NuGetProject target,
            IEnumerable<PackageIdentity> added,
            IEnumerable<PackageIdentity> deleted,
            IEnumerable<UpdatePreviewResult> updated)
        {
            string s = null;
            if (target.TryGetMetadata<string>(NuGetProjectMetadataKeys.Name, out s))
            {
                Name = s;
            }
            else
            {
                Name = "Unknown Project";
            }

            Added = added;
            Deleted = deleted;
            Updated = updated;
        }
Exemplo n.º 4
0
        public PreviewResult(
            NuGetProject target,
            IEnumerable <PackageIdentity> added,
            IEnumerable <PackageIdentity> deleted,
            IEnumerable <UpdatePreviewResult> updated)
        {
            string s = null;

            if (target.TryGetMetadata <string>(NuGetProjectMetadataKeys.Name, out s))
            {
                Name = s;
            }
            else
            {
                Name = "Unknown Project";
            }

            Added   = added;
            Deleted = deleted;
            Updated = updated;
        }
Exemplo n.º 5
0
        public PreviewResult(
            NuGetProject target,
            IEnumerable <AccessiblePackageIdentity> added,
            IEnumerable <AccessiblePackageIdentity> deleted,
            IEnumerable <UpdatePreviewResult> updated)
        {
            string s = null;

            if (target.TryGetMetadata(NuGetProjectMetadataKeys.UniqueName, out s))
            {
                Name = s;
            }
            else
            {
                Name = Resources.Preview_UnknownProject;
            }

            Target  = target;
            Added   = added;
            Deleted = deleted;
            Updated = updated;
        }
        async Task <Tuple <NuGetFramework, IEnumerable <PackageIdentity> > > CollectPackagesForPackagesConfigAsync(
            NuGetProject project,
            CancellationToken token)
        {
            token.ThrowIfCancellationRequested();

            // Read packages.config
            var installedRefs = await project.GetInstalledPackagesAsync(token);

            if (installedRefs?.Any() == true)
            {
                // Index packages.config references by target framework since this affects dependencies
                NuGetFramework targetFramework;
                if (!project.TryGetMetadata(NuGetProjectMetadataKeys.TargetFramework, out targetFramework))
                {
                    targetFramework = NuGetFramework.AnyFramework;
                }

                return(Tuple.Create(targetFramework, installedRefs.Select(reference => reference.PackageIdentity)));
            }

            return(Tuple.Create(NuGetFramework.AnyFramework, Enumerable.Empty <PackageIdentity> ()));
        }
        private async Task <bool> ExecuteCoreAsync(
            PackageIdentity packageIdentity,
            string fullScriptPath,
            string packageInstallPath,
            EnvDTEProject envDTEProject,
            NuGetProject nuGetProject,
            INuGetProjectContext nuGetProjectContext,
            bool throwOnFailure)
        {
            if (File.Exists(fullScriptPath))
            {
                if (fullScriptPath.EndsWith(PowerShellScripts.Init, StringComparison.OrdinalIgnoreCase) &&
                    !TryMarkVisited(packageIdentity, PackageInitPS1State.FoundAndExecuted))
                {
                    return(true);
                }

                ScriptPackage package = null;
                if (envDTEProject != null)
                {
                    NuGetFramework targetFramework;
                    nuGetProject.TryGetMetadata(NuGetProjectMetadataKeys.TargetFramework, out targetFramework);

                    // targetFramework can be null for unknown project types
                    string shortFramework = targetFramework?.GetShortFolderName() ?? string.Empty;

                    nuGetProjectContext.Log(MessageLevel.Debug, Strings.Debug_TargetFrameworkInfoPrefix, packageIdentity,
                                            envDTEProject.Name, shortFramework);
                }

                if (packageIdentity != null)
                {
                    package = new ScriptPackage(packageIdentity.Id, packageIdentity.Version.ToString(), packageInstallPath);
                }

                string toolsPath = Path.GetDirectoryName(fullScriptPath);
                IPSNuGetProjectContext psNuGetProjectContext = nuGetProjectContext as IPSNuGetProjectContext;
                if (psNuGetProjectContext != null &&
                    psNuGetProjectContext.IsExecuting &&
                    psNuGetProjectContext.CurrentPSCmdlet != null)
                {
                    var psVariable = psNuGetProjectContext.CurrentPSCmdlet.SessionState.PSVariable;

                    // set temp variables to pass to the script
                    psVariable.Set("__rootPath", packageInstallPath);
                    psVariable.Set("__toolsPath", toolsPath);
                    psVariable.Set("__package", package);
                    psVariable.Set("__project", envDTEProject);

                    psNuGetProjectContext.ExecutePSScript(fullScriptPath, throwOnFailure);
                }
                else
                {
                    string logMessage = String.Format(CultureInfo.CurrentCulture, Resources.ExecutingScript, fullScriptPath);
                    // logging to both the Output window and progress window.
                    nuGetProjectContext.Log(MessageLevel.Info, logMessage);
                    try
                    {
                        await ExecuteScriptCoreAsync(
                            package,
                            packageInstallPath,
                            fullScriptPath,
                            toolsPath,
                            envDTEProject);
                    }
                    catch (Exception ex)
                    {
                        // throwFailure is set by Package Manager.
                        if (throwOnFailure)
                        {
                            throw;
                        }
                        nuGetProjectContext.Log(MessageLevel.Warning, ex.Message);
                    }
                }

                return(true);
            }
            else
            {
                if (fullScriptPath.EndsWith(PowerShellScripts.Init, StringComparison.OrdinalIgnoreCase))
                {
                    TryMarkVisited(packageIdentity, PackageInitPS1State.NotFound);
                }
            }
            return(false);
        }
Exemplo n.º 8
0
        private async Task <bool> ExecuteCoreAsync(
            string fullScriptPath,
            string packageInstallPath,
            ZipArchive packageZipArchive,
            EnvDTEProject envDTEProject,
            NuGetProject nuGetProject,
            INuGetProjectContext nuGetProjectContext)
        {
            if (File.Exists(fullScriptPath))
            {
                PackageIdentity packageIdentity = null;
                if (envDTEProject != null)
                {
                    NuGetFramework targetFramework;
                    nuGetProject.TryGetMetadata <NuGetFramework>(NuGetProjectMetadataKeys.TargetFramework, out targetFramework);

                    // targetFramework can be null for unknown project types
                    string shortFramework = targetFramework == null ? string.Empty : targetFramework.GetShortFolderName();
                    var    packageReader  = new PackageReader(packageZipArchive);
                    packageIdentity = packageReader.GetIdentity();

                    nuGetProjectContext.Log(MessageLevel.Debug, NuGet.ProjectManagement.Strings.Debug_TargetFrameworkInfoPrefix, packageIdentity,
                                            envDTEProject.Name, shortFramework);

                    //logger.Log(MessageLevel.Debug, NuGetResources.Debug_TargetFrameworkInfo_PowershellScripts,
                    //    Path.GetDirectoryName(scriptFile.Path), VersionUtility.GetTargetFrameworkLogString(scriptFile.TargetFramework));
                }

                if (fullScriptPath.EndsWith(PowerShellScripts.Init, StringComparison.OrdinalIgnoreCase))
                {
                    _skipPSScriptExecution = await NuGetPackageManager.PackageExistsInAnotherNuGetProject(nuGetProject, packageIdentity,
                                                                                                          _solutionManager, CancellationToken.None);
                }
                else
                {
                    _skipPSScriptExecution = false;
                }

                if (!_skipPSScriptExecution)
                {
                    string toolsPath = Path.GetDirectoryName(fullScriptPath);
                    IPSNuGetProjectContext psNuGetProjectContext = nuGetProjectContext as IPSNuGetProjectContext;
                    if (psNuGetProjectContext != null && psNuGetProjectContext.IsExecuting && psNuGetProjectContext.CurrentPSCmdlet != null)
                    {
                        var psVariable = psNuGetProjectContext.CurrentPSCmdlet.SessionState.PSVariable;

                        // set temp variables to pass to the script
                        psVariable.Set("__rootPath", packageInstallPath);
                        psVariable.Set("__toolsPath", toolsPath);
                        psVariable.Set("__package", packageZipArchive);
                        psVariable.Set("__project", envDTEProject);

                        psNuGetProjectContext.ExecutePSScript(fullScriptPath);
                    }
                    else
                    {
                        string command = "$__pc_args=@(); $input|%{$__pc_args+=$_}; & "
                                         + PathUtility.EscapePSPath(fullScriptPath)
                                         + " $__pc_args[0] $__pc_args[1] $__pc_args[2] $__pc_args[3]; Remove-Variable __pc_args -Scope 0";

                        object[] inputs     = new object[] { packageInstallPath, toolsPath, packageZipArchive, envDTEProject };
                        string   logMessage = String.Format(CultureInfo.CurrentCulture, Resources.ExecutingScript, fullScriptPath);

                        // logging to both the Output window and progress window.
                        nuGetProjectContext.Log(MessageLevel.Info, logMessage);
                        IConsole console = OutputConsoleProvider.CreateOutputConsole(requirePowerShellHost: true);
                        Host.Execute(console, command, inputs);
                    }

                    return(true);
                }
            }
            return(false);
        }
        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;
        }