예제 #1
0
        public void ExecuteActions(
            IEnumerable<NewPackageAction> actions,
            IExecutionContext context,
            UserAction userAction = null)
        {
            // Capture actions we've already done so we can roll them back in case of an error
            var executedActions = new List<NewPackageAction>();

            _userAction = userAction;
            ExceptionDispatchInfo capturedException = null;
            try
            {
                _readmeFilePath = null;

                foreach (var action in actions)
                {
                    IActionHandler handler;
                    if (!_actionHandlers.TryGetValue(action.ActionType, out handler))
                    {
                        NuGetTraceSources.ActionExecutor.Error(
                            "execute/unhandledaction",
                            "[{0}] Skipping unknown action: {1}",
                            action.PackageIdentity,
                            action.ToString());
                    }
                    else
                    {
                        NuGetTraceSources.ActionExecutor.Info(
                            "execute/executing",
                            "[{0}] Executing action: {1}",
                            action.PackageIdentity,
                            action.ToString());
                        handler.Execute(action, context, CancellationToken.None);
                        executedActions.Add(action);
                    }

                    // Add binding redirects when neccessary.
                    // Note that the current implementation is kind of inefficient.
                    // AddBindingRedirects is run every time after an install or uninstall, 
                    // so it's called multiple times if multiple packages are installed/uninstalled. 
                    // But in fact, it's only needed to be called per project 
                    // once after all packages are installed uninstalled.
                    var packageManager = action.Target.TryGetFeature<IPackageManager>();
                    var projectManager = action.Target.TryGetFeature<IProjectManager>();
                    if (packageManager != null &&
                        projectManager != null &&
                        packageManager.BindingRedirectEnabled &&
                        projectManager.Project.IsBindingRedirectSupported)
                    {
                        packageManager.AddBindingRedirects(projectManager);
                    }

                    UpdateReadmeFilePath(action);
                }

                if (_readmeFilePath != null)
                {
                    context.OpenFile(_readmeFilePath);
                }
            }
            catch (Exception ex)
            {
                capturedException = ExceptionDispatchInfo.Capture(ex);
            }

            if (capturedException != null)
            {
                // Roll back the actions and rethrow
                Rollback(executedActions, context);
                capturedException.Throw();
            }
        }
        /// <summary>
        /// Resolve and execute actions for a single package for specified package action type.
        /// </summary>
        /// <param name="identity"></param>
        /// <param name="projects"></param>
        /// <param name="actionType"></param>
        protected void ExecuteSinglePackageAction(PackageIdentity identity, IEnumerable<VsProject> projects, PackageActionType actionType)
        {
            if (identity == null)
            {
                return;
            }

            try
            {
                // Resolve Actions
                List<VsProject> targetProjects = projects.ToList();
                Task<IEnumerable<Client.Resolution.PackageAction>> resolverAction =
                    PackageActionResolver.ResolveActionsAsync(identity, actionType, targetProjects, Solution);

                IEnumerable<Client.Resolution.PackageAction> actions = resolverAction.Result;

                if (WhatIf.IsPresent)
                {
                    foreach (VsProject proj in targetProjects)
                    {
                        IEnumerable<PreviewResult> previewResults = PreviewResult.CreatePreview(actions, proj);
                        if (previewResults.Count() == 0)
                        {
                            PowerShellPreviewResult prResult = new PowerShellPreviewResult();
                            prResult.Id = identity.Id;
                            prResult.Action = Resources.Log_NoActionsWhatIf;
                            prResult.ProjectName = proj.Name;
                            WriteObject(prResult);
                        }
                        else
                        {
                            foreach (var p in previewResults)
                            {
                                LogPreviewResult(p, proj);
                            }
                        }
                    }

                    return;
                }

                // Execute Actions
                if (actions.Count() == 0 && actionType == PackageActionType.Install)
                {
                    Log(MessageLevel.Info, NuGetResources.Log_PackageAlreadyInstalled, identity.Id);
                }
                else
                {
                    var userAction = new UserAction(_actionType, identity);
                    ActionExecutor executor = new ActionExecutor();
                    executor.ExecuteActions(actions, this, userAction);
                }
            }
            // TODO: Consider adding the rollback behavior if exception is thrown.
            catch (Exception ex)
            {
                if (ex.InnerException != null && !string.IsNullOrEmpty(ex.InnerException.Message))
                {
                    WriteError(ex.InnerException.Message);
                }
                else
                {
                    WriteError(ex.Message);
                }
            }
        }