DoPy is a small, Python-based task runner that lets you define project-specific or global tasks as Python functions in a do.py file. Tasks are registered with simple decorators and executed from a lightweight CLI. The tool is intended as a flexible alternative to Makefiles where full Python logic is helpful.
- Define tasks as Python functions and register them using decorators (
@command,@sh,@echo). - Supports both project-local
do.pyand global defaults loaded fromDOPY_HOME(default:~/.dopy). The project-localdo.pyalways overrides global defaults when names conflict. - Convenient
key=valueargument passing that is available to all tasks in the same run. - Basic type conversion using Python annotations:
int,float,bool,pathlib.Path,datetime.datetime. - Support for
list[T]andset[T]parameters: pass a single comma-separated string and it will be split and element-wise converted when possible.
- Replace repeated Makefile fragments with reusable Python tasks.
- Keep shared, personal tasks in
DOPY_HOMEand project-specific tasks next to each project. - Run arbitrary Python logic as part of your tasks (complex setup, dynamic inputs, custom validation).
For development, install in editable mode from the repository root:
python3 -m pip install -e .For usage, install the whl file via pip from release
Note: pipx is not recommended for now because DoPy expects to be importable as a Python module in user code.
Create a do.py in the project root. Example:
from dopy import command, sh, echo
@command
def hello(name: str):
print(f"Hello {name}")
@echo
def hello_echo():
return "Hello, World!"
@sh
def hello_sh():
return "echo hello_from_sh"Run tasks with the dopy CLI. key=value pairs are collected and provided to tasks in the run:
$ dopy hello_echo hello_sh
>Hello, World!
>hello_from_sh
$ dopy hello Pami
> Hello Pami
$ dopy name=pami hello
> Hello Pami
$ dopy name=pami hello Lucky
> Hello Lucky # positional argument 'Lucky' overrides name from kwargs for that positional parameter
$ dopy
# print help for the available commands
$ dopy {command} --help
# print help for the {command}- All
key=valuepairs passed on the command line for a run are collected and available to every task executed in that run. - If a task function has parameter annotations, DoPy attempts to convert string inputs to the annotated type. Supported conversions include:
int,float,boolpathlib.Pathdatetime.datetime(ISO format or common date/time patterns)list[T]andset[T]: the CLI accepts a single comma-separated string (e.g."a,b,c") which is split and each element is converted toTwhere possible. If conversion of an element fails, the raw string is kept.
- If you provide a positional argument for a parameter, that positional value takes precedence and will not be replaced by a
key=valueof the same name (avoids duplicate argument errors). - If a conversion fails, DoPy leaves the original string value — it will not raise an error during parsing.
- Pass a list of tags to a task:
dopy tags "alpha,beta,gamma"- Use a global default defined in
~/.dopy/do.py(for example a standardpodman buildrecipe) and override locally where necessary.