public bool ParseArgs(string[] args, out bool hasErrors) { System.CommandLine.ArgumentSyntax parsed = System.CommandLine.ArgumentSyntax.Parse(args, syntax => { syntax.DefineOption("attach", ref Attach, "Pause execution at the start of the program until a debugger is attached."); syntax.DefineOption("solution", ref SolutionFilePath, "The full path of the solution file that contains the project."); syntax.DefineOptionList("p", ref _properties, ParseProperty, "The build properties."); syntax.DefineParameter(nameof(ProjectFilePath), ref ProjectFilePath, "The full path of the project file."); syntax.DefineParameterList(nameof(ScriptFilePaths), ref ScriptFilePaths, "The path(s) of script files to evaluate (can be absolute or relative to the project)."); }); if (_properties != null) { Dictionary <string, string> props = new Dictionary <string, string>(); foreach (KeyValuePair <string, string> pair in _properties) { props[pair.Key] = pair.Value; } Properties = props; } hasErrors = parsed.HasErrors; return(!(parsed.IsHelpRequested() || hasErrors)); }
public bool ParseArgs(string[] args, out bool hasErrors) { System.CommandLine.ArgumentSyntax parsed = System.CommandLine.ArgumentSyntax.Parse(args, syntax => { syntax.DefineParameter(nameof(ProjectFilePath), ref ProjectFilePath, "The full path of the project file."); syntax.DefineParameterList(nameof(ScriptFilePaths), ref ScriptFilePaths, "The path(s) of script files to evaluate (can be absolute or relative to the project)."); }); hasErrors = parsed.HasErrors; return(!(parsed.IsHelpRequested() || hasErrors)); }
private bool ParseArgs(string[] args, out bool hasErrors) { System.CommandLine.ArgumentSyntax parsed = System.CommandLine.ArgumentSyntax.Parse(args, syntax => { syntax.DefineOption("w|watch", ref _watch, "Watches the input folder for any changes."); _preview = syntax.DefineOption("p|preview", ref _previewPort, false, "Start the preview web server on the specified port (default is " + _previewPort + ").").IsSpecified; if (syntax.DefineOption("force-ext", ref _previewForceExtension, "Force the use of extensions in the preview web server (by default, extensionless URLs may be used).").IsSpecified&& !_preview) { syntax.ReportError("force-ext can only be specified if the preview server is running."); } if (syntax.DefineOption("preview-root", ref _previewRoot, DirectoryPath.FromString, "The path to the root of the preview server, if not the output folder.").IsSpecified&& !_preview) { syntax.ReportError("preview-root can only be specified if the preview server is running."); } syntax.DefineOptionList("i|input", ref _inputPaths, DirectoryPath.FromString, "The path(s) of input files, can be absolute or relative to the current folder."); syntax.DefineOption("verify-config", ref _verifyConfig, false, "Compile the configuration but do not execute."); syntax.DefineOption("o|output", ref _outputPath, DirectoryPath.FromString, "The path to output files, can be absolute or relative to the current folder."); syntax.DefineOption("c|config", ref _configFilePath, FilePath.FromString, "Configuration file (by default, config.wyam is used)."); syntax.DefineOption("u|update-packages", ref _updatePackages, "Check the NuGet server for more recent versions of each package and update them if applicable."); syntax.DefineOption("output-scripts", ref _outputScripts, "Outputs the config scripts after they've been processed for further debugging."); syntax.DefineOption("noclean", ref _noClean, "Prevents cleaning of the output path on each execution."); syntax.DefineOption("nocache", ref _noCache, "Prevents caching information during execution (less memory usage but slower execution)."); syntax.DefineOption("v|verbose", ref _verbose, "Turns on verbose output showing additional trace message useful for debugging."); syntax.DefineOption("pause", ref _pause, "Pause execution at the start of the program until a key is pressed (useful for attaching a debugger)."); syntax.DefineOptionList("meta", ref _globalRawMetadata, "Specifies global metadata which can be accessed from the engine or config file (--meta key=value)."); _logFilePath = $"wyam-{DateTime.Now:yyyyMMddHHmmssfff}.txt"; if (!syntax.DefineOption("l|log", ref _logFilePath, FilePath.FromString, false, "Log all trace messages to the specified log file (by default, wyam-[datetime].txt).").IsSpecified) { _logFilePath = null; } if (syntax.DefineParameter("root", ref _rootPath, DirectoryPath.FromString, "The folder (or config file) to use.").IsSpecified) { // If a root folder was defined, but it actually points to a file, set the root folder to the directory // and use the specified file as the config file (if a config file was already specified, it's an error) FilePath rootDirectoryPathAsConfigFile = new DirectoryPath(Environment.CurrentDirectory).CombineFile(_rootPath.FullPath); if (File.Exists(rootDirectoryPathAsConfigFile.FullPath)) { // The specified root actually points to a file... if (_configFilePath != null) { syntax.ReportError("A config file was both explicitly specified and specified in the root folder."); } else { _configFilePath = rootDirectoryPathAsConfigFile.GetFilename(); _rootPath = rootDirectoryPathAsConfigFile.GetDirectory(); } } } }); hasErrors = parsed.HasErrors; if (Console.IsInputRedirected) { using (var reader = new StreamReader(Console.OpenStandardInput(), Console.InputEncoding)) { _stdin = reader.ReadToEnd(); } } return(!(parsed.IsHelpRequested() || hasErrors)); }
public bool ParseArgs(string[] args, Preprocessor preprocessor, out bool hasErrors) { System.CommandLine.ArgumentSyntax parsed = System.CommandLine.ArgumentSyntax.Parse(args, syntax => { // Any changes here should also be made in Cake.Wyam if (syntax.DefineOption("help-directives", ref HelpDirectives, "Displays help for the various preprocessor directives.").IsSpecified) { // Don't care about anything else return; } syntax.DefineOption("w|watch", ref Watch, "Watches the input folder for any changes."); Preview = syntax.DefineOption("p|preview", ref PreviewPort, false, "Start the preview web server on the specified port (default is " + PreviewPort + ").").IsSpecified; if (syntax.DefineOption("force-ext", ref PreviewForceExtension, "Force the use of extensions in the preview web server (by default, extensionless URLs may be used).").IsSpecified&& !Preview) { syntax.ReportError("force-ext can only be specified if the preview server is running."); } if (syntax.DefineOption("preview-root", ref PreviewRoot, DirectoryPath.FromString, "The path to the root of the preview server, if not the output folder.").IsSpecified&& !Preview) { syntax.ReportError("preview-root can only be specified if the preview server is running."); } syntax.DefineOptionList("i|input", ref InputPaths, DirectoryPath.FromString, "The path(s) of input files, can be absolute or relative to the current folder."); syntax.DefineOption("o|output", ref OutputPath, DirectoryPath.FromString, "The path to output files, can be absolute or relative to the current folder."); syntax.DefineOption("c|config", ref ConfigFilePath, FilePath.FromString, "Configuration file (by default, config.wyam is used)."); syntax.DefineOption("u|update-packages", ref UpdatePackages, "Check the NuGet server for more recent versions of each package and update them if applicable."); syntax.DefineOption("use-local-packages", ref UseLocalPackages, "Toggles the use of a local NuGet packages folder."); syntax.DefineOption("packages-path", ref PackagesPath, DirectoryPath.FromString, "The packages path to use (only if use-local is true)."); syntax.DefineOption("output-script", ref OutputScript, "Outputs the config script after it's been processed for further debugging."); syntax.DefineOption("verify-config", ref VerifyConfig, false, "Compile the configuration but do not execute."); syntax.DefineOption("noclean", ref NoClean, "Prevents cleaning of the output path on each execution."); syntax.DefineOption("nocache", ref NoCache, "Prevents caching information during execution (less memory usage but slower execution)."); syntax.DefineOption("v|verbose", ref Verbose, "Turns on verbose output showing additional trace message useful for debugging."); syntax.DefineOption("pause", ref Pause, "Pause execution at the start of the program until a key is pressed (useful for attaching a debugger)."); syntax.DefineOptionList("meta", ref GlobalMetadataArgs, "Specifies global metadata which can be accessed from the engine or config file (--meta key=value)."); LogFilePath = $"wyam-{DateTime.Now:yyyyMMddHHmmssfff}.txt"; if (!syntax.DefineOption("l|log", ref LogFilePath, FilePath.FromString, false, "Log all trace messages to the specified log file (by default, wyam-[datetime].txt).").IsSpecified) { LogFilePath = null; } foreach (IDirective directive in preprocessor.Directives.Where(x => x.SupportsCli)) { IReadOnlyList <string> directiveValues = null; syntax.DefineOptionList(directive.DirectiveNames.First(), ref directiveValues, $"{directive.Description} See below for syntax details."); if (directiveValues != null) { foreach (string directiveValue in directiveValues) { preprocessor.AddValue(new DirectiveValue(directive.DirectiveNames.First(), directiveValue)); } } } if (syntax.DefineParameter("root", ref RootPath, DirectoryPath.FromString, "The folder (or config file) to use.").IsSpecified) { // If a root folder was defined, but it actually points to a file, set the root folder to the directory // and use the specified file as the config file (if a config file was already specified, it's an error) FilePath rootDirectoryPathAsConfigFile = new DirectoryPath(Environment.CurrentDirectory).CombineFile(RootPath.FullPath); if (File.Exists(rootDirectoryPathAsConfigFile.FullPath)) { // The specified root actually points to a file... if (ConfigFilePath != null) { syntax.ReportError("A config file was both explicitly specified and specified in the root folder."); } else { ConfigFilePath = rootDirectoryPathAsConfigFile.FileName; RootPath = rootDirectoryPathAsConfigFile.Directory; } } } }); hasErrors = parsed.HasErrors; // Set verbose tracing if (Verbose) { Trace.Level = System.Diagnostics.SourceLevels.Verbose; } // Capture any stdin, but we have to be very careful because the calling process might have // opened stdin and just left it open, in which case it would register as redirected but the // stream won't ever return because it's just waiting for input if (Console.IsInputRedirected) { Trace.Verbose("Input is redirected, attempting to read..."); using (Stream stream = Console.OpenStandardInput()) { byte[] buffer = new byte[1000]; StringBuilder stdin = new StringBuilder(); int totalRead = 0; int read = -1; while (true) { AutoResetEvent gotInput = new AutoResetEvent(false); Thread inputThread = new Thread(() => { try { read = stream.Read(buffer, 0, buffer.Length); gotInput.Set(); } catch (ThreadAbortException) { Thread.ResetAbort(); } }) { IsBackground = true }; inputThread.Start(); // Timeout expired? if (!gotInput.WaitOne(100)) { inputThread.Abort(); Trace.Verbose("Timeout expired while reading from input"); break; } // End of stream? if (read == 0) { Stdin = stdin.ToString(); Trace.Verbose($"Read {totalRead} bytes ({Stdin.Length} characters) from input"); break; } // Got data stdin.Append(Console.InputEncoding.GetString(buffer, 0, read)); totalRead += read; } } } if (parsed.IsHelpRequested()) { foreach (IDirective directive in preprocessor.Directives.Where(x => x.SupportsCli)) { Console.WriteLine($"--{directive.DirectiveNames.First()} usage:"); Console.WriteLine(); Console.WriteLine(directive.GetHelpText()); Console.WriteLine(); } } return(!(parsed.IsHelpRequested() || hasErrors)); }