Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Return the help output structured if requested. #42

Merged
merged 11 commits into from
Nov 22, 2023
2 changes: 1 addition & 1 deletion examples/main.toit
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ main arguments:
create-status-command -> cli.Command:
return cli.Command "status"
--help="Shows the status of the fleet:"
--help="Shows the status of the fleet."
--options=[
cli.OptionInt "max-lines" --help="Maximum number of lines to show." --default=10,
]
Expand Down
63 changes: 56 additions & 7 deletions src/help-generator_.toit
Original file line number Diff line number Diff line change
Expand Up @@ -33,18 +33,67 @@ help-command_ path/List arguments/List --invoked-command/string --ui/Ui:
command = subcommand
path.add command

print-help_ path --invoked-command=invoked-command --ui=ui
emit-help_ path --invoked-command=invoked-command --ui=ui

/**
Prints the help for the given command.
Emits the help for the given command.

The command is identified by the $path where the command is the last element.
*/
print-help_ path --invoked-command/string --ui/Ui:
generator := HelpGenerator path --invoked-command=invoked-command
generator.build-all
help := generator.to-string
ui.print help
emit-help_ path/List --invoked-command/string --ui/Ui:
ui.do --kind=Ui.RESULT: | printer/Printer |
printer.emit-structured
--json=: build-json-help_ path --invoked-command=invoked-command
--stdout=:
generator := HelpGenerator path --invoked-command=invoked-command
generator.build-all
help := generator.to-string
printer.emit help

build-json-help_ path/List --invoked-command/string -> Map:

extract-options := : | command/Command out-map/Map |
options := command.options_.filter: | option/Option | not option.is-hidden
command.options_.do: | option/Option |
if not out-map.contains option.name:
default := option.default
if default != null and default is not bool and default is not num and default is not string and
default is not List and default is not Map:
default = "$default"
json-option := {
"type": option.type,
"is-flag": option.is-flag,
"is-multi": option.is-multi,
"is-required": option.is-required,
}
if not option.is-required: json-option["default"] = default
if option.help: json-option["help"] = option.help
if option.short-name: json-option["short-name"] = option.short-name
out-map[option.name] = json-option
out-map

command/Command := path.last

global-options := {:}
for i := path.size - 2; i >= 0; i--:
parent-command := path[i]
extract-options.call parent-command global-options

json-examples := command.examples_.map: | example/Example | {
"description": example.description,
"arguments": example.arguments,
"global-priority": example.global-priority,
}

return {
"name": command.name,
"path": path.map: | command/Command | command.name,
"help": command.help_,
"aliases": command.aliases_,
"options": extract-options.call command {:},
"global-options": global-options,
"examples": json-examples,
}

/**
Generates the help for a command.
Expand Down