Comments (14)
Marking as help wanted. Let me know if you want to tackle one of these and let's define an API shape first.
from commandlineutils.
Is there currently a way to specify required command argument type using builder API?
E.g. I want to add a command argument which will be integer (and possibly be within the range)?
from commandlineutils.
Is there currently a way to specify required command argument type using builder API?
Not yet. This is one of the validators I wanted to add for 2.2. Would definitely accept a PR to add something like IValidationBuilder.Range(int min, int max)
.
from commandlineutils.
from commandlineutils.
I think its a good idea. My current thinking is that this would require implementing a mix of the builder API and the attribute-based command-line parsing. I have ideas in my head about how we could introduce CommandArgument<T>
to make this possible. I'll try to sketch down those ideas in a separate issue to make sure the design would actually work.
from commandlineutils.
from commandlineutils.
Ok, here are my ideas: #37
from commandlineutils.
Hi,
Since I needed that feature recently, I'd like to implement validation of CommandArguments to check whether they are contained in a predefined set of values - e.g. string-arrays or enums.
I will keep track of this in my own fork in https://github.com/peterwurzinger/CommandLineUtils/tree/SetValidation and open a PR when I'm finished.
Regards,
Peter
from commandlineutils.
@peterwurzinger I had started implementing this kind of validation too. I struggled to come up with good API names that I felt communicated well what the validator was doing. Here is what I had so far:
// attributes
class MyOptions
{
[Option]
[Values("low", "normal", "high", IgnoreCase = false)] // IgnoreCase defaults to true
public string Importance { get; }
}
// builder api
var app = new CommandLineApplication();
app.Option("--importance", CommandOptionType.SingleValue)
.Accepts().Values("low", "normal", "high", ignoreCase: false);
// ignoreCase defaults to true
I had also intended on adding support for automatically parsing enum types.
enum Importance
{
Low,
Medium,
High
}
class MyOptions
{
[Option]
public Importance Importance { get; }
}
What do you think? How does this compare with what you've drafted?
from commandlineutils.
@natemcmaster It compares quite well, since your implementation is almost identical to mine in the most parts 😄
I am quite bad at API-naming, since english isn't my first language, but i named the corresponding attribute IsInSetAttribute
to fit to other custom attributes like FileExists
or DirectoryExists
.
To support enum validation I added an inherited attribute named IsInEnumAttribute
which only passes the base-constructor all enum-names of a defined enum type. I don't know if that's the way to go, but it's okay as a first shot imho. I'm only handling string-values at the moment...
My blocking issue, which prevents me from going further, is the ambiguity regarding CommandOption<TValue>
and CommandArgument<TValue>
and how those will affect the general architecture. I'll just write down my thoughts on this in context of validation:
Since (Validation)Attributes can't be generic this leads to the problem that they need to interpret object-typed values as the generic target type of the respective option or argument without having compile time safety. I understand that validation attributes are a first level citizen of this library, but with generic arguments/options there are a two main questions to answer:
- Should attribute based validation be restricted to non-generic validators?
- If not, is there a way to make generic implementations of
IValidator<T>
(which it would need as a consequence of generic options/arguments, imho) easily accessible through attribute-API just like there is the other way round asValidationBuilder.Satisfies<ValidationAttribute>(...)
?
To make that clear I'll give a short example:
class FooValidator<TValue> : IValidator<TValue>
{
//Insert highly complex, generic validation logic here
}
static class ValidationExtensions {
static IValidationBuilder<TValue> Foo<TValue>(this IValidationBuilder<TValue> builder)
{
//The easy part
return builder.Use(new FooValidator<TValue>());
}
}
class FooAttribute : ValidationAttribute
{
override ValidationResult IsValid(object value, ValidationContext validationContext)
{
//Instantiate a generic validator?
}
}
What are your thoughts on this?
from commandlineutils.
It compares quite well, since your implementation is almost identical to mine in the most parts
Ok, if what I proposed works for you, let's go with ValuesAttribute
. I also want to implement binding to enums automatically so we don't need something like EnumAttribute
. You can already specify OptionAttribute on int
, bool
, float
, and IList<T>
properties. Using types other than string implies some validation is required.
My blocking issue, which prevents me from going further, is the ambiguity regarding
CommandOption<TValue>
andCommandArgument<TValue>
I assume you're referring to #37. My current thinking is that conversion from string to TValue will happen first, so ValidationAttribute.IsValid(object value)
would be called only if the parsing is successful. After that, ValidationAttribute implementations can use type checks and pattern matching to do the right thing.
class FooAttribute : ValidationAttribute
{
override ValidationResult IsValid(object value, ValidationContext validationContext)
{
int count;
if (value is int i)
{
count = i;
}
else if (value is string str && !int.TryParse(str, out count))
{
return new ValidationResult("Could not parse value to an integer");
}
return count > 5
? ValidationResult.Success
: new ValidationResult("Value must be greater than 5");
}
}
from commandlineutils.
I've added validators for enums, a set of strings, minlength, max length, file paths, and more. Not planning to add anymore at this point in the 2.2.0 release. If you want another validator built in, open a new issue.
12262e3 - enum validation
f6a7768 - set of strings
4f475f8 - minlength, maxlenght, and regex
b2a8439- file path validators
from commandlineutils.
Hi!
@natemcmaster It would be great to have nullable enums as well. Otherwise I can't figure out if a value was given for an optional parameter.
For example:
enum Importance
{
Low,
Medium,
High
}
class MyOptions
{
[Option]
public Importance? Importance { get; }
}
from commandlineutils.
Never mind. I just figured that I can do something like this:
enum Importance
{
Low,
Medium,
High
}
class MyOptions
{
[Option]
public Importance Importance { get; } = Importance.Medium;
}
I just wanted to be able to set some defaults. Btw, Option attribute could also have a Default property.
This library have that: https://github.com/commandlineparser/commandline
from commandlineutils.
Related Issues (20)
- Documentation error in Validation sample program HOT 2
- Support for use as ConfigurationProvider HOT 3
- Add ResponseFileHandling to CommandLineContext so it can be passed through the static CommandLineApp.Execute HOT 2
- [Question] Unrecognized command or argument handling HOT 2
- Not possible to implement subcommand by using the inheritance method and with ExecuteAsync method HOT 3
- [Question] Trim Unused Code option HOT 5
- Nullable boolean Options aren't supported HOT 1
- [Question] Defining Options in Base Class and using them in derived class HOT 2
- [Question] - TargetInvocationException HOT 2
- Nuget package System.ComponentModel.Annotations V5.0.0 is deprecated HOT 2
- VersionOptionFromAssemblyAttributes - no documentation for template HOT 1
- [Question] Changes to DirectoryExists from 3.1.0 to 4.1.0 HOT 1
- [Question] Syntax of templates HOT 1
- Can I specify hidden options HOT 1
- Trimmed compilation fails with annotations HOT 1
- .NET 8: CommandLineApplication.Execute with unknown command throws `System.InvalidOperationException: Enumeration already finished` HOT 9
- [Question] About Attribute API
- [Question] Is it possible to pass an argument more than one time to build a list ? HOT 1
- Dependencies on .NET 5.0 HOT 2
- [Question] Is it possible to detect breaking changes on Attribute Level HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from commandlineutils.