From d697ef038d2c851ccb74e9c08e7b382151dfce36 Mon Sep 17 00:00:00 2001 From: mpeterv Date: Sun, 2 Mar 2014 14:44:55 +0400 Subject: [PATCH] Updated Readme --- README.md | 767 +----------------------------------------------------- 1 file changed, 14 insertions(+), 753 deletions(-) diff --git a/README.md b/README.md index 9ba3852..0bf5fff 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,14 @@ argparse is a feature-rich command line parser for Lua inspired by argparse for Python. +## Contents + +* [Status](#status) +* [Installation](#installation) +* [Tutorial](#tutorial) +* [Testing](#testing) +* [License](#license) + ## Status Almost everything is implemented, and a WIP version will be available soon. @@ -46,762 +54,15 @@ $ luarocks install /path/to/argparse/rockspec Download `/src/argparse.lua` file and put it into the directory for libraries or your working directory. Install 30log using luarocks or manually download `30log.lua` file from [30log repo](https://github.com/Yonaba/30log). + ## Tutorial -### Creating a parser - -The module is a function which, when called, creates an instance of the Parser class. - -```lua --- script.lua -local argparse = require "argparse" -local parser = argparse() -``` - -`parser` is now an empty parser which does not recognize any command line arguments or options. - -### Parsing command line arguments - -`:parse([cmdline])` method of the Parser class returns a table with processed data from the command line or `cmdline` array. - -```lua -local args = parser:parse() -for k, v in pairs(args) do print(k, v) end -``` - -When executed, this script prints nothing because the parser is empty and no command line arguments were supplied. - -```bash -$ lua script.lua -``` - -#### Error handling - -If the provided command line arguments are not recognized by the parser, it will print an error message and call `os.exit(1)`. - -```bash -$ lua script.lua foo -``` - -``` -Usage: script.lua [-h] - -Error: too many arguments -``` - -If halting the program is undesirable, `:pparse([cmdline])` method should be used. It returns boolean flag indicating success of parsing and result or error message. - -An error can raised manually using `:error()` method. - -```lua -parser:error("manual argument validation failed") -``` - -``` -Usage: script.lua [-h] - -Error: manual argument validation failed -``` - -#### Help option - -As the automatically generated usage message states, there is a help option `-h` added to any parser by default. - -When a help option is used, parser will print a help message and call `os.exit(0)`. - -```bash -$ lua script.lua -h -``` - -``` -Usage: script.lua [-h] - -Options: - -h, --help Show this help message and exit. -``` - -#### Typo autocorrection - -When an option is not recognized by the parser, but there is an option with a similar name, a suggestion is automatically added to the error message. - -```bash -$ lua script.lua --hepl -``` - -``` -Usage: script.lua [-h] - -Error: unknown option '--hepl' -Did you mean '--help'? -``` - -### Configuring parser - -Parsers have several fields affecting their behavior. For example, `description` field sets the text to be displayed in the help message between the usage message and the listings of options and arguments. Another is `name`, which overwrites the name of the program which is used in the usage message(default value is inferred from command line arguments). - -There are several ways to set fields. The first is to call a parser with a table containing some fields. - -```lua -local parser = argparse() { - name = "script", - description = "A testing script. " -} -``` - -The second is to chain setter methods of Parser object. - -```lua -local parser = argparse() - :name "script" - :description "A testing script. " -``` - -As a special case, `name` field can be set by calling a parser with a string. - -```lua -local parser = argparse "script" - :description "A testing script. " -``` - -### Adding arguments - -Positional arguments can be added using `:argument()` method. It returns an Argument instance, which can be configured in the same way as Parsers. The `name` field is required. - -```lua -parser:argument "input" -- sugar for :argument():name "input" -``` - -```bash -$ lua script.lua foo -``` - -``` -input foo -``` - -The data passed to the argument is stored in the result table at index `input` because it is the argument's name. The index can be changed using `target` field. - -#### Setting number of arguments - -`args` field sets how many command line arguments the argument consumes. Its value is interpreted as follows: - -Value | Interpretation ---- | --- -Number `N` | Exactly `N` arguments -String `"A-B"`, where `A` and `B` are numbers | From `A` to `B` arguments -String `"N+"`, where `N` is a number | `N` or more arguments -String `"?"` | An optional argument -String `"*"` | Any number of arguments -String `"+"` | At least one argument - -If more than one argument can be passed, a table is used to store the data. - -```lua -parser:argument "pair" - :args(2) - :description "A pair of arguments. " -parser:argument "optional" - :args "?" - :description "An optional argument. " -``` - -```bash -$ lua script.lua foo bar -``` - -``` -pair {foo, bar} -``` - -```bash -$ lua script2.lua foo bar baz -``` - -``` -pair {foo, bar} -optional baz -``` - -### Adding options - -Options can be added using `:option()` method. It returns an Option instance, which can be configured in the same way as Parsers. The `name` field is required. An option can have several aliases, which can be set using `aliases` field or by continuously calling the Option instance. - -```lua -parser:option "-f" "--from" -``` - -```bash -$ lua script.lua --from there -$ lua script.lua --from=there -$ lua script.lua -f there -$ lua script.lua -fthere -``` - -``` -from there -``` - -For an option, default index used to store data is the first 'long' alias (an alias starting with two control characters) or just the first alias, without control characters. - -Sometimes it is useful to explicitly set the index using `target` field to improve readability of help messages. - -```lua -parser:option "-f" "--from" - :target "server" -``` - -```bash -$ lua script.lua --help -``` - -``` -Usage: script.lua [-f ] [-h] - -Options: - -f , --from - -h, --help Show this help message and exit. -``` - -```bash -$ lua script.lua --from there -``` - -``` -server there -``` - -#### Flags - -Flags are almost identical to options, except that they don't take an argument by default. - -```lua -parser:flag "-q" "--quiet" -``` - -```bash -$ lua script.lua -q -``` - -``` -quiet true -``` - -#### Control characters - -The first characters of all aliases of all options of a parser form the set of control characters, used to distinguish options from arguments. Typically the set only consists of a hyphen. - -#### Setting number of arguments - -Just as arguments, options can be configured to take several command line arguments. - -```lua -parser:option "--pair" - :args(2) -parser:option "--optional" - :args "?" -``` - -```bash -$ lua script3.lua --pair foo bar -``` - -``` -pair {foo, bar} -``` - -```bash -$ lua script3.lua --pair foo bar --optional -``` - -``` -pair {foo, bar} -optional {} -``` - -```bash -$ lua script3.lua --optional=baz -``` - -``` -optional {baz} -``` - -Note that the data passed to `optional` option is stored in an array. That is necessary to distinguish whether the option was invoked without an argument or it was not invoked at all. - -#### Setting number of invocations - -For options, it is possible to control how many times they can be used. argparse uses `count` field to set how many times an option can be invoked. The value of the field is interpreted in the same way `args` is. - -```lua -parser:option "-e" "--exclude" - :count "*" -``` - -```bash -$ lua script.lua -eFOO -eBAR -``` - -``` -exclude {FOO, BAR} -``` - -If an option can be used more than once and it can consume more than one argument, the data is stored as an array of invocations, each being an array of arguments. - -As a special case, if an option can be used more than once and it consumes no arguments(e.g. it's a flag), than the number of invocations is stored in associated field of the result table. - -```lua -parser:flag "-v" "--verbose" - :count "0-2" - :target "verbosity" - :description [[Sets verbosity level. --v: Report all warning. --vv: Report all debugging information. ]] -``` - -```bash -$ lua script.lua -vv -``` - -``` -verbosity 2 -``` - -### Commands - -A command is a subparser invoked when its name is passed as an argument. For example, in luarocks CLI `install`, `make`, `build`, etc. are commands. Each command has its own set of arguments and options. - -Commands can be added using `:command()` method. Just as options, commands can have several aliases. - -```lua -parser:command "install" "i" -``` - -If a command it used, `true` is stored in the corresponding field of the result table. - -```bash -$ lua script.lua install -``` - -``` -install true -``` - -A typo will result in an appropriate error message: - -```bash -$ lua script.lua instal -``` - -``` -Usage: script.lua [-h] ... - -Error: unknown command 'instal' -Did you mean 'install'? -``` - -#### Adding elements to commands - -The Command class is a subclass of the Parser class, so all the Parser's methods for adding elements work on commands, too. - -```lua -local install = parser:command "install" -install:argument "rock" -install:option "-f" "--from" -``` - -```bash -$ lua script.lua install foo --from=bar -``` - -``` -install true -rock foo -from bar -``` - -Commands have their own usage and help messages. - -```bash -$ lua script.lua install -``` - -``` -Usage: script.lua install [-f ] [-h] - -Error: too few arguments -``` - -```bash -$ lua script.lua install --help -``` - -``` -Usage: script.lua install [-f ] [-h] - -Arguments: - rock - -Options: - -f , --from - -h, --help Show this help message and exit. -``` - -#### Making a command optional - -By default, if a parser has commands, using one of them is obligatory. - -```lua -local parser = argparse() -parser:command "install" -``` - -```bash -$ lua script.lua -``` - -``` -Usage: script.lua [-h] ... - -Error: a command is required -``` - -This can be changed using the `require_command` field. - -```lua -local parser = argparse() - :require_command(false) -parser:command "install" -``` - -Now not using a command is not an error: - -```bash -$ lua script.lua -``` - -produces nothing. - -### Default values - -For elements such as arguments and options, if `default` field is set, its value is stored in case the element was not used. - -```lua -parser:option "-o" "--output" - :default "a.out" -``` - -```bash -$ lua script.lua -``` - -``` -output a.out -``` - -The existence of a default value is reflected in help message. - -```bash -$ lua script.lua --help -``` - -``` -Usage: script [-o ] [-h] - -Options: - -o , --output - default: a.out - -h, --help Show this help message and exit. -``` - -Note that invocation without required arguments is still an error. - -```bash -$ lua script.lua -o -``` - -``` -Usage: script [-o ] [-h] - -Error: too few arguments -``` - -#### Default mode - -The `defmode` field regulates how argparse should use the default value of an element. - -If `defmode` contains `"u"`(for `unused`), the default value will be automatically passed to the element if it was not invoked at all. This is the default behavior. - -If `defmode` contains `"a"`(for `argument`), the default value will be automatically passed to the element if not enough arguments were passed, or not enough invocations were made. - -Consider the difference: - -``` -parser:option "-o" - :default "a.out" -parser:option "-p" - :default "password" - :defmode "arg" -``` - -```bash -$ lua script.lua -h -``` - -``` -Usage: script [-o ] [-p [

]] [-h] - -Options: - -o default: a.out - -p [

] default: password - -h, --help Show this help message and exit. -``` - -```bash -$ lua script.lua -``` - -``` -o a.out -``` - -```bash -$ lua script.lua -p -``` - -``` -o a.out -p password -``` - -```bash -$ lua script.lua -o -``` - -``` -Usage: script [-o ] [-p [

]] [-h] - -Error: too few arguments -``` - -### Converters - -argparse can perform automatic validation and conversion on arguments. If `convert` field of an element is a function, it will be applied to all the arguments passed to it. The function should return `nil` and, optionally, an error message if conversion failed. Standard `tonumber` and `io.open` functions work exactly like that. - -```lua -parser:argument "input" - :convert(io.open) -parser:option "-t" "--times" - :convert(tonumber) -``` - -```bash -$ lua script.lua foo.txt -t5 -``` - -``` -input file (0xaddress) -times 5 (number) -``` - -```bash -$ lua script.lua nonexistent.txt -``` - -``` -Usage: script.lua [-t ] [-h] - -Error: nonexistent.txt: No such file or directory -``` - -```bash -$ lua script.lua foo.txt --times=many -``` - -``` -Usage: script.lua [-t ] [-h] - -Error: malformed argument 'many' -``` - -#### Table converters - -If `convert` field of an element contains a table, arguments passed to it will be used as keys. If a key is missing, an error is raised. - -```lua -parser:argument "choice" - :convert { - foo = "Something foo-related", - bar = "Something bar-related" - } -``` - -```bash -$ lua script.lua bar -``` - -``` -choice Something bar-related -``` - -```bash -$ lua script.lua baz -``` - -``` -Usage: script.lua [-h] - -Error: malformed argument 'baz' -``` - -### Actions - -argparse can trigger a callback when an option or a command is encountered. The callback can be set using `action` field. Actions are called regardless of whether the rest of command line arguments are correct. - -```lua -parser:flag "-v" "--version" - :description "Show version info and exit. " - :action(function() - print("script.lua v1.0.0") - os.exit(0) - end) -``` - -```bash -$ lua script.lua -v -``` - -``` -script.lua v1.0.0 -``` - -This example would work even if the script had mandatory arguments. - -### Miscellaneous - -#### Overwriting default help option - -If the field `add_help` of a parser is set to false, no help option will be added to it. Otherwise, the value of the field will be used to configure it. - -```lua -local parser = argparse() - :add_help {name = "/?"} -``` - -```bash -$ lua script.lua /? -``` - -``` -Usage: script.lua [/?] - -Options: - /? Show this help message and exit. -``` - -#### Configuring usage and help messages - -##### Description and epilog - -The value of `description` field of a parser is placed between the usage message and the argument list in the help message. - -The value of `epilog` field is appended to the help message. - -```lua -local parser = argparse "script" - :description "A description. " - :epilog "An epilog. " -``` - -```bash -$ lua script.lua --help -``` - -``` -Usage: script [-h] - -A description. - -Options: - -h, --help Show this help message and exit. - -An epilog. -``` - -##### Argument placeholder - -For options and arguments, `argname` field controls the placeholder for the argument in the usage message. - -```lua -parser:option "-f" "--from" - :argname "" -``` - -```bash -$ lua script.lua --help -``` - -``` -Usage: script.lua [-f ] [-h] - -Options: - -f , --from - -h, --help Show this help message and exit. -``` - -#### Prohibiting overuse of options - -By default, if an option is invoked too many times, latest invocations overwrite the data passed earlier. - -```lua -parser:option "-o" "--output" -``` - -```bash -$ lua script.lua -oFOO -oBAR -``` - -``` -output BAR -``` - -Set the `overwrite` field to false to prohibit this behavior. - -```lua -parser:option "-o" "--output" - :overwrite(false) -``` - -```bash -$ lua script.lua -oFOO -oBAR -``` - -``` -Usage: script.lua [-o ] [-h] - -Error: option '-o' must be used at most 1 time -``` - -#### Generating usage and help messages - -`:get_help()` and `get_usage:()` methods of Parser and Command classes can be used to generate their help and usage messages. - -#### Parsing algorithm - -argparse interprets command-line arguments in the following way: - -Argument | Interpretation ---- | --- -`foo` | An argument of an option or a positional argument. -`--foo` | An option. -`--foo=bar` | An option and its argument. The option must be able to take arguments. -`-f` | An option. -`-abcdef` | Letters are interpreted as options. If one of them can take an argument, the rest of the string is passed to it. -`--` | The rest of the command-line arguments will be interpreted as positional arguments. - -## Documentation - -The tutorial ~~is~~ will be available in the `doc` directory. If argparse was installed using luarocks 2.1.2 or later, it can be viewed using `luarocks doc argparse` command. +The tutorial is available [online](http://mpeterv.github.io/argparse/) and in the `doc` directory. If argparse was installed using luarocks 2.1.2 or later, it can be viewed using `luarocks doc argparse` command. ## Testing argparse comes with a testing suite located in `spec` directory. [busted](http://olivinelabs.com/busted/) is required for testing, it can be installed using luarocks. Run the tests using `busted spec` command from the argparse folder. + +## License + +argparse is licensed under the same terms as Lua itself(MIT license).