Conversation
| "version": "myversion", | ||
| "features": ["feature1", "feature2", …] | ||
| "abstract": ["paragraph1", "paragraph2", …], | ||
| "postscript": ["paragraph1", "paragraph2", …], |
There was a problem hiding this comment.
i think we should find a better name for "footer", as that indicates location where to print that, not the category of the text it contains.
Changed it to postscript, but I'm open to other things.
There was a problem hiding this comment.
How about epilog and prolog? The script naming seems quite confusing in this context
There was a problem hiding this comment.
Maybe "header" and "footer"? Sounds more down-to-earth.
keszybz
left a comment
There was a problem hiding this comment.
What about using semantic breaks? I think it'd also make making review comment easier.
There should be a complete example, or maybe even more than one.
| this option may not be called together with. | ||
|
|
||
| `values` is an array of *value objects* describing the values this option may | ||
| take. Value objects are described in a section below. |
There was a problem hiding this comment.
maybe make clear that absence or null of this means that the syntax/dictionary of the values is left open
There was a problem hiding this comment.
I added a formulation regarding this. PTAL whether the intent "this is some arbitrary blob we don't say anything about" comes across.
|
verb objects are not defined yet, but i guess you know that |
| `verbs` are command objects that describe a program's verbs, also called | ||
| subcommands. Verbs may recursively define further verbs up to a maximum depth | ||
| that should not be larger than 16. |
There was a problem hiding this comment.
Should verbs have their own features and version and project fields? Maybe say that those are not allowed except at the top level?
There was a problem hiding this comment.
I think it makes sense for them to have their own, e.g. git just accepts everything as a verb that's git-foo and there are third-party projects hooking into that and providing git subcommands. In that sense I think it makes sense to have this, since a top-level command that uses such an extension mechanism could still generate a global CLI introspection by calling --introspect-cli (or similar) on all of its extensions.
They are defined as recursive commands. |
That is true, I still have a few outstanding things that need typing up:
Happy to clarify this if this is not obvious as it might be lost among the discussion here (and also in the PR by @keszybz that is open on this PR in my fork of the repo), but the schema is recursive, so a command can have commands as arguments, this is the intended mechanism to capture subcommands like git does them. I think I'll try to to (a subset) of ip as another example, as that is a sufficiently complex one to stress test this.
Yeah, I'm in that boat as well. :) This is mainly a difference of taste, for systemd tooling all options live in a single namespace
For
That is intended to be captured by the |
so my understanding is that the ability to have commands objects as one type of arguments in command objects is what open this up. i.e. the command object "ip" has a command object called "address" as parameter, which has a command object "show" as parameter, and so on. but honestly, we should play around with this, and see if we can actually model a semi-complex real-life project's cmdline that follows this style with this model. just because i think it works it doesn't mean it actually does ;-) |
this is not specific to systemd btw. it's a property of glibc getopt/getopt_long, which we just inherited (and which i think makes sense). stupidly, getopt/getop_long on bsd and musl don't do that. but a while back we stopped using libc-provided getopt_long and since then actually expose identical behaviour on glibc and musl. |
so i guess we could fundamentally model the gst-launch ototh maybe this would become too complex, and we should maybe not model this from day 1? |
|
oh, one major think we should add to the spec i think: this describes the json document, but doesn't actually say how to get it. i.e. systemd's tools currently expose "--introspect-cli" for this, in all our tools. I think we should make that official, i.e. and suggest that any tool should dump its introspection that way if it supports introspection. and while we are at it, maybe we should also recommend file suffix to use? in #213 i used (i sense we might eventually see generators that use a json file as input and generate a parser from it, hence we should recommend a way to name these files from day one? |
We had both "cli" and "command" that described the same concept. Let's use "command" as the primary name, since that is what is used in the JSON. "Command line interface" is mentioned once as an explanation. This is needed, since "cli-introspection" is present in the name of the format and mediaType. Rename "optional arguments" to just "options". The problem with the old name is that arguments may also be optional, in the sense of being present or not. And then the naming becomes *exteremely* confusing. We now have "options" and "positional arguments". This is the common naming that is widely used. The description of splitting is reworked to say that the program received already-split arguments. I think this was a logical error in the previous text, since programs on Linux do not do splitting of args, it is handled by the caller. (Windows is different, but we're not trying to describe Windows programs. If we wanted to, we'd need to describe commandline splitting.) The array of strings received by the program is called an "argument array". And the items in it are "arguments". Call the whole program "program". "Binary" is a bad name because it implies compiled programs. Call the thing that is the thing after the option a "value". Previously, the name "argument" was reused, but that makes everything very confusing. Since "argument" was renamed to "value", the field is also renamed, so an option has "value":"required|optional|no", which I think is much nicer. It also matches "valueName" nicely. For postional args, I changed the awkward "argument=required|optional" to "isRequired". The default is false, so this can be omitted in most cases. (Just "required" would be another option. But the variant with "is" matches "isDeprecated".) Also, fixed some minor grammar and markup issues. Removed some parts of definitions that duplicate nearby text. I moved the description of nesting to a separate Limits subsection. We'll want to put limits on the length of everything, e.g. strings and arrays, so having a single section to describe all of that will be easier to manage.
Co-authored-by: Jörg Behrmann <behrmann@physik.fu-berlin.de>
I think the quotes will make the rendered text easier to read.
Yes I think that would be great.
Currently the
I personally find those uppercase extensions quite ugly because they are used effectively nowhere else. I'd rather see
Hm, most people I know and work with have a lot of reservations against code generators, I think the other way around will be more likely. However, I work mostly with higher level languages like Python, Rust and JS where introspection is a lot simpler/more powerful and things are done the other way 'round (generate specs from the code). Another thing that might be worth taking a look into is to specify this as a JSON schema |
| This output can be used, | ||
| among other things, | ||
| to check whether a program has a given option or to automatically generate | ||
| command-line completion for different shells. |
| Further names can be added as aliases, | ||
| e.g. for backward compatibility. | ||
|
|
||
| `version` is a an array of strings describing the version of the program. |
There was a problem hiding this comment.
Why is this not plural? The rest seems to be?
| "valueName": "", | ||
| "sections": [""], | ||
| "values": [<value object>], | ||
| "isDeprecated": false |
There was a problem hiding this comment.
Do you want to encode if an option can be repeated? Or can pass multiple of? For example:
podman allows passing multiple volumes
The idea is to use it as a handle for grouping in synopsis generation.
I'd say that this is out of scope for now, but I think this could be added later, e.g. by a new |
| `continueWith` is a string that if set to a non-empty value describes | ||
| a different program whose command line introspection should be used for subsequent arguments. |
There was a problem hiding this comment.
I don't think this is generic enough. Quite often the following parts are an arbitrary command, so we don't know the command name.
There was a problem hiding this comment.
Yes, this would only know if you know what comes afterwards now, as we do for mkosi vm, we would need something like continueWithFirst that looks at the next word?
|
I think one thing that would likely help this is a PoC that looks like https://docs.rs/clap_complete/latest/clap_complete/ but generates this instead. There's a ton of Rust CLI binaries, and clap is quite expressive, and some of the corner cases there would likely show up in trying to map those to this. |
|
(Sorry, misclick on the closing obviously) |

This is a draft that @keszybz based his work in systemd/systemd#43152 on (with a few typos) fixed. A few commits have been put on top addressing a few things that where found during the review of that PR already and that were commented on behrmann@e7911dc#comments. It also adds what's currently pending in systemd/systemd#43430.
The idea is to have a JSON schema that describes the full output (or a superset of that) that one would get from a binary via
--helpin a structured way. The idea is that this would allow to automatically generate command line completion from this, which we have already done in mkosi, but would also allow other things, like checking for features of a command line program without resorting to brittle parsing of help output.This is still very much work in progress.