private ValidationResult OnValidate(ValidationContext context, CommandLineContext appContext) { if (this.Middle.HasValue && this.Middle < 0) { return(new ValidationResult("Middle must be greater than 0")); } Assert.Equal(typeof(CommandLineApplication <MainValidate>), context.ObjectInstance.GetType()); return(ValidationResult.Success); }
/// <summary> /// Builds the command line. /// </summary> /// <param name="bindingModel">Must not be null.</param> /// <returns></returns> public string Build(GroupBindingModel bindingModel) { _ctx = new CommandLineContext(); NavigateGroup(bindingModel); var commandLine = Compile(_ctx); _ctx = null; return(commandLine); }
protected ValidationResult OnValidate(ValidationContext validationContext, CommandLineContext commandLineContext) { if (!string.IsNullOrWhiteSpace(BasicAuthUser) && string.IsNullOrWhiteSpace(BasicAuthPassword.Value)) { return(new ValidationResult("User was provided but Password was not.", new[] { nameof(BasicAuthUser), nameof(BasicAuthPassword) })); } if (!string.IsNullOrWhiteSpace(BasicAuthPassword.Value) && string.IsNullOrWhiteSpace(BasicAuthUser)) { return(new ValidationResult("Password was provided but User was not.", new[] { nameof(BasicAuthUser), nameof(BasicAuthPassword) })); } return(ValidationResult.Success); }
internal CommandLineApplication(IHelpTextGenerator helpTextGenerator, CommandLineContext context, bool throwOnUnexpectedArg) { _context = context ?? throw new ArgumentNullException(nameof(context)); ThrowOnUnexpectedArgument = throwOnUnexpectedArg; Options = new List <CommandOption>(); Arguments = new List <CommandArgument>(); Commands = new List <CommandLineApplication>(); RemainingArguments = new List <string>(); HelpTextGenerator = helpTextGenerator; Invoke = () => 0; ValidationErrorHandler = DefaultValidationErrorHandler; SetContext(context); }
public int Execute(CommandLineContext context, BindResult bindResult) { var arguments = ReflectionHelper.BindParameters(Method, context, bindResult); var result = Method.Invoke(bindResult.Target, arguments); if (Method.ReturnType == typeof(int)) { return((int)result); } return(0); }
#pragma warning disable RS0026 // Do not add multiple public overloads with optional parameters /// <summary> /// Creates an instance of <typeparamref name="TApp"/>, matching <see cref="CommandLineContext.Arguments"/> /// to all attributes on the type, and then invoking a method named "OnExecute" or "OnExecuteAsync" if it exists. /// </summary> /// <seealso cref="OptionAttribute" /> /// <seealso cref="ArgumentAttribute" /> /// <seealso cref="HelpOptionAttribute"/> /// <seealso cref="VersionOptionAttribute"/> /// <param name="context">The execution context.</param> /// <param name="cancellationToken"></param> /// <typeparam name="TApp">A type that should be bound to the arguments.</typeparam> /// <exception cref="InvalidOperationException">Thrown when attributes are incorrectly configured.</exception> /// <returns>The process exit code</returns> public static async Task <int> ExecuteAsync <TApp>(CommandLineContext context, CancellationToken cancellationToken = default) #pragma warning restore RS0026 // Do not add multiple public overloads with optional parameters where TApp : class { if (context == null) { throw new ArgumentNullException(nameof(context)); } if (context.Arguments == null) { throw new ArgumentNullException(nameof(context) + "." + nameof(context.Arguments)); } if (context.WorkingDirectory == null) { throw new ArgumentNullException(nameof(context) + "." + nameof(context.WorkingDirectory)); } if (context.Console == null) { throw new ArgumentNullException(nameof(context) + "." + nameof(context.Console)); } try { using var app = new CommandLineApplication <TApp>(); app.SetContext(context); app.Conventions.UseDefaultConventions(); return(await app.ExecuteAsync(context.Arguments, cancellationToken)); } catch (OperationCanceledException) { return(s_exitCodeOperationCanceled); } catch (CommandParsingException ex) { context.Console.Error.WriteLine(ex.Message); if (ex is UnrecognizedCommandParsingException uex && uex.NearestMatches.Any()) { context.Console.Error.WriteLine(); context.Console.Error.WriteLine("Did you mean this?"); context.Console.Error.WriteLine(" " + uex.NearestMatches.First()); } return(ValidationErrorExitCode); } }
private void Fill(BindingModel bindingModel, CommandLineContext ctx) { var groupBindingModel = bindingModel as GroupBindingModel; var valueBindingModel = bindingModel as ValueBindingModel; if (groupBindingModel != null) { FillGroup(groupBindingModel, ctx); } if (valueBindingModel != null) { FillValue(valueBindingModel, ctx); } }
public async Task <int> ExecuteAsync(CommandLineContext context, BindResult bindResult) { var arguments = ReflectionHelper.BindParameters(Method, context, bindResult); var result = (Task)Method.Invoke(bindResult.Target, arguments); if (result is Task <int> intResult) { return(await intResult); } await result; return(0); }
private void FillGroup(GroupBindingModel bindingModel, CommandLineContext ctx) { var optionsGroupBindingModel = bindingModel as OptionsGroupBindingModel; if (optionsGroupBindingModel != null) { Fill(optionsGroupBindingModel.SelectedOption, ctx); } else { foreach (var binding in bindingModel.Bindings) { Fill(binding, ctx); } } }
public BindResult Bind(CommandLineContext context) { EnsureInitialized(); App.SetContext(context); var processor = new CommandLineProcessor(App, context.Arguments); var command = processor.Process(); var validationResult = command.GetValidationResult(); command.Invoke(); _bindResult.Command = command; _bindResult.ValidationResult = validationResult; _bindResult.ParentTarget = _target; return(_bindResult); }
/// <summary> /// Creates an instance of <typeparamref name="TApp"/>, matching <see cref="CommandLineContext.Arguments"/> /// to all attributes on the type, and then invoking a method named "OnExecute" or "OnExecuteAsync" if it exists. /// See <seealso cref="OptionAttribute" />, <seealso cref="ArgumentAttribute" />, /// <seealso cref="HelpOptionAttribute"/>, and <seealso cref="VersionOptionAttribute"/>. /// </summary> /// <param name="context">The execution context.</param> /// <typeparam name="TApp">A type that should be bound to the arguments.</typeparam> /// <exception cref="InvalidOperationException">Thrown when attributes are incorrectly configured.</exception> /// <returns>The process exit code</returns> public static int Execute <TApp>(CommandLineContext context) where TApp : class { if (context == null) { throw new ArgumentNullException(nameof(context)); } if (context.Arguments == null) { throw new ArgumentNullException(nameof(context) + "." + nameof(context.Arguments)); } if (context.WorkingDirectory == null) { throw new ArgumentNullException(nameof(context) + "." + nameof(context.WorkingDirectory)); } if (context.Console == null) { throw new ArgumentNullException(nameof(context) + "." + nameof(context.Console)); } try { using (var app = new CommandLineApplication <TApp>()) { app.SetContext(context); app.Conventions.UseDefaultConventions(); return(app.Execute(context.Arguments)); } } catch (CommandParsingException ex) { context.Console.Error.WriteLine(ex.Message); if (ex is UnrecognizedCommandParsingException uex && !string.IsNullOrEmpty(uex.NearestMatch)) { context.Console.Error.WriteLine(); context.Console.Error.WriteLine("Did you mean this?"); context.Console.Error.WriteLine(" " + uex.NearestMatch); } return(ValidationErrorExitCode); } }
/// <summary> /// Creates an instance of <typeparamref name="TApp"/>, matching <see cref="CommandLineContext.Arguments"/> /// to all attributes on the type, and then invoking a method named "OnExecute" or "OnExecuteAsync" if it exists. /// See <seealso cref="OptionAttribute" />, <seealso cref="ArgumentAttribute" />, /// <seealso cref="HelpOptionAttribute"/>, and <seealso cref="VersionOptionAttribute"/>. /// </summary> /// <param name="context">The execution context.</param> /// <typeparam name="TApp">A type that should be bound to the arguments.</typeparam> /// <exception cref="InvalidOperationException">Thrown when attributes are incorrectly configured.</exception> /// <returns>The process exit code</returns> public static int Execute <TApp>(CommandLineContext context) where TApp : class, new() { ValidateContextIsNotNull(context); try { using (var bindResult = Bind <TApp>(context)) { if (bindResult.Command.IsShowingInformation) { return(HelpExitCode); } if (bindResult.ValidationResult != ValidationResult.Success) { return(HandleValidationError(context, bindResult)); } var invoker = ExecuteMethodInvoker.Create(bindResult.Target.GetType()); switch (invoker) { case AsyncMethodInvoker asyncInvoker: return(asyncInvoker.ExecuteAsync(context, bindResult).GetAwaiter().GetResult()); case SynchronousMethodInvoker syncInvoker: return(syncInvoker.Execute(context, bindResult)); default: throw new NotImplementedException(); } } } catch (CommandParsingException ex) { context.Console.Error.WriteLine(ex.Message); return(ValidationErrorExitCode); } }
private static void ValidateContextIsNotNull(CommandLineContext context) { if (context == null) { throw new ArgumentNullException(nameof(context)); } if (context.Arguments == null) { throw new ArgumentNullException(nameof(context) + "." + nameof(context.Arguments)); } if (context.WorkingDirectory == null) { throw new ArgumentNullException(nameof(context) + "." + nameof(context.WorkingDirectory)); } if (context.Console == null) { throw new ArgumentNullException(nameof(context) + "." + nameof(context.Console)); } }
public async Task TestCommandLineContextFromNonDIContexts() { CommandLineContext configureServicesContext = null; CommandLineContext confgureAppContext = null; await new HostBuilder() .ConfigureServices((context, collection) => { configureServicesContext = context.GetCommandLineContext(); collection.AddSingleton <IConsole>(new TestConsole(_output)); }) .ConfigureAppConfiguration((context, builder) => { confgureAppContext = context.GetCommandLineContext(); }) .RunCommandLineApplicationAsync(new string[0], app => app.OnExecute(() => { })); Assert.NotNull(configureServicesContext); Assert.NotNull(confgureAppContext); }
/// <summary> /// Creates an instance of <typeparamref name="TApp"/>, matching <see cref="CommandLineContext.Arguments"/> /// to all attributes on the type, and then invoking a method named "OnExecute" or "OnExecuteAsync" if it exists. /// See <seealso cref="OptionAttribute" />, <seealso cref="ArgumentAttribute" />, /// <seealso cref="HelpOptionAttribute"/>, and <seealso cref="VersionOptionAttribute"/>. /// </summary> /// <param name="context">The execution context.</param> /// <typeparam name="TApp">A type that should be bound to the arguments.</typeparam> /// <exception cref="InvalidOperationException">Thrown when attributes are incorrectly configured.</exception> /// <returns>The process exit code</returns> public static int Execute <TApp>(CommandLineContext context) where TApp : class { if (context == null) { throw new ArgumentNullException(nameof(context)); } if (context.Arguments == null) { throw new ArgumentNullException(nameof(context) + "." + nameof(context.Arguments)); } if (context.WorkingDirectory == null) { throw new ArgumentNullException(nameof(context) + "." + nameof(context.WorkingDirectory)); } if (context.Console == null) { throw new ArgumentNullException(nameof(context) + "." + nameof(context.Console)); } try { using (var app = new CommandLineApplication <TApp>()) { app.SetContext(context); app.Conventions.UseDefaultConventions(); return(app.Execute(context.Arguments)); } } catch (Exception ex) when(ex is CommandParsingException || ex is FormatException) { context.Console.Error.WriteLine(ex.Message); return(ValidationErrorExitCode); } }
private ValidationResult OnValidate(ValidationContext context, CommandLineContext appContext) { if (this.Start >= this.End) { return(new ValidationResult("End must be greater than start")); } Assert.Equal(typeof(CommandLineApplication <SubcommandValidate>), context.ObjectInstance.GetType()); var subcommand = (CommandLineApplication <SubcommandValidate>)context.ObjectInstance; var main = (CommandLineApplication <MainValidate>)subcommand.Parent; var middle = main.Model.Middle; if (middle.HasValue) { if (middle.Value < this.Start || middle.Value >= this.End) { return(new ValidationResult("Middle must be between start and end")); } } return(ValidationResult.Success); }
private static int HandleValidationError(CommandLineContext context, BindResult bindResult) { const BindingFlags MethodFlags = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic; var method = bindResult.Target .GetType() .GetTypeInfo() .GetMethod("OnValidationError", MethodFlags); if (method == null) { return(bindResult.Command.DefaultValidationErrorHandler(bindResult.ValidationResult)); } var arguments = ReflectionHelper.BindParameters(method, context, bindResult); var result = method.Invoke(bindResult.Target, arguments); if (method.ReturnType == typeof(int)) { return((int)result); } return(ValidationErrorExitCode); }
public ExtractCommand(CommandLineContext context) { _context = context; }
public int OnExecute(CommandLineContext context) => context.Arguments.Length;
/// <summary> /// Creates an instance of <typeparamref name="TApp"/>, matching <see cref="CommandLineContext.Arguments"/> /// to all attributes on the type, and then invoking a method named "OnExecute" or "OnExecuteAsync" if it exists. /// </summary> /// <seealso cref="OptionAttribute" /> /// <seealso cref="ArgumentAttribute" /> /// <seealso cref="HelpOptionAttribute"/> /// <seealso cref="VersionOptionAttribute"/> /// <param name="context">The execution context.</param> /// <typeparam name="TApp">A type that should be bound to the arguments.</typeparam> /// <exception cref="InvalidOperationException">Thrown when attributes are incorrectly configured.</exception> /// <returns>The process exit code</returns> public static int Execute <TApp>(CommandLineContext context) where TApp : class => ExecuteAsync <TApp>(context).GetAwaiter().GetResult();
private static BindResult Bind <TApp>(CommandLineContext context) where TApp : class, new() { var applicationBuilder = new ReflectionAppBuilder <TApp>(); return(applicationBuilder.Bind(context)); }
protected override ValidationResult OnValidate(ValidationContext context, CommandLineContext appContext) { //var recurse = this.Recurse ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly; // check that any files are in Input dir //if (!Directory.EnumerateFiles(this.Input.FullName, "*.*", recurse).Any()) //{ // throw new ArgumentException("Input directory contains no files."); //} // check that start offset (if specified) is less than end offset (if specified) if (this.EndOffset.HasValue && this.StartOffset >= this.EndOffset.Value) { return(new ValidationResult( $"StartOffset {this.StartOffset} must be less than EndOffset {this.EndOffset.Value}.", new[] { nameof(this.StartOffset), nameof(this.EndOffset) })); } // check that min duration is less than max duration if (this.SegmentDurationMinimum >= this.SegmentDuration) { return(new ValidationResult( $"SegmentDurationMinimum {this.SegmentDurationMinimum} must be less than AnalysisIdealSegmentDuration {this.SegmentDuration}.", new[] { nameof(this.SegmentDurationMinimum), nameof(this.SegmentDuration) })); } // check that mix down to mono and a a channel haven't both been specified //if (this.Channel.HasValue && this.MixDownToMono) //{ // throw new ArgumentException("You cannot specify a channel and mix down to mono."); //} // check media type if (!MediaTypes.IsFileExtRecognised(this.SegmentFileExtension)) { return(new ValidationResult($"File extension {this.SegmentFileExtension} is not recognised.")); } return(base.OnValidate(context, appContext)); }
protected override ValidationResult OnValidate(ValidationContext context, CommandLineContext appContext) { return(base.OnValidate(context, appContext)); }
private void FillValue(ValueBindingModel bindingModel, CommandLineContext ctx) { var singleValueBindingModel = bindingModel as SingleValueBindingModel; var multiValueBindingModel = bindingModel as MultiValueBindingModel; var optionsValueBindingModel = bindingModel as OptionsValueBindingModel; var repeaterBindingModel = bindingModel as RepeatingValueBindingModel; #if DEBUG if (singleValueBindingModel == null && multiValueBindingModel == null && optionsValueBindingModel == null && repeaterBindingModel == null) { Trace.WriteLine("Warning: Skipping binding model: " + bindingModel.Name); } #endif var arg = FindArgument(bindingModel.Argument.Name); switch (bindingModel.Argument.ValueCount) { case 0: { if (singleValueBindingModel != null && singleValueBindingModel.Value.HasValue) { ctx.Add(arg, bindingModel.Argument); } } break; case 1: { if (singleValueBindingModel != null && singleValueBindingModel.Value.HasValue) { ctx.Add(arg, bindingModel.Argument, singleValueBindingModel.Value); } if (optionsValueBindingModel != null && optionsValueBindingModel.SelectedOption != null && optionsValueBindingModel.SelectedOption.HasValue) { ctx.Add(arg, bindingModel.Argument, optionsValueBindingModel.SelectedOption); } } break; default: { if (multiValueBindingModel != null) { var values = from binding in multiValueBindingModel.Bindings where binding.Value.HasValue == true select binding.Value; ctx.Add(arg, bindingModel.Argument, values); } } break; } if (repeaterBindingModel != null) { foreach (var vbm in repeaterBindingModel.Bindings) { FillValue(vbm, ctx); } } }
/// <summary> /// This method is invoked when the Model is validated as a whole. It allows for complex /// validation scenarios. /// This method is automatically invoked by CommandLineUtils through reflection. /// </summary> /// <param name="context">The current validation context.</param> /// <param name="appContext">The current command line application.</param> /// <returns>A validation result.</returns> protected virtual ValidationResult OnValidate(ValidationContext context, CommandLineContext appContext) { return(ValidationResult.Success); }
/// <summary> /// Creates an instance of <typeparamref name="TApp"/>, matching <see cref="CommandLineContext.Arguments"/> /// to all attributes on the type, and then invoking a method named "OnExecute" or "OnExecuteAsync" if it exists. /// See <seealso cref="OptionAttribute" />, <seealso cref="ArgumentAttribute" />, /// <seealso cref="HelpOptionAttribute"/>, and <seealso cref="VersionOptionAttribute"/>. /// </summary> /// <param name="context">The execution context.</param> /// <typeparam name="TApp">A type that should be bound to the arguments.</typeparam> /// <exception cref="InvalidOperationException">Thrown when attributes are incorrectly configured.</exception> /// <returns>The process exit code</returns> public static Task <int> ExecuteAsync <TApp>(CommandLineContext context) where TApp : class => Task.FromResult(Execute <TApp>(context));
public ScanCommand(CommandLineContext context) { _context = context; }
private ValidationResult OnValidate(ValidationContext context, CommandLineContext appContext) { return(new ValidationResult("Failed")); }
public GenerateQueryCommand(CommandLineContext context) { _context = context; }