--- name: update-software-dependencies description: 'Add or update software dependencies following the REUSE compliance workflow. Use when adding packages to pyproject.toml, updating credits/CREDITS.md, running credits/update_credits_licenses.py to download license files, adding REUSE.toml annotations, and verifying reuse lint and pre-commit hooks pass.' --- # Adding or Updating Software Dependencies This document describes the full workflow for adding a new dependency or updating an existing one in the ArduPilot Methodic Configurator project. It is intended for both human contributors and AI agents. All steps must be completed in order for the project to remain REUSE-compliant and its dependency credits to stay accurate and up to date. ## Overview ```text pyproject.toml → credits/CREDITS.md → credits/update_credits_licenses.py → run script to download license files → REUSE.toml ``` --- ## Step 1 — Add the dependency to `pyproject.toml` Add the package to the appropriate section of `pyproject.toml`: - Runtime dependency → `[project] dependencies` - Development tooling → `[project.optional-dependencies] dev` - CI-only → `[project.optional-dependencies] ci_headless_tests` Pin the exact version (use `==`). For packages sensitive to the Python runtime version, use environment markers (e.g., `python_version < '3.10'`). --- ## Step 2 — Update `credits/CREDITS.md` Add a row to the appropriate table in `credits/CREDITS.md`: - **Direct** runtime or GUI dependencies → "It directly uses:" table - **Indirect** (transitive) dependencies → "It indirectly uses:" table Each row must have: | Column | Content | |----------|--------------------------------------------------------------| | Software | Markdown link to project homepage | | License | Markdown link to the license URL on the project's repository | The author name (e.g., "by Mark Pointing") must be included in the Software column whenever it is known and the dependency is from an individual contributor rather than an organisation. Example row for a direct dependency: ```markdown | [simpleeval](https://github.com/danthedeckie/simpleeval) | [MIT License](https://github.com/danthedeckie/simpleeval/blob/main/LICENCE) | ``` --- ## Step 3 — Update `credits/update_credits_licenses.py` Add the new package to the correct list in `credits/update_credits_licenses.py`: - `direct_dependencies` — for packages listed in the direct-use table - `indirect_dependencies` — for packages listed in the indirect-use table Each entry is a dict with two keys: ```python {"name": "", "license_url": ""} ``` Rules for the URL: - Use a **raw** URL that serves the plain-text license (e.g., `https://raw.githubusercontent.com/...`) - The filename at the end of the URL determines the downloaded file's suffix (e.g., `…/main/LICENCE` → `-LICENCE`) - For packages hosted on Mozilla's site (MPL-2.0) provide `https://mozilla.org/MPL/2.0/` and the download function will use a fixed HTML filename automatically (see `Scrollable_TK_frame`, `Python_Tkinter_ComboBox`) --- ## Step 4 — Run the download script Execute the script from the `credits/` directory. It reads both lists and downloads each license file: ```bash cd credits python update_credits_licenses.py ``` The script saves each file as `-` in the current directory. Check the output log to confirm all downloads succeeded. Re-run if any fail due to network errors. --- ## Step 5 — Add entries to `REUSE.toml` For each newly downloaded license file, append an `[[annotations]]` block to `REUSE.toml` with the correct path, copyright notice, and SPDX license identifier. ### Finding the copyright holder 1. Open the downloaded license file (e.g., `credits/simpleeval-LICENCE`). 2. Look for a line starting with `Copyright` or `©` at the top. 3. If the license file contains no copyright notice, use the project author name from the corresponding entry in `credits/CREDITS.md` or the package's repository. ### Choosing the SPDX identifier Use the canonical [SPDX license list](https://spdx.org/licenses/). Common mappings: | License text says | SPDX-License-Identifier | |------------------------------------|-------------------------| | MIT License | `MIT` | | Apache License, Version 2.0 | `Apache-2.0` | | BSD 2-Clause | `BSD-2-Clause` | | BSD 3-Clause | `BSD-3-Clause` | | Mozilla Public License 2.0 | `MPL-2.0` | | GNU General Public License v3 | `GPL-3.0-or-later` | | GNU Lesser GPL v3 | `LGPL-3.0-or-later` | | Python Software Foundation License | `PSF-2.0` | | MIT-CMU License (Pillow) | `MIT-CMU` | If no standard SPDX identifier exists (e.g., Inno Setup proprietary license), use a `LicenseRef-` identifier (e.g., `LicenseRef-Inno-Setup`) and place the license text in `LICENSES/LicenseRef-Inno-Setup.txt`. ### Example `REUSE.toml` block ```toml [[annotations]] path = "credits/simpleeval-LICENCE" SPDX-FileCopyrightText = "Copyright (c) 2013 Daniel Fairhead" SPDX-License-Identifier = "MIT" ``` For files that have no copyright notice at all (e.g., the Apache 2.0 generic license text at `argparse_check_range-LICENSE-2.0`), credit the known package author: ```toml [[annotations]] path = "credits/argparse_check_range-LICENSE-2.0" SPDX-FileCopyrightText = "Dmitriy Kovalev" SPDX-License-Identifier = "Apache-2.0" ``` --- ## Step 6 — Verify REUSE compliance ```bash reuse lint ``` All reported errors must be resolved before committing. Common errors and fixes: | Error | Fix | |------------------------------------------|------------------------------------------------------------------| | `credits/: no license identifier` | Add the `SPDX-License-Identifier` to the REUSE.toml annotation | | `credits/: no copyright notice` | Add `SPDX-FileCopyrightText` to the REUSE.toml annotation | | `Missing license file LICENSES/.txt` | Add the license text to `LICENSES/` when using `LicenseRef-` IDs | --- ## Step 7 — Run pre-commit checks ```bash pre-commit run --all ``` All hooks must pass (ruff, pylint, mypy, reuse, etc.) before pushing. --- ## Summary checklist - [ ] `pyproject.toml` — dependency added with pinned version - [ ] `credits/CREDITS.md` — row added to the correct table - [ ] `credits/update_credits_licenses.py` — entry added to the correct list - [ ] License file downloaded (`cd credits && python update_credits_licenses.py`) - [ ] `REUSE.toml` — `[[annotations]]` block added for each new license file - [ ] `reuse lint` passes - [ ] `pre-commit run --all` passes