# S’està començant a aportar codi a Weblate

Comprèn el codi font de Weblate passant per [Codi font del lloc web](https://docs.weblate.org/ca/latest/contributing/code.md), [Interfície del weblate](https://docs.weblate.org/ca/latest/contributing/frontend.md) i [Interns del weblate](https://docs.weblate.org/ca/latest/contributing/internals.md).

## Starting with the codebase

Familiaritzeu-vos amb la base de codis de Weblate, provant els errors etiquetats com [bon primer número](https://github.com/WeblateOrg/weblate/labels/good%20first%20issue).

Us convidem a començar a treballar en aquests temes sense demanar-los. Només cal anunciar-ho al número, perquè quedi clar que algú està treballant en aquest tema.

## Execució de Weblate localment

L’enfocament més còmode per començar amb el desenvolupament de Weblate és seguir [Instal·lació des de fonts](https://docs.weblate.org/ca/latest/admin/install/source.md). Us donarà un entorn Python amb fonts Weblate editables.

1. Clone the Weblate source code:
   ```sh
   git clone https://github.com/WeblateOrg/weblate.git
   cd weblate
   ```
2. Instal·leu Weblate i totes les dependències útils per al desenvolupament:
   ```sh
   uv sync --all-extras --dev
   ```
3. Inicieu un servidor de desenvolupament:
   ```sh
   uv run weblate runserver
   ```
4. Depenent de la vostra configuració, és possible que també vulgueu iniciar els treballadors d’Api:
   ```sh
   uv run ./weblate/examples/celery start
   ```
5. Per executar proves (vegeu [Local testing of Weblate](https://docs.weblate.org/ca/latest/contributing/tests.md#local-tests) per a més detalls):
   ```sh
   . scripts/test-database.sh
   uv run pytest
   ```

#### SEE ALSO
[Instal·lació des de fonts](https://docs.weblate.org/ca/latest/admin/install/source.md)

<a id="devcontainer"></a>

## Development container for tests and lint

The development container prepares Python dependencies, PostgreSQL, Valkey,
compiled translations, and static files for running tests and lint checks.
It supports ordinary clones and linked Git worktrees. Each checkout has its
own containers, network, database, virtual environment, and caches, with no
published host ports in the default test profile. The optional application
profile runs [Weblate and workers for local QA](#dev-docker) with separate
storage and dynamically allocated localhost ports.

Install Docker with the Compose plugin, Git, and Python 3.12 or newer on the
host. For the command-line workflow, also install Node.js 20 or newer and the
Dev Container CLI:

```sh
npm install --global @devcontainers/cli@0.89.0
./scripts/devcontainer up
./scripts/devcontainer doctor
./scripts/devcontainer exec -- uv run pytest weblate/lang/tests.py
./scripts/devcontainer exec -- uv run prek run --all-files
```

Alternatively, open the checkout in Visual Studio Code with its Dev Containers
extension and select Dev Containers: Reopen in Container. Both
workflows use `.devcontainer/devcontainer.json` and wait for bootstrap
to finish. The CLI must be installed separately for the default backend of
`scripts/devcontainer`. To use Docker Compose directly without Node.js or
the Dev Container CLI, pass `--backend compose` before the command:

```sh
./scripts/devcontainer --backend compose up
./scripts/devcontainer --backend compose exec -- uv run pytest weblate/lang/tests.py
```

Both backends share the same test environment for a checkout. The Compose
backend runs bootstrap on each `up` invocation. CI checks both backends on
ARM Linux runners, including concurrent application QA in separate worktrees.

Bootstrap uses the frozen dependency lock and builds `lxml` and `xmlsec`
from source, matching CI. Initial setup requires network access to download
images and dependencies; lint hooks download their environments on first use.
After changing dependencies, rerun:

```sh
./scripts/devcontainer bootstrap
```

Pytest creates and migrates its test database on first use and reuses it on
subsequent runs. To recreate it after incompatible migration changes, pass
`--create-db` to pytest. Existing host virtual environments and local
`weblate/settings.py` are not used by the container.

For a separate task, create a worktree and start its environment:

```sh
git worktree add ../weblate-task -b task/example
cd ../weblate-task
./scripts/devcontainer up
```

The environment identifier is derived from the checkout’s absolute path,
so changing branches preserves the environment. Stop or destroy the environment
before moving or deleting its checkout. Linked worktrees also mount the shared
Git metadata directory at its original path; Git operations therefore affect
the same repository as host Git operations. Other worktrees” sources are not
mounted. Unset `COMPOSE_PROJECT_NAME` when using this workflow, and remove
its assignments from `.env` files in the checkout, `.devcontainer`,
and the directory from which you launch the tools. Initialization rejects
these assignments because they can override the checkout-specific project name.

To stop containers while retaining their data, or explicitly delete their
containers and volumes:

```sh
./scripts/devcontainer stop
./scripts/devcontainer destroy --yes
```

These commands only manage the current checkout’s test environment. They do
not remove its source files or the application environment started by
`rundev.sh`. Tests run through `./rundev.sh test` share this test
environment, so stopping it affects both test launchers. Closing the IDE stops
the entire checkout’s Compose project, including application QA, while retaining
its data. Launcher stop commands affect only their selected profile. Use
`--all` before `stop`, `logs`, or `destroy` to manage both profiles in the
checkout.

If setup fails, use `./scripts/devcontainer doctor` to inspect the source
paths, service connections, dependency consistency, and test assets. Service
readiness checks have a timeout. Containers remain available for inspection;
their logs can be read with **docker compose**:

```sh
docker compose -f .devcontainer/compose.yaml -f .devcontainer/compose.local.json logs
```

The generated `.devcontainer/compose.local.json` is ignored by Git and
contains checkout-specific paths. Keep credentials and host configuration out
of this file.

The shared development image includes native Chromium and its matching driver
from the XtraDeb Ubuntu repository on ARM and amd64. These system packages are
not version-pinned. To fetch browser updates, rebuild without the Docker build
cache and recreate the test container:

```sh
./scripts/devcontainer --backend compose compose -- build --no-cache developer
./scripts/devcontainer --backend compose restart
```

To verify browser startup, page loading, and JavaScript execution, or run the
existing Selenium suite with a required browser:

```sh
./scripts/devcontainer doctor --browser
./scripts/devcontainer browser-test
./rundev.sh browser-test -k test_login_form_accessibility
./rundev.sh browser-test --target weblate/trans/tests/test_selenium.py::SeleniumTests::test_js_unit_tests
```

`browser-test` prepares the isolated test environment, runs browser diagnostics,
and sets `CI_SELENIUM=1` so unavailable WebDriver fails instead of skipping.
It prints pytest’s test totals and skip reasons, preserving legitimate skips and
pytest’s exit status. Additional arguments are passed to pytest; repeat
`--target` to select specific test paths or node IDs instead of the default
Selenium module. `doctor --browser` checks the test profile through either
launcher and reports installed browser and driver versions.

The image sets `WEBLATE_TEST_CHROME_BINARY` and `WEBLATE_TEST_CHROMEDRIVER`
to the installed executable paths. These developer-only variables are shared by
the diagnostic and Selenium tests, avoiding automatic browser downloads. Outside
the image, leaving them unset preserves Selenium’s default browser discovery.
Use your own browser with the application profile’s URL for exploratory QA.

Linux and WSL2 with a checkout in the Linux filesystem are the primary targets.
macOS Docker Desktop and Codespaces use the same configuration, but are not
covered by the Linux CI smoke test. Native Windows paths and remote Docker
daemons are not supported by the host-path mounts.

<a id="dev-docker"></a>

## Execució de Weblate localment a Docker

Install Docker with the Compose plugin, Git, and Python 3.12 or newer on the
host. Start the development application with:

```sh
./rundev.sh
```

This is equivalent to `./scripts/devcontainer --profile app up`. Both commands
use the same launcher and Compose project as the test environment, without
requiring Node.js or the Dev Container CLI for the application profile.

The launcher builds the development image, starts Weblate with supervised web
and Celery workers, and prints the application and Maildev mailbox URLs when
Weblate is ready. Sign in as `admin` with password `admin`. The installation
starts empty; continue with [Afegir projectes i components de traducció](https://docs.weblate.org/ca/latest/admin/projects.md#adding-projects).

Docker assigns free HTTP ports bound to `127.0.0.1`. Each worktree has its own
application database, Valkey instance, data, virtual environment, home, and
caches, separate from the test profile. SMTP, PostgreSQL, and Valkey ports are
not published. Weblate uses the discovered application URL for generated links
and authentication origins. To display the current URLs again:

```sh
./rundev.sh urls
./rundev.sh urls --json
```

To exercise real background workers through complete application journeys:

```sh
./rundev.sh application-test
```

This is also available as `./scripts/devcontainer application-test`. It starts
the application profile and uses its administrator API token to import a small
component archive, save a translation, request a background commit, and inspect
the committed Git file. It then checks the exported ZIP, eventual translation
statistics in the API and rendered application page, translation memory, and a
translation notification delivered to
Maildev. Export generation itself is synchronous; its contents must reflect the
completed background work.

A separate transaction check queues a real task before its fixture row is
committed, waits for a retry, and verifies successful redelivery after commit.
The suite requires non-eager Celery and the application’s Valkey broker and
Maildev. Polls have deadlines, worker task failures include their tracebacks,
and failures print the application service logs. CI runs these journeys in both
the Docker development job and concurrent isolated worktrees.

Each invocation creates a uniquely named `celery-qa-` project and notification
recipient with an unusable password. These fixtures remain available for
inspection, including after failure; the suite does not reset existing data.
Remove these projects and users through the application when finished, or
**destroy --yes** the disposable application environment.

Ports can change after containers are recreated or restarted. Use
`./rundev.sh restart` to restart and rediscover them; direct Docker restarts
cannot initialize the application domain. Ordinary startup reuses unchanged
containers. Application containers do not restart automatically after Docker
restarts. When the image changes Python minor versions, startup recreates the
application virtual environment and reinstalls dependencies. Application data
is retained.

To access the application database from inside its container:

```sh
./rundev.sh exec -- weblate dbshell
```

The application service definitions are in `dev-docker/docker-compose.yml`
and are included by the shared Compose configuration. Use the launchers to
initialize paths and ports. For other Compose operations, use
`./rundev.sh compose -- COMMAND` (or existing shortcuts such as
`./rundev.sh ps`). Project-wide Compose commands can affect both profiles.

Existing development environments are not migrated automatically. Before
updating from the old launcher, stop its containers with its `./rundev.sh stop`
command. If already updated, identify the old containers using `docker ps`
and stop them explicitly. The new launcher leaves their databases, volumes,
and `dev-docker/data/` untouched and starts with fresh application data.

To execute tests, run the script with the `test` parameter and pytest arguments,
for example running only tests in the `weblate.machine` module:

```sh
./rundev.sh test --exitfirst weblate/machine
```

The command automatically starts and bootstraps the [development container](#devcontainer) using Docker Compose, without requiring the Dev Container CLI.
It runs independently of the application and workers, with separate databases,
virtual environments, and caches. Each invocation refreshes dependencies and
test assets before running pytest.

To display application logs:

```sh
./rundev.sh logs
```

To stop only the application profile, retaining its data:

```sh
./rundev.sh stop
```

Use `./scripts/devcontainer stop` to stop only tests. To stop or destroy both
profiles, including their volumes when destroying:

```sh
./rundev.sh --all stop
./rundev.sh --all destroy --yes
```

Without `--all`, `destroy --yes` removes only the selected profile’s
containers and volumes. Other worktrees remain running.

#### WARNING
Aquest contenidor no és adequat per a la producció. La seguretat es sacrifica per facilitar el desenvolupament.

<a id="devel-demo"></a>

## Arrancar la vostra instància de desenvolupament

És possible que vulgueu utilitzar [`import_demo`](https://docs.weblate.org/ca/latest/admin/management.md#weblate-admin-import_demo) per crear traduccions de demostració i [`createadmin`](https://docs.weblate.org/ca/latest/admin/management.md#weblate-admin-createadmin) per fer un usuari administrador.

Si també teniu instal·lat [Facturació](https://docs.weblate.org/ca/latest/admin/optionals.md#billing), podeu utilitzar [`billing_demo`](https://docs.weblate.org/ca/latest/admin/management.md#weblate-admin-billing_demo) per crear un projecte de facturació de demostració.

## Codificació de Weblate amb PyCharm

PyCharm és un IDE conegut per a Python, aquí teniu algunes directrius per ajudar-vos a configurar el vostre projecte Weblate.

Tenint en compte que acabeu de clonar el dipòsit de GitHub a una carpeta, només cal que obriu-lo amb PyCharm. Un cop obert l’IDE, el primer pas és especificar l’intèrpret que voleu utilitzar:

![image](images/pycharm-1.png)

Seleccioneu l’entorn `.venv` creat per `uv sync --all-extras --dev` perquè coincideixi amb la configuració de desenvolupament de la línia d’ordres. També podeu deixar que PyCharm us creï un entorn Python, però es prefereix l’entorn gestionat per UV:

![image](images/pycharm-2.png)

No oblideu instal·lar les dependències un cop l’intèrpret estigui configurat. Quan utilitzeu l’entorn gestionat per uv preferit, executeu `uv sync --all-extras --dev` des de la consola.

El segon pas és configurar la informació adequada per utilitzar Django de manera nativa dins de PyCharm: la idea és poder activar immediatament les proves d’unitat a l’IDE. Per a això, heu d’especificar el camí arrel del projecte Django i el camí a la seva configuració:

![image](images/pycharm-3.png)

Aneu amb compte, l’arrel del projecte Django és l’arrel real del dipòsit, no el subdirectori Weblate. Quant a la configuració, podeu utilitzar el `weblate/settings_test.py` del repositori, però podeu crear la vostra pròpia configuració i configurar-la allà.

L’últim pas és executar el servidor i posar punts d’interrupció al codi per poder depurar-lo. Això es fa creant una nova configuració de «Servidor Django»:

![image](images/pycharm-4.png)![image](images/pycharm-5.png)

#### HINT
Aneu amb compte amb la propietat anomenada No reload: evita que el servidor es torni a carregar en directe si modifiqueu fitxers. Això permet que els punts d’interrupció del depurador existents persisteixin, quan normalment es descartarien en tornar a carregar el servidor.
