Passing arguments from the command line¶
Task action parameters¶
It is possible to pass option parameters to the task action through the command line.
Just add a params
field to the task dictionary. params
must be a list of
dictionaries where every entry is an option parameter. Each parameter must
define a name, and a default value. It can optionally define a “short” and
“long” names to be used from the command line (it follows unix command line
conventions). It may also specify additional attributes, such as
type and help (see below).
See the example:
def task_py_params():
def show_params(param1, param2):
print(param1)
print(5 + param2)
return {'actions':[(show_params,)],
'params':[{'name':'param1',
'short':'p',
'default':'default value'},
{'name':'param2',
'long':'param2',
'type': int,
'default':0}],
'verbosity':2,
}
def task_py_params_list():
def print_a_list(list):
for item in list:
print(item)
return {'actions':[(print_a_list,)],
'params':[{'name':'list',
'short':'l',
'long': 'list',
'type': list,
'default': [],
'help': 'Collect a list with multiple -l flags'}],
'verbosity':2,
}
def task_py_params_choice():
def print_choice(choice):
print(choice)
return {'actions':[(print_choice,)],
'params':[{'name':'choice',
'short':'c',
'long': 'choice',
'type': str,
'choices': (('this', ''), ('that', '')),
'default': 'this',
'help': 'Choose between this and that'}],
'verbosity':2,}
def task_cmd_params():
return {'actions':["echo mycmd %(flag)s xxx"],
'params':[{'name':'flag',
'short':'f',
'long': 'flag',
'default': '',
'help': 'helpful message about this flag'}],
'verbosity': 2
}
For python-actions the python function must define arguments with the same name as a task parameter.
$ doit py_params -p abc --param2 4
. py_params
abc
9
Need a list in your python function? Specify an option with type
set to list
.
$ doit py_params_list -l milk -l eggs -l bread
. py_params_list
milk
eggs
bread
Choices can be set by specifying an option with choices
set to a
sequence of a 2-element tuple.
The first element is the choice value.
The second element is the choice description,
if not required, use an empty string.
$ doit py_params_choice -c that
. py_params_choice
that
Invalid choices are detected and passed back to the user.
$ doit py_params_choice -c notavalidchoice
ERROR: Error parsing parameter 'choice'. Provided 'notavalidchoice' but available choices are: 'this', 'that'.
For cmd-actions use python string substitution notation:
$ doit cmd_params -f "-c --other value"
. cmd_params
mycmd -c --other value xxx
All parameters attributes¶
Here is the list of all attributes param
accepts:
name
Name of the parameter, identifier used as name of the the parameter on python code. It should be unique among others.
- required
True
- type
str
default
Default value used when it is set through command-line.
- required
True
short
Short parameter form, used for e.g.
-p value
.- required
optional
- type
str
long
Long parameter form, used for e.g.
--parameter value
.- required
optional
- type
str
type
Actually it can be any python callable. It coverts the string value received from command line to whatever value to be used on python code.
If the
type
isbool
the parameter is treated as an option flag where no value should be specified, value is set toTrue
. Example:doit mytask --flag
.- required
optional
- type
callable (e.g. a function)
- default
str
choices
List of accepted value choices for option. First tuple element is the value name, second tuple element is a help description for value.
- required
optional
- type
list of 2-tuple strings
help
Help message associated to this parameter, shown when help is called for this task, e.g.
doit help mytask
.- required
optional
- type
str
inverse
[only for bool parameter] Set inverse flag long parameter name, value will be set to
False
(see example below).- required
optional
- type
str
Example, given following code:
def task_with_flag(): def _task(flag): print("Flag {0}".format("On" if flag else "Off")) return { 'params': [{ 'name': 'flag', 'long': 'flagon', 'short': 'f', 'type': bool, 'default': True, 'inverse': 'flagoff'}], 'actions': [(_task, )], 'verbosity': 2 }
calls to task with_flag show flag on or off:
$ doit with_flag . with_flag Flag On $ doit with_flag --flagoff . with_flag Flag Off
positional arguments¶
Tasks might also get positional arguments from the command line as standard unix commands do, with positional arguments after optional arguments.
def task_pos_args():
def show_params(param1, pos):
print('param1 is: {0}'.format(param1))
for index, pos_arg in enumerate(pos):
print('positional-{0}: {1}'.format(index, pos_arg))
return {'actions':[(show_params,)],
'params':[{'name':'param1',
'short':'p',
'default':'default value'},
],
'pos_arg': 'pos',
'verbosity': 2,
}
$ doit pos_args -p 4 foo bar
. pos_args
param1 is: 4
positional-0: foo
positional-1: bar
Warning
If a task accepts positional arguments, it is not allowed to pass other tasks after it in the command line. For example if task1 takes positional arguments you can not call:
$ doit task1 pos1 task2
As the string task2 would be interpreted as positional argument from task1 not as another task name.
command line variables (doit.get_var)¶
It is possible to pass variable values to be used in dodo.py from the command line.
from doit import get_var
config = {"abc": get_var('abc', 'NO')}
def task_echo():
return {'actions': ['echo hi %s' % config],
'verbosity': 2,
}
$ doit
. echo
hi {abc: NO}
$ doit abc=xyz x=3
. echo
hi {abc: xyz}
Task creator parameters¶
Command line arguments may also be passed to task creators. It uses the same parameter syntax as is used with task action parameters.
from doit import task_params
@task_params([{"name": "howmany", "default": 3, "type": int, "long": "howmany"}])
def task_subtasks(howmany):
for i in range(howmany):
yield {"name": i, "actions": [f"echo I can count to {howmany}: {i}"]}
Any argument defined for the task generating function will also be available as an argument for any task actions.
def do_work(foo):
print(f'Argument foo={foo}')
@task_params([{"name": "foo", "default": "bar", "long": "foo"}])
def task_use_in_action(foo):
print(f'When the task action runs it will print {foo}')
return {
'actions': [do_work],
'verbosity': 2
}
Warning
When the @task_params
decorator is used, you must not use the params
field.
The content from params
can be easily included in @task_params
.
The reason for this limitation is that the command line parsing happens before the task’s dict is returned. Hence impossible to know its value.