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.

Extending doit

doit is built to be extended and this can be done in several levels. So far we have seen:

  1. User’s can create new ways to define when a task is up-to-date using the uptodate task parameter (more)
  2. Tasks can be created in different styles by creating a custom task creators (more)
  3. The output can be configured by creating custom reports (more)
  4. You can customize how tasks are executed by creating new Action types (more)

Apart from those doit also expose it’s internal API so you can create new applications on top of doit.

task loader customization

The task loader controls the source/creation of tasks. Normally doit tasks are defined in a file. This file is loaded, and the list of tasks is created from the dict containing task meta-data from the task-creator functions.

Subclass TaskLoader to create a custom loader:

class doit.cmd_base.TaskLoader[source]

task-loader interface responsible of creating Task objects

Subclasses must implement the method load_tasks

Variables:cmd_options – (list of dict) see cmdparse.CmdOption for dict format
load_tasks(cmd, opt_values, pos_args)[source]

load tasks and DOIT_CONFIG


(tuple) list of Task, dict with DOIT_CONFIG options

  • cmd – (doit.cmd_base.Command) current command being executed
  • opt_values – (dict) with values for cmd_options
  • pos_args – (list str) positional arguments from command line

The main program is implemented in the DoitMain. It’s constructor takes an instance of the task loader to be used.

Example: pre-defined task

In the full example below a application is created where the only task available is defined using a dict (so no will be used).

#! /usr/bin/env python

import sys

from doit.task import dict_to_task
from doit.cmd_base import TaskLoader
from doit.doit_cmd import DoitMain

my_builtin_task = {
    'name': 'sample_task',
    'actions': ['echo hello from built in'],
    'doc': 'sample doc',

class MyLoader(TaskLoader):
    def load_tasks(cmd, opt_values, pos_args):
        task_list = [dict_to_task(my_builtin_task)]
        config = {'verbosity': 2}
        return task_list, config

if __name__ == "__main__":

Example: load tasks from a module

The ModuleTaskLoader can be used to load tasks from a specified module, where this module specifies tasks in the same way as in ModuleTaskLoader is included in doit source.

#! /usr/bin/env python

import sys

from doit.cmd_base import ModuleTaskLoader
from doit.doit_cmd import DoitMain

if __name__ == "__main__":
    import my_module_with_tasks

ModuleTaskLoader can take also take a dict where its items are functions or methods of an object.

sub-command customization

The doit command line has several sub-commands: run, help, list, clean... By sub-classing DoitMain.get_commands it is possible to add/remove commands.

To create a new sub-cmd, subclass doit.cmd_base.Command set some class variables and implement the execute method.

class doit.cmd_base.Command[source]

third-party should subclass this for commands that do no use tasks

  • name – (str) name of sub-cmd to be use from cmdline
  • doc_purpose – (str) single line cmd description
  • doc_usage – (str) describe accepted parameters
  • doc_description – (str) long description/help for cmd
  • cmd_options – (list of dict) see cmdparse.CmdOption for dict format
execute(opt_values, pos_args)[source]

execute command :param opt_values: (dict) with cmd_options values :param pos_args: (list) of cmd-line positinal arguments

cmd_options uses the same format as task parameters.

Example: scaffolding

A common example is applications that provide some kind of scaffolding when creating new projects.

#! /usr/bin/env python

import sys

from doit.cmd_base import Command
from doit.doit_cmd import DoitMain

class MyCmd(Command):
    doc_purpose = 'test extending doit commands'
    doc_usage = '[XXX]'
    doc_description = 'my command description'

    def execute(self, opt_values, pos_args):
        print "this command does nothing!"

class MyTool(DoitMain):
    def get_commands(self):
        cmds = DoitMain.get_commands(self)
        my_cmd = MyCmd()
        cmds[] = my_cmd
        return cmds

if __name__ == "__main__":