Skip to content

feat(cli): drt init --template <connector> + README quickstart rewrite (closes #545)#564

Merged
masukai merged 2 commits into
mainfrom
feat/init-templates
May 25, 2026
Merged

feat(cli): drt init --template <connector> + README quickstart rewrite (closes #545)#564
masukai merged 2 commits into
mainfrom
feat/init-templates

Conversation

@masukai

@masukai masukai commented May 25, 2026

Copy link
Copy Markdown
Contributor

Closes #545. Eighth slice of the Tech Foundation Hardening epic #538. Closes the last UX gap on the v0.7.5 Wave 1 list.

Why

The README's old 5-step quickstart had users (1) install (2) run the interactive wizard (3) seed sample DuckDB data (4) hand-author a sync YAML (5) run. Steps 2 and 4 were the friction — every newcomer typed something different and roughly half mistyped. This PR collapses the path to a single command:

```bash
$ drt init --template duckdb_to_rest
```

Three curated starter templates

Name Use case Cloud accounts needed
`duckdb_to_rest` DuckDB → REST API POST (httpbin.org) None
`postgres_to_slack` PostgreSQL → Slack webhook (operational alerts) Slack webhook + Postgres profile
`duckdb_to_hubspot` DuckDB → HubSpot contacts upsert HubSpot private app token

Each is a static, self-contained sync YAML under `drt/cli/templates/syncs/`. `drt init --template list` enumerates them; `drt init --template ` writes `syncs/.yml` plus a minimal `drt_project.yml` + `.drt/.gitignore` shell and prints per-template next-steps text (env vars, sample tables).

Design notes

  • Static files, not Jinja-rendered. The on-disk template is what the user gets — no per-invocation substitution. Keeps scaffolding boring and predictable.
  • Project shell created if missing, never overwritten. Running `--template ` in a directory with an existing `drt_project.yml` appends only the new sync file.
  • Registry at `drt/cli/_init_templates.py`. Each `TemplateInfo` carries name + description + next-steps tuple, so `--template list` and the post-scaffold guidance read from one source of truth.

README rewrite

  • New Quickstart fits in one `bash` block: install + `init --template` + seed + run
  • "Other starter templates" subsection points at `--template list`
  • "Customizing your sync" subsection demotes the interactive wizard to advanced usage
  • `docs/connectors/` link + `drt sources/destinations --detailed` discovery hint added above the Connectors table

README.ja.md mirrored in a second commit with the i18n-sync marker updated.

Tests

`tests/unit/test_cli_init_templates.py` — 9 tests:

  • `--template list` exits 0 and surfaces every registered template
  • Per-template (parameterized × 3): scaffolds the expected project shell, sync file lands under `syncs/`, next-steps text prints
  • `--template` does not overwrite an existing `drt_project.yml`
  • `--template invalid_name` exits 1 with a pointer to `list`
  • Validation parity (parameterized × 3): each shipped template YAML parses as a `SyncConfig` via Pydantic — fails fast if a template that `drt validate` would reject is ever shipped

Files

File Type
`drt/cli/_init_templates.py` new — registry + loader
`drt/cli/templates/syncs/duckdb_to_rest.yml` new
`drt/cli/templates/syncs/postgres_to_slack.yml` new
`drt/cli/templates/syncs/duckdb_to_hubspot.yml` new
`drt/cli/main.py` modified — `init` gains `--template` flag + `_list_templates` / `_init_from_template` helpers
`tests/unit/test_cli_init_templates.py` new — 9 tests
`README.md` Quickstart rewrite + docs/connectors link
`README.ja.md` mirrored + i18n-sync marker bumped

Local verification

```
$ pytest tests/ → 1185 passed, 1 skipped, 7 deselected
$ ruff check drt tests → All checks passed!
$ mypy drt → Success: no issues in 96 files
$ make check-i18n → OK
```

Out of scope (follow-ups)

  • Quickstart GIF / asciinema (growth: create Quickstart GIF / asciinema demo #282) lives in v0.8. This PR rewrites the text that the GIF will eventually record
  • Template contribution doc for users to add their own templates — defer until usage shows demand
  • `drt init --template --no-shell` to skip drt_project.yml / .drt creation for users adding a sync to an existing project — easy follow-up

Coordination

Test plan

  • 9 new tests cover `--template list` / scaffolding (3 templates) / no-overwrite / invalid-name / Pydantic-parse parity
  • 1185 existing tests pass unchanged
  • `make check-i18n` clean
  • ruff + mypy clean (96 files)
  • CI Python 3.10–3.13 all green

🤖 Generated with Claude Code

masukai and others added 2 commits May 25, 2026 10:17
closes #545)

Eighth slice of the Tech Foundation Hardening epic (#538). Closes the
last UX gap on the v0.7.5 Wave 1 list.

The README's old 5-step quickstart had users (1) install (2) run the
interactive wizard (3) seed sample DuckDB data (4) hand-author a sync
YAML (5) run. Steps 2 and 4 were the friction — every newcomer typed
something different and roughly half mistyped. Replaces the path with
a single command:

  $ drt init --template duckdb_to_rest

Three curated templates ship in this PR (per #545's scoping):

- duckdb_to_rest      — DuckDB → REST API POST (httpbin.org, no accounts)
- postgres_to_slack   — PostgreSQL → Slack webhook (operational alerts)
- duckdb_to_hubspot   — DuckDB → HubSpot contacts upsert

Each template is a static, self-contained sync YAML living under
``drt/cli/templates/syncs/``. ``drt init --template list`` enumerates
them; ``drt init --template <name>`` writes ``syncs/<name>.yml`` plus
a minimal ``drt_project.yml`` + ``.drt/.gitignore`` shell and prints
per-template next-steps text (env vars to set, sample tables to seed).

Design notes
------------

- **Static files, not Jinja-rendered.** The on-disk template is what
  the user gets — no per-invocation substitution. Edits are then the
  user's domain. Keeps the scaffolding step boring and predictable.
- **Project shell is created if missing, never overwritten.** Running
  ``--template <name>`` in a directory with an existing ``drt_project.yml``
  appends only the new sync file; the project metadata stays put.
- **Registry lives at ``drt/cli/_init_templates.py``.** Each
  ``TemplateInfo`` carries name + description + next-steps tuple, so
  the CLI handler can render both ``--template list`` and the post-
  scaffold guidance from one source of truth.

README quickstart
-----------------

Rewritten end-to-end:

- New quickstart fits in one ``bash`` block: install + ``init --template``
  + seed + run. Three commands, copy-paste friendly.
- "Other starter templates" subsection lists the other two and points
  at ``--template list`` for the live set.
- "Customizing your sync" subsection demotes the interactive wizard
  to advanced usage — it still exists, just not the default path.
- Links added to ``docs/connectors/`` and to the new
  ``drt sources --detailed`` / ``drt destinations --detailed`` flags
  from #543, both as a discovery hint above the Connectors table and
  in the new "Customizing" subsection.

Tests
-----

``tests/unit/test_cli_init_templates.py`` — 9 tests:

- ``--template list`` exits 0 and surfaces every registered template
- Per-template (parameterized × 3): scaffolds the expected project
  shell, sync file lands under ``syncs/``, next-steps text prints
- ``--template`` does not overwrite an existing ``drt_project.yml``
- ``--template invalid_name`` exits 1 with a pointer to ``list``
- **Validation parity (parameterized × 3)**: each shipped template
  YAML parses as a ``SyncConfig`` via Pydantic. Fails fast if a
  template is shipped that ``drt validate`` would reject — i.e. the
  "ready to run" bar the issue calls for.

Local verification
------------------

  pytest tests/                  → 1185 passed, 1 skipped, 7 deselected
  ruff check drt tests           → All checks passed
  mypy drt                       → Success: no issues in 96 files

Out of scope (follow-ups)
-------------------------

- Quickstart GIF / asciinema (#282) lives in v0.8. This PR rewrites
  the text that the GIF will eventually record.
- README.ja.md updated in a follow-up commit so the i18n-sync marker
  hash can reference this commit.

Refs: #538 (epic), #545 (this issue), #543 (companion UX work —
``--detailed`` flags discovered from the new Connectors note), #282
(future GIF), #297 (v0.9 plugin system — third-party connectors can
register templates the same way).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Mirrors the README.md changes from the previous commit:
- Quickstart collapsed to a three-command block using
  ``drt init --template duckdb_to_rest``
- "Other starter templates" subsection
- "Customizing your sync" subsection demoting the interactive wizard
- ``docs/connectors/`` discovery hint above the Connectors table

Updates the i18n-sync marker hash to the previous commit so
``make check-i18n`` returns to clean.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@masukai masukai added this to the v0.7.5 milestone May 25, 2026
@masukai masukai added feat New feature or request cli CLI commands documentation labels May 25, 2026
@masukai masukai self-assigned this May 25, 2026
@codecov

codecov Bot commented May 25, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@masukai masukai merged commit 9bb998e into main May 25, 2026
8 checks passed
@masukai masukai deleted the feat/init-templates branch May 25, 2026 01:27
@github-actions github-actions Bot locked and limited conversation to collaborators May 25, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

cli CLI commands feat New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

UX: drt init --template <connector> scaffolds + README → docs/ entry-point

1 participant