Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 28 additions & 5 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@

## What this repo is

This is a **Copier template repository**. Running `copier copy . /path/to/dest --trust`
renders the `template/` directory into a new Python project. This repo is NOT a runnable
Python application — it is the source that generates other applications.
This repository is a **Copier template repository** (a meta-project). Running Copier against
this repo **generates** a new Python project by rendering the `template/` directory into a
destination folder.

The `template/` directory contains Jinja2-rendered files (`.jinja` suffix or Copier
conventions). Do not edit rendered output here; edit the source templates.
> [!WARNING]
> Copier can run **template tasks** during `copier copy`/`copier update`. Only use the
> `--trust` flag with templates you trust.

## Directory structure

Expand Down Expand Up @@ -78,6 +79,28 @@ copier copy . /tmp/test-output --trust \

Clean up afterward: `rm -rf /tmp/test-output`

## Copy vs update (important)

- **Generate** a new project: `copier copy TEMPLATE DESTINATION`.
- **Update** an existing generated project to the latest template version: `copier update`.

For updates, Copier works best when:

1. The template includes a valid `.copier-answers.yml`.
2. The template is versioned with git tags.
3. The destination folder is versioned with git.

### Never edit `.copier-answers.yml` by hand

Do not manually change the answers file (`.copier-answers.yml`, controlled by `_answers_file` in
`copier.yml`). The update algorithm relies on it and manual edits can lead to unpredictable diffs.

### Handle update conflicts

When Copier can't apply a change automatically you may see `*.rej` files. Review them before
committing. The recommended approach is typically a pre-commit hook that forbids committing
rejection files.

## How tests work

Tests live in `tests/`. They use pytest to call `copier copy` programmatically,
Expand Down
39 changes: 36 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ Prerequisites:
- 🌱 Git
- 🧩 `copier`

> [!WARNING]
> Generate from **trusted templates**: when a template uses Copier `tasks`, they run with the
> same access level as your user.

Generate a project from this repo root:

```bash
Expand All @@ -57,6 +61,8 @@ just ci
- ✅ **`--defaults`**: accept defaults for all questions
- 🔒 **`--trust`**: allow post-generation tasks (bootstraps `uv`, installs deps, runs checks, installs hooks)
- 🤖 **`--data key=value`**: provide answers non-interactively (great for scripts)
- 📌 **`--data-file path.yml`**: provide answers from a YAML file
- 🔖 **`--vcs-ref ref`**: generate from a specific git ref (tag/branch/commit) of the template

## Template options 🧰

Expand All @@ -74,13 +80,27 @@ During `copier copy`, you’ll be prompted for:

## Updating a generated project 🔁

Generated projects store answers in `.copier-answers.yml`. To update a project to the latest template:
Generated projects store answers in `.copier-answers.yml`.

For the update to work best, ensure:

1. The template includes a valid `.copier-answers.yml`
2. The template is versioned with git tags
3. The destination folder is versioned with git

Then, from inside the generated project folder (make sure `git status` is clean), run:

```bash
copier update --trust --defaults
copier update --trust
```

This template is intentionally conservative about overwriting user-edited files (see `copier.yml` → `_skip_if_exists`).
If Copier cannot apply some changes automatically, it may produce `*.rej` files containing unresolved diffs.
Review and resolve those before committing.

Important:

- Never manually edit `.copier-answers.yml` — it can break Copier’s update algorithm.
- This template is intentionally conservative about overwriting user-edited files (see `copier.yml` → `_skip_if_exists`).

## Developing this template 🧪

Expand All @@ -106,6 +126,14 @@ Other useful commands:

## FAQ ❓

### Can Copier be applied over a preexisting project?

Yes. Copier understands this use case (it powers features like updating).

### Should I edit `.copier-answers.yml` manually?

No. Updates rely on that file; editing it manually can lead to unpredictable diffs.

### Why is this “uv-first”?

Both this template repo and generated projects expect a committed `uv.lock`. In CI and locally, `uv sync --frozen` keeps installs reproducible and fails fast on drift.
Expand All @@ -117,3 +145,8 @@ If you enable coverage upload in your CI setup, configure a GitHub **repository
## References 🔗

- Copier docs: `https://github.com/copier-org/copier`
- Copier docs (official): generating, updating, configuring, FAQ
- `https://copier.readthedocs.io/en/stable/creating/`
- `https://copier.readthedocs.io/en/v6.0.0/updating/`
- `https://copier.readthedocs.io/en/stable/configuring/`
- `https://copier.readthedocs.io/en/stable/faq/`
22 changes: 22 additions & 0 deletions template/CLAUDE.md.jinja
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,28 @@ just precommit-install
| Full CI | `just ci` |
{% if include_docs %}| Serve docs | `just docs` |{% endif %}

## Copy vs update (important)

- **Generate** a new project: `copier copy TEMPLATE DESTINATION`.
- **Update** an existing generated project to the latest template version: `copier update`.

For updates, Copier works best when:

1. The template includes a valid `.copier-answers.yml` file.
2. The template is versioned with git tags.
3. The destination folder is versioned with git.

### Never edit `.copier-answers.yml` by hand

Do not manually change the answers file (`.copier-answers.yml`, controlled by `_answers_file` in
`copier.yml`). The update algorithm relies on it and manual edits can lead to unpredictable diffs.

### Handle update conflicts

When Copier can't apply a change automatically you may see `*.rej` files. Review them before
committing. The recommended approach is typically a pre-commit hook that forbids committing
rejection files.

## Package structure

Source code lives under `src/{{ package_name }}/`.
Expand Down
35 changes: 31 additions & 4 deletions template/README.md.jinja
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@
- **Docs**: MkDocs site in `docs/` (served via `just docs`)
{%- endif %}

## Quickstart

Prerequisites:
## Prerequisites

- Python {{ python_min_version }}+
- `uv` (install from `https://astral.sh/uv/`)
- `uv` (install from https://astral.sh/uv/)

## Quickstart

Create the environment and install dependencies:

Expand All @@ -41,6 +41,33 @@ just ci
- `just docs`
{%- endif %}

## Copier usage (generated-project docs)

This project was generated with Copier.

### Generating again

If you run `copier copy` into a preexisting destination, Copier will "recopy" it and ignore prior history.
This is **not** the recommended approach for updates when you want Copier to respect your project evolution.

### Updating this project

If the template includes a valid `.copier-answers.yml` file and both the template and this project are versioned with git tags,
then you can update by running:

```bash
copier update
```

During updates, Copier compares the template evolution with your local changes and may create `*.rej` files when it can't resolve conflicts automatically.
Review those files before committing.

⚠️ Never edit `.copier-answers.yml` manually.

### Trusted templates

Generate projects only from trusted templates, as Copier tasks run with the same level of access as your user.

## Project layout

- `src/{{ package_name }}/`: package source
Expand Down