Contributing¶
Thank you for considering a contribution to Cloup.
Getting started¶
Please discuss a proposed change before opening a pull request:
Search the issue tracker for an existing report or proposal.
Open an issue describing the problem, the desired behavior, and your proposed approach.
Wait for a maintainer to confirm that the change is appropriate and agree on its scope.
If the maintainer agrees, fork the repository, create a branch, implement the change, and open a pull request linked to the issue.
Starting with an issue avoids duplicated work and gives maintainers and contributors a place to settle API and compatibility decisions before code is written.
Development¶
Set up a development environment¶
Cloup uses Hatch for isolated Python environments and Task as its project command interface.
To set up a development environment you have two options:
(recommended) use the Dev Container configuration provided with the repository; this is the quickest option when Docker is available. The dev container also includes the experimental Task build with the TUI described in the box below.
Install them manually.
Experimental TUI for Task
Cloup’s maintainer uses an experimental build of Task including a TUI he’s authored and submitted as a PR. The TUI greatly improves DX when running tasks with parallel dependencies.
If you use the Dev Container, it comes pre-installed. If you chose the manual setup route, download it from the task-tui releases page as described below. Refer to the PR description for how to use it.
Option 1: using the Dev Container¶
The repository includes a Dev Container configuration for clients such as Visual Studio Code and GitHub Codespaces. It requires Docker when run locally.
All you have to do is open the repository folder in the container. For example, in Visual Studio Code, make sure you have the Dev Container Extension installed; then follow these simple steps.
After the container is created, the dev Python virtual environment is created
automatically (using task env) and linked as .dev-container-venv in the
repository directory. Visual Studio Code selects that interpreter by itself, because
the container waits for the environment before letting editors connect. In other IDEs,
select it manually:
.dev-container-venv/bin/python
The link is ignored by Git and points nowhere outside the container.
The container provides two Task executables:
taskis an official released build used for the project commands.task-tuiis a pinned build of the experimental TUI written by Cloup’s maintainer, which was submitted as a PR.
Run the experimental build directly with task-tui --tui or use its tui
alias. The stable task command remains unchanged.
Option 2: manual setup¶
Install Hatch¶
You can install hatch with either pipx or uv:
uv tool install hatch
pipx install hatch
Hatch creates environments automatically when their commands are first used.
By default, Hatch environments are stored in Hatch’s global data directory.
If you prefer to store them in each project/repository folder, under a .hatch/
subfolder, run:
$ hatch config set dirs.env.virtual .hatch
Install Task¶
To install the canonical Task, you can either follow the official installation guide for your OS or install it through the unofficial Python package:
$ uv tool install "go-task-bin>=3.46.1"
$ pipx install "go-task-bin>=3.46.1"
(Optional) Install Task with TUI¶
Builds are published on the task-tui releases page for Linux, macOS, and Windows.
Download the archive for your platform and extract task-tui into a
directory on your PATH. On Linux with an x86-64 processor:
$ mkdir -p "$HOME/.local/bin"
$ curl -fsSL https://github.com/janluke/task-tui/releases/latest/download/task-tui_linux_amd64.tar.gz \
| tar -xz -C "$HOME/.local/bin" task-tui
Replace linux_amd64 with linux_arm64, darwin_amd64 or
darwin_arm64 as needed; the Windows archives are .zip files.
Consider adding the tui alias to your shell’s startup file, such as ~/.bashrc
or ~/.zshrc:
alias tui='task-tui --tui'
The build is installed under a distinct name, so it does not replace the
canonical task executable. To update it later, download a newer release the
same way.
Set up a Python venv for your IDE¶
Even if Hatch creates environments automatically when needed, you probably still want to set a Python environment for your IDE.
To create the dev environment and print its location, run:
$ task env
Select the reported Python interpreter in your IDE. The environment contains Cloup in editable mode together with the test, coverage, and typing dependencies, so it can run tests and type checks directly from the IDE.
Using Task¶
Run task --list to see all available project commands.
Invoke one project task by name, for example:
$ task fix
When several task names are provided on the command line, Task runs them
sequentially by default.
Use --parallel to run independent requested tasks concurrently:
$ task --parallel lint docs
Dependencies declared by a single task run concurrently by default, so aggregate
commands such as task test:all and task qa:all need no --parallel flag.
Use --failfast when one failure should cancel the other running tasks:
$ task --failfast qa:all
The project does not impose a concurrency limit.
Set one for a particular run with task --concurrency N COMMAND or the
TASK_CONCURRENCY environment variable. For example, to run tasks sequentially:
$ task --concurrency 1 qa:all
For contiguous, failure-focused logs, use Task’s grouped output:
$ task --output group --output-group-error-only qa:all
Using the experimental Task TUI¶
When running tasks that execute multiple tasks in parallel, it’s very useful to be able to inspect the output of each one separately in a UI.
The Dev Container includes a pinned build of the branch as task-tui; run it with
the tui alias while keeping the official release available as task, e.g.:
tui qa:all
Code quality¶
Use the following commands while developing:
Command |
Purpose |
|---|---|
|
Lint the code and check its formatting style. |
|
Fix lint violations and format the code with Ruff. |
|
Type-check the code in the development environment. |
|
Type-check in every Python and Click compatibility environment. |
Testing¶
The primary development environment and every test environment expose the same test and typing scripts. The test matrix covers every supported Python version with the latest compatible Click release, plus older supported Click release lines on the latest Python. This ensures that type checking observes the same dependencies and standard library as the corresponding test run.
Command |
Purpose |
|---|---|
|
Run tests with the development environment. |
|
Run every Python and Click compatibility environment in parallel. |
|
Upgrade Click to the latest release allowed by each test environment. |
|
Run tests in the development environment and generate terminal and HTML coverage reports. |
|
Collect coverage from every test environment in parallel and combine the results. |
Use -- before arguments that should be forwarded to pytest.
For example, stop after the first failure with:
$ task test -- -x
For example, run the full test matrix sequentially with:
$ task --concurrency 1 test:all
Quality assurance workflows¶
The aggregate tasks are the recommended checks before submitting changes:
Command |
Purpose |
|---|---|
|
Run lint and formatting checks first, then type checking, tests, and documentation using the primary environments. |
|
Run lint, formatting, and documentation checks plus typing and tests in every test environment. |
Use task qa during routine development. Run task qa:all for changes that
may affect supported Python or Click versions.
Documentation¶
Build the documentation and treat warnings as errors with:
$ task docs
Start a live-reloading server that watches the documentation and package sources with:
$ task docs:serve
Pass -a after -- when changing CSS or other static files so Sphinx rebuilds
every page:
$ task docs:serve -- -a
Dependencies¶
Development dependencies belong to their corresponding environments in
hatch.toml.
The development and Python test environments deliberately resolve compatible
versions afresh so scheduled CI can detect dependency compatibility problems.
Reproducibility-sensitive lint, documentation, and package-checking environments use
committed PEP 751 lockfiles.
Regenerate an affected lockfile after changing a locked environment:
$ hatch env lock ENV_NAME
Use --upgrade or --upgrade-package <package> only when intentionally
upgrading locked dependencies:
$ hatch env lock ENV_NAME --upgrade
Commit each changed pylock.*.toml file with the configuration change that
required it, or as part of a clearly identified intentional dependency refresh.
Building distributions¶
Build the source distribution and wheel and validate their metadata with:
$ task build
Pull requests¶
Keep pull requests focused on the scope agreed in the issue.
Include tests for behavioral changes and update user documentation when the public
API or documented behavior changes.
Before requesting review, run the appropriate QA command described above. Also run
task build after changing packaging, project metadata, package layout, or build
hooks.