/* Function: Start * * Starts <Engine.Instance> using the passed folder of test data. * * If the test data folder is relative it will look for a "Engine.Tests.Data" subfolder where the executing assembly is. If * one doesn't exist, it will check each parent folder for it. Once found it will make the test data folder relative to that. * * If projectConfigFolder is relative it follows the same rules as the test data folder. If it's not specified all defaults will * be used as if the project didn't have any configuration files defined. * * If keepOutputFolder is true, the HTML output folder will not be deleted after the engine is disposed of. */ public void Start(Path testDataFolder, Path projectConfigFolder = default(Path), bool keepOutputFolder = false, string outputTitle = null, string outputSubtitle = null, string outputStyle = null, bool autoGroup = false) { this.inputFolder = testDataFolder; this.projectConfigFolder = projectConfigFolder; this.keepOutputFolder = keepOutputFolder; // testDataRoot Path assemblyFolder = Path.FromAssembly(System.Reflection.Assembly.GetExecutingAssembly()).ParentFolder; Path testDataRoot = assemblyFolder; while (System.IO.Directory.Exists(testDataRoot + "/Engine.Tests.Data") == false) { if (testDataRoot.ParentFolder == testDataRoot) { throw new Exception("Couldn't find Engine.Tests.Data folder in " + assemblyFolder + " or any of its parents."); } testDataRoot = testDataRoot.ParentFolder; } testDataRoot = testDataRoot + "/Engine.Tests.Data"; // inputFolder if (inputFolder.IsRelative) { inputFolder = testDataRoot + '/' + inputFolder; } if (System.IO.Directory.Exists(inputFolder) == false) { throw new Exception("Cannot locate input folder " + inputFolder); } // temporaryFolderRoot temporaryFolderRoot = inputFolder + "/ND Temp"; // projectConfigFolder if (projectConfigFolder == null) { projectConfigFolder = temporaryFolderRoot + "/Project"; } else { if (projectConfigFolder.IsRelative) { projectConfigFolder = testDataRoot + '/' + projectConfigFolder; } if (System.IO.Directory.Exists(projectConfigFolder) == false) { throw new Exception("Cannot locate config folder " + projectConfigFolder); } } // workingDataFolder workingDataFolder = temporaryFolderRoot + "/Working Data"; // outputFolder if (keepOutputFolder) { outputFolder = inputFolder + "/HTML Output"; } else { outputFolder = temporaryFolderRoot + "/HTML Output"; } // Clear out old data before start. try { System.IO.Directory.Delete(temporaryFolderRoot, true); } catch { } if (keepOutputFolder) { // Still need to clear it out so we can make a fresh copy. We just won't delete it afterwards. try { System.IO.Directory.Delete(outputFolder, true); } catch { } } // Create new folders. These functions do nothing if they already exist, they won't throw exceptions. System.IO.Directory.CreateDirectory(projectConfigFolder); System.IO.Directory.CreateDirectory(workingDataFolder); System.IO.Directory.CreateDirectory(outputFolder); // INITIALIZE ZE ENGINE! engineInstance = new NaturalDocs.Engine.Instance(); var config = new Config.ProjectConfig(Config.PropertySource.CommandLine); config.ProjectConfigFolder = projectConfigFolder; config.ProjectConfigFolderPropertyLocation = Config.PropertySource.CommandLine; config.WorkingDataFolder = workingDataFolder; config.WorkingDataFolderPropertyLocation = Config.PropertySource.CommandLine; config.AutoGroup = autoGroup; config.AutoGroupPropertyLocation = Config.PropertySource.CommandLine; var inputTarget = new Config.Targets.SourceFolder(Config.PropertySource.CommandLine); inputTarget.Folder = inputFolder; inputTarget.FolderPropertyLocation = Config.PropertySource.CommandLine; config.InputTargets.Add(inputTarget); var outputTarget = new Config.Targets.HTMLOutputFolder(Config.PropertySource.CommandLine); outputTarget.Folder = outputFolder; outputTarget.FolderPropertyLocation = Config.PropertySource.CommandLine; if (outputTitle != null) { outputTarget.ProjectInfo.Title = outputTitle; outputTarget.ProjectInfo.TitlePropertyLocation = Config.PropertySource.CommandLine; } if (outputSubtitle != null) { outputTarget.ProjectInfo.Subtitle = outputSubtitle; outputTarget.ProjectInfo.SubtitlePropertyLocation = Config.PropertySource.CommandLine; } if (outputStyle != null) { outputTarget.ProjectInfo.StyleName = outputStyle; outputTarget.ProjectInfo.StyleNamePropertyLocation = Config.PropertySource.CommandLine; } config.OutputTargets.Add(outputTarget); Engine.Errors.ErrorList startupErrors = new Engine.Errors.ErrorList(); if (!engineInstance.Start(startupErrors, config)) { StringBuilder message = new StringBuilder(); message.Append("Could not start the Natural Docs engine for testing:"); foreach (var error in startupErrors) { message.Append("\n - "); if (error.File != null) { message.Append(error.File + " line " + error.LineNumber + ": "); } message.Append(error.Message); } Dispose(); throw new Exception(message.ToString()); } }
// Group: Primary Execution Paths // __________________________________________________________________________ /* Function: Main * The program entry point. */ public static void Main (string[] commandLine) { executionTimer = new ExecutionTimer(); executionTimer.Start("Total Execution"); engineInstance = null; quiet = false; workerThreadCount = DefaultWorkerThreadCount; totalFileChanges = 0; benchmark = false; pauseOnError = false; pauseBeforeExit = false; bool gracefulExit = false; var standardOutput = System.Console.Out; try { engineInstance = new NaturalDocs.Engine.Instance(); ErrorList startupErrors = new ErrorList(); ParseCommandLineResult parseCommandLineResult = ParseCommandLine(commandLine, out commandLineConfig, startupErrors); if (parseCommandLineResult == ParseCommandLineResult.Error) { HandleErrorList(startupErrors); } else if (parseCommandLineResult == ParseCommandLineResult.ShowCommandLineReference) { ShowCommandLineReference(); gracefulExit = true; } else if (parseCommandLineResult == ParseCommandLineResult.ShowVersion) { ShowVersion(); gracefulExit = true; } else // (parseCommandLineResult == ParseCommandLineResult.Run) { if (quiet) { // This is easier and less error prone than putting conditional statements around all the non-error console // output, even if it's less efficient. System.Console.SetOut(System.IO.TextWriter.Null); } // Create project configuration files only if (commandLineConfig.ProjectConfigFolderPropertyLocation.IsDefined && commandLineConfig.InputTargets.Count == 0 && commandLineConfig.OutputTargets.Count == 0 && !System.IO.File.Exists(commandLineConfig.ProjectConfigFolder + "/Project.txt")) { if (CreateProjectConfiguration(startupErrors)) { gracefulExit = true; } else { HandleErrorList(startupErrors); } } // Normal execution else { if (BuildDocumentation(startupErrors)) { gracefulExit = true; } else { HandleErrorList(startupErrors); } } } } catch (Exception e) { HandleException(e); } finally { Engine.Path projectFolder = engineInstance.Config.ProjectConfigFolder; engineInstance.Dispose(gracefulExit); engineInstance = null; executionTimer.End("Total Execution"); if (benchmark) { ShowBenchmarksAndBuildCSV(projectFolder + "/Benchmarks.csv"); } // Restore the standard output. We do this before "Press any key to continue" because we never want that to // be hidden. if (quiet) { System.Console.SetOut(standardOutput); } } if (pauseBeforeExit || (pauseOnError && !gracefulExit)) { System.Console.WriteLine(); System.Console.WriteLine( Engine.Locale.SafeGet("NaturalDocs.CLI", "Status.PressAnyKeyToContinue", "Press any key to continue...") ); System.Console.ReadKey(true); } }