Add UAPI.18: CLI introspection - #223
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.
| -`required_argument`, or | ||
| -`optional_argument`. | ||
|
|
||
| `help` is a string that defines the help text of the option. |
There was a problem hiding this comment.
hmm, you call this "help" here, and "abstract for the verbs. we should figure this out, and stick to the same concept
I've still got adding help stashed, because the command objects describe both the top-level program and verbs (so this can cover subcommands in git's style, something systemd doesn't really do). In this case a short help string for a verb makes sense and abstract and postscript don't.
| `documentation` is an array of string values describing URIs referencing | ||
| documentation for this command, see `man:uri(7)`for a description of valid URIs. |
There was a problem hiding this comment.
As mentioned in systemd/systemd#43152 I really like the style man:foo.sec used there, but this currently clashes with the definitions in man:uri(7). I think this works because man reads the dot as the file suffix. Changing this might be difficult, since it would need an IETF RFC?
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.
| aliases, e.g. for backwards-compatibility. | ||
|
|
||
| `argspec` is an array of argspec objects describing the arguments to the command | ||
| after the name of the command, i.e. `argv` excluding the element with index 0. |
There was a problem hiding this comment.
in the brief version above you suggest the array contains strings, here you write "objects". what is it?
| that should not be larger than 16. | ||
|
|
||
| `documentation` is an array of string values describing URIs referencing | ||
| documentation for this command, see `man:uri(7)`for a description of valid URIs. |
There was a problem hiding this comment.
i think we really shoudl recommend man: and https:// urls, and discourage everything else.
man: urls might not be standard, but rlevant terminals all support them.
There was a problem hiding this comment.
The worked example has got both, I'll leave this open to add the encouragement for man:
| command. If it is empty, it defaults to the value of `name`. | ||
|
|
||
| `type` is a string describing what the argument is. It is either of | ||
| - `argument`, a direct argument to the command, |
There was a problem hiding this comment.
is this supposed to be what gnu getopt() docs call "positional arguments"?
|
|
||
| `type` is a string describing what the argument is. It is either of | ||
| - `argument`, a direct argument to the command, | ||
| - `option`, which is an option from the `options` array of a command, or |
There was a problem hiding this comment.
these are switches, right?
|
|
||
| `optional` is a boolean describing whether an argspec object of type `argument` | ||
| or `verb` must be passed or not. `optional` is ignored for argspec objects of | ||
| type `option`. |
There was a problem hiding this comment.
very confusing that option and optional both exist, and do unrelated things?
maybe rename "option" to "switch"?
| 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?
They are defined as recursive commands. |
ah, i see that now. not sure that's ideal though, because some of the props of commands don't really apply to verbs, do they? dunno, i am a bit unsure about thsi. |
|
During implementation I realized that there should be a way to mark both verbs and options as deprecated. Maybe even commands. EDIT: I'm now using optional 'isDeprecated: true'. |
|
Another RFE: indicate that some part of the description is missing. For example, if options are not described, or helps are excluded to save space, etc. And in the future, if we include a description of how to generate values for an option, that is missing for an option. For example, because the completions should be generated dynamically. |
- add nomenclature preamble - make version array-valued, to capture downstream versions, e.g. $ systemctl --version systemd 261 (261.2-1-arch) - merge options and verbs arrays into arguments array and drop argspec array The argspec array was necessary because options and verbs were treated separately and therefore no order between options, positional arguments and verbs was established. The split was awkward, because of the need to consult multiple arrays in the object referencing each other. Combining all arguments into a single array established a natural ordering. This at least the objects in the arguments array to carry a type, so for consistency everything gets one. - drop group and section for sections - add example - indent JSON to 2 spaces
|
I pushed some changes addressing the above remarks, but after implementing them I mostly rewrote this to get rid of the argspec array. The argspec array was necessary because options and verbs were treated separately and therefore no order between options, positional arguments and verbs was established. The split was awkward, because of the need to consult multiple arrays in the object referencing each other. Combining all arguments into a single array established a natural ordering and makes the information more local. This also gets red of some of the option/optional confusions. Unfortunately it meant that the type from the argspec objections needed to be pushed down, because now objects of different shapes live in the same array. For consistency everything got a type field. I also added a nomenclature section and added a worked example. The latest commit address @keszybz most recent RFE. |
|
given that we are going to release systemd v262 soon, where this is supported, is it time to undraft and stabilize this? |
I think the current version in systemd is not quite what's in this spec at the moment (@keszybz will know best) and there's one or two more things I've not pushed yet, because The introspection stuff is has a note
in the NEWS for 262, so this can still change, but I think releasing the spec is more something for after this stabilizes and becomes useful in systemd. |
|
I think this maps reasonably well to my half-design for APT's declarative command-line parser, but it would be useful to be a bit more explicit about help messages. In my mental model (not fully implemented), I define command help as usage, summary and long description - the pattern we go for being
I can map this to the spec to map usage to One of the things that we likely can't address well here is multi-mode commands, notably we have: And similarly say One thing that could be more strictly defined to be useful is the Finally, option groups are often shared for us by up to 10 verbs, having to repeat ourselves is a bit of an overhead but it's likely not the end of the world. |
| ``` | ||
|
|
||
| where `mediaType` is the fixed string | ||
| `application/vnd.uapi-group.cli-introspection-0` and `commands` is a non-empty |
| `project` is a string describing what this command belongs to. | ||
| This may the package that installed it or the project that produced it. | ||
|
|
||
| `isDeprecated` is a boolean describing whether the command has been |
| "type": "argument" | ||
| "name": "filename", | ||
| "value_name": "FILE", | ||
| "help": "Show this help", |
There was a problem hiding this comment.
This should be something like "filename to operate on", since this is an arg.
|
|
||
| `sections` is an array of string that defines sections in which this option should | ||
| be shown. | ||
| This is only for display-purposes. |
There was a problem hiding this comment.
I think "display purposes" is more usual.
| i.e. an option object may not have names both with and without dashes. | ||
| Options prefixed with a single dash (`-`) are called short options and options | ||
| prefixed with two dashes (`--`) are called long options. | ||
| Short options are usually followed by a single character, |
There was a problem hiding this comment.
"Short options are usually just a single character after the dash"
| prefixed with two dashes (`--`) are called long options. | ||
| Short options are usually followed by a single character, | ||
| whereas long options can be a longer string. | ||
| Short options may be followed by multiple characters, |
There was a problem hiding this comment.
I would rephase this. A single-dash option with a long name is not a short option, but a long option with just one dash ;(
| "+AUDIT", | ||
| "-SELINUX", | ||
| "+APPARMOR", | ||
| "-IMA", | ||
| "+IPE", | ||
| "+SMACK", | ||
| "+SECCOMP", | ||
| "+GCRYPT", | ||
| "+GNUTLS", | ||
| "+OPENSSL", | ||
| "+ACL", | ||
| "+BLKID", | ||
| "+CURL", | ||
| "+ELFUTILS", | ||
| "+FIDO2", | ||
| "+IDN2", | ||
| "+KMOD", | ||
| "+LIBCRYPTSETUP", | ||
| "+LIBCRYPTSETUP", | ||
| "PLUGINS", | ||
| "+LIBFDISK", | ||
| "+PCRE2", | ||
| "+PWQUALITY", | ||
| "+P11KIT", | ||
| "+QRENCODE", | ||
| "+TPM2", | ||
| "+BZIP2", | ||
| "+LZ4", | ||
| "+XZ", | ||
| "+ZLIB", | ||
| "+ZSTD", | ||
| "+BPF", | ||
| "FRAMEWORK", | ||
| "+BTF", | ||
| "+XKBCOMMON", | ||
| "+UTMP", | ||
| "+LIBARCHIVE" |
There was a problem hiding this comment.
In the spec we could trim this to maybe 5 lines. We don't need all the systemd internals here.
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.