plesty.sdk.commands.license =========================== .. py:module:: plesty.sdk.commands.license .. autoapi-nested-parse:: Commands for maintaining SPDX license headers with the REUSE tool. Python sources carry inline SPDX headers: a collective ``SPDX-FileCopyrightText`` holder (the first ``[project].authors`` entry) plus one ``SPDX-FileContributor`` line per individual author. Non-code files (docs, assets, the root LICENSE, lockfiles) are covered by ``REUSE.toml``. ``plesty license update`` adds a header only to files that do not have one yet, leaving curated (e.g. per-file contributor) headers untouched. Attributes ---------- .. autoapisummary:: plesty.sdk.commands.license._EXCLUDED_DIRS Functions --------- .. autoapisummary:: plesty.sdk.commands.license.license_command plesty.sdk.commands.license.update_command plesty.sdk.commands.license.author_command plesty.sdk.commands.license.lint_command plesty.sdk.commands.license._get_project_section plesty.sdk.commands.license._get_copyright_holder plesty.sdk.commands.license._get_contributors plesty.sdk.commands.license._get_license_id plesty.sdk.commands.license._ensure_license_text plesty.sdk.commands.license._python_sources plesty.sdk.commands.license._run_reuse Module Contents --------------- .. py:data:: _EXCLUDED_DIRS .. py:function:: license_command() -> None Maintain and verify SPDX license headers using the REUSE tool. .. py:function:: update_command(context: plesty.sdk.context.ApplicationContext) -> None Ensure the license text exists and add SPDX headers to unheadered sources. This command: 1. Reads the copyright holder from the first `[project].authors` entry and the remaining authors as contributors. 2. Reads the SPDX license identifier from `[project].license`. 3. Ensures the license text exists under `LICENSES/`. 4. Runs `reuse annotate --skip-existing` over Python files, adding a header (collective `SPDX-FileCopyrightText` plus one `SPDX-FileContributor` per author) only to files that do not already have one. Curated headers are left unchanged. .. py:function:: author_command(context: plesty.sdk.context.ApplicationContext) -> None Add the authors of unpushed commits as contributors to the files they changed. For every Python file changed by a commit that is not yet pushed, adds the commit author (resolved through `.mailmap`) as an `SPDX-FileContributor`, keeping all existing contributors. Review and commit the result before pushing. This is the fix for a failing Authorship Currency gate. .. py:function:: lint_command(context: plesty.sdk.context.ApplicationContext) -> None Verify the project is compliant with the REUSE specification. .. py:function:: _get_project_section(pyproject_toml: dict[str, Any]) -> dict[str, Any] Return the `[project]` section from pyproject content. .. py:function:: _get_copyright_holder(project_section: dict[str, Any]) -> str Read the collective copyright holder from the first `[project].authors` entry. .. py:function:: _get_contributors(project_section: dict[str, Any]) -> list[str] Read individual contributor names from `[project].authors` after the first. .. py:function:: _get_license_id(project_section: dict[str, Any]) -> str Read the SPDX license identifier from `[project].license`. Supports the PEP 639 SPDX-expression string form (`license = "LGPL-3.0-or-later"`) and the legacy table form (`license = {text = "..."}`). .. py:function:: _ensure_license_text(project_root: pathlib.Path, license_id: str) -> None Download the license text into `LICENSES/` if it is not already present. .. py:function:: _python_sources(project_root: pathlib.Path) -> list[pathlib.Path] Return all Python source files, excluding build, cache and hidden dirs. .. py:function:: _run_reuse(args: list[str], project_root: pathlib.Path) -> None Run the `reuse` tool, falling back to `python -m reuse` if needed.