# Teilchensammler: Collect parts in a list

## Badges

[![status-badge](https://ci.c-base.org/api/badges/9/status.svg)](https://ci.c-base.org/repos/9)
[![Tested with Hypothesis](./docs/hypothesis-tested-brightgreen.svg)](https://hypothesis.readthedocs.io/)
![Tests Status](./docs/tests-badge.svg)
![Coverage Status](./docs/coverage-badge.svg)

<!--toc:start-->
- [Teilchensammler: Collect parts in a list](#teilchensammler-collect-parts-in-a-list)
  - [Badges](#badges)
  - [Development](#development)
    - [Getting started](#getting-started)
      - [Python](#python)
      - [PostgreSQL](#postgresql)
      - [Get the code](#get-the-code)
    - [Making changes](#making-changes)
    - [Using the App](#using-the-app)
  - [Dependency management](#dependency-management)
    - [Installing dependencies](#installing-dependencies)
  - [More on tools that are used](#more-on-tools-that-are-used)
    - [Direnv (automatic venv)](#direnv-automatic-venv)
      - [Subshells or Shells started from Editors](#subshells-or-shells-started-from-editors)
    - [just](#just)
<!--toc:end-->

## Development

This project makes use of several tools:

- [direnv] is used to set up environment variables and activate the virtualenv. I
recommend installing it and integrate it into your favourite shell.
- [just] is used as a task runner.
- [woodpecker-cli] is used to lint `.woodpecker/workflow.yaml`. It is available
from [homebrew].
- [pytest] is the test runner. Invoke it using `just test` (any arguments will be
passed through to pytest).
  Several pytest-plugins are used:
  - [hypothesis]
  - [pytest-django]
  - [pytest-cov]

### Getting started

#### Python

Have Python >= 3.12 installed. I recommend [pyenv] (which in turn is easily
installed by [homebrew]).

#### PostgreSQL

Set up PostgreSQL, a role and a schema.

I have it on localhost, using the project name for role and schema name, and
password. Using a VM, docker or even a remote instance is possible: See
`.env.test` for providing connection information.

#### Get the code

Clone the repo. `cd` into the project directory. ([direnv] should activate the
virtualenv.) Run `python -m pip install -U pip` to upgrade pip. Then `python -m
pip install -r requirements/dev.txt`.

Launch the dev server: `just serve` (or `python -m django runserver` when you
don't have just).

### Making changes

Change code, settings, templates, dependencies as you see fit. Run `just lint`
repeatedly. Don't forget migrations. Commit often. Please add tests.

### Using the App

`just serve` and open
[localhost:8000/](http://localhost:8000/collector/) in your browser. Start
entering Teile.

## Dependency management

This project uses [pip-compile-multi] for hard-pinning dependencies versions.
Please see its documentation for usage instructions. In short,
`requirements/prod.in` contains the list of direct requirements with occasional
version constraints (like `Django<2`) and `requirements/prod.txt` is
automatically generated from it by adding recursive tree of dependencies with
fixed versions. The same goes for `test` and `dev`.

To upgrade dependency versions, run `just deps` (or `pip-compile-multi --uv`).
And to install those packages run `just sync`. To run both of those:

```shell
just deps sync
# OR
just fd
# OR
just freshdeps
```

To add a new dependency without upgrade, add it to the appropriate .in file and
run `pip-compile-multi --no-upgrade` (no [just] recipe yet).

### Installing dependencies

For installation of dependencies always use `requirement/*.txt` files.

For example, the command `pip install -U -r requirements/dev.txt` will install
testing requirements and development tools.

A useful command is `pip-sync requirements/dev.txt`, it uninstalls packages
from your virtualenv that aren't explicitly specified as dependencies.

## More on tools that are used

These are not strictly necessary but very convenient.

### Direnv (automatic venv)

When direnv is [integrated into the shell](https://direnv.net/docs/hook.html)
entering the project directory for the first time will cause direnv to create a
hidden directory for the virtual environment.

It will also activate that existing virtualenv automatically upon entering the
project directory.

#### Subshells or Shells started from Editors

If your editor spawns a shell window or new terminal, it might be necessary to
`direnv reload` before running any commands. This will make sure direnv has
things set up. neovim's terminal requires this.

### just

[just] is used as a task runner. Think "makefile" but less confusing. (make is
a build tool and task runner and much more, just intends to be a task runner.)

If you don't want to install just, you can still look at its `justfile` to see
how test runners, linters, dev servers and such are to be executed.

----

[pip-compile-multi]: https://pypi.org/project/pip-compile-multi/
[direnv]: https://direnv.net/
[just]: https://just.systems/
[pyenv]: https://github.com/pyenv/pyenv
[homebrew]: https://brew.sh/
[pytest]: https://pytest.org/
[woodpecker-cli]: https://formulae.brew.sh/formula/woodpecker-cli
[hypothesis]: https://hypothesis.readthedocs.io/en/latest/
[pytest-django]: https://pytest-django.readthedocs.io/en/latest/
[pytest-cov]: https://pytest-cov.readthedocs.io/en/latest/