Esempio n. 1
0
        private static bool CheckIfTemplateHasScriptRunningPostActions(ITemplate template, IEngineEnvironmentSettings environmentSettings, INewCommandInput commandInput, TemplateCreator templateCreator)
        {
            // use a throwaway set of params for getting the creation effects - it makes changes to them.
            string        targetDir = commandInput.OutputPath ?? environmentSettings.Host.FileSystem.GetCurrentDirectory();
            IParameterSet paramsForCreationEffects = templateCreator.SetupDefaultParamValuesFromTemplateAndHost(template, template.DefaultName ?? "testName", out IReadOnlyList <string> throwaway);

            templateCreator.ResolveUserParameters(template, paramsForCreationEffects, commandInput.InputTemplateParams, out IReadOnlyList <string> userParamsWithInvalidValues);
            ICreationEffects creationEffects = template.Generator.GetCreationEffects(environmentSettings, template, paramsForCreationEffects, environmentSettings.SettingsLoader.Components, targetDir);

            return(creationEffects.CreationResult.PostActions.Any(x => x.ActionId == ProcessStartPostActionProcessor.ActionProcessorId));
        }
 public bool Process(
     IEngineEnvironmentSettings environment,
     IPostAction action,
     ICreationEffects creationEffects,
     ICreationResult templateCreationResult,
     string outputBasePath)
 {
     if (string.IsNullOrWhiteSpace(outputBasePath))
     {
         throw new ArgumentException($"'{nameof(outputBasePath)}' cannot be null or whitespace.", nameof(outputBasePath));
     }
     outputBasePath = Path.GetFullPath(outputBasePath);
     return(ProcessInternal(environment, action, creationEffects, templateCreationResult, outputBasePath));
 }
Esempio n. 3
0
        public void TestLocalizedPostActionFields(
            int postActionIndex,
            string locale,
            string expectedDescription,
            string expectedManualInstructions)
        {
            _ = LoadHostWithLocalizationTemplates(out SettingsLoader settingsLoader);

            IReadOnlyList <TemplateInfo> localizedTemplates = settingsLoader.UserTemplateCache.GetTemplatesForLocale(locale,
                                                                                                                     SettingsStore.CurrentVersion);

            Assert.True(localizedTemplates.Count != 0, "Test template couldn't be loaded.");
            TemplateInfo localizationTemplate = localizedTemplates.FirstOrDefault(t => t.Identity == "TestAssets.TemplateWithLocalization");

            Assert.NotNull(localizationTemplate);

            ITemplate template = settingsLoader.LoadTemplate(localizationTemplate, null);

            Assert.NotNull(template);
            Assert.NotNull(template.Generator);

            ICreationEffects effects = template.Generator.GetCreationEffects(
                settingsLoader.EnvironmentSettings,
                template,
                new MockParameterSet(),
                settingsLoader.Components,
                Path.Combine(Path.GetTempPath(), Path.GetRandomFileName())
                );

            Assert.NotNull(effects);
            Assert.NotNull(effects.CreationResult);
            Assert.NotNull(effects.CreationResult.PostActions);
            Assert.True(effects.CreationResult.PostActions.Count > postActionIndex, "Template does not contain enough post actions");
            Assert.Equal(expectedDescription, effects.CreationResult.PostActions[postActionIndex].Description);
            Assert.Equal(expectedManualInstructions, effects.CreationResult.PostActions[postActionIndex].ManualInstructions);
        }
 public TemplateCreationResult(string message, CreationResultStatus status, string templateFullName, ICreationResult creationOutputs, string outputBaseDir, ICreationEffects creationEffects)
 {
     Message             = message;
     Status              = status;
     TemplateFullName    = templateFullName;
     ResultInfo          = creationOutputs;
     OutputBaseDirectory = outputBaseDir;
     CreationEffects     = creationEffects;
 }
 protected abstract bool ProcessInternal(
     IEngineEnvironmentSettings environment,
     IPostAction action,
     ICreationEffects creationEffects,
     ICreationResult templateCreationResult,
     string outputBasePath);
Esempio n. 6
0
        public async Task <TemplateCreationResult> InstantiateAsync(ITemplateInfo templateInfo, string name, string fallbackName, string outputPath, IReadOnlyDictionary <string, string> inputParameters, bool skipUpdateCheck, bool forceCreation, string baselineName, bool dryRun)
        {
            // SettingsLoader.LoadTemplate is where the loc info should be read!!!
            // templateInfo knows enough to get at the loc, if any
            ITemplate template = _environmentSettings.SettingsLoader.LoadTemplate(templateInfo, baselineName);

            try
            {
                if (template == null)
                {
                    return(new TemplateCreationResult("Could not load template", CreationResultStatus.NotFound, templateInfo.Name));
                }

                string realName = name ?? fallbackName ?? template.DefaultName;

                if (string.IsNullOrEmpty(realName))
                {
                    return(new TemplateCreationResult("--name", CreationResultStatus.MissingMandatoryParam, template.Name));
                }

                if (template.IsNameAgreementWithFolderPreferred && string.IsNullOrEmpty(outputPath))
                {
                    outputPath = name;
                }

                ICreationResult creationResult = null;
                string          targetDir      = outputPath ?? _environmentSettings.Host.FileSystem.GetCurrentDirectory();

                try
                {
                    if (!dryRun)
                    {
                        _environmentSettings.Host.FileSystem.CreateDirectory(targetDir);
                    }

                    Stopwatch         sw = Stopwatch.StartNew();
                    IComponentManager componentManager = _environmentSettings.SettingsLoader.Components;

                    // setup separate sets of parameters to be used for GetCreationEffects() and by CreateAsync().
                    if (!TryCreateParameterSet(template, realName, inputParameters, out IParameterSet effectParams, out TemplateCreationResult resultIfParameterCreationFailed))
                    {
                        return(resultIfParameterCreationFailed);
                    }

                    ICreationEffects            creationEffects    = template.Generator.GetCreationEffects(_environmentSettings, template, effectParams, componentManager, targetDir);
                    IReadOnlyList <IFileChange> changes            = creationEffects.FileChanges;
                    IReadOnlyList <IFileChange> destructiveChanges = changes.Where(x => x.ChangeKind != ChangeKind.Create).ToList();

                    if (!forceCreation && destructiveChanges.Count > 0)
                    {
                        if (!_environmentSettings.Host.OnPotentiallyDestructiveChangesDetected(changes, destructiveChanges))
                        {
                            return(new TemplateCreationResult("Cancelled", CreationResultStatus.Cancelled, template.Name));
                        }
                    }

                    if (!TryCreateParameterSet(template, realName, inputParameters, out IParameterSet creationParams, out resultIfParameterCreationFailed))
                    {
                        return(resultIfParameterCreationFailed);
                    }

                    if (!dryRun)
                    {
                        creationResult = await template.Generator.CreateAsync(_environmentSettings, template, creationParams, componentManager, targetDir).ConfigureAwait(false);
                    }

                    sw.Stop();
                    _environmentSettings.Host.LogTiming("Content generation time", sw.Elapsed, 0);
                    return(new TemplateCreationResult(string.Empty, CreationResultStatus.Success, template.Name, creationResult, targetDir, creationEffects));
                }
                catch (ContentGenerationException cx)
                {
                    string message = cx.Message;
                    if (cx.InnerException != null)
                    {
                        message += Environment.NewLine + cx.InnerException;
                    }

                    return(new TemplateCreationResult(message, CreationResultStatus.CreateFailed, template.Name));
                }
                catch (Exception ex)
                {
                    return(new TemplateCreationResult(ex.Message, CreationResultStatus.CreateFailed, template.Name));
                }
            }
            finally
            {
                ReleaseMountPoints(template);
            }
        }
Esempio n. 7
0
        public async Task <ITemplateCreationResult> InstantiateAsync(
            ITemplateInfo templateInfo,
            string?name,
            string?fallbackName,
            string?outputPath,
            IReadOnlyDictionary <string, string?> inputParameters,
            bool forceCreation  = false,
            string?baselineName = null,
            bool dryRun         = false,
            CancellationToken cancellationToken = default)
        {
            _ = templateInfo ?? throw new ArgumentNullException(nameof(templateInfo));
            inputParameters = inputParameters ?? new Dictionary <string, string?>();
            cancellationToken.ThrowIfCancellationRequested();

            ITemplate?template = LoadTemplate(templateInfo, baselineName);

            if (template == null)
            {
                return(new TemplateCreationResult(CreationResultStatus.NotFound, templateInfo.Name, LocalizableStrings.TemplateCreator_TemplateCreationResult_Error_CouldNotLoadTemplate));
            }

            string?realName = name ?? fallbackName ?? template.DefaultName;

            if (string.IsNullOrWhiteSpace(realName))
            {
                return(new TemplateCreationResult(CreationResultStatus.MissingMandatoryParam, template.Name, "--name"));
            }
            if (template.IsNameAgreementWithFolderPreferred && string.IsNullOrEmpty(outputPath))
            {
                outputPath = name;
            }
            string targetDir             = !string.IsNullOrWhiteSpace(outputPath) ? outputPath ! : _environmentSettings.Host.FileSystem.GetCurrentDirectory();
            Timing contentGeneratorBlock = Timing.Over(_logger, "Template content generation");

            try
            {
                ICreationResult?creationResult = null;
                if (!dryRun)
                {
                    _environmentSettings.Host.FileSystem.CreateDirectory(targetDir);
                }
                IComponentManager componentManager = _environmentSettings.Components;

                // setup separate sets of parameters to be used for GetCreationEffects() and by CreateAsync().
                if (!TryCreateParameterSet(template, realName !, inputParameters, out IParameterSet? effectParams, out TemplateCreationResult? resultIfParameterCreationFailed))
                {
                    //resultIfParameterCreationFailed is not null when TryCreateParameterSet is false
                    return(resultIfParameterCreationFailed !);
                }
                if (effectParams is null)
                {
                    throw new InvalidOperationException($"{nameof(effectParams)} cannot be null when {nameof(TryCreateParameterSet)} returns 'true'");
                }

                ICreationEffects creationEffects = await template.Generator.GetCreationEffectsAsync(
                    _environmentSettings,
                    template,
                    effectParams,
                    targetDir,
                    cancellationToken).ConfigureAwait(false);

                IReadOnlyList <IFileChange> changes            = creationEffects.FileChanges;
                IReadOnlyList <IFileChange> destructiveChanges = changes.Where(x => x.ChangeKind != ChangeKind.Create).ToList();

                if (!forceCreation && destructiveChanges.Count > 0)
                {
#pragma warning disable CS0618 // Type or member is obsolete
                    if (!_environmentSettings.Host.OnPotentiallyDestructiveChangesDetected(changes, destructiveChanges))
#pragma warning restore CS0618 // Type or member is obsolete
                    {
                        return(new TemplateCreationResult(
                                   CreationResultStatus.DestructiveChangesDetected,
                                   template.Name,
                                   LocalizableStrings.TemplateCreator_TemplateCreationResult_Error_DestructiveChanges,
                                   null,
                                   null,
                                   creationEffects));
                    }
                }

                if (!TryCreateParameterSet(template, realName !, inputParameters, out IParameterSet? creationParams, out resultIfParameterCreationFailed))
                {
                    return(resultIfParameterCreationFailed !);
                }

                if (creationParams is null)
                {
                    throw new InvalidOperationException($"{nameof(creationParams)} cannot be null when {nameof(TryCreateParameterSet)} returns 'true'");
                }

                if (!dryRun)
                {
                    creationResult = await template.Generator.CreateAsync(
                        _environmentSettings,
                        template,
                        creationParams,
                        targetDir,
                        cancellationToken).ConfigureAwait(false);
                }
                return(new TemplateCreationResult(
                           status: CreationResultStatus.Success,
                           templateName: template.Name,
                           creationOutputs: creationResult,
                           outputBaseDir: targetDir,
                           creationEffects: creationEffects));
            }
            catch (Exception cx)
            {
                string message = string.Join(Environment.NewLine, ExceptionMessages(cx));
                return(new TemplateCreationResult(
                           status: cx is TemplateAuthoringException ? CreationResultStatus.TemplateIssueDetected : CreationResultStatus.CreateFailed,
                           templateName: template.Name,
                           localizedErrorMessage: string.Format(LocalizableStrings.TemplateCreator_TemplateCreationResult_Error_CreationFailed, message),
                           outputBaseDir: targetDir));
            }
            finally
            {
#pragma warning disable CS0618 // Type or member is obsolete - temporary until the method becomes internal.
                ReleaseMountPoints(template);
#pragma warning restore CS0618 // Type or member is obsolete
                contentGeneratorBlock.Dispose();
            }
        }
        protected override bool ProcessInternal(IEngineEnvironmentSettings environment, IPostAction action, ICreationEffects creationEffects, ICreationResult templateCreationResult, string outputBasePath)
        {
            IReadOnlyList <string>?projectsToProcess = GetConfiguredFiles(action.Args, creationEffects, "targetFiles", outputBasePath);

            if (projectsToProcess is null)
            {
                //If the author didn't opt in to the new behavior by specifying "targetFiles", search for project file in current output directory or above.
                HashSet <string> extensionLimiters = new HashSet <string>(StringComparer.Ordinal);
                if (action.Args.TryGetValue("projectFileExtensions", out string?projectFileExtensions))
                {
                    if (projectFileExtensions.Contains("/") || projectFileExtensions.Contains("\\") || projectFileExtensions.Contains("*"))
                    {
                        // these must be literals
                        Reporter.Error.WriteLine(LocalizableStrings.PostAction_AddReference_Error_ActionMisconfigured);
                        return(false);
                    }

                    extensionLimiters.UnionWith(projectFileExtensions.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries));
                }
                projectsToProcess = FindProjFileAtOrAbovePath(environment.Host.FileSystem, outputBasePath, extensionLimiters);
                if (projectsToProcess.Count > 1)
                {
                    // multiple projects at the same level. Error.
                    Reporter.Error.WriteLine(LocalizableStrings.PostAction_AddReference_Error_UnresolvedProjFile);
                    Reporter.Error.WriteLine(LocalizableStrings.PostAction_AddReference_Error_ProjFileListHeader);
                    foreach (string projectFile in projectsToProcess)
                    {
                        Reporter.Error.WriteLine(string.Format("\t{0}", projectFile));
                    }
                    return(false);
                }
            }
            if (projectsToProcess is null || !projectsToProcess.Any())
            {
                // no projects found. Error.
                Reporter.Error.WriteLine(LocalizableStrings.PostAction_AddReference_Error_UnresolvedProjFile);
                return(false);
            }

            bool success = true;

            foreach (string projectFile in projectsToProcess)
            {
                success &= AddReference(environment, action, projectFile, outputBasePath);

                if (!success)
                {
                    return(false);
                }
            }
            return(true);
        }
        protected override bool ProcessInternal(IEngineEnvironmentSettings environment, IPostAction actionConfig, ICreationEffects creationEffects, ICreationResult templateCreationResult, string outputBasePath)
        {
            if (!actionConfig.Args.TryGetValue("executable", out string?executable) || string.IsNullOrWhiteSpace(executable))
            {
                Reporter.Error.WriteLine(LocalizableStrings.PostAction_ProcessStartProcessor_Error_ConfigMissingExecutable);
                return(false);
            }
            actionConfig.Args.TryGetValue("args", out string?args);

            bool redirectStandardOutput = true;

            // By default, standard out is redirected.
            // Only redirect when the configuration says "redirectStandardOutput = false"
            if (actionConfig.Args.TryGetValue("redirectStandardOutput", out string?redirectStandardOutputString) &&
                string.Equals(redirectStandardOutputString, "false", StringComparison.OrdinalIgnoreCase))
            {
                redirectStandardOutput = false;
            }
            bool redirectStandardError = true;

            // By default, standard error is redirected.
            // Only redirect when the configuration says "redirectStandardError = false"
            if (actionConfig.Args.TryGetValue("redirectStandardError", out string?redirectStandardErrorString) &&
                string.Equals(redirectStandardErrorString, "false", StringComparison.OrdinalIgnoreCase))
            {
                redirectStandardError = false;
            }

            try
            {
                string command = executable;
                if (!string.IsNullOrWhiteSpace(args))
                {
                    command = command + " " + args;
                }
                Reporter.Output.WriteLine(string.Format(LocalizableStrings.RunningCommand, command));
                string resolvedExecutablePath = ResolveExecutableFilePath(environment.Host.FileSystem, executable, outputBasePath);

                Process?commandResult = System.Diagnostics.Process.Start(new ProcessStartInfo
                {
                    RedirectStandardError  = redirectStandardError,
                    RedirectStandardOutput = redirectStandardOutput,
                    UseShellExecute        = false,
                    CreateNoWindow         = false,
                    WorkingDirectory       = outputBasePath,
                    FileName  = resolvedExecutablePath,
                    Arguments = args
                });

                if (commandResult == null)
                {
                    Reporter.Error.WriteLine(LocalizableStrings.CommandFailed);
                    Reporter.Verbose.WriteLine("Unable to start sub-process.");
                    return(false);
                }

                commandResult.WaitForExit();

                if (commandResult.ExitCode != 0)
                {
                    Reporter.Error.WriteLine(LocalizableStrings.CommandFailed);
                    Reporter.Error.WriteCommandOutput(commandResult);
                    Reporter.Error.WriteLine(string.Empty);
                    return(false);
                }
                else
                {
                    Reporter.Output.WriteLine(LocalizableStrings.CommandSucceeded);
                    return(true);
                }
            }
            catch (Exception ex)
            {
                Reporter.Error.WriteLine(LocalizableStrings.CommandFailed);
                Reporter.Error.WriteLine(ex.Message);
                Reporter.Error.WriteLine(string.Empty);
                Reporter.Verbose.WriteLine(string.Format(LocalizableStrings.Generic_Details, ex.ToString()));
                return(false);
            }
        }
Esempio n. 10
0
        protected override bool ProcessInternal(IEngineEnvironmentSettings environment, IPostAction actionConfig, ICreationEffects creationEffects, ICreationResult templateCreationResult, string outputBasePath)
        {
            Reporter.Output.WriteLine(string.Format(LocalizableStrings.PostActionDescription, actionConfig.Description));
            Reporter.Output.WriteLine(string.Format(LocalizableStrings.PostActionInstructions, actionConfig.ManualInstructions));

            if (actionConfig.Args != null && actionConfig.Args.TryGetValue("executable", out string?executable))
            {
                actionConfig.Args.TryGetValue("args", out string?commandArgs);
                Reporter.Output.WriteLine(string.Format(LocalizableStrings.PostActionCommand, $"{executable} {commandArgs}").Bold().Red());
            }

            return(true);
        }
        protected override bool ProcessInternal(IEngineEnvironmentSettings environment, IPostAction actionConfig, ICreationEffects creationEffects, ICreationResult templateCreationResult, string outputBasePath)
        {
            bool allSucceeded = true;

            foreach (KeyValuePair <string, string> entry in actionConfig.Args)
            {
                string[] values;
                try
                {
                    JArray valueArray = JArray.Parse(entry.Value);
                    values = new string[valueArray.Count];

                    for (int i = 0; i < valueArray.Count; ++i)
                    {
                        values[i] = valueArray[i].ToString();
                    }
                }
                catch
                {
                    values = new[] { entry.Value };
                }

                foreach (string file in values)
                {
                    try
                    {
                        Process?commandResult = System.Diagnostics.Process.Start(new ProcessStartInfo
                        {
                            RedirectStandardError  = false,
                            RedirectStandardOutput = false,
                            UseShellExecute        = false,
                            CreateNoWindow         = false,
                            WorkingDirectory       = outputBasePath,
                            FileName  = "/bin/sh",
                            Arguments = $"-c \"chmod {entry.Key} {file}\""
                        });

                        if (commandResult == null)
                        {
                            Reporter.Error.WriteLine(string.Format(LocalizableStrings.UnableToSetPermissions, entry.Key, file));
                            Reporter.Verbose.WriteLine("Unable to start sub-process.");
                            allSucceeded = false;
                            continue;
                        }

                        commandResult.WaitForExit();

                        if (commandResult.ExitCode != 0)
                        {
                            Reporter.Error.WriteLine(string.Format(LocalizableStrings.UnableToSetPermissions, entry.Key, file));
                            allSucceeded = false;
                        }
                    }
                    catch (Exception ex)
                    {
                        Reporter.Error.WriteLine(string.Format(LocalizableStrings.UnableToSetPermissions, entry.Key, file));
                        Reporter.Verbose.WriteLine(string.Format(LocalizableStrings.Generic_Details, ex.ToString()));
                        allSucceeded = false;
                    }
                }
            }

            return(allSucceeded);
        }
Esempio n. 12
0
        protected override bool ProcessInternal(IEngineEnvironmentSettings environment, IPostAction action, ICreationEffects creationEffects, ICreationResult templateCreationResult, string outputBasePath)
        {
            IReadOnlyList <string> nearestSlnFilesFound = FindSolutionFilesAtOrAbovePath(environment.Host.FileSystem, outputBasePath);

            if (nearestSlnFilesFound.Count != 1)
            {
                Reporter.Error.WriteLine(LocalizableStrings.PostAction_AddProjToSln_Error_NoSolutionFile);
                return(false);
            }

            IReadOnlyList <string>?projectFiles = GetConfiguredFiles(action.Args, creationEffects, "projectFiles", outputBasePath, (path) => Path.GetExtension(path).EndsWith("proj", StringComparison.OrdinalIgnoreCase));

            if (projectFiles is null)
            {
                //If the author didn't opt in to the new behavior by specifying "projectFiles", use the old behavior
                if (!TryGetProjectFilesToAdd(action, templateCreationResult, outputBasePath, out projectFiles))
                {
                    Reporter.Error.WriteLine(LocalizableStrings.PostAction_AddProjToSln_Error_NoProjectsToAdd);
                    return(false);
                }
            }
            if (projectFiles.Count == 0)
            {
                Reporter.Error.WriteLine(LocalizableStrings.PostAction_AddProjToSln_Error_NoProjectsToAdd);
                return(false);
            }

            string solutionFolder = GetSolutionFolder(action);

            bool succeeded = false;

            if (Callbacks?.AddProjectsToSolution != null)
            {
                Reporter.Output.WriteLine(string.Format(LocalizableStrings.PostAction_AddProjToSln_Running, string.Join(" ", projectFiles), nearestSlnFilesFound[0], solutionFolder));
                succeeded = Callbacks.AddProjectsToSolution(nearestSlnFilesFound[0], projectFiles, solutionFolder);
            }

            if (!succeeded)
            {
                Reporter.Error.WriteLine(LocalizableStrings.PostAction_AddProjToSln_Failed);
                if (Callbacks?.AddProjectsToSolution == null)
                {
                    Reporter.Error.WriteLine(LocalizableStrings.Generic_NoCallbackError);
                }
                return(false);
            }
            else
            {
                Reporter.Output.WriteLine(LocalizableStrings.PostAction_AddProjToSln_Succeeded);
                return(true);
            }
        }
        protected override bool ProcessInternal(IEngineEnvironmentSettings environment, IPostAction actionConfig, ICreationEffects creationEffects, ICreationResult templateCreationResult, string outputBasePath)
        {
            bool allSucceeded = true;
            IEnumerable <string>?targetFiles = GetConfiguredFiles(actionConfig.Args, creationEffects, "files", outputBasePath);

            if (targetFiles is null || !targetFiles.Any())
            {
                //If the author didn't opt in to the new behavior by specifying "projectFiles", use the old behavior - primary outputs
                if (templateCreationResult.PrimaryOutputs.Count == 0)
                {
                    Reporter.Output.WriteLine(LocalizableStrings.PostAction_Restore_Error_NoProjectsToRestore);
                    return(true);
                }
                targetFiles = templateCreationResult.PrimaryOutputs.Select(output => Path.GetFullPath(output.Path, outputBasePath));
            }

            if (targetFiles is null || !targetFiles.Any())
            {
                Reporter.Error.WriteLine(string.Format(LocalizableStrings.PostAction_Restore_Error_FailedToDetermineProjectToRestore));
                return(false);
            }

            foreach (string pathToRestore in targetFiles)
            {
                //do not check for file existance. The restore will fail in case file doesn't exist.
                Reporter.Output.WriteLine(string.Format(LocalizableStrings.PostAction_Restore_Running, pathToRestore));

                // Prefer to restore the project in-proc vs. creating a new process.
                bool succeeded = false;
                if (Callbacks?.RestoreProject != null)
                {
                    succeeded = Callbacks.RestoreProject(pathToRestore);
                }

                if (!succeeded)
                {
                    Reporter.Error.WriteLine(LocalizableStrings.PostAction_Restore_Failed);
                    if (Callbacks?.RestoreProject == null)
                    {
                        Reporter.Error.WriteLine(LocalizableStrings.Generic_NoCallbackError);
                    }
                    allSucceeded = false;
                }
                else
                {
                    Reporter.Output.WriteLine(LocalizableStrings.PostAction_Restore_Succeeded);
                }
            }
            return(allSucceeded);
        }