Firstly, we need to build an entry point for our command line application. In monolith it is called ExecutionManager.
Create our execution manager
>>> from monolith.cli import ExecutionManager, BaseCommand
>>> manager = ExecutionManager()
Now let’s create simple commands:
>>> class FooCommand(BaseCommand):
... def handle(self, namespace):
... print('foo', file=self.stdout)
...
>>> class BarCommand(BaseCommand):
... def handle(self, namespace):
... print('bar', file=self.stdout)
...
Note
Commands should write to specific stream explicitly or use file keyword argument of print function, but this would require to add following in Python 2.X:
from __future__ import print_function
Now register defined commands:
>>> manager.register('foo', FooCommand)
>>> manager.register('bar', BarCommand)
... and finally run them:
>>> manager.execute(['foo'])
foo
>>> manager.execute(['bar'])
bar
Note
Normally, in your program you would call execute method without any parameters - this would default to sys.argv.
#!/usr/bin/env python
"""
Example of how to create git-like execution manager with monolith.
This is completely fake command.
"""
from __future__ import print_function
from __future__ import unicode_literals
from monolith.cli import ExecutionManager
from monolith.cli import LabelCommand
from monolith.cli import SingleLabelCommand
from monolith.cli import arg
from monolith.cli import CompletionCommand
class AddCommand(LabelCommand):
def handle_label(self, label, namespace):
print("A %s" % label, file=self.stdout)
class InitCommand(SingleLabelCommand):
label = 'directory'
label_required = False
label_default_value = '.'
args = SingleLabelCommand.args + [
arg('--bare', help='Create a bare repository.', default=False,
action='store_true'),
]
def handle_label(self, label, namespace):
print("Initialized empty Git repository in %s.git" % label,
file=self.stdout)
def get_manager(**kwargs):
manager = ExecutionManager(**kwargs)
manager.register('add', AddCommand)
manager.register('init', InitCommand)
manager.register('completion', CompletionCommand),
return manager
def main():
manager = get_manager()
manager.execute()
if __name__ == '__main__':
main()
New in version 0.2.
There is also possibility to use simple execution manager for more complex programs, i.e. if we create a package and put our commands in separate modules we can use string to classes instead of importing all command classes (you can still use imported commands too)
>>> manager = SimpleExecutionManager(program='foobar', commands={'sub-command': 'monolith.tests.test_cli.DummyCommand', 'another-sub-command': AnotherDummyCommand})
>>> manager.get_commands_to_register()
{'sub-command': <class 'monolith.tests.test_cli.DummyCommand'>, 'another-sub-command': <class 'monolith.tests.test_cli.AnotherDummyCommand'>}