示例#1
0
        public void ShowError_WhenArgumentIsSignatureExceptionWithNullResults_DoesNotThrow()
        {
            var exception = new SignatureException(message: "a");

            Assert.Null(exception.Results);

            using (NuGetUI ui = CreateNuGetUI())
            {
                ui.ShowError(exception);
            }
        }
示例#2
0
        private void ProcessSignatureIssues(SignatureException ex)
        {
            if (!string.IsNullOrEmpty(ex.Message))
            {
                UILogger.ReportError(ex.AsLogMessage().FormatWithCode());
                ProjectContext.Log(MessageLevel.Error, ex.AsLogMessage().FormatWithCode());
            }

            foreach (var result in ex.Results)
            {
                var errorList   = result.GetErrorIssues().ToList();
                var warningList = result.GetWarningIssues().ToList();

                errorList.ForEach(p => UILogger.ReportError(p.FormatWithCode()));

                errorList.ForEach(p => ProjectContext.Log(MessageLevel.Error, p.FormatWithCode()));
                warningList.ForEach(p => ProjectContext.Log(MessageLevel.Warning, p.FormatWithCode()));
            }
        }
示例#3
0
        public async Task ExecuteActionsAsync(IEnumerable <ResolvedAction> actions, PackageDownloadContext downloadContext, CancellationToken token)
        {
            var packageWithDirectoriesToBeDeleted = new HashSet <PackageIdentity>(PackageIdentity.Comparer);

            Dictionary <PackageIdentity, PackagePreFetcherResult> downloadTasks = null;
            var executedActions = new Stack <ResolvedAction>();
            ExceptionDispatchInfo   exceptionInfo       = null;
            CancellationTokenSource downloadTokenSource = null;

            try
            {
                var actionsList = actions.ToList();
                var hasInstalls = actionsList.Any(action => action.Action == ResolvedActionType.Install);

                if (hasInstalls)
                {
                    // Make this independently cancelable.
                    downloadTokenSource = CancellationTokenSource.CreateLinkedTokenSource(token);

                    // Download all packages up front in parallel
                    downloadTasks = await PackageLoader.GetPackagesAsync(actionsList, _project.ModulesDirectory,
                                                                         downloadContext, new NullLogger(), downloadTokenSource.Token);
                }

                foreach (var action in actionsList)
                {
                    if (action.Action == ResolvedActionType.Uninstall)
                    {
                        executedActions.Push(action);
                        await ExecuteUninstallAsync(action.PackageIdentity, packageWithDirectoriesToBeDeleted, token);
                    }
                }

                foreach (var action in actionsList)
                {
                    if (action.Action == ResolvedActionType.Install)
                    {
                        executedActions.Push(action);

                        // Retrieve the downloaded package
                        // This will wait on the package if it is still downloading
                        var preFetchResult = downloadTasks[action.PackageIdentity];
                        using (var downloadPackageResult = await preFetchResult.GetResultAsync())
                        {
                            // use the version exactly as specified in the nuspec file
                            var packageIdentity = await downloadPackageResult.PackageReader.GetIdentityAsync(token);

                            var packageExtractionContext = new PackageExtractionContext(
                                PackageSaveMode.Defaultv3,
                                PackageExtractionBehavior.XmlDocFileSaveMode,
                                ClientPolicyContext.GetClientPolicy(new NullSettings(), new NullLogger()),
                                new NullLogger());

                            downloadPackageResult.PackageStream.Position = 0;

                            await PackageExtractor.InstallFromSourceAsync(action.SourceRepository.PackageSource.Source, packageIdentity,
                                                                          stream => downloadPackageResult.PackageStream.CopyToAsync(stream),
                                                                          _project.ModulesDirectory.VersionFolderPathResolver, packageExtractionContext, token);

                            await ExecuteInstallAsync(packageIdentity, downloadPackageResult,
                                                      packageWithDirectoriesToBeDeleted, token);
                        }
                    }
                }
            }
            catch (SignatureException ex)
            {
                var errors = ex.Results.SelectMany(r => r.GetErrorIssues()).ToList();
                //var warnings = ex.Results.SelectMany(r => r.GetWarningIssues());
                SignatureException unwrappedException;

                if (errors.Count == 1)
                {
                    // In case of one error, throw it as the exception
                    var error = errors.First();
                    unwrappedException = new SignatureException(error.Code, error.Message, ex.PackageIdentity);
                }
                else
                {
                    // In case of multiple errors, wrap them in a general NU3000 error
                    var errorMessage = string.Format(CultureInfo.CurrentCulture,
                                                     "Signed package validation failed with multiple errors:{0}",
                                                     $"{Environment.NewLine}{string.Join(Environment.NewLine, errors.Select(e => e.FormatWithCode()))}");

                    unwrappedException = new SignatureException(NuGetLogCode.NU3000, errorMessage, ex.PackageIdentity);
                }

                exceptionInfo = ExceptionDispatchInfo.Capture(unwrappedException);
            }
            catch (Exception ex)
            {
                exceptionInfo = ExceptionDispatchInfo.Capture(ex);
            }
            finally
            {
                if (downloadTasks != null)
                {
                    // Wait for all downloads to cancel and dispose
                    downloadTokenSource.Cancel();

                    foreach (var result in downloadTasks.Values)
                    {
                        await result.EnsureResultAsync();

                        result.Dispose();
                    }

                    downloadTokenSource.Dispose();
                }
            }

            if (exceptionInfo != null)
            {
                await Rollback(executedActions, packageWithDirectoriesToBeDeleted, token);
            }

            // Delete the package directories as the last step, so that, if an uninstall had to be rolled back, we can just use the package file on the directory
            // Also, always perform deletion of package directories, even in a rollback, so that there are no stale package directories
            foreach (var packageWithDirectoryToBeDeleted in packageWithDirectoriesToBeDeleted)
            {
                try
                {
                    await _project.ModulesDirectory.DeleteModule(packageWithDirectoryToBeDeleted);
                }
                finally
                {
                    //if (DeleteOnRestartManager != null)
                    //{
                    //    if (Directory.Exists(packageFolderPath))
                    //    {
                    //        DeleteOnRestartManager.MarkPackageDirectoryForDeletion(
                    //            packageWithDirectoryToBeDeleted,
                    //            packageFolderPath,
                    //            nuGetProjectContext);

                    //        // Raise the event to notify listners to update the UI etc.
                    //        DeleteOnRestartManager.CheckAndRaisePackageDirectoriesMarkedForDeletion();
                    //    }
                    //}
                }
            }
        }