doit logo

Table Of Contents


Your logo here


Gratipay weekly funding goal is $?.?? USD.

Why Donate? Help keep the project alive! Donations will be used for project maintanance tasks (bug fixes, merge patches, reply users).

For corporate donations the logo of your company will be placed on this website side-bar (see above). For more information please contact

Hire me

Looking for a python developer with a proven record of designing and developing robust and well tested applications? The creator and maintainer of doit is available for hire. Full-time, part-time or one-off job.

Command line interface - run

A general doit command goes like this:

$ doit [run] [<options>] [<task|target> <task_options>]* [<variables>]

The doit command line contains several sub-commands. Most of the time you just want to execute your tasks, that’s what run does. Since it is by far the most common operation it is also the default, so if you don’t specify any sub-command to doit it will execute run. So $ doit and $ doit run do the same thing.

The basics of task selection were introduced in Task Selection.

python -m doit

doit can also be executed without using the doit script.

$ python -m doit

This is specially useful when testing doit with different python versions.

dodo file

By default all commands are relative to in the current folder. You can specify a different dodo file containing task with the flag -f. This flag is valid for all sub-commands.

$ doit -f

doit can seek for the file on parent folders if the the option --seek-file is specified.

as an executable file

using a hashbang

If you have doit installed on /usr/bin use the following hashbang:

#! /usr/bin/doit -f

using the API

It is possible to make a dodo file become an executable on its own by calling the, you need to pass the globals:

#! /usr/bin/env python

def task_echo():
    return {
        'actions': ['echo hi'],
        'verbosity': 2,

if __name__ == '__main__':
    import doit


The method will call sys.exit() so any code after it will not be executed. parameter will be passed to a ModuleTaskLoader to find your tasks.

returned value

doit process returns:

  • 0 => all tasks executed successfully

  • 1 => task failed

  • 2 => error executing task

  • 3 => error before task execution starts

    (in this case the reporter is not used)


Command line parameters can be set straight on a dodo file. This example below sets the default tasks to be run, the continue option, and a different reporter.

DOIT_CONFIG = {'default_tasks': ['my_task_1', 'my_task_2'],
               'continue': True,
               'reporter': 'json'}

So if you just execute

$ doit

it will have the same effect as executing

$ doit --continue --reporter json my_task_1 my_task_2

You need to check to find out how parameter maps to config names.


The parameters --file and --dir can not be used on config because they control how the dodo file itself is loaded.

DB backend

doit saves the results of your tasks runs in a “DB-file”, it supports different backends:

  • dbm: (default) It uses python dbm module. The actual DBM used depends on what is available on your machine/platform.
  • json: Plain text using a json structure, it is slow but good for debugging.
  • sqlite3: (experimental) very slow implementation, support concurrent access.

From the command line you can select the backend using the --backend option.

It is quite easy to add a new backend for any key-value store.


Option --db-file sets the name of the file to save the “DB”, default is .doit.db. Note that DBM backends might save more than one file, in this case the specified name is used as a base name.

To configure in a dodo file the field name is dep_file

    'backend': 'json',
    'dep_file': 'doit-db.json',


Option to change the default global task verbosity value.

$ doit --verbosity 2

dir (cwd)

By default the directory of the dodo file is used as the “current working directory” on python execution. You can specify a different cwd with the -d/–dir option.

$ doit --dir path/to/another/cwd


By default the execution of tasks is halted on the first task failure or error. You can force it to continue execution with the option –continue/-c

$ doit --continue

single task execution

The option -s/--single can be used to execute a task without executing its task dependencies.

$ doit -s do_something

parallel execution

doit supports parallel execution –process/-n. This allows different tasks to be run in parallel, as long any dependencies are met. By default the multiprocessing module is used. So the same restrictions also apply to the use of multiprocessing in doit.

$ doit -n 3

You can also execute in parallel using threads by specifying the option –parallel-type/-P.

$ doit -n 3 -P thread


The actions of a single task are always run sequentially; only tasks and sub-tasks are affected by the parallel execution option.


doit provides different “reporters” to display running tasks info on the console. Use the option –reporter/-r to choose a reporter. Apart from the default it also includes:

  • executed-only: Produces zero output if no task is executed
  • json: Output results in JSON format
  • zero: display only error messages (does not display info on tasks being executed/skipped). This is used when you only want to see the output generated by the tasks execution.
$ doit --reporter json

custom reporter

It is possible to define your own custom reporter. Check the code on doit/ ... It is easy to get started by sub-classing the default reporter as shown below. The custom reporter must be configured using DOIT_CONFIG dict.

from doit.reporter import ConsoleReporter

class MyReporter(ConsoleReporter):
    def execute_task(self, task):
        self.outstream.write('MyReporter --> %s\n' % task.title())

DOIT_CONFIG = {'reporter': MyReporter,
               'verbosity': 2}

def task_sample():
    for x in range(3):
        yield {'name': str(x),
               'actions': ['echo out %d' % x]}

Note that the reporter have no control over the real time output from a task while it is being executed, this is controlled by the verbosity param.


The option –output-file/-o let you output the result to a file.

$ doit --output-file result.txt


If the option --pdb is used, a post-mortem debugger will be launched in case of a unhandled exception while loading tasks.


When doit executes by default it will use the location of as the current working directory (unless –dir is specified). The value of doit.get_initial_workdir will contain the path from where doit was invoked from.

This can be used for example set which tasks will be executed:

# Sample to test doit.get_initial_workdir
# First create a folder named 'sub1'.
# Invoking doit from the root folder will execute both tasks 'base' and 'sub1'.
# Invoking 'doit -k' from path 'sub1' will execute only task 'sub1'

import os

import doit

    'verbosity': 2,
    'default_tasks': None, # all by default

# change default tasks based on dir from where doit was run
sub1_dir = os.path.join(os.path.dirname(__file__), 'sub1')
if doit.get_initial_workdir() == sub1_dir:
    DOIT_CONFIG['default_tasks'] = ['sub1']

def task_base():
    return {'actions': ['echo root']}

def task_sub1():
    return {'actions': ['echo sub1']}


minversion can be used to specify the minimum/oldest doit version that can be used with a file.

For example if your makes use of a feature added at doit X and distribute it. If another user who tries this with a version older that X, doit will display an error warning the user to update doit.

    'minversion': '0.24.0',


This feature was added on doit 0.24.0. Older Versions will not check or display error messages.