-
Notifications
You must be signed in to change notification settings - Fork 115
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Importing CLI utilities from gerbil-utils
- Loading branch information
Showing
59 changed files
with
30,572 additions
and
29,730 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,251 @@ | ||
# Command Line Argument Parsing | ||
|
||
The `:std/cli/getopt` library provides facilities for command line argument parsing. | ||
|
||
::: tip usage | ||
(import :std/cli/getopt) | ||
::: | ||
|
||
This library used to be available as `:std/getopt` up to Gerbil v0.18, | ||
and is still available under that name for now, but its use is deprecated. | ||
|
||
## Interface | ||
|
||
### getopt | ||
```scheme | ||
(getopt <specifier> ...) | ||
=> <parser> | ||
specifier: | ||
(command id [help: text] <cmd-specifier>) | ||
<cmd-specifier> ... | ||
cmd-specifier: | ||
(flag id short [long]) | ||
(option id short [long] [help: text] [value: proc] [default: value]) | ||
(argument id [help: text] [value: proc]) | ||
(optional-argument id [help: text] [value: proc] [default: value]) | ||
(rest-arguments id [help: text] [value: proc]) | ||
``` | ||
|
||
`getopt` creates a command line parser, which can be used to parse arguments | ||
with `getopt-parse`. | ||
|
||
### getopt-parse | ||
```scheme | ||
(getopt-parse <parser> args) | ||
=> (values cmd-id options) | ||
options | ||
``` | ||
|
||
`getopt-parse` accepts a parser and a list of string arguments and parses | ||
according to the parser specification. If it is parsing a specification with | ||
subcommands, it returns two values, the command id and a hash table with the | ||
parsed options. Otherwise it just returns the hash table with the parsed options. | ||
An exception is raised if parsing the arguments fails. | ||
|
||
### getopt-error? | ||
```scheme | ||
(getopt-error? obj) | ||
=> boolean | ||
``` | ||
|
||
If parsing fails, then a `getopt-error` is raised, which can be guarded with | ||
`getopt-error?`. | ||
|
||
### getopt-display-help | ||
```scheme | ||
(getopt-display-help <tip> program-name [port = (current-output-port)]) | ||
tip: | ||
<getopt-error> | ||
<parser> | ||
<command> | ||
``` | ||
|
||
The procedure `getopt-display-help` can be used to display | ||
a help message for a getopt error according to the argument specification. | ||
|
||
### getopt-display-help-topic | ||
```scheme | ||
(getopt-display-help-topic <parser> topic program-name [port = (current-output-port)]) | ||
``` | ||
|
||
The procedure `getopt-display-help-topic` can be used to display a help page | ||
for a subcommand. | ||
|
||
### getopt? | ||
```scheme | ||
(getopt? obj) | ||
=> boolean | ||
``` | ||
|
||
Returns true if the object is a getopt parser | ||
|
||
### getopt-object? | ||
```scheme | ||
(getopt-object? obj) | ||
=> boolean | ||
``` | ||
|
||
Returns true if the object is a getopt command or command specifier. | ||
|
||
### call-with-getopt | ||
```scheme | ||
(call-with-getopt proc args | ||
program: program | ||
help: (help #f) | ||
exit-on-error: (exit-on-error? #t) | ||
. gopts) | ||
``` | ||
|
||
This shim around getopt parsing eliminates all the repetitive | ||
boilerplate around argument parsing with getopt. | ||
|
||
It creates a getopt parser that parses with options `gopts`, automatically | ||
including a help option or command accordingly. | ||
|
||
It then uses the parser to pare `args`, handling the exceptions and | ||
displayin help accordingly; if `exit-on-error` is true (the default), | ||
then parsing errors will exit the program. | ||
|
||
If the parse succeeds it invokes `proc` with the output of the parse. | ||
|
||
## Example | ||
|
||
For an example, here the a command line parser for the `gxpkg` program: | ||
```scheme | ||
(def (main . args) | ||
(def install-cmd | ||
(command 'install help: "install one or more packages" | ||
(rest-arguments 'pkg help: "package to install"))) | ||
(def uninstall-cmd | ||
(command 'uninstall help: "uninstall one or more packages" | ||
(flag 'force "-f" help: "force uninstall even if there are orphaned dependencies") | ||
(rest-arguments 'pkg help: "package to uninstall"))) | ||
(def update-cmd | ||
(command 'update help: "update one or more packages" | ||
(rest-arguments 'pkg help: "package to update; all for all packages"))) | ||
(def link-cmd | ||
(command 'link help: "link a local development package" | ||
(argument 'pkg help: "package to link") | ||
(argument 'src help: "path to package source directory"))) | ||
(def unlink-cmd | ||
(command 'unlink help: "unlink one or more local development packages" | ||
(flag 'force "-f" help: "force unlink even if there are orphaned dependencies") | ||
(rest-arguments 'pkg help: "package to unlink"))) | ||
(def build-cmd | ||
(command 'build help: "rebuild one or more packages and their dependents" | ||
(rest-arguments 'pkg help: "package to build; all for all packages"))) | ||
(def clean-cmd | ||
(command 'clean help: "clean compilation artefacts from one or more packages" | ||
(rest-arguments 'pkg help: "package to clean"))) | ||
(def list-cmd | ||
(command 'list help: "list installed packages")) | ||
(def retag-cmd | ||
(command 'retag help: "retag installed packages")) | ||
(def search-cmd | ||
(command 'search help: "search the package directory" | ||
(rest-arguments 'keywords help: "keywords to search for"))) | ||
(call-with-getopt gxpkg-main args | ||
program: "gxpkg" | ||
help: "The Gerbil Package Manager" | ||
install-cmd | ||
uninstall-cmd | ||
update-cmd | ||
link-cmd | ||
unlink-cmd | ||
build-cmd | ||
clean-cmd | ||
list-cmd | ||
retag-cmd | ||
search-cmd)) | ||
(def (gxpkg-main cmd opt) | ||
(let-hash opt | ||
(case cmd | ||
((install) | ||
(install-pkgs .pkg)) | ||
((uninstall) | ||
(uninstall-pkgs .pkg .?force)) | ||
((update) | ||
(update-pkgs .pkg)) | ||
((link) | ||
(link-pkg .pkg .src)) | ||
((unlink) | ||
(unlink-pkgs .pkg .?force)) | ||
((build) | ||
(build-pkgs .pkg)) | ||
((clean) | ||
(clean-pkgs .pkg)) | ||
((list) | ||
(list-pkgs)) | ||
((retag) | ||
(retag-pkgs)) | ||
((search) | ||
(search-pkgs .keywords))))) | ||
``` | ||
|
||
|
||
### getopt-parse->function-arguments | ||
```scheme | ||
(getopt-parse->function-arguments getopt h) => list-of-arguments | ||
``` | ||
|
||
This function takes a `getopt` specification and table `h` of arguments | ||
resulting from calling `getopt-parse`, and returns a list of argument | ||
with which to call a Scheme function that has an analogous call convention: | ||
- supplied positional arguments are passed in order | ||
- they are followed by all the rest arguments | ||
- they are followed by the remaining specified keyword arguments. | ||
|
||
Omitted option arguments without default will be omitted. | ||
Omitted option arguments with a default will be included with the default value; | ||
the programmer must ensure that this default value is the same as | ||
the default value from the Scheme function being called, or there will be | ||
a semantic discrepancy between the CLI interface and the underlying Scheme function. | ||
|
||
NB: `h` will be modified in place, removing positional and rest arguments. | ||
Make sure to use `hash-copy` if you want to preserve the original data. | ||
|
||
TODO: add examples | ||
|
||
### call-with-getopt-parse | ||
```scheme | ||
(call-with-getopt-parse gopt hash fun) => results-of-fun | ||
``` | ||
|
||
Given a getopt specification `gopt`, the `hash` resulting from calling | ||
`getopt-parse` on some provided command-line arguments, and a function `fun` | ||
that has a calling convention analogous to that specified by `gopt`, | ||
call the function with arguments that correspond to those provided by `hash`, | ||
as per `getopt-parse->function-arguments`. | ||
|
||
TODO: add examples, discuss abort-on-error behavior, | ||
lack of automatic help, etc. | ||
|
||
### call-with-processed-command-line | ||
```scheme | ||
(call-with-processed-command-line processor command-line function) => results-of-function | ||
``` | ||
|
||
Generic function of three arguments: | ||
- a `processor` that describes a `getopt` specification, | ||
- a `command-line`, list of strings as provided by the invoking process, and | ||
- a `function` to be called with the results of processing the command-line. | ||
|
||
The function is generic in the first argument. | ||
The default method recognizes a `getopt` specification as first argument, | ||
and appropriately calls `getopt-parse` and `call-with-getopt-parse` | ||
to process the command-line. It also recognizes a list as being arguments | ||
to which to apply `getopt` to obtain a specification, | ||
with which to proceed as above. | ||
|
||
You may define more methods, to work with your own variant of `getopt`, | ||
or with innovative ways to incrementally compose `getopt` specifications | ||
e.g. with prototype objects like `gerbil-poo`. | ||
|
||
TODO: add examples, discuss abort-on-error behavior, | ||
lack of automatic help, etc. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
# Multicall Binaries | ||
|
||
The `:std/cli/multicall` module provides facilities to define multicall binaries | ||
the behavior of which differs depending on the name of the binary, | ||
just like the gerbil binary itself, or famously like `busybox`. | ||
|
||
::: tip usage | ||
(import :std/cli/multicall) | ||
::: | ||
|
||
An earlier version of this library used to be available as `:clan/multicall` | ||
in gerbil-utils. | ||
|
||
## Interface | ||
|
||
### current-program | ||
### entry-points | ||
### current-program-string | ||
### entry-point | ||
### getopt-spec | ||
### entry-points-getopt-spec | ||
### register-entry-point | ||
### define-entry-point | ||
### multicall-default | ||
### set-default-entry-point! | ||
### help | ||
### meta | ||
### version | ||
### call-entry-point | ||
### define-multicall-main |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
# Shell Command Support | ||
|
||
The `:std/cli/shell` library provides facilities for working with Unix shell code | ||
|
||
::: tip usage | ||
(import :std/cli/shell) | ||
::: | ||
|
||
An earlier version of this library used to be available as `:clan/shell` | ||
in gerbil-utils. | ||
|
||
## Interface | ||
|
||
### easy-shell-character? | ||
|
||
### needs-shell-escape? | ||
|
||
### escape-shell-token | ||
|
||
### escape-shell-tokens | ||
|
||
### ->envvar |
Oops, something went wrong.