jcomellas / getopt Goto Github PK
View Code? Open in Web Editor NEWErlang module to parse command line arguments using the GNU getopt syntax
Home Page: http://github.com/jcomellas/getopt
License: BSD 3-Clause "New" or "Revised" License
Erlang module to parse command line arguments using the GNU getopt syntax
Home Page: http://github.com/jcomellas/getopt
License: BSD 3-Clause "New" or "Revised" License
The use case is as follows:
Usage: program -d -v ... <File>
Allowed should only be:
$ program -d test.txt
Disallowed should be:
$ program test.txt -d
...and e.g. {error, {wrong_order, d}} should be returned.
README.md
To run the example module run make example.
I've installed getopt using agner.
I've imported getopt.
When I pass options to the example scripts, only the usage information is displayed.
escript ex1.escript -x
@jcomellas I've seen that your library is published on hex.pm
- https://hex.pm/packages/getopt. Would it be possible that you could takeover this package and make it a "official" one under your name? I think this could help to increase security and confidence in this package.
The output of rebar3 eunit
contains warnings:
_build/test/lib/getopt/test/getopt_test.erl:0: Warning: missing specification for function test/0
_build/test/lib/getopt/test/getopt_test.erl:30: Warning: missing specification for function parse_main_test_/0
_build/test/lib/getopt/test/getopt_test.erl:222: Warning: missing specification for function parse_multiple_repetitions_test_/0
...
I ended up using rebar.config.script
to disable warn_missing_spec
compiler option for eunit
task. I'm not sure if it's the right way to do it. I can make a pull request with the script if it is useful.
@jcomellas could you be so kind and create a new release?
It would be nice to have the default option values appended to the help text. Possible with a "Default: " prefix.
-b, --branch Specify which branch the diff affects. Default: my-branch
Is there a way to break long help lines in usage()? Currently it just write over the e.g. 80 chars length. It would be nice if the help text would wrap after 80/78 chars and then get indented correctly under the beginning of its help text start. E.g.:
-h, --help Show this help message and exit. This is a very
long help test so we need to break it down.
-b, --branch Specify which branch the diff affects.
Hi,
README says that "The module has been tested with all versions of Erlang starting with R13B and ending with 20.", however I found that unit tests are currently failing for Erlang 18
Steps to reproduce:
docker run -it --rm erlang:18.3.4.11 /bin/bash
cd /home
git clone https://github.com/jcomellas/getopt.git
cd getopt
Then I see the following:
root@3a815e322146:/home/getopt# rebar compile
==> getopt (compile)
Compiled src/getopt.erl
root@3a815e322146:/home/getopt# rebar eunit
==> getopt (eunit)
Compiled src/getopt.erl
test/getopt_test.erl:0: Warning: missing specification for function test/0
test/getopt_test.erl:30: Warning: missing specification for function parse_main_test_/0
test/getopt_test.erl:222: Warning: missing specification for function parse_multiple_repetitions_test_/0
test/getopt_test.erl:239: Warning: missing specification for function parse_args_with_spaces_test_/0
test/getopt_test.erl:253: Warning: missing specification for function parse_variable_expansion_test_/0
test/getopt_test.erl:279: Warning: missing specification for function tokenize_test_/0
test/getopt_test.erl:287: Warning: missing specification for function check_test_/0
test/getopt_test.erl:305: Warning: missing specification for function format_error_test_/0
test/getopt_test.erl:354: Warning: missing specification for function utf8_binary_test_/0
Compiled test/getopt_test.erl
getopt_test:367: utf8_binary_test_ (Default utf8_binary argument usage)...*failed*
in function string:find/2
called as find([[" ","--utf8"," ",[85,84,70,45,56,32,97,114,103|...],[],10]],[228,220,223,1455])
in call from getopt_test:'-utf8_binary_test_/0-fun-6-'/1 (test/getopt_test.erl, line 367)
**error:undef
output:<<"">>
=======================================================
Failed: 1. Skipped: 0. Passed: 100.
ERROR: One or more eunit tests failed.
ERROR: eunit failed while processing /home/getopt: rebar_abort
I'm writing a little encryption/decryption CLI program, and I'm trying to use getopt. I've cloned, installed, and listed getopt in my $ERL_LIBS
. But Erlang complains:
** exception error: undefined function getopt:usage/2
Normally, I would insert an include_lib("../..hrl").
statement, but I don't see an HRL file in the getopt source. How should I tweak my include statements to fix this?
What is the intended usage for arguments of binary
type?
When one uses getopt
to parse arguments of escript (which I think is the most popular scenario), Erlang provides arguments as (already decoded) strings containing integer code points.
Using list_to_binary/1
to make binary from such a string
string
module, because they expect binary strings to be normalized UTF-8 sequence.Also, default values for arguments of binary
type are converted to strings using binary_to_list/1
, producing invalid values for non-latin1 strings.
For our project which uses UTF-8 encoded binaries I patched getopt
to add a new argument type utf8
. Arguments of this type are encoded using unicode:characters_to_binary/1
.
The other option is to use file:native_name_encoding/0
to determine how argument should be encoded. This is obviously a breaking change.
The third option is to use string
arguments instead of binary
ones. This supposes manual encoding of each value to produce a binary string.
Please tell me if I misunderstood something.
Juan,
Could you update the tags in getopt to reflect the latest and greatest?
Thanks,
Eric
Hi!
When using floats and default values, the output is provided in scientific format. For example, having
{ratio, $r, "ratio", {float, 0.66},
"Splitting ratio (i.e. the fraction of training examples). This argument is only valid when 'split' is activated."},
Give the, not so pleasing output: [default: 6.60000000000000031086e-01]. A more visually pleasing approximation would be nicer (maybe: 0.66).
Opt =[
{node, $n, "node", {string, "localhost"}, "节点"},
{quit, $q, "quit", {boolean, "true"}, "是否退出"},
{command, undefined, undefined, string, "操作命令"},
{args, undefined, undefined, undefined, "参数"}
].
when I use getopt:usage(Opt, "out"). it will crash.
When runned via rebar, the eunit tests of getopt fail:
$ rebar eunit
==> erlang-getopt-0.5.1 (eunit)
Compiled src/getopt.erl
test/getopt_test.erl:0: Warning: missing specification for function test/0
test/getopt_test.erl:30: Warning: missing specification for function parse_main_test_/0
test/getopt_test.erl:222: Warning: missing specification for function parse_multiple_repetitions_test_/0
test/getopt_test.erl:239: Warning: missing specification for function parse_args_with_spaces_test_/0
test/getopt_test.erl:253: Warning: missing specification for function parse_variable_expansion_test_/0
test/getopt_test.erl:279: Warning: missing specification for function tokenize_test_/0
Compiled test/getopt_test.erl
getopt_test:247: parse_args_with_spaces_test_ (Arguments with spaces)...failed
::{assertEqual_failed,[{module,getopt_test},
{line,248},
{expression,"parse ( OptSpecList , "-D'FOO BAR' -D\"VAR 1=VAL 1\" --user \"my user name\" ' dummy1 dummy2 " )"},
{expected,{ok,{[{define,"FOO BAR"},
{define,"VAR 1=VAL 1"},
{user,"my user name"}],
[" dummy1 dummy2 "]}}},
{value,{ok,{[{define,"'FOO"},
{define,""VAR"},
{user,""my"}],
["BAR'","1=VAL","1"","user","name"",
[...]|...]}}}]}
getopt_test:262: parse_variable_expansion_test_ (Shell variable expansion (simple Unix/bash format))...failed
::{assertEqual_failed,
[{module,getopt_test},
{line,263},
{expression,
"parse ( OptSpecList , "--path $PATH $DUMMY_VAR_THAT_MUST_NOT_EXIST" )"},
{expected,
{ok,{[{path,
"/usr/lib64/erlang/erts-5.9.1/bin:/usr/lib64/erlang/bin:/usr/lib64/portage/bin/ebuild-helpers/4:/usr/lib64/portage/bin/ebuild-helpers:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/opt/bin:/usr/x86_64-pc-linux-gnu/gcc-bin/4.6.3"}],
["$DUMMY_VAR_THAT_MUST_NOT_EXIST"]}}},
{value,{ok,{[{path,"$PATH"}],["$DUMMY_VAR_THAT_MUST_NOT_EXIST"]}}}]}
getopt_test:265: parse_variable_expansion_test_ (Shell variable expansion (full Unix/bash format))...failed
::{assertEqual_failed,
[{module,getopt_test},
{line,266},
{expression,
"parse ( OptSpecList , " --path ${PATH} ${DUMMY_VAR_THAT_MUST_NOT_EXIST} " )"},
{expected,
{ok,{[{path,
"/usr/lib64/erlang/erts-5.9.1/bin:/usr/lib64/erlang/bin:/usr/lib64/portage/bin/ebuild-helpers/4:/usr/lib64/portage/bin/ebuild-helpers:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/opt/bin:/usr/x86_64-pc-linux-gnu/gcc-bin/4.6.3"}],
["${DUMMY_VAR_THAT_MUST_NOT_EXIST}"]}}},
{value,{ok,{[{path,"${PATH}"}],["${DUMMY_VAR_THAT_MUST_NOT_EXIST}"]}}}]}
getopt_test:271: parse_variable_expansion_test_ (Shell variable expansion (Windows format))...failed
::{assertEqual_failed,
[{module,getopt_test},
{line,272},
{expression,
"parse ( OptSpecList , " --path %PATH% %DUMMY_VAR_THAT_MUST_NOT_EXIST% " )"},
{expected,
{ok,{[{path,
"/usr/lib64/erlang/erts-5.9.1/bin:/usr/lib64/erlang/bin:/usr/lib64/portage/bin/ebuild-helpers/4:/usr/lib64/portage/bin/ebuild-helpers:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/opt/bin:/usr/x86_64-pc-linux-gnu/gcc-bin/4.6.3"}],
["%DUMMY_VAR_THAT_MUST_NOT_EXIST%"]}}},
{value,{ok,{[{path,"%PATH%"}],["%DUMMY_VAR_THAT_MUST_NOT_EXIST%"]}}}]}
getopt_test:283: tokenize_test_ (Tokenize)...failed
::undef
Failed: 5. Skipped: 0. Passed: 76.
ERROR: One or more eunit tests failed.
But if the tests are runned directly (by calling eunit:test/1 from erl), they pass.
How can I pass a string with spaces as a value?
I want to pass a username: firstname lastname
I've tried quotes and several ways of escaping but getopt always take only the first word.
Args = "-n "firstname lastname" -h myhost --port=1000"
Thanks
would it be possible to create a new tag v1.0.3
or similar, so that rebar3
can point to the new tag, which should include the changes from #53
The current issue is that OTP-27 will ship with a change that reports as error the use of duplicate annotated variables using different types. At the moment, rebar3
has a dependency towards getopt
v1.0.2
, which means that rebar3
will get a compilation error when we release the change in OTP-27.
This would be very useful:
$ cmd --opt
opt = true
$ cmd --opt one
opt = one
The default value shouldn't be limited to a boolean though.
Hello,
I would suggest to use a similar approach like mochiweb.
They supplies rebar binary along with the project. Therefore make
works out-of-box, it simplifies a project adoption into environment where rebar is not configures.
Getopt properly throws an error for string type, but does not for the integer type.
Following examples/ex1.escript:
When using an integer as the type conversion:
option_spec_list() ->
[
{duration, $d, "duration", {integer, 4}, "Duration"}
].
And then passing in <escript> -d
(with no value for the duration option) does not throw an error but assigns duration a value of 1 aka {duration,1}.
However, if I used a string:
option_spec_list() ->
[
{duration, $d, "duration", {string, "asdf"}, "Duration"}
].
and then call <escript> -d
(again, empty cmd arg value for duration), it properly throws this: {error,{missing_option_arg,duration}} with output to terminal:
"Error: missing_option_arg duration"
Could we submit a package for getopt to CEAN, an automated package repository?
If I add the most recent version of getopt (0.8.2) as a dependency in rebar.config for my own project (https://github.com/squaremo/erlmqtt), I start getting test failures when I run rebar eunit
. Using make test
in the getopt directory works fine.
I suspect this is either a recapitulation of #16 or something very like it. Is there a standard workaround? (e.g., tell rebar not to test dependencies, which seems like a shame)
Hi,
I tried following the README.md and couldn't install version 1.0.2, then I checked hex.pm and it says that 1.0.1 is the latest version of getopt
. Will you publish the 1.0.2 version to hex.pm soon?
Links:
Output when installing:
===> Fetching getopt v1.0.1
===> Downloaded package, caching at /Users/aaron/.cache/rebar3/hex/hexpm/packages/getopt-1.0.1.tar
Thanks
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.