{"id":13507610,"url":"https://github.com/jcomellas/getopt","last_synced_at":"2025-05-15T18:04:03.442Z","repository":{"id":684989,"uuid":"328917","full_name":"jcomellas/getopt","owner":"jcomellas","description":"Erlang module to parse command line arguments using the GNU getopt syntax","archived":false,"fork":false,"pushed_at":"2023-10-11T00:05:59.000Z","size":616,"stargazers_count":254,"open_issues_count":7,"forks_count":84,"subscribers_count":14,"default_branch":"master","last_synced_at":"2025-05-03T00:26:53.736Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"http://github.com/jcomellas/getopt","language":"Erlang","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jcomellas.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2009-10-06T20:10:11.000Z","updated_at":"2025-04-23T14:50:15.000Z","dependencies_parsed_at":"2024-06-18T12:29:22.099Z","dependency_job_id":"d71352f7-df39-43dc-8c26-3d20f83c3625","html_url":"https://github.com/jcomellas/getopt","commit_stats":{"total_commits":124,"total_committers":20,"mean_commits":6.2,"dds":0.5080645161290323,"last_synced_commit":"ba1519fcad0820246d0150613eb55f36fbedf368"},"previous_names":[],"tags_count":19,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jcomellas%2Fgetopt","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jcomellas%2Fgetopt/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jcomellas%2Fgetopt/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jcomellas%2Fgetopt/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jcomellas","download_url":"https://codeload.github.com/jcomellas/getopt/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253850768,"owners_count":21973667,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-01T02:00:36.945Z","updated_at":"2025-05-15T18:04:03.421Z","avatar_url":"https://github.com/jcomellas.png","language":"Erlang","funding_links":[],"categories":["Command Line Applications"],"sub_categories":[],"readme":"Getopt for Erlang\n=================\n\nCommand-line parsing module that uses a syntax similar to that of GNU *getopt*.\n\n\nRequirements\n------------\n\nYou should only need a somewhat recent version of Erlang/OTP. The module has\nbeen tested with all versions of Erlang starting with R13B and ending with 20.\n\nYou also need a recent version of [rebar3](http://www.rebar3.org/) in\nthe system path.\n\nInstallation\n------------\n\nTo compile the module you simply run `rebar3 compile`.\n\nTo run the unit tests run `rebar3 eunit`.\n\nTo build the (very) limited documentation run `rebar edoc`.\n\nTo use getopt in your project you can just add it as a dependency in your\n`rebar.config` file in the following way:\n```erlang\n{deps,\n [\n  {getopt, \"1.0.3\"}\n ]\n}\n```\n\n\nUsage\n-----\n\nThe `getopt` module provides four functions:\n\n```erlang\nparse([{Name, Short, Long, ArgSpec, Help}], Args :: string() | [string()]) -\u003e\n    {ok, {Options, NonOptionArgs}} | {error, {Reason, Data}}\n\ntokenize(CmdLine :: string()) -\u003e [string()]\n\nusage([{Name, Short, Long, ArgSpec, Help}], ProgramName :: string()) -\u003e ok\n\nusage([{Name, Short, Long, ArgSpec, Help}], ProgramName :: string(),\n      CmdLineTail :: string()) -\u003e ok\n\nusage([{Name, Short, Long, ArgSpec, Help}], ProgramName :: string(),\n      CmdLineTail :: string(), OptionsTail :: [{string(), string}]) -\u003e ok\n```\n\nThe `parse/2` function receives a list of tuples with the command line option\nspecifications. The type specification for the tuple is:\n\n```erlang\n-type arg_type() :: 'atom' | 'binary' | 'utf8_binary' | 'boolean' | 'float' | 'integer' | 'string'.\n\n-type arg_value() :: atom() | binary() | boolean() | float() | integer() | string().\n\n-type arg_spec() :: arg_type() | {arg_type(), arg_value()} | undefined.\n\n-type option_spec() :: {\n                   Name    :: atom(),\n                   Short   :: char() | undefined,\n                   Long    :: string() | undefined,\n                   ArgSpec :: arg_spec(),\n                   Help    :: string() | undefined\n                  }.\n```\n\nThe elements of the tuple are:\n\n  - `Name`: name of the option.\n  - `Short`: character for the short option (e.g. $i for -i).\n  - `Long`: string for the long option (e.g. \"info\" for --info).\n  - `ArgSpec`: data type and optional default value the argument will be converted to.\n  - `Help`: help message that is shown for the option when `usage/2` is called.\n\ne.g.\n\n```erlang\n{port, $p, \"port\", {integer, 5432}, \"Database server port\"}\n```\n\nThe second parameter receives the list of arguments as passed to the `main/1`\nfunction in escripts or the unparsed command line as a string.\n\nIf the function is successful parsing the command line arguments it will return\na tuple containing the parsed options and the non-option arguments. The options\nwill be represented by a list of key-value pairs with the `Name` of the\noption as *key* and the argument from the command line as *value*. If the option\ndoesn't have an argument, only the atom corresponding to its `Name` will be\nadded to the list of options. For the example given above we could get something\nlike `{port, 5432}`. The non-option arguments are just a list of strings with\nall the arguments that did not have corresponding options.\n\ne.g. Given the following option specifications:\n\n```erlang\nOptSpecList =\n    [\n     {host,    $h,        \"host\",    {string, \"localhost\"}, \"Database server host\"},\n     {port,    $p,        \"port\",    integer,               \"Database server port\"},\n     {dbname,  undefined, \"dbname\",  {string, \"users\"},     \"Database name\"},\n     {xml,     $x,        undefined, undefined,             \"Output data in XML\"},\n     {verbose, $v,        \"verbose\", integer,               \"Verbosity level\"},\n     {file,    undefined, undefined, string,                \"Output file\"}\n    ].\n```\n\nAnd this command line:\n\n```erlang\nArgs = \"-h myhost --port=1000 -x myfile.txt -vvv dummy1 dummy2\"\n```\n\nWhich could also be passed in the format the `main/1` function receives the arguments in escripts:\n\n```erlang\nArgs = [\"-h\", \"myhost\", \"--port=1000\", \"-x\", \"file.txt\", \"-vvv\", \"dummy1\", \"dummy2\"].\n```\n\nThe call to `getopt:parse/2`:\n\n```erlang\ngetopt:parse(OptSpecList, Args).\n```\n\nWill return:\n\n```erlang\n{ok,{[{host,\"myhost\"},\n      {port,1000},\n      xml,\n      {file,\"file.txt\"},\n      {dbname,\"users\"},\n      {verbose,3}],\n     [\"dummy1\",\"dummy2\"]}}\n```\n\nThe `tokenize/1` function will separate a command line string into\ntokens, taking into account whether an argument is single or double\nquoted, a character is escaped or if there are environment variables to\nbe expanded. e.g.:\n\n```erlang\ngetopt:tokenize(\"  --name John\\\\ Smith --path \\\"John's Files\\\" -u ${USER}\").\n```\n\nWill return something like:\n\n```erlang\n[\"--name\",\"John Smith\",\"--path\",\"John's Files\",\"-u\",\"jsmith\"]\n```\n\nThe other functions exported by the `getopt` module (`usage/2`, `usage/3`\nand `usage/4`) are used to show the command line syntax for the program.\nFor example, given the above-mentioned option specifications, the call to\n`getopt:usage/2`:\n\n```erlang\ngetopt:usage(OptSpecList, \"ex1\").\n```\n\nWill show (on *standard_error*):\n\n    Usage: ex1 [-h \u003chost\u003e] [-p \u003cport\u003e] [--dbname \u003cdbname\u003e] [-x] [-v] \u003cfile\u003e\n\n      -h, --host                    Database server host\n      -p, --port                    Database server port\n      --dbname                      Database name\n      -x                            Output data in XML\n      -v                            Verbosity level\n      \u003cfile\u003e                        Output file\n\nThis call to `getopt:usage/3` will add a string after the usage command line:\n\n```erlang\ngetopt:usage(OptSpecList, \"ex1\", \"[var=value ...] [command ...]\").\n```\n\nWill show (on *standard_error*):\n\n    Usage: ex1 [-h \u003chost\u003e] [-p \u003cport\u003e] [--dbname \u003cdbname\u003e] [-x] [-v \u003cverbose\u003e] \u003cfile\u003e [var=value ...] [command ...]\n\n      -h, --host            Database server host\n      -p, --port            Database server port\n      --dbname              Database name\n      -x                    Output data in XML\n      -v, --verbose         Verbosity level\n      \u003cfile\u003e                Output file\n\nWhereas this call to `getopt:usage/3` will also add some lines to the options\nhelp text:\n\n```erlang\ngetopt:usage(OptSpecList, \"ex1\", \"[var=value ...] [command ...]\",\n             [{\"var=value\", \"Variables that will affect the execution (e.g. debug=1)\"},\n              {\"command\",   \"Commands that will be executed (e.g. count)\"}]).\n```\n\nWill show (on *standard_error*):\n\n    Usage: ex1 [-h \u003chost\u003e] [-p \u003cport\u003e] [--dbname \u003cdbname\u003e] [-x] [-v \u003cverbose\u003e] \u003cfile\u003e [var=value ...] [command ...]\n\n      -h, --host            Database server host\n      -p, --port            Database server port\n      --dbname              Database name\n      -x                    Output data in XML\n      -v, --verbose         Verbosity level\n      \u003cfile\u003e                Output file\n      var=value             Variables that will affect the execution (e.g. debug=1)\n      command               Commands that will be executed (e.g. count)\n\n\nCommand-line Syntax\n-------------------\n\nThe syntax supported by the `getopt` module is very similar to that followed\nby GNU programs, which is described [here](http://www.gnu.org/s/libc/manual/html_node/Argument-Syntax.html).\n\nOptions can have both short (single character) and long (string) option names.\n\nA short option can have the following syntax:\n\n    -a         Single option 'a', no argument or implicit boolean argument\n    -a foo     Single option 'a', argument \"foo\"\n    -afoo      Single option 'a', argument \"foo\"\n    -abc       Multiple options: 'a'; 'b'; 'c'\n    -bcafoo    Multiple options: 'b'; 'c'; 'a' with argument \"foo\"\n    -aaa       Multiple repetitions of option 'a'\n\nA long option can have the following syntax:\n\n    --foo      Single option 'foo', no argument\n    --foo=bar  Single option 'foo', argument \"bar\"\n    --foo bar  Single option 'foo', argument \"bar\"\n\n\nArgument Types\n--------------\n\nThe arguments allowed for options are: *atom*; *binary*; *utf8_binary*; *boolean*;\n*float*; *integer*; *string*.\nThe `getopt` module checks every argument to see if it can be converted to its\ncorrect type.\n\nIn the case of boolean arguments, the following values (in lower or\nupper case) are considered `true`: *true*; *t*; *yes*; *y*; *on*; *enabled*; *1*.\nThese ones are considered `false`: *false*; *f*; *no*; *n*; *off*; *disabled*; *0*.\n\nNumeric arguments can only be negative when passed as part of an assignment expression.\n\ne.g. `--increment=-100` is a valid expression; whereas `--increment -100` is invalid\n\nArguments of `utf8_binary` type allow proper binary encoding of arguments containing\ncode points greater than 255. The resulting value is a normalized UTF-8 binary.\n\nAs of Erlang/20, `standard_error` device has `unicode` option set to `false`.\nIt prevents correct printing of usage for arguments containing unicode\nbinaries/strings as default values. To fix this, one needs to enable unicode:\n\n```erlang\nio:setopts(standard_error, [{unicode, true}]).\n```\n\n\nImplicit Arguments\n------------------\n\nThe arguments for options with the *boolean* and *integer* data types can sometimes\nbe omitted. In those cases the value assigned to the option is *true* for *boolean*\narguments and *1* for integer arguments.\n\n\nMultiple Repetitions\n--------------------\n\nAn option can be repeated several times, in which case there will be multiple\nappearances of the option in the resulting list. The only exceptions are short\noptions with integer arguments. In that particular case, each appearance of\nthe short option within a single command line argument will increment the\nnumber that will be returned for that specific option.\n\ne.g. Given an option specification list with the following format:\n\n```erlang\nOptSpecList =\n    [\n     {define,  $D, \"define\",  string,  \"Define a variable\"},\n     {verbose, $v, \"verbose\", integer, \"Verbosity level\"}\n    ].\n```\n\nThe following invocation:\n\n```erlang\ngetopt:parse(OptSpecList, \"-DFOO -DVAR1=VAL1 -DBAR --verbose --verbose=3 -v -vvvv dummy\").\n```\n\nwould return:\n\n```erlang\n{ok,{[{define,\"FOO\"}, {define,\"VAR1=VAL1\"}, {define,\"BAR\"},\n      {verbose,1}, {verbose,3}, {verbose,1}, {verbose,4}],\n     [\"dummy\"]}}\n```\n\n\nPositional Options\n------------------\n\nWe can also have options with neither short nor long option names. In this case,\nthe options will be taken according to their position in the option specification\nlist passed to `getopt:/parse2`.\n\nFor example, with the following option specifications:\n\n```erlang\nOptSpecList =\n    [\n     {xml,         $x,        \"xml\",     undefined, \"Output data as XML\"},\n     {dbname,      undefined, undefined, string,    \"Database name\"},\n     {output_file, undefined, undefined, string,    \"File where the data will be saved to\"}\n    ].\n```\n\nThis call to `getopt:parse/2`:\n\n```erlang\ngetopt:parse(OptSpecList, \"-x mydb file.out dummy dummy\").\n```\n\nWill return:\n\n```erlang\n{ok,{[xml,{dbname,\"mydb\"},{output_file,\"file.out\"}],\n     [\"dummy\",\"dummy\"]}}\n```\n\n\nOption Terminators\n------------------\n\nThe string `--` is considered an option terminator. This means that all the\ncommand-line arguments after it are considered non-option arguments and will be\nreturned without being evaluated even if they follow the *getopt* syntax.\n\ne.g. This invocation using the first option specification list in the document:\n\n```erlang\ngetopt:parse(OptSpecList, \"-h myhost -p 1000 -- --dbname mydb dummy\").\n```\n\nwill return:\n\n```erlang\n{ok,{[{host,\"myhost\"}, {port,1000},{dbname,\"users\"}],\n     [\"--dbname\",\"mydb\",\"dummy\"]}}\n```\n\nNotice that the *dbname* option was assigned the value `users` instead of `mydb`.\nThis happens because the option terminator prevented *getopt* from evaluating it\nand the default value was assigned to it.\n\n\nNon-option Arguments\n--------------------\n\nThe single `-` character is always considered as a non-option argument.\n\ne.g. This invocation using the specification list from the previous example:\n\n```erlang\ngetopt:parse(OptSpecList, \"-h myhost -p 1000 - --dbname mydb dummy\").\n```\n\nwill return:\n\n```erlang\n{ok,{[{host,\"myhost\"}, {port,1000}, {dbname,\"mydb\"}],\n     [\"-\",\"dummy\"]}}\n```\n\n\nArguments with embedded whitespace\n----------------------------------\n\nArguments that have embedded whitespace have to be quoted with either\nsingle or double quotes to be considered as a single\nargument.\n\n\ne.g. Given an option specification list with the following format:\n\n```erlang\nOptSpecList =\n    [\n     {define,  $D, \"define\",  string,  \"Define a variable\"},\n     {user,    $u, \"user\",    string,  \"User name\"}\n    ].\n```\n\nThe following invocation:\n\n```erlang\ngetopt:parse(OptSpecList,\n             \"-D'FOO=VAR 123' --define \\\"VAR WITH SPACES\\\" -u\\\"my user name\\\"\").\n```\n\nwould return:\n\n```erlang\n{ok,{[{define,\"FOO=VAR 123\"},\n      {define,\"VAR WITH SPACES\"},\n      {user,\"my user name\"}],\n     []}}\n```\n\nWhen parsing a command line with unclosed quotes the last argument\nwill be a single string starting at the position where the last quote\nwas entered.\n\ne.g. The following invocation:\n\n```erlang\ngetopt:parse(OptSpecList, \"--user ' my user ' \\\"argument with unclosed quotes\").\n```\n\nwould return:\n\n```erlang\n{ok,{[{user,\" my user \"}],\n     [\"argument with unclosed quotes\"]}}\n```\n\n\nEnvironment variable expansion\n------------------------------\n\n`getopt:parse/2` will expand environment variables when used with a command\nline that is passed as a single string. The formats that are supported\nfor environment variable expansion are:\n\n  - $VAR (simple Unix/bash format)\n  - ${VAR} (full Unix/bash format)\n  - %VAR% (Windows format)\n\nIf a variable is not present in the environment it will not be\nexpanded. Variables can be expanded within double-quoted and free\narguments. *getopt* will not expand environment variables within\nsingle-quoted arguments.\n\ne.g. Given the following option specification list:\n\n```erlang\nOptSpecList =\n    [\n     {path,    $p, \"path\",    string,  \"File path\"}\n    ].\n```\n\nThe following invocation:\n\n```erlang\ngetopt:parse(OptSpecList, \"--path ${PATH} $NONEXISTENT_DUMMY_VAR\").\n```\n\nwould return (depending on the value of your PATH variable) something like:\n\n```erlang\n{ok,{[{path, \"/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\"}],\n     [\"$NONEXISTENT_DUMMY_VAR\"]}}\n```\n\nCurrently, *getopt* does not perform wildcard expansion of file paths.\n\n\nEscaping arguments\n==================\n\nAny character can be escaped by prepending the \\ (backslash) character\nto it.\n\ne.g.\n\n```erlang\ngetopt:parse(OptSpecList, \"--path /john\\\\'s\\\\ files dummy\").\n```\n\nWill return:\n\n```erlang\n{ok,{[{path,\"/john's files\"}],[\"dummy\"]}}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjcomellas%2Fgetopt","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjcomellas%2Fgetopt","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjcomellas%2Fgetopt/lists"}