Пример #1
0
        /// <summary>
        /// Control flow begins here.
        /// </summary>
        /// <param name="args">Command-line arguments. See <see cref="CommandLineInput.ShowUsage"/>
        /// for usage.</param>.
        /// <returns>0 on success, -1 on bad input, 1 on runtime error.  See also <see cref="Result"/>
        /// enum.</returns>
        public static int Main(string[] args)
        {
            var     input   = new CommandLineInput(args);
            Feature?feature = input.Parse();

            if (feature == null)
            {
                return(CommandLineInput.ShowUsage());
            }

            // hijack Console.Out so it writes to a text file
            RedirectOutput(input.OutputFilename);

            // load configurable properties from a properties file
            ConfiguredProperties properties = ConfiguredProperties.Load(input.PropertiesFilename);

            // map the feature and configurable properties to a Program instance
            Program p = GetProgramInstance(feature.Value, properties);

            if (p == null)
            {
                return(Result.Invalid);
            }

            return(TryToExecute(p, DateTime.Now));
        }
Пример #2
0
        /// <summary>
        /// Runs the application with specified command line arguments and environment variables, and returns the exit code.
        /// </summary>
        public async ValueTask <int> RunAsync(
            IReadOnlyList <string> commandLineArguments,
            IReadOnlyDictionary <string, string> environmentVariables)
        {
            try
            {
                var applicationSchema = ApplicationSchema.Resolve(_configuration.CommandTypes);
                var commandLineInput  = CommandLineInput.Parse(commandLineArguments);

                return
                    (await HandleDebugDirectiveAsync(commandLineInput) ??
                     HandlePreviewDirective(applicationSchema, commandLineInput) ??
                     HandleVersionOption(commandLineInput) ??
                     HandleHelpOption(applicationSchema, commandLineInput) ??
                     await HandleCommandExecutionAsync(applicationSchema, commandLineInput, environmentVariables));
            }
            catch (Exception ex)
            {
                // We want to catch exceptions in order to print errors and return correct exit codes.
                // Doing this also gets rid of the annoying Windows troubleshooting dialog that shows up on unhandled exceptions.

                // Prefer showing message without stack trace on exceptions coming from CliFx or on CommandException
                var errorMessage = !string.IsNullOrWhiteSpace(ex.Message) && (ex is CliFxException || ex is CommandException)
                    ? ex.Message
                    : ex.ToString();

                _console.WithForegroundColor(ConsoleColor.Red, () => _console.Error.WriteLine(errorMessage));

                return(ex is CommandException commandException
                    ? commandException.ExitCode
                    : ex.HResult);
            }
        }
Пример #3
0
        /// <summary>
        /// Runs the application with specified command line arguments and environment variables, and returns the exit code.
        /// </summary>
        public async ValueTask <int> RunAsync(
            IReadOnlyList <string> commandLineArguments,
            IReadOnlyDictionary <string, string> environmentVariables)
        {
            try
            {
                var applicationSchema = ApplicationSchema.Resolve(_configuration.CommandTypes);
                var commandLineInput  = CommandLineInput.Parse(commandLineArguments);

                return
                    (await HandleDebugDirectiveAsync(commandLineInput) ??
                     HandlePreviewDirective(applicationSchema, commandLineInput) ??
                     HandleVersionOption(commandLineInput) ??
                     HandleHelpOption(applicationSchema, commandLineInput) ??
                     await HandleCommandExecutionAsync(applicationSchema, commandLineInput, environmentVariables));
            }
            catch (CliFxException cfe)
            {
                // We want to catch exceptions in order to print errors and return correct exit codes.
                // Doing this also gets rid of the annoying Windows troubleshooting dialog that shows up on unhandled exceptions.
                var exitCode = HandleCliFxException(commandLineArguments, cfe);
                return(exitCode);
            }
            catch (Exception ex)
            {
                // For all other errors, we just write the entire thing to stderr.
                _console.WithForegroundColor(ConsoleColor.Red, () => _console.Error.WriteLine(ex.ToString()));
                return(ex.HResult);
            }
        }
Пример #4
0
        public void Parse_Test(IReadOnlyList <string> commandLineArguments, CommandLineInput expectedResult)
        {
            // Act
            var result = CommandLineInput.Parse(commandLineArguments);

            // Assert
            result.Should().BeEquivalentTo(expectedResult);
        }
Пример #5
0
        internal void Directive_can_be_enabled_by_specifying_its_name_in_square_brackets(string[] arguments, CommandLineInput expectedInput)
        {
            // Act
            var input = CommandLineInput.Parse(arguments);

            // Assert
            input.Should().BeEquivalentTo(expectedInput);
        }
Пример #6
0
        internal void Any_remaining_arguments_are_treated_as_unbound_arguments(string[] arguments, CommandLineInput expectedInput)
        {
            // Act
            var input = CommandLineInput.Parse(arguments);

            // Assert
            input.Should().BeEquivalentTo(expectedInput);
        }
Пример #7
0
        internal void Option_can_be_set_by_specifying_its_short_name_after_a_single_dash(string[] arguments, CommandLineInput expectedInput)
        {
            // Act
            var input = CommandLineInput.Parse(arguments);

            // Assert
            input.Should().BeEquivalentTo(expectedInput);
        }
Пример #8
0
        public void Input_is_empty_if_no_arguments_are_provided()
        {
            // Arrange
            var args = Array.Empty <string>();

            // Act
            var input = CommandLineInput.Parse(args);

            // Assert
            input.Should().BeEquivalentTo(CommandLineInput.Empty);
        }
Пример #9
0
        /// <summary>
        /// Handle <see cref="CommandException"/>s differently from the rest because we want to
        /// display it different based on whether we are showing the help text or not.
        /// </summary>
        private int HandleCliFxException(IReadOnlyList <string> commandLineArguments, CliFxException cfe)
        {
            var showHelp = cfe.ShowHelp;

            var errorMessage = cfe.HasMessage
                ? cfe.Message
                : cfe.ToString();

            _console.WithForegroundColor(ConsoleColor.Red, () => _console.Error.WriteLine(errorMessage));

            if (showHelp)
            {
                var applicationSchema = ApplicationSchema.Resolve(_configuration.CommandTypes);
                var commandLineInput  = CommandLineInput.Parse(commandLineArguments);
                var commandSchema     = applicationSchema.TryFindCommand(commandLineInput) ??
                                        CommandSchema.StubDefaultCommand;
                _helpTextWriter.Write(applicationSchema, commandSchema);
            }

            return(cfe.ExitCode);
        }