Comments (10)
As it stands, the implementation admits no distinction between the different names of an argument, other than their ordering. We would have to rework the internals so that additional metadata is associated with each individual name. As mentioned earlier, the requirement that obsolete arguments be hidden from the usage string or emit a warning in stderr seems arbitrary: other users may have different expectations of obsolescence. I think this is really an issue of introducing a third layer of configurability, at the argument name level, where things like usage string visibility or error messaging can be tweaked.
My impression is that all that engineering can be avoided by resorting to duplication of arguments like so:
type Args =
| Group of id:string
| [<Hidden; CustomCommandLine("group")>] Group_Legacy of id:string
let gpLegacy = parseResults.TryGetResult <@ Group_Legacy @>
let gpNew = parseResults.TryGetResult <@ Group @>
match gpLegacy, gpNew with
| Some id, _ ->
warnObsolete "group"
processGroup id
| None, Some new ->
processGroup id
| _ -> ()
I also think that an obsolete attribute on the union case level would be easier to achieve, assuming we agree what obsolete means in this context.
from argu.
The requirement makes sense, but in general the expected behaviour induced by an obsolete argument seems ambiguous: it could hide from the usage string, it could tag obsolete args in the usage string or it could emit a warning in stderr or neither of the above. Since this is not intimately tied to the parsing process per se, I'd rather this got delegated to the argument post-processing stage of each particular application.
from argu.
Perhaps an attribute that takes a enum of possible actions.
from argu.
@eiriktsarpalis can you please mark these issues up-for-grabs with a short description how it could be solved? maybe we can then advertise like crazy on twitter so that someone can fix it. It would be nice to have for Paket transformation
from argu.
Since this is not intimately tied to the parsing process per se, I'd rather this got delegated to the argument post-processing stage of each particular application.
I've been playing with post-processing but it seems I cannot get ahold of the actual strings (e.g. group
vs --group
) to get the argument parsed. Any ideas?
let parser = ArgumentParser.Create<Command>(programName = "paket",
helpTextMessage = sprintf "Paket version %s%sHelp was requested:" paketVersion Environment.NewLine,
errorHandler = new PaketExiter())
let results = parser.ParseCommandLine(raiseOnUsage = true)
let deprecateAdd (p:ParseResults<AddArgs>) =
if p.Equals("foo") then // <-- ???
failwith "deprecated command used"
else p
let doesntmatter = results.PostProcessResults (<@ Add @>, deprecateAdd)
from argu.
Ok, so you need to mark individual names as obsolete. Hmm...
from argu.
Yes, it would be great to have that. The reasoning is that we don't want to break existing command-line-based APIs (at least until Paket 6) but advertise the new parameters. Right now I have something like this:
type AddArgs =
| [<MainCommandAttribute()>][<Mandatory>][<AltCommandLine("nuget")>] NuGet of package_id:string
| [<AltCommandLine([| "-V"; "--version" |])>][<CustomCommandLine("version")>] Version of version:string
| [<AltCommandLine([| "-p"; "--project" |])>][<CustomCommandLine("project")>] Project of name:string
| [<AltCommandLine([| "-g"; "--group" |])>][<CustomCommandLine("group")>] Group of name:string
...
but that makes the help output rather unreadable.
USAGE: paket add [--help] [version <version>] [project <name>] [group <name>] [--force] [--interactive] [--redirects] [--create-new-binding-files] [--clean-redirects]
[--no-install] [--keep-major] [--keep-minor] [--keep-patch] [--touch-affected-refs] <package id>
NUGET:
<package id> NuGet package ID
OPTIONS:
version, -V, --version <version>
package version constraint
project, -p, --project <name>
add the package to a single project only
group, -g, --group <name>
add the package to a group (default: Main group)
...
The first step would be to omit outputting the old style args in the help. Then warnings when old style is used would be great to make tool vendors and users aware of the new syntax.
from argu.
Sounds good! Many thanks for for the pointer in the right direction.
from argu.
Regarding what I obsolete means: it could either mean that the argument was replaced by another one or that the argument has been removed. I assume removal is already handled, unless positional arguments are used:
foo --arg-exists --was-removed a b c
In this case the argument list should probably not include --was-removed
.
In any case either the attribute would need to support some kind of help message or be inspectable.
from argu.
Excellent, I think I have a working solution. Please let me know what you think about the code and the output!
from argu.
Related Issues (20)
- Case insensitivity of command options names HOT 1
- Seems like Argu not works on Fsi 11.0.0.0 for F# 5.0 (VS preview 16.8.0 Preview 3.2) HOT 2
- Consistent handling of numeric decimal separators using invariant culture
- Support union names without underscores HOT 2
- Integration with IConfiguration HOT 9
- feat: subcommand specific help header? HOT 3
- Subcommands without options HOT 4
- Feature idea - Helper function for subcommand field
- Release? HOT 2
- Query: Command line argument character (I.E. "--", "/") HOT 2
- Question: attribute or possibility to customize casing of commands? HOT 2
- How to add an optional boolean flag? HOT 5
- appsetting.json and NET5 HOT 9
- `-h` short option for `--help` HOT 2
- Empty usage prevents line breaks between options HOT 1
- Expose ArguParseException or similar for use within apps HOT 2
- [Query] Is .net7 support for trimmed binaries planned? HOT 3
- ChatGpt4 proposed Argu, but as an ocaml developer, it is really hard to understand the ParseResults<Args> part HOT 3
- Make a main command optional in subcommand
- Have a positional argument as optional with main command HOT 4
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 argu.