Nessaid CLI frameworks let's us do this in a slightly different way. The package provides a python Cmd like interface with readline integration and helps us to specify the commands using a grammar integrated as docstrings for methods. The 5 objectives can be implemented by the following example.
import sys
from nessaid_cli.cmd import NessaidCmd
from nessaid_cli.tokens import (
StringToken,
RangedIntToken,
RangedStringToken
)
class TestCmd(NessaidCmd):
"""
token STRING_TOKEN StringToken();
token RANGED_STRING_TOKEN_1 RangedStringToken(5, 10);
token RANGED_INT_TOKEN_1 RangedIntToken(1, 1000);
"""
def get_token_classes(self):
return [StringToken, RangedIntToken, RangedStringToken]
def do_command_1(self):
"""
"command1"
"""
print("This is command 1")
def do_foo(self, foo, bar):
"""
"foo"
RANGED_STRING_TOKEN_1 << $foo = $2; >>
{
# Braced parts are optional
RANGED_STRING_TOKEN_1 << $bar = $1; >>
}
"""
print("Foo:", foo)
if bar:
print("Bar:", bar)
def do_foo_arg_optionals(self, foo, bar, args, optionals):
"""
<<
$opt1 = "";
$args = list();
$optionals = list();
>>
"foo1"
RANGED_STRING_TOKEN_1 << $foo = $2; >>
{
# Braced parts are optional
RANGED_STRING_TOKEN_1 << $bar = $1; >>
}
(
STRING_TOKEN << $args = append($args, $1); >>
STRING_TOKEN << $args = append($args, $2); >>
{
(
"true" << $optionals = append($optionals, $1); >>
|
"false" << $optionals = append($optionals, $1); >>
)
(
"opt2"
RANGED_STRING_TOKEN_1
<< $optionals = append($optionals, $2); >>
)
}
)
"""
print("Foo:", foo)
if bar:
print("Bar:", bar)
print("args:", args)
print("optionals:", optionals)
def do_command4(self, opt, arg):
"""
"command4"
{
"opt1"
RANGED_STRING_TOKEN_1 << $opt = $2; >>
}
(
RANGED_STRING_TOKEN_1 << $arg = $3; >>
)
"""
if opt:
print("opt:", opt)
print("arg:", arg)
def do_array(self, array):
"""
<<$array = list();>>
"array"
(
"opt5"
RANGED_STRING_TOKEN_1
<<$array = append($array, $2);>>
) * (1: 5)
"other-args"
(
"opt5"
RANGED_STRING_TOKEN_1
<<$array = append($array, $2);>>
) * (1: 2)
"""
print("Array:", array)
if __name__ == '__main__':
cmd = TestCmd(prompt="nessaid-cmd # ", show_grammar=True)
#show_grammar will print the generated grammar specification
try:
cmd.loop.run_until_complete(cmd.cmdloop(intro="Starting Nessaid CMD Demo"))
except KeyboardInterrupt:
sys.exit(0)
except Exception as e:
print("Exception in cmdloop:", e)
sys.exit(1)
sys.exit(0)
https://github.com/saithalavi/nessaid_cli
This will give an interface like cmd module. The commands can be developed with a grammar to specify sequencing, alternatives, optionals and repititions, with helpstring, suggestions and tab completion at each level. It also supports cutom input tokens.
The output of the above example
nessaid-cmd # <TAB>
array
command1
command4
end
exit
foo
foo1
quit
1.
nessaid-cmd # comm
command1
command4
nessaid-cmd # command1
NEWLINE: Complete command
nessaid-cmd # command1
This is command 1
2.
nessaid-cmd # fo
foo
foo1
nessaid-cmd # foo
Any string of length (5-10)
nessaid-cmd # foo asdfgh
Any string
Any string of length (5-10)
NEWLINE: Complete command
nessaid-cmd # foo asdfgh
Foo: asdfgh
nessaid-cmd # foo asdfgh 123456
Foo: asdfgh
Bar: 123456
nessaid-cmd #
3.
nessaid-cmd # foo1
Any string of length (5-10)
nessaid-cmd # foo1 asd
Failed to parse: Could not match any rule for this sequence
nessaid-cmd # foo1 asd123
Any string
Any string of length (5-10)
nessaid-cmd # foo1 asd123 as
Any string
nessaid-cmd # foo1 asd123 as df
NEWLINE: Complete command
false
true
nessaid-cmd # foo1 asd123 as df tr
true
nessaid-cmd # foo1 asd123 as df true
opt2
nessaid-cmd # foo1 asd123 as df true op
opt2
nessaid-cmd # foo1 asd123 as df true opt2
Any string of length (5-10)
nessaid-cmd # foo1 asd123 as df true opt2 123456
Any string of length (5-10)
nessaid-cmd # foo1 asd123 as df true opt2 123456
Any string of length (5-10)
nessaid-cmd # foo1 asd123 as df true opt2 123456
NEWLINE: Complete command
nessaid-cmd # foo1 asd123 as df true opt2 123456
Foo: asd123
args: ['foo1', 'asd123']
optionals: ['true', 'opt2']
nessaid-cmd #
4.
nessaid-cmd # command4 aaaaaa
arg: aaaaaa
nessaid-cmd # command4 opt1 asdfgh 123456
opt: asdfgh
arg: 123456
5.
nessaid-cmd # array opt5 12345 opt5 qwerty other-args opt5 2222223
Array: ['12345', 'qwerty', '2222223']
nessaid-cmd # array opt5 12345 opt5 qwerty other-args opt5 2222223 opt5 69874566
Array: ['12345', 'qwerty', '2222223', '69874566']
nessaid-cmd # array opt5 qwerty other-args opt5 2222223 opt5 69874566
Array: ['qwerty', '2222223', '69874566']
[UPDATE] The library now supports passing the input from command line. Just like opening the commandline and entering the last command, ie
nessaid-cmd # array opt5 qwerty other-args opt5 2222223 opt5 69874566
The program itself can be invoked with the input. eg. For the last example,
python3 test.py array opt5 qwerty other-args opt5 2222223 opt5 69874566
Will print the same output
Array: ['qwerty', '2222223', '69874566']