|
| 1 | +<!-- |
| 2 | +SPDX-FileCopyrightText: 2024-2026 Amilcar do Carmo Lucas <amilcar.lucas@iav.de> |
| 3 | +
|
| 4 | +SPDX-License-Identifier: GPL-3.0-or-later |
| 5 | +--> |
| 6 | + |
| 7 | +# Adding or Updating Software Dependencies |
| 8 | + |
| 9 | +This document describes the full workflow for adding a new dependency or updating an existing one in the |
| 10 | +ArduPilot Methodic Configurator project. |
| 11 | +It is intended for both human contributors and AI agents. |
| 12 | + |
| 13 | +All steps must be completed in order for the project to remain REUSE-compliant and its dependency |
| 14 | +credits to stay accurate and up to date. |
| 15 | + |
| 16 | +## Overview |
| 17 | + |
| 18 | +```text |
| 19 | +pyproject.toml → credits/CREDITS.md → credits/update_credits_licenses.py |
| 20 | + → run script to download license files → REUSE.toml |
| 21 | +``` |
| 22 | + |
| 23 | +--- |
| 24 | + |
| 25 | +## Step 1 — Add the dependency to `pyproject.toml` |
| 26 | + |
| 27 | +Add the package to the appropriate section of `pyproject.toml`: |
| 28 | + |
| 29 | +- Runtime dependency → `[project] dependencies` |
| 30 | +- Development tooling → `[project.optional-dependencies] dev` |
| 31 | +- CI-only → `[project.optional-dependencies] ci_headless_tests` |
| 32 | + |
| 33 | +Pin the exact version (use `==`). |
| 34 | +For packages sensitive to the Python runtime version, use environment markers (e.g., `python_version < '3.10'`). |
| 35 | + |
| 36 | +--- |
| 37 | + |
| 38 | +## Step 2 — Update `credits/CREDITS.md` |
| 39 | + |
| 40 | +Add a row to the appropriate table in `credits/CREDITS.md`: |
| 41 | + |
| 42 | +- **Direct** runtime or GUI dependencies → "It directly uses:" table |
| 43 | +- **Indirect** (transitive) dependencies → "It indirectly uses:" table |
| 44 | + |
| 45 | +Each row must have: |
| 46 | + |
| 47 | +| Column | Content | |
| 48 | +|----------|--------------------------------------------------------------| |
| 49 | +| Software | Markdown link to project homepage | |
| 50 | +| License | Markdown link to the license URL on the project's repository | |
| 51 | + |
| 52 | +The author name (e.g., "by Mark Pointing") must be included in the Software column whenever |
| 53 | +it is known and the dependency is from an individual contributor rather than an organisation. |
| 54 | + |
| 55 | +Example row for a direct dependency: |
| 56 | + |
| 57 | +```markdown |
| 58 | +| [simpleeval](https://github.com/danthedeckie/simpleeval) | [MIT License](https://github.com/danthedeckie/simpleeval/blob/main/LICENCE) | |
| 59 | +``` |
| 60 | + |
| 61 | +--- |
| 62 | + |
| 63 | +## Step 3 — Update `credits/update_credits_licenses.py` |
| 64 | + |
| 65 | +Add the new package to the correct list in `credits/update_credits_licenses.py`: |
| 66 | + |
| 67 | +- `direct_dependencies` — for packages listed in the direct-use table |
| 68 | +- `indirect_dependencies` — for packages listed in the indirect-use table |
| 69 | + |
| 70 | +Each entry is a dict with two keys: |
| 71 | + |
| 72 | +```python |
| 73 | +{"name": "<PackageName>", "license_url": "<raw-URL-to-license-file>"} |
| 74 | +``` |
| 75 | + |
| 76 | +Rules for the URL: |
| 77 | + |
| 78 | +- Use a **raw** URL that serves the plain-text license (e.g., `https://raw.githubusercontent.com/...`) |
| 79 | +- The filename at the end of the URL determines the downloaded file's suffix |
| 80 | + (e.g., `…/main/LICENCE` → `<PackageName>-LICENCE`) |
| 81 | +- For packages hosted on Mozilla's site (MPL-2.0) provide `https://mozilla.org/MPL/2.0/` and the |
| 82 | + download function will use a fixed HTML filename automatically (see `Scrollable_TK_frame`, |
| 83 | + `Python_Tkinter_ComboBox`) |
| 84 | + |
| 85 | +--- |
| 86 | + |
| 87 | +## Step 4 — Run the download script |
| 88 | + |
| 89 | +Execute the script from the `credits/` directory. |
| 90 | +It reads both lists and downloads each license file: |
| 91 | + |
| 92 | +```bash |
| 93 | +cd credits |
| 94 | +python update_credits_licenses.py |
| 95 | +``` |
| 96 | + |
| 97 | +The script saves each file as `<PackageName>-<license-filename>` in the current directory. |
| 98 | +Check the output log to confirm all downloads succeeded. |
| 99 | +Re-run if any fail due to network errors. |
| 100 | + |
| 101 | +--- |
| 102 | + |
| 103 | +## Step 5 — Add entries to `REUSE.toml` |
| 104 | + |
| 105 | +For each newly downloaded license file, append an `[[annotations]]` block to `REUSE.toml` |
| 106 | +with the correct path, copyright notice, and SPDX license identifier. |
| 107 | + |
| 108 | +### Finding the copyright holder |
| 109 | + |
| 110 | +1. Open the downloaded license file (e.g., `credits/simpleeval-LICENCE`). |
| 111 | +2. Look for a line starting with `Copyright` or `©` at the top. |
| 112 | +3. If the license file contains no copyright notice, use the project author name from the |
| 113 | + corresponding entry in `credits/CREDITS.md` or the package's repository. |
| 114 | + |
| 115 | +### Choosing the SPDX identifier |
| 116 | + |
| 117 | +Use the canonical [SPDX license list](https://spdx.org/licenses/). |
| 118 | +Common mappings: |
| 119 | + |
| 120 | +| License text says | SPDX-License-Identifier | |
| 121 | +|------------------------------------|-------------------------| |
| 122 | +| MIT License | `MIT` | |
| 123 | +| Apache License, Version 2.0 | `Apache-2.0` | |
| 124 | +| BSD 2-Clause | `BSD-2-Clause` | |
| 125 | +| BSD 3-Clause | `BSD-3-Clause` | |
| 126 | +| Mozilla Public License 2.0 | `MPL-2.0` | |
| 127 | +| GNU General Public License v3 | `GPL-3.0-or-later` | |
| 128 | +| GNU Lesser GPL v3 | `LGPL-3.0-or-later` | |
| 129 | +| Python Software Foundation License | `PSF-2.0` | |
| 130 | +| MIT-CMU License (Pillow) | `MIT-CMU` | |
| 131 | + |
| 132 | +If no standard SPDX identifier exists (e.g., Inno Setup proprietary license), use a |
| 133 | +`LicenseRef-` identifier (e.g., `LicenseRef-Inno-Setup`) and place the license text in |
| 134 | +`LICENSES/LicenseRef-Inno-Setup.txt`. |
| 135 | + |
| 136 | +### Example `REUSE.toml` block |
| 137 | + |
| 138 | +```toml |
| 139 | +[[annotations]] |
| 140 | +path = "credits/simpleeval-LICENCE" |
| 141 | +SPDX-FileCopyrightText = "Copyright (c) 2013 Daniel Fairhead" |
| 142 | +SPDX-License-Identifier = "MIT" |
| 143 | +``` |
| 144 | + |
| 145 | +For files that have no copyright notice at all (e.g., the Apache 2.0 generic license text at |
| 146 | +`argparse_check_range-LICENSE-2.0`), credit the known package author: |
| 147 | + |
| 148 | +```toml |
| 149 | +[[annotations]] |
| 150 | +path = "credits/argparse_check_range-LICENSE-2.0" |
| 151 | +SPDX-FileCopyrightText = "Dmitriy Kovalev" |
| 152 | +SPDX-License-Identifier = "Apache-2.0" |
| 153 | +``` |
| 154 | + |
| 155 | +--- |
| 156 | + |
| 157 | +## Step 6 — Verify REUSE compliance |
| 158 | + |
| 159 | +```bash |
| 160 | +reuse lint |
| 161 | +``` |
| 162 | + |
| 163 | +All reported errors must be resolved before committing. |
| 164 | +Common errors and fixes: |
| 165 | + |
| 166 | +| Error | Fix | |
| 167 | +|------------------------------------------|------------------------------------------------------------------| |
| 168 | +| `credits/<file>: no license identifier` | Add the `SPDX-License-Identifier` to the REUSE.toml annotation | |
| 169 | +| `credits/<file>: no copyright notice` | Add `SPDX-FileCopyrightText` to the REUSE.toml annotation | |
| 170 | +| `Missing license file LICENSES/<ID>.txt` | Add the license text to `LICENSES/` when using `LicenseRef-` IDs | |
| 171 | + |
| 172 | +--- |
| 173 | + |
| 174 | +## Step 7 — Run pre-commit checks |
| 175 | + |
| 176 | +```bash |
| 177 | +pre-commit run --all |
| 178 | +``` |
| 179 | + |
| 180 | +All hooks must pass (ruff, pylint, mypy, reuse, etc.) before pushing. |
| 181 | + |
| 182 | +--- |
| 183 | + |
| 184 | +## Summary checklist |
| 185 | + |
| 186 | +- [ ] `pyproject.toml` — dependency added with pinned version |
| 187 | +- [ ] `credits/CREDITS.md` — row added to the correct table |
| 188 | +- [ ] `credits/update_credits_licenses.py` — entry added to the correct list |
| 189 | +- [ ] License file downloaded (`cd credits && python update_credits_licenses.py`) |
| 190 | +- [ ] `REUSE.toml` — `[[annotations]]` block added for each new license file |
| 191 | +- [ ] `reuse lint` passes |
| 192 | +- [ ] `pre-commit run --all` passes |
0 commit comments