Example #1
0
        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));
        }
Example #2
0
        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));
        }
Example #3
0
        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));
        }
Example #4
0
        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));
        }