{"id":7673,"library":"reuse","title":"REUSE Compliance Tool","description":"reuse is a Python command-line tool designed to help projects achieve and verify compliance with the REUSE recommendations (https://reuse.software). It facilitates adding copyright and licensing information to files, checking existing compliance, and downloading SPDX license texts. The current version is 6.2.0, with releases occurring regularly, typically every few months for minor versions.","status":"active","version":"6.2.0","language":"en","source_language":"en","source_url":"https://github.com/fsfe/reuse-tool","tags":["cli","licensing","compliance","spdx","open-source"],"install":[{"cmd":"pip install reuse","lang":"bash","label":"Install stable version"}],"dependencies":[{"reason":"Used for detecting file encodings.","package":"charset-normalizer"},{"reason":"Handles parsing and managing license expressions.","package":"license-expression"},{"reason":"Provides SPDX license expression validation.","package":"SPDX-License-Expression"},{"reason":"Optional module for additional file encoding detection capabilities.","package":"file-magic","optional":true}],"imports":[{"note":"The 'reuse' library is primarily a CLI tool. The 'main' function serves as the programmatic entry point for running commands, mimicking command-line execution by taking a list of arguments.","symbol":"main","correct":"from reuse.main import main"}],"quickstart":{"code":"import sys\nfrom pathlib import Path\nfrom reuse.main import main\n\n# Create a dummy project for demonstration\nproject_path = Path(\"my_reuse_project\")\nproject_path.mkdir(exist_ok=True)\n\n# Create a Python file with an SPDX license identifier\n(project_path / \"main.py\").write_text(\"# SPDX-License-Identifier: MIT\")\n\n# Create a dummy LICENSE file\n(project_path / \"LICENSE\").write_text(\"MIT License\\nCopyright (c) 2024 User\")\n\n# Simulate running 'reuse lint my_reuse_project'\nprint(\"\\n--- Running 'reuse lint my_reuse_project' ---\")\noriginal_argv = sys.argv\nsys.argv = ['reuse', 'lint', str(project_path)]\ntry:\n    main()\nexcept SystemExit as e:\n    # main() calls sys.exit() with 0 for success, non-zero for failure\n    if e.code != 0:\n        print(f\"Command 'lint' failed with exit code {e.code}\")\nfinally:\n    sys.argv = original_argv # Restore original argv\n\n# Simulate running 'reuse spdx --json my_reuse_project'\nprint(\"\\n--- Running 'reuse spdx --json my_reuse_project' ---\")\nsys.argv = ['reuse', 'spdx', '--json', str(project_path)]\ntry:\n    main()\nexcept SystemExit as e:\n    if e.code != 0:\n        print(f\"Command 'spdx' failed with exit code {e.code}\")\nfinally:\n    sys.argv = original_argv\n\n# Clean up dummy files and directory\n(project_path / \"main.py\").unlink()\n(project_path / \"LICENSE\").unlink()\nproject_path.rmdir()","lang":"python","description":"This quickstart demonstrates how to use the `reuse` tool programmatically by directly calling its `main` function. It simulates command-line execution by manipulating `sys.argv` and creating a temporary project structure to run `lint` and `spdx` commands."},"warnings":[{"fix":"To resolve new false positives, ensure any ignored sections are explicitly marked with `REUSE-IgnoreStart` and `REUSE-IgnoreEnd` tags in the relevant files.","message":"Starting from v6.0.0, `reuse lint` now reads entire files for REUSE information instead of just the first 4 KiB. This change can lead to new 'false positive' findings if ignored sections exist deeper in files.","severity":"breaking","affected_versions":">=6.0.0"},{"fix":"As a workaround, you can force the use of `chardet` for encoding detection by setting the environment variable: `REUSE_ENCODING_MODULE=chardet reuse <command>`.","message":"In v6.1.0, a bug was identified where `charset-normalizer` (the default encoding detection module) could incorrectly detect UTF-8 files as binary if the 2048th byte was a non-final byte of a multi-byte glyph.","severity":"gotcha","affected_versions":">=6.1.0"},{"fix":"For scripting and automation, prefer invoking `reuse` as a subprocess (`subprocess.run(['reuse', ...])`) for maximum stability and robustness, rather than relying on direct imports of internal modules.","message":"The `reuse` library is primarily designed as a command-line interface (CLI) tool. While programmatic access via `reuse.main.main` is possible, the internal APIs are not officially stable or guaranteed to maintain compatibility across versions for direct Python imports beyond `main`.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-04-16T00:00:00.000Z","next_check":"2026-07-15T00:00:00.000Z","problems":[{"fix":"Ensure the library is installed with `pip install reuse` and that your Python environment's script directory is included in your system's PATH.","cause":"The 'reuse' executable is not installed or is not in your system's PATH.","error":"Command 'reuse' not found"},{"fix":"Try using the `chardet` encoding module as a workaround: `REUSE_ENCODING_MODULE=chardet reuse lint .` If the issue persists, verify the file's actual encoding and ensure it's valid UTF-8 or consider specifying an explicit encoding for the file if `reuse` offers such a parameter (which it currently does not for `lint`).","cause":"The `reuse` tool attempted to read a file with an incorrect encoding, often due to misdetection by `charset-normalizer` or a genuinely malformed file.","error":"UnicodeDecodeError: 'utf-8' codec can't decode byte 0x... in position ...: invalid start byte"},{"fix":"Review the detailed output from `reuse lint` to identify the specific errors (e.g., missing copyright, missing license identifier, invalid SPDX expression). Correct the identified issues in your files or add appropriate `REUSE-IgnoreStart`/`REUSE-IgnoreEnd` tags.","cause":"The `reuse lint` command detected one or more files that do not comply with the REUSE specification, leading to a non-zero exit code indicating failure.","error":"Errors in files: [...] - reuse lint returned non-zero exit code (e.g., 1)"}]}