Skip to main content

dotmaster

CI PyPI License: MIT

Declarative project configuration, kept in sync.

Answer a few questions once, get .gitignore, linting, formatting, Docker, CI, and more — all generated together, recorded in one dotmaster.yaml, and continuously verifiable with dotmaster check.

Status: beta. The output-correctness and safety issues from earlier 0.2.x releases are fixed and covered by tests (see CHANGELOG), but the plugin API and config schema may still change before 1.0.


Why dotmaster and not a scaffolder

Cookiecutter, Copier, and create-* tools generate a new project. dotmaster generates and maintains the configuration layer of a project that may already exist — and, unlike a one-shot generator, it remembers what it wrote:

dotmaster init      # answer questions once → dotmaster.yaml + generated files
dotmaster check     # in CI: fail the build if the repo has drifted from dotmaster.yaml
dotmaster sync      # bring the repo back in line
dotmaster diff      # see what sync would change, before it changes anything

Edit dotmaster.yaml by hand, or an org-wide preset changes — either way, sync converges the repo, your own edits to generated files are preserved where they can be merged, and files you've genuinely modified are reported as conflicts rather than silently overwritten.


Installation

pipx install dotmaster
# or: uvx dotmaster init

Quick start

cd my-project
dotmaster init

Non-interactive (CI, scripts, agents):

dotmaster init --preset backend_api --yes
dotmaster init --yes --set stack.languages=python,typescript --set infrastructure.docker=true

Commands

Command Description
dotmaster init Run the wizard (or --yes/--set) and generate dotfiles
dotmaster sync Regenerate from dotmaster.yaml; safe to run repeatedly
dotmaster diff Show what sync would change, without changing anything
dotmaster check Exit non-zero if the project has drifted — for CI
dotmaster add <plugin> Add or regenerate one plugin's files
dotmaster remove <plugin> Delete a plugin's generated files
dotmaster restore [--list] Restore files from a pre-generation backup
dotmaster list Show available plugins (and which are active)
dotmaster profile list|show|apply Inspect or apply a preset profile
dotmaster validate Check dotmaster.yaml for schema and consistency errors
dotmaster doctor Detected stack, installed tools, plugin health, drift

Every write command supports --dry-run, --force (overwrite files you've edited since they were generated), and --output <dir>.


How regeneration actually works

  1. Each active plugin's plan() describes the files it wants, as data — it never touches disk.
  2. The engine resolves that against what's on disk and against .dotmaster/state.json (dotmaster's private record of what it last generated and its content hash — not meant to be committed).
  3. If you haven't touched a file, it's regenerated freely. If you have, it's reported as a conflict and left alone unless you pass --force. Structured formats (JSON/YAML/TOML) merge instead of conflicting: your keys always win, new keys from the template are added.
  4. Only then does anything get written — atomically, with a backup of anything about to be overwritten, and a full rollback if any write in the batch fails.

This is why dotmaster sync is safe to run on every commit or as a pre-commit hook, and why dotmaster check is meaningful in CI.


Preset profiles

dotmaster init --preset web_app      # React/Next.js + ESLint + Prettier + Docker + CI
dotmaster init --preset backend_api  # Python + FastAPI + Ruff + Docker + CI
dotmaster init --preset library      # ESLint + Jest, no Docker
dotmaster init --preset monorepo     # pnpm + ESLint + CI

A profile pre-fills the wizard (or, with --yes, applies directly) — nothing is locked in, and dotmaster profile apply <name> merges a profile into an existing config without overwriting anything you've already set explicitly.


dotmaster.yaml

version: "2"
project:
  name: my-app
  author: Jane Doe
stack:
  languages: [javascript, typescript]
  framework: nextjs
  package_manager: pnpm
quality:
  linter: eslint
  formatter: prettier
  testing: jest
infrastructure:
  docker: true
  docker_multistage: true
  ci: github_actions
options:
  offline: true      # no network calls unless you opt out
plugins:
  allow: []           # third-party plugins, opt-in by name (or ["*"])

Hand-editing is a first-class workflow: the file carries a # yaml-language-server: $schema=... hint for editor autocomplete, and every field is validated with a specific error (and a "did you mean" suggestion) rather than a stack trace.


Plugin system

Every generator — .gitignore, Dockerfile, ruff.toml, CI workflows — is a plugin: matches(config) decides if it's active, plan(config, ctx) returns the files it wants. Built-ins are always available; third-party plugins register via a dotmaster.plugins entry point and only load if named in plugins.allow.

See docs/plugin-authoring.md for the full guide — most plugins are 30–80 lines, and it's the easiest way to contribute.


Development

git clone https://github.com/ahron-maslin/dotmaster
cd dotmaster
pip install -e ".[dev]"
pytest
ruff check . && ruff format --check . && mypy dotmaster

See CONTRIBUTING.md.


Security

options.offline defaults to true — no network call happens unless a project explicitly opts out. All file writes are checked to stay inside the project root. See SECURITY.md for the full policy and how to report a vulnerability.

License

MIT

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

dotmaster-0.3.0.tar.gz (121.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

dotmaster-0.3.0-py3-none-any.whl (82.2 kB view details)

Uploaded Python 3

File details

Details for the file dotmaster-0.3.0.tar.gz.

File metadata

  • Download URL: dotmaster-0.3.0.tar.gz
  • Upload date:
  • Size: 121.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for dotmaster-0.3.0.tar.gz
Algorithm Hash digest
SHA256 27014626b7ff77c0e699184d88d886efaf92c041f923cbc134c1f9a222230df8
MD5 0834bbb1495e57292c767686cd7eb021
BLAKE2b-256 80cc77f8dc65988e29ccf8f849bde03737ea35460f2c3cfbae06365199362efe

See more details on using hashes here.

Provenance

The following attestation bundles were made for dotmaster-0.3.0.tar.gz:

Publisher: release.yml on ahron-maslin/dotmaster

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file dotmaster-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: dotmaster-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 82.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for dotmaster-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 b1396fa82f85feaad10c5c91000a1117353b2d3bfcc3f644031fb93f929d5785
MD5 d857aee47ef7356440c2f25e4e6c61d5
BLAKE2b-256 e56d4e1a62a40e9215339e0982bfa2a99e118e06380156213535a22feb711175

See more details on using hashes here.

Provenance

The following attestation bundles were made for dotmaster-0.3.0-py3-none-any.whl:

Publisher: release.yml on ahron-maslin/dotmaster

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

0.3.0 This release

2 files

0.2.2

2 files

0.2.1

2 files

0.1.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page