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
94 changes: 67 additions & 27 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,60 +1,100 @@
# Copier uv-first Python template
# Python Starter Template

This repository is a **Copier** template that generates a modern Python library or application layout using **uv** for dependency management, **ruff** for formatting/linting, and **basedpyright** for type checking. Optional prompts add **NumPy**, **pandas**, and **MkDocs** when you want a data-oriented or documented project.
This repository is a **Copier template** for generating a modern, batteries-included Python project that is:

Reference: [copier-org/copier README](https://github.com/copier-org/copier?tab=readme-ov-file)
- **uv-first**: reproducible installs with a committed `uv.lock`
- **fast to iterate**: one `just ci` command mirrors your local/CI checks
- **strict by default**: ruff for lint/format and basedpyright for type checking
- **optionally data- and docs-ready**: toggle NumPy/pandas and MkDocs during generation

## Prerequisites
This repo is the **template source** (a meta-project), not the generated project itself.

## What you get

- **Dependency workflow**: `uv` + lockfile-first installs (`uv sync --frozen`)
- **Quality gates**: ruff (format + lint), basedpyright (strict typing), pytest
- **Automation**: pre-commit hooks and a `justfile` with common commands
- **CI-ready defaults**: GitHub Actions workflow and coverage upload wiring (optional)
- **Update-friendly**: conservative `copier update` behavior via `_skip_if_exists`

## Quickstart: generate a new project

Prerequisites:

- Python 3.11+
- Git
- `uv`
- `copier`

## Getting started (developing this template)
- `copier` (installed however you prefer)

Sync dev dependencies (uses the committed lockfile):
Generate a project from this repo root:

```bash
uv sync --frozen --extra dev
copier copy . /path/to/new-project --trust --defaults
```

Run template tests:
Common flags:

- **`--defaults`**: accept defaults for all questions
- **`--trust`**: allow running post-generation tasks (install, format, type-check, hooks)
- **`--data key=value`**: answer questions non-interactively (useful in scripts/CI)

After generation, the new project will include a `justfile`. Typical first run:

```bash
uv run pytest
just ci
```

## Generating a project from this template
## Template options (prompts)

During `copier copy`, you’ll be asked for:

- **Project identity**: `project_name`, `project_slug`, `package_name`, description, author, GitHub org/user
- **Python baseline**: minimum version (3.11 / 3.12 / 3.13)
- **Add-ons**:
- **Docs**: MkDocs setup (`include_docs`)
- **Data stack**: NumPy (`include_numpy`) and pandas (`include_pandas_support`)
- **Codecov**: leave the `codecov_token` prompt empty; prefer the GitHub secret described below

## Updating a generated project

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

```bash
copier copy . /path/to/new-project --trust --defaults
copier update --trust --defaults
```

Common flags:
This template is intentionally conservative about overwriting user-edited files (see `copier.yml`’s `_skip_if_exists`).

- `--defaults`: accept defaults for all questions
- `--trust`: allow running template tasks (post-generation commands)
- `--data key=value`: provide answers non-interactively
## Developing this template

## Updating a generated project
Install dev dependencies for the template repo (uses the committed lockfile):

If you generated a project from this template, Copier stores answers in `.copier-answers.yml` in the generated project.
```bash
just sync
```

To update:
Run the full local CI mirror:

```bash
copier update --trust --defaults
just ci
```

Other useful commands:

- **`just fmt`**: format
- **`just lint`**: lint
- **`just type`**: type check
- **`just test`**: run template integration tests (renders the template and asserts output)

## FAQ

### Why does CI use `uv sync --frozen`?
### 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.

### How does Codecov work in generated projects?

This template repository and generated projects are expected to commit a `uv.lock`. That keeps installs reproducible in CI and locally.
If you enable coverage upload in your CI setup, configure a **repository secret** named `CODECOV_TOKEN` in GitHub. You typically do not need to provide a token as a Copier answer.

### Codecov in generated projects
## References

The template can wire GitHub Actions to upload coverage. Configure a **repository secret** named `CODECOV_TOKEN` in GitHub (Codecov’s token); you do not need to paste that token into Copier answers.
- Copier docs: `https://github.com/copier-org/copier`
39 changes: 28 additions & 11 deletions template/README.md.jinja
Original file line number Diff line number Diff line change
Expand Up @@ -2,34 +2,51 @@

{{ project_description }}

## What this project includes

- **uv-first workflow** with a committed lockfile (`uv.lock`)
- **Quality gates**: ruff (format + lint), basedpyright (type checking), pytest
- **One-command workflows** via `just` (mirrors local/CI checks)
{% if include_docs -%}
- **Docs**: MkDocs site in `docs/` (served via `just docs`)
{%- endif %}

## Quickstart

Install `uv` (see `https://astral.sh/uv/`), then:
Prerequisites:

```bash
uv sync --frozen --extra dev --extra test{% if include_docs %} --extra docs{% endif %}
```
- Python {{ python_min_version }}+
- `uv` (install from `https://astral.sh/uv/`)

Run tests:
Create the environment and install dependencies:

```bash
uv run pytest
uv sync --frozen --extra dev --extra test{% if include_docs %} --extra docs{% endif %}
```

## Development

Common commands:
Run the full local CI mirror:

```bash
just ci
```

## Common commands

- `just test`
- `just fmt`
- `just lint`
- `just type`
- `just ci`
{% if include_docs -%}
- `just docs`
{%- endif %}

## Project layout

- `src/{{ package_name }}/`: library code
- `src/{{ package_name }}/`: package source
- `tests/`: test suite
{% if include_docs -%}
- `docs/`: documentation source
- `docs/`: documentation
{%- endif %}

## License
Expand Down