diff --git a/.gitignore b/.gitignore index 0c0434f..859a12a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ *.sublime-* nimcache/ +*.html commandeer testCommandeer \ No newline at end of file diff --git a/README.md b/README.md index 0aa5394..d837f3b 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ Commandeer Take command of your command line. Commandeer easily deals with getting data from the command line to variables. -Period. It does this little thing well and it lets *you* deal with the rest. +Period. It does this little thing well and lets *you* deal with the rest. Usage @@ -47,13 +47,13 @@ Squared = 9 Times 5 = 45 Debugging enabled $ myCLApp 3 yes --times=5 --debug --help -Usage: program [--help|--times=] +Usage: program [--times=|--debug|--help] ``` -See testCommandeer.nim for a bigger example. +See the `tests` folder for other examples. That's all. It's not much and it doesn't pretend to be a magical experience. -Although it would be much cooler if it was. It should Just Work. +Although, it would be much cooler if it was. It should Just Work. Installation @@ -85,7 +85,7 @@ Documentation **commandline** `commandline` is used to delimit the space where you define the command line -arguments you expect. All other commandeer constructs are to be placed under it. +arguments and options you expect. All other commandeer constructs (described below) are placed under it. **argument `identifier`, `type`** @@ -95,6 +95,17 @@ the value of the corresponding command line argument converted to type `type`. Correspondence works as follows: the first occurrence of `argument` corresponds to the first argument, the second to the second argument and so on. +**arguments `identifier`, `type` `[, atLeast1]`** + +It declares a variable named `identifier` of type `seq[type]` initialized with +the value of the sequential command line arguments that can be converted to type `type`. +By default `atLeast1` is `true` which means there must be at least one argument of type +`type` or else an error is thrown. Passing `false` there allows for 0 or more arguments of the +same type to be stored at `identifier`. + +*Warning*: `arguments myListOfStrings, string` will eat all arguments on the command line. The same +applies to other situations where one type is a supertype of another type in terms of conversion e.g., floats eat ints. + **option `identifier`, `type`, `long option`, `short option`** @@ -130,11 +141,12 @@ Design the developer - No magical variables should be made implicitly available. All created variables should be explicitly chosen by the developer. -- Command line parsers can do a lot for you, but I prefer to - be in full control. Keep it simple and streamlined. +- Keep it simple and streamlined. Command line parsers can do a lot for you, but I prefer to + be in full control. TODO and Contribution --------------------- -- Test out and see what needs to be added. \ No newline at end of file +- Better tests! +- Use and see what needs to be added. \ No newline at end of file diff --git a/commandeer.babel b/commandeer.babel index f46f817..6daa1e7 100644 --- a/commandeer.babel +++ b/commandeer.babel @@ -1,6 +1,6 @@ [Package] name = "commandeer" -version = "0.2.0" +version = "0.3.0" author = "Guillaume Viger" description = "A small command line parsing DSL (domain specific language)" license = "MIT" diff --git a/commandeer.nim b/commandeer.nim index 2b54d9f..f103339 100644 --- a/commandeer.nim +++ b/commandeer.nim @@ -39,7 +39,7 @@ template argument*(identifier : expr, t : typeDesc): stmt {.immediate.} = var identifier : t - if argumentList.len <= argumentIndex: + if argumentList.len == argumentIndex: error = newException(E_Base, "Not enough command-line arguments") else: var typeVar : t @@ -50,6 +50,32 @@ template argument*(identifier : expr, t : typeDesc): stmt {.immediate.} = error = getCurrentException() +template arguments*(identifier : expr, t : typeDesc, atLeast1 : bool = true): stmt {.immediate.} = + bind argumentList + bind argumentIndex + bind convert + bind error + + var identifier = newSeq[t]() + + if atLeast1 and (argumentList.len == argumentIndex): + error = newException(E_Base, "Not enough command-line arguments") + else: + var typeVar : t + var firstError = true + while true: + if argumentList.len == argumentIndex: + break + try: + identifier.add(convert(argumentList[argumentIndex], typeVar)) + inc(argumentIndex) + firstError = false + except EInvalidValue: + if atLeast1 and firstError: + error = getCurrentException() + break + + template option*(identifier : expr, t : typeDesc, longName : string, shortName : string): stmt {.immediate.} = bind shortOptions diff --git a/testCommandeer.nim b/tests/testCommandeer.nim similarity index 93% rename from testCommandeer.nim rename to tests/testCommandeer.nim index 92577cc..2b49978 100644 --- a/testCommandeer.nim +++ b/tests/testCommandeer.nim @@ -1,6 +1,6 @@ ## commandeer example file (it doubles as a test file too!) ## When testing commandeer run it as follows on the command line: -## ./testCommandeer 2 on --outside -a:2 +## ./testCommandeer 2 on --outside -a:2 --testing from strutils import join import tables @@ -46,4 +46,5 @@ if testing: #Test that tables is not overwritten var a = tables.initTable[string, int]() a["boo"] = 1 - echo a["boo"] \ No newline at end of file + echo a["boo"] + echo "Tests pass!" \ No newline at end of file diff --git a/tests/testarguments.nim b/tests/testarguments.nim new file mode 100644 index 0000000..127931c --- /dev/null +++ b/tests/testarguments.nim @@ -0,0 +1,27 @@ +## When testing commandeer run it as follows on the command line: +## ./testarguments 2.0 1 1 2 1 a + +import unittest + +import commandeer + +commandLine: + argument floatNumber, float + arguments intNumbers, int + argument character, char + option testing, bool, "testing", "t" + +echo("floatNumber = ", floatNumber) +echo("intNumbers = ", intNumbers) +echo("character = ", character) + +if testing: + + check floatNumber == 2.0 + check intNumbers[0] == 1 + check intNumbers[1] == 1 + check intNumbers[2] == 2 + check intNumbers[3] == 1 + check character == 'a' + + echo "Tests Pass" \ No newline at end of file diff --git a/tests/teststringarguments.nim b/tests/teststringarguments.nim new file mode 100644 index 0000000..14a7820 --- /dev/null +++ b/tests/teststringarguments.nim @@ -0,0 +1,20 @@ +## When testing commandeer run it as follows on the command line: +## ./teststringarguments file1 file2 file3 --testing + +import unittest + +import commandeer + +commandLine: + arguments filenames, string, false + option testing, bool, "testing", "t" + +echo("filenames = ", filenames) + +if testing: + + check filenames[0] == "file1" + check filenames[1] == "file2" + check filenames[2] == "file3" + + echo "Tests Pass" \ No newline at end of file