{"id":5199,"library":"doit","title":"doit - Automation Tool","description":"doit is a Python-native task management and automation tool, similar to 'make' but entirely in Python. It allows users to define tasks as Python functions returning dictionaries, tracks file and task dependencies, caches results, and executes only what has changed, enabling incremental builds and reproducible workflows. As of version 0.37.0, it supports Python 3.10+ and is actively maintained with regular updates.","status":"active","version":"0.37.0","language":"en","source_language":"en","source_url":"https://github.com/pydoit/doit/","tags":["automation","task-runner","build-tool","workflow-management","make-alternative"],"install":[{"cmd":"pip install doit","lang":"bash","label":"Install doit"}],"dependencies":[],"imports":[{"note":"Tasks are typically defined as functions named `task_*` in a `dodo.py` file, which `doit` discovers and runs directly from the command line. Direct Python imports of a 'main' doit object are not the primary usage pattern.","symbol":"Task Definition","correct":"def task_my_task(): return {'actions': ['echo \"hello\"']}"},{"note":"For advanced task configurations, utilities like `result_dep`, `run_once`, or `config_changed` are imported from `doit.tools`.","symbol":"doit.tools","correct":"from doit.tools import result_dep"},{"note":"Global configuration for doit is typically set in a `DOIT_CONFIG` dictionary directly in `dodo.py` or through `pyproject.toml`. While `doit_api.doit_config` exists for programmatically creating config, directly defining the dict is common. Old modules for config factories might be deprecated.","wrong":"from doit.config import DOIT_CONFIG_FACTORY # (deprecated style)","symbol":"DOIT_CONFIG","correct":"DOIT_CONFIG = {'verbosity': 2}"}],"quickstart":{"code":"import os\n\ndef task_hello():\n    \"\"\"create a greeting file\"\"\"\n    return {\n        'actions': ['echo \"Hello from doit\" > hello.txt'],\n        'targets': ['hello.txt'],\n        'clean': True,\n    }\n\ndef task_shout():\n    \"\"\"convert greeting to uppercase\"\"\"\n    return {\n        'actions': ['tr a-z A-Z < hello.txt > shout.txt'],\n        'file_dep': ['hello.txt'],\n        'targets': ['shout.txt'],\n        'clean': True,\n    }\n\n# To run this, save as dodo.py and execute in terminal:\n# $ doit\n# $ cat shout.txt\n# $ doit clean\n# (Note: 'tr' command is Unix-like, might need alternatives on Windows)","lang":"python","description":"Create a file named `dodo.py` with task definitions. `doit` automatically discovers tasks named `task_*`. Tasks are Python functions that return a dictionary describing their actions, dependencies (`file_dep`), and outputs (`targets`). Running `doit` from the command line executes these tasks, honoring dependencies and skipping up-to-date tasks."},"warnings":[{"fix":"Ensure your project uses Python 3.10 or newer. Check the `CHANGES` file for specific version requirements if upgrading from older `doit` releases.","message":"Version 0.37.0 dropped support for Python 3.8 and 3.9. The minimum required Python version is now 3.10. Prior versions also dropped support for older Python versions (e.g., 0.35.0 dropped 3.6/3.7).","severity":"breaking","affected_versions":">=0.37.0"},{"fix":"Review the `CHANGES` file for version 0.36.0 on the official GitHub repository. Update custom task loaders, plugin integrations, or exception handling code accordingly. Consider adding `tomli` if directly interacting with TOML files for configuration.","message":"Version 0.36.0 introduced several backward-incompatible changes, including the removal of the deprecated `doit.cmd_base.py:TaskLoader`, a switch from `toml` to `tomli` for configuration parsing, changes to how plugins are handled, and a restructuring of internal error classes (e.g., `CatchedException` renamed to `BaseFail`).","severity":"breaking","affected_versions":">=0.36.0"},{"fix":"For tasks that produce output or depend on specific inputs, always specify `file_dep` and `targets` to enable `doit`'s incremental build capabilities. If a task truly should run every time, explicitly add `uptodate=False` to its return dictionary.","message":"Tasks without explicitly defined `file_dep` (file dependencies) or `targets` will always be considered 'out-of-date' and re-run every time `doit` is executed, even if their actions have no side effects. This can lead to unnecessary re-execution.","severity":"gotcha","affected_versions":"all"},{"fix":"Consult the `doit` documentation on configuration options and precedence. For global project configuration, `pyproject.toml` (`[tool.doit]` section) or a `DOIT_CONFIG` dictionary in `dodo.py` are common. Ensure paths are correctly handled, especially when using `src` layouts or non-standard `dodo.py` locations.","message":"Configuration files (`pyproject.toml`, `doit.cfg`, `dodo.py`'s `DOIT_CONFIG` variable) and command-line arguments have a specific precedence. Misunderstanding this hierarchy can lead to unexpected behavior where settings are not applied as intended, or `doit` fails to find tasks.","severity":"gotcha","affected_versions":"all"}],"env_vars":null,"last_verified":"2026-04-13T00:00:00.000Z","next_check":"2026-07-12T00:00:00.000Z"}