/** * Create a PatchRunController for running a PatchScript. * @param pForPatchScript PatchScript to be run. * @return A new PatchRunController. */ public PatchRunController createPatchRunController(PatchScript pForPatchScript) { if (!hasCommandLineOption(CommandLineOption.NO_EXEC)) { return new PatchRunController(this, pForPatchScript); } else { return new NoExecPatchRunController(this, pForPatchScript); } }
/** * Prints the parsed contents of each PatchScript in the given path list to standard out. Each statement in the PatchScript * is seperated by an obvious string delimiter. Any errors encountered during the parse are also printed to standard out * and are not re-thrown. This output is for debugging purposes only and should not be processed programatically. * @param pBaseDirectory Base directory for relative path evalulation. * @param pScriptPathList List of paths to all required PathScripts. * @return True if parsing was successful, false otherwise. */ public static bool printScriptsToStandardOut(DirectoryInfo pBaseDirectory, List <string> pScriptPathList) { bool lSuccess = true; foreach (string lPath in pScriptPathList) { try { FileInfo lPatchFile = new FileInfo(lPath); if (!Path.IsPathRooted(lPath)) { //If not absolute, evaluate from the base directory lPatchFile = new FileInfo(Path.Combine(pBaseDirectory.FullName, lPath)); } Console.WriteLine($"\n********** {lPatchFile.Name} **********\n"); string lFileContents = File.ReadAllText(lPatchFile.FullName); PatchScript lPatchScript = createFromString(lPatchFile.FullName, lFileContents); Console.WriteLine($"Patch label: {lPatchScript.PatchLabel}"); Console.WriteLine($"Patch number: {lPatchScript.PatchNumber}"); Console.WriteLine($"Patch description: {lPatchScript.Description}"); foreach (ScriptExecutable lExec in lPatchScript.ExecutableList) { Console.WriteLine(PRINT_STATEMENT_DIVIDER); Console.WriteLine(lExec.getDisplayString()); } Console.WriteLine(PRINT_STATEMENT_DIVIDER); } catch (IOException e) { Console.WriteLine("ERROR: Could not read PatchScript file"); Console.WriteLine($"Reason (see log for details): {e.Message}"); Logger.logError(e); lSuccess = false; } catch (ExParser e) { Console.WriteLine("ERROR: PATCHSCRIPT COULD NOT BE PARSED"); Console.WriteLine($"Reason (see log for details): {e.Message}"); Logger.logError(e); lSuccess = false; } } return(lSuccess); }
/** * Pre-parses all patch scripts in this promote, and returns a map of file paths to PatchScripts. * This should be performed in advance of the promote to catch any parsing issues before runtime. This method also * verifies that the scripts will be executed in the correct order. * @param pManifestParser ManifestParse containing all promotion files. * @return Map of file paths to PatchScripts. * @throws ExFatalError If there is an ordering problem or parsing problem. */ private Dictionary<string, PatchScript> preParsePatchScripts(PromotionManifestParser pManifestParser) { Logger.logInfo("Validating patches..."); Dictionary<string, PatchScript> lParsedScriptMap = new Dictionary<string, PatchScript>(); //Map of patch labels to highest orders - used to verify script order is correct Dictionary<string, int?> lScriptNumberMap = new Dictionary<string, int?>(); foreach (PromotionFile lPromotionFile in pManifestParser.getPromotionFileList()) { if (BuiltInLoader.LOADER_NAME_PATCH == lPromotionFile.getLoaderName()) { try { PatchScript lScript = PatchScript.createFromPromotionFile(this, lPromotionFile); int? lPreviousNumber = lScriptNumberMap[lScript.getPatchLabel()]; if (lPreviousNumber != null && lScript.getPatchNumber() < lPreviousNumber) { throw new ExFatalError("Patch order violation - " + lScript.getDisplayName() + " is implicated after patch with number " + lPreviousNumber); } if (lPromotionFile.isForcedDuplicate()) { throw new ExFatalError("Patch " + lScript.getDisplayName() + " at position " + lPromotionFile.getSequencePosition() + " cannot be a forced duplicate; patches may only be run once in a promote."); }; lParsedScriptMap.Add(lPromotionFile.getFilePath(), lScript); lScriptNumberMap.Add(lScript.getPatchLabel(), lScript.getPatchNumber()); } catch (ExParser e) { throw new ExFatalError("Could not parse patch " + lPromotionFile.getFilePath() + ": " + e.Message, e); } catch (IOException e) { throw new ExFatalError("Could not parse patch " + lPromotionFile.getFilePath(), e); } } } return lParsedScriptMap; }
public static void Main(string[] args) { OptionException oe; //Parse command line options CommandLineWrapper commandLineOptions = null; try { commandLineOptions = new CommandLineWrapper(args); } catch (OptionException e) { Console.Error.WriteLine("ScriptRunner start failed:"); Console.Error.WriteLine(e.Message); commandLineOptions.PrintHelp(); Environment.Exit(0xA0); } //Set up logging try { DirectoryInfo logDirectory; if (!string.IsNullOrEmpty(commandLineOptions.LogDirectory)) { logDirectory = new DirectoryInfo(commandLineOptions.LogDirectory); } else { //Default the log directory to the current working directory logDirectory = new DirectoryInfo(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile)); } //Create a log file in the specified directory and set it up for writing Logger.InitialiseLogFile(logDirectory); } catch (IOException e) { Console.Error.WriteLine("ScriptRunner failed to initialise log file:"); Console.Error.WriteLine(e.Message); Environment.Exit(1); } //Set up the logger if (commandLineOptions.LogStdOut) { Logger.logToStandardOut(); } if (commandLineOptions.LogDebug) { Logger.enableDebugLogging(); } Logger.logAndEcho(ScriptRunnerVersion.getVersionString()); //Main branch - call the relevant subprocess based on supplied arguments bool lError = false; try { if (commandLineOptions.RunDirectory != null) { ScriptRunner.run(commandLineOptions); if (commandLineOptions.hasOption(CommandLineOption.NO_EXEC)) { Logger.logAndEcho("-noexec parse completed successfully"); } else { Logger.logAndEcho("Promotion completed successfully"); } } else if (commandLineOptions.hasOption(CommandLineOption.BUILD)) { ScriptBuilder.run(commandLineOptions); Logger.logAndEcho("Build completed successfully"); } else if (commandLineOptions.hasOption(CommandLineOption.INSTALL)) { Logger.logAndEcho("Installing ScriptRunner"); Installer.run(commandLineOptions); //Haul up to latest version Updater.run(commandLineOptions); Logger.logAndEcho("Install completed successfully"); } else if (commandLineOptions.hasOption(CommandLineOption.UPDATE)) { Logger.logAndEcho("Checking Scriptrunner is up to date"); Updater.run(commandLineOptions); Logger.logAndEcho("Update check completed successfully"); } else if (commandLineOptions.hasOption(CommandLineOption.PARSE_SCRIPTS)) { List <String> lFileList = commandLineOptions.getOptionValues(CommandLineOption.PARSE_SCRIPTS); Logger.logAndEcho("Parsing " + lFileList.size() + " PatchScript" + (lFileList.size() != 1 ? "s" : "")); lError = !PatchScript.printScriptsToStandardOut(new File(System.getProperty("user.dir")), lFileList); } //Print a message to standard out if warnings were encountered int lWarnCount = Logger.getWarningCount(); if (Logger.getWarningCount() > 0) { Logger.logAndEcho(lWarnCount + " warning" + (lWarnCount != 1 ? "s were" : " was") + " detected during execution; please review the log for details"); } } catch (Throwable th) { String timeStamp = Logger.LOG_FILE_LOG_TIMESTAMP_FORMAT.format(new Date()); Console.Error.WriteLine("[" + timeStamp + "] Error encountered while running ScriptRunner (see log for details):"); Console.Error.WriteLine(th.Message); if (!commandLineOptions.hasOption(CommandLineOption.RUN)) { //Error will already have been logged by runner; for all others log it now Logger.logError(th); } lError = true; } finally { Logger.finaliseLogs(); } //Exit with the correct code Environment.Exit(lError ? 1 : 0); }