pax_global_header00006660000000000000000000000064146427521150014521gustar00rootroot0000000000000052 comment=97607144d9c340262236b6eb1cf7b605e9a5880a reuse-tool-4.0.3/000077500000000000000000000000001464275211500136235ustar00rootroot00000000000000reuse-tool-4.0.3/.editorconfig000066400000000000000000000005441464275211500163030ustar00rootroot00000000000000# SPDX-FileCopyrightText: 2017 Free Software Foundation Europe e.V. # # SPDX-License-Identifier: GPL-3.0-or-later root = true [*] indent_style = space indent_size = 4 trim_trailing_whitespace = true insert_final_newline = true charset = utf-8 end_of_line = lf [*.{rst,md,yaml,yml,json}] indent_size = 2 [Makefile] indent_style = tab reuse-tool-4.0.3/.github/000077500000000000000000000000001464275211500151635ustar00rootroot00000000000000reuse-tool-4.0.3/.github/pull_request_template.md000066400000000000000000000012431464275211500221240ustar00rootroot00000000000000 - [ ] Added a change log entry in `changelog.d//`. - [ ] Added self to copyright blurb of touched files. - [ ] Added self to `AUTHORS.rst`. - [ ] Wrote tests. - [ ] Documented my changes in `docs/man/` or elsewhere. - [ ] My changes do not contradict [the current specification](https://reuse.software/spec/). - [x] I agree to license my contribution under the licenses indicated in the changed files. reuse-tool-4.0.3/.github/workflows/000077500000000000000000000000001464275211500172205ustar00rootroot00000000000000reuse-tool-4.0.3/.github/workflows/docker.yaml000066400000000000000000000070061464275211500213560ustar00rootroot00000000000000# SPDX-FileCopyrightText: 2019 Free Software Foundation Europe e.V. # SPDX-FileCopyrightText: 2022 Carmen Bianca Bakker # # SPDX-License-Identifier: GPL-3.0-or-later name: Docker on: push: # Tags will carry the tag's version, e.g. v1.2.3: # - 1.2.3 # - 1.2 # - 1 (not with 0 though) # - latest" tags: - "v*.*.*" # On PRs only do tests pull_request: jobs: # =========================================================================== # Test Docker images # =========================================================================== docker_test: name: Test the Docker images runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v2 # Dockerfile - name: Build Dockerfile run: | docker build -t reuse -f Dockerfile . - name: Run Docker image run: | docker run -v "$(pwd):/data" reuse # Dockerfile-debian - name: Build Dockerfile-debian run: | docker build -t reuse-debian -f Dockerfile-debian . - name: Run Docker debian image run: | docker run -v "$(pwd):/data" reuse-debian # =========================================================================== # Build and push Docker images for tagged releases # =========================================================================== docker_push_tag: name: Push Docker images for tags to Docker Hub runs-on: ubuntu-22.04 # Depends on successful Docker build/test needs: - docker_test if: ${{ github.event_name != 'pull_request' && startsWith(github.ref, 'refs/tags/v') }} steps: - name: Check out the repo uses: actions/checkout@v2 - name: Set up QEMU uses: docker/setup-qemu-action@v1 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v1 - name: Log in to Docker Hub uses: docker/login-action@v1 with: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_TOKEN }} # Dockerfile - name: Alpine Docker - set metadata id: meta_default uses: docker/metadata-action@v3 with: images: fsfe/reuse tags: | type=semver,pattern={{version}} type=semver,pattern={{major}}.{{minor}} type=semver,pattern={{major}},enable=${{ !startsWith(github.ref, 'refs/tags/v0.') }} - name: Alpine docker - build and push uses: docker/build-push-action@v2 with: context: . file: ./Dockerfile platforms: linux/amd64,linux/arm64 push: true tags: ${{ steps.meta_default.outputs.tags }} labels: ${{ steps.meta_default.outputs.labels }} # Dockerfile-debian - name: Debian Docker - set metadata id: meta_debian uses: docker/metadata-action@v3 with: images: fsfe/reuse tags: | type=semver,pattern={{version}} type=semver,pattern={{major}}.{{minor}} type=semver,pattern={{major}},enable=${{ !startsWith(github.ref, 'refs/tags/v0.') }} flavor: | suffix=-debian,onlatest=true - name: Debian Docker - build and push uses: docker/build-push-action@v2 with: context: . file: ./Dockerfile-debian platforms: linux/amd64,linux/arm64 push: true tags: ${{ steps.meta_debian.outputs.tags }} labels: ${{ steps.meta_debian.outputs.labels }} reuse-tool-4.0.3/.github/workflows/gettext.yaml000066400000000000000000000042021464275211500215660ustar00rootroot00000000000000# SPDX-FileCopyrightText: 2023 Carmen Bianca BAKKER # SPDX-FileCopyrightText: 2024 Free Software Foundation Europe e.V. # # SPDX-License-Identifier: GPL-3.0-or-later name: Update .pot file on: push: branches: - main paths: - "src/reuse/**.py" jobs: create-pot: runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v3 with: fetch-depth: 1 # The main branch is protected. fsfe-system has been granted an # exception to the branch protection, so we'll use that account's # token to push to the main branch. token: ${{ secrets.FSFE_SYSTEM_TOKEN }} - name: Install gettext and wlc run: sudo apt-get install -y gettext wlc - name: Lock Weblate run: | wlc --url https://hosted.weblate.org/api/ --key ${{secrets.WEBLATE_KEY }} lock fsfe/reuse-tool - name: Push changes from Weblate to upstream repository run: | wlc --url https://hosted.weblate.org/api/ --key ${{secrets.WEBLATE_KEY }} push fsfe/reuse-tool - name: Pull Weblate translations run: git pull origin main - name: Create .pot file run: make create-pot # Normally, POT-Creation-Date changes in two locations. Check if the diff # includes more than just those two lines. - name: Check if sufficient lines were changed id: diff run: echo "changed=$(git diff -U0 | grep '^[+|-][^+|-]' | grep -Ev '^[+-]("POT-Creation-Date|#:)' | wc -l)" >> $GITHUB_OUTPUT - name: Commit and push updated reuse.pot if: ${{ steps.diff.outputs.changed != '0' }} run: | git config --global user.name "fsfe-system" git config --global user.email "<>" git add po/reuse.pot po/*.po git commit -m "Update reuse.pot" git push origin main - name: Unlock Weblate run: | wlc --url https://hosted.weblate.org/api/ --key ${{ secrets.WEBLATE_KEY }} pull fsfe/reuse-tool wlc --url https://hosted.weblate.org/api/ --key ${{ secrets.WEBLATE_KEY }} unlock fsfe/reuse-tool reuse-tool-4.0.3/.github/workflows/license_list_up_to_date.py000066400000000000000000000042211464275211500244510ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2020 Liferay, Inc. # # SPDX-License-Identifier: GPL-3.0-or-later """A simple script that checks whether the license lists in reuse are up-to-date. For convenience, also overwrite the files. """ import argparse import json import sys import urllib.request from pathlib import Path API_URL = "https://api.github.com/repos/spdx/license-list-data/releases/latest" URLS = { # pylint: disable=line-too-long "exceptions.json": "https://raw.githubusercontent.com/spdx/license-list-data/{tag}/json/exceptions.json", "licenses.json": "https://raw.githubusercontent.com/spdx/license-list-data/{tag}/json/licenses.json", } # Fetch arguments parser = argparse.ArgumentParser( description="Check and update included SPDX licenses and exceptions" ) parser.add_argument( "-d", "--download", action="store_true", help="if newer licenses/exceptions are found, download them to the repo", ) args = parser.parse_args() def latest_tag(): """Find out the tag name of latest stable release of the repo""" with urllib.request.urlopen(API_URL) as response: contents = response.read().decode("utf-8") dictionary = json.loads(contents) return dictionary["tag_name"] def main(args_): """Compare local and remote files, and download if not matching""" result = 0 tag = latest_tag() print(f"spdx-license-list-data latest version is {tag}") for file_, url in URLS.items(): url = url.format(tag=tag) path = Path(f"src/reuse/resources/{file_}") local_contents = path.read_text(encoding="utf-8") with urllib.request.urlopen(url) as response: remote_contents = response.read().decode("utf-8") if remote_contents == local_contents: print(f"{file_} is up-to-date") else: if args_.download: print(f"{file_} is not up-to-date, downloading newer release") path.write_text(remote_contents, encoding="utf-8") else: result = 1 print(f"{file_} is not up-to-date") return result if __name__ == "__main__": sys.exit(main(args)) reuse-tool-4.0.3/.github/workflows/license_list_up_to_date.yaml000066400000000000000000000011271464275211500247650ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2020 Liferay, Inc. # # SPDX-License-Identifier: GPL-3.0-or-later name: Verify that the license lists are up-to-date on: schedule: - cron: "0 9 * * 1" jobs: license-list-up-to-date: runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v2 with: fetch-depth: 0 - name: Set up Python uses: actions/setup-python@v2 with: python-version: 3.x - name: Verify that the license lists are up-to-date run: | python .github/workflows/license_list_up_to_date.py reuse-tool-4.0.3/.github/workflows/pijul.yaml000066400000000000000000000024631464275211500212340ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2020 Liferay, Inc. # SPDX-FileCopyrightText: 2023 Free Software Foundation Europe e.V. # # SPDX-License-Identifier: GPL-3.0-or-later name: Test with Paijul # These tests are run exclusively on the main branch to reduce CPU time wasted # on every single PR that very likely does not affect Pijul functionality. on: push: branches: - main paths: - "src/reuse/**.py" - "tests/**.py" jobs: test-pijul: runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v2 - name: Set up Python uses: actions/setup-python@v2 with: python-version: 3.x - name: Install dependencies run: | pip install poetry~=1.3.0 poetry install --no-interaction --only main,test # TODO: As soon as a binary is available for Ubuntu 22.04, use it instead # of manually building it. - name: Set up Pijul run: | sudo apt install make libsodium-dev libclang-dev pkg-config libssl-dev libxxhash-dev libzstd-dev clang cargo install --locked pijul --version "1.0.0-beta.6" pijul identity new --no-prompt --display-name 'Jane Doe' --email 'jdoe@example.com' 'jdoe' - name: Run tests with pytest run: | poetry run pytest --cov=reuse reuse-tool-4.0.3/.github/workflows/test.yaml000066400000000000000000000067351464275211500210760ustar00rootroot00000000000000# SPDX-FileCopyrightText: 2019 Free Software Foundation Europe e.V. # SPDX-FileCopyrightText: 2022 Carmen Bianca Bakker # SPDX-FileCopyrightText: 2023 DB Systel GmbH # # SPDX-License-Identifier: GPL-3.0-or-later name: Test suites on: push: branches: - main pull_request: jobs: test: runs-on: ${{ matrix.os }} strategy: max-parallel: 10 # do not abort the whole test job if one combination in the matrix fails fail-fast: false matrix: python-version: ["3.8", "3.12"] os: [ubuntu-22.04] include: - python-version: "3.8" os: macos-latest - python-version: "3.8" os: windows-latest steps: - uses: actions/checkout@v2 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v2 with: python-version: ${{ matrix.python-version }} - name: Install dependencies run: | pip install poetry~=1.3.0 poetry install --no-interaction --only main,test - name: Run tests with pytest run: | poetry run pytest --cov=reuse pylint: runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v2 - name: Set up Python uses: actions/setup-python@v2 with: python-version: 3.8 - name: Install dependencies run: | pip install poetry~=1.3.0 poetry install --no-interaction --only main,dev,test - name: Lint with Pylint run: | poetry run pylint src/reuse/ tests/ black: runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v2 - name: Set up Python uses: actions/setup-python@v2 with: python-version: 3.8 - name: Install dependencies run: | pip install poetry~=1.3.0 poetry install --no-interaction --only dev - name: Test formatting with black run: | poetry run isort --check src/ tests/ poetry run black --check . mypy: runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v2 - name: Set up Python uses: actions/setup-python@v2 with: python-version: 3.8 - name: Install dependencies run: | pip install poetry~=1.3.0 poetry install --no-interaction --only main,dev,test - name: Test typing with mypy run: | poetry run mypy prettier: runs-on: ubuntu-22.04 container: node:latest steps: - uses: actions/checkout@v2 - name: Install prettier run: npm install prettier@3.0.3 - name: Run prettier run: npx prettier --check . reuse: runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v2 - name: Set up Python uses: actions/setup-python@v2 with: python-version: 3.8 - name: Install dependencies run: | pip install poetry~=1.3.0 poetry install --no-interaction --only main - name: Test REUSE compliance run: make reuse docs: runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v2 - name: Set up Python uses: actions/setup-python@v2 with: python-version: 3.8 - name: Install dependencies run: | pip install poetry~=1.3.0 poetry install --no-interaction --only main,docs - name: Create docs with Sphinx run: | make docs reuse-tool-4.0.3/.github/workflows/third_party_lint.py000066400000000000000000000077041464275211500231610ustar00rootroot00000000000000#!/usr/bin/env python3 # SPDX-FileCopyrightText: 2023 DB Systel GmbH # SPDX-FileCopyrightText: 2023 Carmen Bianca BAKKER # # SPDX-License-Identifier: GPL-3.0-or-later """Lint 3rd party repositories""" import argparse import shutil import subprocess import sys import tempfile from pathlib import Path from git import Repo CLONE_DIR = Path(tempfile.gettempdir()) / "reuse-third-party" DEFAULT_REPOS = { "https://github.com/fsfe/reuse-example": {}, "https://github.com/curl/curl": {}, "https://github.com/spdx/license-list-XML": {"expect-failure": True}, } def rm_fr(path): """Force-remove directory.""" path = Path(path) if path.exists(): shutil.rmtree(path) def lint_repo(repo, force_clone=False, expect_failure=False, json=False): """Meta function to clone and lint a repository, start to finish.""" # The sanitation only works on Linux. If we want to do this 'properly', we # should use the pathvalidate dependency. repo_dir = Path(f"{CLONE_DIR}/{repo.replace('/', '_')}") if force_clone: rm_fr(repo_dir) # Clone repo if not repo_dir.exists(): print(f"[INFO] Cloning {repo} to {repo_dir}") repo_git = Repo.clone_from( repo, repo_dir, # Shallow clone. depth=1, ) else: print(f"[INFO] Not cloning {repo} as it exists locally.") repo_git = Repo(repo_dir) # Get last commit of repo repo_sha = repo_git.head.object.hexsha # Lint repo print(f"[INFO] Start linting of {repo} (commit {repo_sha})") lint_result = subprocess.run( ["reuse", "--root", repo_dir, "lint", "--json"], capture_output=True, check=False, ) if json: print(lint_result.stdout.decode("utf-8")) print() if lint_result.returncode != 0 and not expect_failure: print(f"[ERROR] Linting {repo} failed unexpectedly") elif lint_result.returncode == 0 and expect_failure: print(f"[ERROR] Linting {repo} succeeded unexpectedly") elif lint_result.returncode != 0 and expect_failure: print(f"[OK] Linting {repo} failed expectedly") elif lint_result.returncode == 0 and not expect_failure: print(f"[OK] Linting {repo} succeeded expectedly") return lint_result def main(args): """Main function""" parser = argparse.ArgumentParser(description=__doc__) parser.add_argument( "-f", "--force", action="store_true", help="force re-clone of third-party repositories", ) parser.add_argument( "--json", action="store_true", help="show json output of lint", ) parser.add_argument( "--expect-failure", action="store_true", help="expect the lint to fail", ) mutex_group = parser.add_mutually_exclusive_group(required=True) mutex_group.add_argument( "repo", help="link to repository", nargs="?", ) mutex_group.add_argument( "--defaults", action="store_true", help="run against some default repositories", ) args = parser.parse_args() total_lint_fails = 0 if args.defaults: for repo, settings in DEFAULT_REPOS.items(): expect_failure = ( settings.get("expect-failure") or args.expect_failure ) result = lint_repo( repo, force_clone=args.force, expect_failure=expect_failure, json=args.json, ) if result.returncode and not expect_failure: total_lint_fails += 1 else: result = lint_repo( args.repo, force_clone=args.force, expect_failure=args.expect_failure, json=args.json, ) if result.returncode and not args.expect_failure: total_lint_fails += 1 return total_lint_fails if __name__ == "__main__": sys.exit(main(sys.argv[1:])) reuse-tool-4.0.3/.github/workflows/third_party_lint.yaml000066400000000000000000000040241464275211500234630ustar00rootroot00000000000000# SPDX-FileCopyrightText: 2023 DB Systel GmbH # SPDX-FileCopyrightText: 2023 Carmen Bianca BAKKER # # SPDX-License-Identifier: GPL-3.0-or-later # Build reuse-tool and lint 3rd party repositories for which we know that they # are reliably REUSE compliant, rather complex, use several annotation # strategies, and are quite popular. This shall prevent that we introduce # unforeseen and unintended breaking changes. name: Lint 3rd party repositories on: push: branches: - main pull_request: jobs: third-party-lint: runs-on: ubuntu-22.04 strategy: # do not abort the whole test job if one combination in the matrix fails fail-fast: false matrix: repo: [ "https://github.com/fsfe/reuse-example", "https://github.com/curl/curl", ] steps: - uses: actions/checkout@v3 - name: Set up Python uses: actions/setup-python@v2 with: python-version: 3.8 - name: Install dependencies run: | pip install poetry~=1.3.0 poetry install --no-interaction # Clone and lint repositories - name: Clone and lint repositories run: poetry run python .github/workflows/third_party_lint.py --json ${{ matrix.repo }} third-party-lint-expect-failure: runs-on: ubuntu-22.04 strategy: # do not abort the whole test job if one combination in the matrix fails fail-fast: false matrix: repo: ["https://github.com/spdx/license-list-XML"] steps: - uses: actions/checkout@v3 - name: Set up Python uses: actions/setup-python@v2 with: python-version: 3.8 - name: Install dependencies run: | pip install poetry~=1.3.0 poetry install --no-interaction # Clone and lint repositories - name: Clone and lint repositories run: poetry run python .github/workflows/third_party_lint.py --json --expect-failure ${{ matrix.repo }} reuse-tool-4.0.3/.gitignore000066400000000000000000000046311464275211500156170ustar00rootroot00000000000000# SPDX-FileCopyrightText: 2017 Free Software Foundation Europe e.V. # # SPDX-License-Identifier: CC0-1.0 # Created by https://www.gitignore.io/api/linux,python # Edit at https://www.gitignore.io/?templates=linux,python ### Linux ### *~ # temporary files which can be created if a process still has a handle open of a deleted file .fuse_hidden* # KDE directory preferences .directory # Linux trash folder which might appear on any partition or disk .Trash-* # .nfs files are created when an open file is removed but is still being accessed .nfs* ### Python ### # Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] *$py.class # C extensions *.so # Distribution / packaging .Python build/ develop-eggs/ dist/ downloads/ eggs/ .eggs/ lib/ lib64/ parts/ sdist/ var/ wheels/ pip-wheel-metadata/ share/python-wheels/ *.egg-info/ .installed.cfg *.egg MANIFEST # PyInstaller # Usually these files are written by a python script from a template # before PyInstaller builds the exe, so as to inject date/other infos into it. *.manifest *.spec # Installer logs pip-log.txt pip-delete-this-directory.txt # Unit test / coverage reports htmlcov/ .tox/ .nox/ .coverage .coverage.* .cache nosetests.xml coverage.xml *.cover .hypothesis/ .pytest_cache/ # Translations *.mo *.pot # Django stuff: *.log local_settings.py db.sqlite3 # Flask stuff: instance/ .webassets-cache # Scrapy stuff: .scrapy # Sphinx documentation docs/_build/ # PyBuilder target/ # Jupyter Notebook .ipynb_checkpoints # IPython profile_default/ ipython_config.py # pyenv .python-version # pipenv # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. # However, in case of collaboration, if having platform-specific dependencies or dependencies # having no cross-platform support, pipenv may install dependencies that don’t work, or not # install all needed dependencies. #Pipfile.lock # celery beat schedule file celerybeat-schedule # SageMath parsed files *.sage.py # Environments .env .venv env/ venv/ ENV/ env.bak/ venv.bak/ # Spyder project settings .spyderproject .spyproject # Rope project settings .ropeproject # mkdocs documentation /site # mypy .mypy_cache/ .dmypy.json dmypy.json # Pyre type checker .pyre/ # End of https://www.gitignore.io/api/linux,python po/reuse.pot *.mo docs/api/ docs/history.md docs/readme.md docs/contribute.md prof/ # Nix-related .direnv/ result .envrc reuse-tool-4.0.3/.pre-commit-config.yaml000066400000000000000000000023551464275211500201110ustar00rootroot00000000000000# SPDX-FileCopyrightText: 2018 Free Software Foundation Europe e.V. # # SPDX-License-Identifier: GPL-3.0-or-later repos: - repo: https://github.com/psf/black rev: 24.4.2 hooks: - id: black - repo: https://github.com/pycqa/isort rev: 5.13.2 hooks: - id: isort name: isort (python) types: [python] - id: isort name: isort (cython) types: [cython] - id: isort name: isort (pyi) types: [pyi] - repo: https://github.com/pre-commit/mirrors-mypy rev: v1.10.0 hooks: - id: mypy # This is a bit annoying. There are probably more dependencies that need # to be defined here for identical behaviour between `poetry run mypy` # and `pre-commit run mypy`. additional_dependencies: [attrs==23.2.0] - repo: https://github.com/pre-commit/mirrors-prettier rev: v3.0.3 hooks: - id: prettier name: prettier - repo: local hooks: - id: pylint name: pylint entry: poetry run pylint language: system types: [python] exclude: ^docs/ args: [ "-rn", # Only display messages "-sn", # Don't display the score ] reuse-tool-4.0.3/.pre-commit-hooks.yaml000066400000000000000000000004661464275211500177700ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2020 Liferay, Inc. # # SPDX-License-Identifier: GPL-3.0-or-later - id: reuse name: reuse entry: reuse args: ["lint"] language: python pass_filenames: false description: "Lint the project directory for compliance with the REUSE Specification" reuse-tool-4.0.3/.prettierignore000066400000000000000000000005051464275211500166660ustar00rootroot00000000000000# SPDX-FileCopyrightText: 2022 Carmen Bianca Bakker # # SPDX-License-Identifier: GPL-3.0-or-later # SPDX resources /src/reuse/resources/*.json # Additional paths in which third-party code/files are located .env .pytest_cache/ .tox/ .venv build/ dist/ docs/_build/ env.bak/ env/ ENV/ venv.bak/ venv/ reuse-tool-4.0.3/.prettierrc.yaml000066400000000000000000000005651464275211500167560ustar00rootroot00000000000000# SPDX-FileCopyrightText: 2022 Carmen Bianca Bakker # # SPDX-License-Identifier: GPL-3.0-or-later printWidth: 80 proseWrap: always useTabs: false tabWidth: 4 overrides: # Identical to file types specified in .editorconfig - files: - "*.rst" - "*.md" - "*.yaml" - "*.yml" - "*.json" options: tabWidth: 2 reuse-tool-4.0.3/.pylintrc000066400000000000000000000043311464275211500154710ustar00rootroot00000000000000# SPDX-FileCopyrightText: 2018 Free Software Foundation Europe e.V. # SPDX-FileCopyrightText: 2022 Florian Snow # # SPDX-License-Identifier: GPL-3.0-or-later [MASTER] jobs=0 [MESSAGES CONTROL] disable=duplicate-code, logging-fstring-interpolation, implicit-str-concat enable=useless-suppression [REPORTS] output-format=text reports=no [FORMAT] expected-line-ending-format=LF ignore-long-lines=^\s*(# )??$|^# SPDX-.*$ indent-after-paren=4 indent-string=' ' max-line-length=80 single-line-if-stmt=no [REFACTORING] max-nested-blocks=4 never-returning-functions=sys.exit [BASIC] argument-naming-style=snake_case attr-naming-style=snake_case bad-names=foo, bar, baz, toto, tutu, tata class-attribute-rgx=^[a-z0-9_]*$|^[A-Z0-9_]*$ class-naming-style=PascalCase const-naming-style=UPPER_CASE docstring-min-length=3 function-naming-style=snake_case good-names=i,j,k,ex,Run,_,fp inlinevar-naming-style=snake_case method-naming-style=snake_case module-naming-style=snake_case variable-naming-style=snake_case [MISCELLANEOUS] notes=FIXME,XXX [SIMILARITIES] ignore-comments=yes ignore-docstrings=yes ignore-imports=yes min-similarity-lines=4 [SPELLING] max-spelling-suggestions=4 spelling-store-unknown-words=no [STRING] check-quote-consistency=yes check-str-concat-over-line-jumps=yes [DESIGN] max-args=6 max-attributes=10 max-bool-expr=5 # we probably want to reduce this a bit, after some refactoring max-branches=12 max-locals=15 max-parents=7 max-public-methods=20 max-returns=6 max-statements=50 min-public-methods=1 [IMPORTS] allow-wildcard-with-all=no analyse-fallback-blocks=no deprecated-modules=optparse,tkinter.tix,distutils known-third-party=enchant [CLASSES] defining-attr-methods=__init__, __new__, setUp, __post_init__ exclude-protected=_asdict, _fields, _replace, _source, _make valid-classmethod-first-arg=cls valid-metaclass-classmethod-first-arg=cls [EXCEPTIONS] overgeneral-exceptions=builtins.BaseException, builtins.Exception reuse-tool-4.0.3/.readthedocs.yaml000066400000000000000000000007511464275211500170550ustar00rootroot00000000000000# SPDX-FileCopyrightText: 2017 Free Software Foundation Europe e.V. # # SPDX-License-Identifier: CC0-1.0 version: 2 build: # This should mirror the configuration in ./.github/workflows/test.yaml os: ubuntu-22.04 tools: python: "3.8" jobs: post_create_environment: - python -m pip install poetry post_install: - VIRTUAL_ENV=$READTHEDOCS_VIRTUALENV_PATH python -m poetry install --with docs sphinx: configuration: docs/conf.py reuse-tool-4.0.3/AUTHORS.rst000066400000000000000000000132101464275211500154770ustar00rootroot00000000000000.. SPDX-FileCopyrightText: 2017 Free Software Foundation Europe e.V. SPDX-FileCopyrightText: 2017 Sebastian Schuberth SPDX-License-Identifier: CC-BY-SA-4.0 ======= Credits ======= Development Lead ---------------- - Carmen Bianca Bakker Contributors ------------ - Linus Sehn - Max Mehl - Nico Rikken - Florian Snow - Sebastian Schuberth - Samuel Gaist - Diego Elio Pettenò - Matija Šuklje - gallegonovato - Ihor Hordiichuk - Liam Beguin - J. Lavoie - Anthony Loiseau - André Ockers - OliBug - Vincent Lequertier - pd - Thomas Doczkal - Tirifto - Luca Bonissi - José Vieira - flow - pd - Roberto Bauglir - T. E. Kalayci - John Mulligan - Kevin Broch - Benoit Rolandeau - David Alfonso - Pietro Albini - Shun Sakai - Jiří Podhorecký - Korrat - Paul Spooren - Tuomas Siipola - Wesley Schwengle - Chris Wesseling - Ethan Kerrick - Friedrich von Never - Gri-ffin - Matthias Riße - Michael Weimann - Roberto Redradix - Robin Vobruba - Stefan Hynek - sudorook - Adam Spiers - Ajinkya Patil - FeRD (Frank Dana) - Greg Kroah-Hartman - Hugo Osvaldo Barrera - Jakelyst <86010593+Jakelyst@users.noreply.github.com> - Jiri Vlasak - Johannes Zarl-Zierl - Keith Maxwell - Kirill Elagin - Kristoffer Grundström - Luca Bonissi - Manlio Perillo - Mauro Aranda - Maxim Cournoyer - Mikko Piuhola - Raniere Silva - Robert Cohn - Sebastian Schuberth - Simon Schliesky - Stefan Bakker - T. E. Kalayci - Thomas Bach - Walter Paulo - Wolfgang Traylor - Xinglu Chen - ethulhu - gfbdrgng - mdolling - psykose - Adrián Chaves - Alvar <8402811+oxzi@users.noreply.github.com> - Alvar Penning - Aminda Suomalainen - Andrey Bienkowski - André Ockers - Anthony Loiseau - Arnout Engelen - Basil Peace - Benedikt Fein - BigBlueHat - David Kleuker - David Marzal <2069735+Marzal@users.noreply.github.com> - Dimitris Apostolou - Dirk Brömmel - Dmitry Bogatov - FestplattenSchnitzel - George Rawlinson - Gert van Dijk - Gerwin Klein - Hanspeter Portner - Hotripak - Jan Staněk - Jason Yundt - Johannes Keyser - Jon Burdo - Josef Andersson - José Vieira - Kevin Meagher <11620178+kjmeagher@users.noreply.github.com> - Lars Francke - Libor Pechacek - Léo de Souza - Marius Brehler - Mark A. Tsuchida - Markus Vieth - Mathias Dannesbo <45558062+md-magenta@users.noreply.github.com> - Miro Hrončok - Monaco - Nicolás Alvarez - Nir Soffer - Olaf Meeuwissen - Pep - Philipp Zabel - Roberto Bauglir - Romain Tartière - Ryan Schmidt - Sebastian Crane - T. E. Kalaycı - Vishesh Handa - Vlad-Stefan Harbuz - Yaman Qalieh - criadoperez - ethulhu - nautilusx - pukkamustard - rajivsunar07 <56905029+rajivsunar07@users.noreply.github.com> - Сергій reuse-tool-4.0.3/CHANGELOG.md000066400000000000000000001205241464275211500154400ustar00rootroot00000000000000 # Change log This change log follows the [Keep a Changelog](http://keepachangelog.com/) spec. Every release contains the following sections: - `Added` for new features. - `Changed` for changes in existing functionality. - `Deprecated` for soon-to-be removed features. - `Removed` for now removed features. - `Fixed` for any bug fixes. - `Security` in case of vulnerabilities. The versions follow [semantic versioning](https://semver.org) for the `reuse` CLI command and its behaviour. There are no guarantees of stability for the `reuse` Python library. ## 4.0.3 - 2024-07-08 ### Fixed - Increased the minimum requirement of `attrs` to `>=21.3`. Older versions do not import correctly. (#1044) ## 4.0.2 - 2024-07-03 ### Fixed - Repaired a bug that would cause a crash when running `annotate --merge-copyrights` on a file that does not yet have a year in the copyright statement. This bug was introduced in v4.0.1. (#1030) ## 4.0.1 - 2024-07-03 ### Fixed - Make sure that Read the Docs can compile the documentation. This necesitated updating `poetry.lock`. (#1028) ## 4.0.0 - 2024-07-03 This release of REUSE implements the new [REUSE Specification v3.2](https://reuse.software/spec-3.2). It adds the `REUSE.toml` file format as a replacement for `.reuse/dep5`. The new format is easier to write and parse, is better at disambiguating certain corner cases, and is more flexible for customisation and future additions. To convert your existing `.reuse/dep5` to `REUSE.toml`, you can simply use the `reuse convert-dep5` command. Alongside the `REUSE.toml` feature is a wealth of other improvements. `reuse lint --lines` may be especially interesting for CI workflows, as well as the fact that the amount of `PendingDeprecationWarning`s has been drastically reduced now that the information aggregation behaviour of `.reuse/dep5` is explicitly defined in the specification. The tool has also been made easier to use with the addition of man pages. The man pages can be found online at . Your distribution's packager will need to make them accessible via `man reuse(1)`. Unfortunately, man pages cannot be made accessible via Python's packaging, although the full documentation (including man pages) is included in the sdist. This changeset also contains the changes of v3.1.0a1. ### Added - Added support for `REUSE.toml`. (#863) - Added `reuse convert-dep5` to convert `.reuse/dep5` to `REUSE.toml`. (#863) - Man pages added for all `reuse` commands. Distribution maintainers might wish to distribute the (Sphinx-built) man pages. (#975) - More file types are recognised: - Assembler (`.asm`) (#928) - GraphQL (`.graphqls`, `.gqls`) (#930) - CUDA-C++ (`.cu`, `.cuh`) (#938) - Various .NET files (`.csproj`, `.fsproj`, `.fsx`, `.props`, `.sln`, `.vbproj`) (#940) - Cargo (`Cargo.lock`) (#937) - Clang-Tidy (`.clang-tidy`) (#961) - Java `.properties` files (#968) - Apache HTTP server config `.htaccess` files (#985) - npm `.npmrc` files (#985) - LaTeX class files (`.cls`) (#971) - CSON (`.cson`) (#1002) - Hjson (`.hjson`) (#1002) - JSON5 (`.json5`) (#1002) - JSON with Comments (`.jsonc`) (#1002) - Tap (`.taprc`) (#997) - Zsh (`.zshrc`) (#997) - Perl test (`.t`) (#997) - BATS test (`.bats`) (#997) - Octave/Matlab (`.m`) (#604) - VHDL(`.vhdl`) (#564) - Earthly files (`Earthfile` and `.earthlyignore`) (#1024) - Added comment styles: - `man` for UNIX Man pages (`.man`) (#954) - Added `--lines` output option for `lint`. (#956) - Treat `% !TEX` and `% !BIB` as shebangs in TeX and BibTeX files, respectively (#971) - Support alternate spelling `--skip-unrecognized`. (#974) - In `annotate`, rename `--copyright-style` to `--copyright-prefix`. The former parameter is still supported. (#973) - Support alternate spelling `--skip-unrecognized` (#974) - `cpp` and `cppsingle` style shorthands (see changes). (#941) ### Changed - Updated SPDX resources to 3.24.0. (#994) - Updated REUSE specification version to 3.2. (#994) - `.s` files now use the Python comment style as per GNU Assembler (gas). (#928) - Previously, any file that begins with `COPYING` or `LICENSE` was ignored. This has been changed. Now, files like `COPYING_README` are no longer ignored, but `COPYING` and `COPYING.txt` are still ignored (in other words: exact matches, or `COPYING` + a file extension). Idem ditto for `LICENSE`. (#886) - Dependencies added: - `attrs>=21.1` (#863) - `tomlkit>=0.8` (#863) - Reorganised the way that `c`, `css`, and `csingle` styles work. (#941) - `c` used to support multi-line comments; it now only supports multi-line `/* */` comments. This is identical to the old `css` style. - `cpp` has been added, which supports multi-line `/* */` comments and single-line `//` comments. This is identical to the old `c` style. - `csingle` has been renamed to `cppsingle`, and it supports only single-line `//` comments. ### Deprecated - `.reuse/dep5` is marked deprecated. `reuse convert-dep5` will help you switch to `REUSE.toml`. (#863) ### Removed - The PendingDeprecationWarning for the aggregation of information between DEP5 and the contents of a file has been removed. This behaviour is now explicitly specified in REUSE Specification v3.2. (#1017, related to #779) - `reuse init` removed. (#863) - `csingle` and `css` style shorthands (see changes). (#941) ### Fixed - The datetime value for `Created:` was wrongly formatted since 3.0.0. It now returns a correctly formatted ISO 8601 date again. (#952) - Repaired the behaviour of `reuse download` where being inside of a LICENSES/ directory should not create a deeper LICENSES/LICENSES/ directory. (#975) - Support annotating a file that contains only a shebang. (#965) - Add `CONTRIBUTING.md` to the sdist. (#987) - In `reuse spdx`, fixed the output to be more compliant by capitalising `SPDXRef-Document DESCRIBES` appropriately. (#1013) ## 3.0.2 - 2024-04-08 ### Fixed - `annotate`'s '`--style` now works again when used for a file with an unrecognised extension. (#909) ## 3.0.1 - 2024-01-19 ### Fixed - `.qrc` and `.ui` now have the HTML comment style instead of being marked uncommentable. (#896) - This reverts behaviour introduced in v3.0.0: the contents of uncommentable files are scanned for REUSE information again. The contents of binary files are not. (#896) ## 3.0.0 - 2024-01-17 This release contains a lot of small improvements and changes without anything big per se. Rather, it is made in advance of a release which will contain a single feature: [REUSE.toml](https://github.com/fsfe/reuse-tool/issues/779), a replacement for `.reuse/dep5`. `.reuse/dep5` will still be supported as a deprecated feature for some time. That future 3.1 release will have some alpha testing in advance. ### Added - Implement handling LicenseRef in `download` and `init`. (#697) - Declared support for Python 3.12. (#846) - More file types are recognised: - TCL (`.tcl`) (#871) - Julia (`.jl`) (#815) - Modern Fortran (`.f90`) (#836) - Bazel (`.bzl`) (#870) - GNU Linker script (`.ld`) (#862) - Assembly code (`.s`) (#862) - Empty placeholders (`.empty`) (#862) - ShellCheck configuration (`.shellcheckrc`) (#862) - Pylint in-project configuration (`pylintrc`) (#862) - Lisp schemes (`.sld`, `.sls`, `.sps`) (#875) - Added comment styles: - `csingle` for Zig (`.zig`) and Hare (`.ha`) (#889) - Display recommendations for steps to fix found issues during a lint. (#698) - Add support for Pijul VCS. Pijul support is not added to the Docker image. (#858) - When running `annotate` on a file with an unrecognised file path, the tool currently exits early. To automatically create a .license file for unrecognised files, `--fallback-dot-license` has been added. (#823, #851, #853, #859; this took a while to get right.) - Ignore `.sl` directory as used by [Sapling SCM](https://sapling-scm.com/). (#867) ### Changed - Alpine Docker image now uses 3.18 as base. (#846) - The Git submodule detection was made less naïve. Where previously it detected a directory with a `.git` file as a submodule, it now uses the git command to detect submodules. This helps detect (quoted from Git man page) "[repositories] that were cloned independently and later added as a submodule or old setups", which "have the submodule's git directory inside the submodule instead of embedded into the superproject's git directory". (#687) - No longer scan binary or uncommentable files for their contents in search of REUSE information. (#825) - `--force-dot-license` and `--skip-unrecognised` are now mutually exclusive on `annotate`. (#852) - No longer create and publish `-extra` Docker images. The `openssh-client` package is now in the main image. (#849) - No longer create and publish `dev` Docker images. (#849) - The `-debian` Docker image is now based off debian:12-slim. It used to be based on the python:slim image, which used debian:slim under the hood. (#849) ### Removed - Removed deprecated `--explicit-license`. (#851) - Removed deprecated `addheader`. (#851) - No longer depend on `sphinx-autodoc-typehints` for documentation. (#772) ### Fixed - Syntax errors in .reuse/dep5 now have better error handling. (#841) - Reduced python-debian minimum version to 0.1.34. (#808) - Fix issue in `annotate` where `--single-line` and `--multi-line` would not correctly raise an error with an incompatible comment style. (#853) - Fix parsing existing copyright lines when they do not have a year (#861) - Better handling of Lisp comment styles. Now, any number of ";" characters is recognised as the prefix to a Lisp comment, and ";;;" is used when inserting comment headers, as per . (#874) ## 2.1.0 - 2023-07-18 After the yanked 2.0.0 release, we're excited to announce our latest major version packed with new features and improvements! We've expanded our file type recognition, now including Fennel, CommonJS, Qt .pro, .pri, .qrc, .qss, .ui, Textile, Visual Studio Code workspace, Application Resource Bundle, Svelte components, AES encrypted files, Jakarta Server Page, Clang format, Browserslist config, Prettier config and ignored files, Flutter pubspec.lock, .metadata, Terraform and HCL, Typst and more. We've also added the ability to detect SPDX snippet tags in files and introduced additional license metadata for the Python package. A new `--json` flag has been added to the `lint` command, marking the first step towards better integration of REUSE output with other tools. On the changes front, we've bumped the SPDX license list to v3.21 and made significant updates to our Sphinx documentation. Please note that Python 3.6 and 3.7 support has been dropped in this release. We've fixed several issues including automatic generation of Sphinx documentation via readthedocs.io and a compatibility issue where reuse could not be installed if gettext is not installed. This update is all about making your experience better. Enjoy adding copyright and licensing information to your code! ### Added - Detect SPDX snippet tags in files. (#699) - More file types are recognised: - Fennel (`.fnl`) (#638) - CommonJS (`.cjs`) (#632) - Qt .pro (`.pro`) (#632) - Qt .pri (`.pri`) (#755) - Qt .qrc (`.qrc`) (#755) - Qt .qss(`.qss`) (#755) - Qt .ui (`.ui`) (#755) - Textile (`.textile`) (#712) - Visual Studio Code workspace (`.code-workspace`) (#747) - Application Resource Bundle (`.arb`) (#749) - Svelte components (`.svelte`) - AES encrypted files (`.aes`) (#758) - Jakarte Server Page (`.jsp`) (#757) - Clang format (`.clang-format`) (#632) - Browserslist config (`.browserslist`) - Prettier config (`.prettierrc`) and ignored files (`.prettierignore`) - Flutter pubspec.lock (`pubspec.lock`) (#751) - Flutter .metadata (`.metadata`) (#751) - Terraform (`.tf`, `tfvars`) and HCL (`.hcl`). (#756) - Typst (`.typ`) - Added loglevel argument to pytest and skip one test if loglevel is too high (#645). - `--add-license-concluded`, `--creator-person`, and `--creator-organization` added to `reuse spdx`. (#623) - Additional license metadata for the Python package has been added. The actual SPDX license expression remains the same: `Apache-2.0 AND CC0-1.0 AND CC-BY-SA-4.0 AND GPL-3.0-or-later`. (#733) - Added `--contributor` option to `annotate`. (#669) - Added `--json` flag to `lint` command (#654). - `reuse.ReuseInfo` now has `copy` and `union` methods. (#759) - `reuse.ReuseInfo` now stores information about the source from which the information was gathered. (#654, #787) - Added Ukrainian and Czech translations (#767) - Added `--suppress-deprecation` to hide (verbose) deprecation warnings. (#778) ### Changed - Bumped SPDX license list to v3.20. (#692) - `reuse.SpdxInfo` was renamed to `reuse.ReuseInfo`. It is now a (frozen) dataclass instead of a namedtuple. This is only relevant if you're using reuse as a library in Python. Other functions and methods were similarly renamed. (#669) - Sphinx documentation: Switched from RTD theme to Furo. (#673, #716) - Removed dependency on setuptools' `pkg_resources` to determine the installed version of reuse. (#724) - Bumped SPDX license list to v3.21. (#763) - `Project.reuse_info_of` now returns a list of `ReuseInfo` objects instead of a single one. This is because the source information is now stored alongside the REUSE information. (#787) ### Deprecated - Pending deprecation of aggregation of file sources. Presently, when copyright and licensing information is defined both within e.g. the file itself and in the DEP5 file, then the information is merged or aggregated for the purposes of linting and BOM generation. In the future, this will no longer be the case unless explicitly defined. The exact mechanism for this is not yet concrete, but a `PendingDeprecationWarning` will be shown to the user to make them aware of this. (#778) ### Removed - Python 3.6 and 3.7 support has been dropped. (#673, #759) - Removed runtime and build time dependency on `setuptools`. (#724) ### Fixed - Fixed automatic generation of Sphinx documentation via readthedocs.io by adding a `.readthedocs.yaml` configuration file (#648) - Fixed a compatibility issue where reuse could not be installed (built) if gettext is not installed. (#691) - Translations are available in Docker images. (#701) - Marked the `/data` directory in Docker containers as safe in Git, preventing errors related to linting Git repositories. (#720) - Repaired error when using Galician translations. (#719) ### Security ## 2.0.0 - 2023-06-21 [YANKED] This version was yanked because of an unanticipated workflow that we broke. The breaking change is the fact that an order of precedence was defined for copyright and licensing information sources. For instance, if a file contained the `SPDX-License-Identifier` tag, and if that file was also (explicitly or implicitly) covered by DEP5, then the information from the DEP5 setting would no longer apply to that file. While the intention of the breaking change was sound (don't mix information sources; define a single source of truth), there were legitimate use-cases that were broken as a result of this. Apologies to everyone whose CI broke. We'll get this one right before long. ## 1.1.2 - 2023-02-09 ### Fixed - Note to maintainers: It is now possible/easier to use the `build` module to build this module. Previously, there was a namespace conflict. (#640) ## 1.1.1 - 2023-02-05 ### Fixed - Don't include documentation files (e.g. `README.md`) in top-level (i.e., `site-packages/`). (#657) - Include documentation directory in sdist. (#657) ## 1.1.0 - 2022-12-01 ### Added - Added support for Python 3.11. (#603) - More file types are recognised: - Kotlin script (`.kts`) - Android Interface Definition Language (`.aidl`) - Certificate files (`.pem`) - Added comment styles: - Apache Velocity Template (Extensions: `.vm`, `.vtl`) (#554) - XQuery comment style (Extensions: `.xq(l|m|y|uery|)`) (#610) - Some special endings are always stripped from copyright and licensing statements (#602): - `">` (and variations such as `'>`, `" >`, and `"/>`) - `] ::` ### Changed - Removed `setup.py` and replaced it with a Poetry configuration. Maintainers beware. (#600) - Updated PyPI development status to 'production/stable' (#381) - The pre-commit hook now passes `lint` as an overridable argument. (#574) - `addheader` has been renamed to `annotate`. The functionality remains the same. (#550) - Bumped SPDX license list to v3.19. ### Deprecated - `addheader` has been deprecated. It still works, but is now undocumented. (#550) ### Removed - `setup.py`. (#600) - Releases to PyPI are no longer GPG-signed. Support for this is not present in Poetry and not planned. (#600) - Dependency on `requests` removed; using `urllib.request` from the standard library instead. (#600) ### Fixed - Repair tests related to CVE-2022-39253 changes in upstream Git. New versions of Git no longer allow `git submodule add repository path` where repository is a file. A flag was added to explicitly allow this in the test framework. (#619) - Sanitize xargs input in scripts documentation. (#525) - License identifiers in comments with symmetrical ASCII art frames are now properly detected (#560) - Fixed an error where copyright statements contained within a multi-line comment style on a single line could not be parsed (#593). - In PHP files, add header after `=0.X.Y` in your requirements.txt, you will get the latest version of `reuse` when you install `fsfe-reuse`. You may like to change the name to `reuse` explicitly, but this is not strictly necessary. - If you depend on `fsfe-reuse==0.X.Y`, then you will keep getting that version. When you bump the version you depend on, you will need to change the name to `reuse`. - If you depend on `fsfe-reuse>=0.X.Y<1.0.0`, then 0.6.0 will be the latest version you receive. In order to get a later version, you will need to change the name to `reuse`. ## 0.6.0 - 2019-11-19 ### Added - `--include-submodules` is added to also include submodules when linting et cetera. - `addheader` now also recognises the following extensions: - .kt - .xml - .yaml - .yml ### Changed - Made the workaround for `MachineReadableFormatError` introduced in 0.5.2 more generic. - Improved shebang detection in `addheader`. - For `addheader`, the SPDX comment block now need not be the first thing in the file. It will find the SPDX comment block and deal with it in-place. - Git submodules are now ignored by default. - `addheader --explicit-license` now no longer breaks on unsupported filetypes. ## 0.5.2 - 2019-10-27 ### Added - `python3 -m reuse` now works. ### Changed - Updated license list to 3.6-2-g2a14810. ### Fixed - Performance of `reuse lint` improved by at least a factor of 2. It no longer does any checksums on files behind the scenes. - Also handle `MachineReadableFormatError` when parsing DEP5 files. Tries to import that error. If the import is unsuccessful, it is handled. ## 0.5.1 - 2019-10-24 [YANKED] This release was replaced by 0.5.2 due to importing `MachineReadableFormatError`, which is not a backwards-compatible change. ## 0.5.0 - 2019-08-29 ### Added - TeX and ML comment styles added. - Added `--year` and `--exclude-year` to `reuse addheader`. - Added `--template` to `reuse addheader`. - Added `--explicit-license` to `reuse addheader`. - `binaryornot` added as new dependency. - Greatly improved the usage documentation. ### Changed - `reuse addheader` now automatically adds the current year to the copyright notice. - `reuse addheader` preserves the original header below the new header if it did not contain any SPDX information. - `reuse addheader` now correctly handles `.license` files. - Bad licenses are no longer resolved to LicenseRef-Unknown. They are instead resolved to the stem of the path. This reduces the magic in the code base. - `.gitkeep` files are now ignored by the tool. - Changed Lisp's comment character from ';;' to ';'. ## 0.4.1 - 2019-08-07 ### Added - `--all` argument help to `reuse download`, which downloads all detected missing licenses. ### Fixed - When using `reuse addheader` on a file that contains a shebang, the shebang is preserved. - Copyright lines in `reuse spdx` are now sorted. - Some publicly visible TODOs were patched away. ## 0.4.0 - 2019-08-07 This release is a major overhaul and refactoring of the tool. Its primary focus is improved usability and speed, as well as adhering to version 3.0 of the REUSE Specification. ### Added - `reuse addheader` has been added as a way to automatically add copyright statements and license identifiers to the headers of files. It is currently not complete. - `reuse init` has been added as a way to initialise a REUSE project. Its functionality is currently scarce, but should improve in the future. ### Changed - `reuse lint` now provides a helpful summary instead of merely spitting out non-compliant files. - `reuse compile` is now `reuse spdx`. - In addition to `Copyright` and `©`, copyright lines can be marked with the tag `SPDX-FileCopyrightText:`. This is the new recommended default. - Project no longer depends on pygit2. - The list of SPDX licenses has been updated. - `Valid-License-Identifier` is no longer used, and licenses and exceptions can now only live inside of the LICENSES/ directory. ### Removed - Removed `--ignore-debian`. - Removed `--spdx-mandatory`, `--copyright-mandatory`, `--ignore-missing` arguments from `reuse lint`. - Remove `reuse license`. - GPL-3.0 and GPL-3.0+ (and all other similar GPL licenses) are no longer detected as SPDX identifiers. Use GPL-3.0-only and GPL-3.0-or-later instead. ### Fixed - Scanning a Git directory is a lot faster now. - Scanning binary files is a lot faster now. ## 0.3.4 - 2019-04-15 This release should be a short-lived one. A new (slightly backwards-incompatible) version is in the works. ### Added - Copyrights can now start with `©` in addition to `Copyright`. The former is now recommended, but they are functionally similar. ### Changed - The source code of reuse is now formatted with black. - The repository has been moved from to . ## 0.3.3 - 2018-07-15 ### Fixed - Any files with the suffix `.spdx` are no longer considered licenses. ## 0.3.2 - 2018-07-15 ### Fixed - The documentation now builds under Python 3.7. ## 0.3.1 - 2018-07-14 ### Fixed - When using reuse from a child directory using pygit2, correctly find the root. ## 0.3.0 - 2018-05-16 ### Changed - The output of `reuse compile` is now deterministic. The files, copyright lines and SPDX expressions are sorted alphabetically. ### Fixed - When a GPL license could not be found, the correct `-only` or `-or-later` extension is now used in the warning message, rather than a bare `GPL-3.0`. - If you have a license listed as `SPDX-Valid-License: GPL-3.0-or-later`, this now correctly matches corresponding SPDX identifiers. Still it is recommended to use `SPDX-Valid-License: GPL-3.0` instead. ## 0.2.0 - 2018-04-17 ### Added - Internationalisation support added. Initial support for: - English. - Dutch. - Esperanto. - Spanish. ### Fixed - The license list of SPDX 3.0 has deprecated `GPL-3.0` and `GPL-3.0+` et al in favour of `GPL-3.0-only` and `GPL-3.0-or-later`. The program has been amended to accommodate sufficiently for those licenses. ### Changed - `Project.reuse_info_of` now extracts, combines and returns information both from the file itself and from debian/copyright. - `ReuseInfo` now holds sets instead of lists. - As a result of this, `ReuseInfo` will not hold duplicates of copyright lines or SPDX expressions. - click removed as dependency. Good old argparse from the library is used instead. ## 0.1.1 - 2017-12-14 ### Changed - The `reuse --help` text has been tidied up a little bit. ### Fixed - Release date in change log fixed. - The PyPI homepage now gets reStructuredText instead of Markdown. ## 0.1.0 - 2017-12-14 ### Added - Successfully parse old-style C and HTML comments now. - Added `reuse compile`, which creates an SPDX bill of materials. - Added `--ignore-missing` to `reuse lint`. - Allow to specify multiple paths to `reuse lint`. - `chardet` added as dependency. - `pygit2` added as soft dependency. reuse remains usable without it, but the performance with `pygit2` is significantly better. Because `pygit2` has a non-Python dependency (`libgit2`), it must be installed independently by the user. In the future, when reuse is packaged natively, this will not be an issue. ### Changed - Updated to version 2.0 of the REUSE recommendations. The most important change is that `License-Filename` is no longer used. Instead, the filename is deducted from `SPDX-License-Identifier`. This change is **NOT** backwards compatible. - The conditions for linting have changed. A file is now non-compliant when: - The license associated with the file could not be found. - There is no SPDX expression associated with the file. - There is no copyright notice associated with the file. - Only read the first 4 KiB (by default) from code files rather than the entire file when searching for SPDX tags. This speeds up the tool a bit. - `Project.reuse_info_of` no longer raises an exception. Instead, it returns an empty `ReuseInfo` object when no reuse information is found. - Logging is a lot prettier now. Only output entries from the `reuse` module. ### Fixed - `reuse --ignore-debian compile` now works as expected. - The tool no longer breaks when reading a file that has a non-UTF-8 encoding. Instead, `chardet` is used to detect the encoding before reading the file. If a file still has errors during decoding, those errors are silently ignored and replaced. ## 0.0.4 - 2017-11-06 ### Fixed - Removed dependency on `os.PathLike` so that Python 3.5 is actually supported ## 0.0.3 - 2017-11-06 ### Fixed - Fixed the link to PyPI in the README. ## 0.0.2 - 2017-11-03 This is a very early development release aimed at distributing the program as soon as possible. Because this is the first release, the changelog is a little empty beyond "created the program". The program can do roughly the following: - Detect the license of a given file through one of three methods (in order of precedence): - Information embedded in the .license file. - Information embedded in its header. - Information from the global debian/copyright file. - Find and report all files in a project tree of which the license could not be found. - Ignore files ignored by Git. - Do some logging into STDERR. reuse-tool-4.0.3/CODE_OF_CONDUCT.md000066400000000000000000000004651464275211500164270ustar00rootroot00000000000000 All activity surrounding this project is covered by the Code of Conduct of the Free Software Foundation Europe, which can be found at . reuse-tool-4.0.3/CONTRIBUTING.md000066400000000000000000000115161464275211500160600ustar00rootroot00000000000000 # Contribution guidelines Any issues or suggestions are welcome at or via e-mail to one of the maintainers. General inquiries can be sent to . ## Code of conduct Interaction within this project is covered by the [FSFE's Code of Conduct](https://fsfe.org/about/codeofconduct). ## Scope and design goals of REUSE REUSE has a finite scope. The goal is to make upstream licensing **easy, comprehensive, unambiguous, and machine-readable**. Contributions which contradict the goals are unlikely to be accepted. Comprehensiveness is especially important; REUSE provides no real mechanism for excluding a file from REUSE compliance testing, and it is unlikely that such a mechanism will be added. Behaviour changes to linting are also unlikely to be accepted, even if they are good changes. The linting behaviour should always match the [REUSE Specification](https://reuse.software/spec/). If you think that the linting behaviour should change, you should open an issue on the [reuse-website](https://github.com/fsfe/reuse-website) repository. The linter does not accept any arguments or configurations which modify its behaviour in determining compliance. This is intentional. ## Pull requests Pull requests are generally welcome and encouraged, but please beware that they may be closed for various reasons, such as: - The change is out-of-scope for REUSE. - The change does not align with the design goals of REUSE. - The change is good, but the maintenance burden is too heavy. To be safe, open an issue and engage in dialogue before beginning to implement a feature that may not be accepted. When making a pull request, don't hesitate to add yourself to the AUTHORS.rst file and the copyright headers of the files you touch. ### Change log Every pull request should add a change log entry. Change log entries go into `changelog.d//.md`, where `` is the appropriate category for the change set, and where `` is a short or random name for your change set. The contents of the file should typically look like this: ```markdown - Added a new feature. (#pr_number) ``` At release time, the contents of the `changelog.d/` directory are compiled into `CHANGELOG.md` using `protokolo compile`. Some PRs are excepted from adding change log entries, such as changes which are too tiny to be significant, certain refactorings, or fixes to pull requests which were already merged, but not yet released. ## Translation Translations are welcome at . If you need additional help to get started, don't hesitate to get in touch with the maintainers. Broader instructions on how to help the FSFE translate things into local languages can be found at . The translators keep in touch with the mailing list. ## Local development Starting local development is very simple, just execute the following commands: ```bash git clone git@github.com:fsfe/reuse-tool.git cd reuse-tool/ poetry install # You may need to install poetry using your package manager. poetry run pre-commit install # Using poetry is optional here if you already have pre-commit. ``` Next, you'll find the following commands handy: - `poetry run reuse` - `poetry run pytest` - `poetry run pylint src` - `poetry run mypy` - `make docs` ## Development conventions ### Poetry Because our downstreams may not have a very recent version of Poetry, we should target `poetry-core>=1.4.0` and `poetry~=1.3.0` when interacting with Poetry, especially when generating the `poetry.lock` file. You can `pip install poetry~=1.3.0` to ascertain that you always get this right. In order to update the `poetry.lock` file while changing as few lines as possible, run `poetry lock --no-update`. ## Release checklist - Verify changelog - Create branch release-x.y.z - `bumpver update --set-version vx.y.z` - `make update-resources` - Alter changelog - Do some final tweaks/bugfixes (and alter changelog) - `make test-release` - `pip install -i https://test.pypi.org/simple reuse` and test the package. - Once everything is good, `git tag -s vx.y.z`. Minimal tag message. - `git push origin vx.y.z` - `make release` - `git checkout main` - `git merge release-x.y.z` - `git push origin main` - Create a release on GitHub. ### After release - Update readthedocs (if not happened automatically) - Update API worker: https://git.fsfe.org/reuse/api-worker#user-content-server - Make sure package is updated in distros (contact maintainers) - Update the revision in `dev.md` of [reuse-website](https://github.com/fsfe/reuse-website). - If a major release, make sure [reuse-action](https://github.com/fsfe/reuse-action/) is updated. reuse-tool-4.0.3/Dockerfile000066400000000000000000000016621464275211500156220ustar00rootroot00000000000000# SPDX-FileCopyrightText: 2019 Free Software Foundation Europe e.V. # SPDX-FileCopyrightText: 2022 Carmen Bianca Bakker # # SPDX-License-Identifier: GPL-3.0-or-later # Create a base image that has dependencies installed. FROM alpine:3.18 AS base RUN apk --no-cache add git mercurial python3 openssh-client # Build reuse into a virtualenv FROM base AS build RUN apk --no-cache add poetry gettext WORKDIR /reuse-tool COPY . /reuse-tool/ ENV VIRTUAL_ENV=/opt/venv RUN python3 -m venv $VIRTUAL_ENV ENV PATH="$VIRTUAL_ENV/bin:$PATH" RUN poetry install --no-interaction --no-root --only main RUN poetry build --no-interaction RUN pip install dist/*.whl # Copy over the virtualenv and use it FROM base COPY --from=build /opt/venv /opt/venv ENV VIRTUAL_ENV=/opt/venv ENV PATH="$VIRTUAL_ENV/bin:$PATH" RUN git config --global --add safe.directory /data WORKDIR /data ENTRYPOINT ["reuse"] CMD ["lint"] reuse-tool-4.0.3/Dockerfile-debian000066400000000000000000000021511464275211500170340ustar00rootroot00000000000000# SPDX-FileCopyrightText: 2021 Free Software Foundation Europe e.V. # # SPDX-License-Identifier: GPL-3.0-or-later # Create a base image that has dependencies installed. FROM debian:12-slim AS base RUN apt-get update \ && apt-get -y upgrade \ && apt-get -y --no-install-recommends install git mercurial python3 \ && apt-get -y clean \ && rm -rf /var/lib/apt/lists/* # Build reuse into a virtualenv FROM base AS build RUN apt-get update \ && apt-get -y --no-install-recommends install python3-venv python3-poetry python3-pip python3-wheel gettext \ && rm -rf /var/lib/apt/lists/* WORKDIR /reuse-tool COPY . /reuse-tool/ ENV VIRTUAL_ENV=/opt/venv RUN python3 -m venv $VIRTUAL_ENV ENV PATH="$VIRTUAL_ENV/bin:$PATH" RUN poetry install --no-interaction --no-root --only main RUN poetry build --no-interaction RUN pip install dist/*.whl # Copy over the virtualenv and use it FROM base COPY --from=build /opt/venv /opt/venv ENV VIRTUAL_ENV=/opt/venv ENV PATH="$VIRTUAL_ENV/bin:$PATH" RUN git config --global --add safe.directory /data WORKDIR /data ENTRYPOINT ["reuse"] CMD ["lint"] reuse-tool-4.0.3/LICENSES/000077500000000000000000000000001464275211500150305ustar00rootroot00000000000000reuse-tool-4.0.3/LICENSES/Apache-2.0.txt000066400000000000000000000261361464275211500172570ustar00rootroot00000000000000 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. reuse-tool-4.0.3/LICENSES/CC-BY-SA-4.0.txt000066400000000000000000000472431464275211500172000ustar00rootroot00000000000000Attribution-ShareAlike 4.0 International ======================================================================= Creative Commons Corporation ("Creative Commons") is not a law firm and does not provide legal services or legal advice. Distribution of Creative Commons public licenses does not create a lawyer-client or other relationship. Creative Commons makes its licenses and related information available on an "as-is" basis. Creative Commons gives no warranties regarding its licenses, any material licensed under their terms and conditions, or any related information. Creative Commons disclaims all liability for damages resulting from their use to the fullest extent possible. Using Creative Commons Public Licenses Creative Commons public licenses provide a standard set of terms and conditions that creators and other rights holders may use to share original works of authorship and other material subject to copyright and certain other rights specified in the public license below. The following considerations are for informational purposes only, are not exhaustive, and do not form part of our licenses. Considerations for licensors: Our public licenses are intended for use by those authorized to give the public permission to use material in ways otherwise restricted by copyright and certain other rights. Our licenses are irrevocable. Licensors should read and understand the terms and conditions of the license they choose before applying it. Licensors should also secure all rights necessary before applying our licenses so that the public can reuse the material as expected. Licensors should clearly mark any material not subject to the license. This includes other CC- licensed material, or material used under an exception or limitation to copyright. More considerations for licensors: wiki.creativecommons.org/Considerations_for_licensors Considerations for the public: By using one of our public licenses, a licensor grants the public permission to use the licensed material under specified terms and conditions. If the licensor's permission is not necessary for any reason--for example, because of any applicable exception or limitation to copyright--then that use is not regulated by the license. Our licenses grant only permissions under copyright and certain other rights that a licensor has authority to grant. Use of the licensed material may still be restricted for other reasons, including because others have copyright or other rights in the material. A licensor may make special requests, such as asking that all changes be marked or described. Although not required by our licenses, you are encouraged to respect those requests where reasonable. More_considerations for the public: wiki.creativecommons.org/Considerations_for_licensees ======================================================================= Creative Commons Attribution-ShareAlike 4.0 International Public License By exercising the Licensed Rights (defined below), You accept and agree to be bound by the terms and conditions of this Creative Commons Attribution-ShareAlike 4.0 International Public License ("Public License"). To the extent this Public License may be interpreted as a contract, You are granted the Licensed Rights in consideration of Your acceptance of these terms and conditions, and the Licensor grants You such rights in consideration of benefits the Licensor receives from making the Licensed Material available under these terms and conditions. Section 1 -- Definitions. a. Adapted Material means material subject to Copyright and Similar Rights that is derived from or based upon the Licensed Material and in which the Licensed Material is translated, altered, arranged, transformed, or otherwise modified in a manner requiring permission under the Copyright and Similar Rights held by the Licensor. For purposes of this Public License, where the Licensed Material is a musical work, performance, or sound recording, Adapted Material is always produced where the Licensed Material is synched in timed relation with a moving image. b. Adapter's License means the license You apply to Your Copyright and Similar Rights in Your contributions to Adapted Material in accordance with the terms and conditions of this Public License. c. BY-SA Compatible License means a license listed at creativecommons.org/compatiblelicenses, approved by Creative Commons as essentially the equivalent of this Public License. d. Copyright and Similar Rights means copyright and/or similar rights closely related to copyright including, without limitation, performance, broadcast, sound recording, and Sui Generis Database Rights, without regard to how the rights are labeled or categorized. For purposes of this Public License, the rights specified in Section 2(b)(1)-(2) are not Copyright and Similar Rights. e. Effective Technological Measures means those measures that, in the absence of proper authority, may not be circumvented under laws fulfilling obligations under Article 11 of the WIPO Copyright Treaty adopted on December 20, 1996, and/or similar international agreements. f. Exceptions and Limitations means fair use, fair dealing, and/or any other exception or limitation to Copyright and Similar Rights that applies to Your use of the Licensed Material. g. License Elements means the license attributes listed in the name of a Creative Commons Public License. The License Elements of this Public License are Attribution and ShareAlike. h. Licensed Material means the artistic or literary work, database, or other material to which the Licensor applied this Public License. i. Licensed Rights means the rights granted to You subject to the terms and conditions of this Public License, which are limited to all Copyright and Similar Rights that apply to Your use of the Licensed Material and that the Licensor has authority to license. j. Licensor means the individual(s) or entity(ies) granting rights under this Public License. k. Share means to provide material to the public by any means or process that requires permission under the Licensed Rights, such as reproduction, public display, public performance, distribution, dissemination, communication, or importation, and to make material available to the public including in ways that members of the public may access the material from a place and at a time individually chosen by them. l. Sui Generis Database Rights means rights other than copyright resulting from Directive 96/9/EC of the European Parliament and of the Council of 11 March 1996 on the legal protection of databases, as amended and/or succeeded, as well as other essentially equivalent rights anywhere in the world. m. You means the individual or entity exercising the Licensed Rights under this Public License. Your has a corresponding meaning. Section 2 -- Scope. a. License grant. 1. Subject to the terms and conditions of this Public License, the Licensor hereby grants You a worldwide, royalty-free, non-sublicensable, non-exclusive, irrevocable license to exercise the Licensed Rights in the Licensed Material to: a. reproduce and Share the Licensed Material, in whole or in part; and b. produce, reproduce, and Share Adapted Material. 2. Exceptions and Limitations. For the avoidance of doubt, where Exceptions and Limitations apply to Your use, this Public License does not apply, and You do not need to comply with its terms and conditions. 3. Term. The term of this Public License is specified in Section 6(a). 4. Media and formats; technical modifications allowed. The Licensor authorizes You to exercise the Licensed Rights in all media and formats whether now known or hereafter created, and to make technical modifications necessary to do so. The Licensor waives and/or agrees not to assert any right or authority to forbid You from making technical modifications necessary to exercise the Licensed Rights, including technical modifications necessary to circumvent Effective Technological Measures. For purposes of this Public License, simply making modifications authorized by this Section 2(a) (4) never produces Adapted Material. 5. Downstream recipients. a. Offer from the Licensor -- Licensed Material. Every recipient of the Licensed Material automatically receives an offer from the Licensor to exercise the Licensed Rights under the terms and conditions of this Public License. b. Additional offer from the Licensor -- Adapted Material. Every recipient of Adapted Material from You automatically receives an offer from the Licensor to exercise the Licensed Rights in the Adapted Material under the conditions of the Adapter's License You apply. c. No downstream restrictions. You may not offer or impose any additional or different terms or conditions on, or apply any Effective Technological Measures to, the Licensed Material if doing so restricts exercise of the Licensed Rights by any recipient of the Licensed Material. 6. No endorsement. Nothing in this Public License constitutes or may be construed as permission to assert or imply that You are, or that Your use of the Licensed Material is, connected with, or sponsored, endorsed, or granted official status by, the Licensor or others designated to receive attribution as provided in Section 3(a)(1)(A)(i). b. Other rights. 1. Moral rights, such as the right of integrity, are not licensed under this Public License, nor are publicity, privacy, and/or other similar personality rights; however, to the extent possible, the Licensor waives and/or agrees not to assert any such rights held by the Licensor to the limited extent necessary to allow You to exercise the Licensed Rights, but not otherwise. 2. Patent and trademark rights are not licensed under this Public License. 3. To the extent possible, the Licensor waives any right to collect royalties from You for the exercise of the Licensed Rights, whether directly or through a collecting society under any voluntary or waivable statutory or compulsory licensing scheme. In all other cases the Licensor expressly reserves any right to collect such royalties. Section 3 -- License Conditions. Your exercise of the Licensed Rights is expressly made subject to the following conditions. a. Attribution. 1. If You Share the Licensed Material (including in modified form), You must: a. retain the following if it is supplied by the Licensor with the Licensed Material: i. identification of the creator(s) of the Licensed Material and any others designated to receive attribution, in any reasonable manner requested by the Licensor (including by pseudonym if designated); ii. a copyright notice; iii. a notice that refers to this Public License; iv. a notice that refers to the disclaimer of warranties; v. a URI or hyperlink to the Licensed Material to the extent reasonably practicable; b. indicate if You modified the Licensed Material and retain an indication of any previous modifications; and c. indicate the Licensed Material is licensed under this Public License, and include the text of, or the URI or hyperlink to, this Public License. 2. You may satisfy the conditions in Section 3(a)(1) in any reasonable manner based on the medium, means, and context in which You Share the Licensed Material. For example, it may be reasonable to satisfy the conditions by providing a URI or hyperlink to a resource that includes the required information. 3. If requested by the Licensor, You must remove any of the information required by Section 3(a)(1)(A) to the extent reasonably practicable. b. ShareAlike. In addition to the conditions in Section 3(a), if You Share Adapted Material You produce, the following conditions also apply. 1. The Adapter's License You apply must be a Creative Commons license with the same License Elements, this version or later, or a BY-SA Compatible License. 2. You must include the text of, or the URI or hyperlink to, the Adapter's License You apply. You may satisfy this condition in any reasonable manner based on the medium, means, and context in which You Share Adapted Material. 3. You may not offer or impose any additional or different terms or conditions on, or apply any Effective Technological Measures to, Adapted Material that restrict exercise of the rights granted under the Adapter's License You apply. Section 4 -- Sui Generis Database Rights. Where the Licensed Rights include Sui Generis Database Rights that apply to Your use of the Licensed Material: a. for the avoidance of doubt, Section 2(a)(1) grants You the right to extract, reuse, reproduce, and Share all or a substantial portion of the contents of the database; b. if You include all or a substantial portion of the database contents in a database in which You have Sui Generis Database Rights, then the database in which You have Sui Generis Database Rights (but not its individual contents) is Adapted Material, including for purposes of Section 3(b); and c. You must comply with the conditions in Section 3(a) if You Share all or a substantial portion of the contents of the database. For the avoidance of doubt, this Section 4 supplements and does not replace Your obligations under this Public License where the Licensed Rights include other Copyright and Similar Rights. Section 5 -- Disclaimer of Warranties and Limitation of Liability. a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS, IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU. b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION, NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT, INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES, COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR IN PART, THIS LIMITATION MAY NOT APPLY TO YOU. c. The disclaimer of warranties and limitation of liability provided above shall be interpreted in a manner that, to the extent possible, most closely approximates an absolute disclaimer and waiver of all liability. Section 6 -- Term and Termination. a. This Public License applies for the term of the Copyright and Similar Rights licensed here. However, if You fail to comply with this Public License, then Your rights under this Public License terminate automatically. b. Where Your right to use the Licensed Material has terminated under Section 6(a), it reinstates: 1. automatically as of the date the violation is cured, provided it is cured within 30 days of Your discovery of the violation; or 2. upon express reinstatement by the Licensor. For the avoidance of doubt, this Section 6(b) does not affect any right the Licensor may have to seek remedies for Your violations of this Public License. c. For the avoidance of doubt, the Licensor may also offer the Licensed Material under separate terms or conditions or stop distributing the Licensed Material at any time; however, doing so will not terminate this Public License. d. Sections 1, 5, 6, 7, and 8 survive termination of this Public License. Section 7 -- Other Terms and Conditions. a. The Licensor shall not be bound by any additional or different terms or conditions communicated by You unless expressly agreed. b. Any arrangements, understandings, or agreements regarding the Licensed Material not stated herein are separate from and independent of the terms and conditions of this Public License. Section 8 -- Interpretation. a. For the avoidance of doubt, this Public License does not, and shall not be interpreted to, reduce, limit, restrict, or impose conditions on any use of the Licensed Material that could lawfully be made without permission under this Public License. b. To the extent possible, if any provision of this Public License is deemed unenforceable, it shall be automatically reformed to the minimum extent necessary to make it enforceable. If the provision cannot be reformed, it shall be severed from this Public License without affecting the enforceability of the remaining terms and conditions. c. No term or condition of this Public License will be waived and no failure to comply consented to unless expressly agreed to by the Licensor. d. Nothing in this Public License constitutes or may be interpreted as a limitation upon, or waiver of, any privileges and immunities that apply to the Licensor or You, including from the legal processes of any jurisdiction or authority. ======================================================================= Creative Commons is not a party to its public licenses. Notwithstanding, Creative Commons may elect to apply one of its public licenses to material it publishes and in those instances will be considered the “Licensor.” The text of the Creative Commons public licenses is dedicated to the public domain under the CC0 Public Domain Dedication. Except for the limited purpose of indicating that material is shared under a Creative Commons public license or as otherwise permitted by the Creative Commons policies published at creativecommons.org/policies, Creative Commons does not authorize the use of the trademark "Creative Commons" or any other trademark or logo of Creative Commons without its prior written consent including, without limitation, in connection with any unauthorized modifications to any of its public licenses or any other arrangements, understandings, or agreements concerning use of licensed material. For the avoidance of doubt, this paragraph does not form part of the public licenses. Creative Commons may be contacted at creativecommons.org. reuse-tool-4.0.3/LICENSES/CC0-1.0.txt000066400000000000000000000156101464275211500164350ustar00rootroot00000000000000Creative Commons Legal Code CC0 1.0 Universal CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED HEREUNDER. Statement of Purpose The laws of most jurisdictions throughout the world automatically confer exclusive Copyright and Related Rights (defined below) upon the creator and subsequent owner(s) (each and all, an "owner") of an original work of authorship and/or a database (each, a "Work"). Certain owners wish to permanently relinquish those rights to a Work for the purpose of contributing to a commons of creative, cultural and scientific works ("Commons") that the public can reliably and without fear of later claims of infringement build upon, modify, incorporate in other works, reuse and redistribute as freely as possible in any form whatsoever and for any purposes, including without limitation commercial purposes. These owners may contribute to the Commons to promote the ideal of a free culture and the further production of creative, cultural and scientific works, or to gain reputation or greater distribution for their Work in part through the use and efforts of others. For these and/or other purposes and motivations, and without any expectation of additional consideration or compensation, the person associating CC0 with a Work (the "Affirmer"), to the extent that he or she is an owner of Copyright and Related Rights in the Work, voluntarily elects to apply CC0 to the Work and publicly distribute the Work under its terms, with knowledge of his or her Copyright and Related Rights in the Work and the meaning and intended legal effect of CC0 on those rights. 1. Copyright and Related Rights. A Work made available under CC0 may be protected by copyright and related or neighboring rights ("Copyright and Related Rights"). Copyright and Related Rights include, but are not limited to, the following: i. the right to reproduce, adapt, distribute, perform, display, communicate, and translate a Work; ii. moral rights retained by the original author(s) and/or performer(s); iii. publicity and privacy rights pertaining to a person's image or likeness depicted in a Work; iv. rights protecting against unfair competition in regards to a Work, subject to the limitations in paragraph 4(a), below; v. rights protecting the extraction, dissemination, use and reuse of data in a Work; vi. database rights (such as those arising under Directive 96/9/EC of the European Parliament and of the Council of 11 March 1996 on the legal protection of databases, and under any national implementation thereof, including any amended or successor version of such directive); and vii. other similar, equivalent or corresponding rights throughout the world based on applicable law or treaty, and any national implementations thereof. 2. Waiver. To the greatest extent permitted by, but not in contravention of, applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and unconditionally waives, abandons, and surrenders all of Affirmer's Copyright and Related Rights and associated claims and causes of action, whether now known or unknown (including existing as well as future claims and causes of action), in the Work (i) in all territories worldwide, (ii) for the maximum duration provided by applicable law or treaty (including future time extensions), (iii) in any current or future medium and for any number of copies, and (iv) for any purpose whatsoever, including without limitation commercial, advertising or promotional purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each member of the public at large and to the detriment of Affirmer's heirs and successors, fully intending that such Waiver shall not be subject to revocation, rescission, cancellation, termination, or any other legal or equitable action to disrupt the quiet enjoyment of the Work by the public as contemplated by Affirmer's express Statement of Purpose. 3. Public License Fallback. Should any part of the Waiver for any reason be judged legally invalid or ineffective under applicable law, then the Waiver shall be preserved to the maximum extent permitted taking into account Affirmer's express Statement of Purpose. In addition, to the extent the Waiver is so judged Affirmer hereby grants to each affected person a royalty-free, non transferable, non sublicensable, non exclusive, irrevocable and unconditional license to exercise Affirmer's Copyright and Related Rights in the Work (i) in all territories worldwide, (ii) for the maximum duration provided by applicable law or treaty (including future time extensions), (iii) in any current or future medium and for any number of copies, and (iv) for any purpose whatsoever, including without limitation commercial, advertising or promotional purposes (the "License"). The License shall be deemed effective as of the date CC0 was applied by Affirmer to the Work. Should any part of the License for any reason be judged legally invalid or ineffective under applicable law, such partial invalidity or ineffectiveness shall not invalidate the remainder of the License, and in such case Affirmer hereby affirms that he or she will not (i) exercise any of his or her remaining Copyright and Related Rights in the Work or (ii) assert any associated claims and causes of action with respect to the Work, in either case contrary to Affirmer's express Statement of Purpose. 4. Limitations and Disclaimers. a. No trademark or patent rights held by Affirmer are waived, abandoned, surrendered, licensed or otherwise affected by this document. b. Affirmer offers the Work as-is and makes no representations or warranties of any kind concerning the Work, express, implied, statutory or otherwise, including without limitation warranties of title, merchantability, fitness for a particular purpose, non infringement, or the absence of latent or other defects, accuracy, or the present or absence of errors, whether or not discoverable, all to the greatest extent permissible under applicable law. c. Affirmer disclaims responsibility for clearing rights of other persons that may apply to the Work or any use thereof, including without limitation any person's Copyright and Related Rights in the Work. Further, Affirmer disclaims responsibility for obtaining any necessary consents, permissions or other rights required for any use of the Work. d. Affirmer understands and acknowledges that Creative Commons is not a party to this document and has no duty or obligation with respect to this CC0 or use of the Work. reuse-tool-4.0.3/LICENSES/GPL-3.0-or-later.txt000066400000000000000000001045151464275211500202420ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . reuse-tool-4.0.3/Makefile000066400000000000000000000057411464275211500152720ustar00rootroot00000000000000# SPDX-FileCopyrightText: 2017 Free Software Foundation Europe e.V. # SPDX-FileCopyrightText: 2023 DB Systel GmbH # SPDX-FileCopyrightText: 2023 Carmen Bianca BAKKER # # SPDX-License-Identifier: GPL-3.0-or-later .DEFAULT_GOAL := help .PHONY: help help: ## show this help message @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' .PHONY: clean clean: clean-build clean-pyc clean-test clean-docs ## remove all build, test, coverage and Python artifacts .PHONY: clean-build clean-build: ## remove build artifacts rm -fr build/ rm -fr dist/ rm -fr .cache/ rm -fr .eggs/ rm -fr pip-wheel-metadata/ find . -name '*.mo' -exec rm -f {} + find . -name '*.egg-info' -exec rm -fr {} + find . -name '*.egg' -exec rm -fr {} + .PHONY: clean-pyc clean-pyc: ## remove Python file artifacts find . -name '*.pyc' -exec rm -f {} + find . -name '*.pyo' -exec rm -f {} + find . -name '*~' -exec rm -f {} + find . -name '__pycache__' -exec rm -fr {} + .PHONY: clean-test clean-test: ## remove test and coverage artifacts rm -f .coverage* rm -fr htmlcov/ rm -fr .pytest_cache/ .PHONY: clean-docs clean-docs: ## remove docs build artifacts -$(MAKE) -C docs clean rm -fr docs/api/ rm -f docs/*.md .PHONY: reuse reuse: dist ## check with self poetry run reuse lint tar -xf dist/reuse*.tar.gz -C dist/ # This prevents the linter from using the project root as root. git init dist/reuse*/ poetry run reuse --root dist/reuse*/ lint .PHONY: lint-third-party lint-third-party: ## Lint selected third-party repositories to compare with expected output poetry run python3 .github/workflows/third_party_lint.py --defaults --json .PHONY: docs docs: clean-docs ## generate Sphinx HTML documentation, including API docs $(MAKE) -C docs html man .PHONY: dist dist: clean-build clean-pyc clean-docs ## builds source and wheel package poetry build ls -l dist .PHONY: create-pot create-pot: ## generate .pot file xgettext --add-comments --from-code=utf-8 --output=po/reuse.pot src/reuse/**.py xgettext --add-comments --output=po/argparse.pot /usr/lib*/python3*/argparse.py msgcat --output=po/reuse.pot po/reuse.pot po/argparse.pot for name in po/*.po; do \ msgmerge --output=$${name} $${name} po/reuse.pot; \ done .PHONY: update-po-files update-po-files: create-pot ## update .po files find ./po -name "*.po" -exec msgmerge --width=79 --output={} {} po/reuse.pot \; .PHONY: test-release test-release: ## package and upload to testpypi poetry config repositories.test-pypi https://test.pypi.org/legacy/ # You may need to use `poetry config pypi-token.test-pypi pypi-YYYYYYYY` poetry publish --build -r test-pypi .PHONY: release release: ## package and upload a release # You may need to use `poetry config pypi-token.pypi pypi-YYYYYYYY` poetry publish --build .PHONY: update-resources update-resources: ## update spdx data files python .github/workflows/license_list_up_to_date.py --download reuse-tool-4.0.3/README.md000066400000000000000000000237641464275211500151160ustar00rootroot00000000000000 # reuse [![The latest version of reuse can be found on PyPI.](https://img.shields.io/pypi/v/reuse.svg)](https://pypi.python.org/pypi/reuse) [![Information on what versions of Python reuse supports can be found on PyPI.](https://img.shields.io/pypi/pyversions/reuse.svg)](https://pypi.python.org/pypi/reuse) [![REUSE status](https://api.reuse.software/badge/github.com/fsfe/reuse-tool)](https://api.reuse.software/info/github.com/fsfe/reuse-tool) [![standard-readme compliant](https://img.shields.io/badge/readme%20style-standard-brightgreen.svg)](https://github.com/RichardLitt/standard-readme) [![Packaging status](https://repology.org/badge/tiny-repos/reuse.svg?header=in%20distro%20repos)](https://repology.org/project/reuse/versions) [![Translation status](https://hosted.weblate.org/widgets/fsfe/-/reuse-tool/svg-badge.svg)](https://hosted.weblate.org/projects/fsfe/reuse-tool/) reuse is a tool for compliance with the [REUSE](https://reuse.software/) recommendations. - Documentation: and - Source code: - PyPI: - REUSE: 3.2 - Python: 3.8+ ## Table of contents - [Background](#background) - [Install](#install) - [Usage](#usage) - [Maintainers](#maintainers) - [Contributing](#contributing) - [Licensing](#licensing) ## Background Copyright and licensing is difficult, especially when reusing software from different projects that are released under various different licenses. [REUSE](https://reuse.software) was started by the [Free Software Foundation Europe](https://fsfe.org) (FSFE) to provide a set of recommendations to make licensing your Free Software projects easier. Not only do these recommendations make it easier for you to declare the licenses under which your works are released, but they also make it easier for a computer to understand how your project is licensed. As a short summary, the recommendations are threefold: 1. Choose and provide licenses 2. Add copyright and licensing information to each file 3. Confirm REUSE compliance You are recommended to read [our tutorial](https://reuse.software/tutorial) for a step-by-step guide through these three steps. The [FAQ](https://reuse.software/faq) covers basic questions about licensing, copyright, and more complex use cases. Advanced users and integrators will find the [full specification](https://reuse.software/spec) helpful. This tool exists to facilitate the developer in complying with the above recommendations. There are [other tools](https://reuse.software/comparison) that have a lot more features and functionality surrounding the analysis and inspection of copyright and licenses in software projects. The REUSE helper tool, on the other hand, is solely designed to be a simple tool to assist in compliance with the REUSE recommendations. ## Install ### Installation via package manager (Recommended) There are packages available for easy install on many operating systems. You are welcome to help us package this tool for more distributions! An automatically generated list can be found at [repology.org](https://repology.org/project/reuse/versions), without any guarantee for completeness. ### Install and run via pipx (Recommended) The following one-liner both installs and runs this tool from [PyPI](https://pypi.org/project/reuse/) via [pipx](https://pypa.github.io/pipx/): ```bash pipx run reuse lint ``` pipx automatically isolates reuse into its own Python virtualenv, which means that it won't interfere with other Python packages, and other Python packages won't interfere with it. If you want to be able to use reuse without prepending it with `pipx run` every time, install it globally like so: ```bash pipx install reuse ``` reuse will then be available in `~/.local/bin`, which must be added to your `$PATH`. After this, make sure that `~/.local/bin` is in your `$PATH`. On Windows, the required path for your environment may look like `%USERPROFILE%\AppData\Roaming\Python\Python39\Scripts`, depending on the Python version you have installed. To upgrade reuse, run this command: ```bash pipx upgrade reuse ``` For full functionality, the following pieces of software are recommended: - Git - Mercurial 4.3+ - Pijul ### Installation via pip To install reuse into `~/.local/bin`, run: ```bash pip3 install --user reuse ``` Subsequently, make sure that `~/.local/bin` is in your `$PATH` like described in the previous section. To upgrade reuse, run this command: ```bash pip3 install --user --upgrade reuse ``` ### Installation from source You can also install this tool from the source code, but we recommend the methods above for easier and more stable updates. Please make sure the requirements for the installation via pip are present on your machine. ```bash pip install . ``` ## Usage First, read the [REUSE tutorial](https://reuse.software/tutorial/). In a nutshell: 1. Put your licenses in the `LICENSES/` directory. 2. Add a comment header to each file that says `SPDX-License-Identifier: GPL-3.0-or-later`, and `SPDX-FileCopyrightText: $YEAR $NAME`. You can be flexible with the format, just make sure that the line starts with `SPDX-FileCopyrightText:`. 3. Verify your work using this tool. Example of header: ``` # SPDX-FileCopyrightText: 2017 Free Software Foundation Europe e.V. # # SPDX-License-Identifier: CC-BY-SA-4.0 ``` ### CLI To check against the recommendations, use `reuse lint`: ``` ~/Projects/reuse-tool $ reuse lint [...] Congratulations! Your project is compliant with version 3.2 of the REUSE Specification :-) ``` This tool can do various more things, detailed in the documentation. Here a short summary: - `annotate` --- Add copyright and/or licensing information to the header of a file. - `download` --- Download the specified license into the `LICENSES/` directory. - `init` --- Set up the project for REUSE compliance. - `lint` --- Verify the project for REUSE compliance. - `spdx` --- Generate an SPDX Document of all files in the project. - `supported-licenses` --- Prints all licenses supported by REUSE. ### Example demo In this screencast, we are going to follow the [tutorial](https://reuse.software/tutorial), making the [REUSE example repository](https://github.com/fsfe/reuse-example/) compliant. ![Demo of some basic REUSE tool commands](https://download.fsfe.org/videos/reuse/screencasts/reuse-tool.gif) ### Run in Docker The `fsfe/reuse` Docker image is available on [Docker Hub](https://hub.docker.com/r/fsfe/reuse). With it, you can easily include REUSE in CI/CD processes. This way, you can check for REUSE compliance for each build. In our [resources for developers](https://reuse.software/dev/) you can learn how to integrate the REUSE tool in Drone, Travis, GitHub, or GitLab CI. You can run the helper tool simply by providing the command you want to run (e.g., `lint`, `spdx`). The image's working directory is `/data` by default. So if you want to lint a project that is in your current working directory, you can mount it on the container's `/data` directory, and tell the tool to lint. That looks a little like this: ```bash docker run --rm --volume $(pwd):/data fsfe/reuse lint ``` You can also provide additional arguments, like so: ```bash docker run --rm --volume $(pwd):/data fsfe/reuse --include-submodules spdx -o out.spdx ``` The available tags are: - `latest` --- the most recent release of reuse. - `{major}` --- the latest major release. - `{major}.{minor}` --- the latest minor release. - `{major}.{minor}.{patch}` --- a precise release. You can add `-debian` to any of the tags to get a Debian-based instead of an Alpine-based image, which is larger, but may be better suited for license compliance. ### Run as pre-commit hook You can automatically run `reuse lint` on every commit as a pre-commit hook for Git. This uses [pre-commit](https://pre-commit.com/). Once you [have it installed](https://pre-commit.com/#install), add this to the `.pre-commit-config.yaml` in your repository: ```yaml repos: - repo: https://github.com/fsfe/reuse-tool rev: v3.0.2 hooks: - id: reuse ``` Then run `pre-commit install`. Now, every time you commit, `reuse lint` is run in the background, and will prevent your commit from going through if there was an error. ## Maintainers - Carmen Bianca Bakker ### Former maintainers - Max Mehl - Linus Sehn ## Contributing If you're interested in contributing to the reuse project, there are several ways to get involved. Development of the project takes place on GitHub at . There, you can submit bug reports, feature requests, and pull requests. Even and especially when in doubt, feel free to open an issue with a question. Contributions of all types are welcome, and the development team is happy to provide guidance and support for new contributors. You should exercise some caution when opening a pull request to make changes which were not (yet) acknowledged by the team as pertinent. Such pull requests may be closed, leading to disappointment. To avoid this, please open an issue first. Additionally, the mailing list is available for discussion and support related to the project. You can find the full contribution guidelines at . ## Licensing This work is licensed under multiple licences. Because keeping this section up-to-date is challenging, here is a brief summary as of April 2024: - All original source code is licensed under GPL-3.0-or-later. - All documentation is licensed under CC-BY-SA-4.0. - Some configuration and data files are licensed under CC0-1.0. - Some code borrowed from [spdx/tools-python](https://github.com/spdx/tools-python) is licensed under Apache-2.0. For more accurate information, check the individual files. reuse-tool-4.0.3/REUSE.toml000066400000000000000000000035501464275211500154060ustar00rootroot00000000000000# SPDX-FileCopyrightText: 2023 Free Software Foundation Europe e.V. # # SPDX-License-Identifier: CC0-1.0 version = 1 [[annotations]] path = [ ".bumpversion.cfg", "setup.cfg" ] precedence = "override" SPDX-FileCopyrightText = "2017 Free Software Foundation Europe e.V. " SPDX-License-Identifier = "GPL-3.0-or-later" [[annotations]] path = "docs/reuse*.rst" precedence = "override" SPDX-FileCopyrightText = "2017 Free Software Foundation Europe e.V. " SPDX-License-Identifier = "CC-BY-SA-4.0" [[annotations]] path = "docs/modules.rst" precedence = "override" SPDX-FileCopyrightText = "2017 Free Software Foundation Europe e.V. " SPDX-License-Identifier = "CC-BY-SA-4.0" [[annotations]] path = "po/*.po" precedence = "aggregate" SPDX-FileCopyrightText = "2023 Free Software Foundation Europe e.V. " SPDX-License-Identifier = "CC-BY-SA-4.0" [[annotations]] path = "tests/resources/**" precedence = "override" SPDX-FileCopyrightText = "2017 Free Software Foundation Europe e.V. " SPDX-License-Identifier = "GPL-3.0-or-later" [[annotations]] path = "src/reuse.egg-info/**" precedence = "override" SPDX-FileCopyrightText = "2017 Free Software Foundation Europe e.V. " SPDX-License-Identifier = "GPL-3.0-or-later" [[annotations]] path = "poetry.lock" precedence = "override" SPDX-FileCopyrightText = "2017 Free Software Foundation Europe e.V. " SPDX-License-Identifier = "CC0-1.0" [[annotations]] path = ".github/pull_request_template.md" precedence = "override" SPDX-FileCopyrightText = "2024 Free Software Foundation Europe e.V. " SPDX-License-Identifier = "CC0-1.0" [[annotations]] path = "changelog.d/**/*.md" SPDX-FileCopyrightText = "REUSE contributors" SPDX-License-Identifier = "CC-BY-SA-4.0 OR GPL-3.0-or-later" reuse-tool-4.0.3/_build.py000066400000000000000000000041751464275211500154420ustar00rootroot00000000000000#!/usr/bin/env python3 # # SPDX-FileCopyrightText: 2017 Free Software Foundation Europe e.V. # SPDX-FileCopyrightText: 2022 Carmen Bianca Bakker # # SPDX-License-Identifier: GPL-3.0-or-later """Script called by poetry. The API used by poetry is unstable, but let's hope this stays functional. """ import glob import logging import os import shutil import subprocess from pathlib import Path _LOGGER = logging.getLogger(__name__) ROOT_DIR = Path(os.path.dirname(__file__)) BUILD_DIR = ROOT_DIR / "build" PO_DIR = ROOT_DIR / "po" def mkdir_p(path): """Make directory and its parents.""" Path(path).mkdir(parents=True, exist_ok=True) def rm_fr(path): """Force-remove directory.""" path = Path(path) if path.exists(): shutil.rmtree(path) def main(): """Compile .mo files and move them into src directory.""" rm_fr(BUILD_DIR) mkdir_p(BUILD_DIR) msgfmt = None for executable in ["msgfmt", "msgfmt.py", "msgfmt3.py"]: msgfmt = shutil.which(executable) if msgfmt: break if msgfmt: po_files = glob.glob(f"{PO_DIR}/*.po") mo_files = [] # Compile for po_file in po_files: _LOGGER.info(f"compiling {po_file}") lang_dir = ( BUILD_DIR / "reuse/locale" / Path(po_file).stem / "LC_MESSAGES" ) mkdir_p(lang_dir) destination = Path(lang_dir) / "reuse.mo" subprocess.run( [ msgfmt, "-o", str(destination), str(po_file), ], check=True, ) mo_files.append(destination) # Move compiled files into src rm_fr(ROOT_DIR / "src/reuse/locale") for mo_file in mo_files: relative = ( ROOT_DIR / Path("src") / os.path.relpath(mo_file, BUILD_DIR) ) _LOGGER.info(f"copying {mo_file} to {relative}") mkdir_p(relative.parent) shutil.copyfile(mo_file, relative) if __name__ == "__main__": main() reuse-tool-4.0.3/changelog.d/000077500000000000000000000000001464275211500157745ustar00rootroot00000000000000reuse-tool-4.0.3/changelog.d/.protokolo.toml000066400000000000000000000002721464275211500210000ustar00rootroot00000000000000# SPDX-FileCopyrightText: 2024 Free Software Foundation Europe e.V. # # SPDX-License-Identifier: CC0-1.0 [protokolo.section] title = "${version} - ${date}" level = 2 reuse-tool-4.0.3/changelog.d/added/000077500000000000000000000000001464275211500170355ustar00rootroot00000000000000reuse-tool-4.0.3/changelog.d/added/.protokolo.toml000066400000000000000000000002531464275211500220400ustar00rootroot00000000000000# SPDX-FileCopyrightText: 2024 Free Software Foundation Europe e.V. # # SPDX-License-Identifier: CC0-1.0 [protokolo.section] title = "Added" order = 1 reuse-tool-4.0.3/changelog.d/changed/000077500000000000000000000000001464275211500173655ustar00rootroot00000000000000reuse-tool-4.0.3/changelog.d/changed/.protokolo.toml000066400000000000000000000002551464275211500223720ustar00rootroot00000000000000# SPDX-FileCopyrightText: 2024 Free Software Foundation Europe e.V. # # SPDX-License-Identifier: CC0-1.0 [protokolo.section] title = "Changed" order = 2 reuse-tool-4.0.3/changelog.d/deprecated/000077500000000000000000000000001464275211500200745ustar00rootroot00000000000000reuse-tool-4.0.3/changelog.d/deprecated/.protokolo.toml000066400000000000000000000002601464275211500230750ustar00rootroot00000000000000# SPDX-FileCopyrightText: 2024 Free Software Foundation Europe e.V. # # SPDX-License-Identifier: CC0-1.0 [protokolo.section] title = "Deprecated" order = 3 reuse-tool-4.0.3/changelog.d/fixed/000077500000000000000000000000001464275211500170735ustar00rootroot00000000000000reuse-tool-4.0.3/changelog.d/fixed/.protokolo.toml000066400000000000000000000002531464275211500220760ustar00rootroot00000000000000# SPDX-FileCopyrightText: 2024 Free Software Foundation Europe e.V. # # SPDX-License-Identifier: CC0-1.0 [protokolo.section] title = "Fixed" order = 5 reuse-tool-4.0.3/changelog.d/removed/000077500000000000000000000000001464275211500174355ustar00rootroot00000000000000reuse-tool-4.0.3/changelog.d/removed/.protokolo.toml000066400000000000000000000002551464275211500224420ustar00rootroot00000000000000# SPDX-FileCopyrightText: 2024 Free Software Foundation Europe e.V. # # SPDX-License-Identifier: CC0-1.0 [protokolo.section] title = "Removed" order = 4 reuse-tool-4.0.3/changelog.d/security/000077500000000000000000000000001464275211500176435ustar00rootroot00000000000000reuse-tool-4.0.3/changelog.d/security/.protokolo.toml000066400000000000000000000002561464275211500226510ustar00rootroot00000000000000# SPDX-FileCopyrightText: 2024 Free Software Foundation Europe e.V. # # SPDX-License-Identifier: CC0-1.0 [protokolo.section] title = "Security" order = 6 reuse-tool-4.0.3/docs/000077500000000000000000000000001464275211500145535ustar00rootroot00000000000000reuse-tool-4.0.3/docs/Makefile000066400000000000000000000012641464275211500162160ustar00rootroot00000000000000# SPDX-FileCopyrightText: 2017 Free Software Foundation Europe e.V. # # SPDX-License-Identifier: GPL-3.0-or-later # You can set these variables from the command line. SPHINXOPTS ?= SPHINXBUILD ?= sphinx-build SOURCEDIR = . BUILDDIR = _build # Put it first so that "make" without argument is like "make help". help: @poetry run $(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) .PHONY: help Makefile # Catch-all target: route all unknown targets to Sphinx using the new # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). %: Makefile @poetry run $(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) reuse-tool-4.0.3/docs/_static/000077500000000000000000000000001464275211500162015ustar00rootroot00000000000000reuse-tool-4.0.3/docs/_static/.gitkeep000066400000000000000000000000001464275211500176200ustar00rootroot00000000000000reuse-tool-4.0.3/docs/authors.rst000066400000000000000000000002441464275211500167720ustar00rootroot00000000000000.. SPDX-FileCopyrightText: 2017 Free Software Foundation Europe e.V. SPDX-License-Identifier: CC-BY-SA-4.0 .. include:: ../AUTHORS.rst reuse-tool-4.0.3/docs/conf.py000066400000000000000000000106161464275211500160560ustar00rootroot00000000000000# SPDX-FileCopyrightText: 2017 Free Software Foundation Europe e.V. # # SPDX-License-Identifier: GPL-3.0-or-later # Configuration file for the Sphinx documentation builder. # # For the full list of built-in configuration values, see the documentation: # https://www.sphinx-doc.org/en/master/usage/configuration.html import os from importlib.metadata import PackageNotFoundError from importlib.metadata import version as get_version from pathlib import Path from shutil import copyfile DOCS_DIR = Path(os.path.dirname(__file__)) ROOT_DIR = (DOCS_DIR / "..").resolve() # -- Project information ----------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information project = "reuse" copyright = "2017, Free Software Foundation Europe. CC-BY-SA-4.0" author = "Free Software Foundation Europe" # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. try: # The full version, including alpha/beta/rc tags. release = get_version("reuse") except PackageNotFoundError: release = "3.0.2" # The short X.Y.Z version. version = ".".join(release.split(".")[:3]) # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. # # This is also used if you do content translation via gettext catalogs. # Usually you set "language" from the command line for these cases. language = "en" # -- General configuration --------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration extensions = [ "myst_parser", "sphinx.ext.autodoc", "sphinx.ext.intersphinx", "sphinx.ext.viewcode", "sphinx.ext.napoleon", "sphinxcontrib.apidoc", ] templates_path = ["_templates"] exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"] # -- Extensions configuration ------------------------------------------------ apidoc_module_dir = str(ROOT_DIR / "src/reuse") # apidoc_output_dir = "api" # apidoc_excluded_paths = [] apidoc_separate_modules = True apidoc_toc_file = False apidoc_extra_args = ["--maxdepth", "2"] autodoc_member_order = "bysource" intersphinx_mapping = {"python": ("https://docs.python.org/3", None)} # -- Options for HTML output ------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output html_theme = "furo" html_logo = "reuse-r-only.svg" html_static_path = ["_static"] # -- Options for man output -------------------------------------------------- man_pages = [ ( "man/reuse", "reuse", "A tool for compliance with the REUSE recommendations", "Free Software Foundation Europe", 1, ), ( "man/reuse-annotate", "reuse-annotate", "Add REUSE information to files", "Free Software Foundation Europe", 1, ), ( "man/reuse-convert-dep5", "reuse-convert-dep5", "Convert .reuse/dep5 to REUSE.toml", "Free Software Foundation Europe", 1, ), ( "man/reuse-download", "reuse-download", "Download license files", "Free Software Foundation Europe", 1, ), ( "man/reuse-lint", "reuse-lint", "Verify whether a project is compliant with the REUSE Specification", "Free Software Foundation Europe", 1, ), ( "man/reuse-spdx", "reuse-spdx", "Generate SPDX bill of materials", "Free Software Foundation Europe", 1, ), ( "man/reuse-supported-licenses", "reuse-supported-licenses", "Print a list of supported licenses", "Free Software Foundation Europe", 1, ), ] # -- Custom ------------------------------------------------------------------ def copy_markdown(_): """Copy the markdown files from the root of the project into the docs/ directory. """ copyfile(ROOT_DIR / "README.md", DOCS_DIR / "readme.md") copyfile(ROOT_DIR / "CHANGELOG.md", DOCS_DIR / "history.md") # this used to be renamed to 'contributing.md', but this caused a conflict # with the ToC in the README. copyfile(ROOT_DIR / "CONTRIBUTING.md", DOCS_DIR / "contribute.md") def setup(app): app.connect("builder-inited", copy_markdown) reuse-tool-4.0.3/docs/index.rst000066400000000000000000000020411464275211500164110ustar00rootroot00000000000000.. SPDX-FileCopyrightText: 2017 Free Software Foundation Europe e.V. SPDX-License-Identifier: CC-BY-SA-4.0 .. reuse documentation master file, created by sphinx-quickstart on Wed Nov 1 14:41:46 2017. You can adapt this file completely to your liking, but it should at least contain the root `toctree` directive. reuse documentation =================== This is the documentation for the REUSE tool. You may find more information about REUSE at ``_. .. toctree:: :maxdepth: 2 Overview scripts man/index API reference ------------- Although the API is not declared stable (and likely never will be declared stable), you may find the API generated from Python docstrings useful or insightful. .. toctree:: :maxdepth: 3 API Project ------- .. toctree:: :maxdepth: 2 contribute authors Change log ---------- .. toctree:: :maxdepth: 2 history Indices and tables ------------------ * :ref:`genindex` * :ref:`modindex` * :ref:`search` reuse-tool-4.0.3/docs/man/000077500000000000000000000000001464275211500153265ustar00rootroot00000000000000reuse-tool-4.0.3/docs/man/index.rst000066400000000000000000000007041464275211500171700ustar00rootroot00000000000000.. SPDX-FileCopyrightText: 2024 Free Software Foundation Europe e.V. SPDX-License-Identifier: CC-BY-SA-4.0 Command-line reference ====================== These are the manpages for ``reuse``. They contain helpful-but-succinct information about the functioning of the tool. .. toctree:: :maxdepth: 1 reuse reuse-annotate reuse-convert-dep5 reuse-download reuse-lint reuse-spdx reuse-supported-licenses reuse-tool-4.0.3/docs/man/reuse-annotate.rst000066400000000000000000000165611464275211500210230ustar00rootroot00000000000000.. SPDX-FileCopyrightText: 2019 Free Software Foundation Europe e.V. SPDX-FileCopyrightText: © 2020 Liferay, Inc. SPDX-License-Identifier: CC-BY-SA-4.0 .. REUSE-IgnoreStart reuse-annotate ============== Synopsis -------- **reuse annotate** [*options*] [*file* ...] Description ----------- :program:`reuse-annotate` adds REUSE information into the headers of files. This is useful especially in scenarios where you want to add a copyright holder or license to a lot of files without having to manually edit the header of each file. .. warning:: You should be cautious with using ``annotate`` in automated processes. While nothing is stopping you from using it in your release script, you should make sure that the information it adds is actually reflective of reality. This is best verified manually. The REUSE header is placed at the very top of the file, excepting certain existing headers like shebangs (``#!``) or XML declarations (````). If a different header containing copyright or licensing information already exists in the file---at the top or elsewhere---that header is replaced in-place with the additionally supplied REUSE information. The tool tries to auto-detect the comment style to use from the file extension of a file, and use that comment style. Normally, the tool uses a single-line comment style when one is available (e.g., ``//`` is used instead of ``/* ... */`` for C++ comment styles). If no single-line comment style is available, a multi-line style is used. Mandatory options ----------------- At least *one* among the following options is required. They contain the information which the tool will add to the file(s). .. option:: -c, --copyright COPYRIGHT A copyright holder. This does not contain the year or the copyright prefix. See :option:`--year` and :option:`--copyright-prefix` for the year and prefix. This option can be repeated. .. option:: -l, --license LICENSE An SPDX license identifier. This option can be repeated. .. option:: --contributor CONTRIBUTOR A name of a contributor. The contributor will be added via the ``SPDX-FileContributor:`` tag. This option can be repeated. Other options ------------- .. option:: -y, --year YEAR Define the year of the copyright statement(s). If not defined, the year defaults to the current year. .. option:: -s, --style STYLE Override the comment style detection mechanism to force a comment style on the files. This is useful when a file extension is not recognised, or when a file extension is associated with a comment style that you disagree with. .. option:: --copyright-prefix PREFIX The prefix to use in the copyright statement. If not defined, ``spdx`` is used as prefix. The available copyright prefixes are: .. code-block:: spdx: SPDX-FileCopyrightText: spdx-c: SPDX-FileCopyrightText: (C) spdx-symbol: SPDX-FileCopyrightText: © string: Copyright string-c: Copyright (C) string-symbol: Copyright © symbol: © .. option:: -t, --template TEMPLATE The template to use for the comment header. The template name match the name of the template in ``.reuse/templates/``, without the ``.jinja2`` or ``.commented.jinja2`` suffix. .. option:: --exclude-year Do not include the year in the copyright notice. .. option:: --merge-copyrights If two (or more) copyright notices are identical except for their years, output them as a single line with the years combined. .. option:: --single-line Force the tool to use a single-line comment style. For C, this would be ``//``. .. option:: --multi-line Force the tool to use a multi-line comment style. For C, this would be ``/* ... */``. .. option:: -r, --recursive Annotate all files recursively under the specified path. .. option:: --no-replace Instead of replacing the first header in the file which contains copyright and licensing information, keep it and create a new header at the top. .. option:: --force-dot-license Always write a .license file instead of trying to write into the file itself. .. option:: --fallback-dot-license Instead of aborting when a file extension does not have an associated comment style, create a .license file for those files. .. option:: --skip-unrecognised Instead of aborting when a file extension does not have an associated comment style, skip those files. .. option:: -h, --help Display help and exit. Templates --------- When the tool adds a header to a file, it normally first lists all copyright statements alphabetically, subsequently all contributors, then adds a single empty line, and finally lists all SPDX License Expressions alphabetically. It is possible to change this behaviour, and use a custom type of header that contains extra text. This is done through Jinja2 templates. The default template is: .. code-block:: jinja {% for copyright_line in copyright_lines %} {{ copyright_line }} {% endfor %} {% for contributor_line in contributor_lines %} SPDX-FileContributor: {{ contributor_line }} {% endfor %} {% for expression in spdx_expressions %} SPDX-License-Identifier: {{ expression }} {% endfor %} Templates are automatically commented by the tool, depending on the detected or specified comment style. You can create your own Jinja2 templates and place them in ``.reuse/templates/``. You must suffix your template with ``.jinja2``. Inside of the template, you have access to the following variables: - ``copyright_lines`` --- a list of copyright notices (string). - ``contributor_lines`` --- a list of contributors (string). - ``spdx_expressions`` --- a list of SPDX License Expressions (string). In the future, more variables may be added. In some cases, you might want to do custom comment formatting. In those cases, you can pre-format your header as a comment. When doing so, suffix your template with ``.commented.jinja2``. An example of a custom template with manual commenting is: .. code-block:: jinja /* {% for copyright_line in copyright_lines %} * {{ copyright_line }} {% endfor %} {% if copyright_lines and spdx_expressions %} * {% endif %} {% for expression in spdx_expressions %} * SPDX-License-Identifier: {{ expression }} {% endfor %} {% if "GPL-3.0-or-later" in spdx_expressions %} * * This program is free software: you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation, either version 3 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along with * this program. If not, see . {% endif %} */ Examples -------- The basic usage is ``reuse annotate --copyright="Jane Doe" --license=MIT my_file.py``. This will add the following header to the file (assuming that the current year is 2019): .. code-block:: python # SPDX-FileCopyrightText: 2019 Jane Doe # # SPDX-License-Identifier: MIT reuse-tool-4.0.3/docs/man/reuse-convert-dep5.rst000066400000000000000000000030121464275211500215100ustar00rootroot00000000000000.. SPDX-FileCopyrightText: 2024 Free Software Foundation Europe e.V. SPDX-License-Identifier: CC-BY-SA-4.0 reuse-convert-dep5 ================== Synopsis -------- **reuse convert-dep5** [*options*] Description ----------- :program:`reuse-convert-dep5` converts the ``.reuse/dep5`` file into a functionally equivalent ``REUSE.toml`` file in the root of the project. The ``.reuse/dep5`` file is subsequently deleted. Options ------- .. option:: -h, --help Display help and exit. Examples -------- Given the following ``.reuse/dep5`` file:: Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Upstream-Name: Some project Upstream-Contact: Jane Doe Source: https://example.com/ Disclaimer: Some rights reserved Files: hello*.txt Copyright: 2018 Jane Doe License: MIT Comment: hello world Files: foo bar Copyright: 2018 Jane Doe 2019 John Doe License: MIT The following ``REUSE.toml`` is generated: .. code-block:: toml version = 1 SPDX-PackageName = "Some project" SPDX-PackageSupplier = "Jane Doe" SPDX-PackageDownloadLocation = "https://example.com/" SPDX-PackageComment = "Some rights reserved" [[annotations]] path = "hello**.txt" precedence = "aggregate" SPDX-FileCopyrightText = "2018 Jane Doe" SPDX-License-Identifier = "MIT" SPDX-FileComment = "hello world" [[annotations]] path = ["foo", "bar"] precedence = "aggregate" SPDX-FileCopyrightText = ["2018 Jane Doe", "2019 John Doe"] SPDX-License-Identifier = "MIT" reuse-tool-4.0.3/docs/man/reuse-download.rst000066400000000000000000000021411464275211500210060ustar00rootroot00000000000000.. SPDX-FileCopyrightText: 2024 Free Software Foundation Europe e.V. SPDX-License-Identifier: CC-BY-SA-4.0 reuse-download ============== Synopsis -------- **reuse download** [*options*] [*license* ...] Description ----------- :program:`reuse-download` downloads licenses into your ``LICENSES/`` directory. The *license* arguments must be SPDX License Identifiers. The ``LICENSES/`` directory will be found in the root of your project. If you are already in a directory named ``LICENSES`` and you are not in a VCS repository, that directory will be used. If no ``LICENSES/`` directory exists, one will be created. Options ------- .. option:: --all Download all licenses detected missing in the project. .. option:: -o, --output FILE If downloading a single file, output it to a specific file instead of putting it in a detected ``LICENSES/`` directory. .. option:: --source SOURCE Specify a source from which to copy custom ``LicenseRef-`` files. This can be a directory containing such file, or a path to the file itself. .. option:: -h, --help Display help and exit. reuse-tool-4.0.3/docs/man/reuse-lint.rst000066400000000000000000000046141464275211500201540ustar00rootroot00000000000000.. SPDX-FileCopyrightText: 2019 Free Software Foundation Europe e.V. SPDX-FileCopyrightText: © 2020 Liferay, Inc. SPDX-License-Identifier: CC-BY-SA-4.0 reuse-lint ========== Synopsis -------- **reuse lint** [*options*] Description ----------- :program:`reuse-lint` verifies whether a project is compliant with the REUSE Specification located at ``_. Criteria -------- These are the criteria that the linter checks against. Bad licenses ~~~~~~~~~~~~ Licenses that are found in ``LICENSES/`` that are not found in the SPDX License List or do not start with ``LicenseRef-`` are bad licenses. Deprecated licenses ~~~~~~~~~~~~~~~~~~~ Licenses whose SPDX License Identifier has been deprecated by SPDX. Licenses without file extension ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ These are licenses whose file names are a valid SPDX License Identifier, but which do not have a file extension. Missing licenses ~~~~~~~~~~~~~~~~ A license which is referred to in a comment header, but which is not found in the ``LICENSES/`` directory. Unused licenses ~~~~~~~~~~~~~~~ A license found in the ``LICENSES/`` directory, but which is not referred to in any comment header. Read errors ~~~~~~~~~~~ Not technically a criterion, but files that cannot be read by the operating system are read errors, and need to be fixed. Files without copyright and license information ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Every file needs to have copyright and licensing information associated with it. The REUSE Specification details several ways of doing it. By and large, these are the methods: - Placing tags in the header of the file. - Placing tags in a ``.license`` file adjacent to the file. - Putting the information in the ``REUSE.toml`` file. - Putting the information in the ``.reuse/dep5`` file. (Deprecated) If a file is found that does not have copyright and/or license information associated with it, then the project is not compliant. Options ------- .. option:: -q, --quiet Do not print anything to STDOUT. .. TODO: specify the JSON output. .. option:: -j, --json Output the results of the lint as JSON. .. option:: -p, --plain Output the results of the lint as descriptive text. The text is valid Markdown. .. option:: -l, --lines Output one line per error, prefixed by the file path. .. option:: -h, --help Display help and exit. reuse-tool-4.0.3/docs/man/reuse-spdx.rst000066400000000000000000000016771464275211500201720ustar00rootroot00000000000000.. SPDX-FileCopyrightText: 2024 Free Software Foundation Europe e.V. SPDX-License-Identifier: CC-BY-SA-4.0 reuse-spdx ========== Synopsis -------- **reuse spdx** [*options*] Description ----------- :program:`reuse-spdx` generates an SPDX bill of materials for the project. The bill of materials is output to STDOUT. .. TODO: add more details here. Maybe wait until this is refactored. Options ------- .. option:: -o, --output FILE Write the bill of materials to a file instead of writing it to STDOUT. .. option:: --add-license-concluded Instead of writing 'NOASSERTION' to LicenseConcluded, write an expression that is the logical equivalent of AND-ing all found expressions. .. option:: --creator-person Name of the creator (person) of the bill of materials. .. option:: --creator-organization Name of the creator (organization) of the bill of materials. .. option:: -h, --help Display help and exit. reuse-tool-4.0.3/docs/man/reuse-supported-licenses.rst000066400000000000000000000013341464275211500230320ustar00rootroot00000000000000.. SPDX-FileCopyrightText: 2024 Free Software Foundation Europe e.V. SPDX-License-Identifier: CC-BY-SA-4.0 reuse-supported-licenses ======================== Synopsis -------- **reuse supported-licenses** [*options*] Description ----------- :program:`reuse-supported-licenses` generates a list of supported licenses. These are the licenses in the SPDX License List found at ``_. The list may not be up-to-date depending on how recent your installation of :program:`reuse` is. The list contains rows with three items each: the SPDX License Identifier, the full name of the license, and an URL to the license. Options ------- .. option:: -h, --help Display help and exit. reuse-tool-4.0.3/docs/man/reuse.rst000066400000000000000000000062111464275211500172030ustar00rootroot00000000000000.. SPDX-FileCopyrightText: 2019 Free Software Foundation Europe e.V. SPDX-FileCopyrightText: © 2020 Liferay, Inc. SPDX-License-Identifier: CC-BY-SA-4.0 reuse ===== Synopsis -------- **reuse** [*options*] Description ----------- :program:`reuse` is a helper tool for the REUSE initiative. Its main functionality in :manpage:`reuse-lint(1)` is to verify whether a project is compliant with the REUSE Specification. It also contains an array of convenience functions to enable developers to become compliant. For more information on how to use reuse beyond a reference of the command-line options, see the accompanying documentation or read it at ``_. For further information about REUSE, see ``_. Details ------- When searching for copyright and licensing tags inside of files, the tool does not strictly limit itself to the header comment as prescribed by the specification. It searches the first 4 kibibytes of the file for REUSE information, whether in comments or not. This makes sure that the tool can parse any type of plain-text file, even if the comment style is not recognised. If a file is found to have an unparsable tag, that file is not parsed at all. This is a bug (``_). The tool does not verify the correctness of copyright notices. If it finds any line containing '©', 'Copyright', or 'SPDX-FileCopyrightText:', then the tag and everything following it is considered a valid copyright notice, even if the copyright notice is not compliant with the specification. Symbolic links and files that are zero-sized are automatically ignored. Options ------- .. option:: --debug Enable debug logging. .. option:: --suppress-deprecation Hide deprecation warnings. .. option:: --include-submodules Do not ignore Git submodules; they are treated as though they are part of the project. This is not strictly compliant with the specification. .. option:: --include-meson-subprojects Do not ignore Meson subprojects (i.e. the ``subprojects`` directory in the root of the project); they are treated as though they are part of the project. This is not strictly compliant with the specification. .. option:: --no-multiprocessing Disable multiprocessing performance enhancer. This may be useful when debugging. .. option:: --root PATH Set the root of the project to PATH. Normally this defaults to the root of the current working directory's VCS repository, or to the current working directory. .. option:: -h, --help Display help and exit. If no command is provided, this option is implied. .. option:: --version Display the version and exit. Commands -------- :manpage:`reuse-annotate(1)` Add REUSE information to files. :manpage:`reuse-convert-dep5(1)` Convert ``.reuse/dep5`` to ``REUSE.toml``. :manpage:`reuse-download(1)` Download license files. :manpage:`reuse-lint(1)` Verify whether a project is compliant with the REUSE Specification. :manpage:`reuse-spdx(1)` Generate SPDX bill of materials. :manpage:`reuse-supported-licenses(1)` Print a list of supported licenses. reuse-tool-4.0.3/docs/reuse-r-only.svg000066400000000000000000000127501464275211500176420ustar00rootroot00000000000000 image/svg+xml reuse-tool-4.0.3/docs/reuse-r-only.svg.license000066400000000000000000000001511464275211500212530ustar00rootroot00000000000000SPDX-FileCopyrightText: 2023 Free Software Foundation Europe e.V. SPDX-License-Identifier: CC-BY-SA-4.0 reuse-tool-4.0.3/docs/scripts.rst000066400000000000000000000132201464275211500167720ustar00rootroot00000000000000.. SPDX-FileCopyrightText: 2022 Nico Rikken SPDX-License-Identifier: CC-BY-SA-4.0 ============== Helper scripts ============== This section contains scripts and snippets to help with the usage of REUSE. REUSE already has a lot of functionality builtin, but there are still cases where REUSE could use support from some external scripts. A typical example is adding SPDX headers based on the information in the version control system. This collection of scripts and snippets offers help for such situations. .. warning:: These scripts help you run REUSE against your codebase. Automatically extracted information might not resemble the truth. The correctness of these scripts is not guaranteed. Use with caution and at your own risk. ****************************** Starting point of the codebase ****************************** The first code contribution can be a worthwhile date to include in the copyright annotation. First commit ============ Git log can show summaries of all commits. At the moment of writing git does not allow selecting just one commit, so ``head`` is used to restrict the output. .. SPDX-SnippetBegin .. SPDX-Snippet-License-Identifier: CC0-1.0 .. code-block:: console $ git log --reverse --all | head -n 3 commit cdcea0887e0a85149f93e734b647301a16dd893e Author: Carmen Bianca Bakker Date: Tue Oct 10 18:27:11 2017 +0200 .. SPDX-SnippetEnd Year of first commit ==================== With a custom format just the year of the first commit can be displayed. This output is convenient for use in larger scripts. .. SPDX-SnippetBegin .. SPDX-Snippet-License-Identifier: CC0-1.0 .. code-block:: console $ git log --reverse --date="format:%Y" --format="format:%cd" | head -n 1 2017 .. SPDX-SnippetEnd ******* Authors ******* Unless the authors have signed away their copyright to a company or the project, the authors are also the copyright holders of their contributions. So in a lot of cases it is valuable to know the original authors in order to explicitly state these copyright holders. Commit authors ============== Some examples on how to get information about the authors from the codebase. Based on commit order --------------------- Print out the authors known to git in chronological order. Awk is used to filter out subsequent duplicate entries so each entry is shown only for the first appearance. .. SPDX-SnippetBegin .. SPDX-Snippet-License-Identifier: CC0-1.0 .. code-block:: console $ git log --reverse --all --format="%aN <%aE>" | awk '!seen[$0]++' Carmen Bianca Bakker carmenbianca Carmen Bianca Bakker ... .. SPDX-SnippetEnd The same command, but now without the email addresses. .. SPDX-SnippetBegin .. SPDX-Snippet-License-Identifier: CC0-1.0 .. code-block:: console $ git log --reverse --all --format="%aN" | awk '!seen[$0]++' Carmen Bianca Bakker carmenbianca Sebastian Schuberth ... .. SPDX-SnippetEnd Sorted by name -------------- All authors as known to the version control system, simply sorted by name. .. SPDX-SnippetBegin .. SPDX-Snippet-License-Identifier: CC0-1.0 .. code-block:: console $ git log --all --format="%aN <%aE>" | sort | uniq Adam Spiers Ajinkya Patil Alvar <8402811+oxzi@users.noreply.github.com> ... .. SPDX-SnippetEnd The same command, but now without the email addresses. .. SPDX-SnippetBegin .. SPDX-Snippet-License-Identifier: CC0-1.0 .. code-block:: console $ git log --all --format="%aN" | sort | uniq Adam Spiers Ajinkya Patil Alvar ... .. SPDX-SnippetEnd Authors in commit trailers like sign-off ======================================== A sign-off annotation in a commit also contains author details that can be as valuable. .. TODO: improve this oneliner based on built-in Git options as documented in https://stackoverflow.com/a/41361273/12013233 .. SPDX-SnippetBegin .. SPDX-Snippet-License-Identifier: CC0-1.0 .. code-block:: console $ git log --all | grep -i 'Signed-off-by\|Co-authored-by' | sort | uniq Co-authored-by: Ethel Morgan Co-authored-by: max.mehl Co-authored-by: Max Mehl Signed-off-by: Carmen Bianca Bakker ... .. SPDX-SnippetEnd *********** Add headers *********** A common use-case is to add headers to existing, modified or newly written code. Add headers to staged files based on git settings ================================================= This script helps you add your copyright headers right before committing the code you wrote. The list of files staged in git can be retrieved using ``git diff --name-only --cached``, which is the basis to apply the ``reuse annotate`` command to. Git user and email address are available through ``git config --get user.name`` and ``git config --get user.email``. REUSE already sets the current year, so there is no need to set that explicitly. These elements can be combined into a single command: .. SPDX-SnippetBegin .. SPDX-Snippet-License-Identifier: CC0-1.0 .. code-block:: console $ git diff --name-only --cached | xargs -I {} reuse annotate -c "$(git config --get user.name) <$(git config --get user.email)>" "{}" .. SPDX-SnippetEnd .. rubric:: Copyright This page is licensed under the `Creative Commons Attribution-ShareAlike 4.0 International license `_. Examples, recipes, and other code in the documentation are additionally licensed under the `Creative Commons Zero v1.0 Universal License `_. reuse-tool-4.0.3/docs/usage.rst.license000066400000000000000000000003001464275211500200230ustar00rootroot00000000000000SPDX-FileCopyrightText: 2019 Free Software Foundation Europe e.V. SPDX-FileCopyrightText: © 2020 Liferay, Inc. SPDX-License-Identifier: CC-BY-SA-4.0 reuse-tool-4.0.3/po/000077500000000000000000000000001464275211500142415ustar00rootroot00000000000000reuse-tool-4.0.3/po/cs.po000066400000000000000000001102211464275211500152030ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # SPDX-License-Identifier: GPL-3.0-or-later # msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-07-03 13:09+0000\n" "PO-Revision-Date: 2023-04-12 13:49+0000\n" "Last-Translator: Jiří Podhorecký \n" "Language-Team: Czech \n" "Language: cs\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" "X-Generator: Weblate 4.17-dev\n" #: src/reuse/_annotate.py:74 #, python-brace-format msgid "" "'{path}' does not support single-line comments, please do not use --single-" "line" msgstr "" "'{path}' nepodporuje jednořádkové komentáře, nepoužívejte prosím --single-" "line" #: src/reuse/_annotate.py:81 #, python-brace-format msgid "" "'{path}' does not support multi-line comments, please do not use --multi-line" msgstr "'{path}' nepodporuje víceřádkové komentáře, nepoužívejte --multi-line" #: src/reuse/_annotate.py:136 #, fuzzy, python-brace-format msgid "Skipped unrecognised file '{path}'" msgstr "Přeskočen nerozpoznaný soubor {path}" #: src/reuse/_annotate.py:142 #, python-brace-format msgid "'{path}' is not recognised; creating '{path}.license'" msgstr "" #: src/reuse/_annotate.py:158 #, fuzzy, python-brace-format msgid "Skipped file '{path}' already containing REUSE information" msgstr "Přeskočený soubor '{path}' již obsahuje informace SPDX" #: src/reuse/_annotate.py:192 #, python-brace-format msgid "Error: Could not create comment for '{path}'" msgstr "Chyba: Nepodařilo se vytvořit komentář pro '{path}'" #: src/reuse/_annotate.py:199 #, python-brace-format msgid "" "Error: Generated comment header for '{path}' is missing copyright lines or " "license expressions. The template is probably incorrect. Did not write new " "header." msgstr "" "Chyba: Chybí řádky s autorskými právy nebo licenční výrazy v generovaném " "záhlaví komentáře pro '{path}'. Šablona je pravděpodobně nesprávná. " "Nepodařilo se zapsat novou hlavičku." #. TODO: This may need to be rephrased more elegantly. #: src/reuse/_annotate.py:210 #, python-brace-format msgid "Successfully changed header of {path}" msgstr "Úspěšně změněna hlavička {path}" #: src/reuse/_annotate.py:221 msgid "--skip-unrecognised has no effect when used together with --style" msgstr "" "--skip-unrecognised nemá žádný účinek, pokud se použije společně s --style" #: src/reuse/_annotate.py:231 #, fuzzy msgid "option --contributor, --copyright or --license is required" msgstr "je vyžadována volba --copyright nebo --licence" #: src/reuse/_annotate.py:272 #, python-brace-format msgid "template {template} could not be found" msgstr "šablonu {template} se nepodařilo najít" #: src/reuse/_annotate.py:341 src/reuse/_util.py:573 msgid "can't write to '{}'" msgstr "nelze zapisovat do '{}'" #: src/reuse/_annotate.py:366 #, fuzzy msgid "" "The following files do not have a recognised file extension. Please use --" "style, --force-dot-license, --fallback-dot-license, or --skip-unrecognised:" msgstr "" "Následující soubory nemají rozpoznanou příponu. Použijte prosím --style, --" "force-dot-licence nebo --skip-unrecognised:" #: src/reuse/_annotate.py:382 msgid "copyright statement, repeatable" msgstr "prohlášení o autorských právech, opakovatelné" #: src/reuse/_annotate.py:389 msgid "SPDX Identifier, repeatable" msgstr "Identifikátor SPDX, opakovatelný" #: src/reuse/_annotate.py:395 #, fuzzy msgid "file contributor, repeatable" msgstr "Identifikátor SPDX, opakovatelný" #: src/reuse/_annotate.py:403 msgid "year of copyright statement, optional" msgstr "rok vydání prohlášení o autorských právech, nepovinné" #: src/reuse/_annotate.py:411 msgid "comment style to use, optional" msgstr "styl komentáře, který se má použít, nepovinné" #: src/reuse/_annotate.py:417 #, fuzzy msgid "copyright prefix to use, optional" msgstr "styl autorských práv, který se má použít, nepovinné" #: src/reuse/_annotate.py:430 msgid "name of template to use, optional" msgstr "název šablony, která se má použít, nepovinné" #: src/reuse/_annotate.py:435 msgid "do not include year in statement" msgstr "neuvádět rok v prohlášení" #: src/reuse/_annotate.py:440 msgid "merge copyright lines if copyright statements are identical" msgstr "" "sloučit řádky s autorskými právy, pokud jsou prohlášení o autorských právech " "totožná" #: src/reuse/_annotate.py:446 msgid "force single-line comment style, optional" msgstr "vynutit jednořádkový styl komentáře, nepovinné" #: src/reuse/_annotate.py:451 msgid "force multi-line comment style, optional" msgstr "vynutit víceřádkový styl komentáře, nepovinné" #: src/reuse/_annotate.py:458 msgid "add headers to all files under specified directories recursively" msgstr "zpětně přidat hlavičky ke všem souborům v zadaných adresářích" #: src/reuse/_annotate.py:465 msgid "do not replace the first header in the file; just add a new one" msgstr "nenahrazovat první hlavičku v souboru, ale přidat novou" #: src/reuse/_annotate.py:473 #, fuzzy msgid "always write a .license file instead of a header inside the file" msgstr "zapsat soubor .license místo hlavičky uvnitř souboru" #: src/reuse/_annotate.py:480 #, fuzzy msgid "write a .license file to files with unrecognised comment styles" msgstr "přeskočit soubory s nerozpoznanými styly komentářů" #: src/reuse/_annotate.py:486 msgid "skip files with unrecognised comment styles" msgstr "přeskočit soubory s nerozpoznanými styly komentářů" #: src/reuse/_annotate.py:497 #, fuzzy msgid "skip files that already contain REUSE information" msgstr "přeskočit soubory, které již obsahují informace SPDX" #: src/reuse/_annotate.py:532 #, python-brace-format msgid "'{path}' is a binary, therefore using '{new_path}' for the header" msgstr "'{path}' je binární soubor, proto použijte '{new_path}' pro hlavičku" #: src/reuse/_main.py:39 msgid "" "reuse is a tool for compliance with the REUSE recommendations. See for more information, and " "for the online documentation." msgstr "" "reuse je nástrojem pro dodržování doporučení REUSE. Další informace " "naleznete na adrese a online dokumentaci na adrese " "." #: src/reuse/_main.py:45 msgid "" "This version of reuse is compatible with version {} of the REUSE " "Specification." msgstr "Tato verze reuse je kompatibilní s verzí {} specifikace REUSE." #: src/reuse/_main.py:48 msgid "Support the FSFE's work:" msgstr "Podpořte činnost FSFE:" #: src/reuse/_main.py:52 msgid "" "Donations are critical to our strength and autonomy. They enable us to " "continue working for Free Software wherever necessary. Please consider " "making a donation at ." msgstr "" "Dary jsou pro naši sílu a nezávislost zásadní. Umožňují nám pokračovat v " "práci pro svobodný software všude tam, kde je to nutné. Zvažte prosím " "možnost přispět na ." #: src/reuse/_main.py:75 msgid "enable debug statements" msgstr "povolit příkazy pro ladění" #: src/reuse/_main.py:80 msgid "hide deprecation warnings" msgstr "" #: src/reuse/_main.py:85 msgid "do not skip over Git submodules" msgstr "nepřeskakovat submoduly systému Git" #: src/reuse/_main.py:90 msgid "do not skip over Meson subprojects" msgstr "nepřeskakovat podprojekty Meson" #: src/reuse/_main.py:95 msgid "do not use multiprocessing" msgstr "nepoužívat multiprocessing" #: src/reuse/_main.py:102 msgid "define root of project" msgstr "definovat kořen projektu" #: src/reuse/_main.py:107 msgid "show program's version number and exit" msgstr "zobrazit číslo verze programu a ukončit jej" #: src/reuse/_main.py:111 msgid "subcommands" msgstr "dílčí příkazy" #: src/reuse/_main.py:118 msgid "add copyright and licensing into the header of files" msgstr "přidání autorských práv a licencí do záhlaví souborů" #: src/reuse/_main.py:121 msgid "" "Add copyright and licensing into the header of one or more files.\n" "\n" "By using --copyright and --license, you can specify which copyright holders " "and licenses to add to the headers of the given files.\n" "\n" "By using --contributor, you can specify people or entity that contributed " "but are not copyright holder of the given files." msgstr "" #: src/reuse/_main.py:140 msgid "download a license and place it in the LICENSES/ directory" msgstr "stáhněte si licenci a umístěte ji do adresáře LICENSES/" #: src/reuse/_main.py:142 #, fuzzy msgid "Download a license and place it in the LICENSES/ directory." msgstr "stáhněte si licenci a umístěte ji do adresáře LICENSES/" #: src/reuse/_main.py:151 msgid "list all non-compliant files" msgstr "seznam všech nevyhovujících souborů" #: src/reuse/_main.py:154 #, python-brace-format msgid "" "Lint the project directory for compliance with version {reuse_version} of " "the REUSE Specification. You can find the latest version of the " "specification at .\n" "\n" "Specifically, the following criteria are checked:\n" "\n" "- Are there any bad (unrecognised, not compliant with SPDX) licenses in the " "project?\n" "\n" "- Are any licenses referred to inside of the project, but not included in " "the LICENSES/ directory?\n" "\n" "- Are any licenses included in the LICENSES/ directory that are not used " "inside of the project?\n" "\n" "- Do all files have valid copyright and licensing information?" msgstr "" "Zkontrolujte soulad adresáře projektu s verzí {reuse_version} specifikace " "REUSE. Nejnovější verzi specifikace najdete na adrese .\n" "\n" "Konkrétně se kontrolují následující kritéria:\n" "\n" "- Jsou v projektu nějaké špatné (nerozpoznané, nevyhovující SPDX) licence?\n" "\n" "- Jsou uvnitř projektu nějaké licence, na které se odkazuje, ale nejsou " "obsaženy v adresáři LICENSES/?\n" "\n" "- Jsou v adresáři LICENSES/ obsaženy licence, které se uvnitř projektu " "nepoužívají?\n" "\n" "- Mají všechny soubory platné informace o autorských právech a licencích?" #: src/reuse/_main.py:181 msgid "print the project's bill of materials in SPDX format" msgstr "vytisknout výkaz materiálu projektu ve formátu SPDX" #: src/reuse/_main.py:189 msgid "list all supported SPDX licenses" msgstr "seznam všech podporovaných licencí SPDX" #: src/reuse/_main.py:198 msgid "convert .reuse/dep5 to REUSE.toml" msgstr "" #: src/reuse/_main.py:263 #, fuzzy, python-brace-format msgid "'{path}' could not be decoded as UTF-8." msgstr ".reuse/dep5 nelze analyzovat jako utf-8" #: src/reuse/_main.py:269 #, python-brace-format msgid "" "'{path}' could not be parsed. We received the following error message: " "{message}" msgstr "" #: src/reuse/_util.py:368 src/reuse/global_licensing.py:218 #, python-brace-format msgid "Could not parse '{expression}'" msgstr "Nepodařilo se analyzovat '{expression}'" #: src/reuse/_util.py:424 #, python-brace-format msgid "" "'{path}' holds an SPDX expression that cannot be parsed, skipping the file" msgstr "" "'{path}' obsahuje výraz SPDX, který nelze analyzovat a soubor se přeskočí" #: src/reuse/_util.py:556 msgid "'{}' is not a file" msgstr "'{}' není soubor" #: src/reuse/_util.py:559 msgid "'{}' is not a directory" msgstr "'{}' není adresář" #: src/reuse/_util.py:562 msgid "can't open '{}'" msgstr "nelze otevřít '{}'" #: src/reuse/_util.py:567 msgid "can't write to directory '{}'" msgstr "nelze zapisovat do adresáře '{}'" #: src/reuse/_util.py:586 msgid "can't read or write '{}'" msgstr "nelze číst ani zapisovat '{}'" #: src/reuse/_util.py:596 msgid "'{}' is not a valid SPDX expression, aborting" msgstr "'{}' není platný výraz SPDX, přeruší se" #: src/reuse/_util.py:624 msgid "'{}' is not a valid SPDX License Identifier." msgstr "'{}' není platný identifikátor licence SPDX." #: src/reuse/_util.py:631 msgid "Did you mean:" msgstr "Měl jste na mysli:" #: src/reuse/_util.py:638 msgid "" "See for a list of valid SPDX License " "Identifiers." msgstr "" "Seznam platných identifikátorů licence SPDX naleznete na adrese ." #: src/reuse/convert_dep5.py:118 #, fuzzy msgid "no '.reuse/dep5' file" msgstr "Vytvoření .reuse/dep5" #: src/reuse/download.py:130 msgid "SPDX License Identifier of license" msgstr "Licence SPDX Identifikátor licence" #: src/reuse/download.py:135 msgid "download all missing licenses detected in the project" msgstr "stáhnout všechny chybějící licence zjištěné v projektu" #: src/reuse/download.py:145 msgid "" "source from which to copy custom LicenseRef- licenses, either a directory " "that contains the file or the file itself" msgstr "" #: src/reuse/download.py:156 #, python-brace-format msgid "Error: {spdx_identifier} already exists." msgstr "Chyba: {spdx_identifier} již existuje." #: src/reuse/download.py:163 #, python-brace-format msgid "Error: {path} does not exist." msgstr "" #: src/reuse/download.py:166 msgid "Error: Failed to download license." msgstr "Chyba: Nepodařilo se stáhnout licenci." #: src/reuse/download.py:171 msgid "Is your internet connection working?" msgstr "Funguje vaše internetové připojení?" #: src/reuse/download.py:176 #, python-brace-format msgid "Successfully downloaded {spdx_identifier}." msgstr "Úspěšně stažen {spdx_identifier}." #: src/reuse/download.py:188 msgid "--output has no effect when used together with --all" msgstr "--output nemá žádný účinek, pokud se použije společně s --all" #: src/reuse/download.py:192 msgid "the following arguments are required: license" msgstr "jsou vyžadovány tyto argumenty: licence" #: src/reuse/download.py:194 msgid "cannot use --output with more than one license" msgstr "nelze použít --output s více než jednou licencí" #: src/reuse/global_licensing.py:109 #, python-brace-format msgid "" "{attr_name} must be a {type_name} (got {value} that is a {value_class})." msgstr "" #: src/reuse/global_licensing.py:122 #, python-brace-format msgid "" "Item in {attr_name} collection must be a {type_name} (got {item_value} that " "is a {item_class})." msgstr "" #: src/reuse/global_licensing.py:133 #, python-brace-format msgid "{attr_name} must not be empty." msgstr "" #: src/reuse/global_licensing.py:156 #, python-brace-format msgid "{name} must be a {type} (got {value} that is a {value_type})." msgstr "" #: src/reuse/global_licensing.py:179 #, python-brace-format msgid "" "The value of 'precedence' must be one of {precedence_vals} (got {received})" msgstr "" #: src/reuse/header.py:99 msgid "generated comment is missing copyright lines or license expressions" msgstr "" "ve vygenerovaném komentáři chybí řádky s autorskými právy nebo licenční " "výrazy" #: src/reuse/lint.py:30 msgid "prevents output" msgstr "" #: src/reuse/lint.py:33 msgid "formats output as JSON" msgstr "" #: src/reuse/lint.py:39 msgid "formats output as plain text" msgstr "" #: src/reuse/lint.py:45 msgid "formats output as errors per line" msgstr "" #: src/reuse/lint.py:64 msgid "BAD LICENSES" msgstr "NEVHODNÉ LICENCE" #: src/reuse/lint.py:66 src/reuse/lint.py:95 msgid "'{}' found in:" msgstr "'{}' nalezeno v:" #: src/reuse/lint.py:73 msgid "DEPRECATED LICENSES" msgstr "ZASTARALÉ LICENCE" #: src/reuse/lint.py:75 msgid "The following licenses are deprecated by SPDX:" msgstr "Následující licence jsou v SPDX zrušeny:" #: src/reuse/lint.py:83 msgid "LICENSES WITHOUT FILE EXTENSION" msgstr "LICENCE BEZ KONCOVKY SOUBORU" #: src/reuse/lint.py:85 msgid "The following licenses have no file extension:" msgstr "Následující licence nemají příponu souboru:" #: src/reuse/lint.py:93 msgid "MISSING LICENSES" msgstr "CHYBĚJÍCÍ LICENCE" #: src/reuse/lint.py:102 msgid "UNUSED LICENSES" msgstr "NEPOUŽITÉ LICENCE" #: src/reuse/lint.py:103 msgid "The following licenses are not used:" msgstr "Následující licence nejsou používány:" #: src/reuse/lint.py:110 msgid "READ ERRORS" msgstr "CHYBY ČTENÍ" #: src/reuse/lint.py:111 msgid "Could not read:" msgstr "Nelze načíst:" #: src/reuse/lint.py:132 msgid "MISSING COPYRIGHT AND LICENSING INFORMATION" msgstr "CHYBĚJÍCÍ INFORMACE O AUTORSKÝCH PRÁVECH A LICENCÍCH" #: src/reuse/lint.py:138 msgid "The following files have no copyright and licensing information:" msgstr "" "Následující soubory neobsahují žádné informace o autorských právech a " "licencích:" #: src/reuse/lint.py:149 msgid "The following files have no copyright information:" msgstr "Následující soubory nemají žádné informace o autorských právech:" #: src/reuse/lint.py:158 msgid "The following files have no licensing information:" msgstr "Následující soubory neobsahují žádné licenční informace:" #: src/reuse/lint.py:166 msgid "SUMMARY" msgstr "SHRNUTÍ" #: src/reuse/lint.py:171 msgid "Bad licenses:" msgstr "Neplatné licence:" #: src/reuse/lint.py:172 msgid "Deprecated licenses:" msgstr "Zastaralé licence:" #: src/reuse/lint.py:173 msgid "Licenses without file extension:" msgstr "Licence bez přípony souboru:" #: src/reuse/lint.py:176 msgid "Missing licenses:" msgstr "Chybějící licence:" #: src/reuse/lint.py:177 msgid "Unused licenses:" msgstr "Nepoužité licence:" #: src/reuse/lint.py:178 msgid "Used licenses:" msgstr "Použité licence:" #: src/reuse/lint.py:179 #, fuzzy msgid "Read errors:" msgstr "Chyby čtení: {count}" #: src/reuse/lint.py:181 #, fuzzy msgid "Files with copyright information:" msgstr "Soubory s informacemi o autorských právech: {count} / {total}" #: src/reuse/lint.py:185 #, fuzzy msgid "Files with license information:" msgstr "Soubory s licenčními informacemi: {count} / {total}" #: src/reuse/lint.py:202 msgid "" "Congratulations! Your project is compliant with version {} of the REUSE " "Specification :-)" msgstr "Gratulujeme! Váš projekt je v souladu s verzí {} specifikace REUSE :-)" #: src/reuse/lint.py:209 msgid "" "Unfortunately, your project is not compliant with version {} of the REUSE " "Specification :-(" msgstr "Váš projekt bohužel není v souladu s verzí {} specifikace REUSE :-(" #: src/reuse/lint.py:216 msgid "RECOMMENDATIONS" msgstr "" #: src/reuse/lint.py:289 #, python-brace-format msgid "{path}: bad license {lic}\n" msgstr "" #: src/reuse/lint.py:296 #, fuzzy, python-brace-format msgid "{lic_path}: deprecated license\n" msgstr "Zastaralé licence:" #: src/reuse/lint.py:303 #, fuzzy, python-brace-format msgid "{lic_path}: license without file extension\n" msgstr "Licence bez přípony souboru:" #: src/reuse/lint.py:312 #, fuzzy, python-brace-format msgid "{lic_path}: unused license\n" msgstr "Nepoužité licence:" #: src/reuse/lint.py:319 #, python-brace-format msgid "{path}: missing license {lic}\n" msgstr "" #: src/reuse/lint.py:326 #, python-brace-format msgid "{path}: read error\n" msgstr "" #: src/reuse/lint.py:330 #, fuzzy, python-brace-format msgid "{path}: no license identifier\n" msgstr "'{}' není platný identifikátor licence SPDX." #: src/reuse/lint.py:334 #, python-brace-format msgid "{path}: no copyright notice\n" msgstr "" #: src/reuse/project.py:262 #, fuzzy, python-brace-format msgid "'{path}' covered by {global_path}" msgstr "'{path}' zahrnuto v .reuse/dep5" #: src/reuse/project.py:270 #, python-brace-format msgid "" "'{path}' is covered exclusively by REUSE.toml. Not reading the file contents." msgstr "" #: src/reuse/project.py:277 #, python-brace-format msgid "" "'{path}' was detected as a binary file; not searching its contents for REUSE " "information." msgstr "" #: src/reuse/project.py:334 msgid "" "'.reuse/dep5' is deprecated. You are recommended to instead use REUSE.toml. " "Use `reuse convert-dep5` to convert." msgstr "" #: src/reuse/project.py:348 #, python-brace-format msgid "" "Found both '{new_path}' and '{old_path}'. You cannot keep both files " "simultaneously; they are not intercompatible." msgstr "" #: src/reuse/project.py:414 #, python-brace-format msgid "determining identifier of '{path}'" msgstr "určující identifikátor '{path}'" #: src/reuse/project.py:422 #, python-brace-format msgid "{path} does not have a file extension" msgstr "{path} nemá příponu souboru" #: src/reuse/project.py:432 #, python-brace-format msgid "" "Could not resolve SPDX License Identifier of {path}, resolving to " "{identifier}. Make sure the license is in the license list found at or that it starts with 'LicenseRef-', and that it has a " "file extension." msgstr "" "Nepodařilo se přeložit identifikátor licence SPDX {path}, přeloženo na " "{identifier}. Zkontrolujte, zda je licence v seznamu licencí nalezeném na " "adrese nebo zda začíná znakem 'LicenseRef-' a " "zda má příponu souboru." #: src/reuse/project.py:444 #, python-brace-format msgid "" "{identifier} is the SPDX License Identifier of both {path} and {other_path}" msgstr "" "{identifier} je identifikátor licence SPDX jak {path}, tak {other_path}" #: src/reuse/project.py:483 msgid "" "project '{}' is not a VCS repository or required VCS software is not " "installed" msgstr "" #: src/reuse/report.py:310 #, python-brace-format msgid "Could not read '{path}'" msgstr "Nepodařilo se načíst '{path}'" #: src/reuse/report.py:317 #, python-brace-format msgid "Unexpected error occurred while parsing '{path}'" msgstr "Při analýze souboru '{path}' došlo k neočekávané chybě" #: src/reuse/report.py:438 msgid "" "Fix bad licenses: At least one license in the LICENSES directory and/or " "provided by 'SPDX-License-Identifier' tags is invalid. They are either not " "valid SPDX License Identifiers or do not start with 'LicenseRef-'. FAQ about " "custom licenses: https://reuse.software/faq/#custom-license" msgstr "" #: src/reuse/report.py:449 msgid "" "Fix deprecated licenses: At least one of the licenses in the LICENSES " "directory and/or provided by an 'SPDX-License-Identifier' tag or in '.reuse/" "dep5' has been deprecated by SPDX. The current list and their respective " "recommended new identifiers can be found here: " msgstr "" #: src/reuse/report.py:460 msgid "" "Fix licenses without file extension: At least one license text file in the " "'LICENSES' directory does not have a '.txt' file extension. Please rename " "the file(s) accordingly." msgstr "" #: src/reuse/report.py:469 msgid "" "Fix missing licenses: For at least one of the license identifiers provided " "by the 'SPDX-License-Identifier' tags, there is no corresponding license " "text file in the 'LICENSES' directory. For SPDX license identifiers, you can " "simply run 'reuse download --all' to get any missing ones. For custom " "licenses (starting with 'LicenseRef-'), you need to add these files yourself." msgstr "" #: src/reuse/report.py:481 msgid "" "Fix unused licenses: At least one of the license text files in 'LICENSES' is " "not referenced by any file, e.g. by an 'SPDX-License-Identifier' tag. Please " "make sure that you either tag the accordingly licensed files properly, or " "delete the unused license text if you are sure that no file or code snippet " "is licensed as such." msgstr "" #: src/reuse/report.py:492 msgid "" "Fix read errors: At least one of the files in your directory cannot be read " "by the tool. Please check the file permissions. You will find the affected " "files at the top of the output as part of the logged error messages." msgstr "" #: src/reuse/report.py:501 msgid "" "Fix missing copyright/licensing information: For one or more files, the tool " "cannot find copyright and/or licensing information. You typically do this by " "adding 'SPDX-FileCopyrightText' and 'SPDX-License-Identifier' tags to each " "file. The tutorial explains additional ways to do this: " msgstr "" #: src/reuse/spdx.py:32 msgid "" "populate the LicenseConcluded field; note that reuse cannot guarantee the " "field is accurate" msgstr "" #: src/reuse/spdx.py:39 msgid "name of the person signing off on the SPDX report" msgstr "" #: src/reuse/spdx.py:44 msgid "name of the organization signing off on the SPDX report" msgstr "" #: src/reuse/spdx.py:60 msgid "" "error: --creator-person=NAME or --creator-organization=NAME required when --" "add-license-concluded is provided" msgstr "" #: src/reuse/spdx.py:75 #, python-brace-format msgid "" "'{path}' does not match a common SPDX file pattern. Find the suggested " "naming conventions here: https://spdx.github.io/spdx-spec/conformance/#44-" "standard-data-format-requirements" msgstr "" "'{path}' neodpovídá běžnému vzoru souboru SPDX. Navrhované konvence pro " "pojmenování najdete zde: https://spdx.github.io/spdx-spec/conformance/#44-" "standard-data-format-requirements" #: /usr/lib/python3.10/argparse.py:308 msgid "usage: " msgstr "použití: " #: /usr/lib/python3.10/argparse.py:880 msgid ".__call__() not defined" msgstr ".__call__() není definováno" #: /usr/lib/python3.10/argparse.py:1223 #, python-format msgid "unknown parser %(parser_name)r (choices: %(choices)s)" msgstr "neznámý parser %(parser_name)r (volby: %(choices)s)" #: /usr/lib/python3.10/argparse.py:1283 #, python-format msgid "argument \"-\" with mode %r" msgstr "argument \"-\" s režimem %r" #: /usr/lib/python3.10/argparse.py:1292 #, python-format msgid "can't open '%(filename)s': %(error)s" msgstr "nelze otevřít '%(filename)s': %(error)s" #: /usr/lib/python3.10/argparse.py:1501 #, python-format msgid "cannot merge actions - two groups are named %r" msgstr "nelze sloučit akce - dvě skupiny se jmenují %r" #: /usr/lib/python3.10/argparse.py:1539 msgid "'required' is an invalid argument for positionals" msgstr "'required' je neplatný argument pro pozicionály" #: /usr/lib/python3.10/argparse.py:1561 #, python-format msgid "" "invalid option string %(option)r: must start with a character " "%(prefix_chars)r" msgstr "neplatný řetězec %(option)r: musí začínat znakem %(prefix_chars)r" #: /usr/lib/python3.10/argparse.py:1579 #, python-format msgid "dest= is required for options like %r" msgstr "dest= je vyžadováno pro možnosti jako %r" #: /usr/lib/python3.10/argparse.py:1596 #, python-format msgid "invalid conflict_resolution value: %r" msgstr "neplatná hodnota conflict_resolution: %r" #: /usr/lib/python3.10/argparse.py:1614 #, python-format msgid "conflicting option string: %s" msgid_plural "conflicting option strings: %s" msgstr[0] "konfliktní volitelný řetězec: %s" msgstr[1] "konfliktní volitelné řetězce: %s" msgstr[2] "konfliktních volitelných řetězců: %s" #: /usr/lib/python3.10/argparse.py:1680 msgid "mutually exclusive arguments must be optional" msgstr "vzájemně se vylučující argumenty musí být nepovinné" #: /usr/lib/python3.10/argparse.py:1748 msgid "positional arguments" msgstr "poziční argumenty" #: /usr/lib/python3.10/argparse.py:1749 msgid "options" msgstr "" #: /usr/lib/python3.10/argparse.py:1764 msgid "show this help message and exit" msgstr "zobrazit tuto nápovědu a ukončit" #: /usr/lib/python3.10/argparse.py:1795 msgid "cannot have multiple subparser arguments" msgstr "nemůže mít více argumentů dílčího parseru" #: /usr/lib/python3.10/argparse.py:1847 /usr/lib/python3.10/argparse.py:2362 #, python-format msgid "unrecognized arguments: %s" msgstr "neuznané argumenty: %s" #: /usr/lib/python3.10/argparse.py:1948 #, python-format msgid "not allowed with argument %s" msgstr "není povoleno s argumentem %s" #: /usr/lib/python3.10/argparse.py:1998 /usr/lib/python3.10/argparse.py:2012 #, python-format msgid "ignored explicit argument %r" msgstr "ignoroval explicitní argument %r" #: /usr/lib/python3.10/argparse.py:2119 #, python-format msgid "the following arguments are required: %s" msgstr "jsou vyžadovány následující argumenty: %s" #: /usr/lib/python3.10/argparse.py:2134 #, python-format msgid "one of the arguments %s is required" msgstr "jeden z argumentů %s je povinný" #: /usr/lib/python3.10/argparse.py:2177 msgid "expected one argument" msgstr "očekávaný jeden argument" #: /usr/lib/python3.10/argparse.py:2178 msgid "expected at most one argument" msgstr "očekává se nejvýše jeden argument" #: /usr/lib/python3.10/argparse.py:2179 msgid "expected at least one argument" msgstr "očekává se alespoň jeden argument" #: /usr/lib/python3.10/argparse.py:2183 #, python-format msgid "expected %s argument" msgid_plural "expected %s arguments" msgstr[0] "očekáván %s argument" msgstr[1] "očekávány %s argumenty" msgstr[2] "očekáváno %s argumentů" #: /usr/lib/python3.10/argparse.py:2241 #, python-format msgid "ambiguous option: %(option)s could match %(matches)s" msgstr "nejednoznačná možnost: %(option)s by mohlo odpovídat %(matches)s" #: /usr/lib/python3.10/argparse.py:2305 #, python-format msgid "unexpected option string: %s" msgstr "neočekávaný volitelný řetězec: %s" #: /usr/lib/python3.10/argparse.py:2502 #, python-format msgid "%r is not callable" msgstr "%r nelze volat" #: /usr/lib/python3.10/argparse.py:2519 #, python-format msgid "invalid %(type)s value: %(value)r" msgstr "neplatná hodnota %(type)s: %(value)r" #: /usr/lib/python3.10/argparse.py:2530 #, python-format msgid "invalid choice: %(value)r (choose from %(choices)s)" msgstr "neplatná volba: %(value)r (vyberte z %(choices)s)" #: /usr/lib/python3.10/argparse.py:2606 #, python-format msgid "%(prog)s: error: %(message)s\n" msgstr "%(prog)s: chyba: %(message)s\n" #~ msgid "initialize REUSE project" #~ msgstr "inicializace projektu REUSE" #, fuzzy #~ msgid "" #~ "What license is your project under? Provide the SPDX License Identifier. " #~ "See for the list." #~ msgstr "" #~ "Pod jakou licencí je váš projekt? Uveďte identifikátor licence SPDX." #~ msgid "" #~ "What other license is your project under? Provide the SPDX License " #~ "Identifier." #~ msgstr "" #~ "Pod jakou jinou licencí je váš projekt? Uveďte identifikátor licence SPDX." #~ msgid "To stop adding licenses, hit RETURN." #~ msgstr "Chcete-li přidávání licencí ukončit, stiskněte klávesu RETURN." #~ msgid "Project already initialized" #~ msgstr "Projekt je již inicializován" #~ msgid "Initializing project for REUSE." #~ msgstr "Inicializace projektu REUSE." #~ msgid "What is the name of the project?" #~ msgstr "Jaký je název projektu?" #~ msgid "What is the internet address of the project?" #~ msgstr "Jaká je internetová adresa projektu?" #~ msgid "What is the name of the maintainer?" #~ msgstr "Jak se jmenuje správce?" #~ msgid "What is the e-mail address of the maintainer?" #~ msgstr "Jaká je e-mailová adresa správce?" #~ msgid "All done! Initializing now." #~ msgstr "Hotovo! Inicializuje se." #~ msgid "{} already exists" #~ msgstr "{} již existuje" #~ msgid "Could not download {}" #~ msgstr "Nelze stáhnout {}" #~ msgid "Initialization complete." #~ msgstr "Inicializace dokončena." #, fuzzy #~ msgid "" #~ "Add copyright and licensing into the header of one or more files.\n" #~ "\n" #~ "By using --copyright and --license, you can specify which copyright " #~ "holders and licenses to add to the headers of the given files.\n" #~ "\n" #~ "By using --contributor, you can specify people or entity that contributed " #~ "but are not copyright holder of the given files.\n" #~ "The first comment is replaced with a new header containing the new " #~ "copyright and licensing information and its former copyright and " #~ "licensing. If you want to keep the first comment intact, use --no-" #~ "replace.\n" #~ "\n" #~ "The comment style should be auto-detected for your files. If a comment " #~ "style could not be detected and --skip-unrecognised is not specified, the " #~ "process aborts. Use --style to specify or override the comment style to " #~ "use.\n" #~ "\n" #~ "A single-line comment style is used when it is available. If no single-" #~ "line comment style is available, a multi-line comment style is used. You " #~ "can force a certain comment style using --single-line or --multi-line.\n" #~ "\n" #~ "You can change the template of the header comment by using --template. " #~ "Place a Jinja2 template in .reuse/templates/mytemplate.jinja2. You can " #~ "use the template by specifying '--template mytemplate'. Read the online " #~ "documentation on how to use this feature.\n" #~ "\n" #~ "If a binary file is detected, or if --force-dot-license is specified, the " #~ "header is placed in a .license file." #~ msgstr "" #~ "Přidání autorských práv a licencí do záhlaví jednoho nebo více souborů.\n" #~ "\n" #~ "Pomocí parametrů --copyright a --license můžete určit, kteří držitelé " #~ "autorských práv a licencí mají být přidáni do záhlaví daných souborů.\n" #~ "\n" #~ "První komentář je nahrazen novou hlavičkou obsahující nové informace o " #~ "autorských právech a licencích a její původní autorská práva a licence. " #~ "Pokud chcete zachovat první komentář nedotčený, použijte parametr --no-" #~ "replace.\n" #~ "\n" #~ "Styl komentáře by měl být pro vaše soubory automaticky detekován. Pokud " #~ "se styl komentáře nepodařilo zjistit a není zadána možnost --skip-" #~ "unrecognised, proces se přeruší. Pomocí --style určete nebo přepište styl " #~ "komentáře, který se má použít.\n" #~ "\n" #~ "Pokud je k dispozici jednořádkový styl komentáře, použije se tento styl. " #~ "Pokud není k dispozici jednořádkový styl komentáře, použije se " #~ "víceřádkový styl komentáře. Určitý styl komentáře můžete vynutit pomocí " #~ "parametrů --single-line nebo --multi-line.\n" #~ "\n" #~ "Šablonu komentáře záhlaví můžete změnit pomocí příkazu --template. " #~ "Umístěte šablonu Jinja2 do souboru .reuse/templates/mytemplate.jinja2. " #~ "Šablonu můžete použít zadáním '--template mytemplate'. Přečtěte si online " #~ "dokumentaci, jak tuto funkci používat.\n" #~ "\n" #~ "Pokud je detekován binární soubor nebo pokud je zadán parametr --explicit-" #~ "license, je hlavička umístěna do souboru .license." #~ msgid "" #~ "Download a license and place it in the LICENSES/ directory.\n" #~ "\n" #~ "The LICENSES/ directory is automatically found in the following order:\n" #~ "\n" #~ "- The LICENSES/ directory in the root of the VCS repository.\n" #~ "\n" #~ "- The current directory if its name is LICENSES.\n" #~ "\n" #~ "- The LICENSES/ directory in the current directory.\n" #~ "\n" #~ "If the LICENSES/ directory cannot be found, one is simply created." #~ msgstr "" #~ "Stáhněte si licenci a umístěte ji do adresáře LICENSES/.\n" #~ "\n" #~ "Adresář LICENSES/ se automaticky vyhledává v následujícím pořadí:\n" #~ "\n" #~ "- Adresář LICENSES/ v kořenovém adresáři úložiště VCS.\n" #~ "\n" #~ "- Aktuální adresář, pokud je jeho název LICENSES.\n" #~ "\n" #~ "- Adresář LICENSES/ v aktuálním adresáři.\n" #~ "\n" #~ "Pokud adresář LICENSES/ nelze nalézt, je jednoduše vytvořen." #~ msgid ".reuse/dep5 has syntax errors" #~ msgstr ".reuse/dep5 obsahuje chyby syntaxe" #~ msgid "optional arguments" #~ msgstr "nepovinné argumenty" #, fuzzy #~ msgid "deprecated in favor of annotate" #~ msgstr "'reuse addheader' bylo zrušeno ve prospěch 'reuse annotate'" #~ msgid "'reuse addheader' has been deprecated in favour of 'reuse annotate'" #~ msgstr "'reuse addheader' bylo zrušeno ve prospěch 'reuse annotate'" #~ msgid "option --exclude-year and --year are mutually exclusive" #~ msgstr "volby --exclude-year a --year se vzájemně vylučují" #~ msgid "option --single-line and --multi-line are mutually exclusive" #~ msgstr "volby --single-line a --multi-line se vzájemně vylučují" #~ msgid "" #~ "--explicit-license has been deprecated in favour of --force-dot-license" #~ msgstr "--explicit-license bylo zrušeno ve prospěch --force-dot-license" #~ msgid "Downloading {}" #~ msgstr "Stahování {}" #, fuzzy #~ msgid "conflicting subparser: %s" #~ msgstr "konfliktní volitelný řetězec: %s" #, fuzzy #~ msgid "conflicting subparser alias: %s" #~ msgstr "konfliktní volitelný řetězec: %s" #, fuzzy #~ msgid "can't open '%s': %s" #~ msgstr "nelze otevřít '{}'" #~ msgid "could not find supported VCS" #~ msgstr "nepodařilo se najít podporovaný VCS" reuse-tool-4.0.3/po/de.po000066400000000000000000001156141464275211500152010ustar00rootroot00000000000000# SPDX-FileCopyrightText: 2020 Max Mehl # SPDX-FileCopyrightText: 2020 Thomas Doczkal # # SPDX-License-Identifier: GPL-3.0-or-later msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-07-03 13:09+0000\n" "PO-Revision-Date: 2024-01-08 20:06+0000\n" "Last-Translator: Johannes Keyser \n" "Language-Team: German \n" "Language: de\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 5.4-dev\n" #: src/reuse/_annotate.py:74 #, python-brace-format msgid "" "'{path}' does not support single-line comments, please do not use --single-" "line" msgstr "" #: src/reuse/_annotate.py:81 #, python-brace-format msgid "" "'{path}' does not support multi-line comments, please do not use --multi-line" msgstr "" #: src/reuse/_annotate.py:136 #, python-brace-format msgid "Skipped unrecognised file '{path}'" msgstr "" #: src/reuse/_annotate.py:142 #, python-brace-format msgid "'{path}' is not recognised; creating '{path}.license'" msgstr "" #: src/reuse/_annotate.py:158 #, python-brace-format msgid "Skipped file '{path}' already containing REUSE information" msgstr "" #: src/reuse/_annotate.py:192 #, python-brace-format msgid "Error: Could not create comment for '{path}'" msgstr "Fehler: Kann kein Kommentar für '{path}' erstellen" #: src/reuse/_annotate.py:199 #, python-brace-format msgid "" "Error: Generated comment header for '{path}' is missing copyright lines or " "license expressions. The template is probably incorrect. Did not write new " "header." msgstr "" "Fehler: Die generierten Kommentar-Kopfzeilen für '{path}' enthalten fehlende " "Urheberrechtszeilen oder Lizenzausdrücke. Die Vorlage ist wahrscheinlich " "falsch. Keine neuen Kopfzeile geschrieben." #. TODO: This may need to be rephrased more elegantly. #: src/reuse/_annotate.py:210 #, python-brace-format msgid "Successfully changed header of {path}" msgstr "Kopfzeilen von {path} erfolgreich geändert" #: src/reuse/_annotate.py:221 #, fuzzy msgid "--skip-unrecognised has no effect when used together with --style" msgstr "--output hat keinen Effekt, wenn es zusammen mit --all benutzt wird" #: src/reuse/_annotate.py:231 msgid "option --contributor, --copyright or --license is required" msgstr "Die Option --contributor, --copyright oder --license ist erforderlich" #: src/reuse/_annotate.py:272 #, python-brace-format msgid "template {template} could not be found" msgstr "Vorlage {template} konnte nicht gefunden werden" #: src/reuse/_annotate.py:341 src/reuse/_util.py:573 msgid "can't write to '{}'" msgstr "kann nicht in '{}' schreiben" #: src/reuse/_annotate.py:366 #, fuzzy msgid "" "The following files do not have a recognised file extension. Please use --" "style, --force-dot-license, --fallback-dot-license, or --skip-unrecognised:" msgstr "" "'{path}' hat keine erkannte Dateiendung, bitte verwenden Sie --style oder --" "explicit-license" #: src/reuse/_annotate.py:382 msgid "copyright statement, repeatable" msgstr "Urheberrechtsinformation, wiederholbar" #: src/reuse/_annotate.py:389 msgid "SPDX Identifier, repeatable" msgstr "SPDX-Lizenz-Identifikator, wiederholbar" #: src/reuse/_annotate.py:395 msgid "file contributor, repeatable" msgstr "Dateimitwirkender, wiederholbar" #: src/reuse/_annotate.py:403 msgid "year of copyright statement, optional" msgstr "Jahr der Urheberrechtsinformation, optional" #: src/reuse/_annotate.py:411 msgid "comment style to use, optional" msgstr "zu benutzender Kommentarstil, optional" #: src/reuse/_annotate.py:417 #, fuzzy msgid "copyright prefix to use, optional" msgstr "zu benutzender Kommentarstil, optional" #: src/reuse/_annotate.py:430 msgid "name of template to use, optional" msgstr "Name der zu verwendenden Vorlage, optional" #: src/reuse/_annotate.py:435 msgid "do not include year in statement" msgstr "füge kein Jahr in Angabe hinzu" #: src/reuse/_annotate.py:440 #, fuzzy msgid "merge copyright lines if copyright statements are identical" msgstr "Jahr der Urheberrechtsinformation, optional" #: src/reuse/_annotate.py:446 #, fuzzy msgid "force single-line comment style, optional" msgstr "zu benutzender Kommentarstil, optional" #: src/reuse/_annotate.py:451 #, fuzzy msgid "force multi-line comment style, optional" msgstr "zu benutzender Kommentarstil, optional" #: src/reuse/_annotate.py:458 msgid "add headers to all files under specified directories recursively" msgstr "" #: src/reuse/_annotate.py:465 msgid "do not replace the first header in the file; just add a new one" msgstr "" #: src/reuse/_annotate.py:473 msgid "always write a .license file instead of a header inside the file" msgstr "" #: src/reuse/_annotate.py:480 msgid "write a .license file to files with unrecognised comment styles" msgstr "" #: src/reuse/_annotate.py:486 msgid "skip files with unrecognised comment styles" msgstr "" #: src/reuse/_annotate.py:497 #, fuzzy msgid "skip files that already contain REUSE information" msgstr "Dateien mit Lizenzinformationen:" #: src/reuse/_annotate.py:532 #, python-brace-format msgid "'{path}' is a binary, therefore using '{new_path}' for the header" msgstr "" "'{path}' ist im Binärformat, benutze daher '{new_path}' für die Kopfzeilen" #: src/reuse/_main.py:39 msgid "" "reuse is a tool for compliance with the REUSE recommendations. See for more information, and " "for the online documentation." msgstr "" "reuse ist ein Werkzeug, um die Empfehlungen von REUSE umzusetzen und zu " "überprüfen. Mehr Informationen finden Sie auf oder " "in der Online-Dokumentation auf ." #: src/reuse/_main.py:45 msgid "" "This version of reuse is compatible with version {} of the REUSE " "Specification." msgstr "" "Diese Version von reuse ist kompatibel mit Version {} der REUSE-" "Spezifikation." #: src/reuse/_main.py:48 msgid "Support the FSFE's work:" msgstr "Die Arbeit der FSFE unterstützen:" #: src/reuse/_main.py:52 msgid "" "Donations are critical to our strength and autonomy. They enable us to " "continue working for Free Software wherever necessary. Please consider " "making a donation at ." msgstr "" "Spenden sind entscheidend für unsere Leistungsfähigkeit und Autonomie. Sie " "ermöglichen es uns, weiterhin für Freie Software zu arbeiten, wo immer es " "nötig ist. Bitte erwägen Sie eine Spende unter ." #: src/reuse/_main.py:75 msgid "enable debug statements" msgstr "Debug-Statements aktivieren" #: src/reuse/_main.py:80 msgid "hide deprecation warnings" msgstr "„Veraltet“-Warnung verbergen" #: src/reuse/_main.py:85 msgid "do not skip over Git submodules" msgstr "Git-Submodules nicht überspringen" #: src/reuse/_main.py:90 msgid "do not skip over Meson subprojects" msgstr "Meson-Teilprojekte nicht überspringen" #: src/reuse/_main.py:95 msgid "do not use multiprocessing" msgstr "kein Multiprocessing verwenden" #: src/reuse/_main.py:102 msgid "define root of project" msgstr "Stammverzeichnis des Projekts bestimmen" #: src/reuse/_main.py:107 msgid "show program's version number and exit" msgstr "zeige die Versionsnummer des Programms und beende" #: src/reuse/_main.py:111 msgid "subcommands" msgstr "Unterkommandos" #: src/reuse/_main.py:118 msgid "add copyright and licensing into the header of files" msgstr "" "schreibe Urheberrechts- und Lizenzinformationen in die Kopfzeilen von Dateien" #: src/reuse/_main.py:121 msgid "" "Add copyright and licensing into the header of one or more files.\n" "\n" "By using --copyright and --license, you can specify which copyright holders " "and licenses to add to the headers of the given files.\n" "\n" "By using --contributor, you can specify people or entity that contributed " "but are not copyright holder of the given files." msgstr "" #: src/reuse/_main.py:140 msgid "download a license and place it in the LICENSES/ directory" msgstr "lade eine Datei herunter und speichere sie im Verzeichnis LICENSES/" #: src/reuse/_main.py:142 #, fuzzy msgid "Download a license and place it in the LICENSES/ directory." msgstr "lade eine Datei herunter und speichere sie im Verzeichnis LICENSES/" #: src/reuse/_main.py:151 msgid "list all non-compliant files" msgstr "alle nicht-konformen Dateien zeigen" #: src/reuse/_main.py:154 #, python-brace-format msgid "" "Lint the project directory for compliance with version {reuse_version} of " "the REUSE Specification. You can find the latest version of the " "specification at .\n" "\n" "Specifically, the following criteria are checked:\n" "\n" "- Are there any bad (unrecognised, not compliant with SPDX) licenses in the " "project?\n" "\n" "- Are any licenses referred to inside of the project, but not included in " "the LICENSES/ directory?\n" "\n" "- Are any licenses included in the LICENSES/ directory that are not used " "inside of the project?\n" "\n" "- Do all files have valid copyright and licensing information?" msgstr "" "Überprüfen Sie das Projektverzeichnis auf die Einhaltung der Version " "{reuse_version} der REUSE-Spezifikation. Die neueste Version der " "Spezifikation finden Sie unter .\n" "\n" "Im Einzelnen werden die folgenden Kriterien geprüft:\n" "\n" "- Sind im Projekt schlechte (nicht erkannte, nicht SPDX-konforme) Lizenzen " "vorhanden?\n" "\n" "- Gibt es Lizenzen, auf die innerhalb des Projekts verwiesen wird, die aber " "nicht im Verzeichnis LICENSES/ enthalten sind?\n" "\n" "- Sind Lizenzen im Verzeichnis LICENSES/ enthalten, die nicht innerhalb des " "Projekts verwendet werden?\n" "\n" "- Sind alle Dateien mit gültigen Urheberrechts- und Lizenzinformationen " "versehen?" #: src/reuse/_main.py:181 msgid "print the project's bill of materials in SPDX format" msgstr "Komponentenliste im SPDX-Format ausgeben" #: src/reuse/_main.py:189 msgid "list all supported SPDX licenses" msgstr "Listet alle unterstützten SPDX-Lizenzen auf" #: src/reuse/_main.py:198 msgid "convert .reuse/dep5 to REUSE.toml" msgstr "" #: src/reuse/_main.py:263 #, fuzzy, python-brace-format msgid "'{path}' could not be decoded as UTF-8." msgstr "'{dep5}' konnte nicht als UTF-8 decodiert werden." #: src/reuse/_main.py:269 #, fuzzy, python-brace-format msgid "" "'{path}' could not be parsed. We received the following error message: " "{message}" msgstr "" "'{dep5}' konnte nicht geparst werden. Wir erhielten folgende Fehlermeldung: " "{message}" #: src/reuse/_util.py:368 src/reuse/global_licensing.py:218 #, python-brace-format msgid "Could not parse '{expression}'" msgstr "Kann '{expression}' nicht parsen" #: src/reuse/_util.py:424 #, python-brace-format msgid "" "'{path}' holds an SPDX expression that cannot be parsed, skipping the file" msgstr "" "'{path}' trägt einen SPDX-Ausdruck, der nicht geparst werden kann. " "Überspringe Datei" #: src/reuse/_util.py:556 msgid "'{}' is not a file" msgstr "'{}' ist keine Datei" #: src/reuse/_util.py:559 msgid "'{}' is not a directory" msgstr "'{}' ist kein Verzeichnis" #: src/reuse/_util.py:562 msgid "can't open '{}'" msgstr "kann '{}' nicht öffnen" #: src/reuse/_util.py:567 msgid "can't write to directory '{}'" msgstr "kann nicht in Verzeichnis '{}' schreiben" #: src/reuse/_util.py:586 msgid "can't read or write '{}'" msgstr "kann '{}' nicht lesen oder schreiben" #: src/reuse/_util.py:596 msgid "'{}' is not a valid SPDX expression, aborting" msgstr "'{}' ist kein gültiger SPDX-Ausdruck, breche ab" #: src/reuse/_util.py:624 msgid "'{}' is not a valid SPDX License Identifier." msgstr "'{}' ist kein gültiger SPDX-Lizenz-Identifikator." #: src/reuse/_util.py:631 msgid "Did you mean:" msgstr "Meinten Sie:" #: src/reuse/_util.py:638 msgid "" "See for a list of valid SPDX License " "Identifiers." msgstr "" "Besuchen Sie für eine Liste von gültigen SPDX-" "Lizenz-Identifikatoren." #: src/reuse/convert_dep5.py:118 #, fuzzy msgid "no '.reuse/dep5' file" msgstr "Erstelle .reuse/dep5" #: src/reuse/download.py:130 msgid "SPDX License Identifier of license" msgstr "SPDX-Lizenz-Identifikator der Lizenz" #: src/reuse/download.py:135 msgid "download all missing licenses detected in the project" msgstr "lade alle fehlenden Lizenzen herunter, die im Projekt gefunden wurden" #: src/reuse/download.py:145 msgid "" "source from which to copy custom LicenseRef- licenses, either a directory " "that contains the file or the file itself" msgstr "" #: src/reuse/download.py:156 #, python-brace-format msgid "Error: {spdx_identifier} already exists." msgstr "Fehler: {spdx_identifier} existiert bereits." #: src/reuse/download.py:163 #, python-brace-format msgid "Error: {path} does not exist." msgstr "Fehler: {path} existiert nicht." #: src/reuse/download.py:166 msgid "Error: Failed to download license." msgstr "Fehler: Lizenz konnte nicht heruntergeladen werden." #: src/reuse/download.py:171 msgid "Is your internet connection working?" msgstr "Funktioniert Ihre Internetverbindung?" #: src/reuse/download.py:176 #, python-brace-format msgid "Successfully downloaded {spdx_identifier}." msgstr "{spdx_identifier} erfolgreich heruntergeladen." #: src/reuse/download.py:188 msgid "--output has no effect when used together with --all" msgstr "--output hat keinen Effekt, wenn es zusammen mit --all benutzt wird" #: src/reuse/download.py:192 msgid "the following arguments are required: license" msgstr "Die folgenden Argumente sind erforderlich: license" #: src/reuse/download.py:194 msgid "cannot use --output with more than one license" msgstr "Kann --output nicht mit mehr als einer Lizenz verwenden" #: src/reuse/global_licensing.py:109 #, python-brace-format msgid "" "{attr_name} must be a {type_name} (got {value} that is a {value_class})." msgstr "" #: src/reuse/global_licensing.py:122 #, python-brace-format msgid "" "Item in {attr_name} collection must be a {type_name} (got {item_value} that " "is a {item_class})." msgstr "" #: src/reuse/global_licensing.py:133 #, python-brace-format msgid "{attr_name} must not be empty." msgstr "" #: src/reuse/global_licensing.py:156 #, python-brace-format msgid "{name} must be a {type} (got {value} that is a {value_type})." msgstr "" #: src/reuse/global_licensing.py:179 #, python-brace-format msgid "" "The value of 'precedence' must be one of {precedence_vals} (got {received})" msgstr "" #: src/reuse/header.py:99 msgid "generated comment is missing copyright lines or license expressions" msgstr "" "Dem generierten Kommentar fehlen Zeilen zum Urheberrecht oder Lizenzausdrücke" #: src/reuse/lint.py:30 msgid "prevents output" msgstr "Verhindert Ausgabe" #: src/reuse/lint.py:33 msgid "formats output as JSON" msgstr "formatiert Ausgabe als JSON" #: src/reuse/lint.py:39 msgid "formats output as plain text" msgstr "formatiert Ausgabe als rohen Text" #: src/reuse/lint.py:45 #, fuzzy msgid "formats output as errors per line" msgstr "formatiert Ausgabe als rohen Text" #: src/reuse/lint.py:64 msgid "BAD LICENSES" msgstr "FALSCHE LIZENZEN" #: src/reuse/lint.py:66 src/reuse/lint.py:95 msgid "'{}' found in:" msgstr "'{}' gefunden in:" #: src/reuse/lint.py:73 msgid "DEPRECATED LICENSES" msgstr "VERALTETE LIZENZEN" #: src/reuse/lint.py:75 msgid "The following licenses are deprecated by SPDX:" msgstr "Die folgenden Lizenzen wurden von SPDX als veraltetet gekennzeichnet:" #: src/reuse/lint.py:83 msgid "LICENSES WITHOUT FILE EXTENSION" msgstr "LIZENZEN OHNE DATEIENDUNG" #: src/reuse/lint.py:85 msgid "The following licenses have no file extension:" msgstr "Die folgenden Lizenzen haben keine Dateiendung:" #: src/reuse/lint.py:93 msgid "MISSING LICENSES" msgstr "FEHLENDE LIZENZEN" #: src/reuse/lint.py:102 msgid "UNUSED LICENSES" msgstr "NICHT VERWENDETE LIZENZEN" #: src/reuse/lint.py:103 msgid "The following licenses are not used:" msgstr "Die folgenden Lizenzen werden nicht benutzt:" #: src/reuse/lint.py:110 msgid "READ ERRORS" msgstr "LESEFEHLER" #: src/reuse/lint.py:111 msgid "Could not read:" msgstr "Unlesbar:" #: src/reuse/lint.py:132 msgid "MISSING COPYRIGHT AND LICENSING INFORMATION" msgstr "FEHLENDE URHEBERRECHTS- UND LIZENZINFORMATIONEN" #: src/reuse/lint.py:138 msgid "The following files have no copyright and licensing information:" msgstr "" "Die folgenden Dateien haben keine Urheberrechts- und Lizenzinformationen:" #: src/reuse/lint.py:149 msgid "The following files have no copyright information:" msgstr "Die folgenden Dateien haben keine Urheberrechtsinformationen:" #: src/reuse/lint.py:158 msgid "The following files have no licensing information:" msgstr "Die folgenden Dateien haben keine Lizenzinformationen:" #: src/reuse/lint.py:166 msgid "SUMMARY" msgstr "ZUSAMMENFASSUNG" #: src/reuse/lint.py:171 msgid "Bad licenses:" msgstr "Falsche Lizenzen:" #: src/reuse/lint.py:172 msgid "Deprecated licenses:" msgstr "Veraltete Lizenzen:" #: src/reuse/lint.py:173 msgid "Licenses without file extension:" msgstr "Lizenzen ohne Dateiendung:" #: src/reuse/lint.py:176 msgid "Missing licenses:" msgstr "Fehlende Lizenzen:" #: src/reuse/lint.py:177 msgid "Unused licenses:" msgstr "Unbenutzte Lizenzen:" #: src/reuse/lint.py:178 msgid "Used licenses:" msgstr "Verwendete Lizenzen:" #: src/reuse/lint.py:179 msgid "Read errors:" msgstr "Lesefehler:" #: src/reuse/lint.py:181 #, fuzzy msgid "Files with copyright information:" msgstr "Dateien mit Urheberrechtsinformationen:" #: src/reuse/lint.py:185 #, fuzzy msgid "Files with license information:" msgstr "Dateien mit Lizenzinformationen:" #: src/reuse/lint.py:202 msgid "" "Congratulations! Your project is compliant with version {} of the REUSE " "Specification :-)" msgstr "" "Herzlichen Glückwunsch! Ihr Projekt ist konform mit Version {} der REUSE-" "Spezifikation :-)" #: src/reuse/lint.py:209 msgid "" "Unfortunately, your project is not compliant with version {} of the REUSE " "Specification :-(" msgstr "" "Leider ist Ihr Projekt nicht konform mit Version {} der REUSE-" "Spezifikation :-(" #: src/reuse/lint.py:216 msgid "RECOMMENDATIONS" msgstr "EMPFEHLUNGEN" #: src/reuse/lint.py:289 #, python-brace-format msgid "{path}: bad license {lic}\n" msgstr "" #: src/reuse/lint.py:296 #, fuzzy, python-brace-format msgid "{lic_path}: deprecated license\n" msgstr "Veraltete Lizenzen:" #: src/reuse/lint.py:303 #, fuzzy, python-brace-format msgid "{lic_path}: license without file extension\n" msgstr "Lizenzen ohne Dateiendung:" #: src/reuse/lint.py:312 #, fuzzy, python-brace-format msgid "{lic_path}: unused license\n" msgstr "Unbenutzte Lizenzen:" #: src/reuse/lint.py:319 #, python-brace-format msgid "{path}: missing license {lic}\n" msgstr "" #: src/reuse/lint.py:326 #, python-brace-format msgid "{path}: read error\n" msgstr "" #: src/reuse/lint.py:330 #, fuzzy, python-brace-format msgid "{path}: no license identifier\n" msgstr "'{}' ist kein gültiger SPDX-Lizenz-Identifikator." #: src/reuse/lint.py:334 #, python-brace-format msgid "{path}: no copyright notice\n" msgstr "" #: src/reuse/project.py:262 #, fuzzy, python-brace-format msgid "'{path}' covered by {global_path}" msgstr "'{path}' abgedeckt durch .reuse/dep5" #: src/reuse/project.py:270 #, python-brace-format msgid "" "'{path}' is covered exclusively by REUSE.toml. Not reading the file contents." msgstr "" #: src/reuse/project.py:277 #, fuzzy, python-brace-format msgid "" "'{path}' was detected as a binary file; not searching its contents for REUSE " "information." msgstr "" "'{path}' wurde als binäre Datei erkannt oder ihre Erweiterung ist als " "unkommentierbar gekennzeichnet; suche ihre Inhalte nicht nach REUSE-" "Informationen." #: src/reuse/project.py:334 msgid "" "'.reuse/dep5' is deprecated. You are recommended to instead use REUSE.toml. " "Use `reuse convert-dep5` to convert." msgstr "" #: src/reuse/project.py:348 #, python-brace-format msgid "" "Found both '{new_path}' and '{old_path}'. You cannot keep both files " "simultaneously; they are not intercompatible." msgstr "" #: src/reuse/project.py:414 #, python-brace-format msgid "determining identifier of '{path}'" msgstr "erkenne Identifikator von '{path}'" #: src/reuse/project.py:422 #, python-brace-format msgid "{path} does not have a file extension" msgstr "{path} hat keine Dateiendung" #: src/reuse/project.py:432 #, python-brace-format msgid "" "Could not resolve SPDX License Identifier of {path}, resolving to " "{identifier}. Make sure the license is in the license list found at or that it starts with 'LicenseRef-', and that it has a " "file extension." msgstr "" "Konnte SPDX-Lizenz-Identifikator von {path} nicht erkennen, der auf " "{identifier} verweist. Stellen Sie sicher, dass die Lizenz in der " "Lizenzliste unter steht oder mit 'LicenseRef-' " "beginnt und eine Dateiendung hat." #: src/reuse/project.py:444 #, python-brace-format msgid "" "{identifier} is the SPDX License Identifier of both {path} and {other_path}" msgstr "" "{identifier} ist der SPDX-Lizenz-Identifikator von {path} und {other_path}" #: src/reuse/project.py:483 msgid "" "project '{}' is not a VCS repository or required VCS software is not " "installed" msgstr "" "Projekt '{}' ist kein VCS-Repository oder die benötigte VCS-Software ist " "nicht installiert" #: src/reuse/report.py:310 #, python-brace-format msgid "Could not read '{path}'" msgstr "Konnte '{path}' nicht lesen" #: src/reuse/report.py:317 #, python-brace-format msgid "Unexpected error occurred while parsing '{path}'" msgstr "Unerwarteter Fehler beim Parsen von '{path}' aufgetreten" #: src/reuse/report.py:438 msgid "" "Fix bad licenses: At least one license in the LICENSES directory and/or " "provided by 'SPDX-License-Identifier' tags is invalid. They are either not " "valid SPDX License Identifiers or do not start with 'LicenseRef-'. FAQ about " "custom licenses: https://reuse.software/faq/#custom-license" msgstr "" "Korrektur ungültiger Lizenzen: Mindestens eine Lizenz im LICENSES-" "Verzeichnis, und/oder die per 'SPDX-License-Identifier' angegeben wird, ist " "ungültig. Sie sind entweder keine gültigen SPDX-Lizenz-Identifikatoren oder " "beginnen nicht mit 'LicenseRef-'. FAQ zu benutzerdefinierten Lizenzen: " "https://reuse.software/faq/#custom-license" #: src/reuse/report.py:449 msgid "" "Fix deprecated licenses: At least one of the licenses in the LICENSES " "directory and/or provided by an 'SPDX-License-Identifier' tag or in '.reuse/" "dep5' has been deprecated by SPDX. The current list and their respective " "recommended new identifiers can be found here: " msgstr "" "Korrektur veralteter Lizenzen: Mindestens eine der Lizenzen im LICENSES-" "Verzeichnis und/oder die per 'SPDX-License-Identifier'-Kennzeichnung oder in " "'.reuse/dep5' angegeben ist wurde von SPDX als veraltet markiert. Die " "aktuelle Liste und ihre jeweiligen empfohlenen neuen Kennungen finden Sie " "hier: " #: src/reuse/report.py:460 msgid "" "Fix licenses without file extension: At least one license text file in the " "'LICENSES' directory does not have a '.txt' file extension. Please rename " "the file(s) accordingly." msgstr "" "Korrektur von Lizenzen ohne Dateierweiterung: Mindestens eine " "Lizenztextdatei im Verzeichnis 'LICENSES' hat keine '.txt'-Dateierweiterung. " "Bitte benennen Sie die Datei(en) entsprechend um." #: src/reuse/report.py:469 msgid "" "Fix missing licenses: For at least one of the license identifiers provided " "by the 'SPDX-License-Identifier' tags, there is no corresponding license " "text file in the 'LICENSES' directory. For SPDX license identifiers, you can " "simply run 'reuse download --all' to get any missing ones. For custom " "licenses (starting with 'LicenseRef-'), you need to add these files yourself." msgstr "" "Korrektur fehlender Lizenzen: Für mindestens eine der durch die 'SPDX-" "License-Identifier' angegebenen Lizenzkennzeichen gibt es im Verzeichnis " "'LICENSES' keine entsprechende Lizenztextdatei. Für SPDX-Lizenz-" "Identifikatoren können Sie einfach 'reuse download --all' ausführen, um " "fehlende zu erhalten. Für benutzerdefinierte Lizenzen (beginnend mit " "'LicenseRef-'), müssen Sie diese Dateien selbst hinzufügen." #: src/reuse/report.py:481 msgid "" "Fix unused licenses: At least one of the license text files in 'LICENSES' is " "not referenced by any file, e.g. by an 'SPDX-License-Identifier' tag. Please " "make sure that you either tag the accordingly licensed files properly, or " "delete the unused license text if you are sure that no file or code snippet " "is licensed as such." msgstr "" "Korrektur ungenutzter Lizenzen: Mindestens eine der Lizenztextdateien in " "'LICENSES' wird von keiner Datei referenziert, z.B. durch einen 'SPDX-" "License-Identifier'-Eintrag. Bitte stellen Sie sicher, dass Sie entweder die " "entsprechend lizenzierten Dateien korrekt markieren oder den ungenutzten " "Lizenztext löschen, wenn Sie sicher sind, dass keine Datei oder Code-" "Schnipsel darunter lizenziert ist." #: src/reuse/report.py:492 msgid "" "Fix read errors: At least one of the files in your directory cannot be read " "by the tool. Please check the file permissions. You will find the affected " "files at the top of the output as part of the logged error messages." msgstr "" #: src/reuse/report.py:501 msgid "" "Fix missing copyright/licensing information: For one or more files, the tool " "cannot find copyright and/or licensing information. You typically do this by " "adding 'SPDX-FileCopyrightText' and 'SPDX-License-Identifier' tags to each " "file. The tutorial explains additional ways to do this: " msgstr "" #: src/reuse/spdx.py:32 msgid "" "populate the LicenseConcluded field; note that reuse cannot guarantee the " "field is accurate" msgstr "" #: src/reuse/spdx.py:39 msgid "name of the person signing off on the SPDX report" msgstr "" #: src/reuse/spdx.py:44 msgid "name of the organization signing off on the SPDX report" msgstr "" #: src/reuse/spdx.py:60 msgid "" "error: --creator-person=NAME or --creator-organization=NAME required when --" "add-license-concluded is provided" msgstr "" #: src/reuse/spdx.py:75 #, python-brace-format msgid "" "'{path}' does not match a common SPDX file pattern. Find the suggested " "naming conventions here: https://spdx.github.io/spdx-spec/conformance/#44-" "standard-data-format-requirements" msgstr "" #: /usr/lib/python3.10/argparse.py:308 msgid "usage: " msgstr "Benutzung: " #: /usr/lib/python3.10/argparse.py:880 msgid ".__call__() not defined" msgstr ".__call__() nicht definiert" #: /usr/lib/python3.10/argparse.py:1223 #, python-format msgid "unknown parser %(parser_name)r (choices: %(choices)s)" msgstr "unbekannter Parser %(parser_name)r (Auswahl: %(choices)s)" #: /usr/lib/python3.10/argparse.py:1283 #, python-format msgid "argument \"-\" with mode %r" msgstr "Argument \"-\" mit Modus %r" #: /usr/lib/python3.10/argparse.py:1292 #, python-format msgid "can't open '%(filename)s': %(error)s" msgstr "Kann '%(filename)s' nicht öffnen: %(error)s" #: /usr/lib/python3.10/argparse.py:1501 #, python-format msgid "cannot merge actions - two groups are named %r" msgstr "Kann Aktionen nicht zusammenführen - zwei Gruppen heißen %r" #: /usr/lib/python3.10/argparse.py:1539 msgid "'required' is an invalid argument for positionals" msgstr "'required' ist ein ungültiges Argument für Positionsangaben" #: /usr/lib/python3.10/argparse.py:1561 #, python-format msgid "" "invalid option string %(option)r: must start with a character " "%(prefix_chars)r" msgstr "" "Ungültige Option %(option)r: Muss mit einem Buchstaben %(prefix_chars)r " "beginnen" #: /usr/lib/python3.10/argparse.py:1579 #, python-format msgid "dest= is required for options like %r" msgstr "dest= ist erforderlich für Optionen wie %r" #: /usr/lib/python3.10/argparse.py:1596 #, python-format msgid "invalid conflict_resolution value: %r" msgstr "Ungültiger Wert für conflict_resolution: %r" #: /usr/lib/python3.10/argparse.py:1614 #, python-format msgid "conflicting option string: %s" msgid_plural "conflicting option strings: %s" msgstr[0] "Widersprüchliche Option: %s" msgstr[1] "Widersprüchliche Optionen: %s" #: /usr/lib/python3.10/argparse.py:1680 msgid "mutually exclusive arguments must be optional" msgstr "Sich gegenseitig ausschließende Argumente müssen optional sein" #: /usr/lib/python3.10/argparse.py:1748 msgid "positional arguments" msgstr "Positions-Argumente" #: /usr/lib/python3.10/argparse.py:1749 msgid "options" msgstr "" #: /usr/lib/python3.10/argparse.py:1764 msgid "show this help message and exit" msgstr "zeige diese Hilfsnachricht und beende" #: /usr/lib/python3.10/argparse.py:1795 msgid "cannot have multiple subparser arguments" msgstr "mehrere Subparser-Argumente sind nicht möglich" #: /usr/lib/python3.10/argparse.py:1847 /usr/lib/python3.10/argparse.py:2362 #, python-format msgid "unrecognized arguments: %s" msgstr "unbekannte Argumente: %s" #: /usr/lib/python3.10/argparse.py:1948 #, python-format msgid "not allowed with argument %s" msgstr "nicht erlaubt mit Argument %s" #: /usr/lib/python3.10/argparse.py:1998 /usr/lib/python3.10/argparse.py:2012 #, python-format msgid "ignored explicit argument %r" msgstr "explizites Argument %r ignoriert" #: /usr/lib/python3.10/argparse.py:2119 #, python-format msgid "the following arguments are required: %s" msgstr "die folgenden Argumente sind erforderlich: %s" #: /usr/lib/python3.10/argparse.py:2134 #, python-format msgid "one of the arguments %s is required" msgstr "eines der Argumente %s ist erforderlich" #: /usr/lib/python3.10/argparse.py:2177 msgid "expected one argument" msgstr "erwartete ein Argument" #: /usr/lib/python3.10/argparse.py:2178 msgid "expected at most one argument" msgstr "erwartete höchstens ein Argument" #: /usr/lib/python3.10/argparse.py:2179 msgid "expected at least one argument" msgstr "erwartete mindestens ein Argument" #: /usr/lib/python3.10/argparse.py:2183 #, python-format msgid "expected %s argument" msgid_plural "expected %s arguments" msgstr[0] "erwartete %s Argument" msgstr[1] "erwartete %s Argumente" #: /usr/lib/python3.10/argparse.py:2241 #, python-format msgid "ambiguous option: %(option)s could match %(matches)s" msgstr "mehrdeutige Option: %(option)s könnte %(matches)s bedeuten" #: /usr/lib/python3.10/argparse.py:2305 #, python-format msgid "unexpected option string: %s" msgstr "unerwarteter Options-String: %s" #: /usr/lib/python3.10/argparse.py:2502 #, python-format msgid "%r is not callable" msgstr "%r ist nicht aufrufbar" #: /usr/lib/python3.10/argparse.py:2519 #, python-format msgid "invalid %(type)s value: %(value)r" msgstr "ungültiger %(type)s Wert: %(value)r" #: /usr/lib/python3.10/argparse.py:2530 #, python-format msgid "invalid choice: %(value)r (choose from %(choices)s)" msgstr "ungültige Auswahl: %(value)r (wähle von %(choices)s)" #: /usr/lib/python3.10/argparse.py:2606 #, python-format msgid "%(prog)s: error: %(message)s\n" msgstr "%(prog)s: Fehler: %(message)s\n" #, fuzzy, python-brace-format #~ msgid "" #~ "Copyright and licensing information for '{original_path}' has been found " #~ "in both '{path}' and in the DEP5 file located at '{dep5_path}'. The " #~ "information for these two sources has been aggregated. You are " #~ "recommended to instead use REUSE.toml, where you can specify the order of " #~ "precedence. Use `reuse convert-dep5` to convert. Run with `--suppress-" #~ "deprecation` to hide this warning." #~ msgstr "" #~ "Urheberrechts- und Lizenzinformationen für '{original_path}' wurden " #~ "sowohl in '{path}' als auch in der DEP5-Datei unter '{dep5_path}' " #~ "gefunden. Die Informationen für diese beiden Quellen wurden " #~ "zusammengelegt. In Zukunft wird sich dieses Verhalten ändern, und Sie " #~ "müssen explizit das Zusammenlegen aktivieren. Siehe . Sie müssen noch nichts tun. Ausführen mit `--" #~ "suppress-deprecation`, um diese Warnung zu verbergen." #~ msgid "initialize REUSE project" #~ msgstr "REUSE-Projekt initialisieren" #~ msgid "no '{}' file, or could not read it" #~ msgstr "Keine datei '{}' oder konnte sie nicht lesen" #~ msgid "" #~ "What license is your project under? Provide the SPDX License Identifier. " #~ "See for the list." #~ msgstr "" #~ "Unter welcher Lizenz steht Ihr Projekt? Geben Sie den SPDX-Lizenz-" #~ "Identifikator an. Sehen Sie die Liste auf ." #~ msgid "" #~ "What other license is your project under? Provide the SPDX License " #~ "Identifier." #~ msgstr "" #~ "Unter welcher anderen Lizenz steht Ihr Projekt? Geben Sie den SPDX-Lizenz-" #~ "Identifikator an." #~ msgid "To stop adding licenses, hit RETURN." #~ msgstr "Um keine weiteren Lizenzen hinzuzufügen, drücken Sie ENTER." #~ msgid "Project already initialized" #~ msgstr "Projekt bereits initialisiert" #~ msgid "Initializing project for REUSE." #~ msgstr "Initialisiere Projekt für REUSE." #~ msgid "What is the name of the project?" #~ msgstr "Was ist der Name des Projekts?" #~ msgid "What is the internet address of the project?" #~ msgstr "Was ist die Internetadresse des Projekts?" #~ msgid "What is the name of the maintainer?" #~ msgstr "Was ist der Name der Betreuenden?" #~ msgid "What is the e-mail address of the maintainer?" #~ msgstr "Wie lautet die E-Mail-Adresse der Betreuenden?" #~ msgid "All done! Initializing now." #~ msgstr "Alles erledigt! Initialisiere jetzt." #~ msgid "Retrieving {}" #~ msgstr "Empfangen von {}" #~ msgid "{} already exists" #~ msgstr "{} existiert bereits" #~ msgid "Could not download {}" #~ msgstr "Konnte {} nicht herunterladen" #, python-brace-format #~ msgid "" #~ "Error: Could not copy {path}, please add {lic}.txt manually in the " #~ "LICENCES/ directory." #~ msgstr "" #~ "Fehler: Konnte {path} nicht kopieren, bitte fügen Sie {lic}.txt manuell " #~ "zum Verzeichnis LICENCES/ hinzu." #~ msgid "Initialization complete." #~ msgstr "Initialisierung vollständig." #~ msgid "" #~ "Add copyright and licensing into the header of one or more files.\n" #~ "\n" #~ "By using --copyright and --license, you can specify which copyright " #~ "holders and licenses to add to the headers of the given files.\n" #~ "\n" #~ "By using --contributor, you can specify people or entity that contributed " #~ "but are not copyright holder of the given files.\n" #~ "The first comment is replaced with a new header containing the new " #~ "copyright and licensing information and its former copyright and " #~ "licensing. If you want to keep the first comment intact, use --no-" #~ "replace.\n" #~ "\n" #~ "The comment style should be auto-detected for your files. If a comment " #~ "style could not be detected and --skip-unrecognised is not specified, the " #~ "process aborts. Use --style to specify or override the comment style to " #~ "use.\n" #~ "\n" #~ "A single-line comment style is used when it is available. If no single-" #~ "line comment style is available, a multi-line comment style is used. You " #~ "can force a certain comment style using --single-line or --multi-line.\n" #~ "\n" #~ "You can change the template of the header comment by using --template. " #~ "Place a Jinja2 template in .reuse/templates/mytemplate.jinja2. You can " #~ "use the template by specifying '--template mytemplate'. Read the online " #~ "documentation on how to use this feature.\n" #~ "\n" #~ "If a binary file is detected, or if --force-dot-license is specified, the " #~ "header is placed in a .license file." #~ msgstr "" #~ "Hinzufügen von Urheberrechten und Lizenzen in die Kopfzeilen einer oder " #~ "mehrerer Dateien.\n" #~ "\n" #~ "Durch die Verwendung von --copyright und --license können Sie festlegen, " #~ "welche Urheberrechtsinhaber und Lizenzen den Kopfzeilen der angegebenen " #~ "Dateien hinzuzufügen werden.\n" #~ "\n" #~ "Durch die Verwendung von --contributor können Sie Personen oder " #~ "Organisationen angeben, die beigetragen haben, aber keine " #~ "Urheberrechtsinhaber der angegebenen Dateien sind.\n" #~ "Das erste Kommentar wird durch einer neuen Kopfzeile ersetzt, die die " #~ "neuen Urheberrechts- und Lizenzierungsinformationen sowie das frühere " #~ "Urheberrecht und die Lizenzierung enthält. Wenn Sie das erste Kommentar " #~ "erhalten möchten, verwenden Sie --no-replace.\n" #~ "\n" #~ "Der Kommentarstil sollte für Ihre Dateien automatisch erkannt werden. " #~ "Wenn ein Kommentastil nicht erkannt werden konnte und --skip-unrecognised " #~ "nicht angegeben wurde, wird der Prozess abgebrochen. Verwenden Sie --" #~ "style, um den Kommentarstil anzugeben oder zu überschreiben.\n" #~ "\n" #~ "Ein einzeiliger Kommentarstil wird verwendet, sofern einer verfügbar ist. " #~ "Falls kein einzeiliger Kommentarstil verfügbar ist, wird ein mehrzeiliger " #~ "Kommentarstil verwendet. Sie können einen bestimmten Kommentarstil mit --" #~ "single-line oder --multi-line erzwingen.\n" #~ "\n" #~ "Sie können die Schablone der Kopfzeilen-Kommentare ändern, indem Sie --" #~ "template verwenden. Speichern Sie eine Jinja2-Schablone in .reuse/" #~ "templates/meineschablone.jinja2. Sie können die Schablone verwenden, " #~ "indem Sie \"--template meineschablone\" angeben. Lesen Sie die Online-" #~ "Dokumentation über die Nutzung dieser Funktion.\n" #~ "\n" #~ "Wird eine binäre Datei erkannt wird oder --force-dot-license angegeben " #~ "ist, werden die Kopfzeilen in eine .license-Datei geschrieben." #~ msgid "" #~ "Download a license and place it in the LICENSES/ directory.\n" #~ "\n" #~ "The LICENSES/ directory is automatically found in the following order:\n" #~ "\n" #~ "- The LICENSES/ directory in the root of the VCS repository.\n" #~ "\n" #~ "- The current directory if its name is LICENSES.\n" #~ "\n" #~ "- The LICENSES/ directory in the current directory.\n" #~ "\n" #~ "If the LICENSES/ directory cannot be found, one is simply created." #~ msgstr "" #~ "Lade eine Datei herunter und speichere sie im Verzeichnis LICENSES/.\n" #~ "\n" #~ "Das LICENSES/-Verzeichnis wird automatisch in dieser Reihenfolge " #~ "gesucht:\n" #~ "\n" #~ "- Das LICENSES/-Verzeichnis im Wurzelverzeichnis des VCS-Repositorys.\n" #~ "\n" #~ "- Das aktuelle Verzeichnis wenn dessen Name LICENSES ist.\n" #~ "\n" #~ "- Das LICENSES/-Verzeichnis im aktuellen Verzeichnis.\n" #~ "\n" #~ "Wenn das LICENSES/-Verzeichnis nicht gefunden werden kann, wird einfach " #~ "eines erstellt." #~ msgid ".reuse/dep5 has syntax errors" #~ msgstr ".reuse/dep5 hat Syntaxfehler" #~ msgid "optional arguments" #~ msgstr "Optionale Argumente" #~ msgid "option --exclude-year and --year are mutually exclusive" #~ msgstr "" #~ "Die Optionen --exclude-year und --year schließen sich gegenseitig aus" #~ msgid "option --single-line and --multi-line are mutually exclusive" #~ msgstr "" #~ "Die Optionen --single-line und --multi-line schließen sich gegenseitig aus" #~ msgid "Downloading {}" #~ msgstr "Lade {} herunter" #, fuzzy #~ msgid "conflicting subparser: %s" #~ msgstr "Widersprüchliche Option: %s" #, fuzzy #~ msgid "conflicting subparser alias: %s" #~ msgstr "Widersprüchliche Option: %s" #~ msgid "can't open '%s': %s" #~ msgstr "Kann '%s' nicht öffnen: %s" #~ msgid "place header in path.license instead of path" #~ msgstr "Speichere Kopfzeilen in path.license anstatt path" #~ msgid "could not find Git" #~ msgstr "konnte Git nicht finden" reuse-tool-4.0.3/po/eo.po000066400000000000000000001140351464275211500152100ustar00rootroot00000000000000# SPDX-FileCopyrightText: 2018, 2020 Carmen Bianca Bakker # SPDX-FileCopyrightText: 2018 Tirifto # # SPDX-License-Identifier: GPL-3.0-or-later msgid "" msgstr "" "Project-Id-Version: unnamed project\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-07-03 13:09+0000\n" "PO-Revision-Date: 2024-01-17 12:48+0000\n" "Last-Translator: Carmen Bianca Bakker \n" "Language-Team: Esperanto \n" "Language: eo\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 5.4-dev\n" #: src/reuse/_annotate.py:74 #, python-brace-format msgid "" "'{path}' does not support single-line comments, please do not use --single-" "line" msgstr "" "'{path}' ne subtenas unuopliniajn komentojn, bonvolu ne uzi --single-line" #: src/reuse/_annotate.py:81 #, python-brace-format msgid "" "'{path}' does not support multi-line comments, please do not use --multi-line" msgstr "" "'{path}' ne subtenas plurliniajn komentojn, bonvolu ne uzi --multi-line" #: src/reuse/_annotate.py:136 #, fuzzy, python-brace-format msgid "Skipped unrecognised file '{path}'" msgstr "Preterpasis nekonatan dosieron {path}" #: src/reuse/_annotate.py:142 #, python-brace-format msgid "'{path}' is not recognised; creating '{path}.license'" msgstr "" #: src/reuse/_annotate.py:158 #, python-brace-format msgid "Skipped file '{path}' already containing REUSE information" msgstr "Preterpasis dosieron '{path}' kiu jam enhavas REUSE-informojn" #: src/reuse/_annotate.py:192 #, python-brace-format msgid "Error: Could not create comment for '{path}'" msgstr "Eraro: Ne povis krei komenton por '{path}'" #: src/reuse/_annotate.py:199 #, python-brace-format msgid "" "Error: Generated comment header for '{path}' is missing copyright lines or " "license expressions. The template is probably incorrect. Did not write new " "header." msgstr "" "Eraro: Al generita komentkapo por '{path}' mankas kopirajtlinioj aŭ " "permesilesprimoj. La ŝablono probable malbonas. Ne skribis novan kapon." #. TODO: This may need to be rephrased more elegantly. #: src/reuse/_annotate.py:210 #, python-brace-format msgid "Successfully changed header of {path}" msgstr "Sukcese ŝanĝis kapon de {path}" #: src/reuse/_annotate.py:221 #, fuzzy msgid "--skip-unrecognised has no effect when used together with --style" msgstr "--output faras nenion kiam --all ankaŭ uziĝas" #: src/reuse/_annotate.py:231 #, fuzzy msgid "option --contributor, --copyright or --license is required" msgstr "opcio --copyright aŭ --license necesas" #: src/reuse/_annotate.py:272 #, python-brace-format msgid "template {template} could not be found" msgstr "ŝablono {template} netroveblas" #: src/reuse/_annotate.py:341 src/reuse/_util.py:573 msgid "can't write to '{}'" msgstr "ne povas skribi al '{}'" #: src/reuse/_annotate.py:366 #, fuzzy msgid "" "The following files do not have a recognised file extension. Please use --" "style, --force-dot-license, --fallback-dot-license, or --skip-unrecognised:" msgstr "" "La sekvaj dosieroj ne havas konatan dosiersufikson. Bonvolu uzi --style, --" "force-dot-license aŭ --skip-unrecognised:" #: src/reuse/_annotate.py:382 msgid "copyright statement, repeatable" msgstr "kopirajtlinio, ripetabla" #: src/reuse/_annotate.py:389 msgid "SPDX Identifier, repeatable" msgstr "SPDX Identigilo, ripetabla" #: src/reuse/_annotate.py:395 #, fuzzy msgid "file contributor, repeatable" msgstr "SPDX Identigilo, ripetabla" #: src/reuse/_annotate.py:403 msgid "year of copyright statement, optional" msgstr "jaro de kopirajtlinio, malnepra" #: src/reuse/_annotate.py:411 msgid "comment style to use, optional" msgstr "uzenda komentstilo, malnepra" #: src/reuse/_annotate.py:417 #, fuzzy msgid "copyright prefix to use, optional" msgstr "uzenda komentstilo, malnepra" #: src/reuse/_annotate.py:430 msgid "name of template to use, optional" msgstr "nomo de uzenda ŝablono, malnepra" #: src/reuse/_annotate.py:435 msgid "do not include year in statement" msgstr "ne inkluzivi jaron en kopirajtlinio" #: src/reuse/_annotate.py:440 #, fuzzy msgid "merge copyright lines if copyright statements are identical" msgstr "jaro de kopirajtlinio, malnepra" #: src/reuse/_annotate.py:446 #, fuzzy msgid "force single-line comment style, optional" msgstr "uzenda komentstilo, malnepra" #: src/reuse/_annotate.py:451 #, fuzzy msgid "force multi-line comment style, optional" msgstr "uzenda komentstilo, malnepra" #: src/reuse/_annotate.py:458 msgid "add headers to all files under specified directories recursively" msgstr "" #: src/reuse/_annotate.py:465 msgid "do not replace the first header in the file; just add a new one" msgstr "" #: src/reuse/_annotate.py:473 msgid "always write a .license file instead of a header inside the file" msgstr "" #: src/reuse/_annotate.py:480 msgid "write a .license file to files with unrecognised comment styles" msgstr "" #: src/reuse/_annotate.py:486 msgid "skip files with unrecognised comment styles" msgstr "" #: src/reuse/_annotate.py:497 #, fuzzy msgid "skip files that already contain REUSE information" msgstr "Preterpasis dosieron '{path}' kiu jam enhavas REUSE-informojn" #: src/reuse/_annotate.py:532 #, python-brace-format msgid "'{path}' is a binary, therefore using '{new_path}' for the header" msgstr "'{path}' estas duuma, tiel uzante '{new_path}' por la kapo" #: src/reuse/_main.py:39 msgid "" "reuse is a tool for compliance with the REUSE recommendations. See for more information, and " "for the online documentation." msgstr "" "reuse estas ilo por konformiĝo al la rekomendoj de REUSE. Vidu por pli da informo, kaj por " "la reta dokumentado." #: src/reuse/_main.py:45 msgid "" "This version of reuse is compatible with version {} of the REUSE " "Specification." msgstr "Ĉi tiu versio de reuse kongruas al versio {} de la REUSE Specifo." #: src/reuse/_main.py:48 msgid "Support the FSFE's work:" msgstr "Subtenu la laboradon de FSFE:" #: src/reuse/_main.py:52 msgid "" "Donations are critical to our strength and autonomy. They enable us to " "continue working for Free Software wherever necessary. Please consider " "making a donation at ." msgstr "" "Donacoj estas gravegaj por niaj forto kaj aŭtonomeco. Ili ebligas nin " "daŭrigi laboradon por libera programaro, kie ajn tio necesas. Bonvolu " "pripensi fari donacon ĉe ." #: src/reuse/_main.py:75 msgid "enable debug statements" msgstr "ŝalti sencimigajn ordonojn" #: src/reuse/_main.py:80 msgid "hide deprecation warnings" msgstr "kaŝi avertojn de evitindaĵoj" #: src/reuse/_main.py:85 msgid "do not skip over Git submodules" msgstr "ne preterpasi Git-submodulojn" #: src/reuse/_main.py:90 #, fuzzy msgid "do not skip over Meson subprojects" msgstr "ne preterpasi Meson-subprojektojn" #: src/reuse/_main.py:95 msgid "do not use multiprocessing" msgstr "ne uzi plurprocesoradon" #: src/reuse/_main.py:102 msgid "define root of project" msgstr "difini radikon de la projekto" #: src/reuse/_main.py:107 msgid "show program's version number and exit" msgstr "montri versionumeron de programo kaj eliri" #: src/reuse/_main.py:111 msgid "subcommands" msgstr "subkomandoj" #: src/reuse/_main.py:118 msgid "add copyright and licensing into the header of files" msgstr "aldoni kopirajtajn kaj permesilajn informojn en la kapojn de dosieroj" #: src/reuse/_main.py:121 msgid "" "Add copyright and licensing into the header of one or more files.\n" "\n" "By using --copyright and --license, you can specify which copyright holders " "and licenses to add to the headers of the given files.\n" "\n" "By using --contributor, you can specify people or entity that contributed " "but are not copyright holder of the given files." msgstr "" #: src/reuse/_main.py:140 msgid "download a license and place it in the LICENSES/ directory" msgstr "elŝuti permesilon kaj meti ĝin en la LICENSES/-dosierujon" #: src/reuse/_main.py:142 #, fuzzy msgid "Download a license and place it in the LICENSES/ directory." msgstr "elŝuti permesilon kaj meti ĝin en la LICENSES/-dosierujon" #: src/reuse/_main.py:151 msgid "list all non-compliant files" msgstr "listigi ĉiujn nekonformajn dosierojn" #: src/reuse/_main.py:154 #, python-brace-format msgid "" "Lint the project directory for compliance with version {reuse_version} of " "the REUSE Specification. You can find the latest version of the " "specification at .\n" "\n" "Specifically, the following criteria are checked:\n" "\n" "- Are there any bad (unrecognised, not compliant with SPDX) licenses in the " "project?\n" "\n" "- Are any licenses referred to inside of the project, but not included in " "the LICENSES/ directory?\n" "\n" "- Are any licenses included in the LICENSES/ directory that are not used " "inside of the project?\n" "\n" "- Do all files have valid copyright and licensing information?" msgstr "" "Kontroli la projektdosierujon por konformiĝo je versio {reuse_version} de la " "REUSE Specifo. Vi povas trovi la lastan version de la specifo ĉe .\n" "\n" "Specife, oni kontrolas la sekvajn kriteriojn:\n" "\n" "- Ĉu estas malbonaj (nekonitaj, nekonformaj) permesiloj en la projekto?\n" "\n" "- Ĉu uziĝas permesiloj en la projekto, kiuj ne estas en la LICENSES/-" "dosierujo?\n" "\n" "- Ĉu estas permesiloj en la LICENSES/-dosierujo, kiuj estas neuzataj?\n" "\n" "- Ĉu ĉiuj dosieroj havas validajn kopirajtajn kaj permesilajn informojn?" #: src/reuse/_main.py:181 msgid "print the project's bill of materials in SPDX format" msgstr "presi la pecoliston de la projekto en SPDX-formo" #: src/reuse/_main.py:189 msgid "list all supported SPDX licenses" msgstr "listigi ĉiujn subtenitajn SPDX-permesilojn" #: src/reuse/_main.py:198 msgid "convert .reuse/dep5 to REUSE.toml" msgstr "" #: src/reuse/_main.py:263 #, fuzzy, python-brace-format msgid "'{path}' could not be decoded as UTF-8." msgstr "ne povis malkodi '{dep5}' kiel UTF-8." #: src/reuse/_main.py:269 #, python-brace-format msgid "" "'{path}' could not be parsed. We received the following error message: " "{message}" msgstr "" #: src/reuse/_util.py:368 src/reuse/global_licensing.py:218 #, python-brace-format msgid "Could not parse '{expression}'" msgstr "Ne povis analizi '{expression}'" #: src/reuse/_util.py:424 #, python-brace-format msgid "" "'{path}' holds an SPDX expression that cannot be parsed, skipping the file" msgstr "" "'{path}' entenas SPDX-esprimon, kiun oni ne povas analizi; preterpasante la " "dosieron" #: src/reuse/_util.py:556 msgid "'{}' is not a file" msgstr "'{}' ne estas dosiero" #: src/reuse/_util.py:559 msgid "'{}' is not a directory" msgstr "'{}' ne estas dosierujo" #: src/reuse/_util.py:562 msgid "can't open '{}'" msgstr "ne povas malfermi '{}'" #: src/reuse/_util.py:567 msgid "can't write to directory '{}'" msgstr "ne povas skribi al dosierujo '{}'" #: src/reuse/_util.py:586 msgid "can't read or write '{}'" msgstr "ne povas legi aŭ skribi '{}'" #: src/reuse/_util.py:596 msgid "'{}' is not a valid SPDX expression, aborting" msgstr "'{}' ne estas valida SPDX-esprimo. Ĉesigante" #: src/reuse/_util.py:624 msgid "'{}' is not a valid SPDX License Identifier." msgstr "'{}' ne estas valida SPDX Permesila Identigilo." #: src/reuse/_util.py:631 msgid "Did you mean:" msgstr "Ĉu vi intencis:" #: src/reuse/_util.py:638 msgid "" "See for a list of valid SPDX License " "Identifiers." msgstr "" "Vidu por listo de validaj SPDX Permesilaj " "Identigiloj." #: src/reuse/convert_dep5.py:118 #, fuzzy msgid "no '.reuse/dep5' file" msgstr "Krante .reuse/dep5" #: src/reuse/download.py:130 msgid "SPDX License Identifier of license" msgstr "SPDX Permesila Identigilo de permesilo" #: src/reuse/download.py:135 msgid "download all missing licenses detected in the project" msgstr "elŝuti ĉiujn mankantajn permesilojn kiujn oni eltrovis en la projekto" #: src/reuse/download.py:145 msgid "" "source from which to copy custom LicenseRef- licenses, either a directory " "that contains the file or the file itself" msgstr "" #: src/reuse/download.py:156 #, python-brace-format msgid "Error: {spdx_identifier} already exists." msgstr "Eraro: {spdx_identifier} jam ekzistas." #: src/reuse/download.py:163 #, fuzzy, python-brace-format msgid "Error: {path} does not exist." msgstr "'{path}' ne finiĝas per .spdx" #: src/reuse/download.py:166 msgid "Error: Failed to download license." msgstr "Eraro: Malsukcesis elŝuti permesilon." #: src/reuse/download.py:171 msgid "Is your internet connection working?" msgstr "Ĉu via retkonekto funkcias?" #: src/reuse/download.py:176 #, python-brace-format msgid "Successfully downloaded {spdx_identifier}." msgstr "Sukceses elŝutis {spdx_identifier}." #: src/reuse/download.py:188 msgid "--output has no effect when used together with --all" msgstr "--output faras nenion kiam --all ankaŭ uziĝas" #: src/reuse/download.py:192 msgid "the following arguments are required: license" msgstr "la sekvaj argumentoj nepras: license" #: src/reuse/download.py:194 msgid "cannot use --output with more than one license" msgstr "ne povas uzi --output kun pli ol unu permesilo" #: src/reuse/global_licensing.py:109 #, python-brace-format msgid "" "{attr_name} must be a {type_name} (got {value} that is a {value_class})." msgstr "" #: src/reuse/global_licensing.py:122 #, python-brace-format msgid "" "Item in {attr_name} collection must be a {type_name} (got {item_value} that " "is a {item_class})." msgstr "" #: src/reuse/global_licensing.py:133 #, python-brace-format msgid "{attr_name} must not be empty." msgstr "" #: src/reuse/global_licensing.py:156 #, python-brace-format msgid "{name} must be a {type} (got {value} that is a {value_type})." msgstr "" #: src/reuse/global_licensing.py:179 #, python-brace-format msgid "" "The value of 'precedence' must be one of {precedence_vals} (got {received})" msgstr "" #: src/reuse/header.py:99 msgid "generated comment is missing copyright lines or license expressions" msgstr "al generita komento mankas kopirajtlinioj aŭ permesilesprimoj" #: src/reuse/lint.py:30 msgid "prevents output" msgstr "" #: src/reuse/lint.py:33 msgid "formats output as JSON" msgstr "" #: src/reuse/lint.py:39 msgid "formats output as plain text" msgstr "" #: src/reuse/lint.py:45 msgid "formats output as errors per line" msgstr "" #: src/reuse/lint.py:64 msgid "BAD LICENSES" msgstr "MALBONAJ PERMESILOJ" #: src/reuse/lint.py:66 src/reuse/lint.py:95 msgid "'{}' found in:" msgstr "'{}' trovita en:" #: src/reuse/lint.py:73 msgid "DEPRECATED LICENSES" msgstr "ARĤAIKIGITAJ PERMESILOJ" #: src/reuse/lint.py:75 msgid "The following licenses are deprecated by SPDX:" msgstr "La sekvajn permesilojn arĥaikigis SPDX:" #: src/reuse/lint.py:83 msgid "LICENSES WITHOUT FILE EXTENSION" msgstr "PERMESILOJ SEN DOSIERSUFIKSO" #: src/reuse/lint.py:85 msgid "The following licenses have no file extension:" msgstr "La sekvaj permesiloj ne havas dosiersufikson:" #: src/reuse/lint.py:93 msgid "MISSING LICENSES" msgstr "MANKANTAJ PERMESILOJ" #: src/reuse/lint.py:102 msgid "UNUSED LICENSES" msgstr "NEUZATAJ PERMESILOJ" #: src/reuse/lint.py:103 msgid "The following licenses are not used:" msgstr "La sekvajn permesilojn oni ne uzas:" #: src/reuse/lint.py:110 msgid "READ ERRORS" msgstr "LEG-ERAROJ" #: src/reuse/lint.py:111 msgid "Could not read:" msgstr "Ne povis legi:" #: src/reuse/lint.py:132 msgid "MISSING COPYRIGHT AND LICENSING INFORMATION" msgstr "MANKANTAJ KOPIRAJTAJ KAJ PERMESILAJ INFORMOJ" #: src/reuse/lint.py:138 msgid "The following files have no copyright and licensing information:" msgstr "La sekvaj dosieroj ne havas kopirajtajn kaj permesilajn informojn:" #: src/reuse/lint.py:149 msgid "The following files have no copyright information:" msgstr "La sekvaj dosieroj ne havas kopirajtajn informojn:" #: src/reuse/lint.py:158 msgid "The following files have no licensing information:" msgstr "La sekvaj dosieroj ne havas permesilajn informojn:" #: src/reuse/lint.py:166 msgid "SUMMARY" msgstr "RESUMO" #: src/reuse/lint.py:171 msgid "Bad licenses:" msgstr "Malbonaj permesiloj:" #: src/reuse/lint.py:172 msgid "Deprecated licenses:" msgstr "Arĥaikigitaj permesiloj:" #: src/reuse/lint.py:173 msgid "Licenses without file extension:" msgstr "Permesiloj sen dosiersufikso:" #: src/reuse/lint.py:176 msgid "Missing licenses:" msgstr "Mankantaj permesiloj:" #: src/reuse/lint.py:177 msgid "Unused licenses:" msgstr "Neuzataj permesiloj:" #: src/reuse/lint.py:178 msgid "Used licenses:" msgstr "Uzataj permesiloj:" #: src/reuse/lint.py:179 #, fuzzy msgid "Read errors:" msgstr "Leg-eraroj: {count}" #: src/reuse/lint.py:181 #, fuzzy msgid "Files with copyright information:" msgstr "Dosieroj sen kopirajtinformo: {count} / {total}" #: src/reuse/lint.py:185 #, fuzzy msgid "Files with license information:" msgstr "Dosieroj sen permesilinformo: {count} / {total}" #: src/reuse/lint.py:202 msgid "" "Congratulations! Your project is compliant with version {} of the REUSE " "Specification :-)" msgstr "Gratulon! Via projekto konformas al versio {} de la REUSE Specifo :-)" #: src/reuse/lint.py:209 msgid "" "Unfortunately, your project is not compliant with version {} of the REUSE " "Specification :-(" msgstr "" "Bedaŭrinde, via projekto ne konformas al versio {} de la REUSE Specifo :-(" #: src/reuse/lint.py:216 msgid "RECOMMENDATIONS" msgstr "" #: src/reuse/lint.py:289 #, python-brace-format msgid "{path}: bad license {lic}\n" msgstr "" #: src/reuse/lint.py:296 #, fuzzy, python-brace-format msgid "{lic_path}: deprecated license\n" msgstr "Arĥaikigitaj permesiloj:" #: src/reuse/lint.py:303 #, fuzzy, python-brace-format msgid "{lic_path}: license without file extension\n" msgstr "Permesiloj sen dosiersufikso:" #: src/reuse/lint.py:312 #, fuzzy, python-brace-format msgid "{lic_path}: unused license\n" msgstr "Neuzataj permesiloj:" #: src/reuse/lint.py:319 #, python-brace-format msgid "{path}: missing license {lic}\n" msgstr "" #: src/reuse/lint.py:326 #, python-brace-format msgid "{path}: read error\n" msgstr "" #: src/reuse/lint.py:330 #, fuzzy, python-brace-format msgid "{path}: no license identifier\n" msgstr "'{}' ne estas valida SPDX Permesila Identigilo." #: src/reuse/lint.py:334 #, python-brace-format msgid "{path}: no copyright notice\n" msgstr "" #: src/reuse/project.py:262 #, fuzzy, python-brace-format msgid "'{path}' covered by {global_path}" msgstr "'{path}' sub .reuse/dep5" #: src/reuse/project.py:270 #, python-brace-format msgid "" "'{path}' is covered exclusively by REUSE.toml. Not reading the file contents." msgstr "" #: src/reuse/project.py:277 #, python-brace-format msgid "" "'{path}' was detected as a binary file; not searching its contents for REUSE " "information." msgstr "" #: src/reuse/project.py:334 msgid "" "'.reuse/dep5' is deprecated. You are recommended to instead use REUSE.toml. " "Use `reuse convert-dep5` to convert." msgstr "" #: src/reuse/project.py:348 #, python-brace-format msgid "" "Found both '{new_path}' and '{old_path}'. You cannot keep both files " "simultaneously; they are not intercompatible." msgstr "" #: src/reuse/project.py:414 #, python-brace-format msgid "determining identifier of '{path}'" msgstr "precizigante identigilon de '{path}'" #: src/reuse/project.py:422 #, python-brace-format msgid "{path} does not have a file extension" msgstr "{path} ne havas dosiersufikson" #: src/reuse/project.py:432 #, python-brace-format msgid "" "Could not resolve SPDX License Identifier of {path}, resolving to " "{identifier}. Make sure the license is in the license list found at or that it starts with 'LicenseRef-', and that it has a " "file extension." msgstr "" "Ne povis precizigi SPDX Permesila Identigilo de {path}, uzante {identifier}. " "Certigu ke la permesilo estas en la listo ĉe aŭ " "ke ĝi komencas per 'LicenseRef-' kaj havas dosiersufikson." #: src/reuse/project.py:444 #, python-brace-format msgid "" "{identifier} is the SPDX License Identifier of both {path} and {other_path}" msgstr "" "{identifier} estas la SPDX Permesila Identigilo de kaj {path} kaj " "{other_path}" #: src/reuse/project.py:483 msgid "" "project '{}' is not a VCS repository or required VCS software is not " "installed" msgstr "" #: src/reuse/report.py:310 #, python-brace-format msgid "Could not read '{path}'" msgstr "Ne povis legi '{path}'" #: src/reuse/report.py:317 #, python-brace-format msgid "Unexpected error occurred while parsing '{path}'" msgstr "Okazis neanticipita eraro dum analizado de '{path}'" #: src/reuse/report.py:438 msgid "" "Fix bad licenses: At least one license in the LICENSES directory and/or " "provided by 'SPDX-License-Identifier' tags is invalid. They are either not " "valid SPDX License Identifiers or do not start with 'LicenseRef-'. FAQ about " "custom licenses: https://reuse.software/faq/#custom-license" msgstr "" #: src/reuse/report.py:449 msgid "" "Fix deprecated licenses: At least one of the licenses in the LICENSES " "directory and/or provided by an 'SPDX-License-Identifier' tag or in '.reuse/" "dep5' has been deprecated by SPDX. The current list and their respective " "recommended new identifiers can be found here: " msgstr "" #: src/reuse/report.py:460 msgid "" "Fix licenses without file extension: At least one license text file in the " "'LICENSES' directory does not have a '.txt' file extension. Please rename " "the file(s) accordingly." msgstr "" #: src/reuse/report.py:469 msgid "" "Fix missing licenses: For at least one of the license identifiers provided " "by the 'SPDX-License-Identifier' tags, there is no corresponding license " "text file in the 'LICENSES' directory. For SPDX license identifiers, you can " "simply run 'reuse download --all' to get any missing ones. For custom " "licenses (starting with 'LicenseRef-'), you need to add these files yourself." msgstr "" #: src/reuse/report.py:481 msgid "" "Fix unused licenses: At least one of the license text files in 'LICENSES' is " "not referenced by any file, e.g. by an 'SPDX-License-Identifier' tag. Please " "make sure that you either tag the accordingly licensed files properly, or " "delete the unused license text if you are sure that no file or code snippet " "is licensed as such." msgstr "" #: src/reuse/report.py:492 msgid "" "Fix read errors: At least one of the files in your directory cannot be read " "by the tool. Please check the file permissions. You will find the affected " "files at the top of the output as part of the logged error messages." msgstr "" #: src/reuse/report.py:501 msgid "" "Fix missing copyright/licensing information: For one or more files, the tool " "cannot find copyright and/or licensing information. You typically do this by " "adding 'SPDX-FileCopyrightText' and 'SPDX-License-Identifier' tags to each " "file. The tutorial explains additional ways to do this: " msgstr "" #: src/reuse/spdx.py:32 msgid "" "populate the LicenseConcluded field; note that reuse cannot guarantee the " "field is accurate" msgstr "" #: src/reuse/spdx.py:39 msgid "name of the person signing off on the SPDX report" msgstr "" #: src/reuse/spdx.py:44 msgid "name of the organization signing off on the SPDX report" msgstr "" #: src/reuse/spdx.py:60 msgid "" "error: --creator-person=NAME or --creator-organization=NAME required when --" "add-license-concluded is provided" msgstr "" #: src/reuse/spdx.py:75 #, python-brace-format msgid "" "'{path}' does not match a common SPDX file pattern. Find the suggested " "naming conventions here: https://spdx.github.io/spdx-spec/conformance/#44-" "standard-data-format-requirements" msgstr "" #: /usr/lib/python3.10/argparse.py:308 msgid "usage: " msgstr "uzo: " #: /usr/lib/python3.10/argparse.py:880 msgid ".__call__() not defined" msgstr ".__call__() ne difiniĝas" #: /usr/lib/python3.10/argparse.py:1223 #, python-format msgid "unknown parser %(parser_name)r (choices: %(choices)s)" msgstr "nekonata analizilo %(parser_name)r (elektoj: %(choices)s)" #: /usr/lib/python3.10/argparse.py:1283 #, python-format msgid "argument \"-\" with mode %r" msgstr "argumento \"-\" kun moduso %r" #: /usr/lib/python3.10/argparse.py:1292 #, python-format msgid "can't open '%(filename)s': %(error)s" msgstr "ne povas malfermi '%(filename)s': %(error)s" #: /usr/lib/python3.10/argparse.py:1501 #, python-format msgid "cannot merge actions - two groups are named %r" msgstr "ne povas kunigi agojn - du grupoj nomiĝas %r" #: /usr/lib/python3.10/argparse.py:1539 msgid "'required' is an invalid argument for positionals" msgstr "'required' estas nevalida argumento por poziciaj" #: /usr/lib/python3.10/argparse.py:1561 #, python-format msgid "" "invalid option string %(option)r: must start with a character " "%(prefix_chars)r" msgstr "" "nevalida elektebla ĉeno %(option)r: devas komenciĝi per signo " "%(prefix_chars)r" #: /usr/lib/python3.10/argparse.py:1579 #, python-format msgid "dest= is required for options like %r" msgstr "dest= nepras por elektebloj kiel %r" #: /usr/lib/python3.10/argparse.py:1596 #, python-format msgid "invalid conflict_resolution value: %r" msgstr "nevalida valoro de conflict_resolution: %r" #: /usr/lib/python3.10/argparse.py:1614 #, python-format msgid "conflicting option string: %s" msgid_plural "conflicting option strings: %s" msgstr[0] "konfliktanta elektebla ĉeno: %s" msgstr[1] "konfliktantaj elekteblaj ĉenoj: %s" #: /usr/lib/python3.10/argparse.py:1680 msgid "mutually exclusive arguments must be optional" msgstr "reciproke ekskluzivaj argumentoj devas esti malnepraj" #: /usr/lib/python3.10/argparse.py:1748 msgid "positional arguments" msgstr "poziciaj argumentoj" #: /usr/lib/python3.10/argparse.py:1749 msgid "options" msgstr "" #: /usr/lib/python3.10/argparse.py:1764 msgid "show this help message and exit" msgstr "montri ĉi tiun helpmesaĝon kaj eliri" #: /usr/lib/python3.10/argparse.py:1795 msgid "cannot have multiple subparser arguments" msgstr "ne povas havi plurajn subanalizilajn argumentojn" #: /usr/lib/python3.10/argparse.py:1847 /usr/lib/python3.10/argparse.py:2362 #, python-format msgid "unrecognized arguments: %s" msgstr "nekonataj argumentoj: %s" #: /usr/lib/python3.10/argparse.py:1948 #, python-format msgid "not allowed with argument %s" msgstr "ne permesita kun argumento: %s" #: /usr/lib/python3.10/argparse.py:1998 /usr/lib/python3.10/argparse.py:2012 #, python-format msgid "ignored explicit argument %r" msgstr "malatentis malimplicitan argumenton %r" #: /usr/lib/python3.10/argparse.py:2119 #, python-format msgid "the following arguments are required: %s" msgstr "la sekvaj argumentoj nepras: %s" #: /usr/lib/python3.10/argparse.py:2134 #, python-format msgid "one of the arguments %s is required" msgstr "unu el la argumentoj %s nepras" #: /usr/lib/python3.10/argparse.py:2177 msgid "expected one argument" msgstr "anticipis unu argumenton" #: /usr/lib/python3.10/argparse.py:2178 msgid "expected at most one argument" msgstr "anticipis maksimume unu argumenton" #: /usr/lib/python3.10/argparse.py:2179 msgid "expected at least one argument" msgstr "anticipis minimume unu argumenton" #: /usr/lib/python3.10/argparse.py:2183 #, python-format msgid "expected %s argument" msgid_plural "expected %s arguments" msgstr[0] "anticipis %s argumenton" msgstr[1] "anticipis %s argumentojn" #: /usr/lib/python3.10/argparse.py:2241 #, python-format msgid "ambiguous option: %(option)s could match %(matches)s" msgstr "dubsenca elekteblo: %(option)s povus egali al %(matches)s" #: /usr/lib/python3.10/argparse.py:2305 #, python-format msgid "unexpected option string: %s" msgstr "neanticipita elektebla ĉeno: %s" #: /usr/lib/python3.10/argparse.py:2502 #, python-format msgid "%r is not callable" msgstr "%r ne alvokeblas" #: /usr/lib/python3.10/argparse.py:2519 #, python-format msgid "invalid %(type)s value: %(value)r" msgstr "nevalida %(type)s-valoro: %(value)r" #: /usr/lib/python3.10/argparse.py:2530 #, python-format msgid "invalid choice: %(value)r (choose from %(choices)s)" msgstr "nevalida elekto: %(value)r (elektu el %(choices)s)" #: /usr/lib/python3.10/argparse.py:2606 #, python-format msgid "%(prog)s: error: %(message)s\n" msgstr "%(prog)s: eraro: %(message)s\n" #~ msgid "initialize REUSE project" #~ msgstr "pravalorizi REUSE-projekton" #~ msgid "no '{}' file, or could not read it" #~ msgstr "neniu dosiero '{}' aŭ ne povis legi ĝin" #, fuzzy #~ msgid "" #~ "What license is your project under? Provide the SPDX License Identifier. " #~ "See for the list." #~ msgstr "" #~ "Sub kiu permesilo estas via projekto? Provizu la SPDX Permesilan " #~ "Identigilon." #~ msgid "" #~ "What other license is your project under? Provide the SPDX License " #~ "Identifier." #~ msgstr "" #~ "Sub kiuj aliaj permesiloj estas via projekto? Provizu la SPDX Permesilan " #~ "Identigilon." #~ msgid "To stop adding licenses, hit RETURN." #~ msgstr "Por ĉesigi aldonadon de permesiloj, premu la enigan klavon." #~ msgid "Project already initialized" #~ msgstr "Projekto jam pravalorizita" #~ msgid "Initializing project for REUSE." #~ msgstr "Pravalorizante projekton por REUSE." #~ msgid "What is the name of the project?" #~ msgstr "Kiu estas la nomo de la projekto?" #~ msgid "What is the internet address of the project?" #~ msgstr "Kiu estas la reta adreso de la projekto?" #~ msgid "What is the name of the maintainer?" #~ msgstr "Kiu estas la nomo de la daŭriganto?" #~ msgid "What is the e-mail address of the maintainer?" #~ msgstr "Kiu estas la retpoŝtadreso de la daŭriganto?" #~ msgid "All done! Initializing now." #~ msgstr "Tute farita! Pravalorizante nun." #~ msgid "{} already exists" #~ msgstr "{} jam ekzistas" #~ msgid "Could not download {}" #~ msgstr "Ne povis elŝuti {}" #~ msgid "Initialization complete." #~ msgstr "Finfaris pravalorizadon." #, fuzzy #~ msgid "" #~ "Add copyright and licensing into the header of one or more files.\n" #~ "\n" #~ "By using --copyright and --license, you can specify which copyright " #~ "holders and licenses to add to the headers of the given files.\n" #~ "\n" #~ "By using --contributor, you can specify people or entity that contributed " #~ "but are not copyright holder of the given files.\n" #~ "The first comment is replaced with a new header containing the new " #~ "copyright and licensing information and its former copyright and " #~ "licensing. If you want to keep the first comment intact, use --no-" #~ "replace.\n" #~ "\n" #~ "The comment style should be auto-detected for your files. If a comment " #~ "style could not be detected and --skip-unrecognised is not specified, the " #~ "process aborts. Use --style to specify or override the comment style to " #~ "use.\n" #~ "\n" #~ "A single-line comment style is used when it is available. If no single-" #~ "line comment style is available, a multi-line comment style is used. You " #~ "can force a certain comment style using --single-line or --multi-line.\n" #~ "\n" #~ "You can change the template of the header comment by using --template. " #~ "Place a Jinja2 template in .reuse/templates/mytemplate.jinja2. You can " #~ "use the template by specifying '--template mytemplate'. Read the online " #~ "documentation on how to use this feature.\n" #~ "\n" #~ "If a binary file is detected, or if --force-dot-license is specified, the " #~ "header is placed in a .license file." #~ msgstr "" #~ "Aldoni kopirajtahn kaj permesilajn informojn en la kapojn de dosieroj.\n" #~ "\n" #~ "Tra uzi --copyright kaj --license, vi povas specifi kiujn kopirajtajn " #~ "proprulojn kaj permesilojn oni aldonu al la kapojn de la specifitaj " #~ "dosieroj.\n" #~ "\n" #~ "Oni aŭtomate eltrovos la komentstilon de viaj dosieroj. Se oni ne povas " #~ "eltrovi tion, la procezo haltas. Uzu --style por specifi aŭ superskribi " #~ "la uzendan komentstilon.\n" #~ "\n" #~ "Vi povas ŝanĝi la ŝablonon de la kapo tra uzi --template. Metu Jinja2-" #~ "ŝablonon en .reuse/templates/miaŝablono.jinja2. Vi povas uzi la ŝablonon " #~ "tra specifi '--template miaŝablono'. Legu la reta dokumentado por pli da " #~ "informoj pri ĉi tiu funkcio.\n" #~ "\n" #~ "Se oni detektas duuman dosieron, aŭ se vi specifas --explicit-license, la " #~ "kapon oni metas en .license-dosieron.\n" #~ "\n" #~ "GRAVA: Ĉi tio estas ĉimomente PROVCELA!" #~ msgid "" #~ "Download a license and place it in the LICENSES/ directory.\n" #~ "\n" #~ "The LICENSES/ directory is automatically found in the following order:\n" #~ "\n" #~ "- The LICENSES/ directory in the root of the VCS repository.\n" #~ "\n" #~ "- The current directory if its name is LICENSES.\n" #~ "\n" #~ "- The LICENSES/ directory in the current directory.\n" #~ "\n" #~ "If the LICENSES/ directory cannot be found, one is simply created." #~ msgstr "" #~ "Elŝuti permesilon kaj meti ĝin en la LICENSES/-dosierujon.\n" #~ "\n" #~ "La LICENSES-dosierujon oni aŭtomate trovas tiel, en ordo:\n" #~ "\n" #~ "- La LICENSES/-dosierujo en la radiko de la VCS-deponejo.\n" #~ "\n" #~ "- La aktuala dosierujo se ĝia nomo ests LICENSES.\n" #~ "\n" #~ "- La LICENSES/-dosierujo sub la aktuala dosierujo.\n" #~ "\n" #~ "Se oni ne povas trovi la LICENSES/-dosierujon, oni kreos ĝin." #~ msgid ".reuse/dep5 has syntax errors" #~ msgstr ".reuse/dep5 havas sintaksajn erarojn" #~ msgid "optional arguments" #~ msgstr "malnepraj argumentoj" #~ msgid "deprecated in favor of annotate" #~ msgstr "evitindigita favore al annotate" #~ msgid "option --exclude-year and --year are mutually exclusive" #~ msgstr "opcio --exclude-year kaj --year ekskluzivas unu la alian" #, fuzzy #~ msgid "option --single-line and --multi-line are mutually exclusive" #~ msgstr "opcio --exclude-year kaj --year ekskluzivas unu la alian" #~ msgid "Downloading {}" #~ msgstr "Elŝutante {}" #, fuzzy #~ msgid "conflicting subparser: %s" #~ msgstr "konfliktanta elektebla ĉeno: %s" #, fuzzy #~ msgid "conflicting subparser alias: %s" #~ msgstr "konfliktanta elektebla ĉeno: %s" #~ msgid "can't open '%s': %s" #~ msgstr "ne povas malfermi '%s': %s" #~ msgid "place header in path.license instead of path" #~ msgstr "meti kapon en path.license anstataŭ path" #~ msgid "could not find Git" #~ msgstr "ne povis trovi programaron Git" #~ msgid "yielding %s" #~ msgstr "traktante %s" #~ msgid "currently walking in %s" #~ msgstr "ĉimomente irante en %s" #~ msgid "ignoring %s" #~ msgstr "ignoras %s" #~ msgid "searching %s for reuse information" #~ msgstr "serĉanta en %s por reuse-informoj" #~ msgid "" #~ "{path} is licensed under {identifier}, but its license file could not be " #~ "found" #~ msgstr "{path} subas permesilon {identifier}, sed ties dosiero mankas" #~ msgid "searching %s for license tags" #~ msgstr "serĉante permesiletikedojn en %s" #~ msgid "" #~ "Could not resolve SPDX identifier of {path}, resolving to {identifier}" #~ msgstr "Ne povis determini SPD-identigilo de {path}, do uziĝas {identifier}" #~ msgid "reuse Copyright (C) 2017-2018 Free Software Foundation Europe e.V." #~ msgstr "" #~ "reuse Kopirajto (C) 2017-2018 Free Software Foundation Europe e.V." #~ msgid "" #~ "reuse is free software: you can redistribute it and/or modify it under " #~ "the terms of the GNU General Public License as published by the Free " #~ "Software Foundation, either version 3 of the License, or (at your option) " #~ "any later version.\n" #~ "\n" #~ "reuse is distributed in the hope that it will be useful, but WITHOUT ANY " #~ "WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS " #~ "FOR A PARTICULAR PURPOSE. See the GNU General Public License for more " #~ "details.\n" #~ "\n" #~ "You should have received a copy of the GNU General Public License along " #~ "with reuse. If not, see ." #~ msgstr "" #~ "reuse estas libera programaro: vi povas ĝin pludistribui kaj/aŭ modifi je " #~ "la kondiĉoj de la GNU Ĝenerala Pubika Permesilo, eldonita de la Free " #~ "Software Foundation, laŭ la versio 3 de la permesilo, aŭ (se vi " #~ "preferas) ajna posta versio.\n" #~ "\n" #~ "Ni distribuas reuse esperante, ke ĝi estos utila, tamen SEN IA AJN " #~ "GARANTIO, i.a. sen la implica garantio pri SURMERKATIGEBLO aŭ TAŬGECO POR " #~ "IU KONKRETA CELO. Pliajn detalojn vidu en la GNU Ĝenerala Publika " #~ "Permesilo.\n" #~ "\n" #~ "Ekzemplaro de la GNU Ĝenerala Publika Permesilo devas esti liverita al vi " #~ "kun reuse. Se ne, vidu ." #~ msgid "IMPORTANT:" #~ msgstr "GRAVA:" #~ msgid "" #~ "You do not have pygit2 installed. reuse will slow down significantly " #~ "because of this. For better performance, please install your " #~ "distribution's version of pygit2." #~ msgstr "" #~ "Vi ne jam instalis pygit2. reuse malrapidiĝas ege pro ĉi tio. Por akiri " #~ "pli bonan rendimenton, bonvolu instali version de pygit2 de via distribuo." #~ msgid "could not read %s" #~ msgstr "ne povis legi dosieron %s" #~ msgid "none\n" #~ msgstr "neniu\n" #~ msgid "do not use debian/copyright to extract reuse information" #~ msgstr "ne uzi debian/copyright por eltiri reuse-informon" #~ msgid "" #~ "List all non-compliant files.\n" #~ "\n" #~ "A file is non-compliant when:\n" #~ "\n" #~ "- It has no copyright information.\n" #~ "\n" #~ "- It has no license (declared as SPDX expression).\n" #~ "\n" #~ "- Its license could not be found.\n" #~ "\n" #~ "This prints only the paths of the files that do not comply, each file on " #~ "a separate line.\n" #~ "\n" #~ "Error and warning messages are output to STDERR." #~ msgstr "" #~ "Listigi ĉiujn nekonformajn dosierojn.\n" #~ "\n" #~ "Dosiero nekonformas kiam:\n" #~ "\n" #~ "- Ĝi havas neniun kopirajtinformon.\n" #~ "\n" #~ "- Ĝi havas neniun permesilon (deklaritan kiel SPDX-esprimo).\n" #~ "\n" #~ "- Ĝia permesilo ne troveblas.\n" #~ "\n" #~ "Ĉi tiu komando presas nur la dosierindikojn, kiuj ne konformas. Ĉiu " #~ "dosiero estas presata sur propra linio.\n" #~ "\n" #~ "Eraraj kaj avertaj mesaĝoj estas presotaj al STDERR." #~ msgid "SPDX expressions are mandatory for compliance" #~ msgstr "SPDX-esprimoj nepras por konformiĝo" #~ msgid "copyright notices are mandatory for compliance" #~ msgstr "kopirajtafiŝoj nepras por konformiĝo" #~ msgid "print the SPDX expressions of each provided file" #~ msgstr "presi la SPDX-esprimon de ĉiu donita dosiero" #~ msgid "reuse, version {}\n" #~ msgstr "reuse, versio {}\n" reuse-tool-4.0.3/po/es.po000066400000000000000000001337761464275211500152310ustar00rootroot00000000000000# SPDX-FileCopyrightText: 2018 pd # SPDX-FileCopyrightText: 2018 flow # SPDX-FileCopyrightText: 2020 Roberto Bauglir # # SPDX-License-Identifier: GPL-3.0-or-later msgid "" msgstr "" "Project-Id-Version: FSFE reuse\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-07-03 13:09+0000\n" "PO-Revision-Date: 2024-05-09 08:19+0000\n" "Last-Translator: gallegonovato \n" "Language-Team: Spanish \n" "Language: es\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 5.5.4-rc\n" #: src/reuse/_annotate.py:74 #, python-brace-format msgid "" "'{path}' does not support single-line comments, please do not use --single-" "line" msgstr "" "'{path}' no admite comentarios de una sola línea, no utilices --single-line" #: src/reuse/_annotate.py:81 #, python-brace-format msgid "" "'{path}' does not support multi-line comments, please do not use --multi-line" msgstr "'{path}' no admite comentarios multilínea, no utilices --multi-line" #: src/reuse/_annotate.py:136 #, python-brace-format msgid "Skipped unrecognised file '{path}'" msgstr "Se ha omitido el archivo no reconocido de '{path}'" #: src/reuse/_annotate.py:142 #, python-brace-format msgid "'{path}' is not recognised; creating '{path}.license'" msgstr "'{path}' no se reconoce; creando '{path}.license'" #: src/reuse/_annotate.py:158 #, python-brace-format msgid "Skipped file '{path}' already containing REUSE information" msgstr "Se ha omitido el archivo '{path}' que ya contiene información REUSE" #: src/reuse/_annotate.py:192 #, python-brace-format msgid "Error: Could not create comment for '{path}'" msgstr "Error: No se pudo crear un comentario para '{path}'" #: src/reuse/_annotate.py:199 #, python-brace-format msgid "" "Error: Generated comment header for '{path}' is missing copyright lines or " "license expressions. The template is probably incorrect. Did not write new " "header." msgstr "" "Error: La cabecera de comentario generada para '{path}' carece del mensaje " "de copyright o de las frases de licencia; la plantilla seguramente es " "incorrecta. No se ha escrito una nueva cabecera." #. TODO: This may need to be rephrased more elegantly. #: src/reuse/_annotate.py:210 #, python-brace-format msgid "Successfully changed header of {path}" msgstr "Cabecera de {path} correctamente cambiada" #: src/reuse/_annotate.py:221 msgid "--skip-unrecognised has no effect when used together with --style" msgstr "" "--skip-unrecognised no tiene efecto cuando se utiliza junto con --style" #: src/reuse/_annotate.py:231 msgid "option --contributor, --copyright or --license is required" msgstr "se requiere la opción --contributor, --copyright o --license" #: src/reuse/_annotate.py:272 #, python-brace-format msgid "template {template} could not be found" msgstr "no pudo encontrarse la plantilla {template}" #: src/reuse/_annotate.py:341 src/reuse/_util.py:573 msgid "can't write to '{}'" msgstr "no se puede escribir en '{}'" #: src/reuse/_annotate.py:366 #, fuzzy msgid "" "The following files do not have a recognised file extension. Please use --" "style, --force-dot-license, --fallback-dot-license, or --skip-unrecognised:" msgstr "" "Los siguientes archivos no tienen una extensión reconocida. Utiliza --style, " "--force-dot-license o --skip-unrecognised:" #: src/reuse/_annotate.py:382 msgid "copyright statement, repeatable" msgstr "declaración de los derechos de autor, repetible" #: src/reuse/_annotate.py:389 msgid "SPDX Identifier, repeatable" msgstr "Identificador SPDX, repetible" #: src/reuse/_annotate.py:395 msgid "file contributor, repeatable" msgstr "colaborador de archivos, repetible" #: src/reuse/_annotate.py:403 msgid "year of copyright statement, optional" msgstr "año de la declaración de copyright; opcional" #: src/reuse/_annotate.py:411 msgid "comment style to use, optional" msgstr "estilo de comentario a utilizar; opcional" #: src/reuse/_annotate.py:417 #, fuzzy msgid "copyright prefix to use, optional" msgstr "estilo del copyright a utilizar, opcional" #: src/reuse/_annotate.py:430 msgid "name of template to use, optional" msgstr "nombre de la plantilla a utilizar; opcional" #: src/reuse/_annotate.py:435 msgid "do not include year in statement" msgstr "no incluir el año en la declaración" #: src/reuse/_annotate.py:440 msgid "merge copyright lines if copyright statements are identical" msgstr "" "fusionar las líneas del copyright si las declaraciones del copyright son " "idénticas" #: src/reuse/_annotate.py:446 msgid "force single-line comment style, optional" msgstr "forzar el estilo del comentario de una sola línea, opcional" #: src/reuse/_annotate.py:451 msgid "force multi-line comment style, optional" msgstr "forzar el estilo del comentario multilínea, opcional" #: src/reuse/_annotate.py:458 msgid "add headers to all files under specified directories recursively" msgstr "" "añadir las cabeceras a todos los archivos de los directorios especificados " "de forma recursiva" #: src/reuse/_annotate.py:465 msgid "do not replace the first header in the file; just add a new one" msgstr "no sustituyas la primera cabecera del archivo; añade una nueva" #: src/reuse/_annotate.py:473 #, fuzzy msgid "always write a .license file instead of a header inside the file" msgstr "" "escribir un archivo .license en lugar de una cabecera dentro del archivo" #: src/reuse/_annotate.py:480 #, fuzzy msgid "write a .license file to files with unrecognised comment styles" msgstr "omitir los archivos con estilos de comentario no reconocidos" #: src/reuse/_annotate.py:486 msgid "skip files with unrecognised comment styles" msgstr "omitir los archivos con estilos de comentario no reconocidos" #: src/reuse/_annotate.py:497 msgid "skip files that already contain REUSE information" msgstr "omitir los archivos que ya contienen la información REUSE" #: src/reuse/_annotate.py:532 #, python-brace-format msgid "'{path}' is a binary, therefore using '{new_path}' for the header" msgstr "" "'{path}' es un fichero binario: en consecuencia, se utiliza '{new_path}' " "para la cabecera" #: src/reuse/_main.py:39 msgid "" "reuse is a tool for compliance with the REUSE recommendations. See for more information, and " "for the online documentation." msgstr "" "reuse es una herramienta para cumplir con las recomendaciones de la " "iniciativa REUSE. Visita para obtener más " "información, y para acceder a la " "documentación en línea." #: src/reuse/_main.py:45 msgid "" "This version of reuse is compatible with version {} of the REUSE " "Specification." msgstr "" "Esta versión de reuse es compatible con la versión {} de la Especificación " "REUSE." #: src/reuse/_main.py:48 msgid "Support the FSFE's work:" msgstr "Apoya el trabajo de la FSFE:" #: src/reuse/_main.py:52 msgid "" "Donations are critical to our strength and autonomy. They enable us to " "continue working for Free Software wherever necessary. Please consider " "making a donation at ." msgstr "" "Las donaciones son esenciales para nuestra fortaleza y autonomía. Estas nos " "permiten continuar trabajando por el Software Libre allá donde sea " "necesario. Por favor, considera el hacer una donación en ." #: src/reuse/_main.py:75 msgid "enable debug statements" msgstr "habilita instrucciones de depuración" #: src/reuse/_main.py:80 msgid "hide deprecation warnings" msgstr "ocultar las advertencias de que está obsoleto" #: src/reuse/_main.py:85 msgid "do not skip over Git submodules" msgstr "no omitas los submódulos de Git" #: src/reuse/_main.py:90 msgid "do not skip over Meson subprojects" msgstr "no te saltes los subproyectos de Meson" #: src/reuse/_main.py:95 msgid "do not use multiprocessing" msgstr "no utilices multiproceso" #: src/reuse/_main.py:102 msgid "define root of project" msgstr "define el origen del proyecto" #: src/reuse/_main.py:107 msgid "show program's version number and exit" msgstr "muestra la versión del programa y sale" #: src/reuse/_main.py:111 msgid "subcommands" msgstr "subcomandos" #: src/reuse/_main.py:118 msgid "add copyright and licensing into the header of files" msgstr "agrega el copyright y la licencia a la cabecera de los ficheros" #: src/reuse/_main.py:121 msgid "" "Add copyright and licensing into the header of one or more files.\n" "\n" "By using --copyright and --license, you can specify which copyright holders " "and licenses to add to the headers of the given files.\n" "\n" "By using --contributor, you can specify people or entity that contributed " "but are not copyright holder of the given files." msgstr "" #: src/reuse/_main.py:140 msgid "download a license and place it in the LICENSES/ directory" msgstr "descarga una licencia y guárdala en el directorio \"LICENSES/\"" #: src/reuse/_main.py:142 #, fuzzy msgid "Download a license and place it in the LICENSES/ directory." msgstr "descarga una licencia y guárdala en el directorio \"LICENSES/\"" #: src/reuse/_main.py:151 msgid "list all non-compliant files" msgstr "lista todos los ficheros no compatibles" #: src/reuse/_main.py:154 #, python-brace-format msgid "" "Lint the project directory for compliance with version {reuse_version} of " "the REUSE Specification. You can find the latest version of the " "specification at .\n" "\n" "Specifically, the following criteria are checked:\n" "\n" "- Are there any bad (unrecognised, not compliant with SPDX) licenses in the " "project?\n" "\n" "- Are any licenses referred to inside of the project, but not included in " "the LICENSES/ directory?\n" "\n" "- Are any licenses included in the LICENSES/ directory that are not used " "inside of the project?\n" "\n" "- Do all files have valid copyright and licensing information?" msgstr "" "Examina el directorio del proyecto para comprobar su conformidad con la " "versión {reuse_version} de la Especificación REUSE. Puedes encontrar la " "última versión de la especificación en \n" "\n" "Los siguientes criterios son específicamente chequeados:\n" "\n" "- ¿Hay alguna licencia mala (no reconocida, no compatible con SPDX...) en el " "proyecto?\n" "\n" "- ¿Se hace referencia a alguna licencia dentro del proyecto, pero esta no se " "encuentra incluida en el directorio LICENSES/?\n" "\n" "- ¿Existe alguna licencia, de las incluidas en el directorio LICENSES/, que " "no esté en uso en el proyecto?\n" "\n" "- ¿Tienen todos los ficheros información válida sobre copyright y licencia?" #: src/reuse/_main.py:181 msgid "print the project's bill of materials in SPDX format" msgstr "imprime la lista de materiales del proyecto en formato SPDX" #: src/reuse/_main.py:189 msgid "list all supported SPDX licenses" msgstr "Lista de todas las licencias SPDX compatibles" #: src/reuse/_main.py:198 msgid "convert .reuse/dep5 to REUSE.toml" msgstr "" #: src/reuse/_main.py:263 #, fuzzy, python-brace-format msgid "'{path}' could not be decoded as UTF-8." msgstr "'{dep5}' no pudo ser decodificado como UTF-8." #: src/reuse/_main.py:269 #, fuzzy, python-brace-format msgid "" "'{path}' could not be parsed. We received the following error message: " "{message}" msgstr "" "{dep5}' no pudo ser analizado. Recibimos el siguiente mensaje de error: " "{message}" #: src/reuse/_util.py:368 src/reuse/global_licensing.py:218 #, python-brace-format msgid "Could not parse '{expression}'" msgstr "No se pudo procesar '{expression}'" #: src/reuse/_util.py:424 #, python-brace-format msgid "" "'{path}' holds an SPDX expression that cannot be parsed, skipping the file" msgstr "" "'{path}' posee una expresión SPDX que no puede ser procesada; omitiendo el " "archivo" #: src/reuse/_util.py:556 msgid "'{}' is not a file" msgstr "'{}' no es un fichero" #: src/reuse/_util.py:559 msgid "'{}' is not a directory" msgstr "'{}' no es un directorio" #: src/reuse/_util.py:562 msgid "can't open '{}'" msgstr "no se puede abrir '{}'" #: src/reuse/_util.py:567 msgid "can't write to directory '{}'" msgstr "no se pude escribir en el directorio '{}'" #: src/reuse/_util.py:586 msgid "can't read or write '{}'" msgstr "no se puede leer o escribir '{}'" #: src/reuse/_util.py:596 msgid "'{}' is not a valid SPDX expression, aborting" msgstr "'{}' no es una expresión SPDX válida; abortando" #: src/reuse/_util.py:624 msgid "'{}' is not a valid SPDX License Identifier." msgstr "'{}' no es un Identificador SPDX de Licencia válido." #: src/reuse/_util.py:631 msgid "Did you mean:" msgstr "Querías decir:" #: src/reuse/_util.py:638 msgid "" "See for a list of valid SPDX License " "Identifiers." msgstr "" "Consulta para obtener un listado de los " "Identificadores SPDX de Licencia válidos." #: src/reuse/convert_dep5.py:118 #, fuzzy msgid "no '.reuse/dep5' file" msgstr "Creando .reuse/dep5" #: src/reuse/download.py:130 msgid "SPDX License Identifier of license" msgstr "Identificador SPDX de la licencia" #: src/reuse/download.py:135 msgid "download all missing licenses detected in the project" msgstr "descargar todas las licencias no disponibles detectadas en el proyecto" #: src/reuse/download.py:145 msgid "" "source from which to copy custom LicenseRef- licenses, either a directory " "that contains the file or the file itself" msgstr "" "fuente desde la que copiar las licencias LicenseRef- personalizadas, ya sea " "un directorio que contenga el archivo o el propio archivo" #: src/reuse/download.py:156 #, python-brace-format msgid "Error: {spdx_identifier} already exists." msgstr "Error: {spdx_identifier} ya existe." #: src/reuse/download.py:163 #, python-brace-format msgid "Error: {path} does not exist." msgstr "Error: {path} no existe." #: src/reuse/download.py:166 msgid "Error: Failed to download license." msgstr "Error: Fallo al descargar la licencia." #: src/reuse/download.py:171 msgid "Is your internet connection working?" msgstr "¿Está funcionando tu conexión a Internet?" #: src/reuse/download.py:176 #, python-brace-format msgid "Successfully downloaded {spdx_identifier}." msgstr "{spdx_identifier} descargado con éxito." #: src/reuse/download.py:188 msgid "--output has no effect when used together with --all" msgstr "--output no tiene efecto cuando se utiliza junto con --all" #: src/reuse/download.py:192 msgid "the following arguments are required: license" msgstr "se requieren los siguientes parámetros: license" #: src/reuse/download.py:194 msgid "cannot use --output with more than one license" msgstr "no se puede utilizar --output con más de una licencia" #: src/reuse/global_licensing.py:109 #, python-brace-format msgid "" "{attr_name} must be a {type_name} (got {value} that is a {value_class})." msgstr "" #: src/reuse/global_licensing.py:122 #, python-brace-format msgid "" "Item in {attr_name} collection must be a {type_name} (got {item_value} that " "is a {item_class})." msgstr "" #: src/reuse/global_licensing.py:133 #, python-brace-format msgid "{attr_name} must not be empty." msgstr "" #: src/reuse/global_licensing.py:156 #, python-brace-format msgid "{name} must be a {type} (got {value} that is a {value_type})." msgstr "" #: src/reuse/global_licensing.py:179 #, python-brace-format msgid "" "The value of 'precedence' must be one of {precedence_vals} (got {received})" msgstr "" #: src/reuse/header.py:99 msgid "generated comment is missing copyright lines or license expressions" msgstr "" "el comentario generado carece del mensaje de copyright o de las frases de " "licencia" #: src/reuse/lint.py:30 msgid "prevents output" msgstr "impide la producción" #: src/reuse/lint.py:33 msgid "formats output as JSON" msgstr "formato de salida JSON" #: src/reuse/lint.py:39 msgid "formats output as plain text" msgstr "formatea la salida como un texto plano" #: src/reuse/lint.py:45 #, fuzzy msgid "formats output as errors per line" msgstr "formatea la salida como un texto plano" #: src/reuse/lint.py:64 msgid "BAD LICENSES" msgstr "LICENCIAS MALAS" #: src/reuse/lint.py:66 src/reuse/lint.py:95 msgid "'{}' found in:" msgstr "'{}' encontrado en:" #: src/reuse/lint.py:73 msgid "DEPRECATED LICENSES" msgstr "LICENCIAS OBSOLETAS" #: src/reuse/lint.py:75 msgid "The following licenses are deprecated by SPDX:" msgstr "Las siguientes licencias han quedado obsoletas según SPDX:" #: src/reuse/lint.py:83 msgid "LICENSES WITHOUT FILE EXTENSION" msgstr "LICENCIAS SIN EXTENSIÓN DE FICHERO" #: src/reuse/lint.py:85 msgid "The following licenses have no file extension:" msgstr "Las siguientes licencias no tienen extensión de fichero:" #: src/reuse/lint.py:93 msgid "MISSING LICENSES" msgstr "LICENCIAS NO ENCONTRADAS" #: src/reuse/lint.py:102 msgid "UNUSED LICENSES" msgstr "LICENCIAS NO UTILIZADAS" #: src/reuse/lint.py:103 msgid "The following licenses are not used:" msgstr "Las siguientes licencias no son utilizadas:" #: src/reuse/lint.py:110 msgid "READ ERRORS" msgstr "ERRORES DE LECTURA" #: src/reuse/lint.py:111 msgid "Could not read:" msgstr "No se pudo leer:" #: src/reuse/lint.py:132 msgid "MISSING COPYRIGHT AND LICENSING INFORMATION" msgstr "FALTA INFORMACIÓN SOBRE COPYRIGHT Y LICENCIA" #: src/reuse/lint.py:138 msgid "The following files have no copyright and licensing information:" msgstr "" "Los siguientes archivos carecen de información de copyright y licencia:" #: src/reuse/lint.py:149 msgid "The following files have no copyright information:" msgstr "Los siguientes ficheros carecen de información de copyright:" #: src/reuse/lint.py:158 msgid "The following files have no licensing information:" msgstr "Los siguientes ficheros carecen de información de licencia:" #: src/reuse/lint.py:166 msgid "SUMMARY" msgstr "RESUMEN" #: src/reuse/lint.py:171 msgid "Bad licenses:" msgstr "Licencias malas:" #: src/reuse/lint.py:172 msgid "Deprecated licenses:" msgstr "Licencias obsoletas:" #: src/reuse/lint.py:173 msgid "Licenses without file extension:" msgstr "Licencias sin extensión de fichero:" #: src/reuse/lint.py:176 msgid "Missing licenses:" msgstr "Licencias no encontradas:" #: src/reuse/lint.py:177 msgid "Unused licenses:" msgstr "Licencias no utilizadas:" #: src/reuse/lint.py:178 msgid "Used licenses:" msgstr "Licencias utilizadas:" #: src/reuse/lint.py:179 msgid "Read errors:" msgstr "Errores de lectura:" #: src/reuse/lint.py:181 #, fuzzy msgid "Files with copyright information:" msgstr "archivos con información sobre los derechos de autor:" #: src/reuse/lint.py:185 #, fuzzy msgid "Files with license information:" msgstr "con información sobre las licencias:" #: src/reuse/lint.py:202 msgid "" "Congratulations! Your project is compliant with version {} of the REUSE " "Specification :-)" msgstr "" "¡Enhorabuena! Tu proyecto es compatible con la versión {} de la " "Especificación REUSE :-)" #: src/reuse/lint.py:209 msgid "" "Unfortunately, your project is not compliant with version {} of the REUSE " "Specification :-(" msgstr "" "Desafortunadamente, tu proyecto no es compatible con la versión {} de la " "Especificación REUSE :-(" #: src/reuse/lint.py:216 msgid "RECOMMENDATIONS" msgstr "RECOMENDACIONES" #: src/reuse/lint.py:289 #, python-brace-format msgid "{path}: bad license {lic}\n" msgstr "" #: src/reuse/lint.py:296 #, fuzzy, python-brace-format msgid "{lic_path}: deprecated license\n" msgstr "Licencias obsoletas:" #: src/reuse/lint.py:303 #, fuzzy, python-brace-format msgid "{lic_path}: license without file extension\n" msgstr "Licencias sin extensión de fichero:" #: src/reuse/lint.py:312 #, fuzzy, python-brace-format msgid "{lic_path}: unused license\n" msgstr "Licencias no utilizadas:" #: src/reuse/lint.py:319 #, python-brace-format msgid "{path}: missing license {lic}\n" msgstr "" #: src/reuse/lint.py:326 #, python-brace-format msgid "{path}: read error\n" msgstr "" #: src/reuse/lint.py:330 #, fuzzy, python-brace-format msgid "{path}: no license identifier\n" msgstr "'{}' no es un Identificador SPDX de Licencia válido." #: src/reuse/lint.py:334 #, python-brace-format msgid "{path}: no copyright notice\n" msgstr "" #: src/reuse/project.py:262 #, fuzzy, python-brace-format msgid "'{path}' covered by {global_path}" msgstr "'{path}' cubierto por .reuse/dep5" #: src/reuse/project.py:270 #, python-brace-format msgid "" "'{path}' is covered exclusively by REUSE.toml. Not reading the file contents." msgstr "" #: src/reuse/project.py:277 #, python-brace-format msgid "" "'{path}' was detected as a binary file; not searching its contents for REUSE " "information." msgstr "" "Se ha detectado que '{path}' es un archivo binario; no se ha buscado " "información REUTILIZABLE en su contenido." #: src/reuse/project.py:334 msgid "" "'.reuse/dep5' is deprecated. You are recommended to instead use REUSE.toml. " "Use `reuse convert-dep5` to convert." msgstr "" #: src/reuse/project.py:348 #, python-brace-format msgid "" "Found both '{new_path}' and '{old_path}'. You cannot keep both files " "simultaneously; they are not intercompatible." msgstr "" #: src/reuse/project.py:414 #, python-brace-format msgid "determining identifier of '{path}'" msgstr "determinando el identificador de '{path}'" #: src/reuse/project.py:422 #, python-brace-format msgid "{path} does not have a file extension" msgstr "{path} no tiene extensión de fichero" #: src/reuse/project.py:432 #, python-brace-format msgid "" "Could not resolve SPDX License Identifier of {path}, resolving to " "{identifier}. Make sure the license is in the license list found at or that it starts with 'LicenseRef-', and that it has a " "file extension." msgstr "" "No pudo detectarse el Identificador SPDX de Licencia de {path}: detectando " "{identifier}. Asegúrate de que la licencia consta en la lista de licencias " "alojada en , o de que empieza por 'LicenseRef-', " "y de que posee una extensión de fichero." #: src/reuse/project.py:444 #, python-brace-format msgid "" "{identifier} is the SPDX License Identifier of both {path} and {other_path}" msgstr "" "{identifier} es el Identificador SPDX de Licencia, tanto de {path}, como de " "{other_path}" #: src/reuse/project.py:483 msgid "" "project '{}' is not a VCS repository or required VCS software is not " "installed" msgstr "" "el proyecto '{}' no es un repositorio VCS o el software VCS requerido no " "está instalado" #: src/reuse/report.py:310 #, python-brace-format msgid "Could not read '{path}'" msgstr "No se pudo leer '{path}'" #: src/reuse/report.py:317 #, python-brace-format msgid "Unexpected error occurred while parsing '{path}'" msgstr "Se produjo un error inesperado al procesar '{path}'" #: src/reuse/report.py:438 msgid "" "Fix bad licenses: At least one license in the LICENSES directory and/or " "provided by 'SPDX-License-Identifier' tags is invalid. They are either not " "valid SPDX License Identifiers or do not start with 'LicenseRef-'. FAQ about " "custom licenses: https://reuse.software/faq/#custom-license" msgstr "" "Corregir licencias defectuosas: Al menos una licencia en el directorio " "LICENCIAS y/o proporcionada por etiquetas 'SPDX-License-Identifier' no es " "válida. No son identificadores de licencia SPDX válidos o no empiezan por " "'LicenseRef-'. Preguntas frecuentes sobre las licencias personalizadas: " "https://reuse.software/faq/#custom-license" #: src/reuse/report.py:449 msgid "" "Fix deprecated licenses: At least one of the licenses in the LICENSES " "directory and/or provided by an 'SPDX-License-Identifier' tag or in '.reuse/" "dep5' has been deprecated by SPDX. The current list and their respective " "recommended new identifiers can be found here: " msgstr "" "Corrección de licencias obsoletas: Al menos una de las licencias en el " "directorio LICENCIAS y/o proporcionada por una etiqueta 'SPDX-License-" "Identifier' o en '.reuse/dep5' ha sido obsoleta por SPDX. La lista actual y " "los nuevos identificadores recomendados se encuentran aquí: " #: src/reuse/report.py:460 msgid "" "Fix licenses without file extension: At least one license text file in the " "'LICENSES' directory does not have a '.txt' file extension. Please rename " "the file(s) accordingly." msgstr "" "Corregir licencias sin extensión de archivo: al menos un archivo de texto " "con la licencia en el directorio 'LICENCIAS' no tiene una extensión '.txt'. " "Cambie el nombre de los archivos en consecuencia." #: src/reuse/report.py:469 msgid "" "Fix missing licenses: For at least one of the license identifiers provided " "by the 'SPDX-License-Identifier' tags, there is no corresponding license " "text file in the 'LICENSES' directory. For SPDX license identifiers, you can " "simply run 'reuse download --all' to get any missing ones. For custom " "licenses (starting with 'LicenseRef-'), you need to add these files yourself." msgstr "" "Corrección de las licencias que faltan: Para al menos uno de los " "identificadores de la licencia proporcionados por las etiquetas 'SPDX-" "License-Identifier', no existe el correspondiente archivo de texto de " "licencia en el directorio 'LICENCIAS'. Para los identificadores de licencia " "SPDX, basta con ejecutar 'reuse download --all' para obtener los que falten. " "En el caso de las licencias personalizadas (que empiezan por 'LicenseRef-'), " "deberá añadir estos archivos usted mismo." #: src/reuse/report.py:481 msgid "" "Fix unused licenses: At least one of the license text files in 'LICENSES' is " "not referenced by any file, e.g. by an 'SPDX-License-Identifier' tag. Please " "make sure that you either tag the accordingly licensed files properly, or " "delete the unused license text if you are sure that no file or code snippet " "is licensed as such." msgstr "" "Corregir licencias no utilizadas: Al menos uno de los archivos de texto de " "la licencia en 'LICENCIAS' no está referenciado por ningún archivo, por " "ejemplo, por una etiqueta 'SPDX-License-Identifier'. Por favor, asegúrese de " "etiquetar correctamente los archivos con la licencia correspondiente, o " "elimine el texto de la licencia no utilizado si está seguro de que ningún " "archivo o fragmento de código tiene una licencia como tal." #: src/reuse/report.py:492 msgid "" "Fix read errors: At least one of the files in your directory cannot be read " "by the tool. Please check the file permissions. You will find the affected " "files at the top of the output as part of the logged error messages." msgstr "" "Corregir errores de lectura: Al menos uno de los archivos de su directorio " "no puede ser leído por la herramienta. Compruebe los permisos de los " "archivos. Encontrará los archivos afectados en la parte superior como parte " "de los mensajes de los errores registrados." #: src/reuse/report.py:501 msgid "" "Fix missing copyright/licensing information: For one or more files, the tool " "cannot find copyright and/or licensing information. You typically do this by " "adding 'SPDX-FileCopyrightText' and 'SPDX-License-Identifier' tags to each " "file. The tutorial explains additional ways to do this: " msgstr "" "Corregir la falta de información del copyright/licencia: Para uno o más " "archivos, la herramienta no puede encontrar la información del copyright y/o " "licencia. Para ello, añada las etiquetas 'SPDX-FileCopyrightText' y 'SPDX-" "License-Identifer' a cada archivo. El tutorial explica otras formas de " "hacerlo: " #: src/reuse/spdx.py:32 msgid "" "populate the LicenseConcluded field; note that reuse cannot guarantee the " "field is accurate" msgstr "" "rellenar el campo LicenseConcluded; ten en cuenta que la reutilización no " "puede garantizar que el campo sea exacto" #: src/reuse/spdx.py:39 msgid "name of the person signing off on the SPDX report" msgstr "nombre de la persona que firma el informe SPDX" #: src/reuse/spdx.py:44 msgid "name of the organization signing off on the SPDX report" msgstr "nombre de la organización que firma el informe SPDX" #: src/reuse/spdx.py:60 msgid "" "error: --creator-person=NAME or --creator-organization=NAME required when --" "add-license-concluded is provided" msgstr "" "error: se requiere --creator-person=NAME o --creator-organization=NAME " "cuando se proporciona --add-license-concluded" #: src/reuse/spdx.py:75 #, python-brace-format msgid "" "'{path}' does not match a common SPDX file pattern. Find the suggested " "naming conventions here: https://spdx.github.io/spdx-spec/conformance/#44-" "standard-data-format-requirements" msgstr "" "'{path}' no coincide con un patrón del archivo SPDX común. Encontrarás las " "convenciones de la nomenclatura sugeridas aquí: https://spdx.github.io/spdx-" "spec/conformance/#44-standard-data-format-requirements" #: /usr/lib/python3.10/argparse.py:308 msgid "usage: " msgstr "uso: " #: /usr/lib/python3.10/argparse.py:880 msgid ".__call__() not defined" msgstr ".__call__() no definido" #: /usr/lib/python3.10/argparse.py:1223 #, python-format msgid "unknown parser %(parser_name)r (choices: %(choices)s)" msgstr "" "analizador sintáctico desconocido: %(parser_name)r (alternativas: " "%(choices)s)" #: /usr/lib/python3.10/argparse.py:1283 #, python-format msgid "argument \"-\" with mode %r" msgstr "parámetro \"-\" con modo %r" #: /usr/lib/python3.10/argparse.py:1292 #, python-format msgid "can't open '%(filename)s': %(error)s" msgstr "no se puede abrir '%(filename)s': %(error)s" #: /usr/lib/python3.10/argparse.py:1501 #, python-format msgid "cannot merge actions - two groups are named %r" msgstr "no se pueden fusionar las acciones: dos grupos se llaman %r" #: /usr/lib/python3.10/argparse.py:1539 msgid "'required' is an invalid argument for positionals" msgstr "'required' es un argumento posicional inválido" #: /usr/lib/python3.10/argparse.py:1561 #, python-format msgid "" "invalid option string %(option)r: must start with a character " "%(prefix_chars)r" msgstr "" "Opción no válida %(option)r: Debe comenzar con una letra %(prefix_chars)r" #: /usr/lib/python3.10/argparse.py:1579 #, python-format msgid "dest= is required for options like %r" msgstr "se requiere dest= para opciones como %r" #: /usr/lib/python3.10/argparse.py:1596 #, python-format msgid "invalid conflict_resolution value: %r" msgstr "valor no válido de conflict_resolution: %r" #: /usr/lib/python3.10/argparse.py:1614 #, python-format msgid "conflicting option string: %s" msgid_plural "conflicting option strings: %s" msgstr[0] "cadena de opción conflictiva: %s" msgstr[1] "cadenas de opción conflictivas: %s" #: /usr/lib/python3.10/argparse.py:1680 msgid "mutually exclusive arguments must be optional" msgstr "los parámetros mutuamente excluyentes deben ser opcionales" #: /usr/lib/python3.10/argparse.py:1748 msgid "positional arguments" msgstr "parámetros posicionales" #: /usr/lib/python3.10/argparse.py:1749 msgid "options" msgstr "opciones" #: /usr/lib/python3.10/argparse.py:1764 msgid "show this help message and exit" msgstr "mostrar este mensaje de ayuda y salir" #: /usr/lib/python3.10/argparse.py:1795 msgid "cannot have multiple subparser arguments" msgstr "no puede contener múltiples parámetros del subanalizador sintáctico" #: /usr/lib/python3.10/argparse.py:1847 /usr/lib/python3.10/argparse.py:2362 #, python-format msgid "unrecognized arguments: %s" msgstr "parámetros no reconocidos: %s" #: /usr/lib/python3.10/argparse.py:1948 #, python-format msgid "not allowed with argument %s" msgstr "no permitido con el parámetro %s" #: /usr/lib/python3.10/argparse.py:1998 /usr/lib/python3.10/argparse.py:2012 #, python-format msgid "ignored explicit argument %r" msgstr "parámetro explícito ignorado: %r" #: /usr/lib/python3.10/argparse.py:2119 #, python-format msgid "the following arguments are required: %s" msgstr "los siguientes parámetros son obligatorios: %s" #: /usr/lib/python3.10/argparse.py:2134 #, python-format msgid "one of the arguments %s is required" msgstr "se requiere uno de los parámetros %s" #: /usr/lib/python3.10/argparse.py:2177 msgid "expected one argument" msgstr "se espera un parámetro" #: /usr/lib/python3.10/argparse.py:2178 msgid "expected at most one argument" msgstr "se espera un parámetro, como máximo" #: /usr/lib/python3.10/argparse.py:2179 msgid "expected at least one argument" msgstr "se espera un parámetro, como mínimo" #: /usr/lib/python3.10/argparse.py:2183 #, python-format msgid "expected %s argument" msgid_plural "expected %s arguments" msgstr[0] "se espera el parámetro %s" msgstr[1] "se esperan los parámetros %s" #: /usr/lib/python3.10/argparse.py:2241 #, python-format msgid "ambiguous option: %(option)s could match %(matches)s" msgstr "opción ambigua: %(option)s podría coincidir con %(matches)s" #: /usr/lib/python3.10/argparse.py:2305 #, python-format msgid "unexpected option string: %s" msgstr "cadena de opción inesperada: %s" #: /usr/lib/python3.10/argparse.py:2502 #, python-format msgid "%r is not callable" msgstr "%r no se puede invocar" #: /usr/lib/python3.10/argparse.py:2519 #, python-format msgid "invalid %(type)s value: %(value)r" msgstr "valor no válido de %(type)s: %(value)r" #: /usr/lib/python3.10/argparse.py:2530 #, python-format msgid "invalid choice: %(value)r (choose from %(choices)s)" msgstr "opción inválida: %(value)r (opciones: %(choices)s)" #: /usr/lib/python3.10/argparse.py:2606 #, python-format msgid "%(prog)s: error: %(message)s\n" msgstr "%(prog)s: error: %(message)s\n" #, fuzzy, python-brace-format #~ msgid "" #~ "Copyright and licensing information for '{original_path}' has been found " #~ "in both '{path}' and in the DEP5 file located at '{dep5_path}'. The " #~ "information for these two sources has been aggregated. You are " #~ "recommended to instead use REUSE.toml, where you can specify the order of " #~ "precedence. Use `reuse convert-dep5` to convert. Run with `--suppress-" #~ "deprecation` to hide this warning." #~ msgstr "" #~ "Se ha encontrado información sobre derechos de autor y licencias para " #~ "'{original_path}' tanto en '{path}' como en el archivo DEP5 ubicado en " #~ "'{dep5_path}'. La información de estas dos fuentes se ha agregado. En el " #~ "futuro, este comportamiento cambiará y tendrás que activar explícitamente " #~ "la agregación. Véase . Aún " #~ "no es necesario hacer nada. Ejecuta con `--suppress-deprecation` para " #~ "ocultar esta advertencia." #~ msgid "initialize REUSE project" #~ msgstr "inicia el proyecto REUSE" #~ msgid "no '{}' file, or could not read it" #~ msgstr "no hay un fichero '{}', o no se ha podido leer" #~ msgid "" #~ "What license is your project under? Provide the SPDX License Identifier. " #~ "See for the list." #~ msgstr "" #~ "¿Cuál es la licencia de tu proyecto? Indica el identificador de licencia " #~ "SPDX. Consulta la lista en ." #~ msgid "" #~ "What other license is your project under? Provide the SPDX License " #~ "Identifier." #~ msgstr "" #~ "¿Bajo qué otras licencias se encuentra tu proyecto? Proporciona el " #~ "Identificador SPDX de Licencia." #~ msgid "To stop adding licenses, hit RETURN." #~ msgstr "Para terminar de añadir licencias pulsa RETORNO." #~ msgid "Project already initialized" #~ msgstr "Proyecto ya inicializado" #~ msgid "Initializing project for REUSE." #~ msgstr "Inicializando el proyecto para REUSE." #~ msgid "What is the name of the project?" #~ msgstr "¿Cuál es el nombre del proyecto?" #~ msgid "What is the internet address of the project?" #~ msgstr "¿Cuál es la dirección de Internet del proyecto?" #~ msgid "What is the name of the maintainer?" #~ msgstr "¿Cuál es el nombre del mantenedor?" #~ msgid "What is the e-mail address of the maintainer?" #~ msgstr "¿Cuál es la dirección de correo electrónico del mantenedor?" #~ msgid "All done! Initializing now." #~ msgstr "¡Ya hemos terminado! Iniciando." #~ msgid "Retrieving {}" #~ msgstr "Recuperando {}" #~ msgid "{} already exists" #~ msgstr "{} ya existe" #~ msgid "Could not download {}" #~ msgstr "No se pudo descargar {}" #, python-brace-format #~ msgid "" #~ "Error: Could not copy {path}, please add {lic}.txt manually in the " #~ "LICENCES/ directory." #~ msgstr "" #~ "Error: No se pudo copiar {path}, por favor añada {lic}.txt manualmente en " #~ "el directorio LICENCIAS/." #~ msgid "Initialization complete." #~ msgstr "Inicialización completa." #~ msgid "" #~ "Add copyright and licensing into the header of one or more files.\n" #~ "\n" #~ "By using --copyright and --license, you can specify which copyright " #~ "holders and licenses to add to the headers of the given files.\n" #~ "\n" #~ "By using --contributor, you can specify people or entity that contributed " #~ "but are not copyright holder of the given files.\n" #~ "The first comment is replaced with a new header containing the new " #~ "copyright and licensing information and its former copyright and " #~ "licensing. If you want to keep the first comment intact, use --no-" #~ "replace.\n" #~ "\n" #~ "The comment style should be auto-detected for your files. If a comment " #~ "style could not be detected and --skip-unrecognised is not specified, the " #~ "process aborts. Use --style to specify or override the comment style to " #~ "use.\n" #~ "\n" #~ "A single-line comment style is used when it is available. If no single-" #~ "line comment style is available, a multi-line comment style is used. You " #~ "can force a certain comment style using --single-line or --multi-line.\n" #~ "\n" #~ "You can change the template of the header comment by using --template. " #~ "Place a Jinja2 template in .reuse/templates/mytemplate.jinja2. You can " #~ "use the template by specifying '--template mytemplate'. Read the online " #~ "documentation on how to use this feature.\n" #~ "\n" #~ "If a binary file is detected, or if --force-dot-license is specified, the " #~ "header is placed in a .license file." #~ msgstr "" #~ "Agregue derechos de autor y licencias al encabezado de uno o más " #~ "archivos.\n" #~ "\n" #~ "Usando --copyright y --license, puede especificar qué titulares de " #~ "derechos de autor y licencias agregar a las cabeceras de los archivos " #~ "dados.\n" #~ "\n" #~ "Usando --contributor, puede especificar personas o entidades que " #~ "contribuyeron, pero no tienen el copyright de los archivos dados.\n" #~ "El primer comentario se sustituye por un nuevo encabezado que contiene la " #~ "nueva información sobre los derechos de autor y licencias y su antigua " #~ "información. Si desea mantener intacto el primer comentario, use --no-" #~ "replace.\n" #~ "\n" #~ "El estilo del comentario debe ser auto-detectado para sus archivos. Si no " #~ "se pudo detectar un estilo de comentario y no se especifica --skip-" #~ "unrecognised, el proceso se aborta. Use --style para especificar o " #~ "sobreescribir el estilo de comentario a usar.\n" #~ "\n" #~ "Se utiliza un estilo de comentario de una sola línea cuando está " #~ "disponible. Si no hay un estilo de comentario de una sola línea, se " #~ "utiliza un estilo de comentario de varias líneas. Puede forzar un cierto " #~ "estilo de comentario usando --single-line o --multi-line.\n" #~ "\n" #~ "Puede cambiar la plantilla del comentario de la cabecera usando --" #~ "template. Coloque una plantilla Jinja2 en .reuse/templates/mytemplate." #~ "jinja2. Puede usar la plantilla especificando '--template mytemplate'. " #~ "Lea la documentación en línea sobre cómo utilizar esta función.\n" #~ "\n" #~ "Si se detecta un archivo binario, o si se especifica --force-dot-license, " #~ "la cabecera se coloca en un archivo .license." #~ msgid "" #~ "Download a license and place it in the LICENSES/ directory.\n" #~ "\n" #~ "The LICENSES/ directory is automatically found in the following order:\n" #~ "\n" #~ "- The LICENSES/ directory in the root of the VCS repository.\n" #~ "\n" #~ "- The current directory if its name is LICENSES.\n" #~ "\n" #~ "- The LICENSES/ directory in the current directory.\n" #~ "\n" #~ "If the LICENSES/ directory cannot be found, one is simply created." #~ msgstr "" #~ "Descarga una licencia y guárdala en el directorio LICENSES/.\n" #~ "\n" #~ "El directorio LICENSES/ es automáticamente detectado en el siguiente " #~ "orden:\n" #~ "\n" #~ "- El directorio LICENSES/ en la raíz del repositorio VCS.\n" #~ "\n" #~ "- El directorio actual, si su nombre es LICENSES.\n" #~ "\n" #~ "- El directorio LICENSES/ en el directorio actual.\n" #~ "\n" #~ "Si el directorio LICENSES/ no fuese encontrado, simplemente se creará uno." #~ msgid ".reuse/dep5 has syntax errors" #~ msgstr ".reuse/dep5 presenta errores de sintaxis" #~ msgid ".reuse/dep5 could not be parsed as utf-8" #~ msgstr ".reuse/dep5 no pudo ser analizado como utf-8" #~ msgid "optional arguments" #~ msgstr "argumentos opcionales" #~ msgid "deprecated in favor of annotate" #~ msgstr "obsoleto en favor de annotate" #~ msgid "'reuse addheader' has been deprecated in favour of 'reuse annotate'" #~ msgstr "" #~ "\"reuse addheader\" ha quedado obsoleto en favor de \"reuse annotate\"" #~ msgid "option --exclude-year and --year are mutually exclusive" #~ msgstr "las opciones -exclude-year y --year son mutuamente excluyentes" #~ msgid "option --single-line and --multi-line are mutually exclusive" #~ msgstr "las opciones --single-line y --multi-line se excluyen mutuamente" #~ msgid "" #~ "--explicit-license has been deprecated in favour of --force-dot-license" #~ msgstr "" #~ "--explicit-license ha quedado obsoleto en favor de --force-dot-license" #~ msgid "Downloading {}" #~ msgstr "Descargando {}" #, fuzzy #~ msgid "conflicting subparser: %s" #~ msgstr "cadena de opción conflictiva: %s" #, fuzzy #~ msgid "conflicting subparser alias: %s" #~ msgstr "cadena de opción conflictiva: %s" #~ msgid "can't open '%s': %s" #~ msgstr "no se puede abrir '%s': %s" #~ msgid "place header in path.license instead of path" #~ msgstr "coloca la cabecera en path.license, en lugar de path" #~ msgid "could not find Git" #~ msgstr "no se pudo encontrar Git" #~ msgid "yielding %s" #~ msgstr "apuntando a %s" #~ msgid "currently walking in %s" #~ msgstr "actualmente recorriendo %s" #~ msgid "ignoring %s" #~ msgstr "ignorando %s" #~ msgid "searching %s for reuse information" #~ msgstr "buscando información de reuse en %s" #~ msgid "%s covered by debian/copyright" #~ msgstr "%s cubierto por debian/copyright" #~ msgid "" #~ "{path} is licensed under {identifier}, but its license file could not be " #~ "found" #~ msgstr "" #~ "{path} con licencia {identifier}, pero no se encontró el archivo con la " #~ "licencia" #~ msgid "searching %s for license tags" #~ msgstr "buscando etiquetas de licencia en %s" #~ msgid "" #~ "Could not resolve SPDX identifier of {path}, resolving to {identifier}" #~ msgstr "" #~ "No se pudo resolver el identificador SPDX de {path}, resolviendo a " #~ "{identifier}" #~ msgid "reuse Copyright (C) 2017-2018 Free Software Foundation Europe e.V." #~ msgstr "" #~ "Copyright (C) 2017-2018 de reuse Free Software Foundation Europe e.V." #~ msgid "" #~ "reuse is free software: you can redistribute it and/or modify it under " #~ "the terms of the GNU General Public License as published by the Free " #~ "Software Foundation, either version 3 of the License, or (at your option) " #~ "any later version.\n" #~ "\n" #~ "reuse is distributed in the hope that it will be useful, but WITHOUT ANY " #~ "WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS " #~ "FOR A PARTICULAR PURPOSE. See the GNU General Public License for more " #~ "details.\n" #~ "\n" #~ "You should have received a copy of the GNU General Public License along " #~ "with reuse. If not, see ." #~ msgstr "" #~ "reuse es software libre: puedes redistribuirlo y/o modificarlo bajo los " #~ "términos de la Licencia Pública General GNU (GNU GPL) tal y como está " #~ "publicada por la Free Software Foundation, tanto la versión 3 de la " #~ "Licencia, o (a tu elección) cualquier versión posterior.\n" #~ "\n" #~ "reuse se distribuye con la esperanza de ser útil, pero SIN NINGUNA " #~ "GARANTIA; ni siquiera la garantia implícita de COMERCIABILIDAD o " #~ "ADECUACIÓN PARA UN PROPÓSITO PARTICULAR. Consulta la Licencia Pública " #~ "General GNU para más detalles.\n" #~ "\n" #~ "Deberías haber recibido una copia de la Licencia Pública General GNU con " #~ "reuse. Si no es así, consulta ." #~ msgid "IMPORTANT:" #~ msgstr "IMPORTANTE:" #~ msgid "" #~ "You do not have pygit2 installed. reuse will slow down significantly " #~ "because of this. For better performance, please install your " #~ "distribution's version of pygit2." #~ msgstr "" #~ "No tienes instalado pygit2 por lo que reuse funcionará significativamente " #~ "más lento. Por favor, instala la versión de pygit2 de tu distribución " #~ "para un mejor rendimiento." #~ msgid "could not read %s" #~ msgstr "no se pudo leer %s" #~ msgid "none\n" #~ msgstr "nada\n" #~ msgid "do not use debian/copyright to extract reuse information" #~ msgstr "no use debian/copyright para extraer información de reuse" #~ msgid "" #~ "List all non-compliant files.\n" #~ "\n" #~ "A file is non-compliant when:\n" #~ "\n" #~ "- It has no copyright information.\n" #~ "\n" #~ "- It has no license (declared as SPDX expression).\n" #~ "\n" #~ "- Its license could not be found.\n" #~ "\n" #~ "This prints only the paths of the files that do not comply, each file on " #~ "a separate line.\n" #~ "\n" #~ "Error and warning messages are output to STDERR." #~ msgstr "" #~ "Lista todos los ficheros no compatibles.\n" #~ "\n" #~ "Un fichero es no compatible si:\n" #~ "\n" #~ "- no tiene información de copyright.\n" #~ "\n" #~ "- no tiene licencia (declarada como una expresión SPDX).\n" #~ "\n" #~ "- su licencia no se encuentra.\n" #~ "\n" #~ "Esto imprime únicamente las rutas de los ficheros no compatibles, cada " #~ "fichero en una línea separada.\n" #~ "\n" #~ "Los mensajes de error y aviso se muestran en STDERR." #~ msgid "SPDX expressions are mandatory for compliance" #~ msgstr "Las expresiones SPDX son de obligatorio cumplimiento" #~ msgid "copyright notices are mandatory for compliance" #~ msgstr "las notas de copyright son de obligatorio cumplimiento" #~ msgid "print the SPDX expressions of each provided file" #~ msgstr "imprime las expresiones SPDX de cada fichero proporcionado" #~ msgid "reuse, version {}\n" #~ msgstr "reuse, versión {}\n" reuse-tool-4.0.3/po/fr.po000066400000000000000000001160011464275211500152070ustar00rootroot00000000000000# SPDX-FileCopyrightText: 2020 OliBug # SPDX-FileCopyrightText: 2020 Vincent Lequertier # # SPDX-License-Identifier: GPL-3.0-or-later msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-07-03 13:09+0000\n" "PO-Revision-Date: 2023-10-04 13:12+0000\n" "Last-Translator: Walter Paulo \n" "Language-Team: French \n" "Language: fr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n > 1;\n" "X-Generator: Weblate 5.1-dev\n" #: src/reuse/_annotate.py:74 #, python-brace-format msgid "" "'{path}' does not support single-line comments, please do not use --single-" "line" msgstr "" "{path} n'accepte pas les commentaires monolignes. Merci de ne pas utiliser --" "single-line" #: src/reuse/_annotate.py:81 #, python-brace-format msgid "" "'{path}' does not support multi-line comments, please do not use --multi-line" msgstr "" "{path} n'accepte pas les commentaires multilinges. Merci de ne pas utiliser " "--multi-line" #: src/reuse/_annotate.py:136 #, fuzzy, python-brace-format msgid "Skipped unrecognised file '{path}'" msgstr "Le fichier {path} non reconnu a été ignoré" #: src/reuse/_annotate.py:142 #, python-brace-format msgid "'{path}' is not recognised; creating '{path}.license'" msgstr "" #: src/reuse/_annotate.py:158 #, python-brace-format msgid "Skipped file '{path}' already containing REUSE information" msgstr "Le fichier ignoré {path} contenait déjà les données REUSE" #: src/reuse/_annotate.py:192 #, python-brace-format msgid "Error: Could not create comment for '{path}'" msgstr "Erreur : les commentaires ne peuvent être créés dans '{path}'" #: src/reuse/_annotate.py:199 #, python-brace-format msgid "" "Error: Generated comment header for '{path}' is missing copyright lines or " "license expressions. The template is probably incorrect. Did not write new " "header." msgstr "" "Erreur : l'en-tête de commentaire généré dans '{path}' ne contient pas de " "ligne ou d'expression de droits d'auteur ou de licence. Le modèle est " "probablement incorrect. Nouvel en-tête non écrit." #. TODO: This may need to be rephrased more elegantly. #: src/reuse/_annotate.py:210 #, python-brace-format msgid "Successfully changed header of {path}" msgstr "En-tête de {path} modifié avec succès" #: src/reuse/_annotate.py:221 msgid "--skip-unrecognised has no effect when used together with --style" msgstr "" "--skip-unrecognised est sans effet quand il est utilisé en même temps que --" "style" #: src/reuse/_annotate.py:231 msgid "option --contributor, --copyright or --license is required" msgstr "une des options --contributor, --copyright ou --license est nécessaire" #: src/reuse/_annotate.py:272 #, python-brace-format msgid "template {template} could not be found" msgstr "le modèle {template} est introuvable" #: src/reuse/_annotate.py:341 src/reuse/_util.py:573 msgid "can't write to '{}'" msgstr "écriture impossible dans '{}'" #: src/reuse/_annotate.py:366 #, fuzzy msgid "" "The following files do not have a recognised file extension. Please use --" "style, --force-dot-license, --fallback-dot-license, or --skip-unrecognised:" msgstr "" "'{path}' n'est pas une extension de fichier reconnue. Merci d'utiliser --" "style, --force-dot-license ou --skip-unrecognised :" #: src/reuse/_annotate.py:382 msgid "copyright statement, repeatable" msgstr "déclaration de droits d'auteur, répétable" #: src/reuse/_annotate.py:389 msgid "SPDX Identifier, repeatable" msgstr "Identifiant SPDX, répétable" #: src/reuse/_annotate.py:395 msgid "file contributor, repeatable" msgstr "contributeur au fichier, répétable" #: src/reuse/_annotate.py:403 msgid "year of copyright statement, optional" msgstr "année de déclaration de droits d'auteur, facultatif" #: src/reuse/_annotate.py:411 msgid "comment style to use, optional" msgstr "style de commentaire à utiliser, facultatif" #: src/reuse/_annotate.py:417 #, fuzzy msgid "copyright prefix to use, optional" msgstr "style de droits d'auteur à utiliser, facultatif" #: src/reuse/_annotate.py:430 msgid "name of template to use, optional" msgstr "nom de modèle à utiliser, facultatif" #: src/reuse/_annotate.py:435 msgid "do not include year in statement" msgstr "ne pas inclure d'année dans la déclaration" #: src/reuse/_annotate.py:440 msgid "merge copyright lines if copyright statements are identical" msgstr "" "fusionner les lignes de droits d'auteur si les déclarations de droits " "d'auteur sont identiques" #: src/reuse/_annotate.py:446 msgid "force single-line comment style, optional" msgstr "forcer le style de commentaire monoligne, facultatif" #: src/reuse/_annotate.py:451 msgid "force multi-line comment style, optional" msgstr "forcer le style de commentaire multiligne, facultatif" #: src/reuse/_annotate.py:458 msgid "add headers to all files under specified directories recursively" msgstr "" "ajouter récursivement les en-têtes dans tous les fichiers des répertoires " "spécifiés" #: src/reuse/_annotate.py:465 msgid "do not replace the first header in the file; just add a new one" msgstr "" "ne pas remplacer le premier en-tête dans le fichier, mais simplement en " "ajouter un" #: src/reuse/_annotate.py:473 #, fuzzy msgid "always write a .license file instead of a header inside the file" msgstr "écrire un fichier .licence plutôt qu'un en-tête dans le fichier" #: src/reuse/_annotate.py:480 #, fuzzy msgid "write a .license file to files with unrecognised comment styles" msgstr "" "ignorer les fichiers comportant des styles de commentaires non reconnus" #: src/reuse/_annotate.py:486 msgid "skip files with unrecognised comment styles" msgstr "" "ignorer les fichiers comportant des styles de commentaires non reconnus" #: src/reuse/_annotate.py:497 msgid "skip files that already contain REUSE information" msgstr "ignorer les fichiers qui contiennent déjà les données REUSE" #: src/reuse/_annotate.py:532 #, python-brace-format msgid "'{path}' is a binary, therefore using '{new_path}' for the header" msgstr "" "'{path}' est un fichier binaire ; par conséquent, le fichier '{new_path}' " "est utilisé pour l'en-tête" #: src/reuse/_main.py:39 msgid "" "reuse is a tool for compliance with the REUSE recommendations. See for more information, and " "for the online documentation." msgstr "" "reuse est un outil pour la conformité aux recommandations de l'initiative " "REUSE. Voir pour plus d'informations, et pour la documentation en ligne." #: src/reuse/_main.py:45 msgid "" "This version of reuse is compatible with version {} of the REUSE " "Specification." msgstr "" "Cette version de reuse est compatible avec la version {} de la spécification " "REUSE." #: src/reuse/_main.py:48 msgid "Support the FSFE's work:" msgstr "Soutenir le travail de la FSFE :" #: src/reuse/_main.py:52 msgid "" "Donations are critical to our strength and autonomy. They enable us to " "continue working for Free Software wherever necessary. Please consider " "making a donation at ." msgstr "" "Les dons sont cruciaux pour notre force et notre autonomie. Ils nous " "permettent de continuer à travailler pour le Logiciel Libre partout où c'est " "nécessaire. Merci d'envisager de faire un don ." #: src/reuse/_main.py:75 msgid "enable debug statements" msgstr "activer les instructions de débogage" #: src/reuse/_main.py:80 msgid "hide deprecation warnings" msgstr "masquer les avertissements d'obsolescence" #: src/reuse/_main.py:85 msgid "do not skip over Git submodules" msgstr "ne pas omettre les sous-modules Git" #: src/reuse/_main.py:90 msgid "do not skip over Meson subprojects" msgstr "ne pas omettre les sous-projets Meson" #: src/reuse/_main.py:95 msgid "do not use multiprocessing" msgstr "pas de multiprocessing" #: src/reuse/_main.py:102 msgid "define root of project" msgstr "définition de la racine (root) du projet" #: src/reuse/_main.py:107 msgid "show program's version number and exit" msgstr "voir la version du programme et quitter" #: src/reuse/_main.py:111 msgid "subcommands" msgstr "sous-commandes" #: src/reuse/_main.py:118 msgid "add copyright and licensing into the header of files" msgstr "" "ajout des informations de droits d'auteur et de licence dans les en-têtes " "(header) des fichiers" #: src/reuse/_main.py:121 msgid "" "Add copyright and licensing into the header of one or more files.\n" "\n" "By using --copyright and --license, you can specify which copyright holders " "and licenses to add to the headers of the given files.\n" "\n" "By using --contributor, you can specify people or entity that contributed " "but are not copyright holder of the given files." msgstr "" #: src/reuse/_main.py:140 msgid "download a license and place it in the LICENSES/ directory" msgstr "télécharger une licence et la placer dans le répertoire LICENSES/" #: src/reuse/_main.py:142 #, fuzzy msgid "Download a license and place it in the LICENSES/ directory." msgstr "télécharger une licence et la placer dans le répertoire LICENSES/" #: src/reuse/_main.py:151 msgid "list all non-compliant files" msgstr "lister tous les fichiers non-conformes" #: src/reuse/_main.py:154 #, python-brace-format msgid "" "Lint the project directory for compliance with version {reuse_version} of " "the REUSE Specification. You can find the latest version of the " "specification at .\n" "\n" "Specifically, the following criteria are checked:\n" "\n" "- Are there any bad (unrecognised, not compliant with SPDX) licenses in the " "project?\n" "\n" "- Are any licenses referred to inside of the project, but not included in " "the LICENSES/ directory?\n" "\n" "- Are any licenses included in the LICENSES/ directory that are not used " "inside of the project?\n" "\n" "- Do all files have valid copyright and licensing information?" msgstr "" "Vérifiez le répertoire projet pour assurer la conformité à la version " "{reuse_version} de la spécification REUSE. Vous pouvez trouver la dernière " "version de la spécification à l'adresse .\n" "\n" "En particulier, les critères suivants sont vérifiés :\n" "\n" "- Une mauvaise licence (non reconnue, non conforme à SPDX) se trouve-t-elle " "dans le projet ?\n" "\n" "- Des licences référencées dans le projet sont-elles absentes du répertoire " "LICENSES/ ?\n" "\n" "- Y a-t-il des licences dans le répertoire LICENSES/ qui sont inutilisées " "dans le projet ?\n" "\n" "- Tous les fichiers disposent-ils de données de droits d'auteur et de " "licence valides ?" #: src/reuse/_main.py:181 msgid "print the project's bill of materials in SPDX format" msgstr "imprimer la nomenclature du projet au format SPDX" #: src/reuse/_main.py:189 msgid "list all supported SPDX licenses" msgstr "lister toutes les licences SPDX acceptées" #: src/reuse/_main.py:198 msgid "convert .reuse/dep5 to REUSE.toml" msgstr "" #: src/reuse/_main.py:263 #, fuzzy, python-brace-format msgid "'{path}' could not be decoded as UTF-8." msgstr ".reuse/dep5 n'a pas pu être analysé comme fichier utf-8" #: src/reuse/_main.py:269 #, python-brace-format msgid "" "'{path}' could not be parsed. We received the following error message: " "{message}" msgstr "" #: src/reuse/_util.py:368 src/reuse/global_licensing.py:218 #, python-brace-format msgid "Could not parse '{expression}'" msgstr "Analyse de la syntaxe de '{expression}' impossible" #: src/reuse/_util.py:424 #, python-brace-format msgid "" "'{path}' holds an SPDX expression that cannot be parsed, skipping the file" msgstr "" "'{path}' contient une expression SPDX qui ne peut pas être analysée : le " "fichier est ignoré" #: src/reuse/_util.py:556 msgid "'{}' is not a file" msgstr "'{}' n'est pas un fichier" #: src/reuse/_util.py:559 msgid "'{}' is not a directory" msgstr "'{}' n'est pas un répertoire" #: src/reuse/_util.py:562 msgid "can't open '{}'" msgstr "'{}' ne peut être ouvert" #: src/reuse/_util.py:567 msgid "can't write to directory '{}'" msgstr "écriture impossible dans le répertoire '{}'" #: src/reuse/_util.py:586 msgid "can't read or write '{}'" msgstr "lecture ou écriture impossible pour '{}'" #: src/reuse/_util.py:596 msgid "'{}' is not a valid SPDX expression, aborting" msgstr "'{}' n'est pas une expression SPDX valide, abandon" #: src/reuse/_util.py:624 msgid "'{}' is not a valid SPDX License Identifier." msgstr "'{}' n'est pas un identifiant de licence SPDX valide." #: src/reuse/_util.py:631 msgid "Did you mean:" msgstr "Vous vouliez dire :" #: src/reuse/_util.py:638 msgid "" "See for a list of valid SPDX License " "Identifiers." msgstr "" "Consultez pour une liste des identifiants de " "licence SPDX valides." #: src/reuse/convert_dep5.py:118 #, fuzzy msgid "no '.reuse/dep5' file" msgstr "Création de .reuse/dep5" #: src/reuse/download.py:130 msgid "SPDX License Identifier of license" msgstr "Identification de la licence SPDX" #: src/reuse/download.py:135 msgid "download all missing licenses detected in the project" msgstr "télécharger toutes les licences manquantes détectées dans le projet" #: src/reuse/download.py:145 msgid "" "source from which to copy custom LicenseRef- licenses, either a directory " "that contains the file or the file itself" msgstr "" #: src/reuse/download.py:156 #, python-brace-format msgid "Error: {spdx_identifier} already exists." msgstr "Erreur : {spdx_identifier} existe déjà." #: src/reuse/download.py:163 #, fuzzy, python-brace-format msgid "Error: {path} does not exist." msgstr "'{path}' ne se termine pas en .spdx" #: src/reuse/download.py:166 msgid "Error: Failed to download license." msgstr "Erreur : échec du téléchargement de licence." #: src/reuse/download.py:171 msgid "Is your internet connection working?" msgstr "Votre connexion internet fonctionne-t-elle ?" #: src/reuse/download.py:176 #, python-brace-format msgid "Successfully downloaded {spdx_identifier}." msgstr "Téléchargement de {spdx_identifier} terminé." #: src/reuse/download.py:188 msgid "--output has no effect when used together with --all" msgstr "--output n'a pas d'effet s'il est utilisé en même temps que --all" #: src/reuse/download.py:192 msgid "the following arguments are required: license" msgstr "les arguments suivants sont nécessaires : license" #: src/reuse/download.py:194 msgid "cannot use --output with more than one license" msgstr "--output ne peut pas être utilisé avec plus d'une licence" #: src/reuse/global_licensing.py:109 #, python-brace-format msgid "" "{attr_name} must be a {type_name} (got {value} that is a {value_class})." msgstr "" #: src/reuse/global_licensing.py:122 #, python-brace-format msgid "" "Item in {attr_name} collection must be a {type_name} (got {item_value} that " "is a {item_class})." msgstr "" #: src/reuse/global_licensing.py:133 #, python-brace-format msgid "{attr_name} must not be empty." msgstr "" #: src/reuse/global_licensing.py:156 #, python-brace-format msgid "{name} must be a {type} (got {value} that is a {value_type})." msgstr "" #: src/reuse/global_licensing.py:179 #, python-brace-format msgid "" "The value of 'precedence' must be one of {precedence_vals} (got {received})" msgstr "" #: src/reuse/header.py:99 msgid "generated comment is missing copyright lines or license expressions" msgstr "" "les commentaires générés ne contiennent pas de ligne ou d'expression de " "droits d'auteur ou de licence" #: src/reuse/lint.py:30 msgid "prevents output" msgstr "empêche la sortie" #: src/reuse/lint.py:33 msgid "formats output as JSON" msgstr "applique le format JSON à la sortie" #: src/reuse/lint.py:39 msgid "formats output as plain text" msgstr "applique le format texte brut pour la sortie" #: src/reuse/lint.py:45 #, fuzzy msgid "formats output as errors per line" msgstr "applique le format texte brut pour la sortie" #: src/reuse/lint.py:64 msgid "BAD LICENSES" msgstr "MAUVAISES LICENCES" #: src/reuse/lint.py:66 src/reuse/lint.py:95 msgid "'{}' found in:" msgstr "'{}' trouvé dans :" #: src/reuse/lint.py:73 msgid "DEPRECATED LICENSES" msgstr "LICENCES OBSOLÈTES" #: src/reuse/lint.py:75 msgid "The following licenses are deprecated by SPDX:" msgstr "Les licences suivantes sont rendues obsolètes par SPDX :" #: src/reuse/lint.py:83 msgid "LICENSES WITHOUT FILE EXTENSION" msgstr "LICENCES SANS EXTENSION DE FICHIER" #: src/reuse/lint.py:85 msgid "The following licenses have no file extension:" msgstr "Les licences suivantes n'ont pas d'extension de fichier :" #: src/reuse/lint.py:93 msgid "MISSING LICENSES" msgstr "LICENCES MANQUANTES" #: src/reuse/lint.py:102 msgid "UNUSED LICENSES" msgstr "LICENCES INUTILISÉES" #: src/reuse/lint.py:103 msgid "The following licenses are not used:" msgstr "Les licences suivantes ne sont pas utilisées :" #: src/reuse/lint.py:110 msgid "READ ERRORS" msgstr "ERREURS DE LECTURE" #: src/reuse/lint.py:111 msgid "Could not read:" msgstr "Illisibles :" #: src/reuse/lint.py:132 msgid "MISSING COPYRIGHT AND LICENSING INFORMATION" msgstr "INFORMATION DE DROITS D'AUTEUR ET DE LICENCE MANQUANTE" #: src/reuse/lint.py:138 msgid "The following files have no copyright and licensing information:" msgstr "" "Les fichiers suivants ne contiennent pas de données de droits d'auteur et de " "licence :" #: src/reuse/lint.py:149 msgid "The following files have no copyright information:" msgstr "" "Les fichiers suivants ne contiennent pas de données de droits d'auteur :" #: src/reuse/lint.py:158 msgid "The following files have no licensing information:" msgstr "Les fichiers suivants ne contiennent pas de données de licence :" #: src/reuse/lint.py:166 msgid "SUMMARY" msgstr "RÉSUMÉ" #: src/reuse/lint.py:171 msgid "Bad licenses:" msgstr "Mauvaises licences :" #: src/reuse/lint.py:172 msgid "Deprecated licenses:" msgstr "Licences obsolètes :" #: src/reuse/lint.py:173 msgid "Licenses without file extension:" msgstr "Licences sans extension de fichier :" #: src/reuse/lint.py:176 msgid "Missing licenses:" msgstr "Licences manquantes :" #: src/reuse/lint.py:177 msgid "Unused licenses:" msgstr "Licences inutilisées :" #: src/reuse/lint.py:178 msgid "Used licenses:" msgstr "Licences utilisées :" #: src/reuse/lint.py:179 msgid "Read errors:" msgstr "Erreurs de lecture :" #: src/reuse/lint.py:181 #, fuzzy msgid "Files with copyright information:" msgstr "Fichiers contenant des données de droits d'auteur :" #: src/reuse/lint.py:185 #, fuzzy msgid "Files with license information:" msgstr "Fichiers contenant des données de licence :" #: src/reuse/lint.py:202 msgid "" "Congratulations! Your project is compliant with version {} of the REUSE " "Specification :-)" msgstr "" "Félicitations ! Votre projet est conforme à la version {} de la " "spécification REUSE :-)" #: src/reuse/lint.py:209 msgid "" "Unfortunately, your project is not compliant with version {} of the REUSE " "Specification :-(" msgstr "" "Malheureusement, votre projet n'est pas conforme à la version {} de la " "spécification REUSE :-(" #: src/reuse/lint.py:216 msgid "RECOMMENDATIONS" msgstr "" #: src/reuse/lint.py:289 #, python-brace-format msgid "{path}: bad license {lic}\n" msgstr "" #: src/reuse/lint.py:296 #, fuzzy, python-brace-format msgid "{lic_path}: deprecated license\n" msgstr "Licences obsolètes :" #: src/reuse/lint.py:303 #, fuzzy, python-brace-format msgid "{lic_path}: license without file extension\n" msgstr "Licences sans extension de fichier :" #: src/reuse/lint.py:312 #, fuzzy, python-brace-format msgid "{lic_path}: unused license\n" msgstr "Licences inutilisées :" #: src/reuse/lint.py:319 #, python-brace-format msgid "{path}: missing license {lic}\n" msgstr "" #: src/reuse/lint.py:326 #, python-brace-format msgid "{path}: read error\n" msgstr "" #: src/reuse/lint.py:330 #, fuzzy, python-brace-format msgid "{path}: no license identifier\n" msgstr "'{}' n'est pas un identifiant de licence SPDX valide." #: src/reuse/lint.py:334 #, python-brace-format msgid "{path}: no copyright notice\n" msgstr "" #: src/reuse/project.py:262 #, fuzzy, python-brace-format msgid "'{path}' covered by {global_path}" msgstr "'{path}' est couvert par .reuse/dep5" #: src/reuse/project.py:270 #, python-brace-format msgid "" "'{path}' is covered exclusively by REUSE.toml. Not reading the file contents." msgstr "" #: src/reuse/project.py:277 #, python-brace-format msgid "" "'{path}' was detected as a binary file; not searching its contents for REUSE " "information." msgstr "" #: src/reuse/project.py:334 msgid "" "'.reuse/dep5' is deprecated. You are recommended to instead use REUSE.toml. " "Use `reuse convert-dep5` to convert." msgstr "" #: src/reuse/project.py:348 #, python-brace-format msgid "" "Found both '{new_path}' and '{old_path}'. You cannot keep both files " "simultaneously; they are not intercompatible." msgstr "" #: src/reuse/project.py:414 #, python-brace-format msgid "determining identifier of '{path}'" msgstr "résolution de l'identifiant de '{path}'" #: src/reuse/project.py:422 #, python-brace-format msgid "{path} does not have a file extension" msgstr "{path} n'a pas d'extension de fichier" #: src/reuse/project.py:432 #, python-brace-format msgid "" "Could not resolve SPDX License Identifier of {path}, resolving to " "{identifier}. Make sure the license is in the license list found at or that it starts with 'LicenseRef-', and that it has a " "file extension." msgstr "" "Impossible de résoudre l'identifiant de licence SPDX de {path}, utilisation " "de {identifier}. Merci de vérifier soit que la licence est dans la liste " "fournie à, soit qu'elle débute par 'LicenseRef-' " "et qu'elle contient une extension de fichier." #: src/reuse/project.py:444 #, python-brace-format msgid "" "{identifier} is the SPDX License Identifier of both {path} and {other_path}" msgstr "{identifier} est l'identifiant SPXD de {path} comme de {other_path}" #: src/reuse/project.py:483 #, fuzzy msgid "" "project '{}' is not a VCS repository or required VCS software is not " "installed" msgstr "" "le projet n'est pas un répertoire VCS ou le logiciel VCS nécessaire n'est " "pas installé" #: src/reuse/report.py:310 #, python-brace-format msgid "Could not read '{path}'" msgstr "Lecture de '{path}' impossible" #: src/reuse/report.py:317 #, python-brace-format msgid "Unexpected error occurred while parsing '{path}'" msgstr "Erreur inattendue lors de l'analyse de '{path}'" #: src/reuse/report.py:438 msgid "" "Fix bad licenses: At least one license in the LICENSES directory and/or " "provided by 'SPDX-License-Identifier' tags is invalid. They are either not " "valid SPDX License Identifiers or do not start with 'LicenseRef-'. FAQ about " "custom licenses: https://reuse.software/faq/#custom-license" msgstr "" #: src/reuse/report.py:449 msgid "" "Fix deprecated licenses: At least one of the licenses in the LICENSES " "directory and/or provided by an 'SPDX-License-Identifier' tag or in '.reuse/" "dep5' has been deprecated by SPDX. The current list and their respective " "recommended new identifiers can be found here: " msgstr "" #: src/reuse/report.py:460 msgid "" "Fix licenses without file extension: At least one license text file in the " "'LICENSES' directory does not have a '.txt' file extension. Please rename " "the file(s) accordingly." msgstr "" #: src/reuse/report.py:469 msgid "" "Fix missing licenses: For at least one of the license identifiers provided " "by the 'SPDX-License-Identifier' tags, there is no corresponding license " "text file in the 'LICENSES' directory. For SPDX license identifiers, you can " "simply run 'reuse download --all' to get any missing ones. For custom " "licenses (starting with 'LicenseRef-'), you need to add these files yourself." msgstr "" #: src/reuse/report.py:481 msgid "" "Fix unused licenses: At least one of the license text files in 'LICENSES' is " "not referenced by any file, e.g. by an 'SPDX-License-Identifier' tag. Please " "make sure that you either tag the accordingly licensed files properly, or " "delete the unused license text if you are sure that no file or code snippet " "is licensed as such." msgstr "" #: src/reuse/report.py:492 msgid "" "Fix read errors: At least one of the files in your directory cannot be read " "by the tool. Please check the file permissions. You will find the affected " "files at the top of the output as part of the logged error messages." msgstr "" #: src/reuse/report.py:501 msgid "" "Fix missing copyright/licensing information: For one or more files, the tool " "cannot find copyright and/or licensing information. You typically do this by " "adding 'SPDX-FileCopyrightText' and 'SPDX-License-Identifier' tags to each " "file. The tutorial explains additional ways to do this: " msgstr "" #: src/reuse/spdx.py:32 msgid "" "populate the LicenseConcluded field; note that reuse cannot guarantee the " "field is accurate" msgstr "" "compléter le champ LicenseConcluded ; notez que la réutilisation ne garantit " "pas que le champ soit correct" #: src/reuse/spdx.py:39 msgid "name of the person signing off on the SPDX report" msgstr "nom de la personne signataire du rapport SPDX" #: src/reuse/spdx.py:44 msgid "name of the organization signing off on the SPDX report" msgstr "nom de l'organisation signataire du rapport SPDX" #: src/reuse/spdx.py:60 msgid "" "error: --creator-person=NAME or --creator-organization=NAME required when --" "add-license-concluded is provided" msgstr "" "erreur : spécifier --creator-person=NOM ou --creator-organization=NOM est " "nécessaire quand --add-license-concluded est fourni" #: src/reuse/spdx.py:75 #, python-brace-format msgid "" "'{path}' does not match a common SPDX file pattern. Find the suggested " "naming conventions here: https://spdx.github.io/spdx-spec/conformance/#44-" "standard-data-format-requirements" msgstr "" "{path} ne correspond pas à un motif de fichier SPDX commun. Vérifiez les " "conventions de nommage conseillées à l'adresse https://spdx.github.io/spdx-" "spec/conformance/#44-standard-data-format-requirements" #: /usr/lib/python3.10/argparse.py:308 msgid "usage: " msgstr "usage : " #: /usr/lib/python3.10/argparse.py:880 msgid ".__call__() not defined" msgstr ".__call__() est indéfini" #: /usr/lib/python3.10/argparse.py:1223 #, python-format msgid "unknown parser %(parser_name)r (choices: %(choices)s)" msgstr "analyseur %(parser_name)r inconnu (choix : %(choices)s)" #: /usr/lib/python3.10/argparse.py:1283 #, python-format msgid "argument \"-\" with mode %r" msgstr "argument \"-\" avec le mode %r" #: /usr/lib/python3.10/argparse.py:1292 #, python-format msgid "can't open '%(filename)s': %(error)s" msgstr "'%(filename)s' ne peut pas être ouvert : %(error)s" #: /usr/lib/python3.10/argparse.py:1501 #, python-format msgid "cannot merge actions - two groups are named %r" msgstr "impossible de fusionner les actions - deux groupes sont nommés %r" #: /usr/lib/python3.10/argparse.py:1539 msgid "'required' is an invalid argument for positionals" msgstr "'required' est un argument invalide pour les positionnels" #: /usr/lib/python3.10/argparse.py:1561 #, python-format msgid "" "invalid option string %(option)r: must start with a character " "%(prefix_chars)r" msgstr "" "option de chaîne %(option)r invalide : doit débuter par un caractère " "%(prefix_chars)r" #: /usr/lib/python3.10/argparse.py:1579 #, python-format msgid "dest= is required for options like %r" msgstr "dest= est nécessaire pour les options comme %r" #: /usr/lib/python3.10/argparse.py:1596 #, python-format msgid "invalid conflict_resolution value: %r" msgstr "valeur de résolution de conflit invalide : %r" #: /usr/lib/python3.10/argparse.py:1614 #, python-format msgid "conflicting option string: %s" msgid_plural "conflicting option strings: %s" msgstr[0] "chaîne d'options contradictoire : %s" msgstr[1] "chaînes d'options contradictoires : %s" #: /usr/lib/python3.10/argparse.py:1680 msgid "mutually exclusive arguments must be optional" msgstr "les arguments mutuellement exclusifs doivent être facultatifs" #: /usr/lib/python3.10/argparse.py:1748 msgid "positional arguments" msgstr "arguments positionnels" #: /usr/lib/python3.10/argparse.py:1749 msgid "options" msgstr "" #: /usr/lib/python3.10/argparse.py:1764 msgid "show this help message and exit" msgstr "afficher ce message d'aide et quitter" #: /usr/lib/python3.10/argparse.py:1795 msgid "cannot have multiple subparser arguments" msgstr "impossible de considérer des arguments de sous-analyse multiples" #: /usr/lib/python3.10/argparse.py:1847 /usr/lib/python3.10/argparse.py:2362 #, python-format msgid "unrecognized arguments: %s" msgstr "arguments non reconnus : %s" #: /usr/lib/python3.10/argparse.py:1948 #, python-format msgid "not allowed with argument %s" msgstr "non autorisé avec l'argument %s" #: /usr/lib/python3.10/argparse.py:1998 /usr/lib/python3.10/argparse.py:2012 #, python-format msgid "ignored explicit argument %r" msgstr "l'argument explicite %r est ignoré" #: /usr/lib/python3.10/argparse.py:2119 #, python-format msgid "the following arguments are required: %s" msgstr "les arguments suivants sont nécessaires : %s" #: /usr/lib/python3.10/argparse.py:2134 #, python-format msgid "one of the arguments %s is required" msgstr "un des arguments %s est nécessaire" #: /usr/lib/python3.10/argparse.py:2177 msgid "expected one argument" msgstr "un argument est attendu" #: /usr/lib/python3.10/argparse.py:2178 msgid "expected at most one argument" msgstr "un argument au plus est attendu" #: /usr/lib/python3.10/argparse.py:2179 msgid "expected at least one argument" msgstr "un argument au moins est attendu" #: /usr/lib/python3.10/argparse.py:2183 #, python-format msgid "expected %s argument" msgid_plural "expected %s arguments" msgstr[0] "l'argument %s est attendu" msgstr[1] "les arguments %s sont attendus" #: /usr/lib/python3.10/argparse.py:2241 #, python-format msgid "ambiguous option: %(option)s could match %(matches)s" msgstr "option ambigüe : %(option)s ne correspond pas à %(matches)s" #: /usr/lib/python3.10/argparse.py:2305 #, python-format msgid "unexpected option string: %s" msgstr "option inattendue : %s" #: /usr/lib/python3.10/argparse.py:2502 #, python-format msgid "%r is not callable" msgstr "%r ne peut être appelé" #: /usr/lib/python3.10/argparse.py:2519 #, python-format msgid "invalid %(type)s value: %(value)r" msgstr "valeur %(type)s invalide : %(value)r" #: /usr/lib/python3.10/argparse.py:2530 #, python-format msgid "invalid choice: %(value)r (choose from %(choices)s)" msgstr "choix non valide : %(value)r (choisir parmi %(choices)s)" #: /usr/lib/python3.10/argparse.py:2606 #, python-format msgid "%(prog)s: error: %(message)s\n" msgstr "%(prog)s : erreur : %(message)s\n" #, fuzzy, python-brace-format #~ msgid "" #~ "Copyright and licensing information for '{original_path}' has been found " #~ "in both '{path}' and in the DEP5 file located at '{dep5_path}'. The " #~ "information for these two sources has been aggregated. You are " #~ "recommended to instead use REUSE.toml, where you can specify the order of " #~ "precedence. Use `reuse convert-dep5` to convert. Run with `--suppress-" #~ "deprecation` to hide this warning." #~ msgstr "" #~ "Les données de droits d'auteur et de licence pour '{original_path}' ont " #~ "été trouvées dans '{path}' et dans le fichier DEP5 placé dans " #~ "'{dep5_path}'. Les données de ces deux sources ont été agrégées. À " #~ "l'avenir, cette procédure sera modifiée et vous devrez autoriser " #~ "explicitement l'agrégation. Consultez . Aucune action de votre part n'est actuellement nécessaire. " #~ "Pour masquer cet avertissement à l'avenir, exécutez la commande avec " #~ "l'argument `--suppress-deprecation`." #~ msgid "initialize REUSE project" #~ msgstr "initialiser le projet REUSE" #~ msgid "" #~ "What license is your project under? Provide the SPDX License Identifier. " #~ "See for the list." #~ msgstr "" #~ "Sous quelle licence est enregistré votre projet ? Merci de fournir un " #~ "identifiant de licence SPDX. Consultez pour " #~ "la liste des licences." #~ msgid "" #~ "What other license is your project under? Provide the SPDX License " #~ "Identifier." #~ msgstr "" #~ "Sous quelle autre licence est enregistré votre projet ? Merci de fournir " #~ "un identifiant de licence SPDX." #~ msgid "To stop adding licenses, hit RETURN." #~ msgstr "Pour finir l'ajout de licences, presser ENTRÉE." #~ msgid "Project already initialized" #~ msgstr "Le projet est déjà initialisé" #~ msgid "Initializing project for REUSE." #~ msgstr "Initialisation du projet pour REUSE." #~ msgid "What is the name of the project?" #~ msgstr "Quel est le nom du projet ?" #~ msgid "What is the internet address of the project?" #~ msgstr "Quelle est l'adresse internet du projet ?" #~ msgid "What is the name of the maintainer?" #~ msgstr "Quel est le nom de la personne chargée de la maintenance ?" #~ msgid "What is the e-mail address of the maintainer?" #~ msgstr "" #~ "Quelle est l'adresse électronique de la personne chargée de la " #~ "maintenance ?" #~ msgid "All done! Initializing now." #~ msgstr "Tout est prêt ! Maintenant, on initialise." #~ msgid "{} already exists" #~ msgstr "{} existe déjà" #~ msgid "Could not download {}" #~ msgstr "{} n'a pas pu être téléchargé" #~ msgid "Initialization complete." #~ msgstr "Initialisation terminée." #, fuzzy #~ msgid "" #~ "Add copyright and licensing into the header of one or more files.\n" #~ "\n" #~ "By using --copyright and --license, you can specify which copyright " #~ "holders and licenses to add to the headers of the given files.\n" #~ "\n" #~ "By using --contributor, you can specify people or entity that contributed " #~ "but are not copyright holder of the given files.\n" #~ "The first comment is replaced with a new header containing the new " #~ "copyright and licensing information and its former copyright and " #~ "licensing. If you want to keep the first comment intact, use --no-" #~ "replace.\n" #~ "\n" #~ "The comment style should be auto-detected for your files. If a comment " #~ "style could not be detected and --skip-unrecognised is not specified, the " #~ "process aborts. Use --style to specify or override the comment style to " #~ "use.\n" #~ "\n" #~ "A single-line comment style is used when it is available. If no single-" #~ "line comment style is available, a multi-line comment style is used. You " #~ "can force a certain comment style using --single-line or --multi-line.\n" #~ "\n" #~ "You can change the template of the header comment by using --template. " #~ "Place a Jinja2 template in .reuse/templates/mytemplate.jinja2. You can " #~ "use the template by specifying '--template mytemplate'. Read the online " #~ "documentation on how to use this feature.\n" #~ "\n" #~ "If a binary file is detected, or if --force-dot-license is specified, the " #~ "header is placed in a .license file." #~ msgstr "" #~ "Ajout des informations de droits d'auteur et de licence dans les en-têtes " #~ "d'un ou plusieurs fichiers.\n" #~ "\n" #~ "En sélectionnant --copyright et --license, vous pouvez spécifier quels " #~ "titulaires de droits et licences sont ajoutés aux en-têtes des fichiers " #~ "listés.\n" #~ "\n" #~ "En sélectionnant --contributor, vous pouvez spécifier des personnes ou " #~ "une organisation qui ont contribué aux fichiers listés sans être " #~ "détenteurs des droits d'auteur.\n" #~ "Le premier commentaire est remplacé par un nouvel en-tête contenant les " #~ "nouvelles données de droits d'auteur et de licence ainsi que les données " #~ "antérieures. Si vous souhaitez conserver le premier commentaire sans " #~ "aucun remplacement, utilisez --no-replace.\n" #~ "\n" #~ "Les styles de commentaire doivent être détectés automatiquement pour vos " #~ "fichiers. Si un style de commentaire ne peut pas être détecté, le " #~ "processus est interrompu. Utilisez --style pour spécifier ou passer outre " #~ "le style de commentaire utilisé.\n" #~ "\n" #~ "Un style de commentaire monoligne est utilisé s'il est disponible. Si " #~ "aucun style de commentaire monoligne n'est disponible, un style de " #~ "commentaire multiligne sera utilisé. Vous pouvez forcer le recours à un " #~ "style de commentaire au moyen de --single-line ou --multi-line.\n" #~ "\n" #~ "Vous pouvez modifier le modèle des commentaires d'en-tête en utilisant " #~ "l'option --template. Placez un modèle Jinja2 dans le répertoire .reuse/" #~ "templates/mytemplate.jinja2. Vous pouvez utiliser le modèle en précisant " #~ "'--template mytemplate'. Consultez la documentation en ligne pour plus " #~ "d'informations sur l'utilisation de cette fonctionnalité.\n" #~ "\n" #~ "Si un fichier binaire est détecté ou si --explicit-license est utilisé, " #~ "l'en-tête est placé dans un fichier .license." #~ msgid "" #~ "Download a license and place it in the LICENSES/ directory.\n" #~ "\n" #~ "The LICENSES/ directory is automatically found in the following order:\n" #~ "\n" #~ "- The LICENSES/ directory in the root of the VCS repository.\n" #~ "\n" #~ "- The current directory if its name is LICENSES.\n" #~ "\n" #~ "- The LICENSES/ directory in the current directory.\n" #~ "\n" #~ "If the LICENSES/ directory cannot be found, one is simply created." #~ msgstr "" #~ "Téléchargez une licence et placez-la dans le répertoire LICENSES/.\n" #~ "\n" #~ "Les répertoires LICENSES/ se trouvent automatiquement dans l'ordre " #~ "suivant :\n" #~ "\n" #~ "- Le répertoire LICENSES/ à la racine du répertoire VCS.\n" #~ "\n" #~ "- Le répertoire actuel, si son nom est LICENSES.\n" #~ "\n" #~ "- Le répertoire LICENSES/ dans le répertoire courant.\n" #~ "\n" #~ "Si le répertoire LICENSES/ n'est pas trouvé, il sera simplement créé." #~ msgid ".reuse/dep5 has syntax errors" #~ msgstr ".reuse/dep5 contient des erreurs de syntaxe" #~ msgid "optional arguments" #~ msgstr "arguments facultatifs" #~ msgid "deprecated in favor of annotate" #~ msgstr "obsolète et remplacé par annotate" #~ msgid "'reuse addheader' has been deprecated in favour of 'reuse annotate'" #~ msgstr "\"reuse addheader\" est obsolète et remplacé par \"reuse annotate\"" #~ msgid "option --exclude-year and --year are mutually exclusive" #~ msgstr "les options --exclude-year et --year sont mutuellement exclusives" #~ msgid "option --single-line and --multi-line are mutually exclusive" #~ msgstr "" #~ "les options --single-line et --multi-line sont mutuellement exclusives" #~ msgid "" #~ "--explicit-license has been deprecated in favour of --force-dot-license" #~ msgstr "--explicit-license est obsolète et remplacé par --force-dot-license" #~ msgid "Downloading {}" #~ msgstr "Téléchargement de {}" #, fuzzy #~ msgid "conflicting subparser: %s" #~ msgstr "chane d'options contradictoire : %s" #, fuzzy #~ msgid "conflicting subparser alias: %s" #~ msgstr "chane d'options contradictoire : %s" #~ msgid "can't open '%s': %s" #~ msgstr "impossible d'ouvrir '%s' : %s" #~ msgid "place header in path.license instead of path" #~ msgstr "placez l'en-tête dans path.license au lieu de path" #~ msgid "could not find Git" #~ msgstr "Git ne peut pas être trouvé" reuse-tool-4.0.3/po/gl.po000066400000000000000000001033071464275211500152070ustar00rootroot00000000000000# SPDX-FileCopyrightText: 2020 pd # # SPDX-License-Identifier: GPL-3.0-or-later msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-07-03 13:09+0000\n" "PO-Revision-Date: 2023-06-21 09:53+0000\n" "Last-Translator: Anonymous \n" "Language-Team: Galician \n" "Language: gl\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 4.18.1\n" #: src/reuse/_annotate.py:74 #, python-brace-format msgid "" "'{path}' does not support single-line comments, please do not use --single-" "line" msgstr "" #: src/reuse/_annotate.py:81 #, python-brace-format msgid "" "'{path}' does not support multi-line comments, please do not use --multi-line" msgstr "" #: src/reuse/_annotate.py:136 #, python-brace-format msgid "Skipped unrecognised file '{path}'" msgstr "" #: src/reuse/_annotate.py:142 #, python-brace-format msgid "'{path}' is not recognised; creating '{path}.license'" msgstr "" #: src/reuse/_annotate.py:158 #, python-brace-format msgid "Skipped file '{path}' already containing REUSE information" msgstr "" #: src/reuse/_annotate.py:192 #, python-brace-format msgid "Error: Could not create comment for '{path}'" msgstr "Erro: Non se pode crear un comentario para '{path}'" #: src/reuse/_annotate.py:199 #, python-brace-format msgid "" "Error: Generated comment header for '{path}' is missing copyright lines or " "license expressions. The template is probably incorrect. Did not write new " "header." msgstr "" "Erro: A cabeceira comentada xerada para '{path}' non contén liñas de " "copyright ou expresións de licenza. Posibelmente o modelo é incorrecto. Non " "se escribiu unha nova cabecereira." #. TODO: This may need to be rephrased more elegantly. #: src/reuse/_annotate.py:210 #, python-brace-format msgid "Successfully changed header of {path}" msgstr "A cabeceira de {path} cambiada con éxito" #: src/reuse/_annotate.py:221 msgid "--skip-unrecognised has no effect when used together with --style" msgstr "" #: src/reuse/_annotate.py:231 #, fuzzy msgid "option --contributor, --copyright or --license is required" msgstr "precisase a opción --copyright ou --license" #: src/reuse/_annotate.py:272 #, python-brace-format msgid "template {template} could not be found" msgstr "no se atopa o modelo {template}" #: src/reuse/_annotate.py:341 src/reuse/_util.py:573 msgid "can't write to '{}'" msgstr "non se pode escribir en '{}'" #: src/reuse/_annotate.py:366 #, fuzzy msgid "" "The following files do not have a recognised file extension. Please use --" "style, --force-dot-license, --fallback-dot-license, or --skip-unrecognised:" msgstr "" "'{path}' non ten unha extensión de arquivo recoñecida, precisa usar --style " "ou --explicit-license" #: src/reuse/_annotate.py:382 msgid "copyright statement, repeatable" msgstr "declaración de copyright, repetibel" #: src/reuse/_annotate.py:389 msgid "SPDX Identifier, repeatable" msgstr "Identificador SPDX, repetibel" #: src/reuse/_annotate.py:395 #, fuzzy msgid "file contributor, repeatable" msgstr "Identificador SPDX, repetibel" #: src/reuse/_annotate.py:403 msgid "year of copyright statement, optional" msgstr "ano da declaración de copyright, opcional" #: src/reuse/_annotate.py:411 msgid "comment style to use, optional" msgstr "estilo de comentario a usar, opcional" #: src/reuse/_annotate.py:417 #, fuzzy msgid "copyright prefix to use, optional" msgstr "estilo de comentario a usar, opcional" #: src/reuse/_annotate.py:430 msgid "name of template to use, optional" msgstr "nome do modelo a usar, opcional" #: src/reuse/_annotate.py:435 msgid "do not include year in statement" msgstr "non incluir ano na declaración" #: src/reuse/_annotate.py:440 #, fuzzy msgid "merge copyright lines if copyright statements are identical" msgstr "ano da declaración de copyright, opcional" #: src/reuse/_annotate.py:446 #, fuzzy msgid "force single-line comment style, optional" msgstr "estilo de comentario a usar, opcional" #: src/reuse/_annotate.py:451 #, fuzzy msgid "force multi-line comment style, optional" msgstr "estilo de comentario a usar, opcional" #: src/reuse/_annotate.py:458 msgid "add headers to all files under specified directories recursively" msgstr "" #: src/reuse/_annotate.py:465 msgid "do not replace the first header in the file; just add a new one" msgstr "" #: src/reuse/_annotate.py:473 msgid "always write a .license file instead of a header inside the file" msgstr "" #: src/reuse/_annotate.py:480 msgid "write a .license file to files with unrecognised comment styles" msgstr "" #: src/reuse/_annotate.py:486 msgid "skip files with unrecognised comment styles" msgstr "" #: src/reuse/_annotate.py:497 #, fuzzy msgid "skip files that already contain REUSE information" msgstr "Arquivos con información de licenza: {count} / {total}" #: src/reuse/_annotate.py:532 #, python-brace-format msgid "'{path}' is a binary, therefore using '{new_path}' for the header" msgstr "'{path}' é binario, logo úsase '{new_path}' para a cabeceira" #: src/reuse/_main.py:39 msgid "" "reuse is a tool for compliance with the REUSE recommendations. See for more information, and " "for the online documentation." msgstr "" "reuse é unha ferramenta para o cumprimento das recomendacións REUSE. Ver " " para máis información e para a documentación en liña." #: src/reuse/_main.py:45 msgid "" "This version of reuse is compatible with version {} of the REUSE " "Specification." msgstr "" "Esta versión de reuse é compatible coa versión {} da especificación REUSE." #: src/reuse/_main.py:48 msgid "Support the FSFE's work:" msgstr "Apoie o traballo da FSFE:" #: src/reuse/_main.py:52 msgid "" "Donations are critical to our strength and autonomy. They enable us to " "continue working for Free Software wherever necessary. Please consider " "making a donation at ." msgstr "" "As doazóns son críticas para a nosa forza e autonomía. Permítennos seguir " "traballando polo software libre onde sexa necesario. Considere facer unha " "doazón a ." #: src/reuse/_main.py:75 msgid "enable debug statements" msgstr "habilitar sentencias de depuración" #: src/reuse/_main.py:80 msgid "hide deprecation warnings" msgstr "" #: src/reuse/_main.py:85 msgid "do not skip over Git submodules" msgstr "non salte os submódulos de Git" #: src/reuse/_main.py:90 #, fuzzy msgid "do not skip over Meson subprojects" msgstr "non salte os submódulos de Git" #: src/reuse/_main.py:95 msgid "do not use multiprocessing" msgstr "non empregue multiprocesamento" #: src/reuse/_main.py:102 msgid "define root of project" msgstr "definir a raíz do proxecto" #: src/reuse/_main.py:107 msgid "show program's version number and exit" msgstr "mostrar o número de versión do programa e saír" #: src/reuse/_main.py:111 msgid "subcommands" msgstr "subcomandos" #: src/reuse/_main.py:118 msgid "add copyright and licensing into the header of files" msgstr "engadir copyright e licenza na cabeceira dos arquivos" #: src/reuse/_main.py:121 msgid "" "Add copyright and licensing into the header of one or more files.\n" "\n" "By using --copyright and --license, you can specify which copyright holders " "and licenses to add to the headers of the given files.\n" "\n" "By using --contributor, you can specify people or entity that contributed " "but are not copyright holder of the given files." msgstr "" #: src/reuse/_main.py:140 msgid "download a license and place it in the LICENSES/ directory" msgstr "Descargar unha licenza e gardala na carpeta LICENSES/" #: src/reuse/_main.py:142 #, fuzzy msgid "Download a license and place it in the LICENSES/ directory." msgstr "Descargar unha licenza e gardala na carpeta LICENSES/" #: src/reuse/_main.py:151 msgid "list all non-compliant files" msgstr "listar todos os arquivos que non cumplen os criterios" #: src/reuse/_main.py:154 #, python-brace-format msgid "" "Lint the project directory for compliance with version {reuse_version} of " "the REUSE Specification. You can find the latest version of the " "specification at .\n" "\n" "Specifically, the following criteria are checked:\n" "\n" "- Are there any bad (unrecognised, not compliant with SPDX) licenses in the " "project?\n" "\n" "- Are any licenses referred to inside of the project, but not included in " "the LICENSES/ directory?\n" "\n" "- Are any licenses included in the LICENSES/ directory that are not used " "inside of the project?\n" "\n" "- Do all files have valid copyright and licensing information?" msgstr "" "Verificar que a carpeta do proxecto cumple coa versión {reuse_version} da " "especificación REUSE. Pode atopar a última versión da especificación en " ".\n" "\n" "Comprobase específicamente os seguintes criterios:\n" "\n" "- Existen licenzas inapropiadas (non recoñecidas ou que incumplen o SPDX) no " "proxecto?\n" "\n" "- Hai algunha licenza mencionada no proxecto que non está incluida na " "carpeta LICENSES/?\n" "\n" "- A carpeta LICENSES/ contén licenzas non usadas no proxecto?\n" "\n" "- Todos os arquivos teñen información correcta de copyright e licenza?" #: src/reuse/_main.py:181 msgid "print the project's bill of materials in SPDX format" msgstr "imprimir a lista de materiales do proxecto en formato SPDX" #: src/reuse/_main.py:189 msgid "list all supported SPDX licenses" msgstr "" #: src/reuse/_main.py:198 msgid "convert .reuse/dep5 to REUSE.toml" msgstr "" #: src/reuse/_main.py:263 #, python-brace-format msgid "'{path}' could not be decoded as UTF-8." msgstr "" #: src/reuse/_main.py:269 #, python-brace-format msgid "" "'{path}' could not be parsed. We received the following error message: " "{message}" msgstr "" #: src/reuse/_util.py:368 src/reuse/global_licensing.py:218 #, python-brace-format msgid "Could not parse '{expression}'" msgstr "Non se pode analizar '{expression}'" #: src/reuse/_util.py:424 #, python-brace-format msgid "" "'{path}' holds an SPDX expression that cannot be parsed, skipping the file" msgstr "" "'{path}' inclúe unha expresión SPDX que non se pode analizar, saltando o " "arquivo" #: src/reuse/_util.py:556 msgid "'{}' is not a file" msgstr "'{}' non é un arquivo" #: src/reuse/_util.py:559 msgid "'{}' is not a directory" msgstr "'{}' non é un directorio" #: src/reuse/_util.py:562 msgid "can't open '{}'" msgstr "non se pode abrir '{}'" #: src/reuse/_util.py:567 msgid "can't write to directory '{}'" msgstr "non se pode escribir no directorio '{}'" #: src/reuse/_util.py:586 msgid "can't read or write '{}'" msgstr "non se pode ler ou escribir en '{}'" #: src/reuse/_util.py:596 msgid "'{}' is not a valid SPDX expression, aborting" msgstr "'{}' non é unha expresión SPDX válida, cancelando" #: src/reuse/_util.py:624 msgid "'{}' is not a valid SPDX License Identifier." msgstr "'{}' non é un Identificador de Licenza SPDX válido." #: src/reuse/_util.py:631 msgid "Did you mean:" msgstr "" #: src/reuse/_util.py:638 msgid "" "See for a list of valid SPDX License " "Identifiers." msgstr "" "Consulte unha lista de Identificadores de Licenza SPDX válidos en ." #: src/reuse/convert_dep5.py:118 #, fuzzy msgid "no '.reuse/dep5' file" msgstr "Creando .reuse/dep5" #: src/reuse/download.py:130 msgid "SPDX License Identifier of license" msgstr "Identificador de Licenza SPDX da licenza" #: src/reuse/download.py:135 msgid "download all missing licenses detected in the project" msgstr "descargar todas as licenzas detectadas mais non atopadas no proxecto" #: src/reuse/download.py:145 msgid "" "source from which to copy custom LicenseRef- licenses, either a directory " "that contains the file or the file itself" msgstr "" #: src/reuse/download.py:156 #, python-brace-format msgid "Error: {spdx_identifier} already exists." msgstr "Erro: {spdx_identifier} xa existe." #: src/reuse/download.py:163 #, fuzzy, python-brace-format msgid "Error: {path} does not exist." msgstr "'{path}' non remata en .spdx" #: src/reuse/download.py:166 msgid "Error: Failed to download license." msgstr "Erro: Fallo descargando a licenza." #: src/reuse/download.py:171 msgid "Is your internet connection working?" msgstr "Está a funcionar a súa conexión a internet?" #: src/reuse/download.py:176 #, python-brace-format msgid "Successfully downloaded {spdx_identifier}." msgstr "Descargouse correctamente o {spdx_identifier}." #: src/reuse/download.py:188 msgid "--output has no effect when used together with --all" msgstr "" #: src/reuse/download.py:192 msgid "the following arguments are required: license" msgstr "requirense os seguintes argumentos: licenza" #: src/reuse/download.py:194 msgid "cannot use --output with more than one license" msgstr "non se pode usar --output con máis dunha licenza" #: src/reuse/global_licensing.py:109 #, python-brace-format msgid "" "{attr_name} must be a {type_name} (got {value} that is a {value_class})." msgstr "" #: src/reuse/global_licensing.py:122 #, python-brace-format msgid "" "Item in {attr_name} collection must be a {type_name} (got {item_value} that " "is a {item_class})." msgstr "" #: src/reuse/global_licensing.py:133 #, python-brace-format msgid "{attr_name} must not be empty." msgstr "" #: src/reuse/global_licensing.py:156 #, python-brace-format msgid "{name} must be a {type} (got {value} that is a {value_type})." msgstr "" #: src/reuse/global_licensing.py:179 #, python-brace-format msgid "" "The value of 'precedence' must be one of {precedence_vals} (got {received})" msgstr "" #: src/reuse/header.py:99 msgid "generated comment is missing copyright lines or license expressions" msgstr "" "o comentario xerado non ten liñas de copyright ou expresións de licenza" #: src/reuse/lint.py:30 msgid "prevents output" msgstr "" #: src/reuse/lint.py:33 msgid "formats output as JSON" msgstr "" #: src/reuse/lint.py:39 msgid "formats output as plain text" msgstr "" #: src/reuse/lint.py:45 msgid "formats output as errors per line" msgstr "" #: src/reuse/lint.py:64 msgid "BAD LICENSES" msgstr "LICENZAS DEFECTUOSAS" #: src/reuse/lint.py:66 src/reuse/lint.py:95 msgid "'{}' found in:" msgstr "'{}' atopado en:" #: src/reuse/lint.py:73 msgid "DEPRECATED LICENSES" msgstr "LICENZAS OBSOLETAS" #: src/reuse/lint.py:75 msgid "The following licenses are deprecated by SPDX:" msgstr "As seguintes licenzas son obsoletas para SPDX:" #: src/reuse/lint.py:83 msgid "LICENSES WITHOUT FILE EXTENSION" msgstr "LICENZAS SEN EXTENSIÓN DE ARQUIVO" #: src/reuse/lint.py:85 msgid "The following licenses have no file extension:" msgstr "As seguintes licenzas non teñen extesión de arquivo:" #: src/reuse/lint.py:93 msgid "MISSING LICENSES" msgstr "LICENZAS NON ATOPADAS" #: src/reuse/lint.py:102 msgid "UNUSED LICENSES" msgstr "LICENZAS SEN USO" #: src/reuse/lint.py:103 msgid "The following licenses are not used:" msgstr "As seguintes licenzas non se usan:" #: src/reuse/lint.py:110 msgid "READ ERRORS" msgstr "ERROS DE LECTURA" #: src/reuse/lint.py:111 msgid "Could not read:" msgstr "Non se pode ler:" #: src/reuse/lint.py:132 msgid "MISSING COPYRIGHT AND LICENSING INFORMATION" msgstr "NON SE ATOPA INFORMACIÓN DE LICENZA OU COPYRIGHT" #: src/reuse/lint.py:138 msgid "The following files have no copyright and licensing information:" msgstr "" "Os seguintes arquivos non teñen información de licenza nen de copyright:" #: src/reuse/lint.py:149 msgid "The following files have no copyright information:" msgstr "Os seguintes arquivos non teñen información de copyright:" #: src/reuse/lint.py:158 msgid "The following files have no licensing information:" msgstr "Os seguintes arquivos non teñen información de licenza:" #: src/reuse/lint.py:166 msgid "SUMMARY" msgstr "RESUMO" #: src/reuse/lint.py:171 msgid "Bad licenses:" msgstr "Licenzas defectuosas:" #: src/reuse/lint.py:172 msgid "Deprecated licenses:" msgstr "Licenzas obsoletas:" #: src/reuse/lint.py:173 msgid "Licenses without file extension:" msgstr "Licenzas sen extensión de arquivo:" #: src/reuse/lint.py:176 msgid "Missing licenses:" msgstr "Licenzas non atopadas:" #: src/reuse/lint.py:177 msgid "Unused licenses:" msgstr "Licenzas non usadas:" #: src/reuse/lint.py:178 msgid "Used licenses:" msgstr "Licenzas usadas:" #: src/reuse/lint.py:179 #, fuzzy msgid "Read errors:" msgstr "Erros de lectura: {count}" #: src/reuse/lint.py:181 #, fuzzy msgid "Files with copyright information:" msgstr "Arquivos con información de copyright: {count} / {total}" #: src/reuse/lint.py:185 #, fuzzy msgid "Files with license information:" msgstr "Arquivos con información de licenza: {count} / {total}" #: src/reuse/lint.py:202 msgid "" "Congratulations! Your project is compliant with version {} of the REUSE " "Specification :-)" msgstr "" "Congratulacións! O seu proxecto cumple coa versión {} da especificación " "REUSE :-)" #: src/reuse/lint.py:209 msgid "" "Unfortunately, your project is not compliant with version {} of the REUSE " "Specification :-(" msgstr "" "Desgraciadamente o seu proxecto non cumple coa versión {} da especificación " "REUSE :-(" #: src/reuse/lint.py:216 msgid "RECOMMENDATIONS" msgstr "" #: src/reuse/lint.py:289 #, python-brace-format msgid "{path}: bad license {lic}\n" msgstr "" #: src/reuse/lint.py:296 #, fuzzy, python-brace-format msgid "{lic_path}: deprecated license\n" msgstr "Licenzas obsoletas:" #: src/reuse/lint.py:303 #, fuzzy, python-brace-format msgid "{lic_path}: license without file extension\n" msgstr "Licenzas sen extensión de arquivo:" #: src/reuse/lint.py:312 #, fuzzy, python-brace-format msgid "{lic_path}: unused license\n" msgstr "Licenzas non usadas:" #: src/reuse/lint.py:319 #, python-brace-format msgid "{path}: missing license {lic}\n" msgstr "" #: src/reuse/lint.py:326 #, python-brace-format msgid "{path}: read error\n" msgstr "" #: src/reuse/lint.py:330 #, fuzzy, python-brace-format msgid "{path}: no license identifier\n" msgstr "'{}' non é un Identificador de Licenza SPDX válido." #: src/reuse/lint.py:334 #, python-brace-format msgid "{path}: no copyright notice\n" msgstr "" #: src/reuse/project.py:262 #, fuzzy, python-brace-format msgid "'{path}' covered by {global_path}" msgstr "'{path}' cuberto por .reuse/dep5" #: src/reuse/project.py:270 #, python-brace-format msgid "" "'{path}' is covered exclusively by REUSE.toml. Not reading the file contents." msgstr "" #: src/reuse/project.py:277 #, python-brace-format msgid "" "'{path}' was detected as a binary file; not searching its contents for REUSE " "information." msgstr "" #: src/reuse/project.py:334 msgid "" "'.reuse/dep5' is deprecated. You are recommended to instead use REUSE.toml. " "Use `reuse convert-dep5` to convert." msgstr "" #: src/reuse/project.py:348 #, python-brace-format msgid "" "Found both '{new_path}' and '{old_path}'. You cannot keep both files " "simultaneously; they are not intercompatible." msgstr "" #: src/reuse/project.py:414 #, python-brace-format msgid "determining identifier of '{path}'" msgstr "resolvendo o identificador de '{path}'" #: src/reuse/project.py:422 #, python-brace-format msgid "{path} does not have a file extension" msgstr "{path} non ten extensión de arquivo" #: src/reuse/project.py:432 #, python-brace-format msgid "" "Could not resolve SPDX License Identifier of {path}, resolving to " "{identifier}. Make sure the license is in the license list found at or that it starts with 'LicenseRef-', and that it has a " "file extension." msgstr "" "Non se pode resolver o Identificador de Licenza SPDX de {path}, resólvese " "como {identifier}. Asegúrese que a licenza está na lista publicada en " " ou que comeza con 'LicenseRef-' e ten unha " "extensión de arquivo." #: src/reuse/project.py:444 #, python-brace-format msgid "" "{identifier} is the SPDX License Identifier of both {path} and {other_path}" msgstr "" "{identifier} é o Identificador de Licenza SPDX de ambos os dous {path} e " "{other_path}" #: src/reuse/project.py:483 msgid "" "project '{}' is not a VCS repository or required VCS software is not " "installed" msgstr "" #: src/reuse/report.py:310 #, python-brace-format msgid "Could not read '{path}'" msgstr "Non se pode ler '{path}'" #: src/reuse/report.py:317 #, python-brace-format msgid "Unexpected error occurred while parsing '{path}'" msgstr "Aconteceu un erro inesperado lendo '{path}'" #: src/reuse/report.py:438 msgid "" "Fix bad licenses: At least one license in the LICENSES directory and/or " "provided by 'SPDX-License-Identifier' tags is invalid. They are either not " "valid SPDX License Identifiers or do not start with 'LicenseRef-'. FAQ about " "custom licenses: https://reuse.software/faq/#custom-license" msgstr "" #: src/reuse/report.py:449 msgid "" "Fix deprecated licenses: At least one of the licenses in the LICENSES " "directory and/or provided by an 'SPDX-License-Identifier' tag or in '.reuse/" "dep5' has been deprecated by SPDX. The current list and their respective " "recommended new identifiers can be found here: " msgstr "" #: src/reuse/report.py:460 msgid "" "Fix licenses without file extension: At least one license text file in the " "'LICENSES' directory does not have a '.txt' file extension. Please rename " "the file(s) accordingly." msgstr "" #: src/reuse/report.py:469 msgid "" "Fix missing licenses: For at least one of the license identifiers provided " "by the 'SPDX-License-Identifier' tags, there is no corresponding license " "text file in the 'LICENSES' directory. For SPDX license identifiers, you can " "simply run 'reuse download --all' to get any missing ones. For custom " "licenses (starting with 'LicenseRef-'), you need to add these files yourself." msgstr "" #: src/reuse/report.py:481 msgid "" "Fix unused licenses: At least one of the license text files in 'LICENSES' is " "not referenced by any file, e.g. by an 'SPDX-License-Identifier' tag. Please " "make sure that you either tag the accordingly licensed files properly, or " "delete the unused license text if you are sure that no file or code snippet " "is licensed as such." msgstr "" #: src/reuse/report.py:492 msgid "" "Fix read errors: At least one of the files in your directory cannot be read " "by the tool. Please check the file permissions. You will find the affected " "files at the top of the output as part of the logged error messages." msgstr "" #: src/reuse/report.py:501 msgid "" "Fix missing copyright/licensing information: For one or more files, the tool " "cannot find copyright and/or licensing information. You typically do this by " "adding 'SPDX-FileCopyrightText' and 'SPDX-License-Identifier' tags to each " "file. The tutorial explains additional ways to do this: " msgstr "" #: src/reuse/spdx.py:32 msgid "" "populate the LicenseConcluded field; note that reuse cannot guarantee the " "field is accurate" msgstr "" #: src/reuse/spdx.py:39 msgid "name of the person signing off on the SPDX report" msgstr "" #: src/reuse/spdx.py:44 msgid "name of the organization signing off on the SPDX report" msgstr "" #: src/reuse/spdx.py:60 msgid "" "error: --creator-person=NAME or --creator-organization=NAME required when --" "add-license-concluded is provided" msgstr "" #: src/reuse/spdx.py:75 #, python-brace-format msgid "" "'{path}' does not match a common SPDX file pattern. Find the suggested " "naming conventions here: https://spdx.github.io/spdx-spec/conformance/#44-" "standard-data-format-requirements" msgstr "" #: /usr/lib/python3.10/argparse.py:308 msgid "usage: " msgstr "uso: " #: /usr/lib/python3.10/argparse.py:880 msgid ".__call__() not defined" msgstr ".__call__() non definido" #: /usr/lib/python3.10/argparse.py:1223 #, python-format msgid "unknown parser %(parser_name)r (choices: %(choices)s)" msgstr "analizador descoñecido %(parser_name)r (alternativas: %(choices)s)" #: /usr/lib/python3.10/argparse.py:1283 #, python-format msgid "argument \"-\" with mode %r" msgstr "argumento \"-\" con modo %r" #: /usr/lib/python3.10/argparse.py:1292 #, python-format msgid "can't open '%(filename)s': %(error)s" msgstr "non se pode abrir '%(filename)s': %(error)s" #: /usr/lib/python3.10/argparse.py:1501 #, python-format msgid "cannot merge actions - two groups are named %r" msgstr "non se poden misturar as accións - dous grupos teñen o nome %r" #: /usr/lib/python3.10/argparse.py:1539 msgid "'required' is an invalid argument for positionals" msgstr "'required' non é un argumento valido para os posicionais" #: /usr/lib/python3.10/argparse.py:1561 #, python-format msgid "" "invalid option string %(option)r: must start with a character " "%(prefix_chars)r" msgstr "" "cadea de opción non válida %(option)r: precisa comenzar cun carácter " "%(prefix_chars)r" #: /usr/lib/python3.10/argparse.py:1579 #, python-format msgid "dest= is required for options like %r" msgstr "requírese dest= para opcións do tipo %r" #: /usr/lib/python3.10/argparse.py:1596 #, python-format msgid "invalid conflict_resolution value: %r" msgstr "valor non válido para conflict_resolution: %r" #: /usr/lib/python3.10/argparse.py:1614 #, python-format msgid "conflicting option string: %s" msgid_plural "conflicting option strings: %s" msgstr[0] "cadea de opción conflictiva: %s" msgstr[1] "cadeas de opción conflictivas: %s" #: /usr/lib/python3.10/argparse.py:1680 msgid "mutually exclusive arguments must be optional" msgstr "os argumentos mutuamente exclusivos deben ser opcionais" #: /usr/lib/python3.10/argparse.py:1748 msgid "positional arguments" msgstr "argumentos posicionais" #: /usr/lib/python3.10/argparse.py:1749 msgid "options" msgstr "" #: /usr/lib/python3.10/argparse.py:1764 msgid "show this help message and exit" msgstr "mostrar esta mensaxe de axuda e sair" #: /usr/lib/python3.10/argparse.py:1795 msgid "cannot have multiple subparser arguments" msgstr "non pode haber múltiples argumentos para o subanalizador" #: /usr/lib/python3.10/argparse.py:1847 /usr/lib/python3.10/argparse.py:2362 #, python-format msgid "unrecognized arguments: %s" msgstr "argumentos non recoñecidos: %s" #: /usr/lib/python3.10/argparse.py:1948 #, python-format msgid "not allowed with argument %s" msgstr "non se permite co argumento %s" #: /usr/lib/python3.10/argparse.py:1998 /usr/lib/python3.10/argparse.py:2012 #, python-format msgid "ignored explicit argument %r" msgstr "argumento explicito %r ignorado" #: /usr/lib/python3.10/argparse.py:2119 #, python-format msgid "the following arguments are required: %s" msgstr "precísanse os seguintes argumentos: %s" #: /usr/lib/python3.10/argparse.py:2134 #, python-format msgid "one of the arguments %s is required" msgstr "precísase un dos argumentos %s" #: /usr/lib/python3.10/argparse.py:2177 msgid "expected one argument" msgstr "espérase un argumento" #: /usr/lib/python3.10/argparse.py:2178 msgid "expected at most one argument" msgstr "espérase un argumento como máximo" #: /usr/lib/python3.10/argparse.py:2179 msgid "expected at least one argument" msgstr "espérase un argumento como mínimo" #: /usr/lib/python3.10/argparse.py:2183 #, python-format msgid "expected %s argument" msgid_plural "expected %s arguments" msgstr[0] "espérase %s argumento" msgstr[1] "espéranse %s argumentos" #: /usr/lib/python3.10/argparse.py:2241 #, python-format msgid "ambiguous option: %(option)s could match %(matches)s" msgstr "opción ambigua: %(option)s pode encaixar con %(matches)s" #: /usr/lib/python3.10/argparse.py:2305 #, python-format msgid "unexpected option string: %s" msgstr "opción de cadea non esperada: %s" #: /usr/lib/python3.10/argparse.py:2502 #, python-format msgid "%r is not callable" msgstr "%r non se pode chamar" #: /usr/lib/python3.10/argparse.py:2519 #, python-format msgid "invalid %(type)s value: %(value)r" msgstr "valor non válido %(type)s: %(value)r" #: /usr/lib/python3.10/argparse.py:2530 #, python-format msgid "invalid choice: %(value)r (choose from %(choices)s)" msgstr "alternativa non válida: %(value)r (elixir entre %(choices)s)" #: /usr/lib/python3.10/argparse.py:2606 #, python-format msgid "%(prog)s: error: %(message)s\n" msgstr "%(prog)s: erro: %(message)s\n" #~ msgid "initialize REUSE project" #~ msgstr "iniciar un proxecto REUSE" #, fuzzy #~ msgid "" #~ "What license is your project under? Provide the SPDX License Identifier. " #~ "See for the list." #~ msgstr "" #~ "Baixo que licenza está o seu proxecto? indique o Identificador de Licenza " #~ "SPDX." #~ msgid "" #~ "What other license is your project under? Provide the SPDX License " #~ "Identifier." #~ msgstr "" #~ "Baixo que outra licenza está o seu proxecto? indique o Identificador de " #~ "Licenza SPDX." #~ msgid "To stop adding licenses, hit RETURN." #~ msgstr "Para rematar de engadir licenzas, prema ENTER." #~ msgid "Project already initialized" #~ msgstr "O proxecto xa está iniciado" #~ msgid "Initializing project for REUSE." #~ msgstr "Iniciando o proxecto para REUSE." #~ msgid "What is the name of the project?" #~ msgstr "Cal é o nome do proxecto?" #~ msgid "What is the internet address of the project?" #~ msgstr "Cal é o enderezo en internet do proxecto?" #~ msgid "What is the name of the maintainer?" #~ msgstr "Cal é o nome do mantenedor?" #~ msgid "What is the e-mail address of the maintainer?" #~ msgstr "Cal é o correo electrónico do mantenedor?" #~ msgid "All done! Initializing now." #~ msgstr "Rematou todo! iniciando arestora." #~ msgid "{} already exists" #~ msgstr "{} xa existe" #~ msgid "Could not download {}" #~ msgstr "Non se pode descargar {}" #~ msgid "Initialization complete." #~ msgstr "Inicialización completada." #, fuzzy #~ msgid "" #~ "Add copyright and licensing into the header of one or more files.\n" #~ "\n" #~ "By using --copyright and --license, you can specify which copyright " #~ "holders and licenses to add to the headers of the given files.\n" #~ "\n" #~ "By using --contributor, you can specify people or entity that contributed " #~ "but are not copyright holder of the given files.\n" #~ "The first comment is replaced with a new header containing the new " #~ "copyright and licensing information and its former copyright and " #~ "licensing. If you want to keep the first comment intact, use --no-" #~ "replace.\n" #~ "\n" #~ "The comment style should be auto-detected for your files. If a comment " #~ "style could not be detected and --skip-unrecognised is not specified, the " #~ "process aborts. Use --style to specify or override the comment style to " #~ "use.\n" #~ "\n" #~ "A single-line comment style is used when it is available. If no single-" #~ "line comment style is available, a multi-line comment style is used. You " #~ "can force a certain comment style using --single-line or --multi-line.\n" #~ "\n" #~ "You can change the template of the header comment by using --template. " #~ "Place a Jinja2 template in .reuse/templates/mytemplate.jinja2. You can " #~ "use the template by specifying '--template mytemplate'. Read the online " #~ "documentation on how to use this feature.\n" #~ "\n" #~ "If a binary file is detected, or if --force-dot-license is specified, the " #~ "header is placed in a .license file." #~ msgstr "" #~ "Engadir copyright e información da licenza na cabeceira de un ou varios " #~ "arquivos\n" #~ "\n" #~ "Pódese especificar mediante --license e --copyright a licenza e os donos " #~ "do copyright a engadir nas cabeceiras dos arquivos indicados.\n" #~ "\n" #~ "O estilo dos comentarios dos arquivos debería detectarse automáticamente, " #~ "de non se detectar o proceso abórtase. Pódese usar --style para definir " #~ "ou forzar o estilo de comentario a usar.\n" #~ "\n" #~ "É posible cambiar o modelo do comentario de cabeceira usando --template. " #~ "Por exemplo, gardando o modelo Jinja2 na carpeta .reuse/templates/" #~ "mytemplate.jinja2 pode usar este modelo indicando '--template " #~ "mytemplate'. Consulte a documentación en liña para máis información sobre " #~ "esta característica.\n" #~ "\n" #~ "Se o arquivo é binario ou se especifica --explicit-license, a cabeceira " #~ "gárdase nun arquivo .license.\n" #~ "\n" #~ "IMPORTANTE: Actualmente isto é EXPERIMENTAL!" #~ msgid "" #~ "Download a license and place it in the LICENSES/ directory.\n" #~ "\n" #~ "The LICENSES/ directory is automatically found in the following order:\n" #~ "\n" #~ "- The LICENSES/ directory in the root of the VCS repository.\n" #~ "\n" #~ "- The current directory if its name is LICENSES.\n" #~ "\n" #~ "- The LICENSES/ directory in the current directory.\n" #~ "\n" #~ "If the LICENSES/ directory cannot be found, one is simply created." #~ msgstr "" #~ "Descargar unha licenza e gardala na carpeta LICENSES/.\n" #~ "\n" #~ "A carpeta LICENSES/ procurase neste orde:\n" #~ "\n" #~ "- a carpeta LICENSES/ na raíz do repositorio VCS.\n" #~ "\n" #~ "- a carpeta actual se o seu nome é LICENSES.\n" #~ "\n" #~ "- a carpeta LICENSES/ no directorio actual.\n" #~ "\n" #~ "Se non se atopa a carpeta LICENSES/ créase unha." #~ msgid ".reuse/dep5 has syntax errors" #~ msgstr ".reuse/dep5 ten erros de sintaxe" #~ msgid "optional arguments" #~ msgstr "argumentos opcionais" #~ msgid "option --exclude-year and --year are mutually exclusive" #~ msgstr "as opcións --exclude-year e --year non se poden usar á vez" #, fuzzy #~ msgid "option --single-line and --multi-line are mutually exclusive" #~ msgstr "as opcións --exclude-year e --year non se poden usar á vez" #~ msgid "Downloading {}" #~ msgstr "Descargando {}" #, fuzzy #~ msgid "conflicting subparser: %s" #~ msgstr "cadea de opción conflictiva: %s" #, fuzzy #~ msgid "conflicting subparser alias: %s" #~ msgstr "cadea de opción conflictiva: %s" #~ msgid "can't open '%s': %s" #~ msgstr "non se pode abrir '%s': %s" #~ msgid "place header in path.license instead of path" #~ msgstr "colocar a cabeceira en carpeta.licenza no canto de carpeta" #~ msgid "could not find Git" #~ msgstr "non se pode atopar o Git" reuse-tool-4.0.3/po/it.po000066400000000000000000001042671464275211500152270ustar00rootroot00000000000000# SPDX-FileCopyrightText: Luca Bonissi # # SPDX-License-Identifier: GPL-3.0-or-later msgid "" msgstr "" "Project-Id-Version: FSFE reuse\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-07-03 13:09+0000\n" "PO-Revision-Date: 2023-02-18 10:24+0000\n" "Last-Translator: \"J. Lavoie\" \n" "Language-Team: Italian \n" "Language: it\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 4.16-dev\n" #: src/reuse/_annotate.py:74 #, python-brace-format msgid "" "'{path}' does not support single-line comments, please do not use --single-" "line" msgstr "" #: src/reuse/_annotate.py:81 #, python-brace-format msgid "" "'{path}' does not support multi-line comments, please do not use --multi-line" msgstr "" #: src/reuse/_annotate.py:136 #, python-brace-format msgid "Skipped unrecognised file '{path}'" msgstr "" #: src/reuse/_annotate.py:142 #, python-brace-format msgid "'{path}' is not recognised; creating '{path}.license'" msgstr "" #: src/reuse/_annotate.py:158 #, python-brace-format msgid "Skipped file '{path}' already containing REUSE information" msgstr "" #: src/reuse/_annotate.py:192 #, python-brace-format msgid "Error: Could not create comment for '{path}'" msgstr "Errore: Non è possibile creare il commento per '{path}'" #: src/reuse/_annotate.py:199 #, python-brace-format msgid "" "Error: Generated comment header for '{path}' is missing copyright lines or " "license expressions. The template is probably incorrect. Did not write new " "header." msgstr "" "Errore: Mancano le linee sul copyright o le espressioni di licenza " "nell'intestazione generata per '{path}'. Il modello è probabilmente " "incorretto. Non è stata scritta una nuova intestazione." #. TODO: This may need to be rephrased more elegantly. #: src/reuse/_annotate.py:210 #, python-brace-format msgid "Successfully changed header of {path}" msgstr "Instestazione di {path} aggiornata" #: src/reuse/_annotate.py:221 msgid "--skip-unrecognised has no effect when used together with --style" msgstr "" #: src/reuse/_annotate.py:231 #, fuzzy msgid "option --contributor, --copyright or --license is required" msgstr "è necessario specificare il parametro --copyright o --license" #: src/reuse/_annotate.py:272 #, python-brace-format msgid "template {template} could not be found" msgstr "il modello {template} non è stato trovato" #: src/reuse/_annotate.py:341 src/reuse/_util.py:573 msgid "can't write to '{}'" msgstr "non è possibile scrivere su '{}'" #: src/reuse/_annotate.py:366 #, fuzzy msgid "" "The following files do not have a recognised file extension. Please use --" "style, --force-dot-license, --fallback-dot-license, or --skip-unrecognised:" msgstr "" "'{path}' non ha una estensione conosciuta, usa --style o --explicit-license" #: src/reuse/_annotate.py:382 msgid "copyright statement, repeatable" msgstr "dichiarazione del copyright, ripetibile" #: src/reuse/_annotate.py:389 msgid "SPDX Identifier, repeatable" msgstr "Identificativo SPDX, ripetibile" #: src/reuse/_annotate.py:395 #, fuzzy msgid "file contributor, repeatable" msgstr "Identificativo SPDX, ripetibile" #: src/reuse/_annotate.py:403 msgid "year of copyright statement, optional" msgstr "anno della dichiaraione del copyright, opzionale" #: src/reuse/_annotate.py:411 msgid "comment style to use, optional" msgstr "stile dei commenti da usare, opzionale" #: src/reuse/_annotate.py:417 #, fuzzy msgid "copyright prefix to use, optional" msgstr "stile dei commenti da usare, opzionale" #: src/reuse/_annotate.py:430 msgid "name of template to use, optional" msgstr "nome del template da usare, opzionale" #: src/reuse/_annotate.py:435 msgid "do not include year in statement" msgstr "non include l'anno nella dichiarazione" #: src/reuse/_annotate.py:440 #, fuzzy msgid "merge copyright lines if copyright statements are identical" msgstr "anno della dichiaraione del copyright, opzionale" #: src/reuse/_annotate.py:446 #, fuzzy msgid "force single-line comment style, optional" msgstr "stile dei commenti da usare, opzionale" #: src/reuse/_annotate.py:451 #, fuzzy msgid "force multi-line comment style, optional" msgstr "stile dei commenti da usare, opzionale" #: src/reuse/_annotate.py:458 msgid "add headers to all files under specified directories recursively" msgstr "" #: src/reuse/_annotate.py:465 msgid "do not replace the first header in the file; just add a new one" msgstr "" #: src/reuse/_annotate.py:473 msgid "always write a .license file instead of a header inside the file" msgstr "" #: src/reuse/_annotate.py:480 msgid "write a .license file to files with unrecognised comment styles" msgstr "" #: src/reuse/_annotate.py:486 msgid "skip files with unrecognised comment styles" msgstr "" #: src/reuse/_annotate.py:497 #, fuzzy msgid "skip files that already contain REUSE information" msgstr "File con informazioni sulla licenza: {count} / {total}" #: src/reuse/_annotate.py:532 #, python-brace-format msgid "'{path}' is a binary, therefore using '{new_path}' for the header" msgstr "" "'{path}' è un file binario, occorre utilizzare '{new_path}' per " "l'intestazione" #: src/reuse/_main.py:39 msgid "" "reuse is a tool for compliance with the REUSE recommendations. See for more information, and " "for the online documentation." msgstr "" "reuse è uno strumento per la conformità alle raccomandazioni REUSE. Visita " " per maggiori informazioni, e per accedere alla documentazione in linea." #: src/reuse/_main.py:45 msgid "" "This version of reuse is compatible with version {} of the REUSE " "Specification." msgstr "" "Questa versione di reuse è compatibile con la versione {} della Specifica " "REUSE." #: src/reuse/_main.py:48 msgid "Support the FSFE's work:" msgstr "Sostieni il lavoro della FSFE:" #: src/reuse/_main.py:52 msgid "" "Donations are critical to our strength and autonomy. They enable us to " "continue working for Free Software wherever necessary. Please consider " "making a donation at ." msgstr "" "Le donazioni sono fondamentali per la nostra forza e la nostra autonomia. Ci " "permettono di continuare a lavorare per il Software Libero ovunque sia " "necessario. Prendi in considerazione di fare una donazione su ." #: src/reuse/_main.py:75 msgid "enable debug statements" msgstr "abilita le istruzioni di debug" #: src/reuse/_main.py:80 msgid "hide deprecation warnings" msgstr "" #: src/reuse/_main.py:85 msgid "do not skip over Git submodules" msgstr "non omettere i sottomoduli Git" #: src/reuse/_main.py:90 #, fuzzy msgid "do not skip over Meson subprojects" msgstr "non omettere i sottomoduli Git" #: src/reuse/_main.py:95 msgid "do not use multiprocessing" msgstr "non utilizzare il multiprocessing" #: src/reuse/_main.py:102 msgid "define root of project" msgstr "impostare la directory principale del progetto" #: src/reuse/_main.py:107 msgid "show program's version number and exit" msgstr "mostra la versione del programma ed esce" #: src/reuse/_main.py:111 msgid "subcommands" msgstr "sottocomandi" #: src/reuse/_main.py:118 msgid "add copyright and licensing into the header of files" msgstr "" "aggiunge le informazioni sul copyright e sulla licenza nell'intestazione dei " "file" #: src/reuse/_main.py:121 msgid "" "Add copyright and licensing into the header of one or more files.\n" "\n" "By using --copyright and --license, you can specify which copyright holders " "and licenses to add to the headers of the given files.\n" "\n" "By using --contributor, you can specify people or entity that contributed " "but are not copyright holder of the given files." msgstr "" #: src/reuse/_main.py:140 msgid "download a license and place it in the LICENSES/ directory" msgstr "scarica una licenza e salvala nella directory LICENSES/" #: src/reuse/_main.py:142 #, fuzzy msgid "Download a license and place it in the LICENSES/ directory." msgstr "scarica una licenza e salvala nella directory LICENSES/" #: src/reuse/_main.py:151 msgid "list all non-compliant files" msgstr "lista dei file non conformi" #: src/reuse/_main.py:154 #, python-brace-format msgid "" "Lint the project directory for compliance with version {reuse_version} of " "the REUSE Specification. You can find the latest version of the " "specification at .\n" "\n" "Specifically, the following criteria are checked:\n" "\n" "- Are there any bad (unrecognised, not compliant with SPDX) licenses in the " "project?\n" "\n" "- Are any licenses referred to inside of the project, but not included in " "the LICENSES/ directory?\n" "\n" "- Are any licenses included in the LICENSES/ directory that are not used " "inside of the project?\n" "\n" "- Do all files have valid copyright and licensing information?" msgstr "" "Controlla che la directory del progetto sia conforme con la versione " "{reuse_version} della Specifica REUSE. Puoi trovare l'ultima versione della " "specifica su \n" "\n" "In particolare, vengono eseguiti i seguenti controlli:\n" "\n" "- Nel progetto c'è qualche licenza non valida (non riconosciuta, non " "conforme con SPDX)?\n" "\n" "- C'è qualche licenza utilizzata all'interno del progetto, ma non inclusa " "nella directory LICENSES/?\n" "\n" "- C'è qualche licenza inclusa della directory LICENSES/ ma non utilizzata " "nel progetto?\n" "\n" "- Tutti i file hanno informazioni valide sul copyright e sulla licenza?" #: src/reuse/_main.py:181 msgid "print the project's bill of materials in SPDX format" msgstr "stampa l'elenco dei componenti del progetto in formato SPDX" #: src/reuse/_main.py:189 msgid "list all supported SPDX licenses" msgstr "" #: src/reuse/_main.py:198 msgid "convert .reuse/dep5 to REUSE.toml" msgstr "" #: src/reuse/_main.py:263 #, python-brace-format msgid "'{path}' could not be decoded as UTF-8." msgstr "" #: src/reuse/_main.py:269 #, python-brace-format msgid "" "'{path}' could not be parsed. We received the following error message: " "{message}" msgstr "" #: src/reuse/_util.py:368 src/reuse/global_licensing.py:218 #, python-brace-format msgid "Could not parse '{expression}'" msgstr "Non è possibile parsificare '{expression}'" #: src/reuse/_util.py:424 #, python-brace-format msgid "" "'{path}' holds an SPDX expression that cannot be parsed, skipping the file" msgstr "" "'{path}' contiene un'espressione SPDX che non può essere parsificata, il " "file viene saltato" #: src/reuse/_util.py:556 msgid "'{}' is not a file" msgstr "'{}' non è un file" #: src/reuse/_util.py:559 msgid "'{}' is not a directory" msgstr "'{}' non è una directory" #: src/reuse/_util.py:562 msgid "can't open '{}'" msgstr "non è possibile aprire '{}'" #: src/reuse/_util.py:567 msgid "can't write to directory '{}'" msgstr "non è possibile scrivere nella directory '{}'" #: src/reuse/_util.py:586 msgid "can't read or write '{}'" msgstr "non è possibile leggere o scrivere '{}'" #: src/reuse/_util.py:596 msgid "'{}' is not a valid SPDX expression, aborting" msgstr "'{}' non è una espressione valida SPDX, interruzione" #: src/reuse/_util.py:624 msgid "'{}' is not a valid SPDX License Identifier." msgstr "'{}' non è un valido Identificativo di Licenza SPDX." #: src/reuse/_util.py:631 msgid "Did you mean:" msgstr "" #: src/reuse/_util.py:638 msgid "" "See for a list of valid SPDX License " "Identifiers." msgstr "" "Consulta per la lista degli Identificativi di " "Licenza SPDX validi." #: src/reuse/convert_dep5.py:118 #, fuzzy msgid "no '.reuse/dep5' file" msgstr "Creazione di .reuse/dep5" #: src/reuse/download.py:130 msgid "SPDX License Identifier of license" msgstr "Identificativo di Licenza SPDX" #: src/reuse/download.py:135 msgid "download all missing licenses detected in the project" msgstr "scarica tutte le licenze mancanti ma usate nel progetto" #: src/reuse/download.py:145 msgid "" "source from which to copy custom LicenseRef- licenses, either a directory " "that contains the file or the file itself" msgstr "" #: src/reuse/download.py:156 #, python-brace-format msgid "Error: {spdx_identifier} already exists." msgstr "Errore: {spdx_identifier} esiste già." #: src/reuse/download.py:163 #, fuzzy, python-brace-format msgid "Error: {path} does not exist." msgstr "'{path}' non ha estensione .spdx" #: src/reuse/download.py:166 msgid "Error: Failed to download license." msgstr "Errore: Fallito lo scaricamento della licenza." #: src/reuse/download.py:171 msgid "Is your internet connection working?" msgstr "La tua connessione Internet funziona?" #: src/reuse/download.py:176 #, python-brace-format msgid "Successfully downloaded {spdx_identifier}." msgstr "Scaricamento completato di {spdx_identifier}." #: src/reuse/download.py:188 msgid "--output has no effect when used together with --all" msgstr "" #: src/reuse/download.py:192 msgid "the following arguments are required: license" msgstr "sono richiesti i seguenti parametri: license" #: src/reuse/download.py:194 msgid "cannot use --output with more than one license" msgstr "non puoi usare --output con più di una licenza" #: src/reuse/global_licensing.py:109 #, python-brace-format msgid "" "{attr_name} must be a {type_name} (got {value} that is a {value_class})." msgstr "" #: src/reuse/global_licensing.py:122 #, python-brace-format msgid "" "Item in {attr_name} collection must be a {type_name} (got {item_value} that " "is a {item_class})." msgstr "" #: src/reuse/global_licensing.py:133 #, python-brace-format msgid "{attr_name} must not be empty." msgstr "" #: src/reuse/global_licensing.py:156 #, python-brace-format msgid "{name} must be a {type} (got {value} that is a {value_type})." msgstr "" #: src/reuse/global_licensing.py:179 #, python-brace-format msgid "" "The value of 'precedence' must be one of {precedence_vals} (got {received})" msgstr "" #: src/reuse/header.py:99 msgid "generated comment is missing copyright lines or license expressions" msgstr "" "nel commento generato mancano le linee sul copyright o le espressioni di " "licenza" #: src/reuse/lint.py:30 msgid "prevents output" msgstr "" #: src/reuse/lint.py:33 msgid "formats output as JSON" msgstr "" #: src/reuse/lint.py:39 msgid "formats output as plain text" msgstr "" #: src/reuse/lint.py:45 msgid "formats output as errors per line" msgstr "" #: src/reuse/lint.py:64 msgid "BAD LICENSES" msgstr "LICENZE NON VALIDA" #: src/reuse/lint.py:66 src/reuse/lint.py:95 msgid "'{}' found in:" msgstr "'{}' trovato in:" #: src/reuse/lint.py:73 msgid "DEPRECATED LICENSES" msgstr "LICENZE OBSOLETE" #: src/reuse/lint.py:75 msgid "The following licenses are deprecated by SPDX:" msgstr "Le seguenti licenze sono obsolete secondo SPDX:" #: src/reuse/lint.py:83 msgid "LICENSES WITHOUT FILE EXTENSION" msgstr "LICENZE SENZA ESTENSIONE DEL FILE" #: src/reuse/lint.py:85 msgid "The following licenses have no file extension:" msgstr "Le seguenti licenze non hanno l'estensione del file:" #: src/reuse/lint.py:93 msgid "MISSING LICENSES" msgstr "LICENZE MANCANTI" #: src/reuse/lint.py:102 msgid "UNUSED LICENSES" msgstr "LICENZE NON UTILIZZATE" #: src/reuse/lint.py:103 msgid "The following licenses are not used:" msgstr "Le seguenti licenze non sono utilizzate:" #: src/reuse/lint.py:110 msgid "READ ERRORS" msgstr "ERRORI DI LETTURA" #: src/reuse/lint.py:111 msgid "Could not read:" msgstr "Non è possibile leggere:" #: src/reuse/lint.py:132 msgid "MISSING COPYRIGHT AND LICENSING INFORMATION" msgstr "MANCANO LE INFORMAZIONI SU COPYRIGHT E LICENZA" #: src/reuse/lint.py:138 msgid "The following files have no copyright and licensing information:" msgstr "I seguenti file non hanno informazioni sul copyright e sulla licenza:" #: src/reuse/lint.py:149 msgid "The following files have no copyright information:" msgstr "I seguenti file non hanno informazioni sul copyright:" #: src/reuse/lint.py:158 msgid "The following files have no licensing information:" msgstr "I seguenti file non hanno informazioni sulla licenza:" #: src/reuse/lint.py:166 msgid "SUMMARY" msgstr "RAPPORTO" #: src/reuse/lint.py:171 msgid "Bad licenses:" msgstr "Licenze non valide:" #: src/reuse/lint.py:172 msgid "Deprecated licenses:" msgstr "Licenze obsolete:" #: src/reuse/lint.py:173 msgid "Licenses without file extension:" msgstr "Licenze senza estensione del file:" #: src/reuse/lint.py:176 msgid "Missing licenses:" msgstr "Licenze mancanti:" #: src/reuse/lint.py:177 msgid "Unused licenses:" msgstr "Licenze non utilizzate:" #: src/reuse/lint.py:178 msgid "Used licenses:" msgstr "Licenze usate:" #: src/reuse/lint.py:179 #, fuzzy msgid "Read errors:" msgstr "Errori di lettura: {count}" #: src/reuse/lint.py:181 #, fuzzy msgid "Files with copyright information:" msgstr "File con informazioni sul copyright: {count} / {total}" #: src/reuse/lint.py:185 #, fuzzy msgid "Files with license information:" msgstr "File con informazioni sulla licenza: {count} / {total}" #: src/reuse/lint.py:202 msgid "" "Congratulations! Your project is compliant with version {} of the REUSE " "Specification :-)" msgstr "" "Congratulazioni! Il tuo progetto è conforme con la versione {} della " "Specifica REUSE :-)" #: src/reuse/lint.py:209 msgid "" "Unfortunately, your project is not compliant with version {} of the REUSE " "Specification :-(" msgstr "" "Siamo spiacenti, il tuo progetto non è conforme con la versione {} della " "Specifica REUSE :-(" #: src/reuse/lint.py:216 msgid "RECOMMENDATIONS" msgstr "" #: src/reuse/lint.py:289 #, python-brace-format msgid "{path}: bad license {lic}\n" msgstr "" #: src/reuse/lint.py:296 #, fuzzy, python-brace-format msgid "{lic_path}: deprecated license\n" msgstr "Licenze obsolete:" #: src/reuse/lint.py:303 #, fuzzy, python-brace-format msgid "{lic_path}: license without file extension\n" msgstr "Licenze senza estensione del file:" #: src/reuse/lint.py:312 #, fuzzy, python-brace-format msgid "{lic_path}: unused license\n" msgstr "Licenze non utilizzate:" #: src/reuse/lint.py:319 #, python-brace-format msgid "{path}: missing license {lic}\n" msgstr "" #: src/reuse/lint.py:326 #, python-brace-format msgid "{path}: read error\n" msgstr "" #: src/reuse/lint.py:330 #, fuzzy, python-brace-format msgid "{path}: no license identifier\n" msgstr "'{}' non è un valido Identificativo di Licenza SPDX." #: src/reuse/lint.py:334 #, python-brace-format msgid "{path}: no copyright notice\n" msgstr "" #: src/reuse/project.py:262 #, fuzzy, python-brace-format msgid "'{path}' covered by {global_path}" msgstr "'{path}' verificato da .reuse/dep5" #: src/reuse/project.py:270 #, python-brace-format msgid "" "'{path}' is covered exclusively by REUSE.toml. Not reading the file contents." msgstr "" #: src/reuse/project.py:277 #, python-brace-format msgid "" "'{path}' was detected as a binary file; not searching its contents for REUSE " "information." msgstr "" #: src/reuse/project.py:334 msgid "" "'.reuse/dep5' is deprecated. You are recommended to instead use REUSE.toml. " "Use `reuse convert-dep5` to convert." msgstr "" #: src/reuse/project.py:348 #, python-brace-format msgid "" "Found both '{new_path}' and '{old_path}'. You cannot keep both files " "simultaneously; they are not intercompatible." msgstr "" #: src/reuse/project.py:414 #, python-brace-format msgid "determining identifier of '{path}'" msgstr "determinazione dell'identificativo di '{path}'" #: src/reuse/project.py:422 #, python-brace-format msgid "{path} does not have a file extension" msgstr "{path} non ha l'estensione del file" #: src/reuse/project.py:432 #, python-brace-format msgid "" "Could not resolve SPDX License Identifier of {path}, resolving to " "{identifier}. Make sure the license is in the license list found at or that it starts with 'LicenseRef-', and that it has a " "file extension." msgstr "" "Non è possibile rilevare l'Identificativo di Licenza SPDX per {path}, viene " "impostato a {identifier}. Assicurati che la licenza sia nella lista delle " "licenze elencate su o che inizi con " "'LicenseRef-', e che abbia un'estensione del file." #: src/reuse/project.py:444 #, python-brace-format msgid "" "{identifier} is the SPDX License Identifier of both {path} and {other_path}" msgstr "" "{identifier} è l'Identificativo di Licenza SPDX sia di {path} che di " "{other_path}" #: src/reuse/project.py:483 msgid "" "project '{}' is not a VCS repository or required VCS software is not " "installed" msgstr "" #: src/reuse/report.py:310 #, python-brace-format msgid "Could not read '{path}'" msgstr "Non è possibile leggere '{path}'" #: src/reuse/report.py:317 #, python-brace-format msgid "Unexpected error occurred while parsing '{path}'" msgstr "Errore sconosciuto durante la parsificazione di '{path}'" #: src/reuse/report.py:438 msgid "" "Fix bad licenses: At least one license in the LICENSES directory and/or " "provided by 'SPDX-License-Identifier' tags is invalid. They are either not " "valid SPDX License Identifiers or do not start with 'LicenseRef-'. FAQ about " "custom licenses: https://reuse.software/faq/#custom-license" msgstr "" #: src/reuse/report.py:449 msgid "" "Fix deprecated licenses: At least one of the licenses in the LICENSES " "directory and/or provided by an 'SPDX-License-Identifier' tag or in '.reuse/" "dep5' has been deprecated by SPDX. The current list and their respective " "recommended new identifiers can be found here: " msgstr "" #: src/reuse/report.py:460 msgid "" "Fix licenses without file extension: At least one license text file in the " "'LICENSES' directory does not have a '.txt' file extension. Please rename " "the file(s) accordingly." msgstr "" #: src/reuse/report.py:469 msgid "" "Fix missing licenses: For at least one of the license identifiers provided " "by the 'SPDX-License-Identifier' tags, there is no corresponding license " "text file in the 'LICENSES' directory. For SPDX license identifiers, you can " "simply run 'reuse download --all' to get any missing ones. For custom " "licenses (starting with 'LicenseRef-'), you need to add these files yourself." msgstr "" #: src/reuse/report.py:481 msgid "" "Fix unused licenses: At least one of the license text files in 'LICENSES' is " "not referenced by any file, e.g. by an 'SPDX-License-Identifier' tag. Please " "make sure that you either tag the accordingly licensed files properly, or " "delete the unused license text if you are sure that no file or code snippet " "is licensed as such." msgstr "" #: src/reuse/report.py:492 msgid "" "Fix read errors: At least one of the files in your directory cannot be read " "by the tool. Please check the file permissions. You will find the affected " "files at the top of the output as part of the logged error messages." msgstr "" #: src/reuse/report.py:501 msgid "" "Fix missing copyright/licensing information: For one or more files, the tool " "cannot find copyright and/or licensing information. You typically do this by " "adding 'SPDX-FileCopyrightText' and 'SPDX-License-Identifier' tags to each " "file. The tutorial explains additional ways to do this: " msgstr "" #: src/reuse/spdx.py:32 msgid "" "populate the LicenseConcluded field; note that reuse cannot guarantee the " "field is accurate" msgstr "" #: src/reuse/spdx.py:39 msgid "name of the person signing off on the SPDX report" msgstr "" #: src/reuse/spdx.py:44 msgid "name of the organization signing off on the SPDX report" msgstr "" #: src/reuse/spdx.py:60 msgid "" "error: --creator-person=NAME or --creator-organization=NAME required when --" "add-license-concluded is provided" msgstr "" #: src/reuse/spdx.py:75 #, python-brace-format msgid "" "'{path}' does not match a common SPDX file pattern. Find the suggested " "naming conventions here: https://spdx.github.io/spdx-spec/conformance/#44-" "standard-data-format-requirements" msgstr "" #: /usr/lib/python3.10/argparse.py:308 msgid "usage: " msgstr "uso: " #: /usr/lib/python3.10/argparse.py:880 msgid ".__call__() not defined" msgstr ".__call__() non definita" #: /usr/lib/python3.10/argparse.py:1223 #, python-format msgid "unknown parser %(parser_name)r (choices: %(choices)s)" msgstr "parsificatore sconosciuto: %(parser_name)r (alternative: %(choices)s)" #: /usr/lib/python3.10/argparse.py:1283 #, python-format msgid "argument \"-\" with mode %r" msgstr "parametro \"-\" con modo %r" #: /usr/lib/python3.10/argparse.py:1292 #, python-format msgid "can't open '%(filename)s': %(error)s" msgstr "non è possibile aprire '%(filename)s': %(error)s" #: /usr/lib/python3.10/argparse.py:1501 #, python-format msgid "cannot merge actions - two groups are named %r" msgstr "non è possibile unire le azioni - due gruppi hanno lo stesso nome %r" #: /usr/lib/python3.10/argparse.py:1539 msgid "'required' is an invalid argument for positionals" msgstr "'required' non è un parametro posizionale valido" #: /usr/lib/python3.10/argparse.py:1561 #, python-format msgid "" "invalid option string %(option)r: must start with a character " "%(prefix_chars)r" msgstr "" "nome opzione non valida %(option)r: deve iniziare con un carattere " "%(prefix_chars)r" #: /usr/lib/python3.10/argparse.py:1579 #, python-format msgid "dest= is required for options like %r" msgstr "dest= è richiesto per opzioni come %r" #: /usr/lib/python3.10/argparse.py:1596 #, python-format msgid "invalid conflict_resolution value: %r" msgstr "valore per conflict_resolution non valido: %r" #: /usr/lib/python3.10/argparse.py:1614 #, python-format msgid "conflicting option string: %s" msgid_plural "conflicting option strings: %s" msgstr[0] "nome opzione in conflitto: %s" msgstr[1] "nomi opzioni in conflitto: %s" #: /usr/lib/python3.10/argparse.py:1680 msgid "mutually exclusive arguments must be optional" msgstr "i parametri mutualmente esclusivi devono essere opzionali" #: /usr/lib/python3.10/argparse.py:1748 msgid "positional arguments" msgstr "parametri posizionali" #: /usr/lib/python3.10/argparse.py:1749 msgid "options" msgstr "" #: /usr/lib/python3.10/argparse.py:1764 msgid "show this help message and exit" msgstr "mostra questo messaggio ed esci" #: /usr/lib/python3.10/argparse.py:1795 msgid "cannot have multiple subparser arguments" msgstr "non è possibile avere più di un parametro con sotto-parsificatore" #: /usr/lib/python3.10/argparse.py:1847 /usr/lib/python3.10/argparse.py:2362 #, python-format msgid "unrecognized arguments: %s" msgstr "parametro sconosciuto: %s" #: /usr/lib/python3.10/argparse.py:1948 #, python-format msgid "not allowed with argument %s" msgstr "non permesso con parametro %s" #: /usr/lib/python3.10/argparse.py:1998 /usr/lib/python3.10/argparse.py:2012 #, python-format msgid "ignored explicit argument %r" msgstr "parametro esplicito ignorato %r" #: /usr/lib/python3.10/argparse.py:2119 #, python-format msgid "the following arguments are required: %s" msgstr "i seguenti parametri sono obbligatori: %s" #: /usr/lib/python3.10/argparse.py:2134 #, python-format msgid "one of the arguments %s is required" msgstr "uno dei parametri %s è richiesto" #: /usr/lib/python3.10/argparse.py:2177 msgid "expected one argument" msgstr "richiesto un parametro" #: /usr/lib/python3.10/argparse.py:2178 msgid "expected at most one argument" msgstr "al massimo un parametro aspettato" #: /usr/lib/python3.10/argparse.py:2179 msgid "expected at least one argument" msgstr "richiesto almeno un parametro" #: /usr/lib/python3.10/argparse.py:2183 #, python-format msgid "expected %s argument" msgid_plural "expected %s arguments" msgstr[0] "richiesto il parametro %s" msgstr[1] "richiesti i parametri %s" #: /usr/lib/python3.10/argparse.py:2241 #, python-format msgid "ambiguous option: %(option)s could match %(matches)s" msgstr "opzione ambigua: %(option)s può essere %(matches)s" #: /usr/lib/python3.10/argparse.py:2305 #, python-format msgid "unexpected option string: %s" msgstr "nome opzione inaspettato: %s" #: /usr/lib/python3.10/argparse.py:2502 #, python-format msgid "%r is not callable" msgstr "%r non è richiamabile" #: /usr/lib/python3.10/argparse.py:2519 #, python-format msgid "invalid %(type)s value: %(value)r" msgstr "valore %(type)s non valido: %(value)r" #: /usr/lib/python3.10/argparse.py:2530 #, python-format msgid "invalid choice: %(value)r (choose from %(choices)s)" msgstr "scelta non valida: %(value)r (opzioni valide: %(choices)s)" #: /usr/lib/python3.10/argparse.py:2606 #, python-format msgid "%(prog)s: error: %(message)s\n" msgstr "%(prog)s: errore: %(message)s\n" #~ msgid "initialize REUSE project" #~ msgstr "inizializza il progetto REUSE" #, fuzzy #~ msgid "" #~ "What license is your project under? Provide the SPDX License Identifier. " #~ "See for the list." #~ msgstr "" #~ "Sotto quale licenza viene rilasciato il tuo progetto? Indica " #~ "l'Identificativo di Licenza SPDX." #~ msgid "" #~ "What other license is your project under? Provide the SPDX License " #~ "Identifier." #~ msgstr "" #~ "Quali altre licenze utilizza il tuo progetto? Indica l'Identificativo di " #~ "Licenza SPDX." #~ msgid "To stop adding licenses, hit RETURN." #~ msgstr "Per terminare l'aggiunta di licenze, premi INVIO." #~ msgid "Project already initialized" #~ msgstr "Progetto già inizializzato" #~ msgid "Initializing project for REUSE." #~ msgstr "Inizializzazione del progetto per REUSE." #~ msgid "What is the name of the project?" #~ msgstr "Qual è il nome del progetto?" #~ msgid "What is the internet address of the project?" #~ msgstr "Qual è l'indirizzo Internet del progetto?" #~ msgid "What is the name of the maintainer?" #~ msgstr "Qual è il nome del responsabile del progetto?" #~ msgid "What is the e-mail address of the maintainer?" #~ msgstr "Qual è l'indirizzo e-mail del responsabile del progetto?" #~ msgid "All done! Initializing now." #~ msgstr "Tutto OK! Sto inizializzando." #~ msgid "{} already exists" #~ msgstr "{} esiste già" #~ msgid "Could not download {}" #~ msgstr "Non è stato possibile scaricare {}" #~ msgid "Initialization complete." #~ msgstr "Inizializzazione completa." #, fuzzy #~ msgid "" #~ "Add copyright and licensing into the header of one or more files.\n" #~ "\n" #~ "By using --copyright and --license, you can specify which copyright " #~ "holders and licenses to add to the headers of the given files.\n" #~ "\n" #~ "By using --contributor, you can specify people or entity that contributed " #~ "but are not copyright holder of the given files.\n" #~ "The first comment is replaced with a new header containing the new " #~ "copyright and licensing information and its former copyright and " #~ "licensing. If you want to keep the first comment intact, use --no-" #~ "replace.\n" #~ "\n" #~ "The comment style should be auto-detected for your files. If a comment " #~ "style could not be detected and --skip-unrecognised is not specified, the " #~ "process aborts. Use --style to specify or override the comment style to " #~ "use.\n" #~ "\n" #~ "A single-line comment style is used when it is available. If no single-" #~ "line comment style is available, a multi-line comment style is used. You " #~ "can force a certain comment style using --single-line or --multi-line.\n" #~ "\n" #~ "You can change the template of the header comment by using --template. " #~ "Place a Jinja2 template in .reuse/templates/mytemplate.jinja2. You can " #~ "use the template by specifying '--template mytemplate'. Read the online " #~ "documentation on how to use this feature.\n" #~ "\n" #~ "If a binary file is detected, or if --force-dot-license is specified, the " #~ "header is placed in a .license file." #~ msgstr "" #~ "Aggiunge le informazioni sul copyright e sulla licenza nell'intestazione " #~ "di uno o più file.\n" #~ "\n" #~ "Usando --copyright e --license, puoi specificare i titolari del copyright " #~ "e le licenze da aggiungere all'intestazione dei file specificati.\n" #~ "\n" #~ "Lo stile dei commenti dovrebbe essere rilevato automaticamente per i tuoi " #~ "file. Se lo stile non può essere rilevato, il programma si interrompe. " #~ "Usa --style per specificare o forzare lo stile dei commenti da usare.\n" #~ "\n" #~ "Puoi cambiare il modello dell'intestazione utilizzando --template. Metti " #~ "un modello Jinja2 in .reuse/templates/miomodello.jinja2. Puoi usare il " #~ "modello specificando '--template miomodello'. Leggi la documentazione in " #~ "linea su come usare questa funzione.\n" #~ "\n" #~ "Se viene rilevato un file binario, o se --explicit-licence viene " #~ "specificato, l'intestazione verrà inserita nel file .license.\n" #~ "\n" #~ "IMPORTANTE: Questo è ancora SPERIMENTALE!" #~ msgid "" #~ "Download a license and place it in the LICENSES/ directory.\n" #~ "\n" #~ "The LICENSES/ directory is automatically found in the following order:\n" #~ "\n" #~ "- The LICENSES/ directory in the root of the VCS repository.\n" #~ "\n" #~ "- The current directory if its name is LICENSES.\n" #~ "\n" #~ "- The LICENSES/ directory in the current directory.\n" #~ "\n" #~ "If the LICENSES/ directory cannot be found, one is simply created." #~ msgstr "" #~ "Scarica una licenza e salvala nella directory LICENSES/.\n" #~ "\n" #~ "La directory LICENSES/ viene automaticamente ricercata nel seguente " #~ "ordine:\n" #~ "\n" #~ "- La directory LICENSES/ sotto la directory principale del repository " #~ "VCS.\n" #~ "\n" #~ "- La directory corrente se il suo nome è LICENSES.\n" #~ "\n" #~ "- La directory LICENSES/ sotto la directory corrente.\n" #~ "\n" #~ "Se la directory LICENSES/ non viene trovata, verrà semplicemente creata." #~ msgid ".reuse/dep5 has syntax errors" #~ msgstr ".reuse/dep5 presenta errori di sintassi" #~ msgid "optional arguments" #~ msgstr "parametri opzionali" #~ msgid "option --exclude-year and --year are mutually exclusive" #~ msgstr "i parametri --exclude-year e --year sono multualmente esclusivi" #, fuzzy #~ msgid "option --single-line and --multi-line are mutually exclusive" #~ msgstr "i parametri --exclude-year e --year sono multualmente esclusivi" #~ msgid "Downloading {}" #~ msgstr "Scaricamento {}" #, fuzzy #~ msgid "conflicting subparser: %s" #~ msgstr "nome opzione in conflitto: %s" #, fuzzy #~ msgid "conflicting subparser alias: %s" #~ msgstr "nome opzione in conflitto: %s" #~ msgid "can't open '%s': %s" #~ msgstr "non è possibile aprire '%s': %s" #~ msgid "place header in path.license instead of path" #~ msgstr "inserisci l'intestazione in path.license invece di path" #~ msgid "could not find Git" #~ msgstr "non è stato possibile trovare Git" reuse-tool-4.0.3/po/nl.po000066400000000000000000001146721464275211500152250ustar00rootroot00000000000000# SPDX-FileCopyrightText: 2018, 2020 Carmen Bianca Bakker # SPDX-FileCopyrightText: 2017, 2020 André Ockers # # SPDX-License-Identifier: GPL-3.0-or-later msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-07-03 13:09+0000\n" "PO-Revision-Date: 2023-02-18 10:24+0000\n" "Last-Translator: \"J. Lavoie\" \n" "Language-Team: Dutch \n" "Language: nl\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 4.18.1\n" #: src/reuse/_annotate.py:74 #, python-brace-format msgid "" "'{path}' does not support single-line comments, please do not use --single-" "line" msgstr "" #: src/reuse/_annotate.py:81 #, python-brace-format msgid "" "'{path}' does not support multi-line comments, please do not use --multi-line" msgstr "" #: src/reuse/_annotate.py:136 #, python-brace-format msgid "Skipped unrecognised file '{path}'" msgstr "" #: src/reuse/_annotate.py:142 #, python-brace-format msgid "'{path}' is not recognised; creating '{path}.license'" msgstr "" #: src/reuse/_annotate.py:158 #, python-brace-format msgid "Skipped file '{path}' already containing REUSE information" msgstr "" #: src/reuse/_annotate.py:192 #, python-brace-format msgid "Error: Could not create comment for '{path}'" msgstr "Fout: Kon geen commentaar voor '{path}' creëren" #: src/reuse/_annotate.py:199 #, python-brace-format msgid "" "Error: Generated comment header for '{path}' is missing copyright lines or " "license expressions. The template is probably incorrect. Did not write new " "header." msgstr "" "Fout: de gegenereerde commentaarheader voor '{path}' mist auteursrechtregels " "of licentie-uitdrukkingen. Het sjabloon is waarschijnlijk niet correct. " "Schreef geen nieuwe header." #. TODO: This may need to be rephrased more elegantly. #: src/reuse/_annotate.py:210 #, python-brace-format msgid "Successfully changed header of {path}" msgstr "Succesvolle verandering van de header van {path}" #: src/reuse/_annotate.py:221 msgid "--skip-unrecognised has no effect when used together with --style" msgstr "" #: src/reuse/_annotate.py:231 #, fuzzy msgid "option --contributor, --copyright or --license is required" msgstr "de optie --copyright of --license is vereist" #: src/reuse/_annotate.py:272 #, python-brace-format msgid "template {template} could not be found" msgstr "sjabloon {template} kon niet worden gevonden" #: src/reuse/_annotate.py:341 src/reuse/_util.py:573 msgid "can't write to '{}'" msgstr "kan niet schrijven naar '{}'" #: src/reuse/_annotate.py:366 #, fuzzy msgid "" "The following files do not have a recognised file extension. Please use --" "style, --force-dot-license, --fallback-dot-license, or --skip-unrecognised:" msgstr "" "'{path}' heeft geen erkende bestandsextensie; gebruik alstublieft --style of " "--explicit-license" #: src/reuse/_annotate.py:382 msgid "copyright statement, repeatable" msgstr "auteursrechtverklaring (herhaalbaar)" #: src/reuse/_annotate.py:389 msgid "SPDX Identifier, repeatable" msgstr "SPDX Identificatie (herhaalbaar)" #: src/reuse/_annotate.py:395 #, fuzzy msgid "file contributor, repeatable" msgstr "SPDX Identificatie (herhaalbaar)" #: src/reuse/_annotate.py:403 msgid "year of copyright statement, optional" msgstr "jaar van auteursrechtverklaring (optie)" #: src/reuse/_annotate.py:411 msgid "comment style to use, optional" msgstr "te gebruiken commentaarstijl (optie)" #: src/reuse/_annotate.py:417 #, fuzzy msgid "copyright prefix to use, optional" msgstr "te gebruiken commentaarstijl (optie)" #: src/reuse/_annotate.py:430 msgid "name of template to use, optional" msgstr "naam van het te gebruiken sjabloon (optie)" #: src/reuse/_annotate.py:435 msgid "do not include year in statement" msgstr "voeg geen jaar toe aan verklaring" #: src/reuse/_annotate.py:440 #, fuzzy msgid "merge copyright lines if copyright statements are identical" msgstr "jaar van auteursrechtverklaring (optie)" #: src/reuse/_annotate.py:446 #, fuzzy msgid "force single-line comment style, optional" msgstr "te gebruiken commentaarstijl (optie)" #: src/reuse/_annotate.py:451 #, fuzzy msgid "force multi-line comment style, optional" msgstr "te gebruiken commentaarstijl (optie)" #: src/reuse/_annotate.py:458 msgid "add headers to all files under specified directories recursively" msgstr "" #: src/reuse/_annotate.py:465 msgid "do not replace the first header in the file; just add a new one" msgstr "" #: src/reuse/_annotate.py:473 msgid "always write a .license file instead of a header inside the file" msgstr "" #: src/reuse/_annotate.py:480 msgid "write a .license file to files with unrecognised comment styles" msgstr "" #: src/reuse/_annotate.py:486 msgid "skip files with unrecognised comment styles" msgstr "" #: src/reuse/_annotate.py:497 #, fuzzy msgid "skip files that already contain REUSE information" msgstr "Bestanden met licentie-informatie: {count} / {total}" #: src/reuse/_annotate.py:532 #, python-brace-format msgid "'{path}' is a binary, therefore using '{new_path}' for the header" msgstr "" "'{path}' is een binary; daarom wordt '{new_path}' gebruikt voor de header" #: src/reuse/_main.py:39 msgid "" "reuse is a tool for compliance with the REUSE recommendations. See for more information, and " "for the online documentation." msgstr "" "reuse is een tool voor naleving van de REUSE Initiatief aanbevelingen. Zie " " voor meer informatie en voor de online documentatie." #: src/reuse/_main.py:45 msgid "" "This version of reuse is compatible with version {} of the REUSE " "Specification." msgstr "" "Deze versie van reuse is compatibel met versie {} van de REUSE Specificatie." #: src/reuse/_main.py:48 msgid "Support the FSFE's work:" msgstr "Ondersteun het werk van de FSFE:" #: src/reuse/_main.py:52 msgid "" "Donations are critical to our strength and autonomy. They enable us to " "continue working for Free Software wherever necessary. Please consider " "making a donation at ." msgstr "" "Donaties zijn belangrijk voor onze sterkte en autonomie. Ze staan ons toe om " "verder te werken voor vrije software waar nodig. Overweeg alstublieft om een " "donatie te maken bij ." #: src/reuse/_main.py:75 msgid "enable debug statements" msgstr "zet debug statements aan" #: src/reuse/_main.py:80 msgid "hide deprecation warnings" msgstr "" #: src/reuse/_main.py:85 msgid "do not skip over Git submodules" msgstr "sla Git-submodules niet over" #: src/reuse/_main.py:90 #, fuzzy msgid "do not skip over Meson subprojects" msgstr "sla Git-submodules niet over" #: src/reuse/_main.py:95 msgid "do not use multiprocessing" msgstr "gebruik geen multiprocessing" #: src/reuse/_main.py:102 msgid "define root of project" msgstr "bepaal de root van het project" #: src/reuse/_main.py:107 msgid "show program's version number and exit" msgstr "versienummer van het programma laten zien en verlaten" #: src/reuse/_main.py:111 msgid "subcommands" msgstr "subcommando's" #: src/reuse/_main.py:118 msgid "add copyright and licensing into the header of files" msgstr "" "voeg auteursrechts- en licentie-informatie toe aan de headers van bestanden" #: src/reuse/_main.py:121 msgid "" "Add copyright and licensing into the header of one or more files.\n" "\n" "By using --copyright and --license, you can specify which copyright holders " "and licenses to add to the headers of the given files.\n" "\n" "By using --contributor, you can specify people or entity that contributed " "but are not copyright holder of the given files." msgstr "" #: src/reuse/_main.py:140 msgid "download a license and place it in the LICENSES/ directory" msgstr "download een licentie en plaats het in de LICENSES/-map" #: src/reuse/_main.py:142 #, fuzzy msgid "Download a license and place it in the LICENSES/ directory." msgstr "download een licentie en plaats het in de LICENSES/-map" #: src/reuse/_main.py:151 msgid "list all non-compliant files" msgstr "lijst maken van alle bestanden die tekortschieten" #: src/reuse/_main.py:154 #, python-brace-format msgid "" "Lint the project directory for compliance with version {reuse_version} of " "the REUSE Specification. You can find the latest version of the " "specification at .\n" "\n" "Specifically, the following criteria are checked:\n" "\n" "- Are there any bad (unrecognised, not compliant with SPDX) licenses in the " "project?\n" "\n" "- Are any licenses referred to inside of the project, but not included in " "the LICENSES/ directory?\n" "\n" "- Are any licenses included in the LICENSES/ directory that are not used " "inside of the project?\n" "\n" "- Do all files have valid copyright and licensing information?" msgstr "" "Voer een statische controle op de naleving van versie {reuse_version} van de " "REUSE-specificatie uit. U kunt de laatste versie van de specificatie vinden " "op .\n" "\n" "De volgende criteria worden in het bijzonder gecontroleerd:\n" "\n" "- Bevat het project slechte (niet-herkende, niet met SPDX in overeenstemming " "zijnde) licenties?\n" "\n" "- Bevat het project gerefereerde licenties die zich niet in de LICENSES/ map " "bevinden?\n" "\n" "- Bevat de map LICENSES/ licenties die binnen het project niet worden " "gebruikt?\n" "\n" "- Bevatten alle bestanden geldige informatie over auteursricht en licenties?" #: src/reuse/_main.py:181 msgid "print the project's bill of materials in SPDX format" msgstr "print de materiaallijst van het project in SPDX-formaat" #: src/reuse/_main.py:189 msgid "list all supported SPDX licenses" msgstr "" #: src/reuse/_main.py:198 msgid "convert .reuse/dep5 to REUSE.toml" msgstr "" #: src/reuse/_main.py:263 #, fuzzy, python-brace-format msgid "'{path}' could not be decoded as UTF-8." msgstr "%s kon niet gedecodeerd worden" #: src/reuse/_main.py:269 #, python-brace-format msgid "" "'{path}' could not be parsed. We received the following error message: " "{message}" msgstr "" #: src/reuse/_util.py:368 src/reuse/global_licensing.py:218 #, python-brace-format msgid "Could not parse '{expression}'" msgstr "Kon '{expression}' niet parsen" #: src/reuse/_util.py:424 #, python-brace-format msgid "" "'{path}' holds an SPDX expression that cannot be parsed, skipping the file" msgstr "" "'{path}' bevat een SPDX-uitdrukking die niet geparsed kan worden; sla het " "bestand over" #: src/reuse/_util.py:556 msgid "'{}' is not a file" msgstr "'{}' is geen bestand" #: src/reuse/_util.py:559 msgid "'{}' is not a directory" msgstr "'{}' is geen map" #: src/reuse/_util.py:562 msgid "can't open '{}'" msgstr "kan '{}' niet openen" #: src/reuse/_util.py:567 msgid "can't write to directory '{}'" msgstr "kan niet schrijven naar map '{}'" #: src/reuse/_util.py:586 msgid "can't read or write '{}'" msgstr "kan '{}' niet lezen of schrijven" #: src/reuse/_util.py:596 msgid "'{}' is not a valid SPDX expression, aborting" msgstr "'{}' is geen geldige SPDX-uitdrukking, aan het afbreken" #: src/reuse/_util.py:624 msgid "'{}' is not a valid SPDX License Identifier." msgstr "'{}' is geen geldige SPDX Licentie Identificatie." #: src/reuse/_util.py:631 msgid "Did you mean:" msgstr "" #: src/reuse/_util.py:638 msgid "" "See for a list of valid SPDX License " "Identifiers." msgstr "" "Zie voor een lijst met geldige SPDX Licentie " "Identificaties." #: src/reuse/convert_dep5.py:118 #, fuzzy msgid "no '.reuse/dep5' file" msgstr ".reuse/dep5 aan het creëren" #: src/reuse/download.py:130 msgid "SPDX License Identifier of license" msgstr "SPDX Licentie Identificatie of licentie" #: src/reuse/download.py:135 msgid "download all missing licenses detected in the project" msgstr "" "download alle ontbrekende licenties die in het project zijn gedetecteerd" #: src/reuse/download.py:145 msgid "" "source from which to copy custom LicenseRef- licenses, either a directory " "that contains the file or the file itself" msgstr "" #: src/reuse/download.py:156 #, python-brace-format msgid "Error: {spdx_identifier} already exists." msgstr "Fout: {spdx_identifier} bestaat al." #: src/reuse/download.py:163 #, fuzzy, python-brace-format msgid "Error: {path} does not exist." msgstr "'{path}' eindigt niet met .spdx" #: src/reuse/download.py:166 msgid "Error: Failed to download license." msgstr "Fout: downloaden van licentie mislukt." #: src/reuse/download.py:171 msgid "Is your internet connection working?" msgstr "Werkt uw internetverbinding?" #: src/reuse/download.py:176 #, python-brace-format msgid "Successfully downloaded {spdx_identifier}." msgstr "{spdx_identifier} met succes gedowload." #: src/reuse/download.py:188 msgid "--output has no effect when used together with --all" msgstr "" #: src/reuse/download.py:192 msgid "the following arguments are required: license" msgstr "de volgende argumenten zijn verplicht: licentie" #: src/reuse/download.py:194 msgid "cannot use --output with more than one license" msgstr "kan --output niet met meer dan een licentie gebruiken" #: src/reuse/global_licensing.py:109 #, python-brace-format msgid "" "{attr_name} must be a {type_name} (got {value} that is a {value_class})." msgstr "" #: src/reuse/global_licensing.py:122 #, python-brace-format msgid "" "Item in {attr_name} collection must be a {type_name} (got {item_value} that " "is a {item_class})." msgstr "" #: src/reuse/global_licensing.py:133 #, python-brace-format msgid "{attr_name} must not be empty." msgstr "" #: src/reuse/global_licensing.py:156 #, python-brace-format msgid "{name} must be a {type} (got {value} that is a {value_type})." msgstr "" #: src/reuse/global_licensing.py:179 #, python-brace-format msgid "" "The value of 'precedence' must be one of {precedence_vals} (got {received})" msgstr "" #: src/reuse/header.py:99 msgid "generated comment is missing copyright lines or license expressions" msgstr "" "gegenereerd commentaar mist auteursrechtregels of licentie-uitdrukkingen" #: src/reuse/lint.py:30 msgid "prevents output" msgstr "" #: src/reuse/lint.py:33 msgid "formats output as JSON" msgstr "" #: src/reuse/lint.py:39 msgid "formats output as plain text" msgstr "" #: src/reuse/lint.py:45 msgid "formats output as errors per line" msgstr "" #: src/reuse/lint.py:64 msgid "BAD LICENSES" msgstr "SLECHTE LICENTIES" #: src/reuse/lint.py:66 src/reuse/lint.py:95 msgid "'{}' found in:" msgstr "'{}' gevonden in:" #: src/reuse/lint.py:73 msgid "DEPRECATED LICENSES" msgstr "VEROUDERDE LICENTIES" #: src/reuse/lint.py:75 msgid "The following licenses are deprecated by SPDX:" msgstr "De volgende licenties zijn verouderd door SPDX:" #: src/reuse/lint.py:83 msgid "LICENSES WITHOUT FILE EXTENSION" msgstr "LICENTIES ZONDER BESTANDSEXTENSIE" #: src/reuse/lint.py:85 msgid "The following licenses have no file extension:" msgstr "De volgende licenties hebben geen bestandsextensie:" #: src/reuse/lint.py:93 msgid "MISSING LICENSES" msgstr "ONTBREKENDE LICENTIES" #: src/reuse/lint.py:102 msgid "UNUSED LICENSES" msgstr "ONGEBRUIKTE LICENTIES" #: src/reuse/lint.py:103 msgid "The following licenses are not used:" msgstr "De volgende licenties zijn niet gebruikt:" #: src/reuse/lint.py:110 msgid "READ ERRORS" msgstr "LEES FOUTEN" #: src/reuse/lint.py:111 msgid "Could not read:" msgstr "Kon niet lezen:" #: src/reuse/lint.py:132 msgid "MISSING COPYRIGHT AND LICENSING INFORMATION" msgstr "AUTEURSRECHT- EN LICENTIE-INFORMATIE ONTBREEKT" #: src/reuse/lint.py:138 msgid "The following files have no copyright and licensing information:" msgstr "" "De volgende bestanden bevatten geen auteursrecht- en licentie-informatie:" #: src/reuse/lint.py:149 msgid "The following files have no copyright information:" msgstr "De volgende bestanden hebben geen auteursrechtinformatie:" #: src/reuse/lint.py:158 msgid "The following files have no licensing information:" msgstr "De volgende bestanden bevatten geen licentie-informatie:" #: src/reuse/lint.py:166 msgid "SUMMARY" msgstr "SAMENVATTING" #: src/reuse/lint.py:171 msgid "Bad licenses:" msgstr "Slechte licenties:" #: src/reuse/lint.py:172 msgid "Deprecated licenses:" msgstr "Verouderde licenties:" #: src/reuse/lint.py:173 msgid "Licenses without file extension:" msgstr "Licenties zonder bestandsextensie:" #: src/reuse/lint.py:176 msgid "Missing licenses:" msgstr "Ontbrekende licenties:" #: src/reuse/lint.py:177 msgid "Unused licenses:" msgstr "Ongebruikte licenties:" #: src/reuse/lint.py:178 msgid "Used licenses:" msgstr "Gebruikte licenties:" #: src/reuse/lint.py:179 #, fuzzy msgid "Read errors:" msgstr "Lees fouten: {count}" #: src/reuse/lint.py:181 #, fuzzy msgid "Files with copyright information:" msgstr "Bestanden met auteursrechtinformatie: {count} / {total}" #: src/reuse/lint.py:185 #, fuzzy msgid "Files with license information:" msgstr "Bestanden met licentie-informatie: {count} / {total}" #: src/reuse/lint.py:202 msgid "" "Congratulations! Your project is compliant with version {} of the REUSE " "Specification :-)" msgstr "" "Gefeliciteerd! Uw project leeft nu versie {} van de REUSE-specificatie na :-)" #: src/reuse/lint.py:209 msgid "" "Unfortunately, your project is not compliant with version {} of the REUSE " "Specification :-(" msgstr "" "Helaas leeft uw project versie {} van de REUSE-specificatie niet na :-(" #: src/reuse/lint.py:216 msgid "RECOMMENDATIONS" msgstr "" #: src/reuse/lint.py:289 #, python-brace-format msgid "{path}: bad license {lic}\n" msgstr "" #: src/reuse/lint.py:296 #, fuzzy, python-brace-format msgid "{lic_path}: deprecated license\n" msgstr "Verouderde licenties:" #: src/reuse/lint.py:303 #, fuzzy, python-brace-format msgid "{lic_path}: license without file extension\n" msgstr "Licenties zonder bestandsextensie:" #: src/reuse/lint.py:312 #, fuzzy, python-brace-format msgid "{lic_path}: unused license\n" msgstr "Ongebruikte licenties:" #: src/reuse/lint.py:319 #, python-brace-format msgid "{path}: missing license {lic}\n" msgstr "" #: src/reuse/lint.py:326 #, python-brace-format msgid "{path}: read error\n" msgstr "" #: src/reuse/lint.py:330 #, fuzzy, python-brace-format msgid "{path}: no license identifier\n" msgstr "'{}' is geen geldige SPDX Licentie Identificatie." #: src/reuse/lint.py:334 #, python-brace-format msgid "{path}: no copyright notice\n" msgstr "" #: src/reuse/project.py:262 #, fuzzy, python-brace-format msgid "'{path}' covered by {global_path}" msgstr "'{path}' valt onder .reuse/dep5" #: src/reuse/project.py:270 #, python-brace-format msgid "" "'{path}' is covered exclusively by REUSE.toml. Not reading the file contents." msgstr "" #: src/reuse/project.py:277 #, python-brace-format msgid "" "'{path}' was detected as a binary file; not searching its contents for REUSE " "information." msgstr "" #: src/reuse/project.py:334 msgid "" "'.reuse/dep5' is deprecated. You are recommended to instead use REUSE.toml. " "Use `reuse convert-dep5` to convert." msgstr "" #: src/reuse/project.py:348 #, python-brace-format msgid "" "Found both '{new_path}' and '{old_path}'. You cannot keep both files " "simultaneously; they are not intercompatible." msgstr "" #: src/reuse/project.py:414 #, python-brace-format msgid "determining identifier of '{path}'" msgstr "identificatie van '{path}' bepalen" #: src/reuse/project.py:422 #, python-brace-format msgid "{path} does not have a file extension" msgstr "{path} heeft geen bestandsextensie" # Niet helemaal duidelijk hoe resolving hier wordt bedoeld. #: src/reuse/project.py:432 #, python-brace-format msgid "" "Could not resolve SPDX License Identifier of {path}, resolving to " "{identifier}. Make sure the license is in the license list found at or that it starts with 'LicenseRef-', and that it has a " "file extension." msgstr "" "Kon de SPDX Licentie Identificatie van {path} niet bepalen, dus gebruiken we " "{identifier}. Zorg ervoor dat de licentie zich in de licentielijst bevind " "die gevonden kan worden op of dat deze begint " "met 'LicenseRef-' en dat deze een bestandsextensie heeft." #: src/reuse/project.py:444 #, python-brace-format msgid "" "{identifier} is the SPDX License Identifier of both {path} and {other_path}" msgstr "" "{identifier} is de SPDX Licentie Identificatie van zowel {path} als " "{other_path}" #: src/reuse/project.py:483 msgid "" "project '{}' is not a VCS repository or required VCS software is not " "installed" msgstr "" #: src/reuse/report.py:310 #, python-brace-format msgid "Could not read '{path}'" msgstr "Kon '{path}' niet lezen" #: src/reuse/report.py:317 #, python-brace-format msgid "Unexpected error occurred while parsing '{path}'" msgstr "Onverwachte fout vond plaats tijdens het parsen van '{path}'" #: src/reuse/report.py:438 msgid "" "Fix bad licenses: At least one license in the LICENSES directory and/or " "provided by 'SPDX-License-Identifier' tags is invalid. They are either not " "valid SPDX License Identifiers or do not start with 'LicenseRef-'. FAQ about " "custom licenses: https://reuse.software/faq/#custom-license" msgstr "" #: src/reuse/report.py:449 msgid "" "Fix deprecated licenses: At least one of the licenses in the LICENSES " "directory and/or provided by an 'SPDX-License-Identifier' tag or in '.reuse/" "dep5' has been deprecated by SPDX. The current list and their respective " "recommended new identifiers can be found here: " msgstr "" #: src/reuse/report.py:460 msgid "" "Fix licenses without file extension: At least one license text file in the " "'LICENSES' directory does not have a '.txt' file extension. Please rename " "the file(s) accordingly." msgstr "" #: src/reuse/report.py:469 msgid "" "Fix missing licenses: For at least one of the license identifiers provided " "by the 'SPDX-License-Identifier' tags, there is no corresponding license " "text file in the 'LICENSES' directory. For SPDX license identifiers, you can " "simply run 'reuse download --all' to get any missing ones. For custom " "licenses (starting with 'LicenseRef-'), you need to add these files yourself." msgstr "" #: src/reuse/report.py:481 msgid "" "Fix unused licenses: At least one of the license text files in 'LICENSES' is " "not referenced by any file, e.g. by an 'SPDX-License-Identifier' tag. Please " "make sure that you either tag the accordingly licensed files properly, or " "delete the unused license text if you are sure that no file or code snippet " "is licensed as such." msgstr "" #: src/reuse/report.py:492 msgid "" "Fix read errors: At least one of the files in your directory cannot be read " "by the tool. Please check the file permissions. You will find the affected " "files at the top of the output as part of the logged error messages." msgstr "" #: src/reuse/report.py:501 msgid "" "Fix missing copyright/licensing information: For one or more files, the tool " "cannot find copyright and/or licensing information. You typically do this by " "adding 'SPDX-FileCopyrightText' and 'SPDX-License-Identifier' tags to each " "file. The tutorial explains additional ways to do this: " msgstr "" #: src/reuse/spdx.py:32 msgid "" "populate the LicenseConcluded field; note that reuse cannot guarantee the " "field is accurate" msgstr "" #: src/reuse/spdx.py:39 msgid "name of the person signing off on the SPDX report" msgstr "" #: src/reuse/spdx.py:44 msgid "name of the organization signing off on the SPDX report" msgstr "" #: src/reuse/spdx.py:60 msgid "" "error: --creator-person=NAME or --creator-organization=NAME required when --" "add-license-concluded is provided" msgstr "" #: src/reuse/spdx.py:75 #, python-brace-format msgid "" "'{path}' does not match a common SPDX file pattern. Find the suggested " "naming conventions here: https://spdx.github.io/spdx-spec/conformance/#44-" "standard-data-format-requirements" msgstr "" #: /usr/lib/python3.10/argparse.py:308 msgid "usage: " msgstr "gebruik: " #: /usr/lib/python3.10/argparse.py:880 msgid ".__call__() not defined" msgstr ".__call__() is niet gedefinieerd" #: /usr/lib/python3.10/argparse.py:1223 #, python-format msgid "unknown parser %(parser_name)r (choices: %(choices)s)" msgstr "onbekende parser %(parser_name)r (keuzes: %(choices)s)" #: /usr/lib/python3.10/argparse.py:1283 #, python-format msgid "argument \"-\" with mode %r" msgstr "argument \"-\" met mode %r" #: /usr/lib/python3.10/argparse.py:1292 #, python-format msgid "can't open '%(filename)s': %(error)s" msgstr "kan '%(filename)s' niet openen: %(error)s" #: /usr/lib/python3.10/argparse.py:1501 #, python-format msgid "cannot merge actions - two groups are named %r" msgstr "kan acties niet samenvoegen - twee groepen delen de naam %r" #: /usr/lib/python3.10/argparse.py:1539 msgid "'required' is an invalid argument for positionals" msgstr "'required' is een ongeldig argument voor positionele argumenten" #: /usr/lib/python3.10/argparse.py:1561 #, python-format msgid "" "invalid option string %(option)r: must start with a character " "%(prefix_chars)r" msgstr "" "ongeldige optiestring %(option)r: moet beginnen met een karakter " "%(prefix_chars)r" #: /usr/lib/python3.10/argparse.py:1579 #, python-format msgid "dest= is required for options like %r" msgstr "dest= is benodigd voor opties zoals %r" #: /usr/lib/python3.10/argparse.py:1596 #, python-format msgid "invalid conflict_resolution value: %r" msgstr "ongeldige conflictresolutiewaarde: %r" #: /usr/lib/python3.10/argparse.py:1614 #, python-format msgid "conflicting option string: %s" msgid_plural "conflicting option strings: %s" msgstr[0] "tegenstrijdige optiestring: %s" msgstr[1] "tegenstrijdige optiestrings: %s" #: /usr/lib/python3.10/argparse.py:1680 msgid "mutually exclusive arguments must be optional" msgstr "argumenten die elkaar uitsluiten moeten optioneel zijn" #: /usr/lib/python3.10/argparse.py:1748 msgid "positional arguments" msgstr "positionele argumenten" #: /usr/lib/python3.10/argparse.py:1749 msgid "options" msgstr "" #: /usr/lib/python3.10/argparse.py:1764 msgid "show this help message and exit" msgstr "dit helpbericht laten zien en verlaten" #: /usr/lib/python3.10/argparse.py:1795 msgid "cannot have multiple subparser arguments" msgstr "kan niet meerdere subparser-argumenten hebben" #: /usr/lib/python3.10/argparse.py:1847 /usr/lib/python3.10/argparse.py:2362 #, python-format msgid "unrecognized arguments: %s" msgstr "niet erkende argumenten: %s" #: /usr/lib/python3.10/argparse.py:1948 #, python-format msgid "not allowed with argument %s" msgstr "niet toegestaan met argument %s" #: /usr/lib/python3.10/argparse.py:1998 /usr/lib/python3.10/argparse.py:2012 #, python-format msgid "ignored explicit argument %r" msgstr "expliciet argument %r genegeerd" #: /usr/lib/python3.10/argparse.py:2119 #, python-format msgid "the following arguments are required: %s" msgstr "de volgende argumenten zijn verplicht: %s" #: /usr/lib/python3.10/argparse.py:2134 #, python-format msgid "one of the arguments %s is required" msgstr "één van de argumenten %s is benodigd" #: /usr/lib/python3.10/argparse.py:2177 msgid "expected one argument" msgstr "verwachtte één argument" #: /usr/lib/python3.10/argparse.py:2178 msgid "expected at most one argument" msgstr "verwachtte maximaal één argument" #: /usr/lib/python3.10/argparse.py:2179 msgid "expected at least one argument" msgstr "verwachtte minimaal één argument" #: /usr/lib/python3.10/argparse.py:2183 #, python-format msgid "expected %s argument" msgid_plural "expected %s arguments" msgstr[0] "verwachtte %s argument" msgstr[1] "verwachtte %s argumenten" #: /usr/lib/python3.10/argparse.py:2241 #, python-format msgid "ambiguous option: %(option)s could match %(matches)s" msgstr "" "dubbelzinnige optie: %(option)s zou ook gelijk kunnen zijn aan %(matches)s" #: /usr/lib/python3.10/argparse.py:2305 #, python-format msgid "unexpected option string: %s" msgstr "onverwachtte optiestring: %s" #: /usr/lib/python3.10/argparse.py:2502 #, python-format msgid "%r is not callable" msgstr "%r is niet callable" #: /usr/lib/python3.10/argparse.py:2519 #, python-format msgid "invalid %(type)s value: %(value)r" msgstr "ongeldige %(type)s waarde: %(value)r" #: /usr/lib/python3.10/argparse.py:2530 #, python-format msgid "invalid choice: %(value)r (choose from %(choices)s)" msgstr "ongeldige keuze: %(value)r (kiezen uit %(choices)s)" #: /usr/lib/python3.10/argparse.py:2606 #, python-format msgid "%(prog)s: error: %(message)s\n" msgstr "%(prog)s: fout: %(message)s\n" #~ msgid "initialize REUSE project" #~ msgstr "initialiseer REUSE-project" #, fuzzy #~ msgid "no '{}' file, or could not read it" #~ msgstr "geen debian/copyright bestand, of kon het niet lezen" #, fuzzy #~ msgid "" #~ "What license is your project under? Provide the SPDX License Identifier. " #~ "See for the list." #~ msgstr "" #~ "Onder welke licentie valt uw project? Voeg de SPDX Licientie " #~ "Identificatie toe." #~ msgid "" #~ "What other license is your project under? Provide the SPDX License " #~ "Identifier." #~ msgstr "" #~ "Onder welke andere licentie valt uw project? Voeg de SPDX Licientie " #~ "Identificatie toe." #~ msgid "To stop adding licenses, hit RETURN." #~ msgstr "Typ RETURN om te stoppen met het toevoegen van licenties." #~ msgid "Project already initialized" #~ msgstr "Project al geïnitialiseerd" #~ msgid "Initializing project for REUSE." #~ msgstr "Project voor REUSE initialiseren." #~ msgid "What is the name of the project?" #~ msgstr "Wat is de naam van het project?" #~ msgid "What is the internet address of the project?" #~ msgstr "Wat is het internetadres van het project?" #~ msgid "What is the name of the maintainer?" #~ msgstr "Wat is de naam van de beheerder?" #~ msgid "What is the e-mail address of the maintainer?" #~ msgstr "Wat is het e-mailadres van de beheerder?" #~ msgid "All done! Initializing now." #~ msgstr "Klaar! Nu aan het initialiseren." #~ msgid "{} already exists" #~ msgstr "{} bestaat al" #~ msgid "Could not download {}" #~ msgstr "Kon {} niet downloaden" #~ msgid "Initialization complete." #~ msgstr "Initialisatie voltooid." #, fuzzy #~ msgid "" #~ "Add copyright and licensing into the header of one or more files.\n" #~ "\n" #~ "By using --copyright and --license, you can specify which copyright " #~ "holders and licenses to add to the headers of the given files.\n" #~ "\n" #~ "By using --contributor, you can specify people or entity that contributed " #~ "but are not copyright holder of the given files.\n" #~ "The first comment is replaced with a new header containing the new " #~ "copyright and licensing information and its former copyright and " #~ "licensing. If you want to keep the first comment intact, use --no-" #~ "replace.\n" #~ "\n" #~ "The comment style should be auto-detected for your files. If a comment " #~ "style could not be detected and --skip-unrecognised is not specified, the " #~ "process aborts. Use --style to specify or override the comment style to " #~ "use.\n" #~ "\n" #~ "A single-line comment style is used when it is available. If no single-" #~ "line comment style is available, a multi-line comment style is used. You " #~ "can force a certain comment style using --single-line or --multi-line.\n" #~ "\n" #~ "You can change the template of the header comment by using --template. " #~ "Place a Jinja2 template in .reuse/templates/mytemplate.jinja2. You can " #~ "use the template by specifying '--template mytemplate'. Read the online " #~ "documentation on how to use this feature.\n" #~ "\n" #~ "If a binary file is detected, or if --force-dot-license is specified, the " #~ "header is placed in a .license file." #~ msgstr "" #~ "Voeg auteursrechts- en licentie-informatie toe aan de headers van een of " #~ "meer bestanden.\n" #~ "\n" #~ "Met --copyright en --license kun je de auteursrechthouders en licenties " #~ "specificeren die toegevoegd moeten worden aan de headers van de " #~ "bestanden.\n" #~ "\n" #~ "De commentstijl wordt automatisch gedetecteerd voor uw bestanden. Als een " #~ "commentstijl niet gedetecteerd kan worden, stopt het proces. Gebruik --" #~ "style om een commentstijl te bepalen.\n" #~ "\n" #~ "U kunt het sjabloon van de header veranderen met --template. Zet een " #~ "Jinja2-sjabloon in .reuse/templates/mijnsjabloon.jinja2. U kunt het " #~ "sjabloon gebruiken door '--template mijnsjabloon' te specificeren. Lees " #~ "de online documentatie voor meer informatie over deze functionaliteit.\n" #~ "\n" #~ "Als een binary bestand gedetecteerd is, of als --explicit-license " #~ "gebruikt wordt, dan wordt de header in een .license bestand geplaatst.\n" #~ "\n" #~ "BELANGRIJK: Dit is momenteel EXPERIMENTEEL!" #~ msgid "" #~ "Download a license and place it in the LICENSES/ directory.\n" #~ "\n" #~ "The LICENSES/ directory is automatically found in the following order:\n" #~ "\n" #~ "- The LICENSES/ directory in the root of the VCS repository.\n" #~ "\n" #~ "- The current directory if its name is LICENSES.\n" #~ "\n" #~ "- The LICENSES/ directory in the current directory.\n" #~ "\n" #~ "If the LICENSES/ directory cannot be found, one is simply created." #~ msgstr "" #~ "Download een licentie en plaats het in de LICENSES/-map.\n" #~ "\n" #~ "De LICENSES/-map is automatisch gevonden in de volgende volgorde:\n" #~ "\n" #~ "- De LICENSES/-map in de root van de VCS-map.\n" #~ "\n" #~ "- De huidige map als de naam van de huidige map LICENSES/ is.\n" #~ "\n" #~ "- De LICENSES/-map in de huidige map.\n" #~ "\n" #~ "Als de LICENSES/-map niet gevonden kan worden, dan wordt er een gemaakt." #~ msgid ".reuse/dep5 has syntax errors" #~ msgstr ".reuse/dep5 kent syntaxfouten" #~ msgid "optional arguments" #~ msgstr "optionele argumenten" #~ msgid "option --exclude-year and --year are mutually exclusive" #~ msgstr "de opties --exclude-year en --year sluiten elkaar uit" #, fuzzy #~ msgid "option --single-line and --multi-line are mutually exclusive" #~ msgstr "de opties --exclude-year en --year sluiten elkaar uit" #~ msgid "Downloading {}" #~ msgstr "{} aan het downloaden" #, fuzzy #~ msgid "conflicting subparser: %s" #~ msgstr "tegenstrijdige optiestring: %s" #, fuzzy #~ msgid "conflicting subparser alias: %s" #~ msgstr "tegenstrijdige optiestring: %s" #~ msgid "can't open '%s': %s" #~ msgstr "kan '%s' niet openen: %s" #~ msgid "place header in path.license instead of path" #~ msgstr "plaats header in path.license in plaats van path" #~ msgid "could not find Git" #~ msgstr "kon Git niet vinden" #~ msgid "yielding %s" #~ msgstr "%s aan het verwerken" #~ msgid "currently walking in %s" #~ msgstr "aan het lopen door %s" #~ msgid "ignoring %s" #~ msgstr "%s negeren" #~ msgid "searching %s for reuse information" #~ msgstr "%s aan het doorzoeken voor reuse informatie" #~ msgid "%s covered by debian/copyright" #~ msgstr "debian/copyright omvat %s" #~ msgid "" #~ "{path} is licensed under {identifier}, but its license file could not be " #~ "found" #~ msgstr "" #~ "{path} valt onder {identifier}, maar het licentiebestand kon niet " #~ "gevonden worden" #~ msgid "searching %s for license tags" #~ msgstr "%s aan het doorzoeken voor licentie-tags" #~ msgid "" #~ "Could not resolve SPDX identifier of {path}, resolving to {identifier}" #~ msgstr "Kon SPDX-identifier van {path} niet oplossen, gebruik {identifier}" #~ msgid "reuse Copyright (C) 2017-2018 Free Software Foundation Europe e.V." #~ msgstr "" #~ "reuse Auteursrecht (C) 2017-2018 Free Software Foundation Europe e.V." #~ msgid "" #~ "reuse is free software: you can redistribute it and/or modify it under " #~ "the terms of the GNU General Public License as published by the Free " #~ "Software Foundation, either version 3 of the License, or (at your option) " #~ "any later version.\n" #~ "\n" #~ "reuse is distributed in the hope that it will be useful, but WITHOUT ANY " #~ "WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS " #~ "FOR A PARTICULAR PURPOSE. See the GNU General Public License for more " #~ "details.\n" #~ "\n" #~ "You should have received a copy of the GNU General Public License along " #~ "with reuse. If not, see ." #~ msgstr "" #~ "reuse is vrije software: u mag het herdistribueren en/of wijzigen onder " #~ "de voorwaarden van de GNU Algemene Publieke Licentie zoals gepubliceerd " #~ "door de Free Software Foundation, onder versie 3 van de Licentie of (naar " #~ "uw keuze) elke latere versie.\n" #~ "\n" #~ "reuse is gedistribueerd in de hoop dat het nuttig zal zijn maar ZONDER " #~ "ENIGE GARANTIE; zelfs zonder de impliciete garanties die GEBRUIKELIJK " #~ "ZIJN IN DE HANDEL of voor BRUIKBAARHEID VOOR EEN SPECIFIEK DOEL. Zie de " #~ "GNU Algemene Publieke Licentie voor meer details.\n" #~ "\n" #~ "U hoort een kopie van de GNU Algemene Publieke Licentie te hebben " #~ "ontvangen samen met reuse. Als dat niet het geval is, zie ." #~ msgid "IMPORTANT:" #~ msgstr "BELANGRIJK:" #~ msgid "" #~ "You do not have pygit2 installed. reuse will slow down significantly " #~ "because of this. For better performance, please install your " #~ "distribution's version of pygit2." #~ msgstr "" #~ "U heeft pygit2 niet geïnstalleerd. reuse zal hierdoor significant " #~ "langzamer draaien. Voor betere prestatie, installeer alstublieft uw " #~ "distributie's versie van pygit2." #~ msgid "could not read %s" #~ msgstr "kon %s niet lezen" #~ msgid "none\n" #~ msgstr "geen\n" #~ msgid "do not use debian/copyright to extract reuse information" #~ msgstr "debian/copyright niet gebruiken om reuse informatie te extraheren" #~ msgid "" #~ "List all non-compliant files.\n" #~ "\n" #~ "A file is non-compliant when:\n" #~ "\n" #~ "- It has no copyright information.\n" #~ "\n" #~ "- It has no license (declared as SPDX expression).\n" #~ "\n" #~ "- Its license could not be found.\n" #~ "\n" #~ "This prints only the paths of the files that do not comply, each file on " #~ "a separate line.\n" #~ "\n" #~ "Error and warning messages are output to STDERR." #~ msgstr "" #~ "Lijst maken van niet-voldoenende bestanden.\n" #~ "\n" #~ "Een bestand voldoet niet als:\n" #~ "\n" #~ "- Het geen auteursrechtinformatie heeft.\n" #~ "\n" #~ "- Het geen licentie heeft (gegeven als SPDX-uitdrukking).\n" #~ "\n" #~ "- Zijn licentie niet gevonden kan worden.\n" #~ "\n" #~ "Dit print enkel de paden van de bestanden die niet voldoen. Elk bestand " #~ "heeft zijn eigen regel.\n" #~ "\n" #~ "Fout- en waarschuwingsmeldingen worden geprint naar STDERR." #~ msgid "SPDX expressions are mandatory for compliance" #~ msgstr "SPDX-uitdrukkingen zijn verplicht voor voldoening" #~ msgid "copyright notices are mandatory for compliance" #~ msgstr "auteursrechtnotities zijn verplicht voor voldoening" #~ msgid "print the SPDX expressions of each provided file" #~ msgstr "de SPDX-uitdrukkingen van elke gegeven file printen" #~ msgid "reuse, version {}\n" #~ msgstr "reuse, versie {}\n" reuse-tool-4.0.3/po/pt.po000066400000000000000000001044751464275211500152370ustar00rootroot00000000000000# SPDX-FileCopyrightText: 2020 José Vieira # # SPDX-License-Identifier: GPL-3.0-or-later msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-07-03 13:09+0000\n" "PO-Revision-Date: 2023-06-21 09:53+0000\n" "Last-Translator: Anonymous \n" "Language-Team: Portuguese \n" "Language: pt\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n > 1;\n" "X-Generator: Weblate 4.18.1\n" #: src/reuse/_annotate.py:74 #, python-brace-format msgid "" "'{path}' does not support single-line comments, please do not use --single-" "line" msgstr "" #: src/reuse/_annotate.py:81 #, python-brace-format msgid "" "'{path}' does not support multi-line comments, please do not use --multi-line" msgstr "" #: src/reuse/_annotate.py:136 #, python-brace-format msgid "Skipped unrecognised file '{path}'" msgstr "" #: src/reuse/_annotate.py:142 #, python-brace-format msgid "'{path}' is not recognised; creating '{path}.license'" msgstr "" #: src/reuse/_annotate.py:158 #, python-brace-format msgid "Skipped file '{path}' already containing REUSE information" msgstr "" #: src/reuse/_annotate.py:192 #, python-brace-format msgid "Error: Could not create comment for '{path}'" msgstr "Erro: Não foi possível criar um comentário para '{path}'" #: src/reuse/_annotate.py:199 #, python-brace-format msgid "" "Error: Generated comment header for '{path}' is missing copyright lines or " "license expressions. The template is probably incorrect. Did not write new " "header." msgstr "" "Erro: O cabeçalho de comentário gerado para '{path}' não contém linhas de " "direitos de autor ou expressões de licenciamento. Provavelmente o modelo não " "está correcto. Não foi escrito nenhum novo cabeçalho." #. TODO: This may need to be rephrased more elegantly. #: src/reuse/_annotate.py:210 #, python-brace-format msgid "Successfully changed header of {path}" msgstr "O cabeçalho de {path} foi alterado com êxito" #: src/reuse/_annotate.py:221 msgid "--skip-unrecognised has no effect when used together with --style" msgstr "" #: src/reuse/_annotate.py:231 #, fuzzy msgid "option --contributor, --copyright or --license is required" msgstr "é requerida uma das opções --copyright ou --license" #: src/reuse/_annotate.py:272 #, python-brace-format msgid "template {template} could not be found" msgstr "o modelo {template} não foi encontrado" #: src/reuse/_annotate.py:341 src/reuse/_util.py:573 msgid "can't write to '{}'" msgstr "não é possível escrever em '{}'" #: src/reuse/_annotate.py:366 #, fuzzy msgid "" "The following files do not have a recognised file extension. Please use --" "style, --force-dot-license, --fallback-dot-license, or --skip-unrecognised:" msgstr "" "'{path}' não têm uma extensão de ficheiro reconhecida; usar --style ou --" "explicit-license" #: src/reuse/_annotate.py:382 msgid "copyright statement, repeatable" msgstr "declaração de direitos de autor (repetível)" #: src/reuse/_annotate.py:389 msgid "SPDX Identifier, repeatable" msgstr "Identificador SPDX (repetível)" #: src/reuse/_annotate.py:395 #, fuzzy msgid "file contributor, repeatable" msgstr "Identificador SPDX (repetível)" #: src/reuse/_annotate.py:403 msgid "year of copyright statement, optional" msgstr "ano da declaração de direitos de autor (opcional)" #: src/reuse/_annotate.py:411 msgid "comment style to use, optional" msgstr "estilo de comentário a usar (opcional)" #: src/reuse/_annotate.py:417 #, fuzzy msgid "copyright prefix to use, optional" msgstr "estilo de comentário a usar (opcional)" #: src/reuse/_annotate.py:430 msgid "name of template to use, optional" msgstr "nome do modelo a usar (opcional)" #: src/reuse/_annotate.py:435 msgid "do not include year in statement" msgstr "não incluir o ano na declaração" #: src/reuse/_annotate.py:440 #, fuzzy msgid "merge copyright lines if copyright statements are identical" msgstr "ano da declaração de direitos de autor (opcional)" #: src/reuse/_annotate.py:446 #, fuzzy msgid "force single-line comment style, optional" msgstr "estilo de comentário a usar (opcional)" #: src/reuse/_annotate.py:451 #, fuzzy msgid "force multi-line comment style, optional" msgstr "estilo de comentário a usar (opcional)" #: src/reuse/_annotate.py:458 msgid "add headers to all files under specified directories recursively" msgstr "" #: src/reuse/_annotate.py:465 msgid "do not replace the first header in the file; just add a new one" msgstr "" #: src/reuse/_annotate.py:473 msgid "always write a .license file instead of a header inside the file" msgstr "" #: src/reuse/_annotate.py:480 msgid "write a .license file to files with unrecognised comment styles" msgstr "" #: src/reuse/_annotate.py:486 msgid "skip files with unrecognised comment styles" msgstr "" #: src/reuse/_annotate.py:497 #, fuzzy msgid "skip files that already contain REUSE information" msgstr "Ficheiros com informação de licenciamento: {count} / {total}" #: src/reuse/_annotate.py:532 #, python-brace-format msgid "'{path}' is a binary, therefore using '{new_path}' for the header" msgstr "'{path}' é binário, por isso é usado '{new_path}' para o cabeçalho" #: src/reuse/_main.py:39 msgid "" "reuse is a tool for compliance with the REUSE recommendations. See for more information, and " "for the online documentation." msgstr "" "O reuse é uma ferramenta para observância das recomendações REUSE. Ver " " para mais informação e para documentação em linha." #: src/reuse/_main.py:45 msgid "" "This version of reuse is compatible with version {} of the REUSE " "Specification." msgstr "" "Esta versão do reuse é compatível com a versão {} da especificação REUSE." #: src/reuse/_main.py:48 msgid "Support the FSFE's work:" msgstr "Apoiar o trabalho da FSFE:" #: src/reuse/_main.py:52 msgid "" "Donations are critical to our strength and autonomy. They enable us to " "continue working for Free Software wherever necessary. Please consider " "making a donation at ." msgstr "" "Os donativos são cruciais para a nossa força e autonomia. Permitem-nos " "continuar a trabalhar em prol do Sotware Livre sempre que necessário. " "Considere fazer um donativo em ." #: src/reuse/_main.py:75 msgid "enable debug statements" msgstr "activar expressões de depuração" #: src/reuse/_main.py:80 msgid "hide deprecation warnings" msgstr "" #: src/reuse/_main.py:85 msgid "do not skip over Git submodules" msgstr "não ignorar sub-módulos do Git" #: src/reuse/_main.py:90 #, fuzzy msgid "do not skip over Meson subprojects" msgstr "não ignorar sub-módulos do Git" #: src/reuse/_main.py:95 msgid "do not use multiprocessing" msgstr "não usar multi-processamento" #: src/reuse/_main.py:102 msgid "define root of project" msgstr "definir a raíz do projecto" #: src/reuse/_main.py:107 msgid "show program's version number and exit" msgstr "mostrar o número de versão do programa e sair" #: src/reuse/_main.py:111 msgid "subcommands" msgstr "sub-comandos" #: src/reuse/_main.py:118 msgid "add copyright and licensing into the header of files" msgstr "adicionar direitos de autor e licenciamento ao cabeçalho dos ficheiros" #: src/reuse/_main.py:121 msgid "" "Add copyright and licensing into the header of one or more files.\n" "\n" "By using --copyright and --license, you can specify which copyright holders " "and licenses to add to the headers of the given files.\n" "\n" "By using --contributor, you can specify people or entity that contributed " "but are not copyright holder of the given files." msgstr "" #: src/reuse/_main.py:140 msgid "download a license and place it in the LICENSES/ directory" msgstr "descarregar uma licença e guardá-la na pasta LICENSES/" #: src/reuse/_main.py:142 #, fuzzy msgid "Download a license and place it in the LICENSES/ directory." msgstr "descarregar uma licença e guardá-la na pasta LICENSES/" #: src/reuse/_main.py:151 msgid "list all non-compliant files" msgstr "listar todos os ficheiros não conformes" #: src/reuse/_main.py:154 #, python-brace-format msgid "" "Lint the project directory for compliance with version {reuse_version} of " "the REUSE Specification. You can find the latest version of the " "specification at .\n" "\n" "Specifically, the following criteria are checked:\n" "\n" "- Are there any bad (unrecognised, not compliant with SPDX) licenses in the " "project?\n" "\n" "- Are any licenses referred to inside of the project, but not included in " "the LICENSES/ directory?\n" "\n" "- Are any licenses included in the LICENSES/ directory that are not used " "inside of the project?\n" "\n" "- Do all files have valid copyright and licensing information?" msgstr "" "Analisar (lint) a pasta do projecto para verificar a conformidade com a " "versão {reuse_version} da especificação REUSE. A última versão da " "especificação encontra-se em .\n" "\n" "Em concreto, são verificados os seguintes critérios:\n" "\n" "- Há no projecto licenças irregulares (não reconhecidas ou não conformes com " "o SPDX)?\n" "\n" "- Há alguma licença mencionada no projecto que não esteja incluída na pasta " "LICENSES/?\n" "\n" "- Há alguma licença incluída na pasta LICENSES/ que não seja usada no " "projecto?\n" "\n" "- Todos os ficheiros têm informação válida de direitos de autor e de " "licenciamento?" #: src/reuse/_main.py:181 msgid "print the project's bill of materials in SPDX format" msgstr "imprimir a lista de materiais do projecto em formato SPDX" #: src/reuse/_main.py:189 msgid "list all supported SPDX licenses" msgstr "" #: src/reuse/_main.py:198 msgid "convert .reuse/dep5 to REUSE.toml" msgstr "" #: src/reuse/_main.py:263 #, python-brace-format msgid "'{path}' could not be decoded as UTF-8." msgstr "" #: src/reuse/_main.py:269 #, python-brace-format msgid "" "'{path}' could not be parsed. We received the following error message: " "{message}" msgstr "" #: src/reuse/_util.py:368 src/reuse/global_licensing.py:218 #, python-brace-format msgid "Could not parse '{expression}'" msgstr "Não foi possível executar parse '{expression}'" #: src/reuse/_util.py:424 #, python-brace-format msgid "" "'{path}' holds an SPDX expression that cannot be parsed, skipping the file" msgstr "" "'{path}' inclui uma expressão SPDX que não pode ser analisada (parsed); " "ficheiro ignorado" #: src/reuse/_util.py:556 msgid "'{}' is not a file" msgstr "'{}' não é um ficheiro" #: src/reuse/_util.py:559 msgid "'{}' is not a directory" msgstr "'{}' não é uma pasta" #: src/reuse/_util.py:562 msgid "can't open '{}'" msgstr "não é possível abrir '{}'" #: src/reuse/_util.py:567 msgid "can't write to directory '{}'" msgstr "não é possível escrever no directório '{}'" #: src/reuse/_util.py:586 msgid "can't read or write '{}'" msgstr "não é possível ler ou escrever em '{}'" #: src/reuse/_util.py:596 msgid "'{}' is not a valid SPDX expression, aborting" msgstr "'{}' não é uma expressão SPDX válida; a abortar" #: src/reuse/_util.py:624 msgid "'{}' is not a valid SPDX License Identifier." msgstr "'{}' não é um Identificador de Licença SPDX válido." #: src/reuse/_util.py:631 msgid "Did you mean:" msgstr "" #: src/reuse/_util.py:638 msgid "" "See for a list of valid SPDX License " "Identifiers." msgstr "" "Consultar uma lista de Identificadores de Licença SPDX válidos em ." #: src/reuse/convert_dep5.py:118 #, fuzzy msgid "no '.reuse/dep5' file" msgstr "A criar .reuse/dep5" #: src/reuse/download.py:130 msgid "SPDX License Identifier of license" msgstr "Identificador de Licença SPDX da licença" #: src/reuse/download.py:135 msgid "download all missing licenses detected in the project" msgstr "descarregar todas as licenças detectadas como em falta no projecto" #: src/reuse/download.py:145 msgid "" "source from which to copy custom LicenseRef- licenses, either a directory " "that contains the file or the file itself" msgstr "" #: src/reuse/download.py:156 #, python-brace-format msgid "Error: {spdx_identifier} already exists." msgstr "Erro: {spdx_identifier} já existe." #: src/reuse/download.py:163 #, fuzzy, python-brace-format msgid "Error: {path} does not exist." msgstr "'{path}' não termina em .spdx" #: src/reuse/download.py:166 msgid "Error: Failed to download license." msgstr "Erro: Falha ao descarregar a licença." #: src/reuse/download.py:171 msgid "Is your internet connection working?" msgstr "A ligação à Internet está a funcionar?" #: src/reuse/download.py:176 #, python-brace-format msgid "Successfully downloaded {spdx_identifier}." msgstr "{spdx_identifier} transferido com êxito." #: src/reuse/download.py:188 msgid "--output has no effect when used together with --all" msgstr "" #: src/reuse/download.py:192 msgid "the following arguments are required: license" msgstr "são requeridos os seguintes argumentos: licença" #: src/reuse/download.py:194 msgid "cannot use --output with more than one license" msgstr "não se pode usar --output com mais do que uma licença" #: src/reuse/global_licensing.py:109 #, python-brace-format msgid "" "{attr_name} must be a {type_name} (got {value} that is a {value_class})." msgstr "" #: src/reuse/global_licensing.py:122 #, python-brace-format msgid "" "Item in {attr_name} collection must be a {type_name} (got {item_value} that " "is a {item_class})." msgstr "" #: src/reuse/global_licensing.py:133 #, python-brace-format msgid "{attr_name} must not be empty." msgstr "" #: src/reuse/global_licensing.py:156 #, python-brace-format msgid "{name} must be a {type} (got {value} that is a {value_type})." msgstr "" #: src/reuse/global_licensing.py:179 #, python-brace-format msgid "" "The value of 'precedence' must be one of {precedence_vals} (got {received})" msgstr "" #: src/reuse/header.py:99 msgid "generated comment is missing copyright lines or license expressions" msgstr "" "o comentário gerado não tem linhas de direitos de autor ou expressões de " "licenciamento" #: src/reuse/lint.py:30 msgid "prevents output" msgstr "" #: src/reuse/lint.py:33 msgid "formats output as JSON" msgstr "" #: src/reuse/lint.py:39 msgid "formats output as plain text" msgstr "" #: src/reuse/lint.py:45 msgid "formats output as errors per line" msgstr "" #: src/reuse/lint.py:64 msgid "BAD LICENSES" msgstr "LICENÇAS IRREGULARES" #: src/reuse/lint.py:66 src/reuse/lint.py:95 msgid "'{}' found in:" msgstr "'{}' encontrado em:" #: src/reuse/lint.py:73 msgid "DEPRECATED LICENSES" msgstr "LICENÇAS DESCONTINUADAS" #: src/reuse/lint.py:75 msgid "The following licenses are deprecated by SPDX:" msgstr "As seguintes licenças foram descontinuadas pelo SPDX:" #: src/reuse/lint.py:83 msgid "LICENSES WITHOUT FILE EXTENSION" msgstr "LICENÇAS SEM EXTENSÃO DE FICHEIRO" #: src/reuse/lint.py:85 msgid "The following licenses have no file extension:" msgstr "As seguintes licenças não têm extensão de ficheiro:" #: src/reuse/lint.py:93 msgid "MISSING LICENSES" msgstr "LICENÇAS EM FALTA" #: src/reuse/lint.py:102 msgid "UNUSED LICENSES" msgstr "LICENÇAS NÃO USADAS" #: src/reuse/lint.py:103 msgid "The following licenses are not used:" msgstr "As seguintes licenças não estão a ser usadas:" #: src/reuse/lint.py:110 msgid "READ ERRORS" msgstr "ERROS DE LEITURA" #: src/reuse/lint.py:111 msgid "Could not read:" msgstr "Não foi possível ler:" #: src/reuse/lint.py:132 msgid "MISSING COPYRIGHT AND LICENSING INFORMATION" msgstr "INFORMAÇÃO EM FALTA SOBRE DIREITOS DE AUTOR E LICENCIAMENTO" #: src/reuse/lint.py:138 msgid "The following files have no copyright and licensing information:" msgstr "" "Os seguintes ficheiros não contêm informação de direitos de autor nem de " "licenciamento:" #: src/reuse/lint.py:149 msgid "The following files have no copyright information:" msgstr "Os seguintes ficheiros não contêm informação de direitos de autor:" #: src/reuse/lint.py:158 msgid "The following files have no licensing information:" msgstr "Os seguintes ficheiros não contêm informação de licenciamento:" #: src/reuse/lint.py:166 msgid "SUMMARY" msgstr "RESUMO" #: src/reuse/lint.py:171 msgid "Bad licenses:" msgstr "Licenças irregulares:" #: src/reuse/lint.py:172 msgid "Deprecated licenses:" msgstr "Licenças descontinuadas:" #: src/reuse/lint.py:173 msgid "Licenses without file extension:" msgstr "Licenças sem extensão de ficheiro:" #: src/reuse/lint.py:176 msgid "Missing licenses:" msgstr "Licenças em falta:" #: src/reuse/lint.py:177 msgid "Unused licenses:" msgstr "Licenças não usadas:" #: src/reuse/lint.py:178 msgid "Used licenses:" msgstr "Licenças usadas:" #: src/reuse/lint.py:179 #, fuzzy msgid "Read errors:" msgstr "Erros de leitura: {count}" #: src/reuse/lint.py:181 #, fuzzy msgid "Files with copyright information:" msgstr "Ficheiros com informação de direitos de autor: {count} / {total}" #: src/reuse/lint.py:185 #, fuzzy msgid "Files with license information:" msgstr "Ficheiros com informação de licenciamento: {count} / {total}" #: src/reuse/lint.py:202 msgid "" "Congratulations! Your project is compliant with version {} of the REUSE " "Specification :-)" msgstr "" "Parabéns! O projecto está conforme com a versão {} da especificação REUSE :-)" #: src/reuse/lint.py:209 msgid "" "Unfortunately, your project is not compliant with version {} of the REUSE " "Specification :-(" msgstr "" "Infelizmente, o projecto não está conforme com a versão {} da especificação " "REUSE :-(" #: src/reuse/lint.py:216 msgid "RECOMMENDATIONS" msgstr "" #: src/reuse/lint.py:289 #, python-brace-format msgid "{path}: bad license {lic}\n" msgstr "" #: src/reuse/lint.py:296 #, fuzzy, python-brace-format msgid "{lic_path}: deprecated license\n" msgstr "Licenças descontinuadas:" #: src/reuse/lint.py:303 #, fuzzy, python-brace-format msgid "{lic_path}: license without file extension\n" msgstr "Licenças sem extensão de ficheiro:" #: src/reuse/lint.py:312 #, fuzzy, python-brace-format msgid "{lic_path}: unused license\n" msgstr "Licenças não usadas:" #: src/reuse/lint.py:319 #, python-brace-format msgid "{path}: missing license {lic}\n" msgstr "" #: src/reuse/lint.py:326 #, python-brace-format msgid "{path}: read error\n" msgstr "" #: src/reuse/lint.py:330 #, fuzzy, python-brace-format msgid "{path}: no license identifier\n" msgstr "'{}' não é um Identificador de Licença SPDX válido." #: src/reuse/lint.py:334 #, python-brace-format msgid "{path}: no copyright notice\n" msgstr "" #: src/reuse/project.py:262 #, fuzzy, python-brace-format msgid "'{path}' covered by {global_path}" msgstr "'{path}' abrangido por .reuse/dep5" #: src/reuse/project.py:270 #, python-brace-format msgid "" "'{path}' is covered exclusively by REUSE.toml. Not reading the file contents." msgstr "" #: src/reuse/project.py:277 #, python-brace-format msgid "" "'{path}' was detected as a binary file; not searching its contents for REUSE " "information." msgstr "" #: src/reuse/project.py:334 msgid "" "'.reuse/dep5' is deprecated. You are recommended to instead use REUSE.toml. " "Use `reuse convert-dep5` to convert." msgstr "" #: src/reuse/project.py:348 #, python-brace-format msgid "" "Found both '{new_path}' and '{old_path}'. You cannot keep both files " "simultaneously; they are not intercompatible." msgstr "" #: src/reuse/project.py:414 #, python-brace-format msgid "determining identifier of '{path}'" msgstr "a determinar o identificador de '{path}'" #: src/reuse/project.py:422 #, python-brace-format msgid "{path} does not have a file extension" msgstr "{path} não tem extensão de ficheiro" #: src/reuse/project.py:432 #, python-brace-format msgid "" "Could not resolve SPDX License Identifier of {path}, resolving to " "{identifier}. Make sure the license is in the license list found at or that it starts with 'LicenseRef-', and that it has a " "file extension." msgstr "" "Não foi possível determinar o Identificador de Licença SPDX de {path}; a " "determinar como {identifier}. Confirmar que a licença está na lista " "publicada em ou que começa por 'LicenseRef-' e " "tem uma extensão de ficheiro." #: src/reuse/project.py:444 #, python-brace-format msgid "" "{identifier} is the SPDX License Identifier of both {path} and {other_path}" msgstr "" "{identifier} é o Identificador de Licença SPDX de {path} e {other_path}" #: src/reuse/project.py:483 msgid "" "project '{}' is not a VCS repository or required VCS software is not " "installed" msgstr "" #: src/reuse/report.py:310 #, python-brace-format msgid "Could not read '{path}'" msgstr "Não foi possível ler '{path}'" #: src/reuse/report.py:317 #, python-brace-format msgid "Unexpected error occurred while parsing '{path}'" msgstr "Ocorreu um erro inesperado ao analisar (parse) '{path}'" #: src/reuse/report.py:438 msgid "" "Fix bad licenses: At least one license in the LICENSES directory and/or " "provided by 'SPDX-License-Identifier' tags is invalid. They are either not " "valid SPDX License Identifiers or do not start with 'LicenseRef-'. FAQ about " "custom licenses: https://reuse.software/faq/#custom-license" msgstr "" #: src/reuse/report.py:449 msgid "" "Fix deprecated licenses: At least one of the licenses in the LICENSES " "directory and/or provided by an 'SPDX-License-Identifier' tag or in '.reuse/" "dep5' has been deprecated by SPDX. The current list and their respective " "recommended new identifiers can be found here: " msgstr "" #: src/reuse/report.py:460 msgid "" "Fix licenses without file extension: At least one license text file in the " "'LICENSES' directory does not have a '.txt' file extension. Please rename " "the file(s) accordingly." msgstr "" #: src/reuse/report.py:469 msgid "" "Fix missing licenses: For at least one of the license identifiers provided " "by the 'SPDX-License-Identifier' tags, there is no corresponding license " "text file in the 'LICENSES' directory. For SPDX license identifiers, you can " "simply run 'reuse download --all' to get any missing ones. For custom " "licenses (starting with 'LicenseRef-'), you need to add these files yourself." msgstr "" #: src/reuse/report.py:481 msgid "" "Fix unused licenses: At least one of the license text files in 'LICENSES' is " "not referenced by any file, e.g. by an 'SPDX-License-Identifier' tag. Please " "make sure that you either tag the accordingly licensed files properly, or " "delete the unused license text if you are sure that no file or code snippet " "is licensed as such." msgstr "" #: src/reuse/report.py:492 msgid "" "Fix read errors: At least one of the files in your directory cannot be read " "by the tool. Please check the file permissions. You will find the affected " "files at the top of the output as part of the logged error messages." msgstr "" #: src/reuse/report.py:501 msgid "" "Fix missing copyright/licensing information: For one or more files, the tool " "cannot find copyright and/or licensing information. You typically do this by " "adding 'SPDX-FileCopyrightText' and 'SPDX-License-Identifier' tags to each " "file. The tutorial explains additional ways to do this: " msgstr "" #: src/reuse/spdx.py:32 msgid "" "populate the LicenseConcluded field; note that reuse cannot guarantee the " "field is accurate" msgstr "" #: src/reuse/spdx.py:39 msgid "name of the person signing off on the SPDX report" msgstr "" #: src/reuse/spdx.py:44 msgid "name of the organization signing off on the SPDX report" msgstr "" #: src/reuse/spdx.py:60 msgid "" "error: --creator-person=NAME or --creator-organization=NAME required when --" "add-license-concluded is provided" msgstr "" #: src/reuse/spdx.py:75 #, python-brace-format msgid "" "'{path}' does not match a common SPDX file pattern. Find the suggested " "naming conventions here: https://spdx.github.io/spdx-spec/conformance/#44-" "standard-data-format-requirements" msgstr "" #: /usr/lib/python3.10/argparse.py:308 msgid "usage: " msgstr "uso: " #: /usr/lib/python3.10/argparse.py:880 msgid ".__call__() not defined" msgstr ".__call__() não definido" #: /usr/lib/python3.10/argparse.py:1223 #, python-format msgid "unknown parser %(parser_name)r (choices: %(choices)s)" msgstr "analisador desconhecido %(parser_name)r (alternativas: %(choices)s)" #: /usr/lib/python3.10/argparse.py:1283 #, python-format msgid "argument \"-\" with mode %r" msgstr "argumento \"-\" com modo %r" #: /usr/lib/python3.10/argparse.py:1292 #, python-format msgid "can't open '%(filename)s': %(error)s" msgstr "não é possível abrir '%(filename)s': %(error)s" #: /usr/lib/python3.10/argparse.py:1501 #, python-format msgid "cannot merge actions - two groups are named %r" msgstr "não é possível combinar as acções - há dois grupos com o nome %r" #: /usr/lib/python3.10/argparse.py:1539 msgid "'required' is an invalid argument for positionals" msgstr "'required' não é um argumento válido para posicionais" #: /usr/lib/python3.10/argparse.py:1561 #, python-format msgid "" "invalid option string %(option)r: must start with a character " "%(prefix_chars)r" msgstr "" "linha de opções %(option)r inválida: tem que começar com um carácter " "%(prefix_chars)r" #: /usr/lib/python3.10/argparse.py:1579 #, python-format msgid "dest= is required for options like %r" msgstr "é requerido dest= para opções do tipo %r" #: /usr/lib/python3.10/argparse.py:1596 #, python-format msgid "invalid conflict_resolution value: %r" msgstr "valor de conflict_resolution inválido: %r" #: /usr/lib/python3.10/argparse.py:1614 #, python-format msgid "conflicting option string: %s" msgid_plural "conflicting option strings: %s" msgstr[0] "linha de opções conflituante: %s" msgstr[1] "linhas de opções conflituantes: %s" #: /usr/lib/python3.10/argparse.py:1680 msgid "mutually exclusive arguments must be optional" msgstr "argumentos mutuamente exclusivos têm que ser opcionais" #: /usr/lib/python3.10/argparse.py:1748 msgid "positional arguments" msgstr "argumentos posicionais" #: /usr/lib/python3.10/argparse.py:1749 msgid "options" msgstr "" #: /usr/lib/python3.10/argparse.py:1764 msgid "show this help message and exit" msgstr "mostrar esta mensagem de ajuda e sair" #: /usr/lib/python3.10/argparse.py:1795 msgid "cannot have multiple subparser arguments" msgstr "não pode haver argumentos múltiplos de sub-análise (subparser)" #: /usr/lib/python3.10/argparse.py:1847 /usr/lib/python3.10/argparse.py:2362 #, python-format msgid "unrecognized arguments: %s" msgstr "argumentos não reconhecidos: %s" #: /usr/lib/python3.10/argparse.py:1948 #, python-format msgid "not allowed with argument %s" msgstr "não permitido com o argumento %s" #: /usr/lib/python3.10/argparse.py:1998 /usr/lib/python3.10/argparse.py:2012 #, python-format msgid "ignored explicit argument %r" msgstr "argumento explícito %r ignorado" #: /usr/lib/python3.10/argparse.py:2119 #, python-format msgid "the following arguments are required: %s" msgstr "são requeridos os seguintes argumentos: %s" #: /usr/lib/python3.10/argparse.py:2134 #, python-format msgid "one of the arguments %s is required" msgstr "é requerido um dos argumentos %s" #: /usr/lib/python3.10/argparse.py:2177 msgid "expected one argument" msgstr "é esperado um argumento" #: /usr/lib/python3.10/argparse.py:2178 msgid "expected at most one argument" msgstr "é esperado um argumento, no máximo" #: /usr/lib/python3.10/argparse.py:2179 msgid "expected at least one argument" msgstr "é esperado um argumento, no mínimo" #: /usr/lib/python3.10/argparse.py:2183 #, python-format msgid "expected %s argument" msgid_plural "expected %s arguments" msgstr[0] "é esperado %s argumento" msgstr[1] "são esperados %s argumentos" #: /usr/lib/python3.10/argparse.py:2241 #, python-format msgid "ambiguous option: %(option)s could match %(matches)s" msgstr "opção ambígua: %(option)s pode ser igual a %(matches)s" #: /usr/lib/python3.10/argparse.py:2305 #, python-format msgid "unexpected option string: %s" msgstr "linha de opções não esperada: %s" #: /usr/lib/python3.10/argparse.py:2502 #, python-format msgid "%r is not callable" msgstr "%r não é invocável" #: /usr/lib/python3.10/argparse.py:2519 #, python-format msgid "invalid %(type)s value: %(value)r" msgstr "valor %(type)s inválido: %(value)r" #: /usr/lib/python3.10/argparse.py:2530 #, python-format msgid "invalid choice: %(value)r (choose from %(choices)s)" msgstr "alternativa inválida: %(value)r (escolher de %(choices)s)" #: /usr/lib/python3.10/argparse.py:2606 #, python-format msgid "%(prog)s: error: %(message)s\n" msgstr "%(prog)s: erro: %(message)s\n" #~ msgid "initialize REUSE project" #~ msgstr "iniciar um projecto REUSE" #, fuzzy #~ msgid "" #~ "What license is your project under? Provide the SPDX License Identifier. " #~ "See for the list." #~ msgstr "" #~ "Sob que licença está o projecto? Indicar o Identificador de Licença SPDX." #~ msgid "" #~ "What other license is your project under? Provide the SPDX License " #~ "Identifier." #~ msgstr "" #~ "Sob que outra licença está o projecto? Indicar o Identificador de Licença " #~ "SPDX." #~ msgid "To stop adding licenses, hit RETURN." #~ msgstr "Para parar a agregação de licenças, premir INTRODUZIR/ENTER." #~ msgid "Project already initialized" #~ msgstr "Projecto já iniciado" #~ msgid "Initializing project for REUSE." #~ msgstr "A iniciar o projecto para REUSE." #~ msgid "What is the name of the project?" #~ msgstr "Qual é o nome do projecto?" #~ msgid "What is the internet address of the project?" #~ msgstr "Qual é o endereço do projecto na internet?" #~ msgid "What is the name of the maintainer?" #~ msgstr "Qual é o nome do responsável (maintainer)?" #~ msgid "What is the e-mail address of the maintainer?" #~ msgstr "Qual é o endereço electrónico do responsável?" #~ msgid "All done! Initializing now." #~ msgstr "Pronto! A iniciar." #~ msgid "{} already exists" #~ msgstr "{} já existe" #~ msgid "Could not download {}" #~ msgstr "Não foi possível descarregar {}" #~ msgid "Initialization complete." #~ msgstr "Iniciação completada." #, fuzzy #~ msgid "" #~ "Add copyright and licensing into the header of one or more files.\n" #~ "\n" #~ "By using --copyright and --license, you can specify which copyright " #~ "holders and licenses to add to the headers of the given files.\n" #~ "\n" #~ "By using --contributor, you can specify people or entity that contributed " #~ "but are not copyright holder of the given files.\n" #~ "The first comment is replaced with a new header containing the new " #~ "copyright and licensing information and its former copyright and " #~ "licensing. If you want to keep the first comment intact, use --no-" #~ "replace.\n" #~ "\n" #~ "The comment style should be auto-detected for your files. If a comment " #~ "style could not be detected and --skip-unrecognised is not specified, the " #~ "process aborts. Use --style to specify or override the comment style to " #~ "use.\n" #~ "\n" #~ "A single-line comment style is used when it is available. If no single-" #~ "line comment style is available, a multi-line comment style is used. You " #~ "can force a certain comment style using --single-line or --multi-line.\n" #~ "\n" #~ "You can change the template of the header comment by using --template. " #~ "Place a Jinja2 template in .reuse/templates/mytemplate.jinja2. You can " #~ "use the template by specifying '--template mytemplate'. Read the online " #~ "documentation on how to use this feature.\n" #~ "\n" #~ "If a binary file is detected, or if --force-dot-license is specified, the " #~ "header is placed in a .license file." #~ msgstr "" #~ "Adicionar direitos de autor e licenciamento ao cabeçalho de um ou mais " #~ "ficheiros.\n" #~ "\n" #~ "Usando --copyright e --license, pode-se especificar que detentores de " #~ "direitos de autor e que licenças adicionar aos cabeçalhos dos ficheiros " #~ "em causa.\n" #~ "\n" #~ "O estilo dos comentários deve ser detectado automaticamente nos " #~ "ficheiros. Se não for detectado nenhum estilo de comentários, o processo " #~ "é abortado. Usar --style para especificar ou sobre-escrever o estilo de " #~ "comentários a usar.\n" #~ "\n" #~ "É possível mudar o modelo de comentários de cabeçalho usando --template. " #~ "Colocarum modelo Jinja2 na pasta .reuse/templates/mytemplate.jinja2. Este " #~ "modelo pode ser usado indicando '--template mytemplate'. Consultar a " #~ "documentação em linha para informação adicional sobre esta " #~ "funcionalidade.\n" #~ "\n" #~ "Se for detectado um ficheiro binário ou se for especificado --explicit-" #~ "license, o cabeçalho é colocado num ficheiro .license\n" #~ "\n" #~ "IMPORTANTE: Presentemente esta funcionalidade é EXPERIMENTAL!" #~ msgid "" #~ "Download a license and place it in the LICENSES/ directory.\n" #~ "\n" #~ "The LICENSES/ directory is automatically found in the following order:\n" #~ "\n" #~ "- The LICENSES/ directory in the root of the VCS repository.\n" #~ "\n" #~ "- The current directory if its name is LICENSES.\n" #~ "\n" #~ "- The LICENSES/ directory in the current directory.\n" #~ "\n" #~ "If the LICENSES/ directory cannot be found, one is simply created." #~ msgstr "" #~ "Descarregar uma licença e guardá-la na pasta LICENSES/.\n" #~ "\n" #~ "A pasta LICENSES/ é procurada automaticamente por esta ordem:\n" #~ "\n" #~ "- Pasta LICENSES/ na raíz do repositório VCS.\n" #~ "\n" #~ "- Pasta actual se o nome for LICENSES.\n" #~ "\n" #~ "- Pasta LICENSES/ na pasta actual.\n" #~ "\n" #~ "Se não for encontrada, a pasta LICENSES/ será criada." #~ msgid ".reuse/dep5 has syntax errors" #~ msgstr ".reuse/dep5 tem erros de sintaxe" #~ msgid "optional arguments" #~ msgstr "argumentos opcionais" #~ msgid "option --exclude-year and --year are mutually exclusive" #~ msgstr "as opções --exclude-year e --year são mutuamente exclusivas" #, fuzzy #~ msgid "option --single-line and --multi-line are mutually exclusive" #~ msgstr "as opções --exclude-year e --year são mutuamente exclusivas" #~ msgid "Downloading {}" #~ msgstr "A descarregar {}" #, fuzzy #~ msgid "conflicting subparser: %s" #~ msgstr "linha de opções conflituante: %s" #, fuzzy #~ msgid "conflicting subparser alias: %s" #~ msgstr "linha de opções conflituante: %s" #~ msgid "can't open '%s': %s" #~ msgstr "não é possível abrir '%s': %s" #~ msgid "place header in path.license instead of path" #~ msgstr "colocar o cabeçalho em path.license em vez de em path" #~ msgid "could not find Git" #~ msgstr "não foi encontrado o Git" reuse-tool-4.0.3/po/reuse.pot000066400000000000000000000540441464275211500161170ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" "#-#-#-#-# reuse.pot (PACKAGE VERSION) #-#-#-#-#\n" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-07-03 13:09+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" "#-#-#-#-# argparse.pot (PACKAGE VERSION) #-#-#-#-#\n" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-07-03 13:09+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" #: src/reuse/_annotate.py:74 #, python-brace-format msgid "" "'{path}' does not support single-line comments, please do not use --single-" "line" msgstr "" #: src/reuse/_annotate.py:81 #, python-brace-format msgid "" "'{path}' does not support multi-line comments, please do not use --multi-line" msgstr "" #: src/reuse/_annotate.py:136 #, python-brace-format msgid "Skipped unrecognised file '{path}'" msgstr "" #: src/reuse/_annotate.py:142 #, python-brace-format msgid "'{path}' is not recognised; creating '{path}.license'" msgstr "" #: src/reuse/_annotate.py:158 #, python-brace-format msgid "Skipped file '{path}' already containing REUSE information" msgstr "" #: src/reuse/_annotate.py:192 #, python-brace-format msgid "Error: Could not create comment for '{path}'" msgstr "" #: src/reuse/_annotate.py:199 #, python-brace-format msgid "" "Error: Generated comment header for '{path}' is missing copyright lines or " "license expressions. The template is probably incorrect. Did not write new " "header." msgstr "" #. TODO: This may need to be rephrased more elegantly. #: src/reuse/_annotate.py:210 #, python-brace-format msgid "Successfully changed header of {path}" msgstr "" #: src/reuse/_annotate.py:221 msgid "--skip-unrecognised has no effect when used together with --style" msgstr "" #: src/reuse/_annotate.py:231 msgid "option --contributor, --copyright or --license is required" msgstr "" #: src/reuse/_annotate.py:272 #, python-brace-format msgid "template {template} could not be found" msgstr "" #: src/reuse/_annotate.py:341 src/reuse/_util.py:573 msgid "can't write to '{}'" msgstr "" #: src/reuse/_annotate.py:366 msgid "" "The following files do not have a recognised file extension. Please use --" "style, --force-dot-license, --fallback-dot-license, or --skip-unrecognised:" msgstr "" #: src/reuse/_annotate.py:382 msgid "copyright statement, repeatable" msgstr "" #: src/reuse/_annotate.py:389 msgid "SPDX Identifier, repeatable" msgstr "" #: src/reuse/_annotate.py:395 msgid "file contributor, repeatable" msgstr "" #: src/reuse/_annotate.py:403 msgid "year of copyright statement, optional" msgstr "" #: src/reuse/_annotate.py:411 msgid "comment style to use, optional" msgstr "" #: src/reuse/_annotate.py:417 msgid "copyright prefix to use, optional" msgstr "" #: src/reuse/_annotate.py:430 msgid "name of template to use, optional" msgstr "" #: src/reuse/_annotate.py:435 msgid "do not include year in statement" msgstr "" #: src/reuse/_annotate.py:440 msgid "merge copyright lines if copyright statements are identical" msgstr "" #: src/reuse/_annotate.py:446 msgid "force single-line comment style, optional" msgstr "" #: src/reuse/_annotate.py:451 msgid "force multi-line comment style, optional" msgstr "" #: src/reuse/_annotate.py:458 msgid "add headers to all files under specified directories recursively" msgstr "" #: src/reuse/_annotate.py:465 msgid "do not replace the first header in the file; just add a new one" msgstr "" #: src/reuse/_annotate.py:473 msgid "always write a .license file instead of a header inside the file" msgstr "" #: src/reuse/_annotate.py:480 msgid "write a .license file to files with unrecognised comment styles" msgstr "" #: src/reuse/_annotate.py:486 msgid "skip files with unrecognised comment styles" msgstr "" #: src/reuse/_annotate.py:497 msgid "skip files that already contain REUSE information" msgstr "" #: src/reuse/_annotate.py:532 #, python-brace-format msgid "'{path}' is a binary, therefore using '{new_path}' for the header" msgstr "" #: src/reuse/_main.py:39 msgid "" "reuse is a tool for compliance with the REUSE recommendations. See for more information, and " "for the online documentation." msgstr "" #: src/reuse/_main.py:45 msgid "" "This version of reuse is compatible with version {} of the REUSE " "Specification." msgstr "" #: src/reuse/_main.py:48 msgid "Support the FSFE's work:" msgstr "" #: src/reuse/_main.py:52 msgid "" "Donations are critical to our strength and autonomy. They enable us to " "continue working for Free Software wherever necessary. Please consider " "making a donation at ." msgstr "" #: src/reuse/_main.py:75 msgid "enable debug statements" msgstr "" #: src/reuse/_main.py:80 msgid "hide deprecation warnings" msgstr "" #: src/reuse/_main.py:85 msgid "do not skip over Git submodules" msgstr "" #: src/reuse/_main.py:90 msgid "do not skip over Meson subprojects" msgstr "" #: src/reuse/_main.py:95 msgid "do not use multiprocessing" msgstr "" #: src/reuse/_main.py:102 msgid "define root of project" msgstr "" #: src/reuse/_main.py:107 msgid "show program's version number and exit" msgstr "" #: src/reuse/_main.py:111 msgid "subcommands" msgstr "" #: src/reuse/_main.py:118 msgid "add copyright and licensing into the header of files" msgstr "" #: src/reuse/_main.py:121 msgid "" "Add copyright and licensing into the header of one or more files.\n" "\n" "By using --copyright and --license, you can specify which copyright holders " "and licenses to add to the headers of the given files.\n" "\n" "By using --contributor, you can specify people or entity that contributed " "but are not copyright holder of the given files." msgstr "" #: src/reuse/_main.py:140 msgid "download a license and place it in the LICENSES/ directory" msgstr "" #: src/reuse/_main.py:142 msgid "Download a license and place it in the LICENSES/ directory." msgstr "" #: src/reuse/_main.py:151 msgid "list all non-compliant files" msgstr "" #: src/reuse/_main.py:154 #, python-brace-format msgid "" "Lint the project directory for compliance with version {reuse_version} of " "the REUSE Specification. You can find the latest version of the " "specification at .\n" "\n" "Specifically, the following criteria are checked:\n" "\n" "- Are there any bad (unrecognised, not compliant with SPDX) licenses in the " "project?\n" "\n" "- Are any licenses referred to inside of the project, but not included in " "the LICENSES/ directory?\n" "\n" "- Are any licenses included in the LICENSES/ directory that are not used " "inside of the project?\n" "\n" "- Do all files have valid copyright and licensing information?" msgstr "" #: src/reuse/_main.py:181 msgid "print the project's bill of materials in SPDX format" msgstr "" #: src/reuse/_main.py:189 msgid "list all supported SPDX licenses" msgstr "" #: src/reuse/_main.py:198 msgid "convert .reuse/dep5 to REUSE.toml" msgstr "" #: src/reuse/_main.py:263 #, python-brace-format msgid "'{path}' could not be decoded as UTF-8." msgstr "" #: src/reuse/_main.py:269 #, python-brace-format msgid "" "'{path}' could not be parsed. We received the following error message: " "{message}" msgstr "" #: src/reuse/_util.py:368 src/reuse/global_licensing.py:218 #, python-brace-format msgid "Could not parse '{expression}'" msgstr "" #: src/reuse/_util.py:424 #, python-brace-format msgid "" "'{path}' holds an SPDX expression that cannot be parsed, skipping the file" msgstr "" #: src/reuse/_util.py:556 msgid "'{}' is not a file" msgstr "" #: src/reuse/_util.py:559 msgid "'{}' is not a directory" msgstr "" #: src/reuse/_util.py:562 msgid "can't open '{}'" msgstr "" #: src/reuse/_util.py:567 msgid "can't write to directory '{}'" msgstr "" #: src/reuse/_util.py:586 msgid "can't read or write '{}'" msgstr "" #: src/reuse/_util.py:596 msgid "'{}' is not a valid SPDX expression, aborting" msgstr "" #: src/reuse/_util.py:624 msgid "'{}' is not a valid SPDX License Identifier." msgstr "" #: src/reuse/_util.py:631 msgid "Did you mean:" msgstr "" #: src/reuse/_util.py:638 msgid "" "See for a list of valid SPDX License " "Identifiers." msgstr "" #: src/reuse/convert_dep5.py:118 msgid "no '.reuse/dep5' file" msgstr "" #: src/reuse/download.py:130 msgid "SPDX License Identifier of license" msgstr "" #: src/reuse/download.py:135 msgid "download all missing licenses detected in the project" msgstr "" #: src/reuse/download.py:145 msgid "" "source from which to copy custom LicenseRef- licenses, either a directory " "that contains the file or the file itself" msgstr "" #: src/reuse/download.py:156 #, python-brace-format msgid "Error: {spdx_identifier} already exists." msgstr "" #: src/reuse/download.py:163 #, python-brace-format msgid "Error: {path} does not exist." msgstr "" #: src/reuse/download.py:166 msgid "Error: Failed to download license." msgstr "" #: src/reuse/download.py:171 msgid "Is your internet connection working?" msgstr "" #: src/reuse/download.py:176 #, python-brace-format msgid "Successfully downloaded {spdx_identifier}." msgstr "" #: src/reuse/download.py:188 msgid "--output has no effect when used together with --all" msgstr "" #: src/reuse/download.py:192 msgid "the following arguments are required: license" msgstr "" #: src/reuse/download.py:194 msgid "cannot use --output with more than one license" msgstr "" #: src/reuse/global_licensing.py:109 #, python-brace-format msgid "" "{attr_name} must be a {type_name} (got {value} that is a {value_class})." msgstr "" #: src/reuse/global_licensing.py:122 #, python-brace-format msgid "" "Item in {attr_name} collection must be a {type_name} (got {item_value} that " "is a {item_class})." msgstr "" #: src/reuse/global_licensing.py:133 #, python-brace-format msgid "{attr_name} must not be empty." msgstr "" #: src/reuse/global_licensing.py:156 #, python-brace-format msgid "{name} must be a {type} (got {value} that is a {value_type})." msgstr "" #: src/reuse/global_licensing.py:179 #, python-brace-format msgid "" "The value of 'precedence' must be one of {precedence_vals} (got {received})" msgstr "" #: src/reuse/header.py:99 msgid "generated comment is missing copyright lines or license expressions" msgstr "" #: src/reuse/lint.py:30 msgid "prevents output" msgstr "" #: src/reuse/lint.py:33 msgid "formats output as JSON" msgstr "" #: src/reuse/lint.py:39 msgid "formats output as plain text" msgstr "" #: src/reuse/lint.py:45 msgid "formats output as errors per line" msgstr "" #: src/reuse/lint.py:64 msgid "BAD LICENSES" msgstr "" #: src/reuse/lint.py:66 src/reuse/lint.py:95 msgid "'{}' found in:" msgstr "" #: src/reuse/lint.py:73 msgid "DEPRECATED LICENSES" msgstr "" #: src/reuse/lint.py:75 msgid "The following licenses are deprecated by SPDX:" msgstr "" #: src/reuse/lint.py:83 msgid "LICENSES WITHOUT FILE EXTENSION" msgstr "" #: src/reuse/lint.py:85 msgid "The following licenses have no file extension:" msgstr "" #: src/reuse/lint.py:93 msgid "MISSING LICENSES" msgstr "" #: src/reuse/lint.py:102 msgid "UNUSED LICENSES" msgstr "" #: src/reuse/lint.py:103 msgid "The following licenses are not used:" msgstr "" #: src/reuse/lint.py:110 msgid "READ ERRORS" msgstr "" #: src/reuse/lint.py:111 msgid "Could not read:" msgstr "" #: src/reuse/lint.py:132 msgid "MISSING COPYRIGHT AND LICENSING INFORMATION" msgstr "" #: src/reuse/lint.py:138 msgid "The following files have no copyright and licensing information:" msgstr "" #: src/reuse/lint.py:149 msgid "The following files have no copyright information:" msgstr "" #: src/reuse/lint.py:158 msgid "The following files have no licensing information:" msgstr "" #: src/reuse/lint.py:166 msgid "SUMMARY" msgstr "" #: src/reuse/lint.py:171 msgid "Bad licenses:" msgstr "" #: src/reuse/lint.py:172 msgid "Deprecated licenses:" msgstr "" #: src/reuse/lint.py:173 msgid "Licenses without file extension:" msgstr "" #: src/reuse/lint.py:176 msgid "Missing licenses:" msgstr "" #: src/reuse/lint.py:177 msgid "Unused licenses:" msgstr "" #: src/reuse/lint.py:178 msgid "Used licenses:" msgstr "" #: src/reuse/lint.py:179 msgid "Read errors:" msgstr "" #: src/reuse/lint.py:181 msgid "Files with copyright information:" msgstr "" #: src/reuse/lint.py:185 msgid "Files with license information:" msgstr "" #: src/reuse/lint.py:202 msgid "" "Congratulations! Your project is compliant with version {} of the REUSE " "Specification :-)" msgstr "" #: src/reuse/lint.py:209 msgid "" "Unfortunately, your project is not compliant with version {} of the REUSE " "Specification :-(" msgstr "" #: src/reuse/lint.py:216 msgid "RECOMMENDATIONS" msgstr "" #: src/reuse/lint.py:289 #, python-brace-format msgid "{path}: bad license {lic}\n" msgstr "" #: src/reuse/lint.py:296 #, python-brace-format msgid "{lic_path}: deprecated license\n" msgstr "" #: src/reuse/lint.py:303 #, python-brace-format msgid "{lic_path}: license without file extension\n" msgstr "" #: src/reuse/lint.py:312 #, python-brace-format msgid "{lic_path}: unused license\n" msgstr "" #: src/reuse/lint.py:319 #, python-brace-format msgid "{path}: missing license {lic}\n" msgstr "" #: src/reuse/lint.py:326 #, python-brace-format msgid "{path}: read error\n" msgstr "" #: src/reuse/lint.py:330 #, python-brace-format msgid "{path}: no license identifier\n" msgstr "" #: src/reuse/lint.py:334 #, python-brace-format msgid "{path}: no copyright notice\n" msgstr "" #: src/reuse/project.py:262 #, python-brace-format msgid "'{path}' covered by {global_path}" msgstr "" #: src/reuse/project.py:270 #, python-brace-format msgid "" "'{path}' is covered exclusively by REUSE.toml. Not reading the file contents." msgstr "" #: src/reuse/project.py:277 #, python-brace-format msgid "" "'{path}' was detected as a binary file; not searching its contents for REUSE " "information." msgstr "" #: src/reuse/project.py:334 msgid "" "'.reuse/dep5' is deprecated. You are recommended to instead use REUSE.toml. " "Use `reuse convert-dep5` to convert." msgstr "" #: src/reuse/project.py:348 #, python-brace-format msgid "" "Found both '{new_path}' and '{old_path}'. You cannot keep both files " "simultaneously; they are not intercompatible." msgstr "" #: src/reuse/project.py:414 #, python-brace-format msgid "determining identifier of '{path}'" msgstr "" #: src/reuse/project.py:422 #, python-brace-format msgid "{path} does not have a file extension" msgstr "" #: src/reuse/project.py:432 #, python-brace-format msgid "" "Could not resolve SPDX License Identifier of {path}, resolving to " "{identifier}. Make sure the license is in the license list found at or that it starts with 'LicenseRef-', and that it has a " "file extension." msgstr "" #: src/reuse/project.py:444 #, python-brace-format msgid "" "{identifier} is the SPDX License Identifier of both {path} and {other_path}" msgstr "" #: src/reuse/project.py:483 msgid "" "project '{}' is not a VCS repository or required VCS software is not " "installed" msgstr "" #: src/reuse/report.py:310 #, python-brace-format msgid "Could not read '{path}'" msgstr "" #: src/reuse/report.py:317 #, python-brace-format msgid "Unexpected error occurred while parsing '{path}'" msgstr "" #: src/reuse/report.py:438 msgid "" "Fix bad licenses: At least one license in the LICENSES directory and/or " "provided by 'SPDX-License-Identifier' tags is invalid. They are either not " "valid SPDX License Identifiers or do not start with 'LicenseRef-'. FAQ about " "custom licenses: https://reuse.software/faq/#custom-license" msgstr "" #: src/reuse/report.py:449 msgid "" "Fix deprecated licenses: At least one of the licenses in the LICENSES " "directory and/or provided by an 'SPDX-License-Identifier' tag or in '.reuse/" "dep5' has been deprecated by SPDX. The current list and their respective " "recommended new identifiers can be found here: " msgstr "" #: src/reuse/report.py:460 msgid "" "Fix licenses without file extension: At least one license text file in the " "'LICENSES' directory does not have a '.txt' file extension. Please rename " "the file(s) accordingly." msgstr "" #: src/reuse/report.py:469 msgid "" "Fix missing licenses: For at least one of the license identifiers provided " "by the 'SPDX-License-Identifier' tags, there is no corresponding license " "text file in the 'LICENSES' directory. For SPDX license identifiers, you can " "simply run 'reuse download --all' to get any missing ones. For custom " "licenses (starting with 'LicenseRef-'), you need to add these files yourself." msgstr "" #: src/reuse/report.py:481 msgid "" "Fix unused licenses: At least one of the license text files in 'LICENSES' is " "not referenced by any file, e.g. by an 'SPDX-License-Identifier' tag. Please " "make sure that you either tag the accordingly licensed files properly, or " "delete the unused license text if you are sure that no file or code snippet " "is licensed as such." msgstr "" #: src/reuse/report.py:492 msgid "" "Fix read errors: At least one of the files in your directory cannot be read " "by the tool. Please check the file permissions. You will find the affected " "files at the top of the output as part of the logged error messages." msgstr "" #: src/reuse/report.py:501 msgid "" "Fix missing copyright/licensing information: For one or more files, the tool " "cannot find copyright and/or licensing information. You typically do this by " "adding 'SPDX-FileCopyrightText' and 'SPDX-License-Identifier' tags to each " "file. The tutorial explains additional ways to do this: " msgstr "" #: src/reuse/spdx.py:32 msgid "" "populate the LicenseConcluded field; note that reuse cannot guarantee the " "field is accurate" msgstr "" #: src/reuse/spdx.py:39 msgid "name of the person signing off on the SPDX report" msgstr "" #: src/reuse/spdx.py:44 msgid "name of the organization signing off on the SPDX report" msgstr "" #: src/reuse/spdx.py:60 msgid "" "error: --creator-person=NAME or --creator-organization=NAME required when --" "add-license-concluded is provided" msgstr "" #: src/reuse/spdx.py:75 #, python-brace-format msgid "" "'{path}' does not match a common SPDX file pattern. Find the suggested " "naming conventions here: https://spdx.github.io/spdx-spec/conformance/#44-" "standard-data-format-requirements" msgstr "" #: /usr/lib/python3.10/argparse.py:308 msgid "usage: " msgstr "" #: /usr/lib/python3.10/argparse.py:880 msgid ".__call__() not defined" msgstr "" #: /usr/lib/python3.10/argparse.py:1223 #, python-format msgid "unknown parser %(parser_name)r (choices: %(choices)s)" msgstr "" #: /usr/lib/python3.10/argparse.py:1283 #, python-format msgid "argument \"-\" with mode %r" msgstr "" #: /usr/lib/python3.10/argparse.py:1292 #, python-format msgid "can't open '%(filename)s': %(error)s" msgstr "" #: /usr/lib/python3.10/argparse.py:1501 #, python-format msgid "cannot merge actions - two groups are named %r" msgstr "" #: /usr/lib/python3.10/argparse.py:1539 msgid "'required' is an invalid argument for positionals" msgstr "" #: /usr/lib/python3.10/argparse.py:1561 #, python-format msgid "" "invalid option string %(option)r: must start with a character " "%(prefix_chars)r" msgstr "" #: /usr/lib/python3.10/argparse.py:1579 #, python-format msgid "dest= is required for options like %r" msgstr "" #: /usr/lib/python3.10/argparse.py:1596 #, python-format msgid "invalid conflict_resolution value: %r" msgstr "" #: /usr/lib/python3.10/argparse.py:1614 #, python-format msgid "conflicting option string: %s" msgid_plural "conflicting option strings: %s" msgstr[0] "" msgstr[1] "" #: /usr/lib/python3.10/argparse.py:1680 msgid "mutually exclusive arguments must be optional" msgstr "" #: /usr/lib/python3.10/argparse.py:1748 msgid "positional arguments" msgstr "" #: /usr/lib/python3.10/argparse.py:1749 msgid "options" msgstr "" #: /usr/lib/python3.10/argparse.py:1764 msgid "show this help message and exit" msgstr "" #: /usr/lib/python3.10/argparse.py:1795 msgid "cannot have multiple subparser arguments" msgstr "" #: /usr/lib/python3.10/argparse.py:1847 /usr/lib/python3.10/argparse.py:2362 #, python-format msgid "unrecognized arguments: %s" msgstr "" #: /usr/lib/python3.10/argparse.py:1948 #, python-format msgid "not allowed with argument %s" msgstr "" #: /usr/lib/python3.10/argparse.py:1998 /usr/lib/python3.10/argparse.py:2012 #, python-format msgid "ignored explicit argument %r" msgstr "" #: /usr/lib/python3.10/argparse.py:2119 #, python-format msgid "the following arguments are required: %s" msgstr "" #: /usr/lib/python3.10/argparse.py:2134 #, python-format msgid "one of the arguments %s is required" msgstr "" #: /usr/lib/python3.10/argparse.py:2177 msgid "expected one argument" msgstr "" #: /usr/lib/python3.10/argparse.py:2178 msgid "expected at most one argument" msgstr "" #: /usr/lib/python3.10/argparse.py:2179 msgid "expected at least one argument" msgstr "" #: /usr/lib/python3.10/argparse.py:2183 #, python-format msgid "expected %s argument" msgid_plural "expected %s arguments" msgstr[0] "" msgstr[1] "" #: /usr/lib/python3.10/argparse.py:2241 #, python-format msgid "ambiguous option: %(option)s could match %(matches)s" msgstr "" #: /usr/lib/python3.10/argparse.py:2305 #, python-format msgid "unexpected option string: %s" msgstr "" #: /usr/lib/python3.10/argparse.py:2502 #, python-format msgid "%r is not callable" msgstr "" #: /usr/lib/python3.10/argparse.py:2519 #, python-format msgid "invalid %(type)s value: %(value)r" msgstr "" #: /usr/lib/python3.10/argparse.py:2530 #, python-format msgid "invalid choice: %(value)r (choose from %(choices)s)" msgstr "" #: /usr/lib/python3.10/argparse.py:2606 #, python-format msgid "%(prog)s: error: %(message)s\n" msgstr "" reuse-tool-4.0.3/po/reuse.pot.license000066400000000000000000000001541464275211500175310ustar00rootroot00000000000000SPDX-FileCopyrightText: 2023 Carmen Bianca BAKKER SPDX-License-Identifier: CC0-1.0 reuse-tool-4.0.3/po/ru.po000066400000000000000000001313111464275211500152270ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-07-03 13:09+0000\n" "PO-Revision-Date: 2024-05-25 05:09+0000\n" "Last-Translator: gfbdrgng \n" "Language-Team: Russian \n" "Language: ru\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && " "n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" "X-Generator: Weblate 5.6-dev\n" #: src/reuse/_annotate.py:74 #, python-brace-format msgid "" "'{path}' does not support single-line comments, please do not use --single-" "line" msgstr "" "'{path}' не поддерживает однострочные комментарии, пожалуйста, не " "используйте --single-line" #: src/reuse/_annotate.py:81 #, python-brace-format msgid "" "'{path}' does not support multi-line comments, please do not use --multi-line" msgstr "" "'{path}' не поддерживает многострочные комментарии, пожалуйста, не " "используйте --multi-line" #: src/reuse/_annotate.py:136 #, python-brace-format msgid "Skipped unrecognised file '{path}'" msgstr "Пропущен нераспознанный файл '{path}'" #: src/reuse/_annotate.py:142 #, python-brace-format msgid "'{path}' is not recognised; creating '{path}.license'" msgstr "'{path}' не распознан; создаем '{path}. лицензия'" #: src/reuse/_annotate.py:158 #, python-brace-format msgid "Skipped file '{path}' already containing REUSE information" msgstr "Пропущенный файл '{path}' уже содержит информацию о REUSE" #: src/reuse/_annotate.py:192 #, python-brace-format msgid "Error: Could not create comment for '{path}'" msgstr "Ошибка: Не удалось создать комментарий для '{path}'" #: src/reuse/_annotate.py:199 #, python-brace-format msgid "" "Error: Generated comment header for '{path}' is missing copyright lines or " "license expressions. The template is probably incorrect. Did not write new " "header." msgstr "" "Ошибка: В сгенерированном заголовке комментария для '{path}' отсутствуют " "строки копирайта или выражения лицензии. Вероятно, шаблон неверен. Не " "удалось написать новый заголовок." #. TODO: This may need to be rephrased more elegantly. #: src/reuse/_annotate.py:210 #, python-brace-format msgid "Successfully changed header of {path}" msgstr "Успешно изменен заголовок {path}" #: src/reuse/_annotate.py:221 msgid "--skip-unrecognised has no effect when used together with --style" msgstr "" "--skip-unrecognised не имеет эффекта, если используется вместе с --style" #: src/reuse/_annotate.py:231 msgid "option --contributor, --copyright or --license is required" msgstr "Требуется опция --создатель, - авторское право или --лицензия" #: src/reuse/_annotate.py:272 #, python-brace-format msgid "template {template} could not be found" msgstr "Шаблон {template} не найден" #: src/reuse/_annotate.py:341 src/reuse/_util.py:573 msgid "can't write to '{}'" msgstr "Невозможно записать в '{}'" #: src/reuse/_annotate.py:366 msgid "" "The following files do not have a recognised file extension. Please use --" "style, --force-dot-license, --fallback-dot-license, or --skip-unrecognised:" msgstr "" "Следующие файлы не имеют распознанного расширения. Пожалуйста, используйте --" "style, --force-dot-license, --fallback-dot-license или --skip-unrecognised:" #: src/reuse/_annotate.py:382 msgid "copyright statement, repeatable" msgstr "заявление об авторских правах, повторяемое" #: src/reuse/_annotate.py:389 msgid "SPDX Identifier, repeatable" msgstr "Идентификатор SPDX, повторяемый" #: src/reuse/_annotate.py:395 msgid "file contributor, repeatable" msgstr "вкладчик файлов, повторяемость" #: src/reuse/_annotate.py:403 msgid "year of copyright statement, optional" msgstr "год утверждения авторского права, необязательно" #: src/reuse/_annotate.py:411 msgid "comment style to use, optional" msgstr "стиль комментария, который следует использовать, необязательно" #: src/reuse/_annotate.py:417 #, fuzzy msgid "copyright prefix to use, optional" msgstr "стиль авторского права, который будет использоваться, необязательно" #: src/reuse/_annotate.py:430 msgid "name of template to use, optional" msgstr "имя шаблона, который будет использоваться, необязательно" #: src/reuse/_annotate.py:435 msgid "do not include year in statement" msgstr "не указывайте год в отчете" #: src/reuse/_annotate.py:440 msgid "merge copyright lines if copyright statements are identical" msgstr "" "объединить строки с авторскими правами, если заявления об авторских правах " "идентичны" #: src/reuse/_annotate.py:446 msgid "force single-line comment style, optional" msgstr "стиль однострочных комментариев, необязательно" #: src/reuse/_annotate.py:451 msgid "force multi-line comment style, optional" msgstr "установить стиль многострочного комментария, необязательно" #: src/reuse/_annotate.py:458 msgid "add headers to all files under specified directories recursively" msgstr "рекурсивно добавлять заголовки ко всем файлам в указанных каталогах" #: src/reuse/_annotate.py:465 msgid "do not replace the first header in the file; just add a new one" msgstr "не заменяйте первый заголовок в файле; просто добавьте новый" #: src/reuse/_annotate.py:473 msgid "always write a .license file instead of a header inside the file" msgstr "всегда записывайте файл .license вместо заголовка внутри файла" #: src/reuse/_annotate.py:480 msgid "write a .license file to files with unrecognised comment styles" msgstr "" "записывать файл .license в файлы с нераспознанными стилями комментариев" #: src/reuse/_annotate.py:486 msgid "skip files with unrecognised comment styles" msgstr "пропускать файлы с нераспознанными стилями комментариев" #: src/reuse/_annotate.py:497 msgid "skip files that already contain REUSE information" msgstr "пропускать файлы, которые уже содержат информацию о REUSE" #: src/reuse/_annotate.py:532 #, python-brace-format msgid "'{path}' is a binary, therefore using '{new_path}' for the header" msgstr "" "'{path}' - двоичный файл, поэтому для заголовка используется '{new_path}'" #: src/reuse/_main.py:39 msgid "" "reuse is a tool for compliance with the REUSE recommendations. See for more information, and " "for the online documentation." msgstr "" "reuse - это инструмент для соблюдения рекомендаций REUSE. Дополнительную " "информацию см. на сайте , а онлайн-документацию - " "на сайте ." #: src/reuse/_main.py:45 msgid "" "This version of reuse is compatible with version {} of the REUSE " "Specification." msgstr "" "Эта версия повторного использования совместима с версией {} спецификации " "REUSE." #: src/reuse/_main.py:48 msgid "Support the FSFE's work:" msgstr "Поддержите работу ФСПО:" #: src/reuse/_main.py:52 msgid "" "Donations are critical to our strength and autonomy. They enable us to " "continue working for Free Software wherever necessary. Please consider " "making a donation at ." msgstr "" "Пожертвования имеют решающее значение для нашей силы и самостоятельности. " "Они позволяют нам продолжать работать во имя свободного программного " "обеспечения везде, где это необходимо. Пожалуйста, рассмотрите возможность " "сделать пожертвование по адресу ." #: src/reuse/_main.py:75 msgid "enable debug statements" msgstr "включить отладочные операторы" #: src/reuse/_main.py:80 msgid "hide deprecation warnings" msgstr "скрыть предупреждения об устаревании" #: src/reuse/_main.py:85 msgid "do not skip over Git submodules" msgstr "не пропускайте подмодули Git" #: src/reuse/_main.py:90 msgid "do not skip over Meson subprojects" msgstr "не пропускайте мезонные подпроекты" #: src/reuse/_main.py:95 msgid "do not use multiprocessing" msgstr "не используйте многопроцессорную обработку" #: src/reuse/_main.py:102 msgid "define root of project" msgstr "определить корень проекта" #: src/reuse/_main.py:107 msgid "show program's version number and exit" msgstr "показать номер версии программы и выйти" #: src/reuse/_main.py:111 msgid "subcommands" msgstr "подкоманды" #: src/reuse/_main.py:118 msgid "add copyright and licensing into the header of files" msgstr "" "добавьте в заголовок файлов информацию об авторских правах и лицензировании" #: src/reuse/_main.py:121 msgid "" "Add copyright and licensing into the header of one or more files.\n" "\n" "By using --copyright and --license, you can specify which copyright holders " "and licenses to add to the headers of the given files.\n" "\n" "By using --contributor, you can specify people or entity that contributed " "but are not copyright holder of the given files." msgstr "" "Добавление авторских прав и лицензий в заголовок одного или нескольких " "файлов.\n" "\n" "Используя команды --copyright и --license, вы можете указать, какие " "авторские права и лицензии следует добавить в заголовки заданных файлов.\n" "\n" "Используя команду --contributor, вы можете указать людей или организации, " "которые внесли свой вклад, но не являются владельцами авторских прав на " "данные файлы." #: src/reuse/_main.py:140 msgid "download a license and place it in the LICENSES/ directory" msgstr "загрузите лицензию и поместите ее в каталог LICENSES/" #: src/reuse/_main.py:142 msgid "Download a license and place it in the LICENSES/ directory." msgstr "Загрузите лицензию и поместите ее в каталог LICENSES/." #: src/reuse/_main.py:151 msgid "list all non-compliant files" msgstr "список всех файлов, не соответствующих требованиям" #: src/reuse/_main.py:154 #, python-brace-format msgid "" "Lint the project directory for compliance with version {reuse_version} of " "the REUSE Specification. You can find the latest version of the " "specification at .\n" "\n" "Specifically, the following criteria are checked:\n" "\n" "- Are there any bad (unrecognised, not compliant with SPDX) licenses in the " "project?\n" "\n" "- Are any licenses referred to inside of the project, but not included in " "the LICENSES/ directory?\n" "\n" "- Are any licenses included in the LICENSES/ directory that are not used " "inside of the project?\n" "\n" "- Do all files have valid copyright and licensing information?" msgstr "" "Проверьте каталог проекта на соответствие версии {reuse_version} " "спецификации REUSE. Последнюю версию спецификации можно найти по адресу " ".\n" "\n" "В частности, проверяются следующие критерии:\n" "\n" "- Есть ли в проекте плохие (нераспознанные, не совместимые с SPDX) " "лицензии?\n" "\n" "- Есть ли лицензии, на которые ссылаются внутри проекта, но которые не " "включены в каталог LICENSES/?\n" "\n" "- Включены ли в каталог LICENSES/ какие-либо лицензии, которые не " "используются в проекте?\n" "\n" "- Все ли файлы содержат достоверную информацию об авторских правах и " "лицензировании?" #: src/reuse/_main.py:181 msgid "print the project's bill of materials in SPDX format" msgstr "распечатать ведомость материалов проекта в формате SPDX" #: src/reuse/_main.py:189 msgid "list all supported SPDX licenses" msgstr "список всех поддерживаемых лицензий SPDX" #: src/reuse/_main.py:198 msgid "convert .reuse/dep5 to REUSE.toml" msgstr "Преобразование .reuse/dep5 в REUSE.toml" #: src/reuse/_main.py:263 #, python-brace-format msgid "'{path}' could not be decoded as UTF-8." msgstr "'{path}' не может быть декодирован как UTF-8." #: src/reuse/_main.py:269 #, python-brace-format msgid "" "'{path}' could not be parsed. We received the following error message: " "{message}" msgstr "" "'{path}' не может быть разобран. Мы получили следующее сообщение об ошибке: " "{message}" #: src/reuse/_util.py:368 src/reuse/global_licensing.py:218 #, python-brace-format msgid "Could not parse '{expression}'" msgstr "Не удалось разобрать '{expression}'" #: src/reuse/_util.py:424 #, python-brace-format msgid "" "'{path}' holds an SPDX expression that cannot be parsed, skipping the file" msgstr "" "'{path}' содержит выражение SPDX, которое не может быть разобрано, что " "приводит к пропуску файла" #: src/reuse/_util.py:556 msgid "'{}' is not a file" msgstr "'{}' не является файлом" #: src/reuse/_util.py:559 msgid "'{}' is not a directory" msgstr "'{}' не является каталогом" #: src/reuse/_util.py:562 msgid "can't open '{}'" msgstr "Невозможно открыть '{}'" #: src/reuse/_util.py:567 msgid "can't write to directory '{}'" msgstr "Невозможно записать в каталог '{}'" #: src/reuse/_util.py:586 msgid "can't read or write '{}'" msgstr "Невозможно прочитать или записать '{}'" #: src/reuse/_util.py:596 msgid "'{}' is not a valid SPDX expression, aborting" msgstr "'{}' не является правильным выражением SPDX, прерывается" #: src/reuse/_util.py:624 msgid "'{}' is not a valid SPDX License Identifier." msgstr "'{}' не является действительным идентификатором лицензии SPDX." #: src/reuse/_util.py:631 msgid "Did you mean:" msgstr "Вы имели в виду:" #: src/reuse/_util.py:638 msgid "" "See for a list of valid SPDX License " "Identifiers." msgstr "" "Список допустимых идентификаторов лицензий SPDX см. в ." #: src/reuse/convert_dep5.py:118 msgid "no '.reuse/dep5' file" msgstr "Нет файла '.reuse/dep5'" #: src/reuse/download.py:130 msgid "SPDX License Identifier of license" msgstr "Лицензия SPDX Идентификатор лицензии" #: src/reuse/download.py:135 msgid "download all missing licenses detected in the project" msgstr "загрузить все отсутствующие лицензии, обнаруженные в проекте" #: src/reuse/download.py:145 msgid "" "source from which to copy custom LicenseRef- licenses, either a directory " "that contains the file or the file itself" msgstr "" "источник, из которого копируются пользовательские лицензии LicenseRef-, либо " "каталог, содержащий файл, либо сам файл" #: src/reuse/download.py:156 #, python-brace-format msgid "Error: {spdx_identifier} already exists." msgstr "Ошибка: {spdx_identifier} уже существует." #: src/reuse/download.py:163 #, python-brace-format msgid "Error: {path} does not exist." msgstr "Ошибка: {path} не существует." #: src/reuse/download.py:166 msgid "Error: Failed to download license." msgstr "Ошибка: Не удалось загрузить лицензию." #: src/reuse/download.py:171 msgid "Is your internet connection working?" msgstr "Работает ли ваше интернет-соединение?" #: src/reuse/download.py:176 #, python-brace-format msgid "Successfully downloaded {spdx_identifier}." msgstr "Успешно загружен {spdx_identifier}." #: src/reuse/download.py:188 msgid "--output has no effect when used together with --all" msgstr "--output не имеет эффекта, если используется вместе с --all" #: src/reuse/download.py:192 msgid "the following arguments are required: license" msgstr "необходимы следующие аргументы: лицензия" #: src/reuse/download.py:194 msgid "cannot use --output with more than one license" msgstr "Невозможно использовать --output с более чем одной лицензией" #: src/reuse/global_licensing.py:109 #, python-brace-format msgid "" "{attr_name} must be a {type_name} (got {value} that is a {value_class})." msgstr "" "{attr_name} должно быть {type_name} (получено {value}, которое является " "{value_class})." #: src/reuse/global_licensing.py:122 #, python-brace-format msgid "" "Item in {attr_name} collection must be a {type_name} (got {item_value} that " "is a {item_class})." msgstr "" "Элемент в коллекции {attr_name} должен быть {type_name} (получил " "{item_value}, который является {item_class})." #: src/reuse/global_licensing.py:133 #, python-brace-format msgid "{attr_name} must not be empty." msgstr "{attr_name} не должно быть пустым." #: src/reuse/global_licensing.py:156 #, python-brace-format msgid "{name} must be a {type} (got {value} that is a {value_type})." msgstr "" "{name} должно быть {type} (получено {value}, которое является {value_type})." #: src/reuse/global_licensing.py:179 #, python-brace-format msgid "" "The value of 'precedence' must be one of {precedence_vals} (got {received})" msgstr "" "Значение '\"Привилегия\" должно быть одним из {precedence_vals} (получено " "{received})" #: src/reuse/header.py:99 msgid "generated comment is missing copyright lines or license expressions" msgstr "" "В сгенерированном комментарии отсутствуют строки об авторских правах или " "выражениях лицензии" #: src/reuse/lint.py:30 msgid "prevents output" msgstr "предотвращает выход" #: src/reuse/lint.py:33 msgid "formats output as JSON" msgstr "форматирует вывод в формате JSON" #: src/reuse/lint.py:39 msgid "formats output as plain text" msgstr "Форматирует вывод в виде обычного текста" #: src/reuse/lint.py:45 #, fuzzy msgid "formats output as errors per line" msgstr "Форматирует вывод в виде обычного текста" #: src/reuse/lint.py:64 msgid "BAD LICENSES" msgstr "ПЛОХАЯ ЛИЦЕНЗИЯ" #: src/reuse/lint.py:66 src/reuse/lint.py:95 msgid "'{}' found in:" msgstr "'{}' найдено в:" #: src/reuse/lint.py:73 msgid "DEPRECATED LICENSES" msgstr "УСТАРЕВШИЕ ЛИЦЕНЗИИ" #: src/reuse/lint.py:75 msgid "The following licenses are deprecated by SPDX:" msgstr "Следующие лицензии устарели в SPDX:" #: src/reuse/lint.py:83 msgid "LICENSES WITHOUT FILE EXTENSION" msgstr "ЛИЦЕНЗИИ БЕЗ РАСШИРЕНИЯ ФАЙЛА" #: src/reuse/lint.py:85 msgid "The following licenses have no file extension:" msgstr "Следующие лицензии не имеют расширения файла:" #: src/reuse/lint.py:93 msgid "MISSING LICENSES" msgstr "ОТСУТСТВУЮЩИЕ ЛИЦЕНЗИИ" #: src/reuse/lint.py:102 msgid "UNUSED LICENSES" msgstr "НЕИСПОЛЬЗОВАННЫЕ ЛИЦЕНЗИИ" #: src/reuse/lint.py:103 msgid "The following licenses are not used:" msgstr "Следующие лицензии не используются:" #: src/reuse/lint.py:110 msgid "READ ERRORS" msgstr "ОШИБКИ ЧТЕНИЯ" #: src/reuse/lint.py:111 msgid "Could not read:" msgstr "Не удалось прочитать:" #: src/reuse/lint.py:132 msgid "MISSING COPYRIGHT AND LICENSING INFORMATION" msgstr "ОТСУТСТВИЕ ИНФОРМАЦИИ ОБ АВТОРСКИХ ПРАВАХ И ЛИЦЕНЗИРОВАНИИ" #: src/reuse/lint.py:138 msgid "The following files have no copyright and licensing information:" msgstr "" "Следующие файлы не содержат информации об авторских правах и лицензировании:" #: src/reuse/lint.py:149 msgid "The following files have no copyright information:" msgstr "Следующие файлы не содержат информации об авторских правах:" #: src/reuse/lint.py:158 msgid "The following files have no licensing information:" msgstr "Следующие файлы не содержат информации о лицензировании:" #: src/reuse/lint.py:166 msgid "SUMMARY" msgstr "РЕЗЮМЕ" #: src/reuse/lint.py:171 msgid "Bad licenses:" msgstr "Плохие лицензии:" #: src/reuse/lint.py:172 msgid "Deprecated licenses:" msgstr "Утраченные лицензии:" #: src/reuse/lint.py:173 msgid "Licenses without file extension:" msgstr "Лицензии без расширения файла:" #: src/reuse/lint.py:176 msgid "Missing licenses:" msgstr "Отсутствующие лицензии:" #: src/reuse/lint.py:177 msgid "Unused licenses:" msgstr "Неиспользованные лицензии:" #: src/reuse/lint.py:178 msgid "Used licenses:" msgstr "Используемые лицензии:" #: src/reuse/lint.py:179 msgid "Read errors:" msgstr "Читайте ошибки:" #: src/reuse/lint.py:181 msgid "Files with copyright information:" msgstr "Файлы с информацией об авторских правах:" #: src/reuse/lint.py:185 msgid "Files with license information:" msgstr "Файлы с информацией о лицензии:" #: src/reuse/lint.py:202 msgid "" "Congratulations! Your project is compliant with version {} of the REUSE " "Specification :-)" msgstr "Поздравляем! Ваш проект соответствует версии {} спецификации REUSE :-)" #: src/reuse/lint.py:209 msgid "" "Unfortunately, your project is not compliant with version {} of the REUSE " "Specification :-(" msgstr "" "К сожалению, ваш проект не соответствует версии {} спецификации REUSE :-(" #: src/reuse/lint.py:216 msgid "RECOMMENDATIONS" msgstr "РЕКОМЕНДАЦИИ" #: src/reuse/lint.py:289 #, python-brace-format msgid "{path}: bad license {lic}\n" msgstr "" #: src/reuse/lint.py:296 #, fuzzy, python-brace-format msgid "{lic_path}: deprecated license\n" msgstr "Утраченные лицензии:" #: src/reuse/lint.py:303 #, fuzzy, python-brace-format msgid "{lic_path}: license without file extension\n" msgstr "Лицензии без расширения файла:" #: src/reuse/lint.py:312 #, fuzzy, python-brace-format msgid "{lic_path}: unused license\n" msgstr "Неиспользованные лицензии:" #: src/reuse/lint.py:319 #, python-brace-format msgid "{path}: missing license {lic}\n" msgstr "" #: src/reuse/lint.py:326 #, python-brace-format msgid "{path}: read error\n" msgstr "" #: src/reuse/lint.py:330 #, fuzzy, python-brace-format msgid "{path}: no license identifier\n" msgstr "'{}' не является действительным идентификатором лицензии SPDX." #: src/reuse/lint.py:334 #, python-brace-format msgid "{path}: no copyright notice\n" msgstr "" #: src/reuse/project.py:262 #, python-brace-format msgid "'{path}' covered by {global_path}" msgstr "'{path}' покрыт {global_path}" #: src/reuse/project.py:270 #, python-brace-format msgid "" "'{path}' is covered exclusively by REUSE.toml. Not reading the file contents." msgstr "" "'{path}' покрывается исключительно REUSE.toml. Не читать содержимое файла." #: src/reuse/project.py:277 #, python-brace-format msgid "" "'{path}' was detected as a binary file; not searching its contents for REUSE " "information." msgstr "" "'{path}' был обнаружен как двоичный файл; поиск информации о REUSE в его " "содержимом не производится." #: src/reuse/project.py:334 msgid "" "'.reuse/dep5' is deprecated. You are recommended to instead use REUSE.toml. " "Use `reuse convert-dep5` to convert." msgstr "" "'.reuse/dep5' является устаревшим. Вместо него рекомендуется использовать " "REUSE.toml. Для преобразования используйте `reuse convert-dep5`." #: src/reuse/project.py:348 #, python-brace-format msgid "" "Found both '{new_path}' and '{old_path}'. You cannot keep both files " "simultaneously; they are not intercompatible." msgstr "" "Найдены оба файла '{new_path}' и '{old_path}'. Вы не можете хранить оба " "файла одновременно; они несовместимы." #: src/reuse/project.py:414 #, python-brace-format msgid "determining identifier of '{path}'" msgstr "определяющий идентификатор '{path}'" #: src/reuse/project.py:422 #, python-brace-format msgid "{path} does not have a file extension" msgstr "У {path} нет расширения файла" #: src/reuse/project.py:432 #, python-brace-format msgid "" "Could not resolve SPDX License Identifier of {path}, resolving to " "{identifier}. Make sure the license is in the license list found at or that it starts with 'LicenseRef-', and that it has a " "file extension." msgstr "" "Не удалось разрешить идентификатор лицензии SPDX {path}, разрешается " "{identifier}. Убедитесь, что лицензия находится в списке лицензий по адресу " " или что она начинается с 'LicenseRef-' и имеет " "расширение файла." #: src/reuse/project.py:444 #, python-brace-format msgid "" "{identifier} is the SPDX License Identifier of both {path} and {other_path}" msgstr "" "{identifier} - это идентификатор лицензии SPDX для {path} и {other_path}" #: src/reuse/project.py:483 msgid "" "project '{}' is not a VCS repository or required VCS software is not " "installed" msgstr "" "Проект '{}' не является репозиторием VCS или в нем не установлено " "необходимое программное обеспечение VCS" #: src/reuse/report.py:310 #, python-brace-format msgid "Could not read '{path}'" msgstr "Не удалось прочитать '{path}'" #: src/reuse/report.py:317 #, python-brace-format msgid "Unexpected error occurred while parsing '{path}'" msgstr "При разборе '{path}' произошла непредвиденная ошибка" #: src/reuse/report.py:438 msgid "" "Fix bad licenses: At least one license in the LICENSES directory and/or " "provided by 'SPDX-License-Identifier' tags is invalid. They are either not " "valid SPDX License Identifiers or do not start with 'LicenseRef-'. FAQ about " "custom licenses: https://reuse.software/faq/#custom-license" msgstr "" "Исправление недействительных лицензий: По крайней мере одна лицензия в " "каталоге LICENSES и/или предоставленная тегами 'SPDX-License-Identifier', " "является недействительной. Они либо не являются действительными " "идентификаторами лицензий SPDX, либо не начинаются с 'LicenseRef-'. Часто " "задаваемые вопросы о пользовательских лицензиях: https://reuse.software/faq/" "#custom-license" #: src/reuse/report.py:449 msgid "" "Fix deprecated licenses: At least one of the licenses in the LICENSES " "directory and/or provided by an 'SPDX-License-Identifier' tag or in '.reuse/" "dep5' has been deprecated by SPDX. The current list and their respective " "recommended new identifiers can be found here: " msgstr "" "Исправление устаревших лицензий: По крайней мере одна из лицензий в каталоге " "LICENSES и/или предоставленная тегом 'SPDX-License-Identifier' или в файле '." "reuse/dep5', была устаревшей в SPDX. Текущий список и рекомендуемые новые " "идентификаторы можно найти здесь: " #: src/reuse/report.py:460 msgid "" "Fix licenses without file extension: At least one license text file in the " "'LICENSES' directory does not have a '.txt' file extension. Please rename " "the file(s) accordingly." msgstr "" "Исправьте лицензии без расширения файла: По крайней мере один текстовый файл " "лицензии в каталоге 'LICENSES' не имеет расширения '.txt'. Пожалуйста, " "переименуйте файл(ы) соответствующим образом." #: src/reuse/report.py:469 msgid "" "Fix missing licenses: For at least one of the license identifiers provided " "by the 'SPDX-License-Identifier' tags, there is no corresponding license " "text file in the 'LICENSES' directory. For SPDX license identifiers, you can " "simply run 'reuse download --all' to get any missing ones. For custom " "licenses (starting with 'LicenseRef-'), you need to add these files yourself." msgstr "" "Исправление отсутствующих лицензий: По крайней мере для одного из " "идентификаторов лицензий, предоставляемых тегами 'SPDX-License-Identifier', " "в каталоге 'LICENSES' нет соответствующего текстового файла лицензии. Для " "идентификаторов лицензий SPDX можно просто выполнить команду 'reuse download " "--all', чтобы получить все недостающие идентификаторы. Для пользовательских " "лицензий (начинающихся с 'LicenseRef-') вам нужно добавить эти файлы " "самостоятельно." #: src/reuse/report.py:481 msgid "" "Fix unused licenses: At least one of the license text files in 'LICENSES' is " "not referenced by any file, e.g. by an 'SPDX-License-Identifier' tag. Please " "make sure that you either tag the accordingly licensed files properly, or " "delete the unused license text if you are sure that no file or code snippet " "is licensed as such." msgstr "" "Исправьте неиспользуемые лицензии: По крайней мере, на один из файлов с " "текстом лицензии в 'LICENSES' не ссылается ни один файл, например, тег 'SPDX-" "License-Identifier'. Пожалуйста, убедитесь, что вы либо пометили " "соответствующие лицензионные файлы должным образом, либо удалили " "неиспользуемый лицензионный текст, если вы уверены, что ни один файл или " "фрагмент кода не лицензируется как таковой." #: src/reuse/report.py:492 msgid "" "Fix read errors: At least one of the files in your directory cannot be read " "by the tool. Please check the file permissions. You will find the affected " "files at the top of the output as part of the logged error messages." msgstr "" "Исправьте ошибки чтения: По крайней мере один из файлов в вашей директории " "не может быть прочитан инструментом. Проверьте права доступа к файлам. " "Затронутые файлы вы найдете в верхней части вывода в виде сообщений об " "ошибках." #: src/reuse/report.py:501 msgid "" "Fix missing copyright/licensing information: For one or more files, the tool " "cannot find copyright and/or licensing information. You typically do this by " "adding 'SPDX-FileCopyrightText' and 'SPDX-License-Identifier' tags to each " "file. The tutorial explains additional ways to do this: " msgstr "" "Исправление отсутствующей информации об авторских правах/лицензировании: Для " "одного или нескольких файлов инструмент не может найти информацию об " "авторских правах и/или лицензировании. Обычно это можно сделать, добавив к " "каждому файлу теги 'SPDX-FileCopyrightText' и 'SPDX-License-Identifier'. В " "учебнике описаны дополнительные способы решения этой задачи: " #: src/reuse/spdx.py:32 msgid "" "populate the LicenseConcluded field; note that reuse cannot guarantee the " "field is accurate" msgstr "" "заполните поле LicenseConcluded; обратите внимание, что повторное " "использование не может гарантировать точность поля" #: src/reuse/spdx.py:39 msgid "name of the person signing off on the SPDX report" msgstr "имя лица, подписавшего отчет SPDX" #: src/reuse/spdx.py:44 msgid "name of the organization signing off on the SPDX report" msgstr "название организации, подписавшей отчет SPDX" #: src/reuse/spdx.py:60 msgid "" "error: --creator-person=NAME or --creator-organization=NAME required when --" "add-license-concluded is provided" msgstr "" "ошибка: требуется --создатель-личность= ИМЯ или -создатель-организация= ИМЯ, " "если указано --добавить- лицензию- заключенную" #: src/reuse/spdx.py:75 #, python-brace-format msgid "" "'{path}' does not match a common SPDX file pattern. Find the suggested " "naming conventions here: https://spdx.github.io/spdx-spec/conformance/#44-" "standard-data-format-requirements" msgstr "" "'{path}' не соответствует распространенному шаблону файлов SPDX. " "Предлагаемые соглашения об именовании можно найти здесь: https://spdx.github." "io/spdx-spec/conformance/#44-standard-data-format-requirements" #: /usr/lib/python3.10/argparse.py:308 msgid "usage: " msgstr "использование: " #: /usr/lib/python3.10/argparse.py:880 msgid ".__call__() not defined" msgstr ".__call__() не определено" #: /usr/lib/python3.10/argparse.py:1223 #, python-format msgid "unknown parser %(parser_name)r (choices: %(choices)s)" msgstr "" "неизвестный синтаксический анализатор %(parser_name)r (варианты: %(choices)s)" #: /usr/lib/python3.10/argparse.py:1283 #, python-format msgid "argument \"-\" with mode %r" msgstr "аргумент \"-\" с режимом %r" #: /usr/lib/python3.10/argparse.py:1292 #, python-format msgid "can't open '%(filename)s': %(error)s" msgstr "Невозможно открыть '%(filename)s': %(error)s" #: /usr/lib/python3.10/argparse.py:1501 #, python-format msgid "cannot merge actions - two groups are named %r" msgstr "Невозможно объединить действия - две группы названы %r" #: /usr/lib/python3.10/argparse.py:1539 msgid "'required' is an invalid argument for positionals" msgstr "'\"Обязательный\" - недопустимый аргумент для позиционирования" #: /usr/lib/python3.10/argparse.py:1561 #, python-format msgid "" "invalid option string %(option)r: must start with a character " "%(prefix_chars)r" msgstr "" "Недопустимая строка опций %(option)r: должна начинаться с символа " "%(prefix_chars)r" #: /usr/lib/python3.10/argparse.py:1579 #, python-format msgid "dest= is required for options like %r" msgstr "dest= требуется для опций типа %r" #: /usr/lib/python3.10/argparse.py:1596 #, python-format msgid "invalid conflict_resolution value: %r" msgstr "Недопустимое значение конфликтного_разрешения: %r" #: /usr/lib/python3.10/argparse.py:1614 #, python-format msgid "conflicting option string: %s" msgid_plural "conflicting option strings: %s" msgstr[0] "" "одна,двадцать одна,тридцать одна,сорок одна,пятьдесят одна,шестьдесят одна," "семьдесят одна,восемдесят одна,девяносто одна, сто одна противоречащая " "строка опций: %s" msgstr[1] "" "две,три,четыре,двадцать две,двадцать три,двадцать четыре,тридцать две," "тридцать три,тридцать четыре,сорок две конфликтующих строк опций: %s" msgstr[2] "" "ноль,пять,шесть,семь,восемь,девять,десять,одинадцать,двенадцать,тринадцать " "конфликтующих строк опций: %s" #: /usr/lib/python3.10/argparse.py:1680 msgid "mutually exclusive arguments must be optional" msgstr "взаимоисключающие аргументы должны быть необязательными" #: /usr/lib/python3.10/argparse.py:1748 msgid "positional arguments" msgstr "позиционные аргументы" #: /usr/lib/python3.10/argparse.py:1749 msgid "options" msgstr "варианты" #: /usr/lib/python3.10/argparse.py:1764 msgid "show this help message and exit" msgstr "покажите это справочное сообщение и выйдите" #: /usr/lib/python3.10/argparse.py:1795 msgid "cannot have multiple subparser arguments" msgstr "не может иметь несколько аргументов подпарсера" #: /usr/lib/python3.10/argparse.py:1847 /usr/lib/python3.10/argparse.py:2362 #, python-format msgid "unrecognized arguments: %s" msgstr "нераспознанные аргументы: %s" #: /usr/lib/python3.10/argparse.py:1948 #, python-format msgid "not allowed with argument %s" msgstr "не разрешено с аргументом %s" #: /usr/lib/python3.10/argparse.py:1998 /usr/lib/python3.10/argparse.py:2012 #, python-format msgid "ignored explicit argument %r" msgstr "проигнорирован явный аргумент %r" #: /usr/lib/python3.10/argparse.py:2119 #, python-format msgid "the following arguments are required: %s" msgstr "требуются следующие аргументы: %s" #: /usr/lib/python3.10/argparse.py:2134 #, python-format msgid "one of the arguments %s is required" msgstr "требуется один из аргументов %s" #: /usr/lib/python3.10/argparse.py:2177 msgid "expected one argument" msgstr "ожидается один аргумент" #: /usr/lib/python3.10/argparse.py:2178 msgid "expected at most one argument" msgstr "ожидается не более одного аргумента" #: /usr/lib/python3.10/argparse.py:2179 msgid "expected at least one argument" msgstr "ожидал по крайней мере один аргумент" #: /usr/lib/python3.10/argparse.py:2183 #, python-format msgid "expected %s argument" msgid_plural "expected %s arguments" msgstr[0] "" "один,двадцать один,тридцать один,сорок один,пятьдесят один,шестьдесят один," "семдесят один,восемдесят один,девяносто один,сто один ожидаемый аргумент %s" msgstr[1] "" "два,три,четыре,двадцать два,двадцать три,двадцать четыре,тридцать два," "тридцать три,тридцать четыре,сорок два ожидаемых %s аргументов" msgstr[2] "" "ноль,пять,шесть,семь,восемь,девять,десять,одинадцать,двенадцать,тринадцать " "ожидаемых %s аргументов" #: /usr/lib/python3.10/argparse.py:2241 #, python-format msgid "ambiguous option: %(option)s could match %(matches)s" msgstr "Неоднозначная опция: %(option)s может соответствовать %(matches)s" #: /usr/lib/python3.10/argparse.py:2305 #, python-format msgid "unexpected option string: %s" msgstr "Неожиданная строка опции: %s" #: /usr/lib/python3.10/argparse.py:2502 #, python-format msgid "%r is not callable" msgstr "%r не является вызываемым" #: /usr/lib/python3.10/argparse.py:2519 #, python-format msgid "invalid %(type)s value: %(value)r" msgstr "Недопустимое значение %(type)s: %(value)r" #: /usr/lib/python3.10/argparse.py:2530 #, python-format msgid "invalid choice: %(value)r (choose from %(choices)s)" msgstr "Неверный выбор: %(value)r (выберите из %(choices)s" #: /usr/lib/python3.10/argparse.py:2606 #, python-format msgid "%(prog)s: error: %(message)s\n" msgstr "%(prog)s: ошибка: %(message)s\n" #, python-brace-format #~ msgid "" #~ "Copyright and licensing information for '{original_path}' has been found " #~ "in both '{path}' and in the DEP5 file located at '{dep5_path}'. The " #~ "information for these two sources has been aggregated. You are " #~ "recommended to instead use REUSE.toml, where you can specify the order of " #~ "precedence. Use `reuse convert-dep5` to convert. Run with `--suppress-" #~ "deprecation` to hide this warning." #~ msgstr "" #~ "Информация об авторских правах и лицензировании для '{original_path}' " #~ "была найдена как в '{path}', так и в файле DEP5, расположенном по адресу " #~ "'{dep5_path}'. Информация из этих двух источников была объединена. Вместо " #~ "этого рекомендуется использовать REUSE.toml, где можно указать порядок " #~ "приоритета. Для преобразования используйте `reuse convert-dep5`. " #~ "Запускайте с `--suppress-deprecation`, чтобы скрыть это предупреждение." reuse-tool-4.0.3/po/sv.po000066400000000000000000000567411464275211500152460ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-07-03 13:09+0000\n" "PO-Revision-Date: 2024-01-08 20:06+0000\n" "Last-Translator: Kristoffer Grundström \n" "Language-Team: Swedish \n" "Language: sv\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 5.4-dev\n" #: src/reuse/_annotate.py:74 #, python-brace-format msgid "" "'{path}' does not support single-line comments, please do not use --single-" "line" msgstr "" #: src/reuse/_annotate.py:81 #, python-brace-format msgid "" "'{path}' does not support multi-line comments, please do not use --multi-line" msgstr "" #: src/reuse/_annotate.py:136 #, python-brace-format msgid "Skipped unrecognised file '{path}'" msgstr "" #: src/reuse/_annotate.py:142 #, python-brace-format msgid "'{path}' is not recognised; creating '{path}.license'" msgstr "" #: src/reuse/_annotate.py:158 #, python-brace-format msgid "Skipped file '{path}' already containing REUSE information" msgstr "" #: src/reuse/_annotate.py:192 #, python-brace-format msgid "Error: Could not create comment for '{path}'" msgstr "" #: src/reuse/_annotate.py:199 #, python-brace-format msgid "" "Error: Generated comment header for '{path}' is missing copyright lines or " "license expressions. The template is probably incorrect. Did not write new " "header." msgstr "" #. TODO: This may need to be rephrased more elegantly. #: src/reuse/_annotate.py:210 #, python-brace-format msgid "Successfully changed header of {path}" msgstr "" #: src/reuse/_annotate.py:221 msgid "--skip-unrecognised has no effect when used together with --style" msgstr "" #: src/reuse/_annotate.py:231 msgid "option --contributor, --copyright or --license is required" msgstr "" #: src/reuse/_annotate.py:272 #, python-brace-format msgid "template {template} could not be found" msgstr "" #: src/reuse/_annotate.py:341 src/reuse/_util.py:573 msgid "can't write to '{}'" msgstr "kan inte skriva till '{}'" #: src/reuse/_annotate.py:366 msgid "" "The following files do not have a recognised file extension. Please use --" "style, --force-dot-license, --fallback-dot-license, or --skip-unrecognised:" msgstr "" #: src/reuse/_annotate.py:382 msgid "copyright statement, repeatable" msgstr "" #: src/reuse/_annotate.py:389 msgid "SPDX Identifier, repeatable" msgstr "" #: src/reuse/_annotate.py:395 msgid "file contributor, repeatable" msgstr "" #: src/reuse/_annotate.py:403 msgid "year of copyright statement, optional" msgstr "" #: src/reuse/_annotate.py:411 msgid "comment style to use, optional" msgstr "" #: src/reuse/_annotate.py:417 msgid "copyright prefix to use, optional" msgstr "" #: src/reuse/_annotate.py:430 msgid "name of template to use, optional" msgstr "" #: src/reuse/_annotate.py:435 msgid "do not include year in statement" msgstr "" #: src/reuse/_annotate.py:440 msgid "merge copyright lines if copyright statements are identical" msgstr "" #: src/reuse/_annotate.py:446 msgid "force single-line comment style, optional" msgstr "" #: src/reuse/_annotate.py:451 msgid "force multi-line comment style, optional" msgstr "" #: src/reuse/_annotate.py:458 msgid "add headers to all files under specified directories recursively" msgstr "" #: src/reuse/_annotate.py:465 msgid "do not replace the first header in the file; just add a new one" msgstr "" #: src/reuse/_annotate.py:473 msgid "always write a .license file instead of a header inside the file" msgstr "" #: src/reuse/_annotate.py:480 msgid "write a .license file to files with unrecognised comment styles" msgstr "" #: src/reuse/_annotate.py:486 msgid "skip files with unrecognised comment styles" msgstr "" #: src/reuse/_annotate.py:497 msgid "skip files that already contain REUSE information" msgstr "" #: src/reuse/_annotate.py:532 #, python-brace-format msgid "'{path}' is a binary, therefore using '{new_path}' for the header" msgstr "" #: src/reuse/_main.py:39 msgid "" "reuse is a tool for compliance with the REUSE recommendations. See for more information, and " "for the online documentation." msgstr "" "reuse är ett verktyg för att följa REUSE-rekommendationerna. Se för mer information och för " "den web-baserade dokumentationen." #: src/reuse/_main.py:45 msgid "" "This version of reuse is compatible with version {} of the REUSE " "Specification." msgstr "" "Den här versionen av reuse är kompatibel med version {} av REUSE-" "specifikationen." #: src/reuse/_main.py:48 msgid "Support the FSFE's work:" msgstr "Stötta FSFE's arbete:" #: src/reuse/_main.py:52 msgid "" "Donations are critical to our strength and autonomy. They enable us to " "continue working for Free Software wherever necessary. Please consider " "making a donation at ." msgstr "" "Donationer är avgörande för vår styrka och självständighet. De gör det " "möjligt för oss att jobba för Fri mjukvara där det är nödvändigt. Vänligen " "överväg att göra en donation till ." #: src/reuse/_main.py:75 msgid "enable debug statements" msgstr "" #: src/reuse/_main.py:80 msgid "hide deprecation warnings" msgstr "" #: src/reuse/_main.py:85 msgid "do not skip over Git submodules" msgstr "hoppa inte över undermoduler för Git" #: src/reuse/_main.py:90 msgid "do not skip over Meson subprojects" msgstr "hoppa inte över underprojekt för Meson" #: src/reuse/_main.py:95 msgid "do not use multiprocessing" msgstr "" #: src/reuse/_main.py:102 msgid "define root of project" msgstr "definiera roten av projektet" #: src/reuse/_main.py:107 msgid "show program's version number and exit" msgstr "visa programmets versionsnummer och avsluta" #: src/reuse/_main.py:111 msgid "subcommands" msgstr "" #: src/reuse/_main.py:118 msgid "add copyright and licensing into the header of files" msgstr "" #: src/reuse/_main.py:121 msgid "" "Add copyright and licensing into the header of one or more files.\n" "\n" "By using --copyright and --license, you can specify which copyright holders " "and licenses to add to the headers of the given files.\n" "\n" "By using --contributor, you can specify people or entity that contributed " "but are not copyright holder of the given files." msgstr "" #: src/reuse/_main.py:140 msgid "download a license and place it in the LICENSES/ directory" msgstr "hämta en licens och placera den i mappen LICENSES/" #: src/reuse/_main.py:142 #, fuzzy msgid "Download a license and place it in the LICENSES/ directory." msgstr "hämta en licens och placera den i mappen LICENSES/" #: src/reuse/_main.py:151 msgid "list all non-compliant files" msgstr "lista alla filer som inte uppfyller kraven" #: src/reuse/_main.py:154 #, python-brace-format msgid "" "Lint the project directory for compliance with version {reuse_version} of " "the REUSE Specification. You can find the latest version of the " "specification at .\n" "\n" "Specifically, the following criteria are checked:\n" "\n" "- Are there any bad (unrecognised, not compliant with SPDX) licenses in the " "project?\n" "\n" "- Are any licenses referred to inside of the project, but not included in " "the LICENSES/ directory?\n" "\n" "- Are any licenses included in the LICENSES/ directory that are not used " "inside of the project?\n" "\n" "- Do all files have valid copyright and licensing information?" msgstr "" #: src/reuse/_main.py:181 msgid "print the project's bill of materials in SPDX format" msgstr "" #: src/reuse/_main.py:189 msgid "list all supported SPDX licenses" msgstr "lista alla SPDX-licenser som stöds" #: src/reuse/_main.py:198 msgid "convert .reuse/dep5 to REUSE.toml" msgstr "" #: src/reuse/_main.py:263 #, fuzzy, python-brace-format msgid "'{path}' could not be decoded as UTF-8." msgstr "'{dep5}' kunde inte avkodas som UTF-8." #: src/reuse/_main.py:269 #, fuzzy, python-brace-format msgid "" "'{path}' could not be parsed. We received the following error message: " "{message}" msgstr "" "'{dep5}' kunde inte tolkas. Vi tog emot följande felmeddelande: {message}" #: src/reuse/_util.py:368 src/reuse/global_licensing.py:218 #, python-brace-format msgid "Could not parse '{expression}'" msgstr "Kunde inte tolka '{expression}'" #: src/reuse/_util.py:424 #, python-brace-format msgid "" "'{path}' holds an SPDX expression that cannot be parsed, skipping the file" msgstr "" #: src/reuse/_util.py:556 msgid "'{}' is not a file" msgstr "'{}' är inte en fil" #: src/reuse/_util.py:559 msgid "'{}' is not a directory" msgstr "'{}' är inte en katalog" #: src/reuse/_util.py:562 msgid "can't open '{}'" msgstr "kan inte öppna '{}'" #: src/reuse/_util.py:567 msgid "can't write to directory '{}'" msgstr "kan inte skriva till katalogen '{}'" #: src/reuse/_util.py:586 msgid "can't read or write '{}'" msgstr "kan inte läsa eller skriva '{}'" #: src/reuse/_util.py:596 msgid "'{}' is not a valid SPDX expression, aborting" msgstr "'{}' är inte ett giltigt SPDX-uttryck, avbryter" #: src/reuse/_util.py:624 msgid "'{}' is not a valid SPDX License Identifier." msgstr "" #: src/reuse/_util.py:631 msgid "Did you mean:" msgstr "Menade du:" #: src/reuse/_util.py:638 msgid "" "See for a list of valid SPDX License " "Identifiers." msgstr "" "Se för en lista över giltiga SPDX-" "licensidentifierare." #: src/reuse/convert_dep5.py:118 msgid "no '.reuse/dep5' file" msgstr "" #: src/reuse/download.py:130 msgid "SPDX License Identifier of license" msgstr "" #: src/reuse/download.py:135 msgid "download all missing licenses detected in the project" msgstr "ladda ner alla saknade licenser som upptäckts i projektet" #: src/reuse/download.py:145 msgid "" "source from which to copy custom LicenseRef- licenses, either a directory " "that contains the file or the file itself" msgstr "" #: src/reuse/download.py:156 #, python-brace-format msgid "Error: {spdx_identifier} already exists." msgstr "Fel: {spdx_identifier} existerar redan." #: src/reuse/download.py:163 #, python-brace-format msgid "Error: {path} does not exist." msgstr "Fel: {path} existerar inte." #: src/reuse/download.py:166 msgid "Error: Failed to download license." msgstr "Fel: Hämtningen av licensen misslyckades." #: src/reuse/download.py:171 msgid "Is your internet connection working?" msgstr "Fungerar din internet-anslutning?" #: src/reuse/download.py:176 #, python-brace-format msgid "Successfully downloaded {spdx_identifier}." msgstr "Hämtningen av {spdx_identifier} lyckades." #: src/reuse/download.py:188 msgid "--output has no effect when used together with --all" msgstr "" #: src/reuse/download.py:192 msgid "the following arguments are required: license" msgstr "följande argument behövs: licens" #: src/reuse/download.py:194 msgid "cannot use --output with more than one license" msgstr "kan inte använda --output med mer än en licens" #: src/reuse/global_licensing.py:109 #, python-brace-format msgid "" "{attr_name} must be a {type_name} (got {value} that is a {value_class})." msgstr "" #: src/reuse/global_licensing.py:122 #, python-brace-format msgid "" "Item in {attr_name} collection must be a {type_name} (got {item_value} that " "is a {item_class})." msgstr "" #: src/reuse/global_licensing.py:133 #, python-brace-format msgid "{attr_name} must not be empty." msgstr "" #: src/reuse/global_licensing.py:156 #, python-brace-format msgid "{name} must be a {type} (got {value} that is a {value_type})." msgstr "" #: src/reuse/global_licensing.py:179 #, python-brace-format msgid "" "The value of 'precedence' must be one of {precedence_vals} (got {received})" msgstr "" #: src/reuse/header.py:99 msgid "generated comment is missing copyright lines or license expressions" msgstr "" #: src/reuse/lint.py:30 msgid "prevents output" msgstr "" #: src/reuse/lint.py:33 msgid "formats output as JSON" msgstr "" #: src/reuse/lint.py:39 msgid "formats output as plain text" msgstr "" #: src/reuse/lint.py:45 msgid "formats output as errors per line" msgstr "" #: src/reuse/lint.py:64 msgid "BAD LICENSES" msgstr "" #: src/reuse/lint.py:66 src/reuse/lint.py:95 msgid "'{}' found in:" msgstr "" #: src/reuse/lint.py:73 msgid "DEPRECATED LICENSES" msgstr "" #: src/reuse/lint.py:75 msgid "The following licenses are deprecated by SPDX:" msgstr "" #: src/reuse/lint.py:83 msgid "LICENSES WITHOUT FILE EXTENSION" msgstr "" #: src/reuse/lint.py:85 msgid "The following licenses have no file extension:" msgstr "" #: src/reuse/lint.py:93 msgid "MISSING LICENSES" msgstr "" #: src/reuse/lint.py:102 msgid "UNUSED LICENSES" msgstr "" #: src/reuse/lint.py:103 msgid "The following licenses are not used:" msgstr "" #: src/reuse/lint.py:110 msgid "READ ERRORS" msgstr "" #: src/reuse/lint.py:111 msgid "Could not read:" msgstr "" #: src/reuse/lint.py:132 msgid "MISSING COPYRIGHT AND LICENSING INFORMATION" msgstr "" #: src/reuse/lint.py:138 msgid "The following files have no copyright and licensing information:" msgstr "" #: src/reuse/lint.py:149 msgid "The following files have no copyright information:" msgstr "" #: src/reuse/lint.py:158 msgid "The following files have no licensing information:" msgstr "" #: src/reuse/lint.py:166 msgid "SUMMARY" msgstr "" #: src/reuse/lint.py:171 msgid "Bad licenses:" msgstr "" #: src/reuse/lint.py:172 msgid "Deprecated licenses:" msgstr "" #: src/reuse/lint.py:173 msgid "Licenses without file extension:" msgstr "" #: src/reuse/lint.py:176 msgid "Missing licenses:" msgstr "" #: src/reuse/lint.py:177 msgid "Unused licenses:" msgstr "" #: src/reuse/lint.py:178 msgid "Used licenses:" msgstr "" #: src/reuse/lint.py:179 msgid "Read errors:" msgstr "" #: src/reuse/lint.py:181 msgid "Files with copyright information:" msgstr "" #: src/reuse/lint.py:185 msgid "Files with license information:" msgstr "" #: src/reuse/lint.py:202 msgid "" "Congratulations! Your project is compliant with version {} of the REUSE " "Specification :-)" msgstr "" #: src/reuse/lint.py:209 msgid "" "Unfortunately, your project is not compliant with version {} of the REUSE " "Specification :-(" msgstr "" #: src/reuse/lint.py:216 msgid "RECOMMENDATIONS" msgstr "" #: src/reuse/lint.py:289 #, python-brace-format msgid "{path}: bad license {lic}\n" msgstr "" #: src/reuse/lint.py:296 #, python-brace-format msgid "{lic_path}: deprecated license\n" msgstr "" #: src/reuse/lint.py:303 #, python-brace-format msgid "{lic_path}: license without file extension\n" msgstr "" #: src/reuse/lint.py:312 #, python-brace-format msgid "{lic_path}: unused license\n" msgstr "" #: src/reuse/lint.py:319 #, python-brace-format msgid "{path}: missing license {lic}\n" msgstr "" #: src/reuse/lint.py:326 #, python-brace-format msgid "{path}: read error\n" msgstr "" #: src/reuse/lint.py:330 #, python-brace-format msgid "{path}: no license identifier\n" msgstr "" #: src/reuse/lint.py:334 #, python-brace-format msgid "{path}: no copyright notice\n" msgstr "" #: src/reuse/project.py:262 #, python-brace-format msgid "'{path}' covered by {global_path}" msgstr "" #: src/reuse/project.py:270 #, python-brace-format msgid "" "'{path}' is covered exclusively by REUSE.toml. Not reading the file contents." msgstr "" #: src/reuse/project.py:277 #, python-brace-format msgid "" "'{path}' was detected as a binary file; not searching its contents for REUSE " "information." msgstr "" #: src/reuse/project.py:334 msgid "" "'.reuse/dep5' is deprecated. You are recommended to instead use REUSE.toml. " "Use `reuse convert-dep5` to convert." msgstr "" #: src/reuse/project.py:348 #, python-brace-format msgid "" "Found both '{new_path}' and '{old_path}'. You cannot keep both files " "simultaneously; they are not intercompatible." msgstr "" #: src/reuse/project.py:414 #, python-brace-format msgid "determining identifier of '{path}'" msgstr "" #: src/reuse/project.py:422 #, python-brace-format msgid "{path} does not have a file extension" msgstr "" #: src/reuse/project.py:432 #, python-brace-format msgid "" "Could not resolve SPDX License Identifier of {path}, resolving to " "{identifier}. Make sure the license is in the license list found at or that it starts with 'LicenseRef-', and that it has a " "file extension." msgstr "" #: src/reuse/project.py:444 #, python-brace-format msgid "" "{identifier} is the SPDX License Identifier of both {path} and {other_path}" msgstr "" #: src/reuse/project.py:483 msgid "" "project '{}' is not a VCS repository or required VCS software is not " "installed" msgstr "" #: src/reuse/report.py:310 #, python-brace-format msgid "Could not read '{path}'" msgstr "" #: src/reuse/report.py:317 #, python-brace-format msgid "Unexpected error occurred while parsing '{path}'" msgstr "" #: src/reuse/report.py:438 msgid "" "Fix bad licenses: At least one license in the LICENSES directory and/or " "provided by 'SPDX-License-Identifier' tags is invalid. They are either not " "valid SPDX License Identifiers or do not start with 'LicenseRef-'. FAQ about " "custom licenses: https://reuse.software/faq/#custom-license" msgstr "" #: src/reuse/report.py:449 msgid "" "Fix deprecated licenses: At least one of the licenses in the LICENSES " "directory and/or provided by an 'SPDX-License-Identifier' tag or in '.reuse/" "dep5' has been deprecated by SPDX. The current list and their respective " "recommended new identifiers can be found here: " msgstr "" #: src/reuse/report.py:460 msgid "" "Fix licenses without file extension: At least one license text file in the " "'LICENSES' directory does not have a '.txt' file extension. Please rename " "the file(s) accordingly." msgstr "" #: src/reuse/report.py:469 msgid "" "Fix missing licenses: For at least one of the license identifiers provided " "by the 'SPDX-License-Identifier' tags, there is no corresponding license " "text file in the 'LICENSES' directory. For SPDX license identifiers, you can " "simply run 'reuse download --all' to get any missing ones. For custom " "licenses (starting with 'LicenseRef-'), you need to add these files yourself." msgstr "" #: src/reuse/report.py:481 msgid "" "Fix unused licenses: At least one of the license text files in 'LICENSES' is " "not referenced by any file, e.g. by an 'SPDX-License-Identifier' tag. Please " "make sure that you either tag the accordingly licensed files properly, or " "delete the unused license text if you are sure that no file or code snippet " "is licensed as such." msgstr "" #: src/reuse/report.py:492 msgid "" "Fix read errors: At least one of the files in your directory cannot be read " "by the tool. Please check the file permissions. You will find the affected " "files at the top of the output as part of the logged error messages." msgstr "" #: src/reuse/report.py:501 msgid "" "Fix missing copyright/licensing information: For one or more files, the tool " "cannot find copyright and/or licensing information. You typically do this by " "adding 'SPDX-FileCopyrightText' and 'SPDX-License-Identifier' tags to each " "file. The tutorial explains additional ways to do this: " msgstr "" #: src/reuse/spdx.py:32 msgid "" "populate the LicenseConcluded field; note that reuse cannot guarantee the " "field is accurate" msgstr "" #: src/reuse/spdx.py:39 msgid "name of the person signing off on the SPDX report" msgstr "" #: src/reuse/spdx.py:44 msgid "name of the organization signing off on the SPDX report" msgstr "" #: src/reuse/spdx.py:60 msgid "" "error: --creator-person=NAME or --creator-organization=NAME required when --" "add-license-concluded is provided" msgstr "" #: src/reuse/spdx.py:75 #, python-brace-format msgid "" "'{path}' does not match a common SPDX file pattern. Find the suggested " "naming conventions here: https://spdx.github.io/spdx-spec/conformance/#44-" "standard-data-format-requirements" msgstr "" #: /usr/lib/python3.10/argparse.py:308 msgid "usage: " msgstr "" #: /usr/lib/python3.10/argparse.py:880 msgid ".__call__() not defined" msgstr "" #: /usr/lib/python3.10/argparse.py:1223 #, python-format msgid "unknown parser %(parser_name)r (choices: %(choices)s)" msgstr "" #: /usr/lib/python3.10/argparse.py:1283 #, python-format msgid "argument \"-\" with mode %r" msgstr "" #: /usr/lib/python3.10/argparse.py:1292 #, python-format msgid "can't open '%(filename)s': %(error)s" msgstr "" #: /usr/lib/python3.10/argparse.py:1501 #, python-format msgid "cannot merge actions - two groups are named %r" msgstr "" #: /usr/lib/python3.10/argparse.py:1539 msgid "'required' is an invalid argument for positionals" msgstr "" #: /usr/lib/python3.10/argparse.py:1561 #, python-format msgid "" "invalid option string %(option)r: must start with a character " "%(prefix_chars)r" msgstr "" #: /usr/lib/python3.10/argparse.py:1579 #, python-format msgid "dest= is required for options like %r" msgstr "" #: /usr/lib/python3.10/argparse.py:1596 #, python-format msgid "invalid conflict_resolution value: %r" msgstr "" #: /usr/lib/python3.10/argparse.py:1614 #, python-format msgid "conflicting option string: %s" msgid_plural "conflicting option strings: %s" msgstr[0] "" msgstr[1] "" #: /usr/lib/python3.10/argparse.py:1680 msgid "mutually exclusive arguments must be optional" msgstr "" #: /usr/lib/python3.10/argparse.py:1748 msgid "positional arguments" msgstr "" #: /usr/lib/python3.10/argparse.py:1749 msgid "options" msgstr "" #: /usr/lib/python3.10/argparse.py:1764 msgid "show this help message and exit" msgstr "" #: /usr/lib/python3.10/argparse.py:1795 msgid "cannot have multiple subparser arguments" msgstr "" #: /usr/lib/python3.10/argparse.py:1847 /usr/lib/python3.10/argparse.py:2362 #, python-format msgid "unrecognized arguments: %s" msgstr "" #: /usr/lib/python3.10/argparse.py:1948 #, python-format msgid "not allowed with argument %s" msgstr "" #: /usr/lib/python3.10/argparse.py:1998 /usr/lib/python3.10/argparse.py:2012 #, python-format msgid "ignored explicit argument %r" msgstr "" #: /usr/lib/python3.10/argparse.py:2119 #, python-format msgid "the following arguments are required: %s" msgstr "" #: /usr/lib/python3.10/argparse.py:2134 #, python-format msgid "one of the arguments %s is required" msgstr "" #: /usr/lib/python3.10/argparse.py:2177 msgid "expected one argument" msgstr "" #: /usr/lib/python3.10/argparse.py:2178 msgid "expected at most one argument" msgstr "" #: /usr/lib/python3.10/argparse.py:2179 msgid "expected at least one argument" msgstr "" #: /usr/lib/python3.10/argparse.py:2183 #, python-format msgid "expected %s argument" msgid_plural "expected %s arguments" msgstr[0] "" msgstr[1] "" #: /usr/lib/python3.10/argparse.py:2241 #, python-format msgid "ambiguous option: %(option)s could match %(matches)s" msgstr "" #: /usr/lib/python3.10/argparse.py:2305 #, python-format msgid "unexpected option string: %s" msgstr "" #: /usr/lib/python3.10/argparse.py:2502 #, python-format msgid "%r is not callable" msgstr "" #: /usr/lib/python3.10/argparse.py:2519 #, python-format msgid "invalid %(type)s value: %(value)r" msgstr "" #: /usr/lib/python3.10/argparse.py:2530 #, python-format msgid "invalid choice: %(value)r (choose from %(choices)s)" msgstr "" #: /usr/lib/python3.10/argparse.py:2606 #, python-format msgid "%(prog)s: error: %(message)s\n" msgstr "" #~ msgid "initialize REUSE project" #~ msgstr "initialisera REUSE-projektet" #~ msgid "no '{}' file, or could not read it" #~ msgstr "ingen '{}'-fil eller kunde inte läsa den" reuse-tool-4.0.3/po/tr.po000066400000000000000000001124021464275211500152260ustar00rootroot00000000000000# SPDX-FileCopyrightText: 2020 T. E. Kalayci # # SPDX-License-Identifier: GPL-3.0-or-later msgid "" msgstr "" "Project-Id-Version: FSFE reuse\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-07-03 13:09+0000\n" "PO-Revision-Date: 2023-09-28 07:03+0000\n" "Last-Translator: \"T. E. Kalaycı\" \n" "Language-Team: Turkish \n" "Language: tr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 5.1-dev\n" #: src/reuse/_annotate.py:74 #, python-brace-format msgid "" "'{path}' does not support single-line comments, please do not use --single-" "line" msgstr "" "'{path}' tek satırlık yorumları desteklemiyor, lütfen --single-line " "kullanmayın" #: src/reuse/_annotate.py:81 #, python-brace-format msgid "" "'{path}' does not support multi-line comments, please do not use --multi-line" msgstr "" "'{path}' çok satırlı yorumları desteklemiyor, lütfen --multi-line kullanmayın" #: src/reuse/_annotate.py:136 #, fuzzy, python-brace-format msgid "Skipped unrecognised file '{path}'" msgstr "Tanınmayan {path} dosyası atlandı" #: src/reuse/_annotate.py:142 #, python-brace-format msgid "'{path}' is not recognised; creating '{path}.license'" msgstr "" #: src/reuse/_annotate.py:158 #, python-brace-format msgid "Skipped file '{path}' already containing REUSE information" msgstr "Halihazırda REUSE bilgisi içeren '{path}' dosyası atlanıyor" #: src/reuse/_annotate.py:192 #, python-brace-format msgid "Error: Could not create comment for '{path}'" msgstr "Hata: '{path}' için yorum oluşturulamıyor" #: src/reuse/_annotate.py:199 #, python-brace-format msgid "" "Error: Generated comment header for '{path}' is missing copyright lines or " "license expressions. The template is probably incorrect. Did not write new " "header." msgstr "" "Hata: '{path}' için üretilen başlık yorumu telif hakkı satırlarını veya " "lisans ifadelerini içermiyor. Şablon hatalı olabilir. Yeni başlık yazılmadı." #. TODO: This may need to be rephrased more elegantly. #: src/reuse/_annotate.py:210 #, python-brace-format msgid "Successfully changed header of {path}" msgstr "{path} başlığı başarılı bir şekilde değiştirildi" #: src/reuse/_annotate.py:221 msgid "--skip-unrecognised has no effect when used together with --style" msgstr "--skip-unrecognised, --style ile kullanıldığında etkisizdir" #: src/reuse/_annotate.py:231 msgid "option --contributor, --copyright or --license is required" msgstr "--contributor, --copyright veya --license seçenekleri gereklidir" #: src/reuse/_annotate.py:272 #, python-brace-format msgid "template {template} could not be found" msgstr "{template} şablonu bulunamıyor" #: src/reuse/_annotate.py:341 src/reuse/_util.py:573 msgid "can't write to '{}'" msgstr "'{}' yazılamıyor" #: src/reuse/_annotate.py:366 #, fuzzy msgid "" "The following files do not have a recognised file extension. Please use --" "style, --force-dot-license, --fallback-dot-license, or --skip-unrecognised:" msgstr "" "Aşağıdaki dosya bilinen bir dosya uzantısına sahip değil. Lütfen --style, --" "force-dot-license veya --skip-unrecognised kullanın:" #: src/reuse/_annotate.py:382 msgid "copyright statement, repeatable" msgstr "telif hakkı ifadesi, tekrarlanabilir" #: src/reuse/_annotate.py:389 msgid "SPDX Identifier, repeatable" msgstr "SPDX Kimliği, tekrarlanabilir" #: src/reuse/_annotate.py:395 msgid "file contributor, repeatable" msgstr "dosyaya katkı veren, tekrarlanabilir" #: src/reuse/_annotate.py:403 msgid "year of copyright statement, optional" msgstr "telif hakkı ifadesi, isteğe bağlı" #: src/reuse/_annotate.py:411 msgid "comment style to use, optional" msgstr "kullanılacak yorum biçimi, isteğe bağlı" #: src/reuse/_annotate.py:417 #, fuzzy msgid "copyright prefix to use, optional" msgstr "kullanılacak telif hakkı biçimi, isteğe bağlı" #: src/reuse/_annotate.py:430 msgid "name of template to use, optional" msgstr "kullanılacak şablon ismi, isteğe bağlı" #: src/reuse/_annotate.py:435 msgid "do not include year in statement" msgstr "ifadede yıl içerme" #: src/reuse/_annotate.py:440 msgid "merge copyright lines if copyright statements are identical" msgstr "eğer telif hakkı ifadeleri aynıysa telif hakkı satırlarını birleştir" #: src/reuse/_annotate.py:446 msgid "force single-line comment style, optional" msgstr "tek satırlı yorum biçimi kullan, isteğe bağlı" #: src/reuse/_annotate.py:451 msgid "force multi-line comment style, optional" msgstr "çok satırlı yorum biçimi kullan, isteğe bağlı" #: src/reuse/_annotate.py:458 msgid "add headers to all files under specified directories recursively" msgstr "" "başlıkları belirlenen dizinlerin altındaki tüm dosyalara yinelemeli olarak " "ekle" #: src/reuse/_annotate.py:465 msgid "do not replace the first header in the file; just add a new one" msgstr "dosyadaki ilk başlığı değiştirme; sadece yeni bir tane ekle" #: src/reuse/_annotate.py:473 #, fuzzy msgid "always write a .license file instead of a header inside the file" msgstr "dosyanın başlığına yazmak yerine bir .license yazar" #: src/reuse/_annotate.py:480 #, fuzzy msgid "write a .license file to files with unrecognised comment styles" msgstr "tanımlanamayan yorum biçimleri içeren dosyaları atla" #: src/reuse/_annotate.py:486 msgid "skip files with unrecognised comment styles" msgstr "tanımlanamayan yorum biçimleri içeren dosyaları atla" #: src/reuse/_annotate.py:497 msgid "skip files that already contain REUSE information" msgstr "halihazırda REUSE bilgisi içeren dosyaları atla" #: src/reuse/_annotate.py:532 #, python-brace-format msgid "'{path}' is a binary, therefore using '{new_path}' for the header" msgstr "" "'{path}' ikili bir dosya, bu nedenle başlık için '{new_path}' kullanılacak" #: src/reuse/_main.py:39 msgid "" "reuse is a tool for compliance with the REUSE recommendations. See for more information, and " "for the online documentation." msgstr "" "reuse, REUSE önerileriyle uyum için bir araçtır. Daha fazla bilgi için " " sitesini, çevrimiçi belgelendirme için sitesini ziyaret edebilirsiniz." #: src/reuse/_main.py:45 msgid "" "This version of reuse is compatible with version {} of the REUSE " "Specification." msgstr "Bu reuse sürümü, REUSE Belirtiminin {} sürümüyle uyumludur." #: src/reuse/_main.py:48 msgid "Support the FSFE's work:" msgstr "FSFE'nin çalışmalarını destekleyin:" #: src/reuse/_main.py:52 msgid "" "Donations are critical to our strength and autonomy. They enable us to " "continue working for Free Software wherever necessary. Please consider " "making a donation at ." msgstr "" "Gücümüz ve özerkliğimiz için bağışlar oldukça önemli. Gereken her yerde " "Özgür Yazılım için çalışmamızı sağlıyorlar. Lütfen adresi üzerinden bağış yapmayı değerlendirin." #: src/reuse/_main.py:75 msgid "enable debug statements" msgstr "hata ayıklama cümlelerini etkinleştirir" #: src/reuse/_main.py:80 msgid "hide deprecation warnings" msgstr "kullanımdan kaldırma uyarılarını gizle" #: src/reuse/_main.py:85 msgid "do not skip over Git submodules" msgstr "Git alt modüllerini atlamaz" #: src/reuse/_main.py:90 msgid "do not skip over Meson subprojects" msgstr "Meson alt projelerini atlamaz" #: src/reuse/_main.py:95 msgid "do not use multiprocessing" msgstr "çoklu işlem kullanmaz" #: src/reuse/_main.py:102 msgid "define root of project" msgstr "projenin kökünü tanımlar" #: src/reuse/_main.py:107 msgid "show program's version number and exit" msgstr "programın sürüm numarasını gösterip çıkar" #: src/reuse/_main.py:111 msgid "subcommands" msgstr "alt komutlar" #: src/reuse/_main.py:118 msgid "add copyright and licensing into the header of files" msgstr "dosya başlıklarına telif hakkı ve lisans bilgilerini ekler" #: src/reuse/_main.py:121 msgid "" "Add copyright and licensing into the header of one or more files.\n" "\n" "By using --copyright and --license, you can specify which copyright holders " "and licenses to add to the headers of the given files.\n" "\n" "By using --contributor, you can specify people or entity that contributed " "but are not copyright holder of the given files." msgstr "" #: src/reuse/_main.py:140 msgid "download a license and place it in the LICENSES/ directory" msgstr "bir lisans indirir ve LICENSES/ dizinine yerleştirir" #: src/reuse/_main.py:142 #, fuzzy msgid "Download a license and place it in the LICENSES/ directory." msgstr "bir lisans indirir ve LICENSES/ dizinine yerleştirir" #: src/reuse/_main.py:151 msgid "list all non-compliant files" msgstr "bütün uyumsuz dosyaları listeler" #: src/reuse/_main.py:154 #, python-brace-format msgid "" "Lint the project directory for compliance with version {reuse_version} of " "the REUSE Specification. You can find the latest version of the " "specification at .\n" "\n" "Specifically, the following criteria are checked:\n" "\n" "- Are there any bad (unrecognised, not compliant with SPDX) licenses in the " "project?\n" "\n" "- Are any licenses referred to inside of the project, but not included in " "the LICENSES/ directory?\n" "\n" "- Are any licenses included in the LICENSES/ directory that are not used " "inside of the project?\n" "\n" "- Do all files have valid copyright and licensing information?" msgstr "" "Proje dizinini REUSE Belirtimi {reuse_version} sürümüyle uyumu için inceler. " "Belirtimin son sürümüne adresinden " "erişebilirsiniz.\n" "\n" "Özellikle aşağıdaki ölçütler denetleniyor:\n" "\n" "- Projede herhangi bir kötü (tanımlanamayan, SPDX ile uyumsuz) lisans var " "mı?\n" "\n" "- Projede belirtilen ama LICENSES/ dizininde yer almayan lisans var mı?\n" "\n" "- LICENSES/ dizininde yer alan ama projede kullanılmayan lisanslar var mı?\n" "\n" "- Bütün dosyalar telif hakkı ve lisans bilgisi içeriyor mu?" #: src/reuse/_main.py:181 msgid "print the project's bill of materials in SPDX format" msgstr "projenin malzeme listesini SPDX biçiminde yazdırır" #: src/reuse/_main.py:189 msgid "list all supported SPDX licenses" msgstr "tüm desteklenen SPDK lisanslarını listeler" #: src/reuse/_main.py:198 msgid "convert .reuse/dep5 to REUSE.toml" msgstr "" #: src/reuse/_main.py:263 #, fuzzy, python-brace-format msgid "'{path}' could not be decoded as UTF-8." msgstr ".reuse/dep5 utf-8 olarak çözümlenemiyor" #: src/reuse/_main.py:269 #, python-brace-format msgid "" "'{path}' could not be parsed. We received the following error message: " "{message}" msgstr "" #: src/reuse/_util.py:368 src/reuse/global_licensing.py:218 #, python-brace-format msgid "Could not parse '{expression}'" msgstr "'{expression}' çözümlenemiyor" #: src/reuse/_util.py:424 #, python-brace-format msgid "" "'{path}' holds an SPDX expression that cannot be parsed, skipping the file" msgstr "'{path}' çözümlenemeyen bir SPDX ifadesine sahip, dosya atlanıyor" #: src/reuse/_util.py:556 msgid "'{}' is not a file" msgstr "'{}' bir dosya değil" #: src/reuse/_util.py:559 msgid "'{}' is not a directory" msgstr "'{}' bir dizin değil" #: src/reuse/_util.py:562 msgid "can't open '{}'" msgstr "'{}' açılamıyor" #: src/reuse/_util.py:567 msgid "can't write to directory '{}'" msgstr "'{}' dizinine yazılamıyor" #: src/reuse/_util.py:586 msgid "can't read or write '{}'" msgstr "'{}' okunamıyor veya yazılamıyor" #: src/reuse/_util.py:596 msgid "'{}' is not a valid SPDX expression, aborting" msgstr "'{}' geçerli bir SPDX ifadesi değil, iptal ediliyor" #: src/reuse/_util.py:624 msgid "'{}' is not a valid SPDX License Identifier." msgstr "'{}' geçerli bir SPDX Lisans Kimliği değil." #: src/reuse/_util.py:631 msgid "Did you mean:" msgstr "Şunu mu kastettiniz:" #: src/reuse/_util.py:638 msgid "" "See for a list of valid SPDX License " "Identifiers." msgstr "" "Geçerli SPDX Lisans Kimlikleri listesi için " "adresine bakın." #: src/reuse/convert_dep5.py:118 #, fuzzy msgid "no '.reuse/dep5' file" msgstr ".reuse/dep5 oluşturuluyor" #: src/reuse/download.py:130 msgid "SPDX License Identifier of license" msgstr "Lisansın SPDX Lisans Kimliği" #: src/reuse/download.py:135 msgid "download all missing licenses detected in the project" msgstr "projede tespit edilen bütün eksik lisansları indir" #: src/reuse/download.py:145 msgid "" "source from which to copy custom LicenseRef- licenses, either a directory " "that contains the file or the file itself" msgstr "" #: src/reuse/download.py:156 #, python-brace-format msgid "Error: {spdx_identifier} already exists." msgstr "Hata: {spdx_identifier} halihazırda mevcut." #: src/reuse/download.py:163 #, fuzzy, python-brace-format msgid "Error: {path} does not exist." msgstr "'{path}' .spdx ile bitmiyor" #: src/reuse/download.py:166 msgid "Error: Failed to download license." msgstr "Hata: lisans indirme başarısız oldu." #: src/reuse/download.py:171 msgid "Is your internet connection working?" msgstr "İnternet bağlantınız çalışıyor mu?" #: src/reuse/download.py:176 #, python-brace-format msgid "Successfully downloaded {spdx_identifier}." msgstr "{spdx_identifier} başarılı bir şekilde indirildi." #: src/reuse/download.py:188 msgid "--output has no effect when used together with --all" msgstr "--all ile birlikte kullanıldığında --output'un bir etkisi yok" #: src/reuse/download.py:192 msgid "the following arguments are required: license" msgstr "şu değişkenler gerekiyor: license" #: src/reuse/download.py:194 msgid "cannot use --output with more than one license" msgstr "--output birden fazla lisansla birlikte kullanılamıyor" #: src/reuse/global_licensing.py:109 #, python-brace-format msgid "" "{attr_name} must be a {type_name} (got {value} that is a {value_class})." msgstr "" #: src/reuse/global_licensing.py:122 #, python-brace-format msgid "" "Item in {attr_name} collection must be a {type_name} (got {item_value} that " "is a {item_class})." msgstr "" #: src/reuse/global_licensing.py:133 #, python-brace-format msgid "{attr_name} must not be empty." msgstr "" #: src/reuse/global_licensing.py:156 #, python-brace-format msgid "{name} must be a {type} (got {value} that is a {value_type})." msgstr "" #: src/reuse/global_licensing.py:179 #, python-brace-format msgid "" "The value of 'precedence' must be one of {precedence_vals} (got {received})" msgstr "" #: src/reuse/header.py:99 msgid "generated comment is missing copyright lines or license expressions" msgstr "oluşturulan yorumda telif hakkı satırları veya lisans ifadeleri eksik" #: src/reuse/lint.py:30 msgid "prevents output" msgstr "çıktıyı önler" #: src/reuse/lint.py:33 msgid "formats output as JSON" msgstr "çıktıyı JSON olarak biçimlendirir" #: src/reuse/lint.py:39 msgid "formats output as plain text" msgstr "çıktıyı düz metin olarak biçimlendirir" #: src/reuse/lint.py:45 #, fuzzy msgid "formats output as errors per line" msgstr "çıktıyı düz metin olarak biçimlendirir" #: src/reuse/lint.py:64 msgid "BAD LICENSES" msgstr "KÖTÜ LİSANSLAR" #: src/reuse/lint.py:66 src/reuse/lint.py:95 msgid "'{}' found in:" msgstr "'{}' şurada mevcut:" #: src/reuse/lint.py:73 msgid "DEPRECATED LICENSES" msgstr "MODASI GEÇMİŞ LİSANSLAR" #: src/reuse/lint.py:75 msgid "The following licenses are deprecated by SPDX:" msgstr "Şu lisanslar artık SPDX tarafından kullanılmıyor:" #: src/reuse/lint.py:83 msgid "LICENSES WITHOUT FILE EXTENSION" msgstr "DOSYA UZANTISI OLMAYAN LİSANSLAR" #: src/reuse/lint.py:85 msgid "The following licenses have no file extension:" msgstr "Şu lisansların dosya uzantısı yok:" #: src/reuse/lint.py:93 msgid "MISSING LICENSES" msgstr "EKSİK LİSANSLAR" #: src/reuse/lint.py:102 msgid "UNUSED LICENSES" msgstr "KULLANILMAYAN LİSANSLAR" #: src/reuse/lint.py:103 msgid "The following licenses are not used:" msgstr "Şu lisanslar kullanılmıyor:" #: src/reuse/lint.py:110 msgid "READ ERRORS" msgstr "OKUMA HATALARI" #: src/reuse/lint.py:111 msgid "Could not read:" msgstr "Okunamıyor:" #: src/reuse/lint.py:132 msgid "MISSING COPYRIGHT AND LICENSING INFORMATION" msgstr "EKSİK TELİF HAKKI VE LİSANS BİLGİSİ" #: src/reuse/lint.py:138 msgid "The following files have no copyright and licensing information:" msgstr "Şu dosyalarda telif hakkı ve lisans bilgisi yok:" #: src/reuse/lint.py:149 msgid "The following files have no copyright information:" msgstr "Şu dosyalarda telif hakkı bilgisi yok:" #: src/reuse/lint.py:158 msgid "The following files have no licensing information:" msgstr "Şu dosyalarda lisans bilgisi yok:" #: src/reuse/lint.py:166 msgid "SUMMARY" msgstr "ÖZET" #: src/reuse/lint.py:171 msgid "Bad licenses:" msgstr "Kötü lisanslar:" #: src/reuse/lint.py:172 msgid "Deprecated licenses:" msgstr "Modası geçmiş lisanslar:" #: src/reuse/lint.py:173 msgid "Licenses without file extension:" msgstr "Dosya uzantısı olmayan lisanslar:" #: src/reuse/lint.py:176 msgid "Missing licenses:" msgstr "Eksik lisanslar:" #: src/reuse/lint.py:177 msgid "Unused licenses:" msgstr "Kullanılmayan lisanslar:" #: src/reuse/lint.py:178 msgid "Used licenses:" msgstr "Kullanılan lisanslar:" #: src/reuse/lint.py:179 msgid "Read errors:" msgstr "Okuma hataları:" #: src/reuse/lint.py:181 #, fuzzy msgid "Files with copyright information:" msgstr "Telif hakkı içeren dosyalar:" #: src/reuse/lint.py:185 #, fuzzy msgid "Files with license information:" msgstr "Lisans bilgisi içeren dosyalar:" #: src/reuse/lint.py:202 msgid "" "Congratulations! Your project is compliant with version {} of the REUSE " "Specification :-)" msgstr "Tebrikler! Projeniz REUSE Belirtiminin {} sürümüyle uyumlu :-)" #: src/reuse/lint.py:209 msgid "" "Unfortunately, your project is not compliant with version {} of the REUSE " "Specification :-(" msgstr "Maalesef, projeniz REUSE Belirtiminin {} sürümüyle uyumlu değil :-(" #: src/reuse/lint.py:216 msgid "RECOMMENDATIONS" msgstr "" #: src/reuse/lint.py:289 #, python-brace-format msgid "{path}: bad license {lic}\n" msgstr "" #: src/reuse/lint.py:296 #, fuzzy, python-brace-format msgid "{lic_path}: deprecated license\n" msgstr "Modası geçmiş lisanslar:" #: src/reuse/lint.py:303 #, fuzzy, python-brace-format msgid "{lic_path}: license without file extension\n" msgstr "Dosya uzantısı olmayan lisanslar:" #: src/reuse/lint.py:312 #, fuzzy, python-brace-format msgid "{lic_path}: unused license\n" msgstr "Kullanılmayan lisanslar:" #: src/reuse/lint.py:319 #, python-brace-format msgid "{path}: missing license {lic}\n" msgstr "" #: src/reuse/lint.py:326 #, python-brace-format msgid "{path}: read error\n" msgstr "" #: src/reuse/lint.py:330 #, fuzzy, python-brace-format msgid "{path}: no license identifier\n" msgstr "'{}' geçerli bir SPDX Lisans Kimliği değil." #: src/reuse/lint.py:334 #, python-brace-format msgid "{path}: no copyright notice\n" msgstr "" #: src/reuse/project.py:262 #, fuzzy, python-brace-format msgid "'{path}' covered by {global_path}" msgstr "'{path}' .reuse/dep5 ile kapsanıyor" #: src/reuse/project.py:270 #, python-brace-format msgid "" "'{path}' is covered exclusively by REUSE.toml. Not reading the file contents." msgstr "" #: src/reuse/project.py:277 #, python-brace-format msgid "" "'{path}' was detected as a binary file; not searching its contents for REUSE " "information." msgstr "" #: src/reuse/project.py:334 msgid "" "'.reuse/dep5' is deprecated. You are recommended to instead use REUSE.toml. " "Use `reuse convert-dep5` to convert." msgstr "" #: src/reuse/project.py:348 #, python-brace-format msgid "" "Found both '{new_path}' and '{old_path}'. You cannot keep both files " "simultaneously; they are not intercompatible." msgstr "" #: src/reuse/project.py:414 #, python-brace-format msgid "determining identifier of '{path}'" msgstr "'{path}' kimliği belirleniyor" #: src/reuse/project.py:422 #, python-brace-format msgid "{path} does not have a file extension" msgstr "{path} dosya uzantısına sahip değil" #: src/reuse/project.py:432 #, python-brace-format msgid "" "Could not resolve SPDX License Identifier of {path}, resolving to " "{identifier}. Make sure the license is in the license list found at or that it starts with 'LicenseRef-', and that it has a " "file extension." msgstr "" "{path} için, {identifier} olarak çözümlenen SPDX Lisans Kimliği " "anlaşılamadı. Lisansın listesinde bulunduğundan " "veya 'LicenseRef-' ile başladığından ve bir dosya uzantısına sahip " "olduğundan emin olun." #: src/reuse/project.py:444 #, python-brace-format msgid "" "{identifier} is the SPDX License Identifier of both {path} and {other_path}" msgstr "" "{identifier} hem {path} hem de {other_path} için SPDX Lisans Kimliğidir" #: src/reuse/project.py:483 #, fuzzy msgid "" "project '{}' is not a VCS repository or required VCS software is not " "installed" msgstr "proje bir VCS deposu değil veya gerekli VCS yazılımı kurulu değil" #: src/reuse/report.py:310 #, python-brace-format msgid "Could not read '{path}'" msgstr "'{path}' okunamıyor" #: src/reuse/report.py:317 #, python-brace-format msgid "Unexpected error occurred while parsing '{path}'" msgstr "'{path}' çözümlenirken beklenmedik bir hata oluştu" #: src/reuse/report.py:438 msgid "" "Fix bad licenses: At least one license in the LICENSES directory and/or " "provided by 'SPDX-License-Identifier' tags is invalid. They are either not " "valid SPDX License Identifiers or do not start with 'LicenseRef-'. FAQ about " "custom licenses: https://reuse.software/faq/#custom-license" msgstr "" #: src/reuse/report.py:449 msgid "" "Fix deprecated licenses: At least one of the licenses in the LICENSES " "directory and/or provided by an 'SPDX-License-Identifier' tag or in '.reuse/" "dep5' has been deprecated by SPDX. The current list and their respective " "recommended new identifiers can be found here: " msgstr "" #: src/reuse/report.py:460 msgid "" "Fix licenses without file extension: At least one license text file in the " "'LICENSES' directory does not have a '.txt' file extension. Please rename " "the file(s) accordingly." msgstr "" #: src/reuse/report.py:469 msgid "" "Fix missing licenses: For at least one of the license identifiers provided " "by the 'SPDX-License-Identifier' tags, there is no corresponding license " "text file in the 'LICENSES' directory. For SPDX license identifiers, you can " "simply run 'reuse download --all' to get any missing ones. For custom " "licenses (starting with 'LicenseRef-'), you need to add these files yourself." msgstr "" #: src/reuse/report.py:481 msgid "" "Fix unused licenses: At least one of the license text files in 'LICENSES' is " "not referenced by any file, e.g. by an 'SPDX-License-Identifier' tag. Please " "make sure that you either tag the accordingly licensed files properly, or " "delete the unused license text if you are sure that no file or code snippet " "is licensed as such." msgstr "" #: src/reuse/report.py:492 msgid "" "Fix read errors: At least one of the files in your directory cannot be read " "by the tool. Please check the file permissions. You will find the affected " "files at the top of the output as part of the logged error messages." msgstr "" #: src/reuse/report.py:501 msgid "" "Fix missing copyright/licensing information: For one or more files, the tool " "cannot find copyright and/or licensing information. You typically do this by " "adding 'SPDX-FileCopyrightText' and 'SPDX-License-Identifier' tags to each " "file. The tutorial explains additional ways to do this: " msgstr "" #: src/reuse/spdx.py:32 msgid "" "populate the LicenseConcluded field; note that reuse cannot guarantee the " "field is accurate" msgstr "" "LicenseConcluded sahasını doldur; lütfen reuse bu sahanın doğru olduğunu " "güvence edemeyeceğini dikkate alın" #: src/reuse/spdx.py:39 msgid "name of the person signing off on the SPDX report" msgstr "SPDX raporunu imzalayan kişinin ismi" #: src/reuse/spdx.py:44 msgid "name of the organization signing off on the SPDX report" msgstr "SPDX raporunu imzalayan kuruluşun ismi" #: src/reuse/spdx.py:60 msgid "" "error: --creator-person=NAME or --creator-organization=NAME required when --" "add-license-concluded is provided" msgstr "" "hata: --add-license-concluded verildiğinde --creator-person=İSİM veya --" "creator-organization=İSİM gereklidir" #: src/reuse/spdx.py:75 #, python-brace-format msgid "" "'{path}' does not match a common SPDX file pattern. Find the suggested " "naming conventions here: https://spdx.github.io/spdx-spec/conformance/#44-" "standard-data-format-requirements" msgstr "" "'{path}' yaygın SPDX dosya deseniyle eşleşmiyor. Önerilen adlandırma " "kurallarına şuradan bakabilirsiniz: https://spdx.github.io/spdx-spec/" "conformance/#44-standard-data-format-requirements" #: /usr/lib/python3.10/argparse.py:308 msgid "usage: " msgstr "kullanım: " #: /usr/lib/python3.10/argparse.py:880 msgid ".__call__() not defined" msgstr ".__call__() tanımlı değil" #: /usr/lib/python3.10/argparse.py:1223 #, python-format msgid "unknown parser %(parser_name)r (choices: %(choices)s)" msgstr "bilinmeyen ayrıştıcı %(parser_name)r (choices: %(choices)s)" #: /usr/lib/python3.10/argparse.py:1283 #, python-format msgid "argument \"-\" with mode %r" msgstr "%r kipine sahip \"-\" argümanı" #: /usr/lib/python3.10/argparse.py:1292 #, python-format msgid "can't open '%(filename)s': %(error)s" msgstr "'%(filename)s' açılamıyor: %(error)s" #: /usr/lib/python3.10/argparse.py:1501 #, python-format msgid "cannot merge actions - two groups are named %r" msgstr "eylemler birleştirilemiyor - iki grup %r olarak adlandırılmış" #: /usr/lib/python3.10/argparse.py:1539 msgid "'required' is an invalid argument for positionals" msgstr "'required' konumsal parametre için hatalı bir değişkendir" #: /usr/lib/python3.10/argparse.py:1561 #, python-format msgid "" "invalid option string %(option)r: must start with a character " "%(prefix_chars)r" msgstr "hatalı %(option)r seçeneği: %(prefix_chars)r karakteriye başlamalı" #: /usr/lib/python3.10/argparse.py:1579 #, python-format msgid "dest= is required for options like %r" msgstr "%r gibi seçenekler için dest= gerekli" #: /usr/lib/python3.10/argparse.py:1596 #, python-format msgid "invalid conflict_resolution value: %r" msgstr "hatalı conflict_resolution değeri: %r" #: /usr/lib/python3.10/argparse.py:1614 #, python-format msgid "conflicting option string: %s" msgid_plural "conflicting option strings: %s" msgstr[0] "çelişkili seçenek karakter dizisi: %s" msgstr[1] "çelişkili seçenek karakter dizisi: %s" #: /usr/lib/python3.10/argparse.py:1680 msgid "mutually exclusive arguments must be optional" msgstr "ayrık seçenekler isteğe bağlı olmalı" #: /usr/lib/python3.10/argparse.py:1748 msgid "positional arguments" msgstr "konumsal değişkenler" #: /usr/lib/python3.10/argparse.py:1749 msgid "options" msgstr "" #: /usr/lib/python3.10/argparse.py:1764 msgid "show this help message and exit" msgstr "bu yardım mesajını gösterip çık" #: /usr/lib/python3.10/argparse.py:1795 msgid "cannot have multiple subparser arguments" msgstr "birden fazla altayrıştırıcı değişkeni içeremez" #: /usr/lib/python3.10/argparse.py:1847 /usr/lib/python3.10/argparse.py:2362 #, python-format msgid "unrecognized arguments: %s" msgstr "tanımlanamayan değişkenler: %s" #: /usr/lib/python3.10/argparse.py:1948 #, python-format msgid "not allowed with argument %s" msgstr "%s değişkeniyle izin yok" #: /usr/lib/python3.10/argparse.py:1998 /usr/lib/python3.10/argparse.py:2012 #, python-format msgid "ignored explicit argument %r" msgstr "açık %r değişkeni yok sayıldı" #: /usr/lib/python3.10/argparse.py:2119 #, python-format msgid "the following arguments are required: %s" msgstr "şu değişkenler gereklidir: %s" #: /usr/lib/python3.10/argparse.py:2134 #, python-format msgid "one of the arguments %s is required" msgstr "%s değişkenlerinden biri gereklidir" #: /usr/lib/python3.10/argparse.py:2177 msgid "expected one argument" msgstr "bir değişken bekleniyor" #: /usr/lib/python3.10/argparse.py:2178 msgid "expected at most one argument" msgstr "en fazla bir değişken bekleniyor" #: /usr/lib/python3.10/argparse.py:2179 msgid "expected at least one argument" msgstr "en azından bir değişken bekleniyor" #: /usr/lib/python3.10/argparse.py:2183 #, python-format msgid "expected %s argument" msgid_plural "expected %s arguments" msgstr[0] "%s değişkeni bekleniyor" msgstr[1] "%s değişkenleri bekleniyor" #: /usr/lib/python3.10/argparse.py:2241 #, python-format msgid "ambiguous option: %(option)s could match %(matches)s" msgstr "belirsiz seçenek: %(option)s, %(matches)s ile eşleşebilir" #: /usr/lib/python3.10/argparse.py:2305 #, python-format msgid "unexpected option string: %s" msgstr "beklenmedik seçenek karakter dizisi: %s" #: /usr/lib/python3.10/argparse.py:2502 #, python-format msgid "%r is not callable" msgstr "%r çağrılabilir değil" #: /usr/lib/python3.10/argparse.py:2519 #, python-format msgid "invalid %(type)s value: %(value)r" msgstr "hatalı %(type)s değeri: %(value)r" #: /usr/lib/python3.10/argparse.py:2530 #, python-format msgid "invalid choice: %(value)r (choose from %(choices)s)" msgstr "hatalı tercih: %(value)r (%(choices)s seçilmelidir)" #: /usr/lib/python3.10/argparse.py:2606 #, python-format msgid "%(prog)s: error: %(message)s\n" msgstr "%(prog)s: hata: %(message)s\n" #, fuzzy, python-brace-format #~ msgid "" #~ "Copyright and licensing information for '{original_path}' has been found " #~ "in both '{path}' and in the DEP5 file located at '{dep5_path}'. The " #~ "information for these two sources has been aggregated. You are " #~ "recommended to instead use REUSE.toml, where you can specify the order of " #~ "precedence. Use `reuse convert-dep5` to convert. Run with `--suppress-" #~ "deprecation` to hide this warning." #~ msgstr "" #~ "'{original_path}' için telif hakkı ve lisans bilgisi hem '{path}' yolunda " #~ "hem de '{dep5_path}' yolunda yer alan DEP5 dosyasında bulundu. Bu iki " #~ "kaynaktaki bilgileri birleştirildi. Gelecekte bu davranış değişecek ve " #~ "açıkça birleştirmeyi etkinleştirmeniz gerekecek. Daha fazla bilgi için " #~ " adresine bakabilirsiniz. " #~ "Henüz bir şey yapmanız gerek yok. Bu uyarıyı gizlemek için `--suppress-" #~ "deprecation` seçeneğiyle çalıştırabilirsiniz." #~ msgid "initialize REUSE project" #~ msgstr "REUSE projesini ilkler" #~ msgid "" #~ "What license is your project under? Provide the SPDX License Identifier. " #~ "See for the list." #~ msgstr "" #~ "Projeniz hangi lisansa sahip? SPDX Lisans Kimliğini belirtin. Liste için " #~ " adresine bakabilirsiniz." #~ msgid "" #~ "What other license is your project under? Provide the SPDX License " #~ "Identifier." #~ msgstr "" #~ "Projeniz başka hangi lisanslara sahip? SPDX Lisans Kimliğini belirtin." #~ msgid "To stop adding licenses, hit RETURN." #~ msgstr "Lisans eklemeyi durdurmak için ENTER tuşuna basın." #~ msgid "Project already initialized" #~ msgstr "Proje zaten ilklenmiş" #~ msgid "Initializing project for REUSE." #~ msgstr "Proje REUSE için ilkleniyor." #~ msgid "What is the name of the project?" #~ msgstr "Projenin ismi nedir?" #~ msgid "What is the internet address of the project?" #~ msgstr "Projenin İnternet adresi nedir?" #~ msgid "What is the name of the maintainer?" #~ msgstr "Bakımcının adı nedir?" #~ msgid "What is the e-mail address of the maintainer?" #~ msgstr "Bakımcının e-posta adresi nedir?" #~ msgid "All done! Initializing now." #~ msgstr "Tümü bitti! Şimdi ilkleniyor." #~ msgid "{} already exists" #~ msgstr "{} zaten mevcut" #~ msgid "Could not download {}" #~ msgstr "{} indirilemiyor" #~ msgid "Initialization complete." #~ msgstr "İlkleme tamamlandı." #, fuzzy #~ msgid "" #~ "Add copyright and licensing into the header of one or more files.\n" #~ "\n" #~ "By using --copyright and --license, you can specify which copyright " #~ "holders and licenses to add to the headers of the given files.\n" #~ "\n" #~ "By using --contributor, you can specify people or entity that contributed " #~ "but are not copyright holder of the given files.\n" #~ "The first comment is replaced with a new header containing the new " #~ "copyright and licensing information and its former copyright and " #~ "licensing. If you want to keep the first comment intact, use --no-" #~ "replace.\n" #~ "\n" #~ "The comment style should be auto-detected for your files. If a comment " #~ "style could not be detected and --skip-unrecognised is not specified, the " #~ "process aborts. Use --style to specify or override the comment style to " #~ "use.\n" #~ "\n" #~ "A single-line comment style is used when it is available. If no single-" #~ "line comment style is available, a multi-line comment style is used. You " #~ "can force a certain comment style using --single-line or --multi-line.\n" #~ "\n" #~ "You can change the template of the header comment by using --template. " #~ "Place a Jinja2 template in .reuse/templates/mytemplate.jinja2. You can " #~ "use the template by specifying '--template mytemplate'. Read the online " #~ "documentation on how to use this feature.\n" #~ "\n" #~ "If a binary file is detected, or if --force-dot-license is specified, the " #~ "header is placed in a .license file." #~ msgstr "" #~ "Bir veya daha fazla dosya başlığına telif hakkı ve lisans bilgisini " #~ "ekle.\n" #~ "\n" #~ "İlgili dosyaların başlığına hangi telif hakkı sahiplerinin ve lisansların " #~ "ekleneceğini --copyright ve --license değişkenlerini kullanarak " #~ "belirtebilirsiniz.\n" #~ "\n" #~ "Katkıda bulunan ama ilgili dosyaların telif hakkı sahibi olmayan kişiler " #~ "veya oluşumlar için --contributor kullanabilirsiniz.\n" #~ "İlk yorum, yeni telif hakkı ve lisans bilgisiyle önceki telif hakkı ve " #~ "lisans bilgisini içeren yeni bir başlık ile değiştiriliyor. Eğer ilk " #~ "yorumu değiştirmemek istiyorsanız --no-replace kullanın.\n" #~ "\n" #~ "Yorum biçimi dosyalarınız için otomatik olarak belirlenecektir. Eğer bir " #~ "yorum biçimi belirlenemezse, süreç iptal edilecektir. Kullanılacak yorum " #~ "biçimini belirtmek için --style değişkenini kullanın.\n" #~ "\n" #~ "Mevcut olduğunda tek satırlı yorum biçimi kullanılacaktır. Eğer tek satır " #~ "yorum biçimi mevcut değilse, çok satırlı yorum biçimi kullanılır. Belirli " #~ "bir yorum biçimini --single-line veya --multi-line ile " #~ "belirleyebilirsiniz.\n" #~ "\n" #~ "Başlık yorumu şablonunu --template değişkenini kullanarak " #~ "değiştirebilirsiniz. Bir Jinja2 şablonunu .reuse/templates/mytemplate." #~ "jinja2 içerisine koyun. Şablonu '--template mytemplate' şeklinde " #~ "kullanabilirsiniz. Bu özelliği nasıl kullanabileceğinizi çevrimiçi " #~ "belgelerden öğrenebilirsiniz.\n" #~ "\n" #~ "Eğer ikili bir dosya tespit edilirse veya eğer --explicit-license " #~ "tanımlıysa, başlık .license dosyasına koyulacaktır." #~ msgid "" #~ "Download a license and place it in the LICENSES/ directory.\n" #~ "\n" #~ "The LICENSES/ directory is automatically found in the following order:\n" #~ "\n" #~ "- The LICENSES/ directory in the root of the VCS repository.\n" #~ "\n" #~ "- The current directory if its name is LICENSES.\n" #~ "\n" #~ "- The LICENSES/ directory in the current directory.\n" #~ "\n" #~ "If the LICENSES/ directory cannot be found, one is simply created." #~ msgstr "" #~ "Bir lisans indirir ve LICENSES/ dizinine yerleştirir.\n" #~ "\n" #~ "LICENSES/ dizini şu sırayla otomatik olarak aranır:\n" #~ "\n" #~ "- VCS deposunun kökündeki LICENSES/ dizini\n" #~ "\n" #~ "- Eğer ismi LICENSES ise mevcut dizin\n" #~ "\n" #~ "- Mevcut dizindeki LICENSES/ dizini\n" #~ "\n" #~ "Eğer LICENSES/ dizini bulunamazsa, yeni bir tane oluşturulur." #~ msgid ".reuse/dep5 has syntax errors" #~ msgstr ".reuse/dep5 sözdizim hataları içeriyor" #~ msgid "optional arguments" #~ msgstr "isteğe bağlı değişkenler" #~ msgid "deprecated in favor of annotate" #~ msgstr "annotate için kullanımdan kaldırıldı" #~ msgid "'reuse addheader' has been deprecated in favour of 'reuse annotate'" #~ msgstr "'reuse addheader', 'reuse annotate' adına kullanımdan kaldırıldı" #~ msgid "option --exclude-year and --year are mutually exclusive" #~ msgstr "--exclude-year ve --year seçeneklerinden biri olmalıdır" #~ msgid "option --single-line and --multi-line are mutually exclusive" #~ msgstr "--single-line ve --multi-line seçeneklerinden biri olmalıdır" #~ msgid "" #~ "--explicit-license has been deprecated in favour of --force-dot-license" #~ msgstr "" #~ "--explicit-license, --force-dot-license adına kullanımdan kaldırıldı" #~ msgid "Downloading {}" #~ msgstr "{} indiriliyor" #, fuzzy #~ msgid "conflicting subparser: %s" #~ msgstr "çelişkili seçenek karakter dizisi: %s" #, fuzzy #~ msgid "conflicting subparser alias: %s" #~ msgstr "çelişkili seçenek karakter dizisi: %s" #~ msgid "can't open '%s': %s" #~ msgstr "'%s' açılamıyor: %s" #~ msgid "place header in path.license instead of path" #~ msgstr "başlığı path yerine path.license içerisine koy" #~ msgid "could not find Git" #~ msgstr "Git bulunamadı" reuse-tool-4.0.3/po/uk.po000066400000000000000000001463701464275211500152330ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # SPDX-License-Identifier: GPL-3.0-or-later # msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-07-03 13:09+0000\n" "PO-Revision-Date: 2024-07-02 21:10+0000\n" "Last-Translator: Hotripak \n" "Language-Team: Ukrainian \n" "Language: uk\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && " "n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" "X-Generator: Weblate 5.7-dev\n" #: src/reuse/_annotate.py:74 #, python-brace-format msgid "" "'{path}' does not support single-line comments, please do not use --single-" "line" msgstr "" "'{path}' не підтримує однорядкові коментарі, не використовуйте --single-line" #: src/reuse/_annotate.py:81 #, python-brace-format msgid "" "'{path}' does not support multi-line comments, please do not use --multi-line" msgstr "" "'{path}' не підтримує багаторядкові коментарі, не використовуйте --multi-line" #: src/reuse/_annotate.py:136 #, python-brace-format msgid "Skipped unrecognised file '{path}'" msgstr "Пропущено нерозпізнаний файл '{path}'" #: src/reuse/_annotate.py:142 #, python-brace-format msgid "'{path}' is not recognised; creating '{path}.license'" msgstr "'{path}' не розпізнано; створення '{path}.license'" #: src/reuse/_annotate.py:158 #, python-brace-format msgid "Skipped file '{path}' already containing REUSE information" msgstr "Пропущений файл '{path}' вже містить інформацію REUSE" #: src/reuse/_annotate.py:192 #, python-brace-format msgid "Error: Could not create comment for '{path}'" msgstr "Помилка: не вдалося створити коментар для '{path}'" #: src/reuse/_annotate.py:199 #, python-brace-format msgid "" "Error: Generated comment header for '{path}' is missing copyright lines or " "license expressions. The template is probably incorrect. Did not write new " "header." msgstr "" "Помилка: у згенерованому заголовку коментаря для '{path}' відсутні рядки " "авторських прав або вирази ліцензії. Шаблон, ймовірно, неправильний. Не " "записано новий заголовок." #. TODO: This may need to be rephrased more elegantly. #: src/reuse/_annotate.py:210 #, python-brace-format msgid "Successfully changed header of {path}" msgstr "Успішно змінено заголовок {path}" #: src/reuse/_annotate.py:221 msgid "--skip-unrecognised has no effect when used together with --style" msgstr "--skip-unrecognised не працює разом із --style" #: src/reuse/_annotate.py:231 msgid "option --contributor, --copyright or --license is required" msgstr "потрібен параметр --contributor, --copyright або --license" #: src/reuse/_annotate.py:272 #, python-brace-format msgid "template {template} could not be found" msgstr "не вдалося знайти шаблон {template}" #: src/reuse/_annotate.py:341 src/reuse/_util.py:573 msgid "can't write to '{}'" msgstr "неможливо записати в '{}'" #: src/reuse/_annotate.py:366 msgid "" "The following files do not have a recognised file extension. Please use --" "style, --force-dot-license, --fallback-dot-license, or --skip-unrecognised:" msgstr "" "Наступні файли не мають розпізнаного файлового розширення. Будь ласка, " "використовуйте --style, --force-dot-license, --fallback-dot-license або --" "skip-unrecognised:" #: src/reuse/_annotate.py:382 msgid "copyright statement, repeatable" msgstr "оголошення авторського права, повторюване" #: src/reuse/_annotate.py:389 msgid "SPDX Identifier, repeatable" msgstr "Ідентифікатор SPDX, повторюваний" #: src/reuse/_annotate.py:395 msgid "file contributor, repeatable" msgstr "співавтор файлу, повторюваний" #: src/reuse/_annotate.py:403 msgid "year of copyright statement, optional" msgstr "рік оголошення авторського права, необов'язково" #: src/reuse/_annotate.py:411 msgid "comment style to use, optional" msgstr "використовуваний стиль коментарів, необов'язковий" #: src/reuse/_annotate.py:417 msgid "copyright prefix to use, optional" msgstr "префікс авторського права для користування, опціонально" #: src/reuse/_annotate.py:430 msgid "name of template to use, optional" msgstr "використовувана назва шаблону, необов'язково" #: src/reuse/_annotate.py:435 msgid "do not include year in statement" msgstr "не включати рік в оголошення" #: src/reuse/_annotate.py:440 msgid "merge copyright lines if copyright statements are identical" msgstr "" "об’єднувати рядки авторських прав, якщо оголошення авторських прав ідентичні" #: src/reuse/_annotate.py:446 msgid "force single-line comment style, optional" msgstr "примусовий однорядковий стиль коментаря, необов'язково" #: src/reuse/_annotate.py:451 msgid "force multi-line comment style, optional" msgstr "примусовий багаторядковий стиль коментарів, необов'язково" #: src/reuse/_annotate.py:458 msgid "add headers to all files under specified directories recursively" msgstr "рекурсивно додавати заголовки до всіх файлів у вказаних каталогах" #: src/reuse/_annotate.py:465 msgid "do not replace the first header in the file; just add a new one" msgstr "не замінювати перший заголовок у файлі; просто додавати новий" #: src/reuse/_annotate.py:473 msgid "always write a .license file instead of a header inside the file" msgstr "завжди записуйте файл .license замість заголовка всередині файлу" #: src/reuse/_annotate.py:480 msgid "write a .license file to files with unrecognised comment styles" msgstr "дописати файл .license до файлів з нерозпізнаними стилями коментарів" #: src/reuse/_annotate.py:486 msgid "skip files with unrecognised comment styles" msgstr "пропускати файли з нерозпізнаними стилями коментарів" #: src/reuse/_annotate.py:497 msgid "skip files that already contain REUSE information" msgstr "пропускати файли, які вже містять інформацію REUSE" #: src/reuse/_annotate.py:532 #, python-brace-format msgid "'{path}' is a binary, therefore using '{new_path}' for the header" msgstr "" "'{path}' — це двійковий файл, тому для заголовка використовується " "'{new_path}'" #: src/reuse/_main.py:39 msgid "" "reuse is a tool for compliance with the REUSE recommendations. See for more information, and " "for the online documentation." msgstr "" "reuse — це засіб для дотримання порад REUSE. Перегляньте для отримання додаткових відомостей і перегляду онлайн-документації." #: src/reuse/_main.py:45 msgid "" "This version of reuse is compatible with version {} of the REUSE " "Specification." msgstr "Ця версія reuse сумісна з версією {} специфікації REUSE." #: src/reuse/_main.py:48 msgid "Support the FSFE's work:" msgstr "Підтримати роботу FSFE:" #: src/reuse/_main.py:52 msgid "" "Donations are critical to our strength and autonomy. They enable us to " "continue working for Free Software wherever necessary. Please consider " "making a donation at ." msgstr "" "Внески мають вирішальне значення для нашої стійкості й незалежності. Вони " "дають нам змогу продовжувати працювати над вільним програмним забезпеченням, " "де це необхідно. Будь ласка, розгляньте можливість підтримати нас на " "." #: src/reuse/_main.py:75 msgid "enable debug statements" msgstr "увімкнути інструкції налагодження" #: src/reuse/_main.py:80 msgid "hide deprecation warnings" msgstr "сховати попередження про застарілість" #: src/reuse/_main.py:85 msgid "do not skip over Git submodules" msgstr "не пропускати підмодулі Git" #: src/reuse/_main.py:90 msgid "do not skip over Meson subprojects" msgstr "не пропускати підпроєкти Meson" #: src/reuse/_main.py:95 msgid "do not use multiprocessing" msgstr "не використовувати багатопроцесорність" #: src/reuse/_main.py:102 msgid "define root of project" msgstr "визначити кореневий каталог проєкту" #: src/reuse/_main.py:107 msgid "show program's version number and exit" msgstr "показати номер версії програми та вийти" #: src/reuse/_main.py:111 msgid "subcommands" msgstr "підкоманди" #: src/reuse/_main.py:118 msgid "add copyright and licensing into the header of files" msgstr "додати авторські права та ліцензії в заголовок файлів" #: src/reuse/_main.py:121 msgid "" "Add copyright and licensing into the header of one or more files.\n" "\n" "By using --copyright and --license, you can specify which copyright holders " "and licenses to add to the headers of the given files.\n" "\n" "By using --contributor, you can specify people or entity that contributed " "but are not copyright holder of the given files." msgstr "" "Додайте інформацію про авторські права та ліцензування в заголовок одного " "або декількох файлів.\n" "\n" " За допомогою --copyright і --license ви можете вказати, яких власників " "авторських прав і ліцензій додавати до заголовків цих файлів.\n" "\n" " За допомогою --contributor ви можете вказати особу або організацію, яка " "зробила внесок, але не є власником авторських прав на дані файли." #: src/reuse/_main.py:140 msgid "download a license and place it in the LICENSES/ directory" msgstr "завантажити ліцензію та розмістити її в каталозі LICENSES/" #: src/reuse/_main.py:142 msgid "Download a license and place it in the LICENSES/ directory." msgstr "Завантажте ліцензію та помістіть її в папку LICENSES/." #: src/reuse/_main.py:151 msgid "list all non-compliant files" msgstr "список усіх несумісних файлів" #: src/reuse/_main.py:154 #, python-brace-format msgid "" "Lint the project directory for compliance with version {reuse_version} of " "the REUSE Specification. You can find the latest version of the " "specification at .\n" "\n" "Specifically, the following criteria are checked:\n" "\n" "- Are there any bad (unrecognised, not compliant with SPDX) licenses in the " "project?\n" "\n" "- Are any licenses referred to inside of the project, but not included in " "the LICENSES/ directory?\n" "\n" "- Are any licenses included in the LICENSES/ directory that are not used " "inside of the project?\n" "\n" "- Do all files have valid copyright and licensing information?" msgstr "" "Перевірте каталог проєкту на відповідність версії {reuse_version} " "специфікації REUSE. Ви можете знайти останню версію специфікації за адресою " ".\n" "\n" "Зокрема, перевіряються такі критерії:\n" "\n" "- Чи є в проєкті погані (нерозпізнані, несумісні з SPDX) ліцензії?\n" "\n" "- Чи є ліцензії, які згадуються всередині проєкту, але не включені в каталог " "LICENSES/?\n" "\n" "- Чи включені будь-які ліцензії в каталог LICENSES/, які не використовуються " "всередині проєкту?\n" "\n" "- Чи всі файли мають дійсні відомості про авторські права та ліцензії?" #: src/reuse/_main.py:181 msgid "print the project's bill of materials in SPDX format" msgstr "друкувати опис матеріалів проєкту у форматі SPDX" #: src/reuse/_main.py:189 msgid "list all supported SPDX licenses" msgstr "список всіх підтримуваних ліцензій SPDX" #: src/reuse/_main.py:198 msgid "convert .reuse/dep5 to REUSE.toml" msgstr "конвертувати .reuse/dep5 у REUSE.toml" #: src/reuse/_main.py:263 #, python-brace-format msgid "'{path}' could not be decoded as UTF-8." msgstr "'{path}' не може бути декодовано як UTF-8." #: src/reuse/_main.py:269 #, python-brace-format msgid "" "'{path}' could not be parsed. We received the following error message: " "{message}" msgstr "" "'{path}' не вдалося розібрати. Ми отримали наступне повідомлення про " "помилку: {message}" #: src/reuse/_util.py:368 src/reuse/global_licensing.py:218 #, python-brace-format msgid "Could not parse '{expression}'" msgstr "Не вдалося проаналізувати '{expression}'" #: src/reuse/_util.py:424 #, python-brace-format msgid "" "'{path}' holds an SPDX expression that cannot be parsed, skipping the file" msgstr "" "'{path}' містить вираз SPDX, який неможливо проаналізувати, пропуск файлу" #: src/reuse/_util.py:556 msgid "'{}' is not a file" msgstr "'{}' не є файлом" #: src/reuse/_util.py:559 msgid "'{}' is not a directory" msgstr "'{}' не є каталогом" #: src/reuse/_util.py:562 msgid "can't open '{}'" msgstr "не вдалося відкрити '{}'" #: src/reuse/_util.py:567 msgid "can't write to directory '{}'" msgstr "неможливо записати в каталог '{}'" #: src/reuse/_util.py:586 msgid "can't read or write '{}'" msgstr "неможливо прочитати чи записати '{}'" #: src/reuse/_util.py:596 msgid "'{}' is not a valid SPDX expression, aborting" msgstr "'{}' не є дійсним виразом SPDX, переривання" #: src/reuse/_util.py:624 msgid "'{}' is not a valid SPDX License Identifier." msgstr "'{}' не є дійсним ідентифікатором ліцензії SPDX." #: src/reuse/_util.py:631 msgid "Did you mean:" msgstr "Ви мали на увазі:" #: src/reuse/_util.py:638 msgid "" "See for a list of valid SPDX License " "Identifiers." msgstr "" "Перегляньте список дійсних ідентифікаторів " "ліцензії SPDX." #: src/reuse/convert_dep5.py:118 msgid "no '.reuse/dep5' file" msgstr "немає файлу '.reuse/dep5" #: src/reuse/download.py:130 msgid "SPDX License Identifier of license" msgstr "Ідентифікатор ліцензії SPDX" #: src/reuse/download.py:135 msgid "download all missing licenses detected in the project" msgstr "завантажити всі відсутні ліцензії, виявлені в проєкті" #: src/reuse/download.py:145 msgid "" "source from which to copy custom LicenseRef- licenses, either a directory " "that contains the file or the file itself" msgstr "" "джерело, з якого можна скопіювати користувацькі ліцензії LicenseRef-, або " "каталог, який містить файл, або сам файл" #: src/reuse/download.py:156 #, python-brace-format msgid "Error: {spdx_identifier} already exists." msgstr "Помилка: {spdx_identifier} вже існує." #: src/reuse/download.py:163 #, python-brace-format msgid "Error: {path} does not exist." msgstr "Помилка: {path} не існує." #: src/reuse/download.py:166 msgid "Error: Failed to download license." msgstr "Помилка: не вдалося завантажити ліцензію." #: src/reuse/download.py:171 msgid "Is your internet connection working?" msgstr "Чи працює ваше інтернет-з'єднання?" #: src/reuse/download.py:176 #, python-brace-format msgid "Successfully downloaded {spdx_identifier}." msgstr "Успішно завантажено {spdx_identifier}." #: src/reuse/download.py:188 msgid "--output has no effect when used together with --all" msgstr "--output не працює разом з --all" #: src/reuse/download.py:192 msgid "the following arguments are required: license" msgstr "необхідні такі аргументи: license" #: src/reuse/download.py:194 msgid "cannot use --output with more than one license" msgstr "не можна використовувати --output з кількома ліцензіями" #: src/reuse/global_licensing.py:109 #, python-brace-format msgid "" "{attr_name} must be a {type_name} (got {value} that is a {value_class})." msgstr "" "{attr_name} має бути {type_name} (отримано {value}, що є {value_class})." #: src/reuse/global_licensing.py:122 #, python-brace-format msgid "" "Item in {attr_name} collection must be a {type_name} (got {item_value} that " "is a {item_class})." msgstr "" "Елемент у колекції {attr_name} має бути {type_name} (отримав {item_value}, " "що є {item_class})." #: src/reuse/global_licensing.py:133 #, python-brace-format msgid "{attr_name} must not be empty." msgstr "{attr_name} не повинне бути порожнім." #: src/reuse/global_licensing.py:156 #, python-brace-format msgid "{name} must be a {type} (got {value} that is a {value_type})." msgstr "{name} має бути {type} (отримано {value}, яке є {value_type})." #: src/reuse/global_licensing.py:179 #, python-brace-format msgid "" "The value of 'precedence' must be one of {precedence_vals} (got {received})" msgstr "" "Значення 'precedence' має бути одним з {precedence_vals} (отримано " "{received})" #: src/reuse/header.py:99 msgid "generated comment is missing copyright lines or license expressions" msgstr "" "у згенерованому коментарі відсутні рядки про авторські права або вирази " "ліцензії" #: src/reuse/lint.py:30 msgid "prevents output" msgstr "запобігає виводу" #: src/reuse/lint.py:33 msgid "formats output as JSON" msgstr "форматує вивід як JSON" #: src/reuse/lint.py:39 msgid "formats output as plain text" msgstr "форматує вивід як звичайний текст" #: src/reuse/lint.py:45 msgid "formats output as errors per line" msgstr "форматує вивід у вигляді помилок на рядок" #: src/reuse/lint.py:64 msgid "BAD LICENSES" msgstr "ПОГАНІ ЛІЦЕНЗІЇ" #: src/reuse/lint.py:66 src/reuse/lint.py:95 msgid "'{}' found in:" msgstr "'{}' знайдено в:" #: src/reuse/lint.py:73 msgid "DEPRECATED LICENSES" msgstr "ЗАСТАРІЛІ ЛІЦЕНЗІЇ" #: src/reuse/lint.py:75 msgid "The following licenses are deprecated by SPDX:" msgstr "У SPDX застаріли такі ліцензії:" #: src/reuse/lint.py:83 msgid "LICENSES WITHOUT FILE EXTENSION" msgstr "ЛІЦЕНЗІЇ БЕЗ РОЗШИРЕННЯ ФАЙЛУ" #: src/reuse/lint.py:85 msgid "The following licenses have no file extension:" msgstr "Ці ліцензії не мають розширення файлу:" #: src/reuse/lint.py:93 msgid "MISSING LICENSES" msgstr "ВІДСУТНІ ЛІЦЕНЗІЇ" #: src/reuse/lint.py:102 msgid "UNUSED LICENSES" msgstr "НЕВИКОРИСТАНІ ЛІЦЕНЗІЇ" #: src/reuse/lint.py:103 msgid "The following licenses are not used:" msgstr "Не використовуються такі ліцензії:" #: src/reuse/lint.py:110 msgid "READ ERRORS" msgstr "ПОМИЛКИ ЧИТАННЯ" #: src/reuse/lint.py:111 msgid "Could not read:" msgstr "Не вдалося прочитати:" #: src/reuse/lint.py:132 msgid "MISSING COPYRIGHT AND LICENSING INFORMATION" msgstr "ВІДСУТНІ ВІДОМОСТІ ПРО АВТОРСЬКІ ПРАВА ТА ЛІЦЕНЗУВАННЯ" #: src/reuse/lint.py:138 msgid "The following files have no copyright and licensing information:" msgstr "Ці файли не містять відомостей про авторські права та ліцензії:" #: src/reuse/lint.py:149 msgid "The following files have no copyright information:" msgstr "Такі файли не містять відомостей про авторські права:" #: src/reuse/lint.py:158 msgid "The following files have no licensing information:" msgstr "Такі файли не мають відомостей про ліцензування:" #: src/reuse/lint.py:166 msgid "SUMMARY" msgstr "ПІДСУМОК" #: src/reuse/lint.py:171 msgid "Bad licenses:" msgstr "Погані ліцензії:" #: src/reuse/lint.py:172 msgid "Deprecated licenses:" msgstr "Застарілі ліцензії:" #: src/reuse/lint.py:173 msgid "Licenses without file extension:" msgstr "Ліцензії без розширення файлу:" #: src/reuse/lint.py:176 msgid "Missing licenses:" msgstr "Відсутні ліцензії:" #: src/reuse/lint.py:177 msgid "Unused licenses:" msgstr "Невикористані ліцензії:" #: src/reuse/lint.py:178 msgid "Used licenses:" msgstr "Використані ліцензії:" #: src/reuse/lint.py:179 msgid "Read errors:" msgstr "Помилки читання:" #: src/reuse/lint.py:181 msgid "Files with copyright information:" msgstr "Файли з інформацією про авторські права:" #: src/reuse/lint.py:185 msgid "Files with license information:" msgstr "Файли з інформацією про ліцензію:" #: src/reuse/lint.py:202 msgid "" "Congratulations! Your project is compliant with version {} of the REUSE " "Specification :-)" msgstr "Вітаємо! Ваш проєкт відповідає версії {} специфікації REUSE :-)" #: src/reuse/lint.py:209 msgid "" "Unfortunately, your project is not compliant with version {} of the REUSE " "Specification :-(" msgstr "На жаль, ваш проєкт не сумісний із версією {} специфікації REUSE :-(" #: src/reuse/lint.py:216 msgid "RECOMMENDATIONS" msgstr "РЕКОМЕНДАЦІЇ" #: src/reuse/lint.py:289 #, python-brace-format msgid "{path}: bad license {lic}\n" msgstr "{path}: bad license {lic}\n" #: src/reuse/lint.py:296 #, python-brace-format msgid "{lic_path}: deprecated license\n" msgstr "{lic_path}: застаріла ліцензія\n" #: src/reuse/lint.py:303 #, python-brace-format msgid "{lic_path}: license without file extension\n" msgstr "{lic_path}: ліцензія без розширення файлу\n" #: src/reuse/lint.py:312 #, python-brace-format msgid "{lic_path}: unused license\n" msgstr "{lic_path}: невикористана ліцензія\n" #: src/reuse/lint.py:319 #, python-brace-format msgid "{path}: missing license {lic}\n" msgstr "{path}: зникла ліцензія {lic}\n" #: src/reuse/lint.py:326 #, python-brace-format msgid "{path}: read error\n" msgstr "{path}: помилка читання\n" #: src/reuse/lint.py:330 #, python-brace-format msgid "{path}: no license identifier\n" msgstr "{path}: немає ідентифікатора ліцензії\n" #: src/reuse/lint.py:334 #, python-brace-format msgid "{path}: no copyright notice\n" msgstr "{path}: без повідомлення про авторське право\n" #: src/reuse/project.py:262 #, python-brace-format msgid "'{path}' covered by {global_path}" msgstr "'{path}' покрито за рахунок {global_path}" #: src/reuse/project.py:270 #, python-brace-format msgid "" "'{path}' is covered exclusively by REUSE.toml. Not reading the file contents." msgstr "'{path}' покрито виключно файлом REUSE.toml. Не читаючи вміст файлу." #: src/reuse/project.py:277 #, python-brace-format msgid "" "'{path}' was detected as a binary file; not searching its contents for REUSE " "information." msgstr "" "'{path}' виявлено як двійковий файл або його розширення позначено таким, що " "не коментується; пошук інформації у його вмісті для REUSE не виконується." #: src/reuse/project.py:334 msgid "" "'.reuse/dep5' is deprecated. You are recommended to instead use REUSE.toml. " "Use `reuse convert-dep5` to convert." msgstr "" "'.reuse/dep5' є застарілим. Замість нього рекомендовано використовувати " "REUSE.toml. Для перетворення використовуйте `reuse convert-dep5`." #: src/reuse/project.py:348 #, python-brace-format msgid "" "Found both '{new_path}' and '{old_path}'. You cannot keep both files " "simultaneously; they are not intercompatible." msgstr "" "Знайдено як '{new_path}', так і '{old_path}'. Ви не можете зберігати обидва " "файли одночасно, вони несумісні." #: src/reuse/project.py:414 #, python-brace-format msgid "determining identifier of '{path}'" msgstr "визначення ідентифікатора '{path}'" #: src/reuse/project.py:422 #, python-brace-format msgid "{path} does not have a file extension" msgstr "{path} не має розширення файлу" #: src/reuse/project.py:432 #, python-brace-format msgid "" "Could not resolve SPDX License Identifier of {path}, resolving to " "{identifier}. Make sure the license is in the license list found at or that it starts with 'LicenseRef-', and that it has a " "file extension." msgstr "" "Не вдалося розпізнати ідентифікатор ліцензії SPDX {path}. Його розв'язано як " "{identifier}. Переконайтеся, що ліцензія є у списку ліцензій на або що вона починається з 'LicenseRef-' і має розширення " "файлу." #: src/reuse/project.py:444 #, python-brace-format msgid "" "{identifier} is the SPDX License Identifier of both {path} and {other_path}" msgstr "" "{identifier} — це ідентифікатор ліцензії SPDX для {path} і {other_path}" #: src/reuse/project.py:483 msgid "" "project '{}' is not a VCS repository or required VCS software is not " "installed" msgstr "" "проєкт '{}' не є репозиторієм VCS або потрібне програмне забезпечення VCS не " "встановлено" #: src/reuse/report.py:310 #, python-brace-format msgid "Could not read '{path}'" msgstr "Не вдалося прочитати '{path}'" #: src/reuse/report.py:317 #, python-brace-format msgid "Unexpected error occurred while parsing '{path}'" msgstr "Під час аналізу '{path}' сталася неочікувана помилка" #: src/reuse/report.py:438 msgid "" "Fix bad licenses: At least one license in the LICENSES directory and/or " "provided by 'SPDX-License-Identifier' tags is invalid. They are either not " "valid SPDX License Identifiers or do not start with 'LicenseRef-'. FAQ about " "custom licenses: https://reuse.software/faq/#custom-license" msgstr "" "Виправте недійсні ліцензії: Принаймні одна ліцензія в директорії LICENSES та/" "або вказана у тегах 'SPDX-License-Identifier' недійсна. Вони або не мають " "дійсних ідентифікаторів ліцензій SPDX, або не починаються з 'LicenseRef-'. " "Часті запитання про користувацькі ліцензії: https://reuse.software/faq/" "#custom-license" #: src/reuse/report.py:449 msgid "" "Fix deprecated licenses: At least one of the licenses in the LICENSES " "directory and/or provided by an 'SPDX-License-Identifier' tag or in '.reuse/" "dep5' has been deprecated by SPDX. The current list and their respective " "recommended new identifiers can be found here: " msgstr "" "Виправте застарілі ліцензії: Принаймні одна з ліцензій у каталозі LICENSES " "та/або зазначена у тезі 'SPDX-License-Identifier' або у файлі '.reuse/dep5' " "застаріла для SPDX. Поточний список і відповідні рекомендовані нові " "ідентифікатори можна знайти тут: " #: src/reuse/report.py:460 msgid "" "Fix licenses without file extension: At least one license text file in the " "'LICENSES' directory does not have a '.txt' file extension. Please rename " "the file(s) accordingly." msgstr "" "Виправте ліцензії без розширення файлів: Принаймні один текстовий файл " "ліцензії в директорії 'LICENSES' не має розширення '.txt'. Перейменуйте " "файл(и) відповідно." #: src/reuse/report.py:469 msgid "" "Fix missing licenses: For at least one of the license identifiers provided " "by the 'SPDX-License-Identifier' tags, there is no corresponding license " "text file in the 'LICENSES' directory. For SPDX license identifiers, you can " "simply run 'reuse download --all' to get any missing ones. For custom " "licenses (starting with 'LicenseRef-'), you need to add these files yourself." msgstr "" "Виправте відсутні ліцензії: Принаймні для одного з ідентифікаторів ліцензій, " "зазначених у тегах 'SPDX-License-Identifier', у директорії 'LICENSES' " "відсутній відповідний текстовий файл ліцензії. Для ідентифікаторів ліцензій " "SPDX ви можете просто виконати команду 'reuse download --all', щоб отримати " "будь-які відсутні ідентифікатори. Для користувацьких ліцензій (починаючи з " "'LicenseRef-') вам потрібно додати ці файли самостійно." #: src/reuse/report.py:481 msgid "" "Fix unused licenses: At least one of the license text files in 'LICENSES' is " "not referenced by any file, e.g. by an 'SPDX-License-Identifier' tag. Please " "make sure that you either tag the accordingly licensed files properly, or " "delete the unused license text if you are sure that no file or code snippet " "is licensed as such." msgstr "" "Виправте невикористані ліцензії: Принаймні на один з файлів з текстом " "ліцензії у 'LICENSES' немає жодного посилання, наприклад, за допомогою тегу " "'SPDX-License-Identifier'. Переконайтеся, що ви або правильно позначили " "відповідні ліцензовані файли, або видаліть невикористаний текст ліцензії, " "якщо ви впевнені, що жоден файл або фрагмент коду не ліцензований як такий." #: src/reuse/report.py:492 msgid "" "Fix read errors: At least one of the files in your directory cannot be read " "by the tool. Please check the file permissions. You will find the affected " "files at the top of the output as part of the logged error messages." msgstr "" "Виправте помилки читання: Принаймні один з файлів у вашій директорії не може " "бути прочитаний інструментом. Перевірте права доступу до файлів. Ви знайдете " "відповідні файли у верхній частині виводу як частину зареєстрованих " "повідомлень про помилки." #: src/reuse/report.py:501 msgid "" "Fix missing copyright/licensing information: For one or more files, the tool " "cannot find copyright and/or licensing information. You typically do this by " "adding 'SPDX-FileCopyrightText' and 'SPDX-License-Identifier' tags to each " "file. The tutorial explains additional ways to do this: " msgstr "" "Виправте відсутню інформацію про авторські права/ліцензування: Для одного " "або кількох файлів інструмент не може знайти інформацію про авторські права " "та/або ліцензування. Зазвичай це можна зробити, додавши до кожного файлу " "теги 'SPDX-FileCopyrightText' і 'SPDX-License-Identifier'. У довіднику " "описано інші способи зробити це: " #: src/reuse/spdx.py:32 msgid "" "populate the LicenseConcluded field; note that reuse cannot guarantee the " "field is accurate" msgstr "" "заповніть поле LicenseConcluded; зауважте, що повторне використання не може " "гарантувати точність поля" #: src/reuse/spdx.py:39 msgid "name of the person signing off on the SPDX report" msgstr "ім'я особи, яка підписує звіт SPDX" #: src/reuse/spdx.py:44 msgid "name of the organization signing off on the SPDX report" msgstr "назва організації, яка підписує звіт SPDX" #: src/reuse/spdx.py:60 msgid "" "error: --creator-person=NAME or --creator-organization=NAME required when --" "add-license-concluded is provided" msgstr "" "помилка: --creator-person=NAME або --creator-organization=NAME вимагається, " "якщо надається --add-license-concluded" #: src/reuse/spdx.py:75 #, python-brace-format msgid "" "'{path}' does not match a common SPDX file pattern. Find the suggested " "naming conventions here: https://spdx.github.io/spdx-spec/conformance/#44-" "standard-data-format-requirements" msgstr "" "'{path}' не відповідає загальному шаблону файлу SPDX. Знайдіть запропоновані " "правила іменування тут: https://spdx.github.io/spdx-spec/conformance/#44-" "standard-data-format-requirements" #: /usr/lib/python3.10/argparse.py:308 msgid "usage: " msgstr "використання: " #: /usr/lib/python3.10/argparse.py:880 msgid ".__call__() not defined" msgstr ".__call__() не визначено" #: /usr/lib/python3.10/argparse.py:1223 #, python-format msgid "unknown parser %(parser_name)r (choices: %(choices)s)" msgstr "невідомий парсер %(parser_name)r (варто вибрати: %(choices)s)" #: /usr/lib/python3.10/argparse.py:1283 #, python-format msgid "argument \"-\" with mode %r" msgstr "аргумент \"-\" з режимом %r" #: /usr/lib/python3.10/argparse.py:1292 #, python-format msgid "can't open '%(filename)s': %(error)s" msgstr "не вдалося відкрити '%(filename)s': %(error)s" #: /usr/lib/python3.10/argparse.py:1501 #, python-format msgid "cannot merge actions - two groups are named %r" msgstr "не вдалося об'єднати дії - дві групи називаються %r" #: /usr/lib/python3.10/argparse.py:1539 msgid "'required' is an invalid argument for positionals" msgstr "'required' — неприпустимий аргумент для позиційних значень" #: /usr/lib/python3.10/argparse.py:1561 #, python-format msgid "" "invalid option string %(option)r: must start with a character " "%(prefix_chars)r" msgstr "" "недійсний рядок опцій %(option)r: має починатися з символу %(prefix_chars)r" #: /usr/lib/python3.10/argparse.py:1579 #, python-format msgid "dest= is required for options like %r" msgstr "dest= потрібен для таких опцій, як %r" #: /usr/lib/python3.10/argparse.py:1596 #, python-format msgid "invalid conflict_resolution value: %r" msgstr "недійсне значення conflict_resolution: %r" #: /usr/lib/python3.10/argparse.py:1614 #, python-format msgid "conflicting option string: %s" msgid_plural "conflicting option strings: %s" msgstr[0] "конфліктний рядок опцій: %s" msgstr[1] "конфліктні рядки опцій: %s" msgstr[2] "конфліктні рядки опцій: %s" #: /usr/lib/python3.10/argparse.py:1680 msgid "mutually exclusive arguments must be optional" msgstr "взаємозаперечні аргументи повинні бути необов'язковими" #: /usr/lib/python3.10/argparse.py:1748 msgid "positional arguments" msgstr "позиційні аргументи" #: /usr/lib/python3.10/argparse.py:1749 msgid "options" msgstr "параметри" #: /usr/lib/python3.10/argparse.py:1764 msgid "show this help message and exit" msgstr "показати це повідомлення та вийти" #: /usr/lib/python3.10/argparse.py:1795 msgid "cannot have multiple subparser arguments" msgstr "не може мати кілька аргументів підпарсера" #: /usr/lib/python3.10/argparse.py:1847 /usr/lib/python3.10/argparse.py:2362 #, python-format msgid "unrecognized arguments: %s" msgstr "нерозпізнані аргументи: %s" #: /usr/lib/python3.10/argparse.py:1948 #, python-format msgid "not allowed with argument %s" msgstr "не дозволено з аргументом %s" #: /usr/lib/python3.10/argparse.py:1998 /usr/lib/python3.10/argparse.py:2012 #, python-format msgid "ignored explicit argument %r" msgstr "нехтується явний аргумент %r" #: /usr/lib/python3.10/argparse.py:2119 #, python-format msgid "the following arguments are required: %s" msgstr "такі аргументи обов'язкові: %s" #: /usr/lib/python3.10/argparse.py:2134 #, python-format msgid "one of the arguments %s is required" msgstr "один з аргументів %s обов'язковий" #: /usr/lib/python3.10/argparse.py:2177 msgid "expected one argument" msgstr "очікується один аргумент" #: /usr/lib/python3.10/argparse.py:2178 msgid "expected at most one argument" msgstr "очікується щонайбільше один аргумент" #: /usr/lib/python3.10/argparse.py:2179 msgid "expected at least one argument" msgstr "очікується хоча б один аргумент" #: /usr/lib/python3.10/argparse.py:2183 #, python-format msgid "expected %s argument" msgid_plural "expected %s arguments" msgstr[0] "очікується %s аргумент" msgstr[1] "очікується %s аргументи" msgstr[2] "очікується %s аргументів" #: /usr/lib/python3.10/argparse.py:2241 #, python-format msgid "ambiguous option: %(option)s could match %(matches)s" msgstr "неоднозначний параметр: %(option)s може відповідати %(matches)s" #: /usr/lib/python3.10/argparse.py:2305 #, python-format msgid "unexpected option string: %s" msgstr "неочікуваний рядок параметрів: %s" #: /usr/lib/python3.10/argparse.py:2502 #, python-format msgid "%r is not callable" msgstr "%r не можна викликати" #: /usr/lib/python3.10/argparse.py:2519 #, python-format msgid "invalid %(type)s value: %(value)r" msgstr "недійсне значення %(type)s: %(value)r" #: /usr/lib/python3.10/argparse.py:2530 #, python-format msgid "invalid choice: %(value)r (choose from %(choices)s)" msgstr "неприпустимий вибір: %(value)r (варто обрати з %(choices)s)" #: /usr/lib/python3.10/argparse.py:2606 #, python-format msgid "%(prog)s: error: %(message)s\n" msgstr "%(prog)s: помилка: %(message)s\n" #, python-brace-format #~ msgid "" #~ "Copyright and licensing information for '{original_path}' has been found " #~ "in both '{path}' and in the DEP5 file located at '{dep5_path}'. The " #~ "information for these two sources has been aggregated. You are " #~ "recommended to instead use REUSE.toml, where you can specify the order of " #~ "precedence. Use `reuse convert-dep5` to convert. Run with `--suppress-" #~ "deprecation` to hide this warning." #~ msgstr "" #~ "Інформацію про авторське право та ліцензування для '{original_path}' " #~ "знайдено як в '{path}', так і у файлі DEP5, розташованому за адресою " #~ "'{dep5_path}'. Інформація з цих двох джерел була об'єднана. Замість цього " #~ "рекомендовано використовувати REUSE.txt, де ви можете вказати порядок " #~ "пріоритету. Використовуйте `reuse convert-dep5` для перетворення. " #~ "Запустіть з `--suppress-deprecation`, щоб приховати це попередження." #~ msgid "initialize REUSE project" #~ msgstr "ініціалізувати проєкт REUSE" #~ msgid "no '{}' file, or could not read it" #~ msgstr "немає файлу '{}', або неможливо його прочитати" #~ msgid "" #~ "What license is your project under? Provide the SPDX License Identifier. " #~ "See for the list." #~ msgstr "" #~ "Якою ліцензією захищено ваш проєкт? Надайте ідентифікатор ліцензії SPDX. " #~ "Перегляньте список ." #~ msgid "" #~ "What other license is your project under? Provide the SPDX License " #~ "Identifier." #~ msgstr "" #~ "Якою ліцензією захищено ваш проєкт? Надайте ідентифікатор ліцензії SPDX." #~ msgid "To stop adding licenses, hit RETURN." #~ msgstr "Щоб припинити додавання ліцензій, натисніть RETURN." #~ msgid "Project already initialized" #~ msgstr "Проєкт уже ініціалізовано" #~ msgid "Initializing project for REUSE." #~ msgstr "Ініціалізація проєкту для REUSE." #~ msgid "What is the name of the project?" #~ msgstr "Як називається проєкт?" #~ msgid "What is the internet address of the project?" #~ msgstr "Яка інтернет-адреса проєкту?" #~ msgid "What is the name of the maintainer?" #~ msgstr "Як звуть супроводжувача?" #~ msgid "What is the e-mail address of the maintainer?" #~ msgstr "Яка адреса електронної пошти супровідника?" #~ msgid "All done! Initializing now." #~ msgstr "Усе готово! Відбувається ініціалізація." #~ msgid "Retrieving {}" #~ msgstr "Витягнення {}" #~ msgid "{} already exists" #~ msgstr "{} вже існує" #~ msgid "Could not download {}" #~ msgstr "Не вдалося завантажити {}" #, python-brace-format #~ msgid "" #~ "Error: Could not copy {path}, please add {lic}.txt manually in the " #~ "LICENCES/ directory." #~ msgstr "" #~ "Помилка: Не вдалося скопіювати {path}. Додайте {lic}.txt вручну до " #~ "директорії LICENCES/." #~ msgid "Initialization complete." #~ msgstr "Ініціалізація завершена." #~ msgid "" #~ "Add copyright and licensing into the header of one or more files.\n" #~ "\n" #~ "By using --copyright and --license, you can specify which copyright " #~ "holders and licenses to add to the headers of the given files.\n" #~ "\n" #~ "By using --contributor, you can specify people or entity that contributed " #~ "but are not copyright holder of the given files.\n" #~ "The first comment is replaced with a new header containing the new " #~ "copyright and licensing information and its former copyright and " #~ "licensing. If you want to keep the first comment intact, use --no-" #~ "replace.\n" #~ "\n" #~ "The comment style should be auto-detected for your files. If a comment " #~ "style could not be detected and --skip-unrecognised is not specified, the " #~ "process aborts. Use --style to specify or override the comment style to " #~ "use.\n" #~ "\n" #~ "A single-line comment style is used when it is available. If no single-" #~ "line comment style is available, a multi-line comment style is used. You " #~ "can force a certain comment style using --single-line or --multi-line.\n" #~ "\n" #~ "You can change the template of the header comment by using --template. " #~ "Place a Jinja2 template in .reuse/templates/mytemplate.jinja2. You can " #~ "use the template by specifying '--template mytemplate'. Read the online " #~ "documentation on how to use this feature.\n" #~ "\n" #~ "If a binary file is detected, or if --force-dot-license is specified, the " #~ "header is placed in a .license file." #~ msgstr "" #~ "Додайте відомості про авторські права та ліцензування в заголовок одного " #~ "або кількох файлів.\n" #~ "\n" #~ "За допомогою --copyright і --license ви можете вказати, яких власників " #~ "авторських прав і ліцензій слід додати до заголовків цих файлів.\n" #~ "\n" #~ "Використовуючи --contributor, ви можете вказати людей або організацію, " #~ "які зробили внесок, але не є власниками авторських прав на дані файли.\n" #~ "Перший коментар замінено новим заголовком, що містить нову інформацію про " #~ "авторське право та ліцензування, а також попередні авторські права та " #~ "ліцензування. Якщо ви хочете залишити перший коментар недоторканим, " #~ "використовуйте --no-replace.\n" #~ "\n" #~ "Стиль коментарів має бути визначено автоматично для ваших файлів. Якщо " #~ "стиль коментаря не вдалося визначити й не вказано --skip-unrecognised, " #~ "процес буде перервано. Використовуйте --style, щоб вказати або " #~ "перевизначити стиль коментування.\n" #~ "\n" #~ "Стиль однорядкового коментаря буде використано, якщо він доступний. Якщо " #~ "стиль однорядкового коментаря недоступний, використовується стиль " #~ "багаторядкового коментаря. Ви можете примусово застосувати певний стиль " #~ "коментарів за ljlfdib --single-line або --multi-line.\n" #~ "\n" #~ "Ви можете змінити шаблон заголовка коментаря за допомогою --template. " #~ "Помістіть шаблон Jinja2 до теки .reuse/templates/mytemplate.jinja2. Ви " #~ "можете використовувати шаблон, вказавши '--template mytemplate'. " #~ "Прочитайте онлайн-документацію про те, як користуватися цією функцією.\n" #~ "\n" #~ "Якщо виявлено двійковий файл або якщо вказано --force-dot-license, " #~ "заголовок буде розміщено у файлі .license." #~ msgid "" #~ "Download a license and place it in the LICENSES/ directory.\n" #~ "\n" #~ "The LICENSES/ directory is automatically found in the following order:\n" #~ "\n" #~ "- The LICENSES/ directory in the root of the VCS repository.\n" #~ "\n" #~ "- The current directory if its name is LICENSES.\n" #~ "\n" #~ "- The LICENSES/ directory in the current directory.\n" #~ "\n" #~ "If the LICENSES/ directory cannot be found, one is simply created." #~ msgstr "" #~ "Завантажте ліцензію та розмістіть її в каталозі LICENSES/.\n" #~ "\n" #~ "Каталог LICENSES/ автоматично розміщено в такому порядку:\n" #~ "\n" #~ "- Каталог LICENSES/ в корені репозиторію VCS.\n" #~ "\n" #~ "- Поточний каталог, якщо його назва - LICENSES.\n" #~ "\n" #~ "- Каталог LICENSES/ в поточному каталозі.\n" #~ "\n" #~ "Якщо каталог LICENSES/ не вдається знайти, він просто створюється." #~ msgid ".reuse/dep5 has syntax errors" #~ msgstr ".reuse/dep5 має синтаксичні помилки" #~ msgid "optional arguments" #~ msgstr "необов'язкові аргументи" #~ msgid "deprecated in favor of annotate" #~ msgstr "вилучено на користь анотації" #~ msgid "'reuse addheader' has been deprecated in favour of 'reuse annotate'" #~ msgstr "'reuse addheader' застаріло й замінено на 'reuse annotate'" #~ msgid "option --exclude-year and --year are mutually exclusive" #~ msgstr "параметр --exclude-year і --year взаємосуперечливі" #~ msgid "option --single-line and --multi-line are mutually exclusive" #~ msgstr "параметр --single-line і --multi-line взаємосуперечливі" #~ msgid "" #~ "--explicit-license has been deprecated in favour of --force-dot-license" #~ msgstr "--explicit-license замінено на --force-dot-license" #~ msgid "Downloading {}" #~ msgstr "Завантаження {}" #~ msgid "argument %(argument_name)s: %(message)s" #~ msgstr "аргумент %(argument_name)s: %(message)s" #~ msgid "conflicting subparser: %s" #~ msgstr "конфліктний субпарсер: %s" #~ msgid "conflicting subparser alias: %s" #~ msgstr "конфліктний псевдонім субпарсера: %s" #~ msgid "can't open '%s': %s" #~ msgstr "не вдалося відкрити '%s': %s" #~ msgid "could not find supported VCS" #~ msgstr "не вдалося знайти підтримуваний VCS" reuse-tool-4.0.3/poetry.lock000066400000000000000000003313261464275211500160270ustar00rootroot00000000000000# This file is automatically @generated by Poetry and should not be changed by hand. [[package]] name = "alabaster" version = "0.7.13" description = "A configurable sidebar-enabled Sphinx theme" category = "dev" optional = false python-versions = ">=3.6" files = [ {file = "alabaster-0.7.13-py3-none-any.whl", hash = "sha256:1ee19aca801bbabb5ba3f5f258e4422dfa86f82f3e9cefb0859b283cdd7f62a3"}, {file = "alabaster-0.7.13.tar.gz", hash = "sha256:a27a4a084d5e690e16e01e03ad2b2e552c61a65469419b907243193de1a84ae2"}, ] [[package]] name = "astroid" version = "3.2.2" description = "An abstract syntax tree for Python with inference support." category = "dev" optional = false python-versions = ">=3.8.0" files = [ {file = "astroid-3.2.2-py3-none-any.whl", hash = "sha256:e8a0083b4bb28fcffb6207a3bfc9e5d0a68be951dd7e336d5dcf639c682388c0"}, {file = "astroid-3.2.2.tar.gz", hash = "sha256:8ead48e31b92b2e217b6c9733a21afafe479d52d6e164dd25fb1a770c7c3cf94"}, ] [package.dependencies] typing-extensions = {version = ">=4.0.0", markers = "python_version < \"3.11\""} [[package]] name = "attrs" version = "23.2.0" description = "Classes Without Boilerplate" category = "main" optional = false python-versions = ">=3.7" files = [ {file = "attrs-23.2.0-py3-none-any.whl", hash = "sha256:99b87a485a5820b23b879f04c2305b44b951b502fd64be915879d77a7e8fc6f1"}, {file = "attrs-23.2.0.tar.gz", hash = "sha256:935dc3b529c262f6cf76e50877d35a4bd3c1de194fd41f47a2b7ae8f19971f30"}, ] [package.extras] cov = ["attrs[tests]", "coverage[toml] (>=5.3)"] dev = ["attrs[tests]", "pre-commit"] docs = ["furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier", "zope-interface"] tests = ["attrs[tests-no-zope]", "zope-interface"] tests-mypy = ["mypy (>=1.6)", "pytest-mypy-plugins"] tests-no-zope = ["attrs[tests-mypy]", "cloudpickle", "hypothesis", "pympler", "pytest (>=4.3.0)", "pytest-xdist[psutil]"] [[package]] name = "babel" version = "2.15.0" description = "Internationalization utilities" category = "dev" optional = false python-versions = ">=3.8" files = [ {file = "Babel-2.15.0-py3-none-any.whl", hash = "sha256:08706bdad8d0a3413266ab61bd6c34d0c28d6e1e7badf40a2cebe67644e2e1fb"}, {file = "babel-2.15.0.tar.gz", hash = "sha256:8daf0e265d05768bc6c7a314cf1321e9a123afc328cc635c18622a2f30a04413"}, ] [package.dependencies] pytz = {version = ">=2015.7", markers = "python_version < \"3.9\""} [package.extras] dev = ["freezegun (>=1.0,<2.0)", "pytest (>=6.0)", "pytest-cov"] [[package]] name = "beautifulsoup4" version = "4.12.3" description = "Screen-scraping library" category = "dev" optional = false python-versions = ">=3.6.0" files = [ {file = "beautifulsoup4-4.12.3-py3-none-any.whl", hash = "sha256:b80878c9f40111313e55da8ba20bdba06d8fa3969fc68304167741bbf9e082ed"}, {file = "beautifulsoup4-4.12.3.tar.gz", hash = "sha256:74e3d1928edc070d21748185c46e3fb33490f22f52a3addee9aee0f4f7781051"}, ] [package.dependencies] soupsieve = ">1.2" [package.extras] cchardet = ["cchardet"] chardet = ["chardet"] charset-normalizer = ["charset-normalizer"] html5lib = ["html5lib"] lxml = ["lxml"] [[package]] name = "binaryornot" version = "0.4.4" description = "Ultra-lightweight pure Python package to check if a file is binary or text." category = "main" optional = false python-versions = "*" files = [ {file = "binaryornot-0.4.4-py2.py3-none-any.whl", hash = "sha256:b8b71173c917bddcd2c16070412e369c3ed7f0528926f70cac18a6c97fd563e4"}, {file = "binaryornot-0.4.4.tar.gz", hash = "sha256:359501dfc9d40632edc9fac890e19542db1a287bbcfa58175b66658392018061"}, ] [package.dependencies] chardet = ">=3.0.2" [[package]] name = "black" version = "24.4.2" description = "The uncompromising code formatter." category = "dev" optional = false python-versions = ">=3.8" files = [ {file = "black-24.4.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:dd1b5a14e417189db4c7b64a6540f31730713d173f0b63e55fabd52d61d8fdce"}, {file = "black-24.4.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8e537d281831ad0e71007dcdcbe50a71470b978c453fa41ce77186bbe0ed6021"}, {file = "black-24.4.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eaea3008c281f1038edb473c1aa8ed8143a5535ff18f978a318f10302b254063"}, {file = "black-24.4.2-cp310-cp310-win_amd64.whl", hash = "sha256:7768a0dbf16a39aa5e9a3ded568bb545c8c2727396d063bbaf847df05b08cd96"}, {file = "black-24.4.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:257d724c2c9b1660f353b36c802ccece186a30accc7742c176d29c146df6e474"}, {file = "black-24.4.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:bdde6f877a18f24844e381d45e9947a49e97933573ac9d4345399be37621e26c"}, {file = "black-24.4.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e151054aa00bad1f4e1f04919542885f89f5f7d086b8a59e5000e6c616896ffb"}, {file = "black-24.4.2-cp311-cp311-win_amd64.whl", hash = "sha256:7e122b1c4fb252fd85df3ca93578732b4749d9be076593076ef4d07a0233c3e1"}, {file = "black-24.4.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:accf49e151c8ed2c0cdc528691838afd217c50412534e876a19270fea1e28e2d"}, {file = "black-24.4.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:88c57dc656038f1ab9f92b3eb5335ee9b021412feaa46330d5eba4e51fe49b04"}, {file = "black-24.4.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:be8bef99eb46d5021bf053114442914baeb3649a89dc5f3a555c88737e5e98fc"}, {file = "black-24.4.2-cp312-cp312-win_amd64.whl", hash = "sha256:415e686e87dbbe6f4cd5ef0fbf764af7b89f9057b97c908742b6008cc554b9c0"}, {file = "black-24.4.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:bf10f7310db693bb62692609b397e8d67257c55f949abde4c67f9cc574492cc7"}, {file = "black-24.4.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:98e123f1d5cfd42f886624d84464f7756f60ff6eab89ae845210631714f6db94"}, {file = "black-24.4.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:48a85f2cb5e6799a9ef05347b476cce6c182d6c71ee36925a6c194d074336ef8"}, {file = "black-24.4.2-cp38-cp38-win_amd64.whl", hash = "sha256:b1530ae42e9d6d5b670a34db49a94115a64596bc77710b1d05e9801e62ca0a7c"}, {file = "black-24.4.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:37aae07b029fa0174d39daf02748b379399b909652a806e5708199bd93899da1"}, {file = "black-24.4.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:da33a1a5e49c4122ccdfd56cd021ff1ebc4a1ec4e2d01594fef9b6f267a9e741"}, {file = "black-24.4.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ef703f83fc32e131e9bcc0a5094cfe85599e7109f896fe8bc96cc402f3eb4b6e"}, {file = "black-24.4.2-cp39-cp39-win_amd64.whl", hash = "sha256:b9176b9832e84308818a99a561e90aa479e73c523b3f77afd07913380ae2eab7"}, {file = "black-24.4.2-py3-none-any.whl", hash = "sha256:d36ed1124bb81b32f8614555b34cc4259c3fbc7eec17870e8ff8ded335b58d8c"}, {file = "black-24.4.2.tar.gz", hash = "sha256:c872b53057f000085da66a19c55d68f6f8ddcac2642392ad3a355878406fbd4d"}, ] [package.dependencies] click = ">=8.0.0" mypy-extensions = ">=0.4.3" packaging = ">=22.0" pathspec = ">=0.9.0" platformdirs = ">=2" tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} typing-extensions = {version = ">=4.0.1", markers = "python_version < \"3.11\""} [package.extras] colorama = ["colorama (>=0.4.3)"] d = ["aiohttp (>=3.7.4)", "aiohttp (>=3.7.4,!=3.9.0)"] jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"] uvloop = ["uvloop (>=0.15.2)"] [[package]] name = "boolean-py" version = "4.0" description = "Define boolean algebras, create and parse boolean expressions and create custom boolean DSL." category = "main" optional = false python-versions = "*" files = [ {file = "boolean.py-4.0-py3-none-any.whl", hash = "sha256:2876f2051d7d6394a531d82dc6eb407faa0b01a0a0b3083817ccd7323b8d96bd"}, {file = "boolean.py-4.0.tar.gz", hash = "sha256:17b9a181630e43dde1851d42bef546d616d5d9b4480357514597e78b203d06e4"}, ] [[package]] name = "bumpver" version = "2023.1129" description = "Bump version numbers in project files." category = "dev" optional = false python-versions = ">=2.7" files = [ {file = "bumpver-2023.1129-py2.py3-none-any.whl", hash = "sha256:b2a55c0224215b6ca1c3a0c99827749927b7c61cbb5dfef75565dbda8e75f687"}, {file = "bumpver-2023.1129.tar.gz", hash = "sha256:2a09813066d92ae2eabf882d4f9a88ebd60135e828c424bdf7800e1723e15010"}, ] [package.dependencies] click = {version = "*", markers = "python_version >= \"3.6\""} colorama = ">=0.4" lexid = "*" looseversion = {version = "*", markers = "python_version >= \"3.5\""} toml = "*" [[package]] name = "certifi" version = "2024.6.2" description = "Python package for providing Mozilla's CA Bundle." category = "dev" optional = false python-versions = ">=3.6" files = [ {file = "certifi-2024.6.2-py3-none-any.whl", hash = "sha256:ddc6c8ce995e6987e7faf5e3f1b02b302836a0e5d98ece18392cb1a36c72ad56"}, {file = "certifi-2024.6.2.tar.gz", hash = "sha256:3cd43f1c6fa7dedc5899d69d3ad0398fd018ad1a17fba83ddaf78aa46c747516"}, ] [[package]] name = "cfgv" version = "3.4.0" description = "Validate configuration and produce human readable error messages." category = "dev" optional = false python-versions = ">=3.8" files = [ {file = "cfgv-3.4.0-py2.py3-none-any.whl", hash = "sha256:b7265b1f29fd3316bfcd2b330d63d024f2bfd8bcb8b0272f8e19a504856c48f9"}, {file = "cfgv-3.4.0.tar.gz", hash = "sha256:e52591d4c5f5dead8e0f673fb16db7949d2cfb3f7da4582893288f0ded8fe560"}, ] [[package]] name = "chardet" version = "5.2.0" description = "Universal encoding detector for Python 3" category = "main" optional = false python-versions = ">=3.7" files = [ {file = "chardet-5.2.0-py3-none-any.whl", hash = "sha256:e1cf59446890a00105fe7b7912492ea04b6e6f06d4b742b2c788469e34c82970"}, {file = "chardet-5.2.0.tar.gz", hash = "sha256:1b3b6ff479a8c414bc3fa2c0852995695c4a026dcd6d0633b2dd092ca39c1cf7"}, ] [[package]] name = "charset-normalizer" version = "3.3.2" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." category = "dev" optional = false python-versions = ">=3.7.0" files = [ {file = "charset-normalizer-3.3.2.tar.gz", hash = "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5"}, {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3"}, {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027"}, {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03"}, {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d"}, {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e"}, {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6"}, {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5"}, {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537"}, {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c"}, {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12"}, {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f"}, {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269"}, {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519"}, {file = "charset_normalizer-3.3.2-cp310-cp310-win32.whl", hash = "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73"}, {file = "charset_normalizer-3.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09"}, {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db"}, {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96"}, {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e"}, {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f"}, {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574"}, {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4"}, {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8"}, {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc"}, {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae"}, {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887"}, {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae"}, {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce"}, {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f"}, {file = "charset_normalizer-3.3.2-cp311-cp311-win32.whl", hash = "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab"}, {file = "charset_normalizer-3.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77"}, {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8"}, {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b"}, {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6"}, {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a"}, {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389"}, {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa"}, {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b"}, {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed"}, {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26"}, {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d"}, {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068"}, {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143"}, {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4"}, {file = "charset_normalizer-3.3.2-cp312-cp312-win32.whl", hash = "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7"}, {file = "charset_normalizer-3.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001"}, {file = "charset_normalizer-3.3.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c"}, {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5"}, {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985"}, {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6"}, {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714"}, {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786"}, {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5"}, {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c"}, {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8"}, {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711"}, {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811"}, {file = "charset_normalizer-3.3.2-cp37-cp37m-win32.whl", hash = "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4"}, {file = "charset_normalizer-3.3.2-cp37-cp37m-win_amd64.whl", hash = "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99"}, {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a"}, {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac"}, {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a"}, {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33"}, {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238"}, {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a"}, {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2"}, {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8"}, {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898"}, {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99"}, {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d"}, {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04"}, {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087"}, {file = "charset_normalizer-3.3.2-cp38-cp38-win32.whl", hash = "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25"}, {file = "charset_normalizer-3.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b"}, {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4"}, {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d"}, {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0"}, {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269"}, {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c"}, {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519"}, {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796"}, {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185"}, {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c"}, {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458"}, {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2"}, {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8"}, {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561"}, {file = "charset_normalizer-3.3.2-cp39-cp39-win32.whl", hash = "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f"}, {file = "charset_normalizer-3.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d"}, {file = "charset_normalizer-3.3.2-py3-none-any.whl", hash = "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc"}, ] [[package]] name = "click" version = "8.1.7" description = "Composable command line interface toolkit" category = "dev" optional = false python-versions = ">=3.7" files = [ {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"}, {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"}, ] [package.dependencies] colorama = {version = "*", markers = "platform_system == \"Windows\""} [[package]] name = "colorama" version = "0.4.6" description = "Cross-platform colored terminal text." category = "dev" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" files = [ {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, ] [[package]] name = "coverage" version = "7.5.4" description = "Code coverage measurement for Python" category = "dev" optional = false python-versions = ">=3.8" files = [ {file = "coverage-7.5.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6cfb5a4f556bb51aba274588200a46e4dd6b505fb1a5f8c5ae408222eb416f99"}, {file = "coverage-7.5.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2174e7c23e0a454ffe12267a10732c273243b4f2d50d07544a91198f05c48f47"}, {file = "coverage-7.5.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2214ee920787d85db1b6a0bd9da5f8503ccc8fcd5814d90796c2f2493a2f4d2e"}, {file = "coverage-7.5.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1137f46adb28e3813dec8c01fefadcb8c614f33576f672962e323b5128d9a68d"}, {file = "coverage-7.5.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b385d49609f8e9efc885790a5a0e89f2e3ae042cdf12958b6034cc442de428d3"}, {file = "coverage-7.5.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:b4a474f799456e0eb46d78ab07303286a84a3140e9700b9e154cfebc8f527016"}, {file = "coverage-7.5.4-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:5cd64adedf3be66f8ccee418473c2916492d53cbafbfcff851cbec5a8454b136"}, {file = "coverage-7.5.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e564c2cf45d2f44a9da56f4e3a26b2236504a496eb4cb0ca7221cd4cc7a9aca9"}, {file = "coverage-7.5.4-cp310-cp310-win32.whl", hash = "sha256:7076b4b3a5f6d2b5d7f1185fde25b1e54eb66e647a1dfef0e2c2bfaf9b4c88c8"}, {file = "coverage-7.5.4-cp310-cp310-win_amd64.whl", hash = "sha256:018a12985185038a5b2bcafab04ab833a9a0f2c59995b3cec07e10074c78635f"}, {file = "coverage-7.5.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:db14f552ac38f10758ad14dd7b983dbab424e731588d300c7db25b6f89e335b5"}, {file = "coverage-7.5.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3257fdd8e574805f27bb5342b77bc65578e98cbc004a92232106344053f319ba"}, {file = "coverage-7.5.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3a6612c99081d8d6134005b1354191e103ec9705d7ba2754e848211ac8cacc6b"}, {file = "coverage-7.5.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d45d3cbd94159c468b9b8c5a556e3f6b81a8d1af2a92b77320e887c3e7a5d080"}, {file = "coverage-7.5.4-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ed550e7442f278af76d9d65af48069f1fb84c9f745ae249c1a183c1e9d1b025c"}, {file = "coverage-7.5.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:7a892be37ca35eb5019ec85402c3371b0f7cda5ab5056023a7f13da0961e60da"}, {file = "coverage-7.5.4-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8192794d120167e2a64721d88dbd688584675e86e15d0569599257566dec9bf0"}, {file = "coverage-7.5.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:820bc841faa502e727a48311948e0461132a9c8baa42f6b2b84a29ced24cc078"}, {file = "coverage-7.5.4-cp311-cp311-win32.whl", hash = "sha256:6aae5cce399a0f065da65c7bb1e8abd5c7a3043da9dceb429ebe1b289bc07806"}, {file = "coverage-7.5.4-cp311-cp311-win_amd64.whl", hash = "sha256:d2e344d6adc8ef81c5a233d3a57b3c7d5181f40e79e05e1c143da143ccb6377d"}, {file = "coverage-7.5.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:54317c2b806354cbb2dc7ac27e2b93f97096912cc16b18289c5d4e44fc663233"}, {file = "coverage-7.5.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:042183de01f8b6d531e10c197f7f0315a61e8d805ab29c5f7b51a01d62782747"}, {file = "coverage-7.5.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a6bb74ed465d5fb204b2ec41d79bcd28afccf817de721e8a807d5141c3426638"}, {file = "coverage-7.5.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3d45ff86efb129c599a3b287ae2e44c1e281ae0f9a9bad0edc202179bcc3a2e"}, {file = "coverage-7.5.4-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5013ed890dc917cef2c9f765c4c6a8ae9df983cd60dbb635df8ed9f4ebc9f555"}, {file = "coverage-7.5.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1014fbf665fef86cdfd6cb5b7371496ce35e4d2a00cda501cf9f5b9e6fced69f"}, {file = "coverage-7.5.4-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:3684bc2ff328f935981847082ba4fdc950d58906a40eafa93510d1b54c08a66c"}, {file = "coverage-7.5.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:581ea96f92bf71a5ec0974001f900db495488434a6928a2ca7f01eee20c23805"}, {file = "coverage-7.5.4-cp312-cp312-win32.whl", hash = "sha256:73ca8fbc5bc622e54627314c1a6f1dfdd8db69788f3443e752c215f29fa87a0b"}, {file = "coverage-7.5.4-cp312-cp312-win_amd64.whl", hash = "sha256:cef4649ec906ea7ea5e9e796e68b987f83fa9a718514fe147f538cfeda76d7a7"}, {file = "coverage-7.5.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cdd31315fc20868c194130de9ee6bfd99755cc9565edff98ecc12585b90be882"}, {file = "coverage-7.5.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:02ff6e898197cc1e9fa375581382b72498eb2e6d5fc0b53f03e496cfee3fac6d"}, {file = "coverage-7.5.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d05c16cf4b4c2fc880cb12ba4c9b526e9e5d5bb1d81313d4d732a5b9fe2b9d53"}, {file = "coverage-7.5.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c5986ee7ea0795a4095ac4d113cbb3448601efca7f158ec7f7087a6c705304e4"}, {file = "coverage-7.5.4-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5df54843b88901fdc2f598ac06737f03d71168fd1175728054c8f5a2739ac3e4"}, {file = "coverage-7.5.4-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:ab73b35e8d109bffbda9a3e91c64e29fe26e03e49addf5b43d85fc426dde11f9"}, {file = "coverage-7.5.4-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:aea072a941b033813f5e4814541fc265a5c12ed9720daef11ca516aeacd3bd7f"}, {file = "coverage-7.5.4-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:16852febd96acd953b0d55fc842ce2dac1710f26729b31c80b940b9afcd9896f"}, {file = "coverage-7.5.4-cp38-cp38-win32.whl", hash = "sha256:8f894208794b164e6bd4bba61fc98bf6b06be4d390cf2daacfa6eca0a6d2bb4f"}, {file = "coverage-7.5.4-cp38-cp38-win_amd64.whl", hash = "sha256:e2afe743289273209c992075a5a4913e8d007d569a406ffed0bd080ea02b0633"}, {file = "coverage-7.5.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b95c3a8cb0463ba9f77383d0fa8c9194cf91f64445a63fc26fb2327e1e1eb088"}, {file = "coverage-7.5.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3d7564cc09dd91b5a6001754a5b3c6ecc4aba6323baf33a12bd751036c998be4"}, {file = "coverage-7.5.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:44da56a2589b684813f86d07597fdf8a9c6ce77f58976727329272f5a01f99f7"}, {file = "coverage-7.5.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e16f3d6b491c48c5ae726308e6ab1e18ee830b4cdd6913f2d7f77354b33f91c8"}, {file = "coverage-7.5.4-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dbc5958cb471e5a5af41b0ddaea96a37e74ed289535e8deca404811f6cb0bc3d"}, {file = "coverage-7.5.4-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:a04e990a2a41740b02d6182b498ee9796cf60eefe40cf859b016650147908029"}, {file = "coverage-7.5.4-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:ddbd2f9713a79e8e7242d7c51f1929611e991d855f414ca9996c20e44a895f7c"}, {file = "coverage-7.5.4-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:b1ccf5e728ccf83acd313c89f07c22d70d6c375a9c6f339233dcf792094bcbf7"}, {file = "coverage-7.5.4-cp39-cp39-win32.whl", hash = "sha256:56b4eafa21c6c175b3ede004ca12c653a88b6f922494b023aeb1e836df953ace"}, {file = "coverage-7.5.4-cp39-cp39-win_amd64.whl", hash = "sha256:65e528e2e921ba8fd67d9055e6b9f9e34b21ebd6768ae1c1723f4ea6ace1234d"}, {file = "coverage-7.5.4-pp38.pp39.pp310-none-any.whl", hash = "sha256:79b356f3dd5b26f3ad23b35c75dbdaf1f9e2450b6bcefc6d0825ea0aa3f86ca5"}, {file = "coverage-7.5.4.tar.gz", hash = "sha256:a44963520b069e12789d0faea4e9fdb1e410cdc4aab89d94f7f55cbb7fef0353"}, ] [package.dependencies] tomli = {version = "*", optional = true, markers = "python_full_version <= \"3.11.0a6\" and extra == \"toml\""} [package.extras] toml = ["tomli"] [[package]] name = "dill" version = "0.3.8" description = "serialize all of Python" category = "dev" optional = false python-versions = ">=3.8" files = [ {file = "dill-0.3.8-py3-none-any.whl", hash = "sha256:c36ca9ffb54365bdd2f8eb3eff7d2a21237f8452b57ace88b1ac615b7e815bd7"}, {file = "dill-0.3.8.tar.gz", hash = "sha256:3ebe3c479ad625c4553aca177444d89b486b1d84982eeacded644afc0cf797ca"}, ] [package.extras] graph = ["objgraph (>=1.7.2)"] profile = ["gprof2dot (>=2022.7.29)"] [[package]] name = "distlib" version = "0.3.8" description = "Distribution utilities" category = "dev" optional = false python-versions = "*" files = [ {file = "distlib-0.3.8-py2.py3-none-any.whl", hash = "sha256:034db59a0b96f8ca18035f36290806a9a6e6bd9d1ff91e45a7f172eb17e51784"}, {file = "distlib-0.3.8.tar.gz", hash = "sha256:1530ea13e350031b6312d8580ddb6b27a104275a31106523b8f123787f494f64"}, ] [[package]] name = "docstring-to-markdown" version = "0.15" description = "On the fly conversion of Python docstrings to markdown" category = "dev" optional = false python-versions = ">=3.6" files = [ {file = "docstring-to-markdown-0.15.tar.gz", hash = "sha256:e146114d9c50c181b1d25505054a8d0f7a476837f0da2c19f07e06eaed52b73d"}, {file = "docstring_to_markdown-0.15-py3-none-any.whl", hash = "sha256:27afb3faedba81e34c33521c32bbd258d7fbb79eedf7d29bc4e81080e854aec0"}, ] [[package]] name = "docutils" version = "0.20.1" description = "Docutils -- Python Documentation Utilities" category = "dev" optional = false python-versions = ">=3.7" files = [ {file = "docutils-0.20.1-py3-none-any.whl", hash = "sha256:96f387a2c5562db4476f09f13bbab2192e764cac08ebbf3a34a95d9b1e4a59d6"}, {file = "docutils-0.20.1.tar.gz", hash = "sha256:f08a4e276c3a1583a86dce3e34aba3fe04d02bba2dd51ed16106244e8a923e3b"}, ] [[package]] name = "exceptiongroup" version = "1.2.1" description = "Backport of PEP 654 (exception groups)" category = "dev" optional = false python-versions = ">=3.7" files = [ {file = "exceptiongroup-1.2.1-py3-none-any.whl", hash = "sha256:5258b9ed329c5bbdd31a309f53cbfb0b155341807f6ff7606a1e801a891b29ad"}, {file = "exceptiongroup-1.2.1.tar.gz", hash = "sha256:a4785e48b045528f5bfe627b6ad554ff32def154f42372786903b7abcfe1aa16"}, ] [package.extras] test = ["pytest (>=6)"] [[package]] name = "filelock" version = "3.15.4" description = "A platform independent file lock." category = "dev" optional = false python-versions = ">=3.8" files = [ {file = "filelock-3.15.4-py3-none-any.whl", hash = "sha256:6ca1fffae96225dab4c6eaf1c4f4f28cd2568d3ec2a44e15a08520504de468e7"}, {file = "filelock-3.15.4.tar.gz", hash = "sha256:2207938cbc1844345cb01a5a95524dae30f0ce089eba5b00378295a17e3e90cb"}, ] [package.extras] docs = ["furo (>=2023.9.10)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.25.2)"] testing = ["covdefaults (>=2.3)", "coverage (>=7.3.2)", "diff-cover (>=8.0.1)", "pytest (>=7.4.3)", "pytest-asyncio (>=0.21)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)", "pytest-timeout (>=2.2)", "virtualenv (>=20.26.2)"] typing = ["typing-extensions (>=4.8)"] [[package]] name = "freezegun" version = "1.5.1" description = "Let your Python tests travel through time" category = "dev" optional = false python-versions = ">=3.7" files = [ {file = "freezegun-1.5.1-py3-none-any.whl", hash = "sha256:bf111d7138a8abe55ab48a71755673dbaa4ab87f4cff5634a4442dfec34c15f1"}, {file = "freezegun-1.5.1.tar.gz", hash = "sha256:b29dedfcda6d5e8e083ce71b2b542753ad48cfec44037b3fc79702e2980a89e9"}, ] [package.dependencies] python-dateutil = ">=2.7" [[package]] name = "furo" version = "2024.5.6" description = "A clean customisable Sphinx documentation theme." category = "dev" optional = false python-versions = ">=3.8" files = [ {file = "furo-2024.5.6-py3-none-any.whl", hash = "sha256:490a00d08c0a37ecc90de03ae9227e8eb5d6f7f750edf9807f398a2bdf2358de"}, {file = "furo-2024.5.6.tar.gz", hash = "sha256:81f205a6605ebccbb883350432b4831c0196dd3d1bc92f61e1f459045b3d2b0b"}, ] [package.dependencies] beautifulsoup4 = "*" pygments = ">=2.7" sphinx = ">=6.0,<8.0" sphinx-basic-ng = ">=1.0.0.beta2" [[package]] name = "gitdb" version = "4.0.11" description = "Git Object Database" category = "dev" optional = false python-versions = ">=3.7" files = [ {file = "gitdb-4.0.11-py3-none-any.whl", hash = "sha256:81a3407ddd2ee8df444cbacea00e2d038e40150acfa3001696fe0dcf1d3adfa4"}, {file = "gitdb-4.0.11.tar.gz", hash = "sha256:bf5421126136d6d0af55bc1e7c1af1c397a34f5b7bd79e776cd3e89785c2b04b"}, ] [package.dependencies] smmap = ">=3.0.1,<6" [[package]] name = "gitpython" version = "3.1.43" description = "GitPython is a Python library used to interact with Git repositories" category = "dev" optional = false python-versions = ">=3.7" files = [ {file = "GitPython-3.1.43-py3-none-any.whl", hash = "sha256:eec7ec56b92aad751f9912a73404bc02ba212a23adb2c7098ee668417051a1ff"}, {file = "GitPython-3.1.43.tar.gz", hash = "sha256:35f314a9f878467f5453cc1fee295c3e18e52f1b99f10f6cf5b1682e968a9e7c"}, ] [package.dependencies] gitdb = ">=4.0.1,<5" [package.extras] doc = ["sphinx (==4.3.2)", "sphinx-autodoc-typehints", "sphinx-rtd-theme", "sphinxcontrib-applehelp (>=1.0.2,<=1.0.4)", "sphinxcontrib-devhelp (==1.0.2)", "sphinxcontrib-htmlhelp (>=2.0.0,<=2.0.1)", "sphinxcontrib-qthelp (==1.0.3)", "sphinxcontrib-serializinghtml (==1.1.5)"] test = ["coverage[toml]", "ddt (>=1.1.1,!=1.4.3)", "mock", "mypy", "pre-commit", "pytest (>=7.3.1)", "pytest-cov", "pytest-instafail", "pytest-mock", "pytest-sugar", "typing-extensions"] [[package]] name = "identify" version = "2.5.36" description = "File identification library for Python" category = "dev" optional = false python-versions = ">=3.8" files = [ {file = "identify-2.5.36-py2.py3-none-any.whl", hash = "sha256:37d93f380f4de590500d9dba7db359d0d3da95ffe7f9de1753faa159e71e7dfa"}, {file = "identify-2.5.36.tar.gz", hash = "sha256:e5e00f54165f9047fbebeb4a560f9acfb8af4c88232be60a488e9b68d122745d"}, ] [package.extras] license = ["ukkonen"] [[package]] name = "idna" version = "3.7" description = "Internationalized Domain Names in Applications (IDNA)" category = "dev" optional = false python-versions = ">=3.5" files = [ {file = "idna-3.7-py3-none-any.whl", hash = "sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0"}, {file = "idna-3.7.tar.gz", hash = "sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc"}, ] [[package]] name = "imagesize" version = "1.4.1" description = "Getting image size from png/jpeg/jpeg2000/gif file" category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ {file = "imagesize-1.4.1-py2.py3-none-any.whl", hash = "sha256:0d8d18d08f840c19d0ee7ca1fd82490fdc3729b7ac93f49870406ddde8ef8d8b"}, {file = "imagesize-1.4.1.tar.gz", hash = "sha256:69150444affb9cb0d5cc5a92b3676f0b2fb7cd9ae39e947a5e11a36b4497cd4a"}, ] [[package]] name = "importlib-metadata" version = "8.0.0" description = "Read metadata from Python packages" category = "dev" optional = false python-versions = ">=3.8" files = [ {file = "importlib_metadata-8.0.0-py3-none-any.whl", hash = "sha256:15584cf2b1bf449d98ff8a6ff1abef57bf20f3ac6454f431736cd3e660921b2f"}, {file = "importlib_metadata-8.0.0.tar.gz", hash = "sha256:188bd24e4c346d3f0a933f275c2fec67050326a856b9a359881d7c2a697e8812"}, ] [package.dependencies] zipp = ">=0.5" [package.extras] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] perf = ["ipython"] test = ["flufl.flake8", "importlib-resources (>=1.3)", "jaraco.test (>=5.4)", "packaging", "pyfakefs", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy", "pytest-perf (>=0.9.2)", "pytest-ruff (>=0.2.1)"] [[package]] name = "iniconfig" version = "2.0.0" description = "brain-dead simple config-ini parsing" category = "dev" optional = false python-versions = ">=3.7" files = [ {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, ] [[package]] name = "isort" version = "5.13.2" description = "A Python utility / library to sort Python imports." category = "dev" optional = false python-versions = ">=3.8.0" files = [ {file = "isort-5.13.2-py3-none-any.whl", hash = "sha256:8ca5e72a8d85860d5a3fa69b8745237f2939afe12dbf656afbcb47fe72d947a6"}, {file = "isort-5.13.2.tar.gz", hash = "sha256:48fdfcb9face5d58a4f6dde2e72a1fb8dcaf8ab26f95ab49fab84c2ddefb0109"}, ] [package.extras] colors = ["colorama (>=0.4.6)"] [[package]] name = "jedi" version = "0.19.1" description = "An autocompletion tool for Python that can be used for text editors." category = "dev" optional = false python-versions = ">=3.6" files = [ {file = "jedi-0.19.1-py2.py3-none-any.whl", hash = "sha256:e983c654fe5c02867aef4cdfce5a2fbb4a50adc0af145f70504238f18ef5e7e0"}, {file = "jedi-0.19.1.tar.gz", hash = "sha256:cf0496f3651bc65d7174ac1b7d043eff454892c708a87d1b683e57b569927ffd"}, ] [package.dependencies] parso = ">=0.8.3,<0.9.0" [package.extras] docs = ["Jinja2 (==2.11.3)", "MarkupSafe (==1.1.1)", "Pygments (==2.8.1)", "alabaster (==0.7.12)", "babel (==2.9.1)", "chardet (==4.0.0)", "commonmark (==0.8.1)", "docutils (==0.17.1)", "future (==0.18.2)", "idna (==2.10)", "imagesize (==1.2.0)", "mock (==1.0.1)", "packaging (==20.9)", "pyparsing (==2.4.7)", "pytz (==2021.1)", "readthedocs-sphinx-ext (==2.1.4)", "recommonmark (==0.5.0)", "requests (==2.25.1)", "six (==1.15.0)", "snowballstemmer (==2.1.0)", "sphinx (==1.8.5)", "sphinx-rtd-theme (==0.4.3)", "sphinxcontrib-serializinghtml (==1.1.4)", "sphinxcontrib-websupport (==1.2.4)", "urllib3 (==1.26.4)"] qa = ["flake8 (==5.0.4)", "mypy (==0.971)", "types-setuptools (==67.2.0.1)"] testing = ["Django", "attrs", "colorama", "docopt", "pytest (<7.0.0)"] [[package]] name = "jinja2" version = "3.1.4" description = "A very fast and expressive template engine." category = "main" optional = false python-versions = ">=3.7" files = [ {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, ] [package.dependencies] MarkupSafe = ">=2.0" [package.extras] i18n = ["Babel (>=2.7)"] [[package]] name = "lexid" version = "2021.1006" description = "Variable width build numbers with lexical ordering." category = "dev" optional = false python-versions = ">=2.7" files = [ {file = "lexid-2021.1006-py2.py3-none-any.whl", hash = "sha256:5526bb5606fd74c7add23320da5f02805bddd7c77916f2dc1943e6bada8605ed"}, {file = "lexid-2021.1006.tar.gz", hash = "sha256:509a3a4cc926d3dbf22b203b18a4c66c25e6473fb7c0e0d30374533ac28bafe5"}, ] [[package]] name = "license-expression" version = "30.3.0" description = "license-expression is a comprehensive utility library to parse, compare, simplify and normalize license expressions (such as SPDX license expressions) using boolean logic." category = "main" optional = false python-versions = ">=3.8" files = [ {file = "license-expression-30.3.0.tar.gz", hash = "sha256:1295406f736b4f395ff069aec1cebfad53c0fcb3cf57df0f5ec58fc7b905aea5"}, {file = "license_expression-30.3.0-py3-none-any.whl", hash = "sha256:ae0ba9a829d6909c785dc2f0131f13d10d68318e4a5f28af5ef152d6b52f9b41"}, ] [package.dependencies] "boolean.py" = ">=4.0" [package.extras] docs = ["Sphinx (>=5.0.2)", "doc8 (>=0.11.2)", "sphinx-autobuild", "sphinx-copybutton", "sphinx-reredirects (>=0.1.2)", "sphinx-rtd-dark-mode (>=1.3.0)", "sphinx-rtd-theme (>=1.0.0)", "sphinxcontrib-apidoc (>=0.4.0)"] testing = ["black", "isort", "pytest (>=6,!=7.0.0)", "pytest-xdist (>=2)", "twine"] [[package]] name = "looseversion" version = "1.3.0" description = "Version numbering for anarchists and software realists" category = "dev" optional = false python-versions = "*" files = [ {file = "looseversion-1.3.0-py2.py3-none-any.whl", hash = "sha256:781ef477b45946fc03dd4c84ea87734b21137ecda0e1e122bcb3c8d16d2a56e0"}, {file = "looseversion-1.3.0.tar.gz", hash = "sha256:ebde65f3f6bb9531a81016c6fef3eb95a61181adc47b7f949e9c0ea47911669e"}, ] [[package]] name = "markdown-it-py" version = "3.0.0" description = "Python port of markdown-it. Markdown parsing, done right!" category = "dev" optional = false python-versions = ">=3.8" files = [ {file = "markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb"}, {file = "markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1"}, ] [package.dependencies] mdurl = ">=0.1,<1.0" [package.extras] benchmarking = ["psutil", "pytest", "pytest-benchmark"] code-style = ["pre-commit (>=3.0,<4.0)"] compare = ["commonmark (>=0.9,<1.0)", "markdown (>=3.4,<4.0)", "mistletoe (>=1.0,<2.0)", "mistune (>=2.0,<3.0)", "panflute (>=2.3,<3.0)"] linkify = ["linkify-it-py (>=1,<3)"] plugins = ["mdit-py-plugins"] profiling = ["gprof2dot"] rtd = ["jupyter_sphinx", "mdit-py-plugins", "myst-parser", "pyyaml", "sphinx", "sphinx-copybutton", "sphinx-design", "sphinx_book_theme"] testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"] [[package]] name = "markupsafe" version = "2.1.5" description = "Safely add untrusted strings to HTML/XML markup." category = "main" optional = false python-versions = ">=3.7" files = [ {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc"}, {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5"}, {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46"}, {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f"}, {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900"}, {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff"}, {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad"}, {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd"}, {file = "MarkupSafe-2.1.5-cp310-cp310-win32.whl", hash = "sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4"}, {file = "MarkupSafe-2.1.5-cp310-cp310-win_amd64.whl", hash = "sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5"}, {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f"}, {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2"}, {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced"}, {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5"}, {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c"}, {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f"}, {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a"}, {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f"}, {file = "MarkupSafe-2.1.5-cp311-cp311-win32.whl", hash = "sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906"}, {file = "MarkupSafe-2.1.5-cp311-cp311-win_amd64.whl", hash = "sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617"}, {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1"}, {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4"}, {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee"}, {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5"}, {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b"}, {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a"}, {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f"}, {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169"}, {file = "MarkupSafe-2.1.5-cp312-cp312-win32.whl", hash = "sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad"}, {file = "MarkupSafe-2.1.5-cp312-cp312-win_amd64.whl", hash = "sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb"}, {file = "MarkupSafe-2.1.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c8b29db45f8fe46ad280a7294f5c3ec36dbac9491f2d1c17345be8e69cc5928f"}, {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec6a563cff360b50eed26f13adc43e61bc0c04d94b8be985e6fb24b81f6dcfdf"}, {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a549b9c31bec33820e885335b451286e2969a2d9e24879f83fe904a5ce59d70a"}, {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4f11aa001c540f62c6166c7726f71f7573b52c68c31f014c25cc7901deea0b52"}, {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:7b2e5a267c855eea6b4283940daa6e88a285f5f2a67f2220203786dfa59b37e9"}, {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:2d2d793e36e230fd32babe143b04cec8a8b3eb8a3122d2aceb4a371e6b09b8df"}, {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ce409136744f6521e39fd8e2a24c53fa18ad67aa5bc7c2cf83645cce5b5c4e50"}, {file = "MarkupSafe-2.1.5-cp37-cp37m-win32.whl", hash = "sha256:4096e9de5c6fdf43fb4f04c26fb114f61ef0bf2e5604b6ee3019d51b69e8c371"}, {file = "MarkupSafe-2.1.5-cp37-cp37m-win_amd64.whl", hash = "sha256:4275d846e41ecefa46e2015117a9f491e57a71ddd59bbead77e904dc02b1bed2"}, {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:656f7526c69fac7f600bd1f400991cc282b417d17539a1b228617081106feb4a"}, {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:97cafb1f3cbcd3fd2b6fbfb99ae11cdb14deea0736fc2b0952ee177f2b813a46"}, {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f3fbcb7ef1f16e48246f704ab79d79da8a46891e2da03f8783a5b6fa41a9532"}, {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa9db3f79de01457b03d4f01b34cf91bc0048eb2c3846ff26f66687c2f6d16ab"}, {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffee1f21e5ef0d712f9033568f8344d5da8cc2869dbd08d87c84656e6a2d2f68"}, {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:5dedb4db619ba5a2787a94d877bc8ffc0566f92a01c0ef214865e54ecc9ee5e0"}, {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:30b600cf0a7ac9234b2638fbc0fb6158ba5bdcdf46aeb631ead21248b9affbc4"}, {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8dd717634f5a044f860435c1d8c16a270ddf0ef8588d4887037c5028b859b0c3"}, {file = "MarkupSafe-2.1.5-cp38-cp38-win32.whl", hash = "sha256:daa4ee5a243f0f20d528d939d06670a298dd39b1ad5f8a72a4275124a7819eff"}, {file = "MarkupSafe-2.1.5-cp38-cp38-win_amd64.whl", hash = "sha256:619bc166c4f2de5caa5a633b8b7326fbe98e0ccbfacabd87268a2b15ff73a029"}, {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7a68b554d356a91cce1236aa7682dc01df0edba8d043fd1ce607c49dd3c1edcf"}, {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:db0b55e0f3cc0be60c1f19efdde9a637c32740486004f20d1cff53c3c0ece4d2"}, {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e53af139f8579a6d5f7b76549125f0d94d7e630761a2111bc431fd820e163b8"}, {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:17b950fccb810b3293638215058e432159d2b71005c74371d784862b7e4683f3"}, {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4c31f53cdae6ecfa91a77820e8b151dba54ab528ba65dfd235c80b086d68a465"}, {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bff1b4290a66b490a2f4719358c0cdcd9bafb6b8f061e45c7a2460866bf50c2e"}, {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:bc1667f8b83f48511b94671e0e441401371dfd0f0a795c7daa4a3cd1dde55bea"}, {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5049256f536511ee3f7e1b3f87d1d1209d327e818e6ae1365e8653d7e3abb6a6"}, {file = "MarkupSafe-2.1.5-cp39-cp39-win32.whl", hash = "sha256:00e046b6dd71aa03a41079792f8473dc494d564611a8f89bbbd7cb93295ebdcf"}, {file = "MarkupSafe-2.1.5-cp39-cp39-win_amd64.whl", hash = "sha256:fa173ec60341d6bb97a89f5ea19c85c5643c1e7dedebc22f5181eb73573142c5"}, {file = "MarkupSafe-2.1.5.tar.gz", hash = "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b"}, ] [[package]] name = "mccabe" version = "0.7.0" description = "McCabe checker, plugin for flake8" category = "dev" optional = false python-versions = ">=3.6" files = [ {file = "mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e"}, {file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"}, ] [[package]] name = "mdit-py-plugins" version = "0.4.1" description = "Collection of plugins for markdown-it-py" category = "dev" optional = false python-versions = ">=3.8" files = [ {file = "mdit_py_plugins-0.4.1-py3-none-any.whl", hash = "sha256:1020dfe4e6bfc2c79fb49ae4e3f5b297f5ccd20f010187acc52af2921e27dc6a"}, {file = "mdit_py_plugins-0.4.1.tar.gz", hash = "sha256:834b8ac23d1cd60cec703646ffd22ae97b7955a6d596eb1d304be1e251ae499c"}, ] [package.dependencies] markdown-it-py = ">=1.0.0,<4.0.0" [package.extras] code-style = ["pre-commit"] rtd = ["myst-parser", "sphinx-book-theme"] testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"] [[package]] name = "mdurl" version = "0.1.2" description = "Markdown URL utilities" category = "dev" optional = false python-versions = ">=3.7" files = [ {file = "mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8"}, {file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"}, ] [[package]] name = "mypy" version = "1.10.1" description = "Optional static typing for Python" category = "dev" optional = false python-versions = ">=3.8" files = [ {file = "mypy-1.10.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e36f229acfe250dc660790840916eb49726c928e8ce10fbdf90715090fe4ae02"}, {file = "mypy-1.10.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:51a46974340baaa4145363b9e051812a2446cf583dfaeba124af966fa44593f7"}, {file = "mypy-1.10.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:901c89c2d67bba57aaaca91ccdb659aa3a312de67f23b9dfb059727cce2e2e0a"}, {file = "mypy-1.10.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0cd62192a4a32b77ceb31272d9e74d23cd88c8060c34d1d3622db3267679a5d9"}, {file = "mypy-1.10.1-cp310-cp310-win_amd64.whl", hash = "sha256:a2cbc68cb9e943ac0814c13e2452d2046c2f2b23ff0278e26599224cf164e78d"}, {file = "mypy-1.10.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:bd6f629b67bb43dc0d9211ee98b96d8dabc97b1ad38b9b25f5e4c4d7569a0c6a"}, {file = "mypy-1.10.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a1bbb3a6f5ff319d2b9d40b4080d46cd639abe3516d5a62c070cf0114a457d84"}, {file = "mypy-1.10.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b8edd4e9bbbc9d7b79502eb9592cab808585516ae1bcc1446eb9122656c6066f"}, {file = "mypy-1.10.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:6166a88b15f1759f94a46fa474c7b1b05d134b1b61fca627dd7335454cc9aa6b"}, {file = "mypy-1.10.1-cp311-cp311-win_amd64.whl", hash = "sha256:5bb9cd11c01c8606a9d0b83ffa91d0b236a0e91bc4126d9ba9ce62906ada868e"}, {file = "mypy-1.10.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d8681909f7b44d0b7b86e653ca152d6dff0eb5eb41694e163c6092124f8246d7"}, {file = "mypy-1.10.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:378c03f53f10bbdd55ca94e46ec3ba255279706a6aacaecac52ad248f98205d3"}, {file = "mypy-1.10.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6bacf8f3a3d7d849f40ca6caea5c055122efe70e81480c8328ad29c55c69e93e"}, {file = "mypy-1.10.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:701b5f71413f1e9855566a34d6e9d12624e9e0a8818a5704d74d6b0402e66c04"}, {file = "mypy-1.10.1-cp312-cp312-win_amd64.whl", hash = "sha256:3c4c2992f6ea46ff7fce0072642cfb62af7a2484efe69017ed8b095f7b39ef31"}, {file = "mypy-1.10.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:604282c886497645ffb87b8f35a57ec773a4a2721161e709a4422c1636ddde5c"}, {file = "mypy-1.10.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:37fd87cab83f09842653f08de066ee68f1182b9b5282e4634cdb4b407266bade"}, {file = "mypy-1.10.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8addf6313777dbb92e9564c5d32ec122bf2c6c39d683ea64de6a1fd98b90fe37"}, {file = "mypy-1.10.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:5cc3ca0a244eb9a5249c7c583ad9a7e881aa5d7b73c35652296ddcdb33b2b9c7"}, {file = "mypy-1.10.1-cp38-cp38-win_amd64.whl", hash = "sha256:1b3a2ffce52cc4dbaeee4df762f20a2905aa171ef157b82192f2e2f368eec05d"}, {file = "mypy-1.10.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:fe85ed6836165d52ae8b88f99527d3d1b2362e0cb90b005409b8bed90e9059b3"}, {file = "mypy-1.10.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c2ae450d60d7d020d67ab440c6e3fae375809988119817214440033f26ddf7bf"}, {file = "mypy-1.10.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6be84c06e6abd72f960ba9a71561c14137a583093ffcf9bbfaf5e613d63fa531"}, {file = "mypy-1.10.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:2189ff1e39db399f08205e22a797383613ce1cb0cb3b13d8bcf0170e45b96cc3"}, {file = "mypy-1.10.1-cp39-cp39-win_amd64.whl", hash = "sha256:97a131ee36ac37ce9581f4220311247ab6cba896b4395b9c87af0675a13a755f"}, {file = "mypy-1.10.1-py3-none-any.whl", hash = "sha256:71d8ac0b906354ebda8ef1673e5fde785936ac1f29ff6987c7483cfbd5a4235a"}, {file = "mypy-1.10.1.tar.gz", hash = "sha256:1f8f492d7db9e3593ef42d4f115f04e556130f2819ad33ab84551403e97dd4c0"}, ] [package.dependencies] mypy-extensions = ">=1.0.0" tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} typing-extensions = ">=4.1.0" [package.extras] dmypy = ["psutil (>=4.0)"] install-types = ["pip"] mypyc = ["setuptools (>=50)"] reports = ["lxml"] [[package]] name = "mypy-extensions" version = "1.0.0" description = "Type system extensions for programs checked with the mypy type checker." category = "dev" optional = false python-versions = ">=3.5" files = [ {file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"}, {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, ] [[package]] name = "myst-parser" version = "3.0.1" description = "An extended [CommonMark](https://spec.commonmark.org/) compliant parser," category = "dev" optional = false python-versions = ">=3.8" files = [ {file = "myst_parser-3.0.1-py3-none-any.whl", hash = "sha256:6457aaa33a5d474aca678b8ead9b3dc298e89c68e67012e73146ea6fd54babf1"}, {file = "myst_parser-3.0.1.tar.gz", hash = "sha256:88f0cb406cb363b077d176b51c476f62d60604d68a8dcdf4832e080441301a87"}, ] [package.dependencies] docutils = ">=0.18,<0.22" jinja2 = "*" markdown-it-py = ">=3.0,<4.0" mdit-py-plugins = ">=0.4,<1.0" pyyaml = "*" sphinx = ">=6,<8" [package.extras] code-style = ["pre-commit (>=3.0,<4.0)"] linkify = ["linkify-it-py (>=2.0,<3.0)"] rtd = ["ipython", "sphinx (>=7)", "sphinx-autodoc2 (>=0.5.0,<0.6.0)", "sphinx-book-theme (>=1.1,<2.0)", "sphinx-copybutton", "sphinx-design", "sphinx-pyscript", "sphinx-tippy (>=0.4.3)", "sphinx-togglebutton", "sphinxext-opengraph (>=0.9.0,<0.10.0)", "sphinxext-rediraffe (>=0.2.7,<0.3.0)"] testing = ["beautifulsoup4", "coverage[toml]", "defusedxml", "pytest (>=8,<9)", "pytest-cov", "pytest-param-files (>=0.6.0,<0.7.0)", "pytest-regressions", "sphinx-pytest"] testing-docutils = ["pygments", "pytest (>=8,<9)", "pytest-param-files (>=0.6.0,<0.7.0)"] [[package]] name = "nodeenv" version = "1.9.1" description = "Node.js virtual environment builder" category = "dev" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" files = [ {file = "nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9"}, {file = "nodeenv-1.9.1.tar.gz", hash = "sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f"}, ] [[package]] name = "packaging" version = "24.1" description = "Core utilities for Python packages" category = "dev" optional = false python-versions = ">=3.8" files = [ {file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"}, {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"}, ] [[package]] name = "parso" version = "0.8.4" description = "A Python Parser" category = "dev" optional = false python-versions = ">=3.6" files = [ {file = "parso-0.8.4-py2.py3-none-any.whl", hash = "sha256:a418670a20291dacd2dddc80c377c5c3791378ee1e8d12bffc35420643d43f18"}, {file = "parso-0.8.4.tar.gz", hash = "sha256:eb3a7b58240fb99099a345571deecc0f9540ea5f4dd2fe14c2a99d6b281ab92d"}, ] [package.extras] qa = ["flake8 (==5.0.4)", "mypy (==0.971)", "types-setuptools (==67.2.0.1)"] testing = ["docopt", "pytest"] [[package]] name = "pathspec" version = "0.12.1" description = "Utility library for gitignore style pattern matching of file paths." category = "dev" optional = false python-versions = ">=3.8" files = [ {file = "pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08"}, {file = "pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712"}, ] [[package]] name = "pbr" version = "6.0.0" description = "Python Build Reasonableness" category = "dev" optional = false python-versions = ">=2.6" files = [ {file = "pbr-6.0.0-py2.py3-none-any.whl", hash = "sha256:4a7317d5e3b17a3dccb6a8cfe67dab65b20551404c52c8ed41279fa4f0cb4cda"}, {file = "pbr-6.0.0.tar.gz", hash = "sha256:d1377122a5a00e2f940ee482999518efe16d745d423a670c27773dfbc3c9a7d9"}, ] [[package]] name = "platformdirs" version = "4.2.2" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." category = "dev" optional = false python-versions = ">=3.8" files = [ {file = "platformdirs-4.2.2-py3-none-any.whl", hash = "sha256:2d7a1657e36a80ea911db832a8a6ece5ee53d8de21edd5cc5879af6530b1bfee"}, {file = "platformdirs-4.2.2.tar.gz", hash = "sha256:38b7b51f512eed9e84a22788b4bce1de17c0adb134d6becb09836e37d8654cd3"}, ] [package.extras] docs = ["furo (>=2023.9.10)", "proselint (>=0.13)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.25.2)"] test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)"] type = ["mypy (>=1.8)"] [[package]] name = "pluggy" version = "1.5.0" description = "plugin and hook calling mechanisms for python" category = "dev" optional = false python-versions = ">=3.8" files = [ {file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"}, {file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"}, ] [package.extras] dev = ["pre-commit", "tox"] testing = ["pytest", "pytest-benchmark"] [[package]] name = "pre-commit" version = "3.5.0" description = "A framework for managing and maintaining multi-language pre-commit hooks." category = "dev" optional = false python-versions = ">=3.8" files = [ {file = "pre_commit-3.5.0-py2.py3-none-any.whl", hash = "sha256:841dc9aef25daba9a0238cd27984041fa0467b4199fc4852e27950664919f660"}, {file = "pre_commit-3.5.0.tar.gz", hash = "sha256:5804465c675b659b0862f07907f96295d490822a450c4c40e747d0b1c6ebcb32"}, ] [package.dependencies] cfgv = ">=2.0.0" identify = ">=1.0.0" nodeenv = ">=0.11.1" pyyaml = ">=5.1" virtualenv = ">=20.10.0" [[package]] name = "protokolo" version = "2.1.4" description = "Protokolo is a change log generator." category = "dev" optional = false python-versions = "<4.0,>=3.11" files = [ {file = "protokolo-2.1.4-cp311-cp311-manylinux_2_36_x86_64.whl", hash = "sha256:b10ff72199e5ced3fd662a5b870b673bf37a5c990dd4eacf054bdf3ea5f2e359"}, {file = "protokolo-2.1.4.tar.gz", hash = "sha256:451addc697e43a2aac4db612acf747ffe839686e5ea71018a5bc1ea5adeddc08"}, ] [package.dependencies] attrs = ">=22.1.0" click = ">=8.0" [[package]] name = "pygments" version = "2.18.0" description = "Pygments is a syntax highlighting package written in Python." category = "dev" optional = false python-versions = ">=3.8" files = [ {file = "pygments-2.18.0-py3-none-any.whl", hash = "sha256:b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a"}, {file = "pygments-2.18.0.tar.gz", hash = "sha256:786ff802f32e91311bff3889f6e9a86e81505fe99f2735bb6d60ae0c5004f199"}, ] [package.extras] windows-terminal = ["colorama (>=0.4.6)"] [[package]] name = "pylint" version = "3.2.5" description = "python code static checker" category = "dev" optional = false python-versions = ">=3.8.0" files = [ {file = "pylint-3.2.5-py3-none-any.whl", hash = "sha256:32cd6c042b5004b8e857d727708720c54a676d1e22917cf1a2df9b4d4868abd6"}, {file = "pylint-3.2.5.tar.gz", hash = "sha256:e9b7171e242dcc6ebd0aaa7540481d1a72860748a0a7816b8fe6cf6c80a6fe7e"}, ] [package.dependencies] astroid = ">=3.2.2,<=3.3.0-dev0" colorama = {version = ">=0.4.5", markers = "sys_platform == \"win32\""} dill = [ {version = ">=0.2", markers = "python_version < \"3.11\""}, {version = ">=0.3.6", markers = "python_version >= \"3.11\""}, {version = ">=0.3.7", markers = "python_version >= \"3.12\""}, ] isort = ">=4.2.5,<5.13.0 || >5.13.0,<6" mccabe = ">=0.6,<0.8" platformdirs = ">=2.2.0" tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} tomlkit = ">=0.10.1" typing-extensions = {version = ">=3.10.0", markers = "python_version < \"3.10\""} [package.extras] spelling = ["pyenchant (>=3.2,<4.0)"] testutils = ["gitpython (>3)"] [[package]] name = "pyls-isort" version = "0.2.2" description = "Isort plugin for python-lsp-server" category = "dev" optional = false python-versions = "*" files = [ {file = "pyls-isort-0.2.2.tar.gz", hash = "sha256:2192bd2203db00459f85eb329521feba58af63075d2dd10a051a4eccd000bba0"}, ] [package.dependencies] isort = "*" python-lsp-server = "*" [[package]] name = "pylsp-mypy" version = "0.6.8" description = "Mypy linter for the Python LSP Server" category = "dev" optional = false python-versions = ">=3.8" files = [ {file = "pylsp-mypy-0.6.8.tar.gz", hash = "sha256:3f8307ca07d7e253e50e38c5fe31c371ceace0bc33d31c3429fa035d6d41bd5f"}, {file = "pylsp_mypy-0.6.8-py3-none-any.whl", hash = "sha256:3ea7c406d0f100317a212d8cd39075a2c139f1a4a2866d4412fe531b3f23b381"}, ] [package.dependencies] mypy = ">=0.981" python-lsp-server = ">=1.7.0" tomli = ">=1.1.0" [package.extras] test = ["coverage", "pytest", "pytest-cov", "tox"] [[package]] name = "pytest" version = "8.2.2" description = "pytest: simple powerful testing with Python" category = "dev" optional = false python-versions = ">=3.8" files = [ {file = "pytest-8.2.2-py3-none-any.whl", hash = "sha256:c434598117762e2bd304e526244f67bf66bbd7b5d6cf22138be51ff661980343"}, {file = "pytest-8.2.2.tar.gz", hash = "sha256:de4bb8104e201939ccdc688b27a89a7be2079b22e2bd2b07f806b6ba71117977"}, ] [package.dependencies] colorama = {version = "*", markers = "sys_platform == \"win32\""} exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""} iniconfig = "*" packaging = "*" pluggy = ">=1.5,<2.0" tomli = {version = ">=1", markers = "python_version < \"3.11\""} [package.extras] dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] [[package]] name = "pytest-cov" version = "5.0.0" description = "Pytest plugin for measuring coverage." category = "dev" optional = false python-versions = ">=3.8" files = [ {file = "pytest-cov-5.0.0.tar.gz", hash = "sha256:5837b58e9f6ebd335b0f8060eecce69b662415b16dc503883a02f45dfeb14857"}, {file = "pytest_cov-5.0.0-py3-none-any.whl", hash = "sha256:4f0764a1219df53214206bf1feea4633c3b558a2925c8b59f144f682861ce652"}, ] [package.dependencies] coverage = {version = ">=5.2.1", extras = ["toml"]} pytest = ">=4.6" [package.extras] testing = ["fields", "hunter", "process-tests", "pytest-xdist", "virtualenv"] [[package]] name = "python-dateutil" version = "2.9.0.post0" description = "Extensions to the standard Python datetime module" category = "dev" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ {file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"}, {file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"}, ] [package.dependencies] six = ">=1.5" [[package]] name = "python-debian" version = "0.1.49" description = "Debian package related modules" category = "main" optional = false python-versions = ">=3.5" files = [ {file = "python-debian-0.1.49.tar.gz", hash = "sha256:8cf677a30dbcb4be7a99536c17e11308a827a4d22028dc59a67f6c6dd3f0f58c"}, {file = "python_debian-0.1.49-py3-none-any.whl", hash = "sha256:880f3bc52e31599f2a9b432bd7691844286825087fccdcf2f6ffd5cd79a26f9f"}, ] [package.dependencies] chardet = "*" [[package]] name = "python-lsp-black" version = "2.0.0" description = "Black plugin for the Python LSP Server" category = "dev" optional = false python-versions = ">=3.8" files = [ {file = "python-lsp-black-2.0.0.tar.gz", hash = "sha256:8286d2d310c566844b3c116b824ada6fccfa6ba228b1a09a0526b74c04e0805f"}, {file = "python_lsp_black-2.0.0-py3-none-any.whl", hash = "sha256:d5efdee45f5fa9e5241f5d4d396cd46127f45c85817916b1fd92c2986652bf7e"}, ] [package.dependencies] black = ">=23.11.0" python-lsp-server = ">=1.4.0" tomli = {version = "*", markers = "python_version < \"3.11\""} [package.extras] dev = ["flake8", "isort (>=5.0)", "mypy", "pre-commit", "pytest", "types-pkg-resources", "types-setuptools"] [[package]] name = "python-lsp-jsonrpc" version = "1.1.2" description = "JSON RPC 2.0 server library" category = "dev" optional = false python-versions = ">=3.8" files = [ {file = "python-lsp-jsonrpc-1.1.2.tar.gz", hash = "sha256:4688e453eef55cd952bff762c705cedefa12055c0aec17a06f595bcc002cc912"}, {file = "python_lsp_jsonrpc-1.1.2-py3-none-any.whl", hash = "sha256:7339c2e9630ae98903fdaea1ace8c47fba0484983794d6aafd0bd8989be2b03c"}, ] [package.dependencies] ujson = ">=3.0.0" [package.extras] test = ["coverage", "pycodestyle", "pyflakes", "pylint", "pytest", "pytest-cov"] [[package]] name = "python-lsp-server" version = "1.11.0" description = "Python Language Server for the Language Server Protocol" category = "dev" optional = false python-versions = ">=3.8" files = [ {file = "python-lsp-server-1.11.0.tar.gz", hash = "sha256:89edd6fb3f7852e4bf5a3d1d95ea41484d1a28fa94b6e3cbff12b9db123b8e86"}, {file = "python_lsp_server-1.11.0-py3-none-any.whl", hash = "sha256:278cb41ea69ca9f84ec99d4edc96ff5f2f9e795d240771dc46dc1653f56ddfe3"}, ] [package.dependencies] docstring-to-markdown = "*" importlib-metadata = {version = ">=4.8.3", markers = "python_version < \"3.10\""} jedi = ">=0.17.2,<0.20.0" pluggy = ">=1.0.0" python-lsp-jsonrpc = ">=1.1.0,<2.0.0" ujson = ">=3.0.0" [package.extras] all = ["autopep8 (>=2.0.4,<2.1.0)", "flake8 (>=7,<8)", "mccabe (>=0.7.0,<0.8.0)", "pycodestyle (>=2.11.0,<2.12.0)", "pydocstyle (>=6.3.0,<6.4.0)", "pyflakes (>=3.2.0,<3.3.0)", "pylint (>=3.1,<4)", "rope (>=1.11.0)", "whatthepatch (>=1.0.2,<2.0.0)", "yapf (>=0.33.0)"] autopep8 = ["autopep8 (>=2.0.4,<2.1.0)"] flake8 = ["flake8 (>=7,<8)"] mccabe = ["mccabe (>=0.7.0,<0.8.0)"] pycodestyle = ["pycodestyle (>=2.11.0,<2.12.0)"] pydocstyle = ["pydocstyle (>=6.3.0,<6.4.0)"] pyflakes = ["pyflakes (>=3.2.0,<3.3.0)"] pylint = ["pylint (>=3.1,<4)"] rope = ["rope (>=1.11.0)"] test = ["coverage", "flaky", "matplotlib", "numpy", "pandas", "pylint (>=3.1,<4)", "pyqt5", "pytest", "pytest-cov"] websockets = ["websockets (>=10.3)"] yapf = ["whatthepatch (>=1.0.2,<2.0.0)", "yapf (>=0.33.0)"] [[package]] name = "pytz" version = "2024.1" description = "World timezone definitions, modern and historical" category = "dev" optional = false python-versions = "*" files = [ {file = "pytz-2024.1-py2.py3-none-any.whl", hash = "sha256:328171f4e3623139da4983451950b28e95ac706e13f3f2630a879749e7a8b319"}, {file = "pytz-2024.1.tar.gz", hash = "sha256:2a29735ea9c18baf14b448846bde5a48030ed267578472d8955cd0e7443a9812"}, ] [[package]] name = "pyyaml" version = "6.0.1" description = "YAML parser and emitter for Python" category = "dev" optional = false python-versions = ">=3.6" files = [ {file = "PyYAML-6.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a"}, {file = "PyYAML-6.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f"}, {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"}, {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"}, {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"}, {file = "PyYAML-6.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290"}, {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"}, {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"}, {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"}, {file = "PyYAML-6.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab"}, {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"}, {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"}, {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"}, {file = "PyYAML-6.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b"}, {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"}, {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, {file = "PyYAML-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df"}, {file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"}, {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"}, {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"}, {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd"}, {file = "PyYAML-6.0.1-cp36-cp36m-win32.whl", hash = "sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585"}, {file = "PyYAML-6.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa"}, {file = "PyYAML-6.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3"}, {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27"}, {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3"}, {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c"}, {file = "PyYAML-6.0.1-cp37-cp37m-win32.whl", hash = "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba"}, {file = "PyYAML-6.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867"}, {file = "PyYAML-6.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595"}, {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"}, {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"}, {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"}, {file = "PyYAML-6.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6"}, {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"}, {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"}, {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"}, {file = "PyYAML-6.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859"}, {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"}, {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"}, {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"}, {file = "PyYAML-6.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5"}, {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"}, {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"}, {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, ] [[package]] name = "requests" version = "2.32.3" description = "Python HTTP for Humans." category = "dev" optional = false python-versions = ">=3.8" files = [ {file = "requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6"}, {file = "requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760"}, ] [package.dependencies] certifi = ">=2017.4.17" charset-normalizer = ">=2,<4" idna = ">=2.5,<4" urllib3 = ">=1.21.1,<3" [package.extras] socks = ["PySocks (>=1.5.6,!=1.5.7)"] use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] [[package]] name = "six" version = "1.16.0" description = "Python 2 and 3 compatibility utilities" category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" files = [ {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, ] [[package]] name = "smmap" version = "5.0.1" description = "A pure Python implementation of a sliding window memory map manager" category = "dev" optional = false python-versions = ">=3.7" files = [ {file = "smmap-5.0.1-py3-none-any.whl", hash = "sha256:e6d8668fa5f93e706934a62d7b4db19c8d9eb8cf2adbb75ef1b675aa332b69da"}, {file = "smmap-5.0.1.tar.gz", hash = "sha256:dceeb6c0028fdb6734471eb07c0cd2aae706ccaecab45965ee83f11c8d3b1f62"}, ] [[package]] name = "snowballstemmer" version = "2.2.0" description = "This package provides 29 stemmers for 28 languages generated from Snowball algorithms." category = "dev" optional = false python-versions = "*" files = [ {file = "snowballstemmer-2.2.0-py2.py3-none-any.whl", hash = "sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a"}, {file = "snowballstemmer-2.2.0.tar.gz", hash = "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1"}, ] [[package]] name = "soupsieve" version = "2.5" description = "A modern CSS selector implementation for Beautiful Soup." category = "dev" optional = false python-versions = ">=3.8" files = [ {file = "soupsieve-2.5-py3-none-any.whl", hash = "sha256:eaa337ff55a1579b6549dc679565eac1e3d000563bcb1c8ab0d0fefbc0c2cdc7"}, {file = "soupsieve-2.5.tar.gz", hash = "sha256:5663d5a7b3bfaeee0bc4372e7fc48f9cff4940b3eec54a6451cc5299f1097690"}, ] [[package]] name = "sphinx" version = "7.1.2" description = "Python documentation generator" category = "dev" optional = false python-versions = ">=3.8" files = [ {file = "sphinx-7.1.2-py3-none-any.whl", hash = "sha256:d170a81825b2fcacb6dfd5a0d7f578a053e45d3f2b153fecc948c37344eb4cbe"}, {file = "sphinx-7.1.2.tar.gz", hash = "sha256:780f4d32f1d7d1126576e0e5ecc19dc32ab76cd24e950228dcf7b1f6d3d9e22f"}, ] [package.dependencies] alabaster = ">=0.7,<0.8" babel = ">=2.9" colorama = {version = ">=0.4.5", markers = "sys_platform == \"win32\""} docutils = ">=0.18.1,<0.21" imagesize = ">=1.3" importlib-metadata = {version = ">=4.8", markers = "python_version < \"3.10\""} Jinja2 = ">=3.0" packaging = ">=21.0" Pygments = ">=2.13" requests = ">=2.25.0" snowballstemmer = ">=2.0" sphinxcontrib-applehelp = "*" sphinxcontrib-devhelp = "*" sphinxcontrib-htmlhelp = ">=2.0.0" sphinxcontrib-jsmath = "*" sphinxcontrib-qthelp = "*" sphinxcontrib-serializinghtml = ">=1.1.5" [package.extras] docs = ["sphinxcontrib-websupport"] lint = ["docutils-stubs", "flake8 (>=3.5.0)", "flake8-simplify", "isort", "mypy (>=0.990)", "ruff", "sphinx-lint", "types-requests"] test = ["cython", "filelock", "html5lib", "pytest (>=4.6)"] [[package]] name = "sphinx-basic-ng" version = "1.0.0b2" description = "A modern skeleton for Sphinx themes." category = "dev" optional = false python-versions = ">=3.7" files = [ {file = "sphinx_basic_ng-1.0.0b2-py3-none-any.whl", hash = "sha256:eb09aedbabfb650607e9b4b68c9d240b90b1e1be221d6ad71d61c52e29f7932b"}, {file = "sphinx_basic_ng-1.0.0b2.tar.gz", hash = "sha256:9ec55a47c90c8c002b5960c57492ec3021f5193cb26cebc2dc4ea226848651c9"}, ] [package.dependencies] sphinx = ">=4.0" [package.extras] docs = ["furo", "ipython", "myst-parser", "sphinx-copybutton", "sphinx-inline-tabs"] [[package]] name = "sphinxcontrib-apidoc" version = "0.5.0" description = "A Sphinx extension for running 'sphinx-apidoc' on each build" category = "dev" optional = false python-versions = ">=3.8" files = [ {file = "sphinxcontrib-apidoc-0.5.0.tar.gz", hash = "sha256:65efcd92212a5f823715fb95ee098b458a6bb09a5ee617d9ed3dead97177cd55"}, {file = "sphinxcontrib_apidoc-0.5.0-py3-none-any.whl", hash = "sha256:c671d644d6dc468be91b813dcddf74d87893bff74fe8f1b8b01b69408f0fb776"}, ] [package.dependencies] pbr = "*" Sphinx = ">=5.0.0" [[package]] name = "sphinxcontrib-applehelp" version = "1.0.4" description = "sphinxcontrib-applehelp is a Sphinx extension which outputs Apple help books" category = "dev" optional = false python-versions = ">=3.8" files = [ {file = "sphinxcontrib-applehelp-1.0.4.tar.gz", hash = "sha256:828f867945bbe39817c210a1abfd1bc4895c8b73fcaade56d45357a348a07d7e"}, {file = "sphinxcontrib_applehelp-1.0.4-py3-none-any.whl", hash = "sha256:29d341f67fb0f6f586b23ad80e072c8e6ad0b48417db2bde114a4c9746feb228"}, ] [package.extras] lint = ["docutils-stubs", "flake8", "mypy"] test = ["pytest"] [[package]] name = "sphinxcontrib-devhelp" version = "1.0.2" description = "sphinxcontrib-devhelp is a sphinx extension which outputs Devhelp document." category = "dev" optional = false python-versions = ">=3.5" files = [ {file = "sphinxcontrib-devhelp-1.0.2.tar.gz", hash = "sha256:ff7f1afa7b9642e7060379360a67e9c41e8f3121f2ce9164266f61b9f4b338e4"}, {file = "sphinxcontrib_devhelp-1.0.2-py2.py3-none-any.whl", hash = "sha256:8165223f9a335cc1af7ffe1ed31d2871f325254c0423bc0c4c7cd1c1e4734a2e"}, ] [package.extras] lint = ["docutils-stubs", "flake8", "mypy"] test = ["pytest"] [[package]] name = "sphinxcontrib-htmlhelp" version = "2.0.1" description = "sphinxcontrib-htmlhelp is a sphinx extension which renders HTML help files" category = "dev" optional = false python-versions = ">=3.8" files = [ {file = "sphinxcontrib-htmlhelp-2.0.1.tar.gz", hash = "sha256:0cbdd302815330058422b98a113195c9249825d681e18f11e8b1f78a2f11efff"}, {file = "sphinxcontrib_htmlhelp-2.0.1-py3-none-any.whl", hash = "sha256:c38cb46dccf316c79de6e5515e1770414b797162b23cd3d06e67020e1d2a6903"}, ] [package.extras] lint = ["docutils-stubs", "flake8", "mypy"] test = ["html5lib", "pytest"] [[package]] name = "sphinxcontrib-jsmath" version = "1.0.1" description = "A sphinx extension which renders display math in HTML via JavaScript" category = "dev" optional = false python-versions = ">=3.5" files = [ {file = "sphinxcontrib-jsmath-1.0.1.tar.gz", hash = "sha256:a9925e4a4587247ed2191a22df5f6970656cb8ca2bd6284309578f2153e0c4b8"}, {file = "sphinxcontrib_jsmath-1.0.1-py2.py3-none-any.whl", hash = "sha256:2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178"}, ] [package.extras] test = ["flake8", "mypy", "pytest"] [[package]] name = "sphinxcontrib-qthelp" version = "1.0.3" description = "sphinxcontrib-qthelp is a sphinx extension which outputs QtHelp document." category = "dev" optional = false python-versions = ">=3.5" files = [ {file = "sphinxcontrib-qthelp-1.0.3.tar.gz", hash = "sha256:4c33767ee058b70dba89a6fc5c1892c0d57a54be67ddd3e7875a18d14cba5a72"}, {file = "sphinxcontrib_qthelp-1.0.3-py2.py3-none-any.whl", hash = "sha256:bd9fc24bcb748a8d51fd4ecaade681350aa63009a347a8c14e637895444dfab6"}, ] [package.extras] lint = ["docutils-stubs", "flake8", "mypy"] test = ["pytest"] [[package]] name = "sphinxcontrib-serializinghtml" version = "1.1.5" description = "sphinxcontrib-serializinghtml is a sphinx extension which outputs \"serialized\" HTML files (json and pickle)." category = "dev" optional = false python-versions = ">=3.5" files = [ {file = "sphinxcontrib-serializinghtml-1.1.5.tar.gz", hash = "sha256:aa5f6de5dfdf809ef505c4895e51ef5c9eac17d0f287933eb49ec495280b6952"}, {file = "sphinxcontrib_serializinghtml-1.1.5-py2.py3-none-any.whl", hash = "sha256:352a9a00ae864471d3a7ead8d7d79f5fc0b57e8b3f95e9867eb9eb28999b92fd"}, ] [package.extras] lint = ["docutils-stubs", "flake8", "mypy"] test = ["pytest"] [[package]] name = "toml" version = "0.10.2" description = "Python Library for Tom's Obvious, Minimal Language" category = "dev" optional = false python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" files = [ {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"}, {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, ] [[package]] name = "tomli" version = "2.0.1" description = "A lil' TOML parser" category = "dev" optional = false python-versions = ">=3.7" files = [ {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, ] [[package]] name = "tomlkit" version = "0.12.5" description = "Style preserving TOML library" category = "main" optional = false python-versions = ">=3.7" files = [ {file = "tomlkit-0.12.5-py3-none-any.whl", hash = "sha256:af914f5a9c59ed9d0762c7b64d3b5d5df007448eb9cd2edc8a46b1eafead172f"}, {file = "tomlkit-0.12.5.tar.gz", hash = "sha256:eef34fba39834d4d6b73c9ba7f3e4d1c417a4e56f89a7e96e090dd0d24b8fb3c"}, ] [[package]] name = "typing-extensions" version = "4.12.2" description = "Backported and Experimental Type Hints for Python 3.8+" category = "dev" optional = false python-versions = ">=3.8" files = [ {file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"}, {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, ] [[package]] name = "ujson" version = "5.10.0" description = "Ultra fast JSON encoder and decoder for Python" category = "dev" optional = false python-versions = ">=3.8" files = [ {file = "ujson-5.10.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2601aa9ecdbee1118a1c2065323bda35e2c5a2cf0797ef4522d485f9d3ef65bd"}, {file = "ujson-5.10.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:348898dd702fc1c4f1051bc3aacbf894caa0927fe2c53e68679c073375f732cf"}, {file = "ujson-5.10.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22cffecf73391e8abd65ef5f4e4dd523162a3399d5e84faa6aebbf9583df86d6"}, {file = "ujson-5.10.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:26b0e2d2366543c1bb4fbd457446f00b0187a2bddf93148ac2da07a53fe51569"}, {file = "ujson-5.10.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:caf270c6dba1be7a41125cd1e4fc7ba384bf564650beef0df2dd21a00b7f5770"}, {file = "ujson-5.10.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a245d59f2ffe750446292b0094244df163c3dc96b3ce152a2c837a44e7cda9d1"}, {file = "ujson-5.10.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:94a87f6e151c5f483d7d54ceef83b45d3a9cca7a9cb453dbdbb3f5a6f64033f5"}, {file = "ujson-5.10.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:29b443c4c0a113bcbb792c88bea67b675c7ca3ca80c3474784e08bba01c18d51"}, {file = "ujson-5.10.0-cp310-cp310-win32.whl", hash = "sha256:c18610b9ccd2874950faf474692deee4223a994251bc0a083c114671b64e6518"}, {file = "ujson-5.10.0-cp310-cp310-win_amd64.whl", hash = "sha256:924f7318c31874d6bb44d9ee1900167ca32aa9b69389b98ecbde34c1698a250f"}, {file = "ujson-5.10.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a5b366812c90e69d0f379a53648be10a5db38f9d4ad212b60af00bd4048d0f00"}, {file = "ujson-5.10.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:502bf475781e8167f0f9d0e41cd32879d120a524b22358e7f205294224c71126"}, {file = "ujson-5.10.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5b91b5d0d9d283e085e821651184a647699430705b15bf274c7896f23fe9c9d8"}, {file = "ujson-5.10.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:129e39af3a6d85b9c26d5577169c21d53821d8cf68e079060602e861c6e5da1b"}, {file = "ujson-5.10.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f77b74475c462cb8b88680471193064d3e715c7c6074b1c8c412cb526466efe9"}, {file = "ujson-5.10.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:7ec0ca8c415e81aa4123501fee7f761abf4b7f386aad348501a26940beb1860f"}, {file = "ujson-5.10.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:ab13a2a9e0b2865a6c6db9271f4b46af1c7476bfd51af1f64585e919b7c07fd4"}, {file = "ujson-5.10.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:57aaf98b92d72fc70886b5a0e1a1ca52c2320377360341715dd3933a18e827b1"}, {file = "ujson-5.10.0-cp311-cp311-win32.whl", hash = "sha256:2987713a490ceb27edff77fb184ed09acdc565db700ee852823c3dc3cffe455f"}, {file = "ujson-5.10.0-cp311-cp311-win_amd64.whl", hash = "sha256:f00ea7e00447918ee0eff2422c4add4c5752b1b60e88fcb3c067d4a21049a720"}, {file = "ujson-5.10.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:98ba15d8cbc481ce55695beee9f063189dce91a4b08bc1d03e7f0152cd4bbdd5"}, {file = "ujson-5.10.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a9d2edbf1556e4f56e50fab7d8ff993dbad7f54bac68eacdd27a8f55f433578e"}, {file = "ujson-5.10.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6627029ae4f52d0e1a2451768c2c37c0c814ffc04f796eb36244cf16b8e57043"}, {file = "ujson-5.10.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8ccb77b3e40b151e20519c6ae6d89bfe3f4c14e8e210d910287f778368bb3d1"}, {file = "ujson-5.10.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3caf9cd64abfeb11a3b661329085c5e167abbe15256b3b68cb5d914ba7396f3"}, {file = "ujson-5.10.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6e32abdce572e3a8c3d02c886c704a38a1b015a1fb858004e03d20ca7cecbb21"}, {file = "ujson-5.10.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:a65b6af4d903103ee7b6f4f5b85f1bfd0c90ba4eeac6421aae436c9988aa64a2"}, {file = "ujson-5.10.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:604a046d966457b6cdcacc5aa2ec5314f0e8c42bae52842c1e6fa02ea4bda42e"}, {file = "ujson-5.10.0-cp312-cp312-win32.whl", hash = "sha256:6dea1c8b4fc921bf78a8ff00bbd2bfe166345f5536c510671bccececb187c80e"}, {file = "ujson-5.10.0-cp312-cp312-win_amd64.whl", hash = "sha256:38665e7d8290188b1e0d57d584eb8110951a9591363316dd41cf8686ab1d0abc"}, {file = "ujson-5.10.0-cp313-cp313-macosx_10_9_x86_64.whl", hash = "sha256:618efd84dc1acbd6bff8eaa736bb6c074bfa8b8a98f55b61c38d4ca2c1f7f287"}, {file = "ujson-5.10.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:38d5d36b4aedfe81dfe251f76c0467399d575d1395a1755de391e58985ab1c2e"}, {file = "ujson-5.10.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:67079b1f9fb29ed9a2914acf4ef6c02844b3153913eb735d4bf287ee1db6e557"}, {file = "ujson-5.10.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d7d0e0ceeb8fe2468c70ec0c37b439dd554e2aa539a8a56365fd761edb418988"}, {file = "ujson-5.10.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:59e02cd37bc7c44d587a0ba45347cc815fb7a5fe48de16bf05caa5f7d0d2e816"}, {file = "ujson-5.10.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:2a890b706b64e0065f02577bf6d8ca3b66c11a5e81fb75d757233a38c07a1f20"}, {file = "ujson-5.10.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:621e34b4632c740ecb491efc7f1fcb4f74b48ddb55e65221995e74e2d00bbff0"}, {file = "ujson-5.10.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:b9500e61fce0cfc86168b248104e954fead61f9be213087153d272e817ec7b4f"}, {file = "ujson-5.10.0-cp313-cp313-win32.whl", hash = "sha256:4c4fc16f11ac1612f05b6f5781b384716719547e142cfd67b65d035bd85af165"}, {file = "ujson-5.10.0-cp313-cp313-win_amd64.whl", hash = "sha256:4573fd1695932d4f619928fd09d5d03d917274381649ade4328091ceca175539"}, {file = "ujson-5.10.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:a984a3131da7f07563057db1c3020b1350a3e27a8ec46ccbfbf21e5928a43050"}, {file = "ujson-5.10.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:73814cd1b9db6fc3270e9d8fe3b19f9f89e78ee9d71e8bd6c9a626aeaeaf16bd"}, {file = "ujson-5.10.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:61e1591ed9376e5eddda202ec229eddc56c612b61ac6ad07f96b91460bb6c2fb"}, {file = "ujson-5.10.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2c75269f8205b2690db4572a4a36fe47cd1338e4368bc73a7a0e48789e2e35a"}, {file = "ujson-5.10.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7223f41e5bf1f919cd8d073e35b229295aa8e0f7b5de07ed1c8fddac63a6bc5d"}, {file = "ujson-5.10.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:d4dc2fd6b3067c0782e7002ac3b38cf48608ee6366ff176bbd02cf969c9c20fe"}, {file = "ujson-5.10.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:232cc85f8ee3c454c115455195a205074a56ff42608fd6b942aa4c378ac14dd7"}, {file = "ujson-5.10.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:cc6139531f13148055d691e442e4bc6601f6dba1e6d521b1585d4788ab0bfad4"}, {file = "ujson-5.10.0-cp38-cp38-win32.whl", hash = "sha256:e7ce306a42b6b93ca47ac4a3b96683ca554f6d35dd8adc5acfcd55096c8dfcb8"}, {file = "ujson-5.10.0-cp38-cp38-win_amd64.whl", hash = "sha256:e82d4bb2138ab05e18f089a83b6564fee28048771eb63cdecf4b9b549de8a2cc"}, {file = "ujson-5.10.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:dfef2814c6b3291c3c5f10065f745a1307d86019dbd7ea50e83504950136ed5b"}, {file = "ujson-5.10.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4734ee0745d5928d0ba3a213647f1c4a74a2a28edc6d27b2d6d5bd9fa4319e27"}, {file = "ujson-5.10.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d47ebb01bd865fdea43da56254a3930a413f0c5590372a1241514abae8aa7c76"}, {file = "ujson-5.10.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dee5e97c2496874acbf1d3e37b521dd1f307349ed955e62d1d2f05382bc36dd5"}, {file = "ujson-5.10.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7490655a2272a2d0b072ef16b0b58ee462f4973a8f6bbe64917ce5e0a256f9c0"}, {file = "ujson-5.10.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:ba17799fcddaddf5c1f75a4ba3fd6441f6a4f1e9173f8a786b42450851bd74f1"}, {file = "ujson-5.10.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:2aff2985cef314f21d0fecc56027505804bc78802c0121343874741650a4d3d1"}, {file = "ujson-5.10.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:ad88ac75c432674d05b61184178635d44901eb749786c8eb08c102330e6e8996"}, {file = "ujson-5.10.0-cp39-cp39-win32.whl", hash = "sha256:2544912a71da4ff8c4f7ab5606f947d7299971bdd25a45e008e467ca638d13c9"}, {file = "ujson-5.10.0-cp39-cp39-win_amd64.whl", hash = "sha256:3ff201d62b1b177a46f113bb43ad300b424b7847f9c5d38b1b4ad8f75d4a282a"}, {file = "ujson-5.10.0-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:5b6fee72fa77dc172a28f21693f64d93166534c263adb3f96c413ccc85ef6e64"}, {file = "ujson-5.10.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:61d0af13a9af01d9f26d2331ce49bb5ac1fb9c814964018ac8df605b5422dcb3"}, {file = "ujson-5.10.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ecb24f0bdd899d368b715c9e6664166cf694d1e57be73f17759573a6986dd95a"}, {file = "ujson-5.10.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fbd8fd427f57a03cff3ad6574b5e299131585d9727c8c366da4624a9069ed746"}, {file = "ujson-5.10.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:beeaf1c48e32f07d8820c705ff8e645f8afa690cca1544adba4ebfa067efdc88"}, {file = "ujson-5.10.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:baed37ea46d756aca2955e99525cc02d9181de67f25515c468856c38d52b5f3b"}, {file = "ujson-5.10.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:7663960f08cd5a2bb152f5ee3992e1af7690a64c0e26d31ba7b3ff5b2ee66337"}, {file = "ujson-5.10.0-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:d8640fb4072d36b08e95a3a380ba65779d356b2fee8696afeb7794cf0902d0a1"}, {file = "ujson-5.10.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78778a3aa7aafb11e7ddca4e29f46bc5139131037ad628cc10936764282d6753"}, {file = "ujson-5.10.0-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b0111b27f2d5c820e7f2dbad7d48e3338c824e7ac4d2a12da3dc6061cc39c8e6"}, {file = "ujson-5.10.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:c66962ca7565605b355a9ed478292da628b8f18c0f2793021ca4425abf8b01e5"}, {file = "ujson-5.10.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:ba43cc34cce49cf2d4bc76401a754a81202d8aa926d0e2b79f0ee258cb15d3a4"}, {file = "ujson-5.10.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:ac56eb983edce27e7f51d05bc8dd820586c6e6be1c5216a6809b0c668bb312b8"}, {file = "ujson-5.10.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f44bd4b23a0e723bf8b10628288c2c7c335161d6840013d4d5de20e48551773b"}, {file = "ujson-5.10.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7c10f4654e5326ec14a46bcdeb2b685d4ada6911050aa8baaf3501e57024b804"}, {file = "ujson-5.10.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0de4971a89a762398006e844ae394bd46991f7c385d7a6a3b93ba229e6dac17e"}, {file = "ujson-5.10.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:e1402f0564a97d2a52310ae10a64d25bcef94f8dd643fcf5d310219d915484f7"}, {file = "ujson-5.10.0.tar.gz", hash = "sha256:b3cd8f3c5d8c7738257f1018880444f7b7d9b66232c64649f562d7ba86ad4bc1"}, ] [[package]] name = "urllib3" version = "2.2.2" description = "HTTP library with thread-safe connection pooling, file post, and more." category = "dev" optional = false python-versions = ">=3.8" files = [ {file = "urllib3-2.2.2-py3-none-any.whl", hash = "sha256:a448b2f64d686155468037e1ace9f2d2199776e17f0a46610480d311f73e3472"}, {file = "urllib3-2.2.2.tar.gz", hash = "sha256:dd505485549a7a552833da5e6063639d0d177c04f23bc3864e41e5dc5f612168"}, ] [package.extras] brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] h2 = ["h2 (>=4,<5)"] socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] zstd = ["zstandard (>=0.18.0)"] [[package]] name = "virtualenv" version = "20.26.3" description = "Virtual Python Environment builder" category = "dev" optional = false python-versions = ">=3.7" files = [ {file = "virtualenv-20.26.3-py3-none-any.whl", hash = "sha256:8cc4a31139e796e9a7de2cd5cf2489de1217193116a8fd42328f1bd65f434589"}, {file = "virtualenv-20.26.3.tar.gz", hash = "sha256:4c43a2a236279d9ea36a0d76f98d84bd6ca94ac4e0f4a3b9d46d05e10fea542a"}, ] [package.dependencies] distlib = ">=0.3.7,<1" filelock = ">=3.12.2,<4" platformdirs = ">=3.9.1,<5" [package.extras] docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.2,!=7.3)", "sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=23.6)"] test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=23.1)", "pytest (>=7.4)", "pytest-env (>=0.8.2)", "pytest-freezer (>=0.4.8)", "pytest-mock (>=3.11.1)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)", "setuptools (>=68)", "time-machine (>=2.10)"] [[package]] name = "zipp" version = "3.19.2" description = "Backport of pathlib-compatible object wrapper for zip files" category = "dev" optional = false python-versions = ">=3.8" files = [ {file = "zipp-3.19.2-py3-none-any.whl", hash = "sha256:f091755f667055f2d02b32c53771a7a6c8b47e1fdbc4b72a8b9072b3eef8015c"}, {file = "zipp-3.19.2.tar.gz", hash = "sha256:bf1dcf6450f873a13e952a29504887c89e6de7506209e5b1bcc3460135d4de19"}, ] [package.extras] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] test = ["big-O", "importlib-resources", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more-itertools", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-ignore-flaky", "pytest-mypy", "pytest-ruff (>=0.2.1)"] [metadata] lock-version = "2.0" python-versions = "^3.8" content-hash = "3f000ef7f191dd1e5648641ddfef4e469429e33e583299bbcac630bfd59ac10b" reuse-tool-4.0.3/pyproject.toml000066400000000000000000000100121464275211500165310ustar00rootroot00000000000000# SPDX-FileCopyrightText: 2018 Free Software Foundation Europe e.V. # SPDX-FileCopyrightText: 2022 Alliander N.V. # SPDX-FileCopyrightText: 2022 Carmen Bianca Bakker # SPDX-FileCopyrightText: 2023 DB Systel GmbH # # SPDX-License-Identifier: GPL-3.0-or-later [tool.poetry] name = "reuse" version = "4.0.3" description = "reuse is a tool for compliance with the REUSE recommendations." authors = [ "Free Software Foundation Europe ", ] maintainers = [ "Carmen Bianca Bakker ", "Max Mehl ", "Linus Sehn ", ] license = "Apache-2.0 AND CC0-1.0 AND CC-BY-SA-4.0 AND GPL-3.0-or-later" readme = "README.md" packages = [ { include = "reuse", from = "src" } ] include = [ { path = "src/reuse/locale/**/*.mo", format="wheel" }, { path = "tests", format = "sdist" }, { path = "po", format = "sdist" }, { path = "AUTHORS.rst", format = "sdist" }, { path = "README.md", format = "sdist" }, { path = "CHANGELOG.md", format = "sdist" }, { path = "CONTRIBUTING.md", format = "sdist" }, { path = ".reuse", format = "sdist" }, { path = "REUSE.toml", format = "sdist" }, { path = "LICENSES", format = "sdist" }, { path = "docs", format = "sdist" }, ] homepage = "https://reuse.software/" repository = "https://github.com/fsfe/reuse-tool" documentation = "https://reuse.readthedocs.org/" classifiers = [ "Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", "License :: OSI Approved", "License :: DFSG approved", "License :: CC0 1.0 Universal (CC0 1.0) Public Domain Dedication", "License :: OSI Approved :: Apache Software License", "License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)", ] [tool.poetry.dependencies] python = "^3.8" Jinja2 = ">=3.0.0" binaryornot = ">=0.4.4" "boolean.py" = ">=3.8" license-expression = ">=1.0" python-debian = ">=0.1.34,!=0.1.45,!=0.1.46,!=0.1.47" tomlkit = ">=0.8" attrs = ">=21.3" [tool.poetry.group.test.dependencies] pytest = ">=6.0.0" pytest-cov = ">=2.10.0" freezegun = ">=1.0.0" [tool.poetry.group.docs.dependencies] Sphinx = ">=4.0.0" myst-parser = ">=2.0.0" sphinxcontrib-apidoc = ">=0.3.0" furo = ">=2023.3.27" [tool.poetry.group.dev.dependencies] black = ">=20" isort = ">=5.6.0" pre-commit = ">=2.9.0" bumpver = ">=2023.1129" pylint = ">=2.12.2" mypy = ">=1.0" GitPython = ">=3.0" protokolo = { version = ">=2.1.0", python = "^3.11" } [tool.poetry.group.lsp] optional = true [tool.poetry.group.lsp.dependencies] python-lsp-server = "*" pylsp-mypy = "*" pyls-isort = "*" python-lsp-black = "*" [tool.poetry.scripts] reuse = 'reuse._main:main' [tool.poetry.build] generate-setup-file = false script = "_build.py" [build-system] requires = ["poetry-core>=1.1.0"] build-backend = "poetry.core.masonry.api" [bumpver] current_version = "v4.0.3" version_pattern = "vMAJOR.MINOR.PATCH[PYTAGNUM]" commit_message = "Bump version: {old_version} → {new_version}" tag_message = "{new_version}" tag_scope = "default" pre_commit_hook = "" post_commit_hook = "" commit = true tag = false push = false [bumpver.file_patterns] "pyproject.toml" = [ '^version = "{pep440_version}"$', '^current_version = "{version}"$', ] "src/reuse/__init__.py" = [ '__version__ = "{pep440_version}"$', ] [tool.protokolo] changelog = "CHANGELOG.md" markup = "markdown" directory = "changelog.d" [tool.black] line-length = 80 [tool.isort] multi_line_output = 3 include_trailing_comma = true force_grid_wrap = 0 use_parentheses = true line_length = 80 [tool.pytest.ini_options] addopts = "--doctest-modules" [tool.mypy] files = [ "src/reuse/**.py", "tests/**.py", ] exclude = [ '^_build\.py$', '^conf\.py$', ] [[tool.mypy.overrides]] module = "reuse.*" disallow_untyped_defs = true disallow_incomplete_defs = true [[tool.mypy.overrides]] module = [ "binaryornot.check", "boolean.boolean", "license_expression", "pkg_resources", ] ignore_missing_imports = true reuse-tool-4.0.3/src/000077500000000000000000000000001464275211500144125ustar00rootroot00000000000000reuse-tool-4.0.3/src/reuse/000077500000000000000000000000001464275211500155355ustar00rootroot00000000000000reuse-tool-4.0.3/src/reuse/__init__.py000066400000000000000000000145221464275211500176520ustar00rootroot00000000000000# SPDX-FileCopyrightText: 2017 Free Software Foundation Europe e.V. # SPDX-FileCopyrightText: 2021 Alliander N.V. # SPDX-FileCopyrightText: 2023 Carmen Bianca BAKKER # # SPDX-License-Identifier: GPL-3.0-or-later """reuse is a tool for compliance with the REUSE recommendations. Although the API is documented, it is **NOT** guaranteed stable between minor or even patch releases. The semantic versioning of this program pertains exclusively to the reuse CLI command. If you want to use reuse as a Python library, you should pin reuse to an exact version. Having given the above disclaimer, the API has been relatively stable nevertheless, and we (the maintainers) do make some efforts to not needlessly change the public API. """ import gettext import logging import os import re from dataclasses import dataclass, field from enum import Enum from importlib.metadata import PackageNotFoundError, version from typing import Any, Dict, NamedTuple, Optional, Set, Type from boolean.boolean import Expression try: __version__ = version("reuse") except PackageNotFoundError: # package is not installed __version__ = "4.0.3" __author__ = "Carmen Bianca Bakker" __email__ = "carmenbianca@fsfe.org" __license__ = "Apache-2.0 AND CC0-1.0 AND CC-BY-SA-4.0 AND GPL-3.0-or-later" __REUSE_version__ = "3.2" _LOGGER = logging.getLogger(__name__) _PACKAGE_PATH = os.path.dirname(__file__) _LOCALE_DIR = os.path.join(_PACKAGE_PATH, "locale") if gettext.find("reuse", localedir=_LOCALE_DIR): gettext.bindtextdomain("reuse", _LOCALE_DIR) gettext.textdomain("reuse") _LOGGER.debug("translations found at %s", _LOCALE_DIR) else: _LOGGER.debug("no translations found at %s", _LOCALE_DIR) _IGNORE_DIR_PATTERNS = [ re.compile(r"^\.git$"), re.compile(r"^\.hg$"), re.compile(r"^\.sl$"), # Used by Sapling SCM re.compile(r"^LICENSES$"), re.compile(r"^\.reuse$"), ] _IGNORE_MESON_PARENT_DIR_PATTERNS = [ re.compile(r"^subprojects$"), ] _IGNORE_FILE_PATTERNS = [ re.compile(r"^LICENSE(\..*)?$"), re.compile(r"^COPYING(\..*)?$"), # ".git" as file happens in submodules re.compile(r"^\.git$"), re.compile(r"^\.gitkeep$"), re.compile(r"^\.hgtags$"), re.compile(r".*\.license$"), # Workaround for https://github.com/fsfe/reuse-tool/issues/229 re.compile(r"^CAL-1.0(-Combined-Work-Exception)?(\..+)?$"), re.compile(r"^SHL-2.1(\..+)?$"), ] _IGNORE_SPDX_PATTERNS = [ # SPDX files from # https://spdx.github.io/spdx-spec/conformance/#44-standard-data-format-requirements re.compile(r".*\.spdx$"), re.compile(r".*\.spdx.(rdf|json|xml|ya?ml)$"), ] # Combine SPDX patterns into file patterns to ease default ignore usage _IGNORE_FILE_PATTERNS.extend(_IGNORE_SPDX_PATTERNS) class SourceType(Enum): """ An enumeration representing the types of sources for license information. """ #: A .license file containing license information. DOT_LICENSE = "dot-license" #: A file header containing license information. FILE_HEADER = "file-header" #: A .reuse/dep5 file containing license information. DEP5 = "dep5" #: A REUSE.toml file containing license information. REUSE_TOML = "reuse-toml" # TODO: In Python 3.10+, add kw_only=True @dataclass(frozen=True) class ReuseInfo: """Simple dataclass holding licensing and copyright information""" spdx_expressions: Set[Expression] = field(default_factory=set) copyright_lines: Set[str] = field(default_factory=set) contributor_lines: Set[str] = field(default_factory=set) path: Optional[str] = None source_path: Optional[str] = None source_type: Optional[SourceType] = None def _check_nonexistent(self, **kwargs: Any) -> None: nonexistent_attributes = set(kwargs) - set(self.__dict__) if nonexistent_attributes: raise KeyError( f"The following attributes do not exist in" f" {self.__class__}: {', '.join(nonexistent_attributes)}" ) def copy(self, **kwargs: Any) -> "ReuseInfo": """Return a copy of ReuseInfo, replacing the values of attributes with the values from *kwargs*. """ self._check_nonexistent(**kwargs) new_kwargs = {} for key, value in self.__dict__.items(): new_kwargs[key] = kwargs.get(key, value) return self.__class__(**new_kwargs) # type: ignore def union(self, value: "ReuseInfo") -> "ReuseInfo": """Return a new instance of ReuseInfo where all Set attributes are equal to the union of the set in *self* and the set in *value*. All non-Set attributes are set to their values in *self*. >>> one = ReuseInfo(copyright_lines={"Jane Doe"}, source_path="foo.py") >>> two = ReuseInfo(copyright_lines={"John Doe"}, source_path="bar.py") >>> result = one.union(two) >>> print(sorted(result.copyright_lines)) ['Jane Doe', 'John Doe'] >>> print(result.source_path) foo.py """ new_kwargs = {} for key, attr_val in self.__dict__.items(): if isinstance(attr_val, set) and (other_val := getattr(value, key)): new_kwargs[key] = attr_val.union(other_val) else: new_kwargs[key] = attr_val return self.__class__(**new_kwargs) # type: ignore def contains_copyright_or_licensing(self) -> bool: """Either *spdx_expressions* or *copyright_lines* is non-empty.""" return bool(self.spdx_expressions or self.copyright_lines) def contains_copyright_xor_licensing(self) -> bool: """One of *spdx_expressions* or *copyright_lines* is non-empty.""" return bool(self.spdx_expressions) ^ bool(self.copyright_lines) def contains_info(self) -> bool: """Any field except *path*, *source_path* and *source_type* is non-empty. """ keys = { key for key in self.__dict__ if key not in ("path", "source_path", "source_type") } return any(self.__dict__[key] for key in keys) def __bool__(self) -> bool: return any(self.__dict__.values()) def __or__(self, value: "ReuseInfo") -> "ReuseInfo": return self.union(value) class ReuseException(Exception): """Base exception.""" class IdentifierNotFound(ReuseException): """Could not find SPDX identifier for license file.""" reuse-tool-4.0.3/src/reuse/__main__.py000066400000000000000000000003761464275211500176350ustar00rootroot00000000000000# SPDX-FileCopyrightText: 2019 Free Software Foundation Europe e.V. # # SPDX-License-Identifier: GPL-3.0-or-later """Entry module for reuse.""" import sys if __name__ == "__main__": from ._main import main sys.exit(main()) reuse-tool-4.0.3/src/reuse/_annotate.py000066400000000000000000000420501464275211500200600ustar00rootroot00000000000000# SPDX-FileCopyrightText: 2019 Free Software Foundation Europe e.V. # SPDX-FileCopyrightText: 2019 Kirill Elagin # SPDX-FileCopyrightText: 2019 Stefan Bakker # SPDX-FileCopyrightText: 2020 Dmitry Bogatov # SPDX-FileCopyrightText: 2021 Alliander N.V. # SPDX-FileCopyrightText: 2021 Alvar Penning # SPDX-FileCopyrightText: 2021 Robin Vobruba # SPDX-FileCopyrightText: 2022 Carmen Bianca Bakker # SPDX-FileCopyrightText: 2022 Florian Snow # SPDX-FileCopyrightText: 2022 Yaman Qalieh # SPDX-FileCopyrightText: 2024 Rivos Inc. # SPDX-FileCopyrightText: © 2020 Liferay, Inc. # # SPDX-License-Identifier: GPL-3.0-or-later """Functions for the CLI portion of manipulating headers.""" import datetime import logging import os import sys from argparse import SUPPRESS, ArgumentParser, Namespace from gettext import gettext as _ from pathlib import Path from typing import IO, Iterable, Optional, Set, Tuple, Type, cast from binaryornot.check import is_binary from jinja2 import Environment, FileSystemLoader, Template from jinja2.exceptions import TemplateNotFound from . import ReuseInfo from ._util import ( _COPYRIGHT_PREFIXES, PathType, StrPath, _determine_license_path, _determine_license_suffix_path, _get_comment_style, _has_style, _is_uncommentable, contains_reuse_info, detect_line_endings, make_copyright_line, spdx_identifier, ) from .comment import ( NAME_STYLE_MAP, CommentCreateError, CommentStyle, EmptyCommentStyle, ) from .header import MissingReuseInfo, add_new_header, find_and_replace_header from .project import Project _LOGGER = logging.getLogger(__name__) def verify_paths_line_handling( args: Namespace, paths: Iterable[Path], ) -> None: """This function aborts the parser when --single-line or --multi-line is used, but the file type does not support that type of comment style. """ for path in paths: style = NAME_STYLE_MAP.get(args.style) if style is None: style = _get_comment_style(path) if style is None: continue if args.single_line and not style.can_handle_single(): args.parser.error( _( "'{path}' does not support single-line comments, please" " do not use --single-line" ).format(path=path) ) if args.multi_line and not style.can_handle_multi(): args.parser.error( _( "'{path}' does not support multi-line comments, please" " do not use --multi-line" ).format(path=path) ) def find_template(project: Project, name: str) -> Template: """Find a template given a name. Raises: TemplateNotFound: if template could not be found. """ template_dir = project.root / ".reuse/templates" env = Environment( loader=FileSystemLoader(str(template_dir)), trim_blocks=True ) names = [name] if not name.endswith(".jinja2"): names.append(f"{name}.jinja2") if not name.endswith(".commented.jinja2"): names.append(f"{name}.commented.jinja2") for item in names: try: return env.get_template(item) except TemplateNotFound: pass raise TemplateNotFound(name) def add_header_to_file( path: StrPath, reuse_info: ReuseInfo, template: Optional[Template], template_is_commented: bool, style: Optional[str], force_multi: bool = False, skip_existing: bool = False, skip_unrecognised: bool = False, fallback_dot_license: bool = False, merge_copyrights: bool = False, replace: bool = True, out: IO[str] = sys.stdout, ) -> int: """Helper function.""" # pylint: disable=too-many-arguments,too-many-locals result = 0 comment_style: Optional[Type[CommentStyle]] = NAME_STYLE_MAP.get( cast(str, style) ) if comment_style is None: comment_style = _get_comment_style(path) if comment_style is None: if skip_unrecognised: out.write(_("Skipped unrecognised file '{path}'").format(path=path)) out.write("\n") return result if fallback_dot_license: out.write( _( "'{path}' is not recognised; creating '{path}.license'" ).format(path=path) ) out.write("\n") path = _determine_license_suffix_path(path) path.touch() comment_style = EmptyCommentStyle with open(path, "r", encoding="utf-8", newline="") as fp: text = fp.read() # Ideally, this check is done elsewhere. But that would necessitate reading # the file contents before this function is called. if skip_existing and contains_reuse_info(text): out.write( _( "Skipped file '{path}' already containing REUSE information" ).format(path=path) ) out.write("\n") return result # Detect and remember line endings for later conversion. line_ending = detect_line_endings(text) # Normalise line endings. text = text.replace(line_ending, "\n") try: if replace: output = find_and_replace_header( text, reuse_info, template=template, template_is_commented=template_is_commented, style=comment_style, force_multi=force_multi, merge_copyrights=merge_copyrights, ) else: output = add_new_header( text, reuse_info, template=template, template_is_commented=template_is_commented, style=comment_style, force_multi=force_multi, merge_copyrights=merge_copyrights, ) except CommentCreateError: out.write( _("Error: Could not create comment for '{path}'").format(path=path) ) out.write("\n") result = 1 except MissingReuseInfo: out.write( _( "Error: Generated comment header for '{path}' is missing" " copyright lines or license expressions. The template is" " probably incorrect. Did not write new header." ).format(path=path) ) out.write("\n") result = 1 else: with open(path, "w", encoding="utf-8", newline=line_ending) as fp: fp.write(output) # TODO: This may need to be rephrased more elegantly. out.write(_("Successfully changed header of {path}").format(path=path)) out.write("\n") return result def style_and_unrecognised_warning(args: Namespace) -> None: """Log a warning if --style is used together with --skip-unrecognised.""" if args.style is not None and args.skip_unrecognised: _LOGGER.warning( _( "--skip-unrecognised has no effect when used together with" " --style" ) ) def test_mandatory_option_required(args: Namespace) -> None: """Raise a parser error if one of the mandatory options is not provided.""" if not any((args.contributor, args.copyright, args.license)): args.parser.error( _("option --contributor, --copyright or --license is required") ) def all_paths(args: Namespace, project: Project) -> Set[Path]: """Return a set of all provided paths, converted into .license paths if they exist. If recursive is enabled, all files belonging to *project* are also added. """ if args.recursive: paths: Set[Path] = set() all_files = [path.resolve() for path in project.all_files()] for path in args.path: if path.is_file(): paths.add(path) else: paths |= { child for child in all_files if path.resolve() in child.parents } else: paths = args.path return {_determine_license_path(path) for path in paths} def get_template( args: Namespace, project: Project ) -> Tuple[Optional[Template], bool]: """If a template is specified on the CLI, find and return it, including whether it is a 'commented' template. If no template is specified, just return None. """ template: Optional[Template] = None commented = False if args.template: try: template = cast(Template, find_template(project, args.template)) except TemplateNotFound: args.parser.error( _("template {template} could not be found").format( template=args.template ) ) # This code is never reached, but mypy is not aware that # parser.error quits the program. raise if ".commented" in Path(cast(str, template.name)).suffixes: commented = True return template, commented def get_year(args: Namespace) -> Optional[str]: """Get the year. Normally it is today's year. If --year is specified once, get that one. If it is specified twice (or more), return the range between the two. If --exclude-year is specified, return None. """ year = None if not args.exclude_year: if args.year and len(args.year) > 1: year = f"{min(args.year)} - {max(args.year)}" elif args.year: year = args.year[0] else: year = str(datetime.date.today().year) return year def get_reuse_info(args: Namespace, year: Optional[str]) -> ReuseInfo: """Create a ReuseInfo object from --license, --copyright, and --contributor. """ expressions = set(args.license) if args.license is not None else set() copyright_prefix = ( args.copyright_prefix if args.copyright_prefix is not None else "spdx" ) copyright_lines = ( { make_copyright_line( item, year=year, copyright_prefix=copyright_prefix ) for item in args.copyright } if args.copyright is not None else set() ) contributors = ( set(args.contributor) if args.contributor is not None else set() ) return ReuseInfo( spdx_expressions=expressions, copyright_lines=copyright_lines, contributor_lines=contributors, ) def verify_write_access( paths: Iterable[StrPath], parser: ArgumentParser ) -> None: """Raise a parser.error if one of the paths is not writable.""" not_writeable = [ str(path) for path in paths if not os.access(path, os.W_OK) ] if not_writeable: parser.error( _("can't write to '{}'").format("', '".join(not_writeable)) ) def verify_paths_comment_style(args: Namespace, paths: Iterable[Path]) -> None: """Exit if --style, --force-dot-license, --fallback-dot-license, or --skip-unrecognised is not enabled and one of the paths has an unrecognised style. """ if ( not args.style and not args.fallback_dot_license and not args.skip_unrecognised and not args.force_dot_license ): unrecognised_files = [] for path in paths: if not _has_style(path): unrecognised_files.append(path) if unrecognised_files: args.parser.error( "{}\n\n{}".format( _( "The following files do not have a recognised file" " extension. Please use --style, --force-dot-license," " --fallback-dot-license, or --skip-unrecognised:" ), "\n".join(str(path) for path in unrecognised_files), ) ) def add_arguments(parser: ArgumentParser) -> None: """Add arguments to parser.""" parser.add_argument( "--copyright", "-c", action="append", type=str, help=_("copyright statement, repeatable"), ) parser.add_argument( "--license", "-l", action="append", type=spdx_identifier, help=_("SPDX Identifier, repeatable"), ) parser.add_argument( "--contributor", action="append", type=str, help=_("file contributor, repeatable"), ) year_mutex_group = parser.add_mutually_exclusive_group() year_mutex_group.add_argument( "--year", "-y", action="append", type=str, help=_("year of copyright statement, optional"), ) parser.add_argument( "--style", "-s", action="store", type=str, choices=list(NAME_STYLE_MAP), help=_("comment style to use, optional"), ) parser.add_argument( "--copyright-prefix", action="store", choices=list(_COPYRIGHT_PREFIXES.keys()), help=_("copyright prefix to use, optional"), ) parser.add_argument( "--copyright-style", action="store", dest="copyright_prefix", help=SUPPRESS, ) parser.add_argument( "--template", "-t", action="store", type=str, help=_("name of template to use, optional"), ) year_mutex_group.add_argument( "--exclude-year", action="store_true", help=_("do not include year in statement"), ) parser.add_argument( "--merge-copyrights", action="store_true", help=_("merge copyright lines if copyright statements are identical"), ) line_mutex_group = parser.add_mutually_exclusive_group() line_mutex_group.add_argument( "--single-line", action="store_true", help=_("force single-line comment style, optional"), ) line_mutex_group.add_argument( "--multi-line", action="store_true", help=_("force multi-line comment style, optional"), ) parser.add_argument( "--recursive", "-r", action="store_true", help=_( "add headers to all files under specified directories recursively" ), ) parser.add_argument( "--no-replace", action="store_true", help=_( "do not replace the first header in the file; just add a new one" ), ) style_mutex_group = parser.add_mutually_exclusive_group() style_mutex_group.add_argument( "--force-dot-license", action="store_true", help=_( "always write a .license file instead of a header inside the file" ), ) style_mutex_group.add_argument( "--fallback-dot-license", action="store_true", help=_( "write a .license file to files with unrecognised comment styles" ), ) style_mutex_group.add_argument( "--skip-unrecognised", action="store_true", help=_("skip files with unrecognised comment styles"), ) style_mutex_group.add_argument( "--skip-unrecognized", dest="skip_unrecognised", action="store_true", help=SUPPRESS, ) parser.add_argument( "--skip-existing", action="store_true", help=_("skip files that already contain REUSE information"), ) parser.add_argument("path", action="store", nargs="+", type=PathType("r")) def run(args: Namespace, project: Project, out: IO[str] = sys.stdout) -> int: """Add headers to files.""" test_mandatory_option_required(args) style_and_unrecognised_warning(args) paths = all_paths(args, project) verify_paths_comment_style(args, paths) if not args.force_dot_license: verify_write_access(paths, args.parser) # Verify line handling and comment styles before proceeding verify_paths_line_handling(args, paths) template, commented = get_template(args, project) year = get_year(args) reuse_info = get_reuse_info(args, year) result = 0 for path in paths: binary = is_binary(str(path)) if binary or _is_uncommentable(path) or args.force_dot_license: new_path = _determine_license_suffix_path(path) if binary: _LOGGER.info( _( "'{path}' is a binary, therefore using '{new_path}'" " for the header" ).format(path=path, new_path=new_path) ) path = Path(new_path) path.touch() result += add_header_to_file( path=path, reuse_info=reuse_info, template=template, template_is_commented=commented, style=args.style, force_multi=args.multi_line, skip_existing=args.skip_existing, skip_unrecognised=args.skip_unrecognised, fallback_dot_license=args.fallback_dot_license, merge_copyrights=args.merge_copyrights, replace=not args.no_replace, out=out, ) return min(result, 1) reuse-tool-4.0.3/src/reuse/_format.py000066400000000000000000000025161464275211500175420ustar00rootroot00000000000000# SPDX-FileCopyrightText: 2018 Free Software Foundation Europe e.V. # # SPDX-License-Identifier: GPL-3.0-or-later """Formatting functions primarily for the CLI.""" from textwrap import fill, indent from typing import Iterator WIDTH = 78 INDENT = 2 def fill_paragraph(text: str, width: int = WIDTH, indent_width: int = 0) -> str: """Wrap a single paragraph.""" return indent( fill(text.strip(), width=width - indent_width), indent_width * " " ) def fill_all(text: str, width: int = WIDTH, indent_width: int = 0) -> str: """Wrap all paragraphs.""" return "\n\n".join( fill_paragraph(paragraph, width=width, indent_width=indent_width) for paragraph in split_into_paragraphs(text) ) def split_into_paragraphs(text: str) -> Iterator[str]: """Yield all paragraphs in a text. A paragraph is a piece of text surrounded by empty lines. """ lines = text.splitlines() paragraph = "" for line in lines: if not line: if paragraph: yield paragraph paragraph = "" else: continue else: if paragraph: padding = " " else: padding = "" paragraph = f"{paragraph}{padding}{line}" if paragraph: yield paragraph reuse-tool-4.0.3/src/reuse/_licenses.py000066400000000000000000000041621464275211500200560ustar00rootroot00000000000000# SPDX-FileCopyrightText: 2014 Ahmed H. Ismail # SPDX-FileCopyrightText: 2019 Free Software Foundation Europe e.V. # # SPDX-License-Identifier: Apache-2.0 # SPDX-License-Identifier: GPL-3.0-or-later # # load_license_list was copied and altered from its original location # at . """A list with all SPDX licenses.""" import json import os from typing import Dict, List, Tuple _BASE_DIR = os.path.dirname(__file__) _RESOURCES_DIR = os.path.join(_BASE_DIR, "resources") _LICENSES = os.path.join(_RESOURCES_DIR, "licenses.json") _EXCEPTIONS = os.path.join(_RESOURCES_DIR, "exceptions.json") def _load_license_list(file_name: str) -> Tuple[List[int], Dict[str, Dict]]: """Return the licenses list version tuple and a mapping of licenses id->name loaded from a JSON file from https://github.com/spdx/license-list-data """ licenses_map = {} with open(file_name, "r", encoding="utf-8") as lics: licenses = json.load(lics) version = licenses["licenseListVersion"].split(".") for lic in licenses["licenses"]: identifier = lic["licenseId"] licenses_map[identifier] = lic return version, licenses_map def _load_exception_list(file_name: str) -> Tuple[List[int], Dict[str, Dict]]: """Return the exceptions list version tuple and a mapping of exceptions id->name loaded from a JSON file from https://github.com/spdx/license-list-data """ exceptions_map = {} with open(file_name, "r", encoding="utf-8") as excs: exceptions = json.load(excs) version = exceptions["licenseListVersion"].split(".") for exc in exceptions["exceptions"]: identifier = exc["licenseExceptionId"] exceptions_map[identifier] = exc return version, exceptions_map _, LICENSE_MAP = _load_license_list(_LICENSES) _, EXCEPTION_MAP = _load_exception_list(_EXCEPTIONS) ALL_MAP = {**LICENSE_MAP, **EXCEPTION_MAP} ALL_NON_DEPRECATED_MAP = { identifier: contents.copy() for identifier, contents in ALL_MAP.items() if not contents["isDeprecatedLicenseId"] } reuse-tool-4.0.3/src/reuse/_main.py000066400000000000000000000217121464275211500171750ustar00rootroot00000000000000# SPDX-FileCopyrightText: 2017 Free Software Foundation Europe e.V. # SPDX-FileCopyrightText: 2022 Florian Snow # SPDX-FileCopyrightText: 2024 Carmen Bianca BAKKER # SPDX-FileCopyrightText: © 2020 Liferay, Inc. # # SPDX-License-Identifier: GPL-3.0-or-later """Entry functions for reuse.""" import argparse import logging import os import sys import warnings from gettext import gettext as _ from pathlib import Path from typing import IO, Callable, List, Optional, Type, cast from . import ( __REUSE_version__, __version__, _annotate, convert_dep5, download, lint, spdx, supported_licenses, ) from ._format import INDENT, fill_all, fill_paragraph from ._util import PathType, setup_logging from .global_licensing import GlobalLicensingParseError from .project import GlobalLicensingConflict, GlobalLicensingFound, Project from .vcs import find_root _LOGGER = logging.getLogger(__name__) _DESCRIPTION_LINES = [ _( "reuse is a tool for compliance with the REUSE" " recommendations. See for more" " information, and for the online" " documentation." ), _( "This version of reuse is compatible with version {} of the REUSE" " Specification." ).format(__REUSE_version__), _("Support the FSFE's work:"), ] _INDENTED_LINE = _( "Donations are critical to our strength and autonomy. They enable us to" " continue working for Free Software wherever necessary. Please consider" " making a donation at ." ) _DESCRIPTION_TEXT = ( fill_all("\n\n".join(_DESCRIPTION_LINES)) + "\n\n" + fill_paragraph(_INDENTED_LINE, indent_width=INDENT) ) _EPILOG_TEXT = "" def parser() -> argparse.ArgumentParser: """Create the parser and return it.""" # pylint: disable=redefined-outer-name parser = argparse.ArgumentParser( formatter_class=argparse.RawTextHelpFormatter, description=_DESCRIPTION_TEXT, epilog=_EPILOG_TEXT, ) parser.add_argument( "--debug", action="store_true", help=_("enable debug statements") ) parser.add_argument( "--suppress-deprecation", action="store_true", help=_("hide deprecation warnings"), ) parser.add_argument( "--include-submodules", action="store_true", help=_("do not skip over Git submodules"), ) parser.add_argument( "--include-meson-subprojects", action="store_true", help=_("do not skip over Meson subprojects"), ) parser.add_argument( "--no-multiprocessing", action="store_true", help=_("do not use multiprocessing"), ) parser.add_argument( "--root", action="store", metavar="PATH", type=PathType("r", force_directory=True), help=_("define root of project"), ) parser.add_argument( "--version", action="store_true", help=_("show program's version number and exit"), ) parser.set_defaults(func=lambda *args: parser.print_help()) subparsers = parser.add_subparsers(title=_("subcommands")) add_command( subparsers, "annotate", _annotate.add_arguments, _annotate.run, help=_("add copyright and licensing into the header of files"), description=fill_all( _( "Add copyright and licensing into the header of one or more" " files.\n" "\n" "By using --copyright and --license, you can specify which" " copyright holders and licenses to add to the headers of the" " given files.\n" "\n" "By using --contributor, you can specify people or entity that" " contributed but are not copyright holder of the given" " files." ) ), ) add_command( subparsers, "download", download.add_arguments, download.run, help=_("download a license and place it in the LICENSES/ directory"), description=fill_all( _("Download a license and place it in the LICENSES/ directory.") ), ) add_command( subparsers, "lint", lint.add_arguments, lint.run, help=_("list all non-compliant files"), description=fill_all( _( "Lint the project directory for compliance with" " version {reuse_version} of the REUSE Specification. You can" " find the latest version of the specification at" " .\n" "\n" "Specifically, the following criteria are checked:\n" "\n" "- Are there any bad (unrecognised, not compliant with SPDX)" " licenses in the project?\n" "\n" "- Are any licenses referred to inside of the project, but" " not included in the LICENSES/ directory?\n" "\n" "- Are any licenses included in the LICENSES/ directory that" " are not used inside of the project?\n" "\n" "- Do all files have valid copyright and licensing" " information?" ).format(reuse_version=__REUSE_version__) ), ) add_command( subparsers, "spdx", spdx.add_arguments, spdx.run, help=_("print the project's bill of materials in SPDX format"), ) add_command( subparsers, "supported-licenses", supported_licenses.add_arguments, supported_licenses.run, help=_("list all supported SPDX licenses"), aliases=["supported-licences"], ) add_command( subparsers, "convert-dep5", convert_dep5.add_arguments, convert_dep5.run, help=_("convert .reuse/dep5 to REUSE.toml"), ) return parser def add_command( # pylint: disable=too-many-arguments,redefined-builtin subparsers: argparse._SubParsersAction, name: str, add_arguments_func: Callable[[argparse.ArgumentParser], None], run_func: Callable[[argparse.Namespace, Project, IO[str]], int], formatter_class: Optional[Type[argparse.HelpFormatter]] = None, description: Optional[str] = None, help: Optional[str] = None, aliases: Optional[List[str]] = None, ) -> None: """Add a subparser for a command.""" if formatter_class is None: formatter_class = argparse.RawTextHelpFormatter subparser = subparsers.add_parser( name, formatter_class=formatter_class, description=description, help=help, aliases=aliases or [], ) add_arguments_func(subparser) subparser.set_defaults(func=run_func) subparser.set_defaults(parser=subparser) def main(args: Optional[List[str]] = None, out: IO[str] = sys.stdout) -> int: """Main entry function.""" if args is None: args = cast(List[str], sys.argv[1:]) main_parser = parser() parsed_args = main_parser.parse_args(args) setup_logging(level=logging.DEBUG if parsed_args.debug else logging.WARNING) # Show all warnings raised by ourselves. if not parsed_args.suppress_deprecation: warnings.filterwarnings("default", module="reuse") if parsed_args.version: out.write(f"reuse {__version__}\n") return 0 # Very stupid workaround to not print a DEP5 deprecation warning in the # middle of conversion to REUSE.toml. if args and args[0] == "convert-dep5": os.environ["_SUPPRESS_DEP5_WARNING"] = "1" root = parsed_args.root if root is None: root = find_root() if root is None: root = Path.cwd() try: project = Project.from_directory(root) # FileNotFoundError and NotADirectoryError don't need to be caught because # argparse already made sure of these things. except UnicodeDecodeError: found = cast(GlobalLicensingFound, Project.find_global_licensing(root)) main_parser.error( _("'{path}' could not be decoded as UTF-8.").format(path=found.path) ) except GlobalLicensingParseError as error: found = cast(GlobalLicensingFound, Project.find_global_licensing(root)) main_parser.error( _( "'{path}' could not be parsed. We received the following error" " message: {message}" ).format(path=found.path, message=str(error)) ) except GlobalLicensingConflict as error: main_parser.error(str(error)) except OSError as error: main_parser.error(str(error)) project.include_submodules = parsed_args.include_submodules project.include_meson_subprojects = parsed_args.include_meson_subprojects return parsed_args.func(parsed_args, project, out) if __name__ == "__main__": sys.exit(main()) reuse-tool-4.0.3/src/reuse/_util.py000066400000000000000000000514701464275211500172320ustar00rootroot00000000000000# SPDX-FileCopyrightText: 2017 Free Software Foundation Europe e.V. # SPDX-FileCopyrightText: 2020 Tuomas Siipola # SPDX-FileCopyrightText: 2022 Carmen Bianca Bakker # SPDX-FileCopyrightText: 2022 Florian Snow # SPDX-FileCopyrightText: 2022 Nico Rikken # SPDX-FileCopyrightText: 2022 Pietro Albini # SPDX-FileCopyrightText: 2023 DB Systel GmbH # SPDX-FileCopyrightText: 2023 Johannes Zarl-Zierl # SPDX-FileCopyrightText: 2024 Rivos Inc. # SPDX-FileCopyrightText: © 2020 Liferay, Inc. # # SPDX-License-Identifier: GPL-3.0-or-later """Misc. utilities for reuse.""" import logging import os import re import shutil import subprocess import sys from argparse import ArgumentTypeError from collections import Counter from difflib import SequenceMatcher from gettext import gettext as _ from hashlib import sha1 from inspect import cleandoc from itertools import chain from os import PathLike from pathlib import Path from typing import ( IO, Any, BinaryIO, Dict, Iterator, List, Optional, Set, Type, Union, cast, ) from boolean.boolean import Expression, ParseError from license_expression import ExpressionError, Licensing from . import ReuseInfo, SourceType from ._licenses import ALL_NON_DEPRECATED_MAP from .comment import ( EXTENSION_COMMENT_STYLE_MAP_LOWERCASE, FILENAME_COMMENT_STYLE_MAP_LOWERCASE, CommentStyle, UncommentableCommentStyle, _all_style_classes, ) # TODO: When removing Python 3.8 support, use PathLike[str] StrPath = Union[str, PathLike] GIT_EXE = shutil.which("git") HG_EXE = shutil.which("hg") PIJUL_EXE = shutil.which("pijul") REUSE_IGNORE_START = "REUSE-IgnoreStart" REUSE_IGNORE_END = "REUSE-IgnoreEnd" SPDX_SNIPPET_INDICATOR = b"SPDX-SnippetBegin" _LOGGER = logging.getLogger(__name__) _LICENSING = Licensing() # REUSE-IgnoreStart _END_PATTERN = r"{}$".format( "".join( { r"(?:{})*".format(item) # pylint: disable=consider-using-f-string for item in chain( ( re.escape(style.MULTI_LINE.end) for style in _all_style_classes() if style.MULTI_LINE.end ), # These are special endings which do not belong to specific # comment styles, but which we want to nonetheless strip away # while parsing. ( ending for ending in [ # ex: r'"\s*/*>', r"'\s*/*>", # ex: [SPDX-License-Identifier: GPL-3.0-or-later] :: r"\]\s*::", ] ), ) } ) ) _LICENSE_IDENTIFIER_PATTERN = re.compile( r"^(.*?)SPDX-License-Identifier:[ \t]+(.*?)" + _END_PATTERN, re.MULTILINE ) _CONTRIBUTOR_PATTERN = re.compile( r"^(.*?)SPDX-FileContributor:[ \t]+(.*?)" + _END_PATTERN, re.MULTILINE ) # The keys match the relevant attributes of ReuseInfo. _SPDX_TAGS: Dict[str, re.Pattern] = { "spdx_expressions": _LICENSE_IDENTIFIER_PATTERN, "contributor_lines": _CONTRIBUTOR_PATTERN, } _COPYRIGHT_PATTERNS = [ re.compile( r"(?P(?PSPDX-(File|Snippet)CopyrightText:)\s+" r"((?P\d{4} ?- ?\d{4}|\d{4}),?\s+)?" r"(?P.*?))" + _END_PATTERN ), re.compile( r"(?P(?PCopyright(\s?\([cC]\))?)\s+" r"((?P\d{4} ?- ?\d{4}|\d{4}),?\s+)?" r"(?P.*?))" + _END_PATTERN ), re.compile( r"(?P(?P©)\s+" r"((?P\d{4} ?- ?\d{4}|\d{4}),?\s+)?" r"(?P.*?))" + _END_PATTERN ), ] _COPYRIGHT_PREFIXES = { "spdx": "SPDX-FileCopyrightText:", "spdx-c": "SPDX-FileCopyrightText: (C)", "spdx-symbol": "SPDX-FileCopyrightText: ©", "string": "Copyright", "string-c": "Copyright (C)", "string-symbol": "Copyright ©", "symbol": "©", } _LICENSEREF_PATTERN = re.compile("LicenseRef-[a-zA-Z0-9-.]+$") # Amount of bytes that we assume will be big enough to contain the entire # comment header (including SPDX tags), so that we don't need to read the # entire file. _HEADER_BYTES = 4096 def setup_logging(level: int = logging.WARNING) -> None: """Configure logging for reuse. You can only call this function once. """ # library_logger is the root logger for reuse. We configure logging solely # for reuse, not for any other libraries. library_logger = logging.getLogger("reuse") if not library_logger.hasHandlers(): library_logger.setLevel(level) handler = logging.StreamHandler() formatter = logging.Formatter("%(name)s - %(levelname)s - %(message)s") handler.setFormatter(formatter) library_logger.addHandler(handler) def execute_command( command: List[str], logger: logging.Logger, cwd: Optional[StrPath] = None, **kwargs: Any, ) -> subprocess.CompletedProcess: """Run the given command with subprocess.run. Forward kwargs. Silence output into a pipe unless kwargs override it. """ logger.debug("running '%s'", " ".join(command)) stdout: Union[None, int, IO[Any]] = kwargs.get("stdout", subprocess.PIPE) stderr: Union[None, int, IO[Any]] = kwargs.get("stderr", subprocess.PIPE) return subprocess.run( list(map(str, command)), stdout=stdout, stderr=stderr, check=False, cwd=str(cwd), **kwargs, ) def find_licenses_directory(root: Optional[StrPath] = None) -> Path: """Find the licenses directory from CWD or *root*. In the following order: - LICENSES/ in *root*. - Current directory if its name is "LICENSES" - LICENSES/ in CWD. The returned LICENSES/ directory NEED NOT EXIST. It may still need to be created. """ cwd = Path.cwd() licenses_path = cwd / "LICENSES" if root: licenses_path = Path(root) / "LICENSES" elif cwd.name == "LICENSES": licenses_path = cwd return licenses_path def decoded_text_from_binary( binary_file: BinaryIO, size: Optional[int] = None ) -> str: """Given a binary file object, detect its encoding and return its contents as a decoded string. Do not throw any errors if the encoding contains errors: Just replace the false characters. If *size* is specified, only read so many bytes. """ if size is None: size = -1 rawdata = binary_file.read(size) result = rawdata.decode("utf-8", errors="replace") return result.replace("\r\n", "\n") def _determine_license_path(path: StrPath) -> Path: """Given a path FILE, return FILE.license if it exists, otherwise return FILE. """ license_path = Path(f"{path}.license") if not license_path.exists(): license_path = Path(path) return license_path def _determine_license_suffix_path(path: StrPath) -> Path: """Given a path FILE or FILE.license, return FILE.license.""" path = Path(path) if path.suffix == ".license": return path return Path(f"{path}.license") def _parse_copyright_year(year: Optional[str]) -> List[str]: """Parse copyright years and return list.""" ret: List[str] = [] if not year: return ret if re.match(r"\d{4}$", year): ret = [year] elif re.match(r"\d{4} ?- ?\d{4}$", year): ret = [year[:4], year[-4:]] return ret def _contains_snippet(binary_file: BinaryIO) -> bool: """Check if a file seems to contain a SPDX snippet""" # Assumes that if SPDX_SNIPPET_INDICATOR (SPDX-SnippetBegin) is found in a # file, the file contains a snippet content = binary_file.read() if SPDX_SNIPPET_INDICATOR in content: return True return False def _get_comment_style(path: StrPath) -> Optional[Type[CommentStyle]]: """Return value of CommentStyle detected for *path* or None.""" path = Path(path) style = FILENAME_COMMENT_STYLE_MAP_LOWERCASE.get(path.name.lower()) if style is None: style = cast( Optional[Type[CommentStyle]], EXTENSION_COMMENT_STYLE_MAP_LOWERCASE.get(path.suffix.lower()), ) return style def _is_uncommentable(path: Path) -> bool: """*path*'s extension has the UncommentableCommentStyle.""" return _get_comment_style(path) == UncommentableCommentStyle def _has_style(path: Path) -> bool: """*path*'s extension has a CommentStyle.""" return _get_comment_style(path) is not None def merge_copyright_lines(copyright_lines: Set[str]) -> Set[str]: """Parse all copyright lines and merge identical statements making years into a range. If a same statement uses multiple prefixes, use only the most frequent one. """ # pylint: disable=too-many-locals # TODO: Rewrite this function. It's a bit of a mess. copyright_in = [] for line in copyright_lines: for pattern in _COPYRIGHT_PATTERNS: match = pattern.search(line) if match is not None: copyright_in.append( { "statement": match.groupdict()["statement"], "year": _parse_copyright_year( match.groupdict()["year"] ), "prefix": match.groupdict()["prefix"], } ) copyright_out = set() for line_info in copyright_in: statement = str(line_info["statement"]) copyright_list = [ item for item in copyright_in if item["statement"] == statement ] # Get the most common prefix. most_common = str( Counter([item["prefix"] for item in copyright_list]).most_common(1)[ 0 ][0] ) prefix = "spdx" for key, value in _COPYRIGHT_PREFIXES.items(): if most_common == value: prefix = key break # get year range if any years: List[str] = [] for copy in copyright_list: years += copy["year"] year: Optional[str] = None if years: if min(years) == max(years): year = min(years) else: year = f"{min(years)} - {max(years)}" copyright_out.add(make_copyright_line(statement, year, prefix)) return copyright_out def extract_reuse_info(text: str) -> ReuseInfo: """Extract REUSE information from comments in a string. Raises: ExpressionError: if an SPDX expression could not be parsed. ParseError: if an SPDX expression could not be parsed. """ text = filter_ignore_block(text) spdx_tags: Dict[str, Set[str]] = {} for tag, pattern in _SPDX_TAGS.items(): spdx_tags[tag] = set(find_spdx_tag(text, pattern)) # License expressions and copyright matches are special cases. expressions = set() copyright_matches = set() for expression in spdx_tags.pop("spdx_expressions"): try: expressions.add(_LICENSING.parse(expression)) except (ExpressionError, ParseError): _LOGGER.error( _("Could not parse '{expression}'").format( expression=expression ) ) raise for line in text.splitlines(): for pattern in _COPYRIGHT_PATTERNS: match = pattern.search(line) if match is not None: copyright_matches.add(match.groupdict()["copyright"].strip()) break return ReuseInfo( spdx_expressions=expressions, copyright_lines=copyright_matches, **spdx_tags, # type: ignore ) def reuse_info_of_file( path: StrPath, original_path: StrPath, root: StrPath ) -> ReuseInfo: """Open *path* and return its :class:`ReuseInfo`. Normally only the first few :const:`_HEADER_BYTES` are read. But if a snippet was detected, the entire file is read. """ path = Path(path) with path.open("rb") as fp: try: read_limit: Optional[int] = _HEADER_BYTES # Completely read the file once # to search for possible snippets if _contains_snippet(fp): _LOGGER.debug(f"'{path}' seems to contain an SPDX Snippet") read_limit = None # Reset read position fp.seek(0) # Scan the file for REUSE info, possibly limiting the read # length file_result = extract_reuse_info( decoded_text_from_binary(fp, size=read_limit) ) if file_result.contains_copyright_or_licensing(): source_type = SourceType.FILE_HEADER if path.suffix == ".license": source_type = SourceType.DOT_LICENSE return file_result.copy( path=relative_from_root(original_path, root).as_posix(), source_path=relative_from_root(path, root).as_posix(), source_type=source_type, ) except (ExpressionError, ParseError): _LOGGER.error( _( "'{path}' holds an SPDX expression that cannot be" " parsed, skipping the file" ).format(path=path) ) return ReuseInfo() def relative_from_root(path: StrPath, root: StrPath) -> Path: """A helper function to get *path* relative to *root*.""" path = Path(path) try: return path.relative_to(root) except ValueError: return Path(os.path.relpath(path, start=root)) def find_spdx_tag(text: str, pattern: re.Pattern) -> Iterator[str]: """Extract all the values in *text* matching *pattern*'s regex, taking care of stripping extraneous whitespace of formatting. """ for prefix, value in pattern.findall(text): prefix, value = prefix.strip(), value.strip() # Some comment headers have ASCII art to "frame" the comment, like this: # # /***********************\ # |* This is a comment *| # \***********************/ # # To ensure we parse them correctly, if the line ends with the inverse # of the comment prefix, we strip that suffix. See #343 for a real # world example of a project doing this (LLVM). suffix = prefix[::-1] if suffix and value.endswith(suffix): value = value[: -len(suffix)] yield value.strip() def filter_ignore_block(text: str) -> str: """Filter out blocks beginning with REUSE_IGNORE_START and ending with REUSE_IGNORE_END to remove lines that should not be treated as copyright and licensing information. """ ignore_start = None ignore_end = None if REUSE_IGNORE_START in text: ignore_start = text.index(REUSE_IGNORE_START) if REUSE_IGNORE_END in text: ignore_end = text.index(REUSE_IGNORE_END) + len(REUSE_IGNORE_END) if not ignore_start: return text if not ignore_end: return text[:ignore_start] if ignore_end > ignore_start: return text[:ignore_start] + filter_ignore_block(text[ignore_end:]) rest = text[ignore_start + len(REUSE_IGNORE_START) :] if REUSE_IGNORE_END in rest: ignore_end = rest.index(REUSE_IGNORE_END) + len(REUSE_IGNORE_END) return text[:ignore_start] + filter_ignore_block(rest[ignore_end:]) return text[:ignore_start] def contains_reuse_info(text: str) -> bool: """The text contains REUSE info.""" try: return bool(extract_reuse_info(text)) except (ExpressionError, ParseError): return False def make_copyright_line( statement: str, year: Optional[str] = None, copyright_prefix: str = "spdx" ) -> str: """Given a statement, prefix it with ``SPDX-FileCopyrightText:`` if it is not already prefixed with some manner of copyright tag. """ if "\n" in statement: raise RuntimeError(f"Unexpected newline in '{statement}'") prefix = _COPYRIGHT_PREFIXES.get(copyright_prefix) if prefix is None: # TODO: Maybe translate this. Also maybe reduce DRY here. raise RuntimeError( "Unexpected copyright prefix: Need 'spdx', 'spdx-c', " "'spdx-symbol', 'string', 'string-c', " "'string-symbol', or 'symbol'" ) for pattern in _COPYRIGHT_PATTERNS: match = pattern.search(statement) if match is not None: return statement if year is not None: return f"{prefix} {year} {statement}" return f"{prefix} {statement}" def _checksum(path: StrPath) -> str: path = Path(path) file_sha1 = sha1() with path.open("rb") as fp: for chunk in iter(lambda: fp.read(128 * file_sha1.block_size), b""): file_sha1.update(chunk) return file_sha1.hexdigest() class PathType: """Factory for creating Paths""" def __init__( self, mode: str = "r", force_file: bool = False, force_directory: bool = False, ): if mode in ("r", "r+", "w"): self._mode = mode else: raise ValueError(f"mode='{mode}' is not valid") self._force_file = force_file self._force_directory = force_directory if self._force_file and self._force_directory: raise ValueError( "'force_file' and 'force_directory' cannot both be True" ) def _check_read(self, path: Path) -> None: if path.exists() and os.access(path, os.R_OK): if self._force_file and not path.is_file(): raise ArgumentTypeError(_("'{}' is not a file").format(path)) if self._force_directory and not path.is_dir(): raise ArgumentTypeError( _("'{}' is not a directory").format(path) ) return raise ArgumentTypeError(_("can't open '{}'").format(path)) def _check_write(self, path: Path) -> None: if path.is_dir(): raise ArgumentTypeError( _("can't write to directory '{}'").format(path) ) if path.exists() and os.access(path, os.W_OK): return if not path.exists() and os.access(path.parent, os.W_OK): return raise ArgumentTypeError(_("can't write to '{}'").format(path)) def __call__(self, string: str) -> Path: path = Path(string) try: if self._mode in ("r", "r+"): self._check_read(path) if self._mode in ("w", "r+"): self._check_write(path) return path except OSError as error: raise ArgumentTypeError( _("can't read or write '{}'").format(path) ) from error def spdx_identifier(text: str) -> Expression: """argparse factory for creating SPDX expressions.""" try: return _LICENSING.parse(text) except (ExpressionError, ParseError) as error: raise ArgumentTypeError( _("'{}' is not a valid SPDX expression, aborting").format(text) ) from error def similar_spdx_identifiers(identifier: str) -> List[str]: """Given an incorrect SPDX identifier, return a list of similar ones.""" suggestions: List[str] = [] if identifier in ALL_NON_DEPRECATED_MAP: return suggestions for valid_identifier in ALL_NON_DEPRECATED_MAP: distance = SequenceMatcher( a=identifier.lower(), b=valid_identifier[: len(identifier)].lower() ).ratio() if distance > 0.75: suggestions.append(valid_identifier) suggestions = sorted(suggestions) return suggestions def print_incorrect_spdx_identifier( identifier: str, out: IO[str] = sys.stdout ) -> None: """Print out that *identifier* is not valid, and follow up with some suggestions. """ out.write( _("'{}' is not a valid SPDX License Identifier.").format(identifier) ) out.write("\n") suggestions = similar_spdx_identifiers(identifier) if suggestions: out.write("\n") out.write(_("Did you mean:")) out.write("\n") for suggestion in suggestions: out.write(f"* {suggestion}\n") out.write("\n") out.write( _( "See for a list of valid " "SPDX License Identifiers." ) ) def detect_line_endings(text: str) -> str: """Return one of '\n', '\r' or '\r\n' depending on the line endings used in *text*. Return os.linesep if there are no line endings. """ line_endings = ["\r\n", "\r", "\n"] for line_ending in line_endings: if line_ending in text: return line_ending return os.linesep def cleandoc_nl(text: str) -> str: """Like :func:`inspect.cleandoc`, but with a newline at the end.""" return cleandoc(text) + "\n" # REUSE-IgnoreEnd reuse-tool-4.0.3/src/reuse/comment.py000066400000000000000000000675041464275211500175650ustar00rootroot00000000000000# SPDX-FileCopyrightText: 2019 Free Software Foundation Europe e.V. # SPDX-FileCopyrightText: 2019 Kirill Elagin # SPDX-FileCopyrightText: 2020 Dmitry Bogatov # SPDX-FileCopyrightText: 2021 Alvar Penning # SPDX-FileCopyrightText: 2021 Matija Šuklje # SPDX-FileCopyrightText: 2021 Robin Vobruba # SPDX-FileCopyrightText: 2021-2022 Alliander N.V. # SPDX-FileCopyrightText: 2022 Carmen Bianca Bakker # SPDX-FileCopyrightText: 2022 Florian Snow # SPDX-FileCopyrightText: 2022 Nico Rikken # SPDX-FileCopyrightText: 2022 Sebastian Crane # SPDX-FileCopyrightText: 2022 Stefan Hynek # SPDX-FileCopyrightText: 2023 Juelich Supercomputing Centre, Forschungszentrum Juelich GmbH # SPDX-FileCopyrightText: 2023 Kevin Meagher # SPDX-FileCopyrightText: 2023 Mathias Dannesbo # SPDX-FileCopyrightText: 2023 Maxim Cournoyer # SPDX-FileCopyrightText: 2023 Redradix S.L. # SPDX-FileCopyrightText: 2023 Shun Sakai # SPDX-FileCopyrightText: 2024 Rivos Inc. # # SPDX-License-Identifier: GPL-3.0-or-later """Module for parsing and creating comments. Just enough to deal with comment headers, in any case. """ import logging import operator import re from textwrap import dedent from typing import List, NamedTuple, Optional, Type _LOGGER = logging.getLogger(__name__) class CommentParseError(Exception): """An error occurred during the parsing of a comment.""" class CommentCreateError(Exception): """An error occurred during the creation of a comment.""" class MultiLineSegments(NamedTuple): """Components that make up a multi-line comment style, e.g. '/*', '*', and '*/'. """ start: str middle: str end: str class CommentStyle: """Base class for comment style.""" SHORTHAND = "" SINGLE_LINE = "" SINGLE_LINE_REGEXP: Optional[re.Pattern] = None INDENT_AFTER_SINGLE = "" # (start, middle, end) # e.g., ("/*", "*", "*/") MULTI_LINE = MultiLineSegments("", "", "") INDENT_BEFORE_MIDDLE = "" INDENT_AFTER_MIDDLE = "" INDENT_BEFORE_END = "" SHEBANGS: List[str] = [] @classmethod def can_handle_single(cls) -> bool: """Whether the :class:`CommentStyle` can handle single-line comments.""" return bool(cls.SINGLE_LINE) @classmethod def can_handle_multi(cls) -> bool: """Whether the :class:`CommentStyle` can handle multi-line comments.""" return all((cls.MULTI_LINE.start, cls.MULTI_LINE.end)) @classmethod def create_comment(cls, text: str, force_multi: bool = False) -> str: """Comment all lines in *text*. Single-line comments are preferred over multi-line comments, unless *force_multi* is provided. Raises: CommentCreateError: if *text* could not be commented. """ if force_multi or not cls.can_handle_single(): return cls._create_comment_multi(text) return cls._create_comment_single(text) @classmethod def _create_comment_single(cls, text: str) -> str: """Comment all lines in *text*, using single-line comments. Raises: CommentCreateError: if *text* could not be commented. """ if not cls.can_handle_single(): raise CommentCreateError( f"{cls} cannot create single-line comments" ) result = [] for line in text.split("\n"): line_result = cls.SINGLE_LINE if line: line_result += cls.INDENT_AFTER_SINGLE + line result.append(line_result) return "\n".join(result) @classmethod def _create_comment_multi(cls, text: str) -> str: """Comment all lines in *text*, using multi-line comments. Raises: CommentCreateError: if *text* could not be commented. """ if not cls.can_handle_multi(): raise CommentCreateError(f"{cls} cannot create multi-line comments") result = [] result.append(cls.MULTI_LINE.start) for line in text.split("\n"): if cls.MULTI_LINE.end in text: raise CommentCreateError( f"'{line}' contains a premature comment delimiter" ) line_result = "" if cls.MULTI_LINE.middle: line_result += cls.INDENT_BEFORE_MIDDLE + cls.MULTI_LINE.middle if line: line_result += cls.INDENT_AFTER_MIDDLE + line result.append(line_result) result.append(cls.INDENT_BEFORE_END + cls.MULTI_LINE.end) return "\n".join(result) @classmethod def parse_comment(cls, text: str) -> str: """Uncomment all lines in *text*. Raises: CommentParseError: if *text* could not be parsed. """ try: # Attempt to parse multi-line comments first, in case of comment # styles like Julia, where '#=' starts a multi-line comment, and '#' # starts a single-line comment. If we parsed single-line comments # first, '#=' would be a valid single-line comment. return cls._parse_comment_multi(text) except CommentParseError: return cls._parse_comment_single(text) @classmethod def _parse_comment_single(cls, text: str) -> str: """Uncomment all lines in *text*, assuming they are commented by single-line comments. Raises: CommentParseError: if *text* could not be parsed. """ if not cls.can_handle_single(): raise CommentParseError(f"{cls} cannot parse single-line comments") result_lines = [] for line in text.splitlines(): # TODO: When Python 3.8 is dropped, consider using str.removeprefix if cls.SINGLE_LINE_REGEXP: if match := cls.SINGLE_LINE_REGEXP.match(line): line = line.lstrip(match.group(0)) result_lines.append(line) continue if not line.startswith(cls.SINGLE_LINE): raise CommentParseError( f"'{line}' does not start with a comment marker" ) line = line.lstrip(cls.SINGLE_LINE) result_lines.append(line) result = "\n".join(result_lines) return dedent(result) @classmethod def _remove_middle_marker(cls, line: str) -> str: if cls.MULTI_LINE.middle: possible_line = line.lstrip() prefix = cls.MULTI_LINE.middle if possible_line.startswith(prefix): line = possible_line.lstrip(prefix) # Note to future self: line.removeprefix would be preferable # here. if line.startswith(cls.INDENT_AFTER_MIDDLE): line = line.replace(cls.INDENT_AFTER_MIDDLE, "", 1) else: _LOGGER.debug( "'%s' does not contain a middle comment marker", line ) return line @classmethod def _parse_comment_multi(cls, text: str) -> str: """Uncomment all lines in *text*, assuming they are commented by multi-line comments. Raises: CommentParseError: if *text* could not be parsed. """ if not cls.can_handle_multi(): raise CommentParseError(f"{cls} cannot parse multi-line comments") result_lines = [] try: first, *lines, last = text.splitlines() last_is_first = False except ValueError: first = text lines = [] last = "" # Set this later. last_is_first = True if not first.startswith(cls.MULTI_LINE.start): raise CommentParseError( f"'{first}' does not start with a comment marker" ) first = first.lstrip(cls.MULTI_LINE.start) first = first.lstrip() for line in lines: line = cls._remove_middle_marker(line) result_lines.append(line) if last_is_first: last = first first = "" if not last.endswith(cls.MULTI_LINE.end): raise CommentParseError( f"'{last}' does not end with a comment delimiter" ) last = last.rstrip(cls.MULTI_LINE.end) last = last.rstrip() last = cls._remove_middle_marker(last) result = "\n".join(result_lines) result = dedent(result) return "\n".join(item for item in (first, result, last) if item) @classmethod def comment_at_first_character(cls, text: str) -> str: """Return the comment block that starts at the first character of *text*. This is chiefly handy to get the header comment of a file, assuming that the header comment starts at the first character in the file. Raises: CommentParseError: if *text* does not start with a parseable comment block. """ if not any((cls.can_handle_single(), cls.can_handle_multi())): raise CommentParseError(f"{cls} cannot parse comments") lines = text.splitlines() end: Optional[int] = None if cls.can_handle_single(): for i, line in enumerate(lines): if ( cls.SINGLE_LINE_REGEXP and cls.SINGLE_LINE_REGEXP.match(line) ) or line.startswith(cls.SINGLE_LINE): end = i else: break if ( end is None and cls.can_handle_multi() and text.startswith(cls.MULTI_LINE.start) ): for i, line in enumerate(lines): end = i if line.endswith(cls.MULTI_LINE.end): break else: raise CommentParseError("Comment block never delimits") if end is not None: return "\n".join(lines[: end + 1]) raise CommentParseError( "Could not find a parseable comment block at the first character" ) class AppleScriptCommentStyle(CommentStyle): """AppleScript comment style.""" SHORTHAND = "applescript" SINGLE_LINE = "--" INDENT_AFTER_SINGLE = " " MULTI_LINE = MultiLineSegments("(*", "", "*)") class AspxCommentStyle(CommentStyle): """ASPX comment style.""" SHORTHAND = "aspx" MULTI_LINE = MultiLineSegments("<%--", "", "--%>") class BatchFileCommentStyle(CommentStyle): """Windows batch file comment style.""" SHORTHAND = "bat" SINGLE_LINE = "REM" INDENT_AFTER_SINGLE = " " class BibTexCommentStyle(CommentStyle): """BibTex comment style.""" SHORTHAND = "bibtex" MULTI_LINE = MultiLineSegments("@Comment{", "", "}") SHEBANGS = ["% !BIB", "%!BIB"] class CCommentStyle(CommentStyle): """C comment style.""" SHORTHAND = "c" MULTI_LINE = MultiLineSegments("/*", "*", "*/") INDENT_BEFORE_MIDDLE = " " INDENT_AFTER_MIDDLE = " " INDENT_BEFORE_END = " " class CppCommentStyle(CommentStyle): """C++ comment style.""" SHORTHAND = "cpp" SINGLE_LINE = "//" INDENT_AFTER_SINGLE = " " MULTI_LINE = MultiLineSegments("/*", "*", "*/") INDENT_BEFORE_MIDDLE = " " INDENT_AFTER_MIDDLE = " " INDENT_BEFORE_END = " " SHEBANGS = [ "#!", # V-Lang " str: return text @classmethod def parse_comment(cls, text: str) -> str: return text @classmethod def comment_at_first_character(cls, text: str) -> str: return text class FortranCommentStyle(CommentStyle): """Fortran (fixed form) comment style.""" SHORTHAND = "f" SINGLE_LINE = "c" INDENT_AFTER_SINGLE = " " class ModernFortranCommentStyle(CommentStyle): """Fortran (free form) comment style.""" SHORTHAND = "f90" SINGLE_LINE = "!" INDENT_AFTER_SINGLE = " " class FtlCommentStyle(CommentStyle): """FreeMarker Template Language comment style.""" SHORTHAND = "ftl" MULTI_LINE = MultiLineSegments("<#--", "", "-->") class HandlebarsCommentStyle(CommentStyle): """Handlebars comment style.""" SHORTHAND = "handlebars" MULTI_LINE = MultiLineSegments("{{!--", "", "--}}") class HaskellCommentStyle(CommentStyle): """Haskell comment style.""" SHORTHAND = "haskell" SINGLE_LINE = "--" INDENT_AFTER_SINGLE = " " class HtmlCommentStyle(CommentStyle): """HTML comment style.""" SHORTHAND = "html" MULTI_LINE = MultiLineSegments("") SHEBANGS = [" List[Type[CommentStyle]]: """Return a list of all defined style classes, excluding the base class.""" result = [] for key, value in globals().items(): if key.endswith("CommentStyle") and key != "CommentStyle": result.append(value) return sorted(result, key=operator.attrgetter("__name__")) _result = _all_style_classes() _result.remove(EmptyCommentStyle) _result.remove(UncommentableCommentStyle) #: A map of human-friendly names against style classes. NAME_STYLE_MAP = {style.SHORTHAND: style for style in _result} reuse-tool-4.0.3/src/reuse/convert_dep5.py000066400000000000000000000077261464275211500205200ustar00rootroot00000000000000# SPDX-FileCopyrightText: 2024 Carmen Bianca BAKKER # # SPDX-License-Identifier: GPL-3.0-or-later """Logic to convert a .reuse/dep5 file to a REUSE.toml file.""" import re import sys from argparse import ArgumentParser, Namespace from gettext import gettext as _ from typing import IO, Any, Dict, Iterable, List, Optional, TypeVar, Union, cast import tomlkit from debian.copyright import Copyright, FilesParagraph, Header from .global_licensing import REUSE_TOML_VERSION, ReuseDep5 from .project import Project _SINGLE_ASTERISK_PATTERN = re.compile(r"(? Union[List[_T], _T]: """Return the only item of the list if the length of the list is one, else return the list. """ if len(sequence) == 1: return sequence[0] return sequence def _header_from_dep5_header( header: Header, ) -> Dict[str, Union[str, List[str]]]: result: Dict[str, Union[str, List[str]]] = {} if header.upstream_name: result["SPDX-PackageName"] = str(header.upstream_name) if header.upstream_contact: result["SPDX-PackageSupplier"] = _collapse_list_if_one_item( list(map(str, header.upstream_contact)) ) if header.source: result["SPDX-PackageDownloadLocation"] = str(header.source) if header.disclaimer: result["SPDX-PackageComment"] = str(header.disclaimer) return result def _copyrights_from_paragraph( paragraph: FilesParagraph, ) -> Union[str, List[str]]: return _collapse_list_if_one_item( [line.strip() for line in cast(str, paragraph.copyright).splitlines()] ) def _convert_asterisk(path: str) -> str: """This solves a semantics difference. A singular asterisk is semantically identical to a double asterisk in REUSE.toml. """ return _SINGLE_ASTERISK_PATTERN.sub("**", path) def _paths_from_paragraph(paragraph: FilesParagraph) -> Union[str, List[str]]: return _collapse_list_if_one_item( [_convert_asterisk(path) for path in list(paragraph.files)] ) def _comment_from_paragraph(paragraph: FilesParagraph) -> Optional[str]: return cast(Optional[str], paragraph.comment) def _annotations_from_paragraphs( paragraphs: Iterable[FilesParagraph], ) -> List[Dict[str, Union[str, List[str]]]]: annotations = [] for paragraph in paragraphs: copyrights = _copyrights_from_paragraph(paragraph) paths = _paths_from_paragraph(paragraph) paragraph_result = { "path": paths, "precedence": "aggregate", "SPDX-FileCopyrightText": copyrights, "SPDX-License-Identifier": paragraph.license.to_str(), } comment = _comment_from_paragraph(paragraph) if comment: paragraph_result["SPDX-FileComment"] = comment annotations.append(paragraph_result) return annotations def toml_from_dep5(dep5: Copyright) -> str: """Given a Copyright object, return an equivalent REUSE.toml string.""" header = _header_from_dep5_header(dep5.header) annotations = _annotations_from_paragraphs(dep5.all_files_paragraphs()) result: Dict[str, Any] = {"version": REUSE_TOML_VERSION} result.update(header) result["annotations"] = annotations return tomlkit.dumps(result) # pylint: disable=unused-argument def add_arguments(parser: ArgumentParser) -> None: """Add arguments to parser.""" # Nothing to do. # pylint: disable=unused-argument def run(args: Namespace, project: Project, out: IO[str] = sys.stdout) -> int: """Convert .reuse/dep5 to REUSE.toml.""" if not (project.root / ".reuse/dep5").exists(): args.parser.error(_("no '.reuse/dep5' file")) text = toml_from_dep5( cast(ReuseDep5, project.global_licensing).dep5_copyright ) (project.root / "REUSE.toml").write_text(text) (project.root / ".reuse/dep5").unlink() return 0 reuse-tool-4.0.3/src/reuse/download.py000066400000000000000000000154031464275211500177210ustar00rootroot00000000000000# SPDX-FileCopyrightText: 2019 Free Software Foundation Europe e.V. # SPDX-FileCopyrightText: 2023 Nico Rikken # # SPDX-License-Identifier: GPL-3.0-or-later """Functions for downloading license files from spdx/license-list-data.""" import errno import logging import os import shutil import sys import urllib.request from argparse import ArgumentParser, Namespace from gettext import gettext as _ from pathlib import Path from typing import IO, Optional, cast from urllib.error import URLError from urllib.parse import urljoin from ._licenses import ALL_NON_DEPRECATED_MAP from ._util import ( _LICENSEREF_PATTERN, PathType, StrPath, find_licenses_directory, print_incorrect_spdx_identifier, ) from .project import Project from .report import ProjectReport from .vcs import VCSStrategyNone _LOGGER = logging.getLogger(__name__) # All raw text files are available as files underneath this path. _SPDX_REPOSITORY_BASE_URL = ( "https://raw.githubusercontent.com/spdx/license-list-data/master/text/" ) def download_license(spdx_identifier: str) -> str: """Download the license text from the SPDX repository. Args: spdx_identifier: SPDX identifier of the license. Raises: URLError: if the license could not be downloaded. Returns: The license text. """ # This is fairly naive, but I can't see anything wrong with it. url = urljoin(_SPDX_REPOSITORY_BASE_URL, "".join((spdx_identifier, ".txt"))) _LOGGER.debug("downloading license from '%s'", url) # TODO: Cache result? with urllib.request.urlopen(url) as response: if response.getcode() == 200: return response.read().decode("utf-8") raise URLError("Status code was not 200") def _path_to_license_file(spdx_identifier: str, project: Project) -> Path: root: Optional[Path] = project.root # Hack if cast(Path, root).name == "LICENSES" and isinstance( project.vcs_strategy, VCSStrategyNone ): root = None licenses_path = find_licenses_directory(root=root) return licenses_path / "".join((spdx_identifier, ".txt")) def put_license_in_file( spdx_identifier: str, destination: StrPath, source: Optional[StrPath] = None, ) -> None: """Download a license and put it in the destination file. This function exists solely for convenience. Args: spdx_identifier: SPDX License Identifier of the license. destination: Where to put the license. source: Path to file or directory containing the text for LicenseRef licenses. Raises: URLError: if the license could not be downloaded. FileExistsError: if the license file already exists. FileNotFoundError: if the source could not be found in the directory. """ header = "" destination = Path(destination) destination.parent.mkdir(exist_ok=True) if destination.exists(): raise FileExistsError( errno.EEXIST, os.strerror(errno.EEXIST), str(destination) ) # LicenseRef- license; don't download anything. if _LICENSEREF_PATTERN.match(spdx_identifier): if source: source = Path(source) if source.is_dir(): source = source / f"{spdx_identifier}.txt" if not source.exists(): raise FileNotFoundError( errno.ENOENT, os.strerror(errno.ENOENT), str(source) ) shutil.copyfile(source, destination) else: destination.touch() else: text = download_license(spdx_identifier) with destination.open("w", encoding="utf-8") as fp: fp.write(header) fp.write(text) def add_arguments(parser: ArgumentParser) -> None: """Add arguments to parser.""" parser.add_argument( "license", action="store", nargs="*", help=_("SPDX License Identifier of license"), ) parser.add_argument( "--all", action="store_true", help=_("download all missing licenses detected in the project"), ) parser.add_argument( "--output", "-o", dest="file", action="store", type=PathType("w") ) parser.add_argument( "--source", action="store", type=PathType("r"), help=_( "source from which to copy custom LicenseRef- licenses, either" " a directory that contains the file or the file itself" ), ) def run(args: Namespace, project: Project, out: IO[str] = sys.stdout) -> int: """Download license and place it in the LICENSES/ directory.""" def _already_exists(path: StrPath) -> None: out.write( _("Error: {spdx_identifier} already exists.").format( spdx_identifier=path ) ) out.write("\n") def _not_found(path: StrPath) -> None: out.write(_("Error: {path} does not exist.").format(path=path)) def _could_not_download(identifier: str) -> None: out.write(_("Error: Failed to download license.")) out.write(" ") if identifier not in ALL_NON_DEPRECATED_MAP: print_incorrect_spdx_identifier(identifier, out=out) else: out.write(_("Is your internet connection working?")) out.write("\n") def _successfully_downloaded(destination: StrPath) -> None: out.write( _("Successfully downloaded {spdx_identifier}.").format( spdx_identifier=destination ) ) out.write("\n") licenses = args.license if args.all: # TODO: This is fairly inefficient, but gets the job done. report = ProjectReport.generate(project) licenses = report.missing_licenses if args.file: _LOGGER.warning( _("--output has no effect when used together with --all") ) args.file = None elif not args.license: args.parser.error(_("the following arguments are required: license")) elif len(args.license) > 1 and args.file: args.parser.error(_("cannot use --output with more than one license")) return_code = 0 for lic in licenses: if args.file: destination = args.file else: destination = _path_to_license_file(lic, project) try: put_license_in_file( lic, destination=destination, source=args.source ) except URLError: _could_not_download(lic) return_code = 1 except FileExistsError as err: _already_exists(err.filename) return_code = 1 except FileNotFoundError as err: _not_found(err.filename) return_code = 1 else: _successfully_downloaded(destination) return return_code reuse-tool-4.0.3/src/reuse/global_licensing.py000066400000000000000000000464011464275211500214070ustar00rootroot00000000000000# SPDX-FileCopyrightText: 2023 Free Software Foundation Europe e.V. # # SPDX-License-Identifier: GPL-3.0-or-later """Code for parsing and validating REUSE.toml.""" # mypy: disable-error-code=attr-defined import contextlib import logging import re from abc import ABC, abstractmethod from collections import defaultdict from enum import Enum from gettext import gettext as _ from pathlib import Path, PurePath from typing import ( Any, Callable, Collection, Dict, Generator, List, Optional, Set, Tuple, Type, TypeVar, Union, cast, overload, ) import attrs import tomlkit from attr.validators import _InstanceOfValidator as _AttrInstanceOfValidator from boolean.boolean import Expression, ParseError from debian.copyright import Copyright from debian.copyright import Error as DebianError from license_expression import ExpressionError from . import ReuseInfo, SourceType from ._util import _LICENSING, StrPath _LOGGER = logging.getLogger(__name__) _T = TypeVar("_T") #: Current version of REUSE.toml. REUSE_TOML_VERSION = 1 class PrecedenceType(Enum): """An enum of behaviours surrounding order of precedence for entries in a :class:`GlobalLicensing`. """ #: Aggregate the results from the file with the results from the global #: licensing file. AGGREGATE = "aggregate" #: Use the results that are closest to the covered file. This is typically #: the file itself, or the global licensing file if no REUSE information #: exists inside of the file. CLOSEST = "closest" #: Only use the results from the global licensing file. OVERRIDE = "override" class GlobalLicensingParseError(Exception): """An exception representing any kind of error that occurs when trying to parse a :class:`GlobalLicensing` file. """ class GlobalLicensingParseTypeError(TypeError, GlobalLicensingParseError): """An exception representing a type error while trying to parse a :class:`GlobalLicensing` file. """ class GlobalLicensingParseValueError(GlobalLicensingParseError, ValueError): """An exception representing a value error while trying to parse a :class:`GlobalLicensing` file. """ @attrs.define class _CollectionOfValidator: collection_type: Type[Collection] = attrs.field() value_type: Type = attrs.field() optional: bool = attrs.field(default=True) def __call__( self, instance: object, attribute: attrs.Attribute, value: Collection[_T], ) -> None: # This is a hack to display the TOML's key names instead of the Python # attributes. if hasattr(instance, "TOML_KEYS"): attr_name = instance.TOML_KEYS[attribute.name] else: attr_name = attribute.name if not isinstance(value, self.collection_type): raise GlobalLicensingParseTypeError( _( "{attr_name} must be a {type_name} (got {value} that is a" " {value_class})." ).format( attr_name=repr(attr_name), type_name=self.collection_type.__name__, value=repr(value), value_class=repr(value.__class__), ) ) for item in value: if not isinstance(item, self.value_type): raise GlobalLicensingParseTypeError( _( "Item in {attr_name} collection must be a {type_name}" " (got {item_value} that is a {item_class})." ).format( attr_name=repr(attr_name), type_name=self.value_type.__name__, item_value=repr(item), item_class=repr(item.__class__), ) ) if not self.optional and not value: raise GlobalLicensingParseValueError( _("{attr_name} must not be empty.").format( attr_name=repr(attr_name) ) ) def _validate_collection_of( collection_type: Type[Collection], value_type: Type[_T], optional: bool = False, ) -> Callable[[Any, attrs.Attribute, Collection[_T]], Any]: return _CollectionOfValidator( collection_type, value_type, optional=optional ) class _InstanceOfValidator(_AttrInstanceOfValidator): def __call__(self, inst: Any, attr: attrs.Attribute, value: _T) -> None: try: super().__call__(inst, attr, value) except TypeError as error: raise GlobalLicensingParseTypeError( _( "{name} must be a {type} (got {value} that is a" " {value_type})." ).format( name=repr(error.args[1].name), type=repr(error.args[2].__name__), value=repr(error.args[3]), value_type=repr(error.args[3].__class__), ) ) from error def _instance_of( type_: Type[_T], ) -> Callable[[Any, attrs.Attribute, _T], Any]: return _InstanceOfValidator(type_) def _str_to_global_precedence(value: Any) -> PrecedenceType: try: return PrecedenceType(value) except ValueError as err: raise GlobalLicensingParseValueError( _( "The value of 'precedence' must be one of {precedence_vals}" " (got {received})" ).format( precedence_vals=tuple( member.value for member in PrecedenceType ), received=repr(value), ) ) from err @overload def _str_to_set(value: str) -> Set[str]: ... @overload def _str_to_set(value: Union[None, _T, Collection[_T]]) -> Set[_T]: ... def _str_to_set( value: Union[str, None, _T, Collection[_T]] ) -> Union[Set[str], Set[_T]]: if value is None: return cast(Set[str], set()) if isinstance(value, str): return {value} if hasattr(value, "__iter__"): return set(value) return {value} def _str_to_set_of_expr(value: Any) -> Set[Expression]: value = _str_to_set(value) result = set() for expression in value: try: result.add(_LICENSING.parse(expression)) except (ExpressionError, ParseError) as error: raise GlobalLicensingParseValueError( _("Could not parse '{expression}'").format( expression=expression ) ) from error return result @attrs.define class GlobalLicensing(ABC): """An abstract class that represents a configuration file that contains licensing information that is pertinent to other files in the project. """ source: str = attrs.field(validator=_instance_of(str)) @classmethod @abstractmethod def from_file(cls, path: StrPath) -> "GlobalLicensing": """Parse the file and create a :class:`GlobalLicensing` object from its contents. Raises: FileNotFoundError: file doesn't exist. UnicodeDecodeError: could not decode file as UTF-8. OSError: some other error surrounding I/O. GlobalLicensingParseError: file could not be parsed. """ @abstractmethod def reuse_info_of( self, path: StrPath ) -> Dict[PrecedenceType, List[ReuseInfo]]: """Find the REUSE information of *path* defined in the configuration. The path must be relative to the root of a :class:`reuse.project.Project`. The key indicates the precedence type for the subsequent information. """ @attrs.define class ReuseDep5(GlobalLicensing): """A soft wrapper around :class:`Copyright`.""" dep5_copyright: Copyright @classmethod def from_file(cls, path: StrPath) -> "ReuseDep5": path = Path(path) try: with path.open(encoding="utf-8") as fp: return cls(str(path), Copyright(fp)) except UnicodeDecodeError: raise # TODO: Remove ValueError once # # is closed except (DebianError, ValueError) as error: raise GlobalLicensingParseError(str(error)) from error def reuse_info_of( self, path: StrPath ) -> Dict[PrecedenceType, List[ReuseInfo]]: path = PurePath(path).as_posix() result = self.dep5_copyright.find_files_paragraph(path) if result is None: return {} return { PrecedenceType.AGGREGATE: [ ReuseInfo( spdx_expressions=set( map(_LICENSING.parse, [result.license.synopsis]) ), copyright_lines=set( map(str.strip, result.copyright.splitlines()) ), path=path, source_type=SourceType.DEP5, # This is hardcoded. It must be a relative path from the # project root. self.source is not (guaranteed) a relative # path. source_path=".reuse/dep5", ) ] } @attrs.define class AnnotationsItem: """A class that maps to a single [[annotations]] table element in REUSE.toml. """ TOML_KEYS = { "paths": "path", "precedence": "precedence", "copyright_lines": "SPDX-FileCopyrightText", "spdx_expressions": "SPDX-License-Identifier", } paths: Set[str] = attrs.field( converter=_str_to_set, validator=_validate_collection_of(set, str, optional=False), ) precedence: PrecedenceType = attrs.field( converter=_str_to_global_precedence, default=PrecedenceType.CLOSEST ) copyright_lines: Set[str] = attrs.field( converter=_str_to_set, validator=_validate_collection_of(set, str, optional=True), default=None, ) spdx_expressions: Set[Expression] = attrs.field( converter=_str_to_set_of_expr, validator=_validate_collection_of(set, Expression, optional=True), default=None, ) _paths_regex: re.Pattern = attrs.field(init=False) def __attrs_post_init__(self) -> None: def translate(path: str) -> str: blocks = [] escaping = False globstar = False prev_char = "" for char in path: if char == "\\": if prev_char == "\\" and escaping: escaping = False blocks.append(r"\\") else: escaping = True elif char == "*": if escaping: blocks.append(re.escape("*")) escaping = False elif prev_char == "*" and not globstar: globstar = True blocks.append(r".*") elif char == "/": if not globstar: blocks.append("/") escaping = False else: if prev_char == "*" and not globstar: blocks.append(r"[^/]*") blocks.append(re.escape(char)) globstar = False escaping = False prev_char = char if prev_char == "*" and not globstar: blocks.append(r"[^/]*") result = "".join(blocks) return f"^({result})$" self._paths_regex = re.compile( "|".join(translate(path) for path in self.paths) ) @classmethod def from_dict(cls, values: Dict[str, Any]) -> "AnnotationsItem": """Create an :class:`AnnotationsItem` from a dictionary that uses the key-value pairs for an [[annotations]] table in REUSE.toml. """ new_dict = {} new_dict["paths"] = values.get(cls.TOML_KEYS["paths"]) precedence = values.get(cls.TOML_KEYS["precedence"]) if precedence is not None: new_dict["precedence"] = precedence new_dict["copyright_lines"] = values.get( cls.TOML_KEYS["copyright_lines"] ) new_dict["spdx_expressions"] = values.get( cls.TOML_KEYS["spdx_expressions"] ) return cls(**new_dict) # type: ignore def matches(self, path: str) -> bool: """Determine whether *path* matches any of the paths (or path globs) in :class:`AnnotationsItem`. """ return bool(self._paths_regex.match(path)) @attrs.define class ReuseTOML(GlobalLicensing): """A class that contains the data parsed from a REUSE.toml file.""" version: int = attrs.field(validator=_instance_of(int)) annotations: List[AnnotationsItem] = attrs.field( validator=_validate_collection_of(list, AnnotationsItem, optional=True) ) @classmethod def from_dict(cls, values: Dict[str, Any], source: str) -> "ReuseTOML": """Create a :class:`ReuseTOML` from the dict version of REUSE.toml.""" new_dict = {} new_dict["version"] = values.get("version") new_dict["source"] = source annotation_dicts = values.get("annotations", []) annotations = [ AnnotationsItem.from_dict(annotation) for annotation in annotation_dicts ] new_dict["annotations"] = annotations return cls(**new_dict) # type: ignore @classmethod def from_toml(cls, toml: str, source: str) -> "ReuseTOML": """Create a :class:`ReuseTOML` from TOML text.""" try: tomldict = tomlkit.loads(toml) except tomlkit.exceptions.TOMLKitError as error: raise GlobalLicensingParseError(str(error)) from error return cls.from_dict(tomldict, source) @classmethod def from_file(cls, path: StrPath) -> "ReuseTOML": with Path(path).open(encoding="utf-8") as fp: return cls.from_toml(fp.read(), str(path)) def find_annotations_item(self, path: StrPath) -> Optional[AnnotationsItem]: """Find a :class:`AnnotationsItem` that matches *path*. The latest match in :attr:`annotations` is returned. """ path = PurePath(path).as_posix() for item in reversed(self.annotations): if item.matches(path): return item return None def reuse_info_of( self, path: StrPath ) -> Dict[PrecedenceType, List[ReuseInfo]]: path = PurePath(path).as_posix() item = self.find_annotations_item(path) if item: return { item.precedence: [ ReuseInfo( spdx_expressions=item.spdx_expressions, copyright_lines=item.copyright_lines, path=path, source_path="REUSE.toml", source_type=SourceType.REUSE_TOML, ) ] } return {} @property def directory(self) -> PurePath: """The directory in which the REUSE.toml file is located.""" return PurePath(self.source).parent @attrs.define class NestedReuseTOML(GlobalLicensing): """A class that represents a hierarchy of :class:`ReuseTOML` objects.""" reuse_tomls: List[ReuseTOML] = attrs.field() @classmethod def from_file(cls, path: StrPath) -> "GlobalLicensing": """TODO: *path* is a directory instead of a file.""" tomls = [ ReuseTOML.from_file(toml_path) for toml_path in cls.find_reuse_tomls(path) ] return cls(reuse_tomls=tomls, source=str(path)) def reuse_info_of( self, path: StrPath ) -> Dict[PrecedenceType, List[ReuseInfo]]: path = PurePath(path) toml_items: List[Tuple[ReuseTOML, AnnotationsItem]] = ( self._find_relevant_tomls_and_items(path) ) result = defaultdict(list) for keyval in toml_items: toml = keyval[0] item = keyval[1] relpath = (PurePath(self.source) / path).relative_to(toml.directory) # I'm pretty sure there should be no KeyError here. info = toml.reuse_info_of(relpath)[item.precedence][0] result[item.precedence].append( # Fix the paths to be relative to self.source. As-is, they # were relative to the directory of the respective # REUSE.toml. info.copy( path=path.as_posix(), source_path=PurePath(toml.source) .relative_to(self.source) .as_posix(), ) ) if item.precedence == PrecedenceType.OVERRIDE: # No more! break # Clean up CLOSEST. Some items were added that are not the closest. # Consider copyright and licensing separately. copyright_found = False licence_found = False to_keep: List[ReuseInfo] = [] for info in reversed(result[PrecedenceType.CLOSEST]): new_info = info.copy(copyright_lines=set(), spdx_expressions=set()) if not copyright_found and info.copyright_lines: new_info = new_info.copy(copyright_lines=info.copyright_lines) copyright_found = True if not licence_found and info.spdx_expressions: new_info = new_info.copy(spdx_expressions=info.spdx_expressions) licence_found = True if new_info.contains_copyright_or_licensing(): to_keep.append(new_info) result[PrecedenceType.CLOSEST] = list(reversed(to_keep)) # Looping over CLOSEST created it in the defaultdict. Remove it if it's # empty. if not result[PrecedenceType.CLOSEST]: del result[PrecedenceType.CLOSEST] return dict(result) @classmethod def find_reuse_tomls(cls, path: StrPath) -> Generator[Path, None, None]: """Find all REUSE.toml files in *path*.""" return Path(path).rglob("**/REUSE.toml") def _find_relevant_tomls(self, path: StrPath) -> List[ReuseTOML]: found = [] for toml in self.reuse_tomls: # TODO: When Python 3.8 is dropped, use is_relative_to instead. with contextlib.suppress(ValueError): PurePath(path).relative_to(toml.directory) # No error. found.append(toml) # Sort from topmost to deepest directory. found.sort(key=lambda toml: toml.directory.parts) return found def _find_relevant_tomls_and_items( self, path: StrPath ) -> List[Tuple[ReuseTOML, AnnotationsItem]]: # *path* is relative to the Project root, which is the *source* of # NestedReuseTOML, which itself is a relative (to CWD) or absolute # path. path = PurePath(path) adjusted_path = PurePath(self.source) / path tomls = self._find_relevant_tomls(adjusted_path) toml_items: List[Tuple[ReuseTOML, AnnotationsItem]] = [] for toml in tomls: relpath = adjusted_path.relative_to(toml.directory) item = toml.find_annotations_item(relpath) if item is not None: toml_items.append((toml, item)) return toml_items reuse-tool-4.0.3/src/reuse/header.py000066400000000000000000000251741464275211500173500ustar00rootroot00000000000000# SPDX-FileCopyrightText: 2019 Free Software Foundation Europe e.V. # SPDX-FileCopyrightText: 2019 Stefan Bakker # SPDX-FileCopyrightText: 2019 Kirill Elagin # SPDX-FileCopyrightText: 2020 Dmitry Bogatov # SPDX-FileCopyrightText: © 2020 Liferay, Inc. # SPDX-FileCopyrightText: 2021 Alvar Penning # SPDX-FileCopyrightText: 2021 Alliander N.V. # SPDX-FileCopyrightText: 2021 Robin Vobruba # SPDX-FileCopyrightText: 2022 Florian Snow # SPDX-FileCopyrightText: 2022 Yaman Qalieh # SPDX-FileCopyrightText: 2022 Carmen Bianca Bakker # # SPDX-License-Identifier: GPL-3.0-or-later """Functions for manipulating the comment headers of files.""" import logging import re from gettext import gettext as _ from typing import NamedTuple, Optional, Sequence, Tuple, Type, cast from boolean.boolean import ParseError from jinja2 import Environment, PackageLoader, Template from license_expression import ExpressionError from . import ReuseInfo from ._util import ( contains_reuse_info, extract_reuse_info, merge_copyright_lines, ) from .comment import ( CommentCreateError, CommentParseError, CommentStyle, EmptyCommentStyle, PythonCommentStyle, ) _LOGGER = logging.getLogger(__name__) _ENV = Environment(loader=PackageLoader("reuse", "templates"), trim_blocks=True) DEFAULT_TEMPLATE = _ENV.get_template("default_template.jinja2") _NEWLINE_PATTERN = re.compile(r"\n", re.MULTILINE) class _TextSections(NamedTuple): """Used to split up text in three parts.""" before: str middle: str after: str class MissingReuseInfo(Exception): """Some REUSE information is missing from the result.""" def _create_new_header( reuse_info: ReuseInfo, template: Optional[Template] = None, template_is_commented: bool = False, style: Optional[Type[CommentStyle]] = None, force_multi: bool = False, ) -> str: """Format a new header from scratch. Raises: CommentCreateError: if a comment could not be created. MissingReuseInfo: if the generated comment is missing SPDX information. """ if template is None: template = DEFAULT_TEMPLATE if style is None: style = cast(Type[CommentStyle], PythonCommentStyle) rendered = template.render( copyright_lines=sorted(reuse_info.copyright_lines), contributor_lines=sorted(reuse_info.contributor_lines), spdx_expressions=sorted(map(str, reuse_info.spdx_expressions)), ).strip("\n") if template_is_commented: result = rendered else: result = style.create_comment(rendered, force_multi=force_multi).strip( "\n" ) # Verify that the result contains all ReuseInfo. new_reuse_info = extract_reuse_info(result) if ( reuse_info.copyright_lines != new_reuse_info.copyright_lines and reuse_info.spdx_expressions != new_reuse_info.spdx_expressions ): _LOGGER.debug( _( "generated comment is missing copyright lines or license" " expressions" ) ) _LOGGER.debug(result) raise MissingReuseInfo() return result # pylint: disable=too-many-arguments def create_header( reuse_info: ReuseInfo, header: Optional[str] = None, template: Optional[Template] = None, template_is_commented: bool = False, style: Optional[Type[CommentStyle]] = None, force_multi: bool = False, merge_copyrights: bool = False, ) -> str: """Create a header containing *reuse_info*. *header* is an optional argument containing a header which should be modified to include *reuse_info*. If *header* is not given, a brand new header is created. *template*, *template_is_commented*, and *style* determine what the header will look like, and whether it will be commented or not. Raises: CommentCreateError: if a comment could not be created. MissingReuseInfo: if the generated comment is missing SPDX information. """ if template is None: template = DEFAULT_TEMPLATE if style is None: style = PythonCommentStyle new_header = "" if header: try: existing_spdx = extract_reuse_info(header) except (ExpressionError, ParseError) as err: raise CommentCreateError( "existing header contains an erroneous SPDX expression" ) from err if merge_copyrights: spdx_copyrights = merge_copyright_lines( reuse_info.copyright_lines.union(existing_spdx.copyright_lines), ) else: spdx_copyrights = reuse_info.copyright_lines.union( existing_spdx.copyright_lines ) # TODO: This behaviour does not match the docstring. reuse_info = existing_spdx | reuse_info reuse_info = reuse_info.copy(copyright_lines=spdx_copyrights) new_header += _create_new_header( reuse_info, template=template, template_is_commented=template_is_commented, style=style, force_multi=force_multi, ) return new_header def _indices_of_newlines(text: str) -> Sequence[int]: indices = [0] start = 0 while True: match = _NEWLINE_PATTERN.search(text, start) if match: start = match.span()[1] indices.append(start) else: break return indices def _find_first_spdx_comment( text: str, style: Optional[Type[CommentStyle]] = None ) -> _TextSections: """Find the first SPDX comment in the file. Return a tuple with everything preceding the comment, the comment itself, and everything following it. Raises: MissingReuseInfo: if no REUSE info can be found in any comment """ if style is None: style = PythonCommentStyle indices = _indices_of_newlines(text) for index in indices: try: comment = style.comment_at_first_character(text[index:]) except CommentParseError: continue if contains_reuse_info(comment): return _TextSections( text[:index], comment + "\n", text[index + len(comment) + 1 :] ) raise MissingReuseInfo() def _extract_shebang(prefix: str, text: str) -> Tuple[str, str]: """Remove all lines that start with the shebang prefix from *text*. Return a tuple of (shebang, reduced_text). """ shebang_lines = [] for line in text.splitlines(): if line.startswith(prefix): shebang_lines.append(line) text = text.replace(line, "", 1) else: break shebang = "\n".join(shebang_lines) return (shebang, text) # pylint: disable=too-many-arguments def find_and_replace_header( text: str, reuse_info: ReuseInfo, template: Optional[Template] = None, template_is_commented: bool = False, style: Optional[Type[CommentStyle]] = None, force_multi: bool = False, merge_copyrights: bool = False, ) -> str: """Find the first SPDX comment block in *text*. That comment block is replaced by a new comment block containing *reuse_info*. It is formatted as according to *template*. The template is normally uncommented, but if it is already commented, *template_is_commented* should be :const:`True`. If both *style* and *template_is_commented* are provided, *style* is only used to find the header comment. If the comment block already contained some REUSE information, that information is merged into *reuse_info*. If no header exists, one is simply created. *text* is returned with a new header. Raises: CommentCreateError: if a comment could not be created. MissingReuseInfo: if the generated comment is missing SPDX information. """ if style is None: style = PythonCommentStyle try: before, header, after = _find_first_spdx_comment(text, style=style) except MissingReuseInfo: before, header, after = "", "", text # Workaround. EmptyCommentStyle should always be completely replaced. if style is EmptyCommentStyle: after = "" _LOGGER.debug(f"before = {repr(before)}") _LOGGER.debug(f"header = {repr(header)}") _LOGGER.debug(f"after = {repr(after)}") # Keep special first-line-of-file lines as the first line in the file, # or say, move our comments after it. if style.SHEBANGS: for shebang in style.SHEBANGS: # Extract shebang from header and put it in before. It's a bit # messy, but it ends up working. if header.startswith(shebang) and not before.strip(): before, header = _extract_shebang(shebang, header) elif after.startswith(shebang) and not any((before, header)): before, after = _extract_shebang(shebang, after) else: continue break header = create_header( reuse_info, header, template=template, template_is_commented=template_is_commented, style=style, force_multi=force_multi, merge_copyrights=merge_copyrights, ) new_text = f"{header}\n" if before.strip(): new_text = f"{before.rstrip()}\n\n{new_text}" if after.strip(): new_text = f"{new_text}\n{after.lstrip()}" return new_text # pylint: disable=too-many-arguments def add_new_header( text: str, reuse_info: ReuseInfo, template: Optional[Template] = None, template_is_commented: bool = False, style: Optional[Type[CommentStyle]] = None, force_multi: bool = False, merge_copyrights: bool = False, ) -> str: """Add a new header at the very top of *text*, similar to find_and_replace_header. But in this function, do not replace any headers or search for any existing REUSE information. Raises: CommentCreateError: if a comment could not be created. """ if style is None: style = PythonCommentStyle shebang = "" if style.SHEBANGS: for shebang_prefix in style.SHEBANGS: if text.startswith(shebang_prefix): shebang, text = _extract_shebang(shebang_prefix, text) break header = create_header( reuse_info, None, template=template, template_is_commented=template_is_commented, style=style, force_multi=force_multi, merge_copyrights=merge_copyrights, ) new_text = f"{header}\n" if shebang.strip(): new_text = f"{shebang.rstrip()}\n\n{new_text}" if text.strip(): new_text = f"{new_text}\n{text.lstrip()}" return new_text reuse-tool-4.0.3/src/reuse/lint.py000066400000000000000000000270311464275211500170600ustar00rootroot00000000000000# SPDX-FileCopyrightText: 2017 Free Software Foundation Europe e.V. # SPDX-FileCopyrightText: 2022 Florian Snow # SPDX-FileCopyrightText: 2023 DB Systel GmbH # SPDX-FileCopyrightText: 2024 Nico Rikken # # SPDX-License-Identifier: GPL-3.0-or-later """All linting happens here. The linting here is nothing more than reading the reports and printing some conclusions. """ import json import sys from argparse import ArgumentParser, Namespace from gettext import gettext as _ from io import StringIO from pathlib import Path from textwrap import TextWrapper from typing import IO, Any, Optional from . import __REUSE_version__ from .project import Project from .report import ProjectReport def add_arguments(parser: ArgumentParser) -> None: """Add arguments to parser.""" mutex_group = parser.add_mutually_exclusive_group() mutex_group.add_argument( "-q", "--quiet", action="store_true", help=_("prevents output") ) mutex_group.add_argument( "-j", "--json", action="store_true", help=_("formats output as JSON") ) mutex_group.add_argument( "-p", "--plain", action="store_true", help=_("formats output as plain text"), ) mutex_group.add_argument( "-l", "--lines", action="store_true", help=_("formats output as errors per line"), ) # pylint: disable=too-many-branches,too-many-statements,too-many-locals def format_plain(report: ProjectReport) -> str: """Formats data dictionary as plaintext string to be printed to sys.stdout Args: report: ProjectReport data Returns: String (in plaintext) that can be output to sys.stdout """ output = StringIO() if not report.is_compliant: # Bad licenses if report.bad_licenses: output.write("# " + _("BAD LICENSES") + "\n\n") for lic, files in sorted(report.bad_licenses.items()): output.write(_("'{}' found in:").format(lic) + "\n") for file in sorted(files): output.write(f"* {file}\n") output.write("\n\n") # Deprecated licenses if report.deprecated_licenses: output.write("# " + _("DEPRECATED LICENSES") + "\n\n") output.write( _("The following licenses are deprecated by SPDX:") + "\n" ) for lic in sorted(report.deprecated_licenses): output.write(f"* {lic}\n") output.write("\n\n") # Licenses without extension if report.licenses_without_extension: output.write("# " + _("LICENSES WITHOUT FILE EXTENSION") + "\n\n") output.write( _("The following licenses have no file extension:") + "\n" ) for lic in sorted(report.licenses_without_extension): output.write(f"* {lic}\n") output.write("\n\n") # Missing licenses if report.missing_licenses: output.write("# " + _("MISSING LICENSES") + "\n\n") for lic, files in sorted(report.missing_licenses.items()): output.write(_("'{}' found in:").format(lic) + "\n") for file in sorted(files): output.write(f"* {file}\n") output.write("\n\n") # Unused licenses if report.unused_licenses: output.write("# " + _("UNUSED LICENSES") + "\n\n") output.write(_("The following licenses are not used:") + "\n") for lic in sorted(report.unused_licenses): output.write(f"* {lic}\n") output.write("\n\n") # Read errors if report.read_errors: output.write("# " + _("READ ERRORS") + "\n\n") output.write(_("Could not read:") + "\n") for path in sorted(report.read_errors): output.write(f"* {path}\n") output.write("\n\n") # Missing copyright and licensing information files_without_both = report.files_without_copyright.intersection( report.files_without_licenses ) files_without_copyright_excl = ( report.files_without_copyright - files_without_both ) files_without_licenses_excl = ( report.files_without_licenses - files_without_both ) files_without_either = files_without_copyright_excl.union( files_without_licenses_excl ) if files_without_either or files_without_both: header = ( "# " + _("MISSING COPYRIGHT AND LICENSING INFORMATION") + "\n\n" ) output.write(header) if files_without_both: output.write( _( "The following files have no copyright and licensing " "information:" ) ) output.write("\n") for file in sorted(files_without_both): output.write(f"* {file}\n") output.write("\n") if files_without_copyright_excl: output.write( _("The following files have no copyright information:") ) output.write("\n") for file in sorted(files_without_copyright_excl): output.write(f"* {file}\n") output.write("\n") if files_without_licenses_excl: output.write( _("The following files have no licensing information:") ) output.write("\n") for file in sorted(files_without_licenses_excl): output.write(f"* {file}\n") output.write("\n") output.write("\n") output.write("# " + _("SUMMARY")) output.write("\n\n") total_files = len(report.file_reports) summary_contents = { _("Bad licenses:"): ", ".join(report.bad_licenses), _("Deprecated licenses:"): ", ".join(report.deprecated_licenses), _("Licenses without file extension:"): ", ".join( report.licenses_without_extension ), _("Missing licenses:"): ", ".join(report.missing_licenses), _("Unused licenses:"): ", ".join(report.unused_licenses), _("Used licenses:"): ", ".join(report.used_licenses), _("Read errors:"): str(len(report.read_errors)), _( "Files with copyright information:" ): f"{total_files - len(report.files_without_copyright)}" f" / {total_files}", _( "Files with license information:" ): f"{total_files - len(report.files_without_licenses)}" f" / {total_files}", } # Replace empty values with 0. summary_contents = { key: value if value else "0" for key, value in summary_contents.items() } for key, value in summary_contents.items(): output.write(f"* {key} {value}\n") output.write("\n") if report.is_compliant: output.write( _( "Congratulations! Your project is compliant with version" " {} of the REUSE Specification :-)" ).format(__REUSE_version__) ) else: output.write( _( "Unfortunately, your project is not compliant with version " "{} of the REUSE Specification :-(" ).format(__REUSE_version__) ) # Write recommendations in a nicely wrapped format output.write("\n\n\n# ") output.write(_("RECOMMENDATIONS")) output.write("\n\n") wrapper = TextWrapper( width=80, drop_whitespace=True, break_long_words=False, initial_indent="* ", subsequent_indent=" ", ) for help_text in report.recommendations: output.write("\n".join(wrapper.wrap(help_text))) output.write("\n") output.write("\n") return output.getvalue() def format_json(report: ProjectReport) -> str: """Formats data dictionary as JSON string ready to be printed to sys.stdout Args: report: Dictionary containing formatted ProjectReport data Returns: String (representing JSON) that can be output to sys.stdout """ def custom_serializer(obj: Any) -> Any: """Custom serializer for the dictionary output of ProjectReport Args: obj: Object to be serialized """ if isinstance(obj, Path): return str(obj) if isinstance(obj, set): return list(obj) raise TypeError( f"Object of type {obj.__class__.__name__} is not JSON serializable" ) return json.dumps( report.to_dict_lint(), indent=2, # Serialize sets to lists default=custom_serializer, ) def format_lines(report: ProjectReport) -> str: """Formats data dictionary as plaintext strings to be printed to sys.stdout Sorting of output is not guaranteed. Symbolic links can result in multiple entries per file. Args: report: ProjectReport data Returns: String (in plaintext) that can be output to sys.stdout """ output = StringIO() def license_path(lic: str) -> Optional[Path]: """Resolve a license identifier to a license path.""" return report.licenses.get(lic) if not report.is_compliant: # Bad licenses for lic, files in sorted(report.bad_licenses.items()): for path in sorted(files): output.write( _("{path}: bad license {lic}\n").format(path=path, lic=lic) ) # Deprecated licenses for lic in sorted(report.deprecated_licenses): lic_path = license_path(lic) output.write( _("{lic_path}: deprecated license\n").format(lic_path=lic_path) ) # Licenses without extension for lic in sorted(report.licenses_without_extension): lic_path = license_path(lic) output.write( _("{lic_path}: license without file extension\n").format( lic_path=lic_path ) ) # Unused licenses for lic in sorted(report.unused_licenses): lic_path = license_path(lic) output.write( _("{lic_path}: unused license\n").format(lic_path=lic_path) ) # Missing licenses for lic, files in sorted(report.missing_licenses.items()): for path in sorted(files): output.write( _("{path}: missing license {lic}\n").format( path=path, lic=lic ) ) # Read errors for path in sorted(report.read_errors): output.write(_("{path}: read error\n").format(path=path)) # Without licenses for path in report.files_without_licenses: output.write(_("{path}: no license identifier\n").format(path=path)) # Without copyright for path in report.files_without_copyright: output.write(_("{path}: no copyright notice\n").format(path=path)) return output.getvalue() def run(args: Namespace, project: Project, out: IO[str] = sys.stdout) -> int: """List all non-compliant files.""" report = ProjectReport.generate( project, do_checksum=False, multiprocessing=not args.no_multiprocessing ) if args.quiet: pass elif args.json: out.write(format_json(report)) elif args.lines: out.write(format_lines(report)) else: out.write(format_plain(report)) return 0 if report.is_compliant else 1 reuse-tool-4.0.3/src/reuse/project.py000066400000000000000000000436221464275211500175640ustar00rootroot00000000000000# SPDX-FileCopyrightText: 2017 Free Software Foundation Europe e.V. # SPDX-FileCopyrightText: 2022 Florian Snow # SPDX-FileCopyrightText: 2023 Carmen Bianca BAKKER # SPDX-FileCopyrightText: 2023 Matthias Riße # SPDX-FileCopyrightText: 2023 DB Systel GmbH # # SPDX-License-Identifier: GPL-3.0-or-later """Module that contains the central Project class.""" import contextlib import errno import glob import logging import os import warnings from collections import defaultdict from gettext import gettext as _ from pathlib import Path from typing import DefaultDict, Dict, Iterator, List, NamedTuple, Optional, Type from binaryornot.check import is_binary from . import ( _IGNORE_DIR_PATTERNS, _IGNORE_FILE_PATTERNS, _IGNORE_MESON_PARENT_DIR_PATTERNS, IdentifierNotFound, ReuseInfo, ) from ._licenses import EXCEPTION_MAP, LICENSE_MAP from ._util import ( _LICENSEREF_PATTERN, StrPath, _determine_license_path, relative_from_root, reuse_info_of_file, ) from .global_licensing import ( GlobalLicensing, NestedReuseTOML, PrecedenceType, ReuseDep5, ) from .vcs import VCSStrategy, VCSStrategyNone, all_vcs_strategies _LOGGER = logging.getLogger(__name__) class GlobalLicensingConflict(Exception): """There are two global licensing files in the project that are not compatible. """ class GlobalLicensingFound(NamedTuple): path: Path cls: Type[GlobalLicensing] class Project: """Simple object that holds the project's root, which is necessary for many interactions. """ # pylint: disable=too-many-arguments def __init__( self, root: StrPath, vcs_strategy: Optional[Type[VCSStrategy]] = None, license_map: Optional[Dict[str, Dict]] = None, licenses: Optional[Dict[str, Path]] = None, global_licensing: Optional[GlobalLicensing] = None, include_submodules: bool = False, include_meson_subprojects: bool = False, ): self.root = Path(root) if vcs_strategy is None: vcs_strategy = VCSStrategyNone self.vcs_strategy = vcs_strategy(self) if license_map is None: license_map = LICENSE_MAP self.license_map = license_map.copy() self.license_map.update(EXCEPTION_MAP) self.licenses_without_extension: Dict[str, Path] = {} if licenses is None: licenses = {} self.licenses = licenses self.global_licensing = global_licensing self.include_submodules = include_submodules self.include_meson_subprojects = include_meson_subprojects @classmethod def from_directory( cls, root: StrPath, include_submodules: bool = False, include_meson_subprojects: bool = False, ) -> "Project": """A factory method that reads various files in the *root* directory to correctly build the :class:`Project` object. Args: root: The root of the project. include_submodules: Whether to also lint VCS submodules. include_meson_subprojects: Whether to also lint Meson subprojects. Raises: FileNotFoundError: if root does not exist. NotADirectoryError: if root is not a directory. UnicodeDecodeError: if the global licensing config file could not be decoded. GlobalLicensingParseError: if the global licensing config file could not be parsed. GlobalLicensingConflict: if more than one global licensing config file is present. """ root = Path(root) if not root.exists(): raise FileNotFoundError( errno.ENOENT, os.strerror(errno.ENOENT), str(root), ) if not root.is_dir(): raise NotADirectoryError( errno.ENOTDIR, os.strerror(errno.ENOTDIR), str(root), ) vcs_strategy = cls._detect_vcs_strategy(root) global_licensing: Optional[GlobalLicensing] = None found = cls.find_global_licensing(root) if found: global_licensing = found.cls.from_file(found.path) project = cls( root, vcs_strategy=vcs_strategy, global_licensing=global_licensing, include_submodules=include_submodules, include_meson_subprojects=include_meson_subprojects, ) # TODO: Because the `_find_licenses()` method is so broad and depends on # some object attributes, we set the attribute after creating the # object. Ideally we do this before creating the object, but that would # require refactoring the method. project.licenses = project._find_licenses() return project def all_files(self, directory: Optional[StrPath] = None) -> Iterator[Path]: """Yield all files in *directory* and its subdirectories. The files that are not yielded are: - Files ignored by VCS (e.g., see .gitignore) - Files/directories matching IGNORE_*_PATTERNS. """ if directory is None: directory = self.root directory = Path(directory) for root_str, dirs, files in os.walk(directory): root = Path(root_str) _LOGGER.debug("currently walking in '%s'", root) # Don't walk ignored directories for dir_ in list(dirs): the_dir = root / dir_ if self._is_path_ignored(the_dir): _LOGGER.debug("ignoring '%s'", the_dir) dirs.remove(dir_) elif the_dir.is_symlink(): _LOGGER.debug("skipping symlink '%s'", the_dir) dirs.remove(dir_) elif ( not self.include_submodules and self.vcs_strategy.is_submodule(the_dir) ): _LOGGER.info( "ignoring '%s' because it is a submodule", the_dir ) dirs.remove(dir_) # Filter files. for file_ in files: the_file = root / file_ if self._is_path_ignored(the_file): _LOGGER.debug("ignoring '%s'", the_file) continue if the_file.is_symlink(): _LOGGER.debug("skipping symlink '%s'", the_file) continue # Suppressing this error because I simply don't want to deal # with that here. with contextlib.suppress(OSError): if the_file.stat().st_size == 0: _LOGGER.debug("skipping 0-sized file '%s'", the_file) continue _LOGGER.debug("yielding '%s'", the_file) yield the_file def reuse_info_of(self, path: StrPath) -> List[ReuseInfo]: """Return REUSE info of *path*. This function will return any REUSE information that it can find: from within the file, the .license file, from REUSE.toml, and/or from the .reuse/dep5 file. The presence of a .license file always means that the file itself will not be parsed for REUSE information. When information is found from multiple sources, and if the precedence for that file in REUSE.toml is 'aggregate' (or if .reuse/dep5 is used), then two (or more) :class:`ReuseInfo` objects are returned in list set, each with respective discovered REUSE information and information about the source. Alternatively, if the precedence is set to 'closest' or 'toml', or if information was found in only one source, then a list of one item is returned. The exact precedence handling is detailed in the specification. An empty list is returned if no information was found whatsoever. """ # pylint: disable=too-many-branches original_path = path path = _determine_license_path(path) _LOGGER.debug(f"searching '{path}' for REUSE information") # This means that only one 'source' of licensing/copyright information # is captured in ReuseInfo global_results: "DefaultDict[PrecedenceType, List[ReuseInfo]]" = ( defaultdict(list) ) file_result = ReuseInfo() result: List[ReuseInfo] = [] # Search the global licensing file for REUSE information. if self.global_licensing: relpath = self.relative_from_root(path) global_results = defaultdict( list, self.global_licensing.reuse_info_of(relpath) ) for info_list in global_results.values(): for global_result in info_list: if global_result.contains_copyright_or_licensing(): _LOGGER.info( _("'{path}' covered by {global_path}").format( path=path, global_path=global_result.source_path ) ) if PrecedenceType.OVERRIDE in global_results: _LOGGER.info( _( "'{path}' is covered exclusively by REUSE.toml. Not reading" " the file contents." ).format(path=path) ) elif is_binary(str(path)): _LOGGER.info( _( "'{path}' was detected as a binary file; not searching its" " contents for REUSE information." ).format(path=path) ) else: file_result = reuse_info_of_file(path, original_path, self.root) result.extend(global_results[PrecedenceType.OVERRIDE]) result.extend(global_results[PrecedenceType.AGGREGATE]) if file_result.contains_info(): result.append(file_result) if not file_result.contains_copyright_or_licensing(): result.extend(global_results[PrecedenceType.CLOSEST]) # Special case: If a file contains only copyright, apply the # REUSE.toml's licensing if it exists, and vice versa. elif file_result.contains_copyright_xor_licensing(): if global_results[PrecedenceType.CLOSEST]: # There should only by a single CLOSEST result in the list. closest = global_results[PrecedenceType.CLOSEST][0] if file_result.copyright_lines: result.append( closest.copy( copyright_lines=set(), ) ) elif file_result.spdx_expressions: result.append( closest.copy( spdx_expressions=set(), ) ) return result def relative_from_root(self, path: StrPath) -> Path: """If the project root is /tmp/project, and *path* is /tmp/project/src/file, then return src/file. """ return relative_from_root(path, self.root) @classmethod def find_global_licensing( cls, root: Path ) -> Optional[GlobalLicensingFound]: """Find the path and corresponding class of a project directory's :class:`GlobalLicensing`. Raises: GlobalLicensingConflict: if more than one global licensing config file is present. """ candidate: Optional[GlobalLicensingFound] = None dep5_path = root / ".reuse/dep5" if (dep5_path).exists(): # Sneaky workaround to not print this warning. if not os.environ.get("_SUPPRESS_DEP5_WARNING"): warnings.warn( _( "'.reuse/dep5' is deprecated. You are recommended to" " instead use REUSE.toml. Use `reuse convert-dep5` to" " convert." ), PendingDeprecationWarning, ) candidate = GlobalLicensingFound(dep5_path, ReuseDep5) toml_path = None with contextlib.suppress(StopIteration): toml_path = next(root.rglob("**/REUSE.toml")) if toml_path is not None: if candidate is not None: raise GlobalLicensingConflict( _( "Found both '{new_path}' and '{old_path}'. You" " cannot keep both files simultaneously; they are" " not intercompatible." ).format(new_path=toml_path, old_path=dep5_path) ) candidate = GlobalLicensingFound(root, NestedReuseTOML) return candidate def _is_path_ignored(self, path: Path) -> bool: """Is *path* ignored by some mechanism?""" name = path.name parent_parts = path.parent.parts parent_dir = parent_parts[-1] if len(parent_parts) > 0 else "" if path.is_file(): for pattern in _IGNORE_FILE_PATTERNS: if pattern.match(name): return True elif path.is_dir(): for pattern in _IGNORE_DIR_PATTERNS: if pattern.match(name): return True if not self.include_meson_subprojects: for pattern in _IGNORE_MESON_PARENT_DIR_PATTERNS: if pattern.match(parent_dir): return True if self.vcs_strategy.is_ignored(path): return True return False def _identifier_of_license(self, path: Path) -> str: """Figure out the SPDX License identifier of a license given its path. The name of the path (minus its extension) should be a valid SPDX License Identifier. """ if not path.suffix: raise IdentifierNotFound(f"{path} has no file extension") if path.stem in self.license_map: return path.stem if _LICENSEREF_PATTERN.match(path.stem): return path.stem raise IdentifierNotFound( f"Could not find SPDX License Identifier for {path}" ) def _find_licenses(self) -> Dict[str, Path]: """Return a dictionary of all licenses in the project, with their SPDX identifiers as names and paths as values. """ # TODO: This method does more than one thing. We ought to simplify it. license_files: Dict[str, Path] = {} directory = str(self.root / "LICENSES/**") for path_str in glob.iglob(directory, recursive=True): path = Path(path_str) # For some reason, LICENSES/** is resolved even though it # doesn't exist. I have no idea why. Deal with that here. if not Path(path).exists() or Path(path).is_dir(): continue if Path(path).suffix == ".license": continue path = self.relative_from_root(path) _LOGGER.debug( _("determining identifier of '{path}'").format(path=path) ) try: identifier = self._identifier_of_license(path) except IdentifierNotFound: if path.name in self.license_map: _LOGGER.info( _("{path} does not have a file extension").format( path=path ) ) identifier = path.name self.licenses_without_extension[identifier] = path else: identifier = path.stem _LOGGER.warning( _( "Could not resolve SPDX License Identifier of" " {path}, resolving to {identifier}. Make sure the" " license is in the license list found at" " or that it starts" " with 'LicenseRef-', and that it has a file" " extension." ).format(path=path, identifier=identifier) ) if identifier in license_files: _LOGGER.critical( _( "{identifier} is the SPDX License Identifier of both" " {path} and {other_path}" ).format( identifier=identifier, path=path, other_path=license_files[identifier], ) ) raise RuntimeError("Multiple licenses resolve to {identifier}") # Add the identifiers license_files[identifier] = path if ( _LICENSEREF_PATTERN.match(identifier) and "Unknown" not in identifier ): self.license_map[identifier] = { "reference": str(path), "isDeprecatedLicenseId": False, "detailsUrl": None, "referenceNumber": None, "name": identifier, "licenseId": identifier, "seeAlso": [], "isOsiApproved": None, } return license_files @classmethod def _detect_vcs_strategy(cls, root: StrPath) -> Type[VCSStrategy]: """For each supported VCS, check if the software is available and if the directory is a repository. If not, return :class:`VCSStrategyNone`. """ for strategy in all_vcs_strategies(): if strategy.EXE and strategy.in_repo(root): return strategy _LOGGER.info( _( "project '{}' is not a VCS repository or required VCS" " software is not installed" ).format(root) ) return VCSStrategyNone reuse-tool-4.0.3/src/reuse/py.typed000066400000000000000000000001721464275211500172340ustar00rootroot00000000000000# SPDX-FileCopyrightText: 2023 Carmen Bianca BAKKER # # SPDX-License-Identifier: GPL-3.0-or-later reuse-tool-4.0.3/src/reuse/report.py000066400000000000000000000614561464275211500174360ustar00rootroot00000000000000# SPDX-FileCopyrightText: 2017 Free Software Foundation Europe e.V. # SPDX-FileCopyrightText: 2022 Florian Snow # SPDX-FileCopyrightText: 2022 Pietro Albini # SPDX-FileCopyrightText: 2023 DB Systel GmbH # SPDX-FileCopyrightText: 2023 Carmen Bianca BAKKER # # SPDX-License-Identifier: GPL-3.0-or-later """Module that contains reports about files and projects for linting.""" import bdb import contextlib import datetime import logging import multiprocessing as mp import random from gettext import gettext as _ from hashlib import md5 from io import StringIO from os import cpu_count from pathlib import Path, PurePath from typing import Any, Dict, Iterable, List, NamedTuple, Optional, Set, cast from uuid import uuid4 from . import __REUSE_version__, __version__ from ._util import _LICENSEREF_PATTERN, _LICENSING, StrPath, _checksum from .global_licensing import ReuseDep5 from .project import Project, ReuseInfo _LOGGER = logging.getLogger(__name__) LINT_VERSION = "1.0" class _MultiprocessingContainer: """Container that remembers some data in order to generate a FileReport.""" def __init__( self, project: Project, do_checksum: bool, add_license_concluded: bool ): if isinstance(project.global_licensing, ReuseDep5): # Remember that a dep5_copyright was (or was not) set prior. self.has_dep5 = bool(project.global_licensing) # TODO: We create a copy of the project in the following # song-and-dance because the debian Copyright object cannot be # pickled. new_project = Project( project.root, vcs_strategy=project.vcs_strategy.__class__, license_map=project.license_map, licenses=project.licenses.copy(), # TODO: adjust this method/class to account for REUSE.toml as # well. Unset dep5_copyright global_licensing=None, include_submodules=project.include_submodules, include_meson_subprojects=project.include_meson_subprojects, ) new_project.licenses_without_extension = ( project.licenses_without_extension ) self.project = new_project else: self.has_dep5 = False self.project = project self.reuse_dep5: Optional[ReuseDep5] = None self.do_checksum = do_checksum self.add_license_concluded = add_license_concluded def __call__(self, file_: StrPath) -> "_MultiprocessingResult": # By remembering that we've parsed the .reuse/dep5, we only parse it # once (the first time) inside of each process. if self.has_dep5 and not self.reuse_dep5: with contextlib.suppress(Exception): self.reuse_dep5 = ReuseDep5.from_file( self.project.root / ".reuse/dep5" ) self.project.global_licensing = self.reuse_dep5 # pylint: disable=broad-except try: return _MultiprocessingResult( file_, FileReport.generate( self.project, file_, do_checksum=self.do_checksum, add_license_concluded=self.add_license_concluded, ), None, ) except Exception as exc: return _MultiprocessingResult(file_, None, exc) class _MultiprocessingResult(NamedTuple): """Result of :class:`MultiprocessingContainer`.""" path: StrPath report: Optional["FileReport"] error: Optional[Exception] class ProjectReport: # pylint: disable=too-many-instance-attributes """Object that holds linting report about the project.""" def __init__(self, do_checksum: bool = True): self.path: StrPath = "" self.licenses: Dict[str, Path] = {} self.missing_licenses: Dict[str, Set[Path]] = {} self.bad_licenses: Dict[str, Set[Path]] = {} self.deprecated_licenses: Set[str] = set() self.read_errors: Set[Path] = set() self.file_reports: Set[FileReport] = set() self.licenses_without_extension: Dict[str, Path] = {} self.do_checksum = do_checksum self._unused_licenses: Optional[Set[str]] = None self._used_licenses: Optional[Set[str]] = None self._files_without_licenses: Optional[Set[Path]] = None self._files_without_copyright: Optional[Set[Path]] = None self._is_compliant: Optional[bool] = None def to_dict_lint(self) -> Dict[str, Any]: """Collects and formats data relevant to linting from report and returns it as a dictionary. Returns: Dictionary containing data from the ProjectReport object. """ # Setup report data container data: Dict[str, Any] = { "non_compliant": { "missing_licenses": self.missing_licenses, "unused_licenses": [str(file) for file in self.unused_licenses], "deprecated_licenses": [ str(file) for file in self.deprecated_licenses ], "bad_licenses": self.bad_licenses, "licenses_without_extension": self.licenses_without_extension, "missing_copyright_info": [ str(file) for file in self.files_without_copyright ], "missing_licensing_info": [ str(file) for file in self.files_without_licenses ], "read_errors": [str(file) for file in self.read_errors], }, "files": [], "summary": { "used_licenses": [], }, "recommendations": self.recommendations, } # Populate 'files' for file_report in self.file_reports: data["files"].append(file_report.to_dict_lint()) # Populate 'summary' number_of_files = len(self.file_reports) data["summary"] = { "used_licenses": list(self.used_licenses), "files_total": number_of_files, "files_with_copyright_info": number_of_files - len(self.files_without_copyright), "files_with_licensing_info": number_of_files - len(self.files_without_licenses), "compliant": self.is_compliant, } # Add the top three keys unsorted_data = { "lint_version": LINT_VERSION, "reuse_spec_version": __REUSE_version__, "reuse_tool_version": __version__, **data, } # Sort dictionary keys while keeping the top three keys at the beginning # and the recommendations on the bottom sorted_keys = sorted(list(unsorted_data.keys())) sorted_keys.remove("lint_version") sorted_keys.remove("reuse_spec_version") sorted_keys.remove("reuse_tool_version") sorted_keys.remove("recommendations") sorted_keys = ( [ "lint_version", "reuse_spec_version", "reuse_tool_version", ] + sorted_keys + ["recommendations"] ) sorted_data = {key: unsorted_data[key] for key in sorted_keys} return sorted_data def bill_of_materials( self, creator_person: Optional[str] = None, creator_organization: Optional[str] = None, ) -> str: """Generate a bill of materials from the project. See https://spdx.org/specifications. """ out = StringIO() # Write mandatory tags out.write("SPDXVersion: SPDX-2.1\n") out.write("DataLicense: CC0-1.0\n") out.write("SPDXID: SPDXRef-DOCUMENT\n") out.write(f"DocumentName: {Path(self.path).resolve().name}\n") # TODO: Generate UUID from git revision maybe # TODO: Fix the URL out.write( f"DocumentNamespace: http://spdx.org/spdxdocs/spdx-v2.1-{uuid4()}\n" ) # Author out.write(f"Creator: Person: {format_creator(creator_person)}\n") out.write( f"Creator: Organization: {format_creator(creator_organization)}\n" ) out.write(f"Creator: Tool: reuse-{__version__}\n") now = datetime.datetime.now(tz=datetime.timezone.utc) out.write(f"Created: {now.strftime('%Y-%m-%dT%H:%M:%SZ')}\n") out.write( "CreatorComment: This document was created automatically" " using available reuse information consistent with" " REUSE.\n" ) reports = sorted(self.file_reports, key=lambda x: x.name) for report in reports: out.write( "Relationship: SPDXRef-DOCUMENT DESCRIBES" f" {report.spdx_id}\n" ) for report in reports: out.write("\n") out.write(f"FileName: {report.name}\n") out.write(f"SPDXID: {report.spdx_id}\n") out.write(f"FileChecksum: SHA1: {report.chk_sum}\n") out.write(f"LicenseConcluded: {report.license_concluded}\n") for lic in sorted(report.licenses_in_file): out.write(f"LicenseInfoInFile: {lic}\n") if report.copyright: out.write( "FileCopyrightText:" f" {report.copyright}\n" ) else: out.write("FileCopyrightText: NONE\n") # Licenses for lic, path in sorted(self.licenses.items()): if _LICENSEREF_PATTERN.match(lic): out.write("\n") out.write(f"LicenseID: {lic}\n") out.write("LicenseName: NOASSERTION\n") with (Path(self.path) / path).open(encoding="utf-8") as fp: out.write(f"ExtractedText: {fp.read()}\n") return out.getvalue() @classmethod def generate( cls, project: Project, do_checksum: bool = True, multiprocessing: bool = cpu_count() > 1, # type: ignore add_license_concluded: bool = False, ) -> "ProjectReport": """Generate a ProjectReport from a Project.""" project_report = cls(do_checksum=do_checksum) project_report.path = project.root project_report.licenses = project.licenses project_report.licenses_without_extension = ( project.licenses_without_extension ) container = _MultiprocessingContainer( project, do_checksum, add_license_concluded ) if multiprocessing: with mp.Pool() as pool: results: Iterable[_MultiprocessingResult] = pool.map( container, project.all_files() ) pool.join() else: results = map(container, project.all_files()) for result in results: if result.error: # Facilitate better debugging by being able to quit the program. if isinstance(result.error, bdb.BdbQuit): raise bdb.BdbQuit() from result.error if isinstance(result.error, (OSError, UnicodeError)): _LOGGER.error( _("Could not read '{path}'").format(path=result.path), exc_info=result.error, ) project_report.read_errors.add(Path(result.path)) continue _LOGGER.error( _( "Unexpected error occurred while parsing '{path}'" ).format(path=result.path), exc_info=result.error, ) project_report.read_errors.add(Path(result.path)) continue file_report = cast(FileReport, result.report) # File report. project_report.file_reports.add(file_report) # Missing licenses. for missing_license in file_report.missing_licenses: project_report.missing_licenses.setdefault( missing_license, set() ).add(file_report.path) # Bad licenses for bad_license in file_report.bad_licenses: project_report.bad_licenses.setdefault(bad_license, set()).add( file_report.path ) # More bad licenses, and also deprecated licenses for name, path in project.licenses.items(): if name not in project.license_map: project_report.bad_licenses.setdefault(name, set()).add(path) elif project.license_map[name]["isDeprecatedLicenseId"]: project_report.deprecated_licenses.add(name) return project_report @property def used_licenses(self) -> Set[str]: """Set of license identifiers that are found in file reports.""" if self._used_licenses is not None: return self._used_licenses self._used_licenses = { lic for file_report in self.file_reports for lic in file_report.licenses_in_file } return self._used_licenses @property def unused_licenses(self) -> Set[str]: """Set of license identifiers that are not found in any file report.""" if self._unused_licenses is not None: return self._unused_licenses # First collect licenses that are suspected to be unused. suspected_unused_licenses = { lic for lic in self.licenses if lic not in self.used_licenses } # Remove false positives. self._unused_licenses = { lic for lic in suspected_unused_licenses if f"{lic}+" not in self.used_licenses } return self._unused_licenses @property def files_without_licenses(self) -> Set[Path]: """Set of paths that have no licensing information.""" if self._files_without_licenses is not None: return self._files_without_licenses self._files_without_licenses = { file_report.path for file_report in self.file_reports if not file_report.licenses_in_file } return self._files_without_licenses @property def files_without_copyright(self) -> Set[Path]: """Set of paths that have no copyright information.""" if self._files_without_copyright is not None: return self._files_without_copyright self._files_without_copyright = { file_report.path for file_report in self.file_reports if not file_report.copyright } return self._files_without_copyright @property def is_compliant(self) -> bool: """Whether the report is compliant with the REUSE Spec.""" if self._is_compliant is not None: return self._is_compliant self._is_compliant = not any( ( self.missing_licenses, self.unused_licenses, self.bad_licenses, self.deprecated_licenses, self.licenses_without_extension, self.files_without_copyright, self.files_without_licenses, self.read_errors, ) ) return self._is_compliant @property def recommendations(self) -> List[str]: """Generate help for next steps based on found REUSE issues""" recommendations = [] # These items should be ordered in the same way as in the summary. if self.bad_licenses: recommendations.append( _( "Fix bad licenses: At least one license in the LICENSES" " directory and/or provided by 'SPDX-License-Identifier'" " tags is invalid. They are either not valid SPDX License" " Identifiers or do not start with 'LicenseRef-'. FAQ about" " custom licenses:" " https://reuse.software/faq/#custom-license" ) ) if self.deprecated_licenses: recommendations.append( _( "Fix deprecated licenses: At least one of the licenses in" " the LICENSES directory and/or provided by an" " 'SPDX-License-Identifier' tag or in '.reuse/dep5' has" " been deprecated by SPDX. The current list and their" " respective recommended new identifiers can be found" " here: " ) ) if self.licenses_without_extension: recommendations.append( _( "Fix licenses without file extension: At least one license" " text file in the 'LICENSES' directory does not have a" " '.txt' file extension. Please rename the file(s)" " accordingly." ) ) if self.missing_licenses: recommendations.append( _( "Fix missing licenses: For at least one of the license" " identifiers provided by the 'SPDX-License-Identifier'" " tags, there is no corresponding license text file in the" " 'LICENSES' directory. For SPDX license identifiers, you" " can simply run 'reuse download --all' to get any missing" " ones. For custom licenses (starting with 'LicenseRef-')," " you need to add these files yourself." ) ) if self.unused_licenses: recommendations.append( _( "Fix unused licenses: At least one of the license text" " files in 'LICENSES' is not referenced by any file, e.g." " by an 'SPDX-License-Identifier' tag. Please make sure" " that you either tag the accordingly licensed files" " properly, or delete the unused license text if you are" " sure that no file or code snippet is licensed as such." ) ) if self.read_errors: recommendations.append( _( "Fix read errors: At least one of the files in your" " directory cannot be read by the tool. Please check the" " file permissions. You will find the affected files at the" " top of the output as part of the logged error messages." ) ) if self.files_without_copyright or self.files_without_licenses: recommendations.append( _( "Fix missing copyright/licensing information: For one or" " more files, the tool cannot find copyright and/or" " licensing information. You typically do this by adding" " 'SPDX-FileCopyrightText' and 'SPDX-License-Identifier'" " tags to each file. The tutorial explains additional ways" " to do this: " ) ) return recommendations class FileReport: # pylint: disable=too-many-instance-attributes """Object that holds a linting report about a single file.""" def __init__(self, name: str, path: StrPath, do_checksum: bool = True): self.name = name self.path = Path(path) self.do_checksum = do_checksum self.reuse_infos: List[ReuseInfo] = [] self.spdx_id: Optional[str] = None self.chk_sum: Optional[str] = None self.licenses_in_file: List[str] = [] self.license_concluded: str = "" self.copyright: str = "" self.bad_licenses: Set[str] = set() self.missing_licenses: Set[str] = set() def to_dict_lint(self) -> Dict[str, Any]: """Turn the report into a json-like dictionary with exclusively information relevant for linting. """ return { # This gets rid of the './' prefix. In Python 3.9, use # str.removeprefix. "path": PurePath(self.name).as_posix(), "copyrights": [ { "value": line, "source": reuse_info.source_path, "source_type": ( reuse_info.source_type.value if reuse_info.source_type else None ), } for reuse_info in self.reuse_infos for line in reuse_info.copyright_lines ], "spdx_expressions": [ { "value": str(expression), "source": reuse_info.source_path, "source_type": ( reuse_info.source_type.value if reuse_info.source_type else None ), } for reuse_info in self.reuse_infos for expression in reuse_info.spdx_expressions ], } @classmethod def generate( cls, project: Project, path: StrPath, do_checksum: bool = True, add_license_concluded: bool = False, ) -> "FileReport": """Generate a FileReport from a path in a Project.""" path = Path(path) if not path.is_file(): raise OSError(f"{path} is not a file") relative = project.relative_from_root(path) report = cls(f"./{relative}", path, do_checksum=do_checksum) # Checksum and ID if report.do_checksum: report.chk_sum = _checksum(path) else: # This path avoids a lot of heavy computation, which is handy for # scenarios where you only need a unique hash, not a consistent # hash. report.chk_sum = f"{random.getrandbits(160):040x}" spdx_id = md5() spdx_id.update(report.name.encode("utf-8")) spdx_id.update(report.chk_sum.encode("utf-8")) report.spdx_id = f"SPDXRef-{spdx_id.hexdigest()}" reuse_infos = project.reuse_info_of(path) for reuse_info in reuse_infos: for expression in reuse_info.spdx_expressions: for identifier in _LICENSING.license_keys(expression): # A license expression akin to Apache-1.0+ should register # correctly if LICENSES/Apache-1.0.txt exists. identifiers = {identifier} if identifier.endswith("+"): identifiers.add(identifier[:-1]) # Bad license if not identifiers.intersection(project.license_map): report.bad_licenses.add(identifier) # Missing license if not identifiers.intersection(project.licenses): report.missing_licenses.add(identifier) # Add license to report. report.licenses_in_file.append(identifier) if not add_license_concluded: report.license_concluded = "NOASSERTION" elif not any(reuse_info.spdx_expressions for reuse_info in reuse_infos): report.license_concluded = "NONE" else: # Merge all the license expressions together, wrapping them in # parentheses to make sure an expression doesn't spill into another # one. The extra parentheses will be removed by the roundtrip # through parse() -> simplify() -> render(). report.license_concluded = ( _LICENSING.parse( " AND ".join( f"({expression})" for reuse_info in reuse_infos for expression in reuse_info.spdx_expressions ), ) .simplify() .render() ) # Copyright text report.copyright = "\n".join( sorted( line for reuse_info in reuse_infos for line in reuse_info.copyright_lines ) ) # Source of licensing and copyright info report.reuse_infos = reuse_infos return report def __hash__(self) -> int: if self.chk_sum is not None: return hash(self.name + self.chk_sum) return super().__hash__() def format_creator(creator: Optional[str]) -> str: """Render the creator field based on the provided flag""" if creator is None: return "Anonymous ()" if "(" in creator and creator.endswith(")"): # The creator field already contains an email address return creator return creator + " ()" reuse-tool-4.0.3/src/reuse/resources/000077500000000000000000000000001464275211500175475ustar00rootroot00000000000000reuse-tool-4.0.3/src/reuse/resources/exceptions.json000066400000000000000000000717671464275211500226450ustar00rootroot00000000000000{ "licenseListVersion": "3.24.0", "exceptions": [ { "reference": "./389-exception.json", "isDeprecatedLicenseId": false, "detailsUrl": "./389-exception.html", "referenceNumber": 52, "name": "389 Directory Server Exception", "licenseExceptionId": "389-exception", "seeAlso": [ "http://directory.fedoraproject.org/wiki/GPL_Exception_License_Text", "https://web.archive.org/web/20080828121337/http://directory.fedoraproject.org/wiki/GPL_Exception_License_Text" ] }, { "reference": "./Asterisk-exception.json", "isDeprecatedLicenseId": false, "detailsUrl": "./Asterisk-exception.html", "referenceNumber": 39, "name": "Asterisk exception", "licenseExceptionId": "Asterisk-exception", "seeAlso": [ "https://github.com/asterisk/libpri/blob/7f91151e6bd10957c746c031c1f4a030e8146e9a/pri.c#L22", "https://github.com/asterisk/libss7/blob/03e81bcd0d28ff25d4c77c78351ddadc82ff5c3f/ss7.c#L24" ] }, { "reference": "./Asterisk-linking-protocols-exception.json", "isDeprecatedLicenseId": false, "detailsUrl": "./Asterisk-linking-protocols-exception.html", "referenceNumber": 24, "name": "Asterisk linking protocols exception", "licenseExceptionId": "Asterisk-linking-protocols-exception", "seeAlso": [ "https://github.com/asterisk/asterisk/blob/115d7c01e32ccf4566a99e9d74e2b88830985a0b/LICENSE#L27" ] }, { "reference": "./Autoconf-exception-2.0.json", "isDeprecatedLicenseId": false, "detailsUrl": "./Autoconf-exception-2.0.html", "referenceNumber": 60, "name": "Autoconf exception 2.0", "licenseExceptionId": "Autoconf-exception-2.0", "seeAlso": [ "http://ac-archive.sourceforge.net/doc/copyright.html", "http://ftp.gnu.org/gnu/autoconf/autoconf-2.59.tar.gz" ] }, { "reference": "./Autoconf-exception-3.0.json", "isDeprecatedLicenseId": false, "detailsUrl": "./Autoconf-exception-3.0.html", "referenceNumber": 42, "name": "Autoconf exception 3.0", "licenseExceptionId": "Autoconf-exception-3.0", "seeAlso": [ "http://www.gnu.org/licenses/autoconf-exception-3.0.html" ] }, { "reference": "./Autoconf-exception-generic.json", "isDeprecatedLicenseId": false, "detailsUrl": "./Autoconf-exception-generic.html", "referenceNumber": 70, "name": "Autoconf generic exception", "licenseExceptionId": "Autoconf-exception-generic", "seeAlso": [ "https://launchpad.net/ubuntu/precise/+source/xmltooling/+copyright", "https://tracker.debian.org/media/packages/s/sipwitch/copyright-1.9.15-3", "https://opensource.apple.com/source/launchd/launchd-258.1/launchd/compile.auto.html", "https://git.savannah.gnu.org/gitweb/?p\u003dgnulib.git;a\u003dblob;f\u003dgnulib-tool;h\u003d029a8cf377ad8d8f2d9e54061bf2f20496ad2eef;hb\u003d73c74ba0197e6566da6882c87b1adee63e24d75c#l407" ] }, { "reference": "./Autoconf-exception-generic-3.0.json", "isDeprecatedLicenseId": false, "detailsUrl": "./Autoconf-exception-generic-3.0.html", "referenceNumber": 44, "name": "Autoconf generic exception for GPL-3.0", "licenseExceptionId": "Autoconf-exception-generic-3.0", "seeAlso": [ "https://src.fedoraproject.org/rpms/redhat-rpm-config/blob/rawhide/f/config.guess" ] }, { "reference": "./Autoconf-exception-macro.json", "isDeprecatedLicenseId": false, "detailsUrl": "./Autoconf-exception-macro.html", "referenceNumber": 15, "name": "Autoconf macro exception", "licenseExceptionId": "Autoconf-exception-macro", "seeAlso": [ "https://github.com/freedesktop/xorg-macros/blob/39f07f7db58ebbf3dcb64a2bf9098ed5cf3d1223/xorg-macros.m4.in", "https://www.gnu.org/software/autoconf-archive/ax_pthread.html", "https://launchpad.net/ubuntu/precise/+source/xmltooling/+copyright" ] }, { "reference": "./Bison-exception-1.24.json", "isDeprecatedLicenseId": false, "detailsUrl": "./Bison-exception-1.24.html", "referenceNumber": 4, "name": "Bison exception 1.24", "licenseExceptionId": "Bison-exception-1.24", "seeAlso": [ "https://github.com/arineng/rwhoisd/blob/master/rwhoisd/mkdb/y.tab.c#L180" ] }, { "reference": "./Bison-exception-2.2.json", "isDeprecatedLicenseId": false, "detailsUrl": "./Bison-exception-2.2.html", "referenceNumber": 30, "name": "Bison exception 2.2", "licenseExceptionId": "Bison-exception-2.2", "seeAlso": [ "http://git.savannah.gnu.org/cgit/bison.git/tree/data/yacc.c?id\u003d193d7c7054ba7197b0789e14965b739162319b5e#n141" ] }, { "reference": "./Bootloader-exception.json", "isDeprecatedLicenseId": false, "detailsUrl": "./Bootloader-exception.html", "referenceNumber": 21, "name": "Bootloader Distribution Exception", "licenseExceptionId": "Bootloader-exception", "seeAlso": [ "https://github.com/pyinstaller/pyinstaller/blob/develop/COPYING.txt" ] }, { "reference": "./Classpath-exception-2.0.json", "isDeprecatedLicenseId": false, "detailsUrl": "./Classpath-exception-2.0.html", "referenceNumber": 11, "name": "Classpath exception 2.0", "licenseExceptionId": "Classpath-exception-2.0", "seeAlso": [ "http://www.gnu.org/software/classpath/license.html", "https://fedoraproject.org/wiki/Licensing/GPL_Classpath_Exception" ] }, { "reference": "./CLISP-exception-2.0.json", "isDeprecatedLicenseId": false, "detailsUrl": "./CLISP-exception-2.0.html", "referenceNumber": 49, "name": "CLISP exception 2.0", "licenseExceptionId": "CLISP-exception-2.0", "seeAlso": [ "http://sourceforge.net/p/clisp/clisp/ci/default/tree/COPYRIGHT" ] }, { "reference": "./cryptsetup-OpenSSL-exception.json", "isDeprecatedLicenseId": false, "detailsUrl": "./cryptsetup-OpenSSL-exception.html", "referenceNumber": 26, "name": "cryptsetup OpenSSL exception", "licenseExceptionId": "cryptsetup-OpenSSL-exception", "seeAlso": [ "https://gitlab.com/cryptsetup/cryptsetup/-/blob/main/COPYING", "https://gitlab.nic.cz/datovka/datovka/-/blob/develop/COPYING", "https://github.com/nbs-system/naxsi/blob/951123ad456bdf5ac94e8d8819342fe3d49bc002/naxsi_src/naxsi_raw.c", "http://web.mit.edu/jgross/arch/amd64_deb60/bin/mosh", "https://sourceforge.net/p/linux-ima/ima-evm-utils/ci/master/tree/src/evmctl.c#l30" ] }, { "reference": "./DigiRule-FOSS-exception.json", "isDeprecatedLicenseId": false, "detailsUrl": "./DigiRule-FOSS-exception.html", "referenceNumber": 16, "name": "DigiRule FOSS License Exception", "licenseExceptionId": "DigiRule-FOSS-exception", "seeAlso": [ "http://www.digirulesolutions.com/drupal/foss" ] }, { "reference": "./eCos-exception-2.0.json", "isDeprecatedLicenseId": false, "detailsUrl": "./eCos-exception-2.0.html", "referenceNumber": 45, "name": "eCos exception 2.0", "licenseExceptionId": "eCos-exception-2.0", "seeAlso": [ "http://ecos.sourceware.org/license-overview.html" ] }, { "reference": "./Fawkes-Runtime-exception.json", "isDeprecatedLicenseId": false, "detailsUrl": "./Fawkes-Runtime-exception.html", "referenceNumber": 31, "name": "Fawkes Runtime Exception", "licenseExceptionId": "Fawkes-Runtime-exception", "seeAlso": [ "http://www.fawkesrobotics.org/about/license/" ] }, { "reference": "./FLTK-exception.json", "isDeprecatedLicenseId": false, "detailsUrl": "./FLTK-exception.html", "referenceNumber": 59, "name": "FLTK exception", "licenseExceptionId": "FLTK-exception", "seeAlso": [ "http://www.fltk.org/COPYING.php" ] }, { "reference": "./fmt-exception.json", "isDeprecatedLicenseId": false, "detailsUrl": "./fmt-exception.html", "referenceNumber": 48, "name": "fmt exception", "licenseExceptionId": "fmt-exception", "seeAlso": [ "https://github.com/fmtlib/fmt/blob/master/LICENSE", "https://github.com/fmtlib/fmt/blob/2eb363297b24cd71a68ccfb20ff755430f17e60f/LICENSE#L22C1-L27C62" ] }, { "reference": "./Font-exception-2.0.json", "isDeprecatedLicenseId": false, "detailsUrl": "./Font-exception-2.0.html", "referenceNumber": 62, "name": "Font exception 2.0", "licenseExceptionId": "Font-exception-2.0", "seeAlso": [ "http://www.gnu.org/licenses/gpl-faq.html#FontException" ] }, { "reference": "./freertos-exception-2.0.json", "isDeprecatedLicenseId": false, "detailsUrl": "./freertos-exception-2.0.html", "referenceNumber": 14, "name": "FreeRTOS Exception 2.0", "licenseExceptionId": "freertos-exception-2.0", "seeAlso": [ "https://web.archive.org/web/20060809182744/http://www.freertos.org/a00114.html" ] }, { "reference": "./GCC-exception-2.0.json", "isDeprecatedLicenseId": false, "detailsUrl": "./GCC-exception-2.0.html", "referenceNumber": 29, "name": "GCC Runtime Library exception 2.0", "licenseExceptionId": "GCC-exception-2.0", "seeAlso": [ "https://gcc.gnu.org/git/?p\u003dgcc.git;a\u003dblob;f\u003dgcc/libgcc1.c;h\u003d762f5143fc6eed57b6797c82710f3538aa52b40b;hb\u003dcb143a3ce4fb417c68f5fa2691a1b1b1053dfba9#l10", "https://sourceware.org/git/?p\u003dglibc.git;a\u003dblob;f\u003dcsu/abi-note.c;h\u003dc2ec208e94fbe91f63d3c375bd254b884695d190;hb\u003dHEAD" ] }, { "reference": "./GCC-exception-2.0-note.json", "isDeprecatedLicenseId": false, "detailsUrl": "./GCC-exception-2.0-note.html", "referenceNumber": 1, "name": "GCC Runtime Library exception 2.0 - note variant", "licenseExceptionId": "GCC-exception-2.0-note", "seeAlso": [ "https://sourceware.org/git/?p\u003dglibc.git;a\u003dblob;f\u003dsysdeps/x86_64/start.S" ] }, { "reference": "./GCC-exception-3.1.json", "isDeprecatedLicenseId": false, "detailsUrl": "./GCC-exception-3.1.html", "referenceNumber": 64, "name": "GCC Runtime Library exception 3.1", "licenseExceptionId": "GCC-exception-3.1", "seeAlso": [ "http://www.gnu.org/licenses/gcc-exception-3.1.html" ] }, { "reference": "./Gmsh-exception.json", "isDeprecatedLicenseId": false, "detailsUrl": "./Gmsh-exception.html", "referenceNumber": 25, "name": "Gmsh exception\u003e", "licenseExceptionId": "Gmsh-exception", "seeAlso": [ "https://gitlab.onelab.info/gmsh/gmsh/-/raw/master/LICENSE.txt" ] }, { "reference": "./GNAT-exception.json", "isDeprecatedLicenseId": false, "detailsUrl": "./GNAT-exception.html", "referenceNumber": 18, "name": "GNAT exception", "licenseExceptionId": "GNAT-exception", "seeAlso": [ "https://github.com/AdaCore/florist/blob/master/libsrc/posix-configurable_file_limits.adb" ] }, { "reference": "./GNOME-examples-exception.json", "isDeprecatedLicenseId": false, "detailsUrl": "./GNOME-examples-exception.html", "referenceNumber": 40, "name": "GNOME examples exception", "licenseExceptionId": "GNOME-examples-exception", "seeAlso": [ "https://gitlab.gnome.org/Archive/gnome-devel-docs/-/blob/master/platform-demos/C/legal.xml?ref_type\u003dheads", "http://meldmerge.org/help/" ] }, { "reference": "./GNU-compiler-exception.json", "isDeprecatedLicenseId": false, "detailsUrl": "./GNU-compiler-exception.html", "referenceNumber": 9, "name": "GNU Compiler Exception", "licenseExceptionId": "GNU-compiler-exception", "seeAlso": [ "https://sourceware.org/git?p\u003dbinutils-gdb.git;a\u003dblob;f\u003dlibiberty/unlink-if-ordinary.c;h\u003de49f2f2f67bfdb10d6b2bd579b0e01cad0fd708e;hb\u003dHEAD#l19" ] }, { "reference": "./gnu-javamail-exception.json", "isDeprecatedLicenseId": false, "detailsUrl": "./gnu-javamail-exception.html", "referenceNumber": 20, "name": "GNU JavaMail exception", "licenseExceptionId": "gnu-javamail-exception", "seeAlso": [ "http://www.gnu.org/software/classpathx/javamail/javamail.html" ] }, { "reference": "./GPL-3.0-interface-exception.json", "isDeprecatedLicenseId": false, "detailsUrl": "./GPL-3.0-interface-exception.html", "referenceNumber": 3, "name": "GPL-3.0 Interface Exception", "licenseExceptionId": "GPL-3.0-interface-exception", "seeAlso": [ "https://www.gnu.org/licenses/gpl-faq.en.html#LinkingOverControlledInterface" ] }, { "reference": "./GPL-3.0-linking-exception.json", "isDeprecatedLicenseId": false, "detailsUrl": "./GPL-3.0-linking-exception.html", "referenceNumber": 41, "name": "GPL-3.0 Linking Exception", "licenseExceptionId": "GPL-3.0-linking-exception", "seeAlso": [ "https://www.gnu.org/licenses/gpl-faq.en.html#GPLIncompatibleLibs" ] }, { "reference": "./GPL-3.0-linking-source-exception.json", "isDeprecatedLicenseId": false, "detailsUrl": "./GPL-3.0-linking-source-exception.html", "referenceNumber": 68, "name": "GPL-3.0 Linking Exception (with Corresponding Source)", "licenseExceptionId": "GPL-3.0-linking-source-exception", "seeAlso": [ "https://www.gnu.org/licenses/gpl-faq.en.html#GPLIncompatibleLibs", "https://github.com/mirror/wget/blob/master/src/http.c#L20" ] }, { "reference": "./GPL-CC-1.0.json", "isDeprecatedLicenseId": false, "detailsUrl": "./GPL-CC-1.0.html", "referenceNumber": 50, "name": "GPL Cooperation Commitment 1.0", "licenseExceptionId": "GPL-CC-1.0", "seeAlso": [ "https://github.com/gplcc/gplcc/blob/master/Project/COMMITMENT", "https://gplcc.github.io/gplcc/Project/README-PROJECT.html" ] }, { "reference": "./GStreamer-exception-2005.json", "isDeprecatedLicenseId": false, "detailsUrl": "./GStreamer-exception-2005.html", "referenceNumber": 61, "name": "GStreamer Exception (2005)", "licenseExceptionId": "GStreamer-exception-2005", "seeAlso": [ "https://gstreamer.freedesktop.org/documentation/frequently-asked-questions/licensing.html?gi-language\u003dc#licensing-of-applications-using-gstreamer" ] }, { "reference": "./GStreamer-exception-2008.json", "isDeprecatedLicenseId": false, "detailsUrl": "./GStreamer-exception-2008.html", "referenceNumber": 10, "name": "GStreamer Exception (2008)", "licenseExceptionId": "GStreamer-exception-2008", "seeAlso": [ "https://gstreamer.freedesktop.org/documentation/frequently-asked-questions/licensing.html?gi-language\u003dc#licensing-of-applications-using-gstreamer" ] }, { "reference": "./i2p-gpl-java-exception.json", "isDeprecatedLicenseId": false, "detailsUrl": "./i2p-gpl-java-exception.html", "referenceNumber": 13, "name": "i2p GPL+Java Exception", "licenseExceptionId": "i2p-gpl-java-exception", "seeAlso": [ "http://geti2p.net/en/get-involved/develop/licenses#java_exception" ] }, { "reference": "./KiCad-libraries-exception.json", "isDeprecatedLicenseId": false, "detailsUrl": "./KiCad-libraries-exception.html", "referenceNumber": 8, "name": "KiCad Libraries Exception", "licenseExceptionId": "KiCad-libraries-exception", "seeAlso": [ "https://www.kicad.org/libraries/license/" ] }, { "reference": "./LGPL-3.0-linking-exception.json", "isDeprecatedLicenseId": false, "detailsUrl": "./LGPL-3.0-linking-exception.html", "referenceNumber": 7, "name": "LGPL-3.0 Linking Exception", "licenseExceptionId": "LGPL-3.0-linking-exception", "seeAlso": [ "https://raw.githubusercontent.com/go-xmlpath/xmlpath/v2/LICENSE", "https://github.com/goamz/goamz/blob/master/LICENSE", "https://github.com/juju/errors/blob/master/LICENSE" ] }, { "reference": "./libpri-OpenH323-exception.json", "isDeprecatedLicenseId": false, "detailsUrl": "./libpri-OpenH323-exception.html", "referenceNumber": 5, "name": "libpri OpenH323 exception", "licenseExceptionId": "libpri-OpenH323-exception", "seeAlso": [ "https://github.com/asterisk/libpri/blob/1.6.0/README#L19-L22" ] }, { "reference": "./Libtool-exception.json", "isDeprecatedLicenseId": false, "detailsUrl": "./Libtool-exception.html", "referenceNumber": 63, "name": "Libtool Exception", "licenseExceptionId": "Libtool-exception", "seeAlso": [ "http://git.savannah.gnu.org/cgit/libtool.git/tree/m4/libtool.m4", "https://git.savannah.gnu.org/cgit/libtool.git/tree/libltdl/lt__alloc.c#n15" ] }, { "reference": "./Linux-syscall-note.json", "isDeprecatedLicenseId": false, "detailsUrl": "./Linux-syscall-note.html", "referenceNumber": 54, "name": "Linux Syscall Note", "licenseExceptionId": "Linux-syscall-note", "seeAlso": [ "https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/COPYING" ] }, { "reference": "./LLGPL.json", "isDeprecatedLicenseId": false, "detailsUrl": "./LLGPL.html", "referenceNumber": 19, "name": "LLGPL Preamble", "licenseExceptionId": "LLGPL", "seeAlso": [ "http://opensource.franz.com/preamble.html" ] }, { "reference": "./LLVM-exception.json", "isDeprecatedLicenseId": false, "detailsUrl": "./LLVM-exception.html", "referenceNumber": 57, "name": "LLVM Exception", "licenseExceptionId": "LLVM-exception", "seeAlso": [ "http://llvm.org/foundation/relicensing/LICENSE.txt" ] }, { "reference": "./LZMA-exception.json", "isDeprecatedLicenseId": false, "detailsUrl": "./LZMA-exception.html", "referenceNumber": 2, "name": "LZMA exception", "licenseExceptionId": "LZMA-exception", "seeAlso": [ "http://nsis.sourceforge.net/Docs/AppendixI.html#I.6" ] }, { "reference": "./mif-exception.json", "isDeprecatedLicenseId": false, "detailsUrl": "./mif-exception.html", "referenceNumber": 6, "name": "Macros and Inline Functions Exception", "licenseExceptionId": "mif-exception", "seeAlso": [ "http://www.scs.stanford.edu/histar/src/lib/cppsup/exception", "http://dev.bertos.org/doxygen/", "https://www.threadingbuildingblocks.org/licensing" ] }, { "reference": "./Nokia-Qt-exception-1.1.json", "isDeprecatedLicenseId": true, "detailsUrl": "./Nokia-Qt-exception-1.1.html", "referenceNumber": 51, "name": "Nokia Qt LGPL exception 1.1", "licenseExceptionId": "Nokia-Qt-exception-1.1", "seeAlso": [ "https://www.keepassx.org/dev/projects/keepassx/repository/revisions/b8dfb9cc4d5133e0f09cd7533d15a4f1c19a40f2/entry/LICENSE.NOKIA-LGPL-EXCEPTION" ] }, { "reference": "./OCaml-LGPL-linking-exception.json", "isDeprecatedLicenseId": false, "detailsUrl": "./OCaml-LGPL-linking-exception.html", "referenceNumber": 43, "name": "OCaml LGPL Linking Exception", "licenseExceptionId": "OCaml-LGPL-linking-exception", "seeAlso": [ "https://caml.inria.fr/ocaml/license.en.html" ] }, { "reference": "./OCCT-exception-1.0.json", "isDeprecatedLicenseId": false, "detailsUrl": "./OCCT-exception-1.0.html", "referenceNumber": 56, "name": "Open CASCADE Exception 1.0", "licenseExceptionId": "OCCT-exception-1.0", "seeAlso": [ "http://www.opencascade.com/content/licensing" ] }, { "reference": "./OpenJDK-assembly-exception-1.0.json", "isDeprecatedLicenseId": false, "detailsUrl": "./OpenJDK-assembly-exception-1.0.html", "referenceNumber": 35, "name": "OpenJDK Assembly exception 1.0", "licenseExceptionId": "OpenJDK-assembly-exception-1.0", "seeAlso": [ "http://openjdk.java.net/legal/assembly-exception.html" ] }, { "reference": "./openvpn-openssl-exception.json", "isDeprecatedLicenseId": false, "detailsUrl": "./openvpn-openssl-exception.html", "referenceNumber": 55, "name": "OpenVPN OpenSSL Exception", "licenseExceptionId": "openvpn-openssl-exception", "seeAlso": [ "http://openvpn.net/index.php/license.html", "https://github.com/psycopg/psycopg2/blob/2_9_3/LICENSE#L14" ] }, { "reference": "./PCRE2-exception.json", "isDeprecatedLicenseId": false, "detailsUrl": "./PCRE2-exception.html", "referenceNumber": 27, "name": "PCRE2 exception", "licenseExceptionId": "PCRE2-exception", "seeAlso": [ "https://www.pcre.org/licence.txt" ] }, { "reference": "./PS-or-PDF-font-exception-20170817.json", "isDeprecatedLicenseId": false, "detailsUrl": "./PS-or-PDF-font-exception-20170817.html", "referenceNumber": 67, "name": "PS/PDF font exception (2017-08-17)", "licenseExceptionId": "PS-or-PDF-font-exception-20170817", "seeAlso": [ "https://github.com/ArtifexSoftware/urw-base35-fonts/blob/65962e27febc3883a17e651cdb23e783668c996f/LICENSE" ] }, { "reference": "./QPL-1.0-INRIA-2004-exception.json", "isDeprecatedLicenseId": false, "detailsUrl": "./QPL-1.0-INRIA-2004-exception.html", "referenceNumber": 47, "name": "INRIA QPL 1.0 2004 variant exception", "licenseExceptionId": "QPL-1.0-INRIA-2004-exception", "seeAlso": [ "https://git.frama-c.com/pub/frama-c/-/blob/master/licenses/Q_MODIFIED_LICENSE", "https://github.com/maranget/hevea/blob/master/LICENSE" ] }, { "reference": "./Qt-GPL-exception-1.0.json", "isDeprecatedLicenseId": false, "detailsUrl": "./Qt-GPL-exception-1.0.html", "referenceNumber": 46, "name": "Qt GPL exception 1.0", "licenseExceptionId": "Qt-GPL-exception-1.0", "seeAlso": [ "http://code.qt.io/cgit/qt/qtbase.git/tree/LICENSE.GPL3-EXCEPT" ] }, { "reference": "./Qt-LGPL-exception-1.1.json", "isDeprecatedLicenseId": false, "detailsUrl": "./Qt-LGPL-exception-1.1.html", "referenceNumber": 65, "name": "Qt LGPL exception 1.1", "licenseExceptionId": "Qt-LGPL-exception-1.1", "seeAlso": [ "http://code.qt.io/cgit/qt/qtbase.git/tree/LGPL_EXCEPTION.txt" ] }, { "reference": "./Qwt-exception-1.0.json", "isDeprecatedLicenseId": false, "detailsUrl": "./Qwt-exception-1.0.html", "referenceNumber": 58, "name": "Qwt exception 1.0", "licenseExceptionId": "Qwt-exception-1.0", "seeAlso": [ "http://qwt.sourceforge.net/qwtlicense.html" ] }, { "reference": "./RRDtool-FLOSS-exception-2.0.json", "isDeprecatedLicenseId": false, "detailsUrl": "./RRDtool-FLOSS-exception-2.0.html", "referenceNumber": 22, "name": "RRDtool FLOSS exception 2.0", "licenseExceptionId": "RRDtool-FLOSS-exception-2.0", "seeAlso": [ "https://github.com/oetiker/rrdtool-1.x/blob/master/COPYRIGHT#L25-L90", "https://oss.oetiker.ch/rrdtool/license.en.html" ] }, { "reference": "./SANE-exception.json", "isDeprecatedLicenseId": false, "detailsUrl": "./SANE-exception.html", "referenceNumber": 12, "name": "SANE Exception", "licenseExceptionId": "SANE-exception", "seeAlso": [ "https://github.com/alexpevzner/sane-airscan/blob/master/LICENSE", "https://gitlab.com/sane-project/backends/-/blob/master/sanei/sanei_pp.c?ref_type\u003dheads", "https://gitlab.com/sane-project/frontends/-/blob/master/sanei/sanei_codec_ascii.c?ref_type\u003dheads" ] }, { "reference": "./SHL-2.0.json", "isDeprecatedLicenseId": false, "detailsUrl": "./SHL-2.0.html", "referenceNumber": 17, "name": "Solderpad Hardware License v2.0", "licenseExceptionId": "SHL-2.0", "seeAlso": [ "https://solderpad.org/licenses/SHL-2.0/" ] }, { "reference": "./SHL-2.1.json", "isDeprecatedLicenseId": false, "detailsUrl": "./SHL-2.1.html", "referenceNumber": 32, "name": "Solderpad Hardware License v2.1", "licenseExceptionId": "SHL-2.1", "seeAlso": [ "https://solderpad.org/licenses/SHL-2.1/" ] }, { "reference": "./stunnel-exception.json", "isDeprecatedLicenseId": false, "detailsUrl": "./stunnel-exception.html", "referenceNumber": 66, "name": "stunnel Exception", "licenseExceptionId": "stunnel-exception", "seeAlso": [ "https://github.com/mtrojnar/stunnel/blob/master/COPYING.md" ] }, { "reference": "./SWI-exception.json", "isDeprecatedLicenseId": false, "detailsUrl": "./SWI-exception.html", "referenceNumber": 36, "name": "SWI exception", "licenseExceptionId": "SWI-exception", "seeAlso": [ "https://github.com/SWI-Prolog/packages-clpqr/blob/bfa80b9270274f0800120d5b8e6fef42ac2dc6a5/clpqr/class.pl" ] }, { "reference": "./Swift-exception.json", "isDeprecatedLicenseId": false, "detailsUrl": "./Swift-exception.html", "referenceNumber": 37, "name": "Swift Exception", "licenseExceptionId": "Swift-exception", "seeAlso": [ "https://swift.org/LICENSE.txt", "https://github.com/apple/swift-package-manager/blob/7ab2275f447a5eb37497ed63a9340f8a6d1e488b/LICENSE.txt#L205" ] }, { "reference": "./Texinfo-exception.json", "isDeprecatedLicenseId": false, "detailsUrl": "./Texinfo-exception.html", "referenceNumber": 23, "name": "Texinfo exception", "licenseExceptionId": "Texinfo-exception", "seeAlso": [ "https://git.savannah.gnu.org/cgit/automake.git/tree/lib/texinfo.tex?h\u003dv1.16.5#n23" ] }, { "reference": "./u-boot-exception-2.0.json", "isDeprecatedLicenseId": false, "detailsUrl": "./u-boot-exception-2.0.html", "referenceNumber": 69, "name": "U-Boot exception 2.0", "licenseExceptionId": "u-boot-exception-2.0", "seeAlso": [ "http://git.denx.de/?p\u003du-boot.git;a\u003dblob;f\u003dLicenses/Exceptions" ] }, { "reference": "./UBDL-exception.json", "isDeprecatedLicenseId": false, "detailsUrl": "./UBDL-exception.html", "referenceNumber": 53, "name": "Unmodified Binary Distribution exception", "licenseExceptionId": "UBDL-exception", "seeAlso": [ "https://github.com/ipxe/ipxe/blob/master/COPYING.UBDL" ] }, { "reference": "./Universal-FOSS-exception-1.0.json", "isDeprecatedLicenseId": false, "detailsUrl": "./Universal-FOSS-exception-1.0.html", "referenceNumber": 38, "name": "Universal FOSS Exception, Version 1.0", "licenseExceptionId": "Universal-FOSS-exception-1.0", "seeAlso": [ "https://oss.oracle.com/licenses/universal-foss-exception/" ] }, { "reference": "./vsftpd-openssl-exception.json", "isDeprecatedLicenseId": false, "detailsUrl": "./vsftpd-openssl-exception.html", "referenceNumber": 33, "name": "vsftpd OpenSSL exception", "licenseExceptionId": "vsftpd-openssl-exception", "seeAlso": [ "https://git.stg.centos.org/source-git/vsftpd/blob/f727873674d9c9cd7afcae6677aa782eb54c8362/f/LICENSE", "https://launchpad.net/debian/squeeze/+source/vsftpd/+copyright", "https://github.com/richardcochran/vsftpd/blob/master/COPYING" ] }, { "reference": "./WxWindows-exception-3.1.json", "isDeprecatedLicenseId": false, "detailsUrl": "./WxWindows-exception-3.1.html", "referenceNumber": 28, "name": "WxWindows Library Exception 3.1", "licenseExceptionId": "WxWindows-exception-3.1", "seeAlso": [ "http://www.opensource.org/licenses/WXwindows" ] }, { "reference": "./x11vnc-openssl-exception.json", "isDeprecatedLicenseId": false, "detailsUrl": "./x11vnc-openssl-exception.html", "referenceNumber": 34, "name": "x11vnc OpenSSL Exception", "licenseExceptionId": "x11vnc-openssl-exception", "seeAlso": [ "https://github.com/LibVNC/x11vnc/blob/master/src/8to24.c#L22" ] } ], "releaseDate": "2024-05-22" }reuse-tool-4.0.3/src/reuse/resources/exceptions.json.license000066400000000000000000000001441464275211500242430ustar00rootroot00000000000000# SPDX-FileCopyrightText: Linux Foundation and its Contributors # # SPDX-License-Identifier: CC0-1.0reuse-tool-4.0.3/src/reuse/resources/licenses.json000066400000000000000000011123341464275211500222540ustar00rootroot00000000000000{ "licenseListVersion": "3.24.0", "licenses": [ { "reference": "https://spdx.org/licenses/0BSD.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/0BSD.json", "referenceNumber": 537, "name": "BSD Zero Clause License", "licenseId": "0BSD", "seeAlso": [ "http://landley.net/toybox/license.html", "https://opensource.org/licenses/0BSD" ], "isOsiApproved": true }, { "reference": "https://spdx.org/licenses/3D-Slicer-1.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/3D-Slicer-1.0.json", "referenceNumber": 200, "name": "3D Slicer License v1.0", "licenseId": "3D-Slicer-1.0", "seeAlso": [ "https://slicer.org/LICENSE", "https://github.com/Slicer/Slicer/blob/main/License.txt" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/AAL.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/AAL.json", "referenceNumber": 406, "name": "Attribution Assurance License", "licenseId": "AAL", "seeAlso": [ "https://opensource.org/licenses/attribution" ], "isOsiApproved": true }, { "reference": "https://spdx.org/licenses/Abstyles.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Abstyles.json", "referenceNumber": 526, "name": "Abstyles License", "licenseId": "Abstyles", "seeAlso": [ "https://fedoraproject.org/wiki/Licensing/Abstyles" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/AdaCore-doc.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/AdaCore-doc.json", "referenceNumber": 382, "name": "AdaCore Doc License", "licenseId": "AdaCore-doc", "seeAlso": [ "https://github.com/AdaCore/xmlada/blob/master/docs/index.rst", "https://github.com/AdaCore/gnatcoll-core/blob/master/docs/index.rst", "https://github.com/AdaCore/gnatcoll-db/blob/master/docs/index.rst" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/Adobe-2006.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Adobe-2006.json", "referenceNumber": 558, "name": "Adobe Systems Incorporated Source Code License Agreement", "licenseId": "Adobe-2006", "seeAlso": [ "https://fedoraproject.org/wiki/Licensing/AdobeLicense" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/Adobe-Display-PostScript.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Adobe-Display-PostScript.json", "referenceNumber": 431, "name": "Adobe Display PostScript License", "licenseId": "Adobe-Display-PostScript", "seeAlso": [ "https://gitlab.freedesktop.org/xorg/xserver/-/blob/master/COPYING?ref_type\u003dheads#L752" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/Adobe-Glyph.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Adobe-Glyph.json", "referenceNumber": 297, "name": "Adobe Glyph List License", "licenseId": "Adobe-Glyph", "seeAlso": [ "https://fedoraproject.org/wiki/Licensing/MIT#AdobeGlyph" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/Adobe-Utopia.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Adobe-Utopia.json", "referenceNumber": 532, "name": "Adobe Utopia Font License", "licenseId": "Adobe-Utopia", "seeAlso": [ "https://gitlab.freedesktop.org/xorg/font/adobe-utopia-100dpi/-/blob/master/COPYING?ref_type\u003dheads" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/ADSL.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/ADSL.json", "referenceNumber": 463, "name": "Amazon Digital Services License", "licenseId": "ADSL", "seeAlso": [ "https://fedoraproject.org/wiki/Licensing/AmazonDigitalServicesLicense" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/AFL-1.1.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/AFL-1.1.json", "referenceNumber": 601, "name": "Academic Free License v1.1", "licenseId": "AFL-1.1", "seeAlso": [ "http://opensource.linux-mirror.org/licenses/afl-1.1.txt", "http://wayback.archive.org/web/20021004124254/http://www.opensource.org/licenses/academic.php" ], "isOsiApproved": true, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/AFL-1.2.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/AFL-1.2.json", "referenceNumber": 72, "name": "Academic Free License v1.2", "licenseId": "AFL-1.2", "seeAlso": [ "http://opensource.linux-mirror.org/licenses/afl-1.2.txt", "http://wayback.archive.org/web/20021204204652/http://www.opensource.org/licenses/academic.php" ], "isOsiApproved": true, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/AFL-2.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/AFL-2.0.json", "referenceNumber": 187, "name": "Academic Free License v2.0", "licenseId": "AFL-2.0", "seeAlso": [ "http://wayback.archive.org/web/20060924134533/http://www.opensource.org/licenses/afl-2.0.txt" ], "isOsiApproved": true, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/AFL-2.1.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/AFL-2.1.json", "referenceNumber": 383, "name": "Academic Free License v2.1", "licenseId": "AFL-2.1", "seeAlso": [ "http://opensource.linux-mirror.org/licenses/afl-2.1.txt" ], "isOsiApproved": true, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/AFL-3.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/AFL-3.0.json", "referenceNumber": 369, "name": "Academic Free License v3.0", "licenseId": "AFL-3.0", "seeAlso": [ "http://www.rosenlaw.com/AFL3.0.htm", "https://opensource.org/licenses/afl-3.0" ], "isOsiApproved": true, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/Afmparse.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Afmparse.json", "referenceNumber": 345, "name": "Afmparse License", "licenseId": "Afmparse", "seeAlso": [ "https://fedoraproject.org/wiki/Licensing/Afmparse" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/AGPL-1.0.html", "isDeprecatedLicenseId": true, "detailsUrl": "https://spdx.org/licenses/AGPL-1.0.json", "referenceNumber": 221, "name": "Affero General Public License v1.0", "licenseId": "AGPL-1.0", "seeAlso": [ "http://www.affero.org/oagpl.html" ], "isOsiApproved": false, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/AGPL-1.0-only.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/AGPL-1.0-only.json", "referenceNumber": 334, "name": "Affero General Public License v1.0 only", "licenseId": "AGPL-1.0-only", "seeAlso": [ "http://www.affero.org/oagpl.html" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/AGPL-1.0-or-later.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/AGPL-1.0-or-later.json", "referenceNumber": 527, "name": "Affero General Public License v1.0 or later", "licenseId": "AGPL-1.0-or-later", "seeAlso": [ "http://www.affero.org/oagpl.html" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/AGPL-3.0.html", "isDeprecatedLicenseId": true, "detailsUrl": "https://spdx.org/licenses/AGPL-3.0.json", "referenceNumber": 394, "name": "GNU Affero General Public License v3.0", "licenseId": "AGPL-3.0", "seeAlso": [ "https://www.gnu.org/licenses/agpl.txt", "https://opensource.org/licenses/AGPL-3.0" ], "isOsiApproved": true, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/AGPL-3.0-only.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/AGPL-3.0-only.json", "referenceNumber": 123, "name": "GNU Affero General Public License v3.0 only", "licenseId": "AGPL-3.0-only", "seeAlso": [ "https://www.gnu.org/licenses/agpl.txt", "https://opensource.org/licenses/AGPL-3.0" ], "isOsiApproved": true, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/AGPL-3.0-or-later.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/AGPL-3.0-or-later.json", "referenceNumber": 105, "name": "GNU Affero General Public License v3.0 or later", "licenseId": "AGPL-3.0-or-later", "seeAlso": [ "https://www.gnu.org/licenses/agpl.txt", "https://opensource.org/licenses/AGPL-3.0" ], "isOsiApproved": true, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/Aladdin.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Aladdin.json", "referenceNumber": 168, "name": "Aladdin Free Public License", "licenseId": "Aladdin", "seeAlso": [ "http://pages.cs.wisc.edu/~ghost/doc/AFPL/6.01/Public.htm" ], "isOsiApproved": false, "isFsfLibre": false }, { "reference": "https://spdx.org/licenses/AMD-newlib.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/AMD-newlib.json", "referenceNumber": 222, "name": "AMD newlib License", "licenseId": "AMD-newlib", "seeAlso": [ "https://sourceware.org/git/?p\u003dnewlib-cygwin.git;a\u003dblob;f\u003dnewlib/libc/sys/a29khif/_close.S;h\u003d04f52ae00de1dafbd9055ad8d73c5c697a3aae7f;hb\u003dHEAD" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/AMDPLPA.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/AMDPLPA.json", "referenceNumber": 149, "name": "AMD\u0027s plpa_map.c License", "licenseId": "AMDPLPA", "seeAlso": [ "https://fedoraproject.org/wiki/Licensing/AMD_plpa_map_License" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/AML.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/AML.json", "referenceNumber": 13, "name": "Apple MIT License", "licenseId": "AML", "seeAlso": [ "https://fedoraproject.org/wiki/Licensing/Apple_MIT_License" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/AML-glslang.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/AML-glslang.json", "referenceNumber": 1, "name": "AML glslang variant License", "licenseId": "AML-glslang", "seeAlso": [ "https://github.com/KhronosGroup/glslang/blob/main/LICENSE.txt#L949", "https://docs.omniverse.nvidia.com/install-guide/latest/common/licenses.html" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/AMPAS.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/AMPAS.json", "referenceNumber": 420, "name": "Academy of Motion Picture Arts and Sciences BSD", "licenseId": "AMPAS", "seeAlso": [ "https://fedoraproject.org/wiki/Licensing/BSD#AMPASBSD" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/ANTLR-PD.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/ANTLR-PD.json", "referenceNumber": 576, "name": "ANTLR Software Rights Notice", "licenseId": "ANTLR-PD", "seeAlso": [ "http://www.antlr2.org/license.html" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/ANTLR-PD-fallback.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/ANTLR-PD-fallback.json", "referenceNumber": 194, "name": "ANTLR Software Rights Notice with license fallback", "licenseId": "ANTLR-PD-fallback", "seeAlso": [ "http://www.antlr2.org/license.html" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/any-OSI.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/any-OSI.json", "referenceNumber": 121, "name": "Any OSI License", "licenseId": "any-OSI", "seeAlso": [ "https://metacpan.org/pod/Exporter::Tidy#LICENSE" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/Apache-1.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Apache-1.0.json", "referenceNumber": 616, "name": "Apache License 1.0", "licenseId": "Apache-1.0", "seeAlso": [ "http://www.apache.org/licenses/LICENSE-1.0" ], "isOsiApproved": false, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/Apache-1.1.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Apache-1.1.json", "referenceNumber": 313, "name": "Apache License 1.1", "licenseId": "Apache-1.1", "seeAlso": [ "http://apache.org/licenses/LICENSE-1.1", "https://opensource.org/licenses/Apache-1.1" ], "isOsiApproved": true, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/Apache-2.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Apache-2.0.json", "referenceNumber": 564, "name": "Apache License 2.0", "licenseId": "Apache-2.0", "seeAlso": [ "https://www.apache.org/licenses/LICENSE-2.0", "https://opensource.org/licenses/Apache-2.0" ], "isOsiApproved": true, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/APAFML.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/APAFML.json", "referenceNumber": 136, "name": "Adobe Postscript AFM License", "licenseId": "APAFML", "seeAlso": [ "https://fedoraproject.org/wiki/Licensing/AdobePostscriptAFM" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/APL-1.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/APL-1.0.json", "referenceNumber": 515, "name": "Adaptive Public License 1.0", "licenseId": "APL-1.0", "seeAlso": [ "https://opensource.org/licenses/APL-1.0" ], "isOsiApproved": true }, { "reference": "https://spdx.org/licenses/App-s2p.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/App-s2p.json", "referenceNumber": 470, "name": "App::s2p License", "licenseId": "App-s2p", "seeAlso": [ "https://fedoraproject.org/wiki/Licensing/App-s2p" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/APSL-1.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/APSL-1.0.json", "referenceNumber": 39, "name": "Apple Public Source License 1.0", "licenseId": "APSL-1.0", "seeAlso": [ "https://fedoraproject.org/wiki/Licensing/Apple_Public_Source_License_1.0" ], "isOsiApproved": true, "isFsfLibre": false }, { "reference": "https://spdx.org/licenses/APSL-1.1.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/APSL-1.1.json", "referenceNumber": 582, "name": "Apple Public Source License 1.1", "licenseId": "APSL-1.1", "seeAlso": [ "http://www.opensource.apple.com/source/IOSerialFamily/IOSerialFamily-7/APPLE_LICENSE" ], "isOsiApproved": true }, { "reference": "https://spdx.org/licenses/APSL-1.2.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/APSL-1.2.json", "referenceNumber": 628, "name": "Apple Public Source License 1.2", "licenseId": "APSL-1.2", "seeAlso": [ "http://www.samurajdata.se/opensource/mirror/licenses/apsl.php" ], "isOsiApproved": true }, { "reference": "https://spdx.org/licenses/APSL-2.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/APSL-2.0.json", "referenceNumber": 144, "name": "Apple Public Source License 2.0", "licenseId": "APSL-2.0", "seeAlso": [ "http://www.opensource.apple.com/license/apsl/" ], "isOsiApproved": true, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/Arphic-1999.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Arphic-1999.json", "referenceNumber": 131, "name": "Arphic Public License", "licenseId": "Arphic-1999", "seeAlso": [ "http://ftp.gnu.org/gnu/non-gnu/chinese-fonts-truetype/LICENSE" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/Artistic-1.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Artistic-1.0.json", "referenceNumber": 388, "name": "Artistic License 1.0", "licenseId": "Artistic-1.0", "seeAlso": [ "https://opensource.org/licenses/Artistic-1.0" ], "isOsiApproved": true, "isFsfLibre": false }, { "reference": "https://spdx.org/licenses/Artistic-1.0-cl8.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Artistic-1.0-cl8.json", "referenceNumber": 321, "name": "Artistic License 1.0 w/clause 8", "licenseId": "Artistic-1.0-cl8", "seeAlso": [ "https://opensource.org/licenses/Artistic-1.0" ], "isOsiApproved": true }, { "reference": "https://spdx.org/licenses/Artistic-1.0-Perl.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Artistic-1.0-Perl.json", "referenceNumber": 652, "name": "Artistic License 1.0 (Perl)", "licenseId": "Artistic-1.0-Perl", "seeAlso": [ "http://dev.perl.org/licenses/artistic.html" ], "isOsiApproved": true }, { "reference": "https://spdx.org/licenses/Artistic-2.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Artistic-2.0.json", "referenceNumber": 355, "name": "Artistic License 2.0", "licenseId": "Artistic-2.0", "seeAlso": [ "http://www.perlfoundation.org/artistic_license_2_0", "https://www.perlfoundation.org/artistic-license-20.html", "https://opensource.org/licenses/artistic-license-2.0" ], "isOsiApproved": true, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/ASWF-Digital-Assets-1.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/ASWF-Digital-Assets-1.0.json", "referenceNumber": 330, "name": "ASWF Digital Assets License version 1.0", "licenseId": "ASWF-Digital-Assets-1.0", "seeAlso": [ "https://github.com/AcademySoftwareFoundation/foundation/blob/main/digital_assets/aswf_digital_assets_license_v1.0.txt" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/ASWF-Digital-Assets-1.1.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/ASWF-Digital-Assets-1.1.json", "referenceNumber": 447, "name": "ASWF Digital Assets License 1.1", "licenseId": "ASWF-Digital-Assets-1.1", "seeAlso": [ "https://github.com/AcademySoftwareFoundation/foundation/blob/main/digital_assets/aswf_digital_assets_license_v1.1.txt" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/Baekmuk.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Baekmuk.json", "referenceNumber": 436, "name": "Baekmuk License", "licenseId": "Baekmuk", "seeAlso": [ "https://fedoraproject.org/wiki/Licensing:Baekmuk?rd\u003dLicensing/Baekmuk" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/Bahyph.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Bahyph.json", "referenceNumber": 494, "name": "Bahyph License", "licenseId": "Bahyph", "seeAlso": [ "https://fedoraproject.org/wiki/Licensing/Bahyph" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/Barr.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Barr.json", "referenceNumber": 48, "name": "Barr License", "licenseId": "Barr", "seeAlso": [ "https://fedoraproject.org/wiki/Licensing/Barr" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/bcrypt-Solar-Designer.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/bcrypt-Solar-Designer.json", "referenceNumber": 27, "name": "bcrypt Solar Designer License", "licenseId": "bcrypt-Solar-Designer", "seeAlso": [ "https://github.com/bcrypt-ruby/bcrypt-ruby/blob/master/ext/mri/crypt_blowfish.c" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/Beerware.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Beerware.json", "referenceNumber": 143, "name": "Beerware License", "licenseId": "Beerware", "seeAlso": [ "https://fedoraproject.org/wiki/Licensing/Beerware", "https://people.freebsd.org/~phk/" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/Bitstream-Charter.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Bitstream-Charter.json", "referenceNumber": 560, "name": "Bitstream Charter Font License", "licenseId": "Bitstream-Charter", "seeAlso": [ "https://fedoraproject.org/wiki/Licensing/Charter#License_Text", "https://raw.githubusercontent.com/blackhole89/notekit/master/data/fonts/Charter%20license.txt" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/Bitstream-Vera.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Bitstream-Vera.json", "referenceNumber": 581, "name": "Bitstream Vera Font License", "licenseId": "Bitstream-Vera", "seeAlso": [ "https://web.archive.org/web/20080207013128/http://www.gnome.org/fonts/", "https://docubrain.com/sites/default/files/licenses/bitstream-vera.html" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/BitTorrent-1.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/BitTorrent-1.0.json", "referenceNumber": 373, "name": "BitTorrent Open Source License v1.0", "licenseId": "BitTorrent-1.0", "seeAlso": [ "http://sources.gentoo.org/cgi-bin/viewvc.cgi/gentoo-x86/licenses/BitTorrent?r1\u003d1.1\u0026r2\u003d1.1.1.1\u0026diff_format\u003ds" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/BitTorrent-1.1.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/BitTorrent-1.1.json", "referenceNumber": 288, "name": "BitTorrent Open Source License v1.1", "licenseId": "BitTorrent-1.1", "seeAlso": [ "http://directory.fsf.org/wiki/License:BitTorrentOSL1.1" ], "isOsiApproved": false, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/blessing.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/blessing.json", "referenceNumber": 469, "name": "SQLite Blessing", "licenseId": "blessing", "seeAlso": [ "https://www.sqlite.org/src/artifact/e33a4df7e32d742a?ln\u003d4-9", "https://sqlite.org/src/artifact/df5091916dbb40e6" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/BlueOak-1.0.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/BlueOak-1.0.0.json", "referenceNumber": 60, "name": "Blue Oak Model License 1.0.0", "licenseId": "BlueOak-1.0.0", "seeAlso": [ "https://blueoakcouncil.org/license/1.0.0" ], "isOsiApproved": true }, { "reference": "https://spdx.org/licenses/Boehm-GC.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Boehm-GC.json", "referenceNumber": 322, "name": "Boehm-Demers-Weiser GC License", "licenseId": "Boehm-GC", "seeAlso": [ "https://fedoraproject.org/wiki/Licensing:MIT#Another_Minimal_variant_(found_in_libatomic_ops)", "https://github.com/uim/libgcroots/blob/master/COPYING", "https://github.com/ivmai/libatomic_ops/blob/master/LICENSE" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/Borceux.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Borceux.json", "referenceNumber": 552, "name": "Borceux license", "licenseId": "Borceux", "seeAlso": [ "https://fedoraproject.org/wiki/Licensing/Borceux" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/Brian-Gladman-2-Clause.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Brian-Gladman-2-Clause.json", "referenceNumber": 457, "name": "Brian Gladman 2-Clause License", "licenseId": "Brian-Gladman-2-Clause", "seeAlso": [ "https://github.com/krb5/krb5/blob/krb5-1.21.2-final/NOTICE#L140-L156", "https://web.mit.edu/kerberos/krb5-1.21/doc/mitK5license.html" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/Brian-Gladman-3-Clause.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Brian-Gladman-3-Clause.json", "referenceNumber": 409, "name": "Brian Gladman 3-Clause License", "licenseId": "Brian-Gladman-3-Clause", "seeAlso": [ "https://github.com/SWI-Prolog/packages-clib/blob/master/sha1/brg_endian.h" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/BSD-1-Clause.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/BSD-1-Clause.json", "referenceNumber": 567, "name": "BSD 1-Clause License", "licenseId": "BSD-1-Clause", "seeAlso": [ "https://svnweb.freebsd.org/base/head/include/ifaddrs.h?revision\u003d326823" ], "isOsiApproved": true }, { "reference": "https://spdx.org/licenses/BSD-2-Clause.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/BSD-2-Clause.json", "referenceNumber": 264, "name": "BSD 2-Clause \"Simplified\" License", "licenseId": "BSD-2-Clause", "seeAlso": [ "https://opensource.org/licenses/BSD-2-Clause" ], "isOsiApproved": true, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/BSD-2-Clause-Darwin.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/BSD-2-Clause-Darwin.json", "referenceNumber": 231, "name": "BSD 2-Clause - Ian Darwin variant", "licenseId": "BSD-2-Clause-Darwin", "seeAlso": [ "https://github.com/file/file/blob/master/COPYING" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/BSD-2-Clause-first-lines.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/BSD-2-Clause-first-lines.json", "referenceNumber": 245, "name": "BSD 2-Clause - first lines requirement", "licenseId": "BSD-2-Clause-first-lines", "seeAlso": [ "https://github.com/krb5/krb5/blob/krb5-1.21.2-final/NOTICE#L664-L690", "https://web.mit.edu/kerberos/krb5-1.21/doc/mitK5license.html" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/BSD-2-Clause-FreeBSD.html", "isDeprecatedLicenseId": true, "detailsUrl": "https://spdx.org/licenses/BSD-2-Clause-FreeBSD.json", "referenceNumber": 192, "name": "BSD 2-Clause FreeBSD License", "licenseId": "BSD-2-Clause-FreeBSD", "seeAlso": [ "http://www.freebsd.org/copyright/freebsd-license.html" ], "isOsiApproved": false, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/BSD-2-Clause-NetBSD.html", "isDeprecatedLicenseId": true, "detailsUrl": "https://spdx.org/licenses/BSD-2-Clause-NetBSD.json", "referenceNumber": 449, "name": "BSD 2-Clause NetBSD License", "licenseId": "BSD-2-Clause-NetBSD", "seeAlso": [ "http://www.netbsd.org/about/redistribution.html#default" ], "isOsiApproved": false, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/BSD-2-Clause-Patent.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/BSD-2-Clause-Patent.json", "referenceNumber": 612, "name": "BSD-2-Clause Plus Patent License", "licenseId": "BSD-2-Clause-Patent", "seeAlso": [ "https://opensource.org/licenses/BSDplusPatent" ], "isOsiApproved": true }, { "reference": "https://spdx.org/licenses/BSD-2-Clause-Views.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/BSD-2-Clause-Views.json", "referenceNumber": 657, "name": "BSD 2-Clause with views sentence", "licenseId": "BSD-2-Clause-Views", "seeAlso": [ "http://www.freebsd.org/copyright/freebsd-license.html", "https://people.freebsd.org/~ivoras/wine/patch-wine-nvidia.sh", "https://github.com/protegeproject/protege/blob/master/license.txt" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/BSD-3-Clause.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/BSD-3-Clause.json", "referenceNumber": 216, "name": "BSD 3-Clause \"New\" or \"Revised\" License", "licenseId": "BSD-3-Clause", "seeAlso": [ "https://opensource.org/licenses/BSD-3-Clause", "https://www.eclipse.org/org/documents/edl-v10.php" ], "isOsiApproved": true, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/BSD-3-Clause-acpica.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/BSD-3-Clause-acpica.json", "referenceNumber": 408, "name": "BSD 3-Clause acpica variant", "licenseId": "BSD-3-Clause-acpica", "seeAlso": [ "https://github.com/acpica/acpica/blob/master/source/common/acfileio.c#L119" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/BSD-3-Clause-Attribution.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/BSD-3-Clause-Attribution.json", "referenceNumber": 14, "name": "BSD with attribution", "licenseId": "BSD-3-Clause-Attribution", "seeAlso": [ "https://fedoraproject.org/wiki/Licensing/BSD_with_Attribution" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/BSD-3-Clause-Clear.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/BSD-3-Clause-Clear.json", "referenceNumber": 347, "name": "BSD 3-Clause Clear License", "licenseId": "BSD-3-Clause-Clear", "seeAlso": [ "http://labs.metacarta.com/license-explanation.html#license" ], "isOsiApproved": false, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/BSD-3-Clause-flex.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/BSD-3-Clause-flex.json", "referenceNumber": 211, "name": "BSD 3-Clause Flex variant", "licenseId": "BSD-3-Clause-flex", "seeAlso": [ "https://github.com/westes/flex/blob/master/COPYING" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/BSD-3-Clause-HP.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/BSD-3-Clause-HP.json", "referenceNumber": 210, "name": "Hewlett-Packard BSD variant license", "licenseId": "BSD-3-Clause-HP", "seeAlso": [ "https://github.com/zdohnal/hplip/blob/master/COPYING#L939" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/BSD-3-Clause-LBNL.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/BSD-3-Clause-LBNL.json", "referenceNumber": 597, "name": "Lawrence Berkeley National Labs BSD variant license", "licenseId": "BSD-3-Clause-LBNL", "seeAlso": [ "https://fedoraproject.org/wiki/Licensing/LBNLBSD" ], "isOsiApproved": true }, { "reference": "https://spdx.org/licenses/BSD-3-Clause-Modification.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/BSD-3-Clause-Modification.json", "referenceNumber": 364, "name": "BSD 3-Clause Modification", "licenseId": "BSD-3-Clause-Modification", "seeAlso": [ "https://fedoraproject.org/wiki/Licensing:BSD#Modification_Variant" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/BSD-3-Clause-No-Military-License.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/BSD-3-Clause-No-Military-License.json", "referenceNumber": 30, "name": "BSD 3-Clause No Military License", "licenseId": "BSD-3-Clause-No-Military-License", "seeAlso": [ "https://gitlab.syncad.com/hive/dhive/-/blob/master/LICENSE", "https://github.com/greymass/swift-eosio/blob/master/LICENSE" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/BSD-3-Clause-No-Nuclear-License.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/BSD-3-Clause-No-Nuclear-License.json", "referenceNumber": 21, "name": "BSD 3-Clause No Nuclear License", "licenseId": "BSD-3-Clause-No-Nuclear-License", "seeAlso": [ "http://download.oracle.com/otn-pub/java/licenses/bsd.txt" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/BSD-3-Clause-No-Nuclear-License-2014.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/BSD-3-Clause-No-Nuclear-License-2014.json", "referenceNumber": 543, "name": "BSD 3-Clause No Nuclear License 2014", "licenseId": "BSD-3-Clause-No-Nuclear-License-2014", "seeAlso": [ "https://java.net/projects/javaeetutorial/pages/BerkeleyLicense" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/BSD-3-Clause-No-Nuclear-Warranty.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/BSD-3-Clause-No-Nuclear-Warranty.json", "referenceNumber": 402, "name": "BSD 3-Clause No Nuclear Warranty", "licenseId": "BSD-3-Clause-No-Nuclear-Warranty", "seeAlso": [ "https://jogamp.org/git/?p\u003dgluegen.git;a\u003dblob_plain;f\u003dLICENSE.txt" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/BSD-3-Clause-Open-MPI.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/BSD-3-Clause-Open-MPI.json", "referenceNumber": 376, "name": "BSD 3-Clause Open MPI variant", "licenseId": "BSD-3-Clause-Open-MPI", "seeAlso": [ "https://www.open-mpi.org/community/license.php", "http://www.netlib.org/lapack/LICENSE.txt" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/BSD-3-Clause-Sun.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/BSD-3-Clause-Sun.json", "referenceNumber": 554, "name": "BSD 3-Clause Sun Microsystems", "licenseId": "BSD-3-Clause-Sun", "seeAlso": [ "https://github.com/xmlark/msv/blob/b9316e2f2270bc1606952ea4939ec87fbba157f3/xsdlib/src/main/java/com/sun/msv/datatype/regexp/InternalImpl.java" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/BSD-4-Clause.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/BSD-4-Clause.json", "referenceNumber": 650, "name": "BSD 4-Clause \"Original\" or \"Old\" License", "licenseId": "BSD-4-Clause", "seeAlso": [ "http://directory.fsf.org/wiki/License:BSD_4Clause" ], "isOsiApproved": false, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/BSD-4-Clause-Shortened.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/BSD-4-Clause-Shortened.json", "referenceNumber": 252, "name": "BSD 4 Clause Shortened", "licenseId": "BSD-4-Clause-Shortened", "seeAlso": [ "https://metadata.ftp-master.debian.org/changelogs//main/a/arpwatch/arpwatch_2.1a15-7_copyright" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/BSD-4-Clause-UC.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/BSD-4-Clause-UC.json", "referenceNumber": 117, "name": "BSD-4-Clause (University of California-Specific)", "licenseId": "BSD-4-Clause-UC", "seeAlso": [ "http://www.freebsd.org/copyright/license.html" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/BSD-4.3RENO.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/BSD-4.3RENO.json", "referenceNumber": 298, "name": "BSD 4.3 RENO License", "licenseId": "BSD-4.3RENO", "seeAlso": [ "https://sourceware.org/git/?p\u003dbinutils-gdb.git;a\u003dblob;f\u003dlibiberty/strcasecmp.c;h\u003d131d81c2ce7881fa48c363dc5bf5fb302c61ce0b;hb\u003dHEAD", "https://git.openldap.org/openldap/openldap/-/blob/master/COPYRIGHT#L55-63" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/BSD-4.3TAHOE.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/BSD-4.3TAHOE.json", "referenceNumber": 0, "name": "BSD 4.3 TAHOE License", "licenseId": "BSD-4.3TAHOE", "seeAlso": [ "https://github.com/389ds/389-ds-base/blob/main/ldap/include/sysexits-compat.h#L15", "https://git.savannah.gnu.org/cgit/indent.git/tree/doc/indent.texi?id\u003da74c6b4ee49397cf330b333da1042bffa60ed14f#n1788" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/BSD-Advertising-Acknowledgement.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/BSD-Advertising-Acknowledgement.json", "referenceNumber": 423, "name": "BSD Advertising Acknowledgement License", "licenseId": "BSD-Advertising-Acknowledgement", "seeAlso": [ "https://github.com/python-excel/xlrd/blob/master/LICENSE#L33" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/BSD-Attribution-HPND-disclaimer.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/BSD-Attribution-HPND-disclaimer.json", "referenceNumber": 171, "name": "BSD with Attribution and HPND disclaimer", "licenseId": "BSD-Attribution-HPND-disclaimer", "seeAlso": [ "https://github.com/cyrusimap/cyrus-sasl/blob/master/COPYING" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/BSD-Inferno-Nettverk.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/BSD-Inferno-Nettverk.json", "referenceNumber": 401, "name": "BSD-Inferno-Nettverk", "licenseId": "BSD-Inferno-Nettverk", "seeAlso": [ "https://www.inet.no/dante/LICENSE" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/BSD-Protection.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/BSD-Protection.json", "referenceNumber": 403, "name": "BSD Protection License", "licenseId": "BSD-Protection", "seeAlso": [ "https://fedoraproject.org/wiki/Licensing/BSD_Protection_License" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/BSD-Source-beginning-file.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/BSD-Source-beginning-file.json", "referenceNumber": 97, "name": "BSD Source Code Attribution - beginning of file variant", "licenseId": "BSD-Source-beginning-file", "seeAlso": [ "https://github.com/lattera/freebsd/blob/master/sys/cam/cam.c#L4" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/BSD-Source-Code.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/BSD-Source-Code.json", "referenceNumber": 22, "name": "BSD Source Code Attribution", "licenseId": "BSD-Source-Code", "seeAlso": [ "https://github.com/robbiehanson/CocoaHTTPServer/blob/master/LICENSE.txt" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/BSD-Systemics.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/BSD-Systemics.json", "referenceNumber": 178, "name": "Systemics BSD variant license", "licenseId": "BSD-Systemics", "seeAlso": [ "https://metacpan.org/release/DPARIS/Crypt-DES-2.07/source/COPYRIGHT" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/BSD-Systemics-W3Works.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/BSD-Systemics-W3Works.json", "referenceNumber": 350, "name": "Systemics W3Works BSD variant license", "licenseId": "BSD-Systemics-W3Works", "seeAlso": [ "https://metacpan.org/release/DPARIS/Crypt-Blowfish-2.14/source/COPYRIGHT#L7" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/BSL-1.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/BSL-1.0.json", "referenceNumber": 514, "name": "Boost Software License 1.0", "licenseId": "BSL-1.0", "seeAlso": [ "http://www.boost.org/LICENSE_1_0.txt", "https://opensource.org/licenses/BSL-1.0" ], "isOsiApproved": true, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/BUSL-1.1.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/BUSL-1.1.json", "referenceNumber": 549, "name": "Business Source License 1.1", "licenseId": "BUSL-1.1", "seeAlso": [ "https://mariadb.com/bsl11/" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/bzip2-1.0.5.html", "isDeprecatedLicenseId": true, "detailsUrl": "https://spdx.org/licenses/bzip2-1.0.5.json", "referenceNumber": 419, "name": "bzip2 and libbzip2 License v1.0.5", "licenseId": "bzip2-1.0.5", "seeAlso": [ "https://sourceware.org/bzip2/1.0.5/bzip2-manual-1.0.5.html", "http://bzip.org/1.0.5/bzip2-manual-1.0.5.html" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/bzip2-1.0.6.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/bzip2-1.0.6.json", "referenceNumber": 396, "name": "bzip2 and libbzip2 License v1.0.6", "licenseId": "bzip2-1.0.6", "seeAlso": [ "https://sourceware.org/git/?p\u003dbzip2.git;a\u003dblob;f\u003dLICENSE;hb\u003dbzip2-1.0.6", "http://bzip.org/1.0.5/bzip2-manual-1.0.5.html", "https://sourceware.org/cgit/valgrind/tree/mpi/libmpiwrap.c" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/C-UDA-1.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/C-UDA-1.0.json", "referenceNumber": 432, "name": "Computational Use of Data Agreement v1.0", "licenseId": "C-UDA-1.0", "seeAlso": [ "https://github.com/microsoft/Computational-Use-of-Data-Agreement/blob/master/C-UDA-1.0.md", "https://cdla.dev/computational-use-of-data-agreement-v1-0/" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/CAL-1.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/CAL-1.0.json", "referenceNumber": 653, "name": "Cryptographic Autonomy License 1.0", "licenseId": "CAL-1.0", "seeAlso": [ "http://cryptographicautonomylicense.com/license-text.html", "https://opensource.org/licenses/CAL-1.0" ], "isOsiApproved": true }, { "reference": "https://spdx.org/licenses/CAL-1.0-Combined-Work-Exception.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/CAL-1.0-Combined-Work-Exception.json", "referenceNumber": 217, "name": "Cryptographic Autonomy License 1.0 (Combined Work Exception)", "licenseId": "CAL-1.0-Combined-Work-Exception", "seeAlso": [ "http://cryptographicautonomylicense.com/license-text.html", "https://opensource.org/licenses/CAL-1.0" ], "isOsiApproved": true }, { "reference": "https://spdx.org/licenses/Caldera.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Caldera.json", "referenceNumber": 622, "name": "Caldera License", "licenseId": "Caldera", "seeAlso": [ "http://www.lemis.com/grog/UNIX/ancient-source-all.pdf" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/Caldera-no-preamble.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Caldera-no-preamble.json", "referenceNumber": 585, "name": "Caldera License (without preamble)", "licenseId": "Caldera-no-preamble", "seeAlso": [ "https://github.com/apache/apr/blob/trunk/LICENSE#L298C6-L298C29" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/Catharon.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Catharon.json", "referenceNumber": 45, "name": "Catharon License", "licenseId": "Catharon", "seeAlso": [ "https://github.com/scummvm/scummvm/blob/v2.8.0/LICENSES/CatharonLicense.txt" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/CATOSL-1.1.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/CATOSL-1.1.json", "referenceNumber": 193, "name": "Computer Associates Trusted Open Source License 1.1", "licenseId": "CATOSL-1.1", "seeAlso": [ "https://opensource.org/licenses/CATOSL-1.1" ], "isOsiApproved": true }, { "reference": "https://spdx.org/licenses/CC-BY-1.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/CC-BY-1.0.json", "referenceNumber": 37, "name": "Creative Commons Attribution 1.0 Generic", "licenseId": "CC-BY-1.0", "seeAlso": [ "https://creativecommons.org/licenses/by/1.0/legalcode" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/CC-BY-2.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/CC-BY-2.0.json", "referenceNumber": 241, "name": "Creative Commons Attribution 2.0 Generic", "licenseId": "CC-BY-2.0", "seeAlso": [ "https://creativecommons.org/licenses/by/2.0/legalcode" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/CC-BY-2.5.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/CC-BY-2.5.json", "referenceNumber": 129, "name": "Creative Commons Attribution 2.5 Generic", "licenseId": "CC-BY-2.5", "seeAlso": [ "https://creativecommons.org/licenses/by/2.5/legalcode" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/CC-BY-2.5-AU.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/CC-BY-2.5-AU.json", "referenceNumber": 583, "name": "Creative Commons Attribution 2.5 Australia", "licenseId": "CC-BY-2.5-AU", "seeAlso": [ "https://creativecommons.org/licenses/by/2.5/au/legalcode" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/CC-BY-3.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/CC-BY-3.0.json", "referenceNumber": 302, "name": "Creative Commons Attribution 3.0 Unported", "licenseId": "CC-BY-3.0", "seeAlso": [ "https://creativecommons.org/licenses/by/3.0/legalcode" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/CC-BY-3.0-AT.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/CC-BY-3.0-AT.json", "referenceNumber": 324, "name": "Creative Commons Attribution 3.0 Austria", "licenseId": "CC-BY-3.0-AT", "seeAlso": [ "https://creativecommons.org/licenses/by/3.0/at/legalcode" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/CC-BY-3.0-AU.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/CC-BY-3.0-AU.json", "referenceNumber": 342, "name": "Creative Commons Attribution 3.0 Australia", "licenseId": "CC-BY-3.0-AU", "seeAlso": [ "https://creativecommons.org/licenses/by/3.0/au/legalcode" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/CC-BY-3.0-DE.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/CC-BY-3.0-DE.json", "referenceNumber": 239, "name": "Creative Commons Attribution 3.0 Germany", "licenseId": "CC-BY-3.0-DE", "seeAlso": [ "https://creativecommons.org/licenses/by/3.0/de/legalcode" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/CC-BY-3.0-IGO.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/CC-BY-3.0-IGO.json", "referenceNumber": 19, "name": "Creative Commons Attribution 3.0 IGO", "licenseId": "CC-BY-3.0-IGO", "seeAlso": [ "https://creativecommons.org/licenses/by/3.0/igo/legalcode" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/CC-BY-3.0-NL.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/CC-BY-3.0-NL.json", "referenceNumber": 501, "name": "Creative Commons Attribution 3.0 Netherlands", "licenseId": "CC-BY-3.0-NL", "seeAlso": [ "https://creativecommons.org/licenses/by/3.0/nl/legalcode" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/CC-BY-3.0-US.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/CC-BY-3.0-US.json", "referenceNumber": 569, "name": "Creative Commons Attribution 3.0 United States", "licenseId": "CC-BY-3.0-US", "seeAlso": [ "https://creativecommons.org/licenses/by/3.0/us/legalcode" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/CC-BY-4.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/CC-BY-4.0.json", "referenceNumber": 265, "name": "Creative Commons Attribution 4.0 International", "licenseId": "CC-BY-4.0", "seeAlso": [ "https://creativecommons.org/licenses/by/4.0/legalcode" ], "isOsiApproved": false, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/CC-BY-NC-1.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/CC-BY-NC-1.0.json", "referenceNumber": 167, "name": "Creative Commons Attribution Non Commercial 1.0 Generic", "licenseId": "CC-BY-NC-1.0", "seeAlso": [ "https://creativecommons.org/licenses/by-nc/1.0/legalcode" ], "isOsiApproved": false, "isFsfLibre": false }, { "reference": "https://spdx.org/licenses/CC-BY-NC-2.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/CC-BY-NC-2.0.json", "referenceNumber": 92, "name": "Creative Commons Attribution Non Commercial 2.0 Generic", "licenseId": "CC-BY-NC-2.0", "seeAlso": [ "https://creativecommons.org/licenses/by-nc/2.0/legalcode" ], "isOsiApproved": false, "isFsfLibre": false }, { "reference": "https://spdx.org/licenses/CC-BY-NC-2.5.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/CC-BY-NC-2.5.json", "referenceNumber": 253, "name": "Creative Commons Attribution Non Commercial 2.5 Generic", "licenseId": "CC-BY-NC-2.5", "seeAlso": [ "https://creativecommons.org/licenses/by-nc/2.5/legalcode" ], "isOsiApproved": false, "isFsfLibre": false }, { "reference": "https://spdx.org/licenses/CC-BY-NC-3.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/CC-BY-NC-3.0.json", "referenceNumber": 199, "name": "Creative Commons Attribution Non Commercial 3.0 Unported", "licenseId": "CC-BY-NC-3.0", "seeAlso": [ "https://creativecommons.org/licenses/by-nc/3.0/legalcode" ], "isOsiApproved": false, "isFsfLibre": false }, { "reference": "https://spdx.org/licenses/CC-BY-NC-3.0-DE.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/CC-BY-NC-3.0-DE.json", "referenceNumber": 429, "name": "Creative Commons Attribution Non Commercial 3.0 Germany", "licenseId": "CC-BY-NC-3.0-DE", "seeAlso": [ "https://creativecommons.org/licenses/by-nc/3.0/de/legalcode" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/CC-BY-NC-4.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/CC-BY-NC-4.0.json", "referenceNumber": 188, "name": "Creative Commons Attribution Non Commercial 4.0 International", "licenseId": "CC-BY-NC-4.0", "seeAlso": [ "https://creativecommons.org/licenses/by-nc/4.0/legalcode" ], "isOsiApproved": false, "isFsfLibre": false }, { "reference": "https://spdx.org/licenses/CC-BY-NC-ND-1.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/CC-BY-NC-ND-1.0.json", "referenceNumber": 365, "name": "Creative Commons Attribution Non Commercial No Derivatives 1.0 Generic", "licenseId": "CC-BY-NC-ND-1.0", "seeAlso": [ "https://creativecommons.org/licenses/by-nd-nc/1.0/legalcode" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/CC-BY-NC-ND-2.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/CC-BY-NC-ND-2.0.json", "referenceNumber": 416, "name": "Creative Commons Attribution Non Commercial No Derivatives 2.0 Generic", "licenseId": "CC-BY-NC-ND-2.0", "seeAlso": [ "https://creativecommons.org/licenses/by-nc-nd/2.0/legalcode" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/CC-BY-NC-ND-2.5.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/CC-BY-NC-ND-2.5.json", "referenceNumber": 58, "name": "Creative Commons Attribution Non Commercial No Derivatives 2.5 Generic", "licenseId": "CC-BY-NC-ND-2.5", "seeAlso": [ "https://creativecommons.org/licenses/by-nc-nd/2.5/legalcode" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/CC-BY-NC-ND-3.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/CC-BY-NC-ND-3.0.json", "referenceNumber": 213, "name": "Creative Commons Attribution Non Commercial No Derivatives 3.0 Unported", "licenseId": "CC-BY-NC-ND-3.0", "seeAlso": [ "https://creativecommons.org/licenses/by-nc-nd/3.0/legalcode" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/CC-BY-NC-ND-3.0-DE.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/CC-BY-NC-ND-3.0-DE.json", "referenceNumber": 84, "name": "Creative Commons Attribution Non Commercial No Derivatives 3.0 Germany", "licenseId": "CC-BY-NC-ND-3.0-DE", "seeAlso": [ "https://creativecommons.org/licenses/by-nc-nd/3.0/de/legalcode" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/CC-BY-NC-ND-3.0-IGO.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/CC-BY-NC-ND-3.0-IGO.json", "referenceNumber": 587, "name": "Creative Commons Attribution Non Commercial No Derivatives 3.0 IGO", "licenseId": "CC-BY-NC-ND-3.0-IGO", "seeAlso": [ "https://creativecommons.org/licenses/by-nc-nd/3.0/igo/legalcode" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/CC-BY-NC-ND-4.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/CC-BY-NC-ND-4.0.json", "referenceNumber": 296, "name": "Creative Commons Attribution Non Commercial No Derivatives 4.0 International", "licenseId": "CC-BY-NC-ND-4.0", "seeAlso": [ "https://creativecommons.org/licenses/by-nc-nd/4.0/legalcode" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/CC-BY-NC-SA-1.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/CC-BY-NC-SA-1.0.json", "referenceNumber": 170, "name": "Creative Commons Attribution Non Commercial Share Alike 1.0 Generic", "licenseId": "CC-BY-NC-SA-1.0", "seeAlso": [ "https://creativecommons.org/licenses/by-nc-sa/1.0/legalcode" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/CC-BY-NC-SA-2.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/CC-BY-NC-SA-2.0.json", "referenceNumber": 484, "name": "Creative Commons Attribution Non Commercial Share Alike 2.0 Generic", "licenseId": "CC-BY-NC-SA-2.0", "seeAlso": [ "https://creativecommons.org/licenses/by-nc-sa/2.0/legalcode" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/CC-BY-NC-SA-2.0-DE.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/CC-BY-NC-SA-2.0-DE.json", "referenceNumber": 184, "name": "Creative Commons Attribution Non Commercial Share Alike 2.0 Germany", "licenseId": "CC-BY-NC-SA-2.0-DE", "seeAlso": [ "https://creativecommons.org/licenses/by-nc-sa/2.0/de/legalcode" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/CC-BY-NC-SA-2.0-FR.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/CC-BY-NC-SA-2.0-FR.json", "referenceNumber": 116, "name": "Creative Commons Attribution-NonCommercial-ShareAlike 2.0 France", "licenseId": "CC-BY-NC-SA-2.0-FR", "seeAlso": [ "https://creativecommons.org/licenses/by-nc-sa/2.0/fr/legalcode" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/CC-BY-NC-SA-2.0-UK.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/CC-BY-NC-SA-2.0-UK.json", "referenceNumber": 415, "name": "Creative Commons Attribution Non Commercial Share Alike 2.0 England and Wales", "licenseId": "CC-BY-NC-SA-2.0-UK", "seeAlso": [ "https://creativecommons.org/licenses/by-nc-sa/2.0/uk/legalcode" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/CC-BY-NC-SA-2.5.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/CC-BY-NC-SA-2.5.json", "referenceNumber": 106, "name": "Creative Commons Attribution Non Commercial Share Alike 2.5 Generic", "licenseId": "CC-BY-NC-SA-2.5", "seeAlso": [ "https://creativecommons.org/licenses/by-nc-sa/2.5/legalcode" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/CC-BY-NC-SA-3.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/CC-BY-NC-SA-3.0.json", "referenceNumber": 323, "name": "Creative Commons Attribution Non Commercial Share Alike 3.0 Unported", "licenseId": "CC-BY-NC-SA-3.0", "seeAlso": [ "https://creativecommons.org/licenses/by-nc-sa/3.0/legalcode" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/CC-BY-NC-SA-3.0-DE.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/CC-BY-NC-SA-3.0-DE.json", "referenceNumber": 150, "name": "Creative Commons Attribution Non Commercial Share Alike 3.0 Germany", "licenseId": "CC-BY-NC-SA-3.0-DE", "seeAlso": [ "https://creativecommons.org/licenses/by-nc-sa/3.0/de/legalcode" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/CC-BY-NC-SA-3.0-IGO.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/CC-BY-NC-SA-3.0-IGO.json", "referenceNumber": 295, "name": "Creative Commons Attribution Non Commercial Share Alike 3.0 IGO", "licenseId": "CC-BY-NC-SA-3.0-IGO", "seeAlso": [ "https://creativecommons.org/licenses/by-nc-sa/3.0/igo/legalcode" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/CC-BY-NC-SA-4.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/CC-BY-NC-SA-4.0.json", "referenceNumber": 351, "name": "Creative Commons Attribution Non Commercial Share Alike 4.0 International", "licenseId": "CC-BY-NC-SA-4.0", "seeAlso": [ "https://creativecommons.org/licenses/by-nc-sa/4.0/legalcode" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/CC-BY-ND-1.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/CC-BY-ND-1.0.json", "referenceNumber": 56, "name": "Creative Commons Attribution No Derivatives 1.0 Generic", "licenseId": "CC-BY-ND-1.0", "seeAlso": [ "https://creativecommons.org/licenses/by-nd/1.0/legalcode" ], "isOsiApproved": false, "isFsfLibre": false }, { "reference": "https://spdx.org/licenses/CC-BY-ND-2.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/CC-BY-ND-2.0.json", "referenceNumber": 640, "name": "Creative Commons Attribution No Derivatives 2.0 Generic", "licenseId": "CC-BY-ND-2.0", "seeAlso": [ "https://creativecommons.org/licenses/by-nd/2.0/legalcode" ], "isOsiApproved": false, "isFsfLibre": false }, { "reference": "https://spdx.org/licenses/CC-BY-ND-2.5.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/CC-BY-ND-2.5.json", "referenceNumber": 276, "name": "Creative Commons Attribution No Derivatives 2.5 Generic", "licenseId": "CC-BY-ND-2.5", "seeAlso": [ "https://creativecommons.org/licenses/by-nd/2.5/legalcode" ], "isOsiApproved": false, "isFsfLibre": false }, { "reference": "https://spdx.org/licenses/CC-BY-ND-3.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/CC-BY-ND-3.0.json", "referenceNumber": 173, "name": "Creative Commons Attribution No Derivatives 3.0 Unported", "licenseId": "CC-BY-ND-3.0", "seeAlso": [ "https://creativecommons.org/licenses/by-nd/3.0/legalcode" ], "isOsiApproved": false, "isFsfLibre": false }, { "reference": "https://spdx.org/licenses/CC-BY-ND-3.0-DE.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/CC-BY-ND-3.0-DE.json", "referenceNumber": 525, "name": "Creative Commons Attribution No Derivatives 3.0 Germany", "licenseId": "CC-BY-ND-3.0-DE", "seeAlso": [ "https://creativecommons.org/licenses/by-nd/3.0/de/legalcode" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/CC-BY-ND-4.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/CC-BY-ND-4.0.json", "referenceNumber": 328, "name": "Creative Commons Attribution No Derivatives 4.0 International", "licenseId": "CC-BY-ND-4.0", "seeAlso": [ "https://creativecommons.org/licenses/by-nd/4.0/legalcode" ], "isOsiApproved": false, "isFsfLibre": false }, { "reference": "https://spdx.org/licenses/CC-BY-SA-1.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/CC-BY-SA-1.0.json", "referenceNumber": 453, "name": "Creative Commons Attribution Share Alike 1.0 Generic", "licenseId": "CC-BY-SA-1.0", "seeAlso": [ "https://creativecommons.org/licenses/by-sa/1.0/legalcode" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/CC-BY-SA-2.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/CC-BY-SA-2.0.json", "referenceNumber": 174, "name": "Creative Commons Attribution Share Alike 2.0 Generic", "licenseId": "CC-BY-SA-2.0", "seeAlso": [ "https://creativecommons.org/licenses/by-sa/2.0/legalcode" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/CC-BY-SA-2.0-UK.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/CC-BY-SA-2.0-UK.json", "referenceNumber": 387, "name": "Creative Commons Attribution Share Alike 2.0 England and Wales", "licenseId": "CC-BY-SA-2.0-UK", "seeAlso": [ "https://creativecommons.org/licenses/by-sa/2.0/uk/legalcode" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/CC-BY-SA-2.1-JP.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/CC-BY-SA-2.1-JP.json", "referenceNumber": 471, "name": "Creative Commons Attribution Share Alike 2.1 Japan", "licenseId": "CC-BY-SA-2.1-JP", "seeAlso": [ "https://creativecommons.org/licenses/by-sa/2.1/jp/legalcode" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/CC-BY-SA-2.5.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/CC-BY-SA-2.5.json", "referenceNumber": 461, "name": "Creative Commons Attribution Share Alike 2.5 Generic", "licenseId": "CC-BY-SA-2.5", "seeAlso": [ "https://creativecommons.org/licenses/by-sa/2.5/legalcode" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/CC-BY-SA-3.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/CC-BY-SA-3.0.json", "referenceNumber": 621, "name": "Creative Commons Attribution Share Alike 3.0 Unported", "licenseId": "CC-BY-SA-3.0", "seeAlso": [ "https://creativecommons.org/licenses/by-sa/3.0/legalcode" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/CC-BY-SA-3.0-AT.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/CC-BY-SA-3.0-AT.json", "referenceNumber": 31, "name": "Creative Commons Attribution Share Alike 3.0 Austria", "licenseId": "CC-BY-SA-3.0-AT", "seeAlso": [ "https://creativecommons.org/licenses/by-sa/3.0/at/legalcode" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/CC-BY-SA-3.0-DE.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/CC-BY-SA-3.0-DE.json", "referenceNumber": 325, "name": "Creative Commons Attribution Share Alike 3.0 Germany", "licenseId": "CC-BY-SA-3.0-DE", "seeAlso": [ "https://creativecommons.org/licenses/by-sa/3.0/de/legalcode" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/CC-BY-SA-3.0-IGO.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/CC-BY-SA-3.0-IGO.json", "referenceNumber": 20, "name": "Creative Commons Attribution-ShareAlike 3.0 IGO", "licenseId": "CC-BY-SA-3.0-IGO", "seeAlso": [ "https://creativecommons.org/licenses/by-sa/3.0/igo/legalcode" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/CC-BY-SA-4.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/CC-BY-SA-4.0.json", "referenceNumber": 155, "name": "Creative Commons Attribution Share Alike 4.0 International", "licenseId": "CC-BY-SA-4.0", "seeAlso": [ "https://creativecommons.org/licenses/by-sa/4.0/legalcode" ], "isOsiApproved": false, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/CC-PDDC.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/CC-PDDC.json", "referenceNumber": 349, "name": "Creative Commons Public Domain Dedication and Certification", "licenseId": "CC-PDDC", "seeAlso": [ "https://creativecommons.org/licenses/publicdomain/" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/CC0-1.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/CC0-1.0.json", "referenceNumber": 70, "name": "Creative Commons Zero v1.0 Universal", "licenseId": "CC0-1.0", "seeAlso": [ "https://creativecommons.org/publicdomain/zero/1.0/legalcode" ], "isOsiApproved": false, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/CDDL-1.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/CDDL-1.0.json", "referenceNumber": 282, "name": "Common Development and Distribution License 1.0", "licenseId": "CDDL-1.0", "seeAlso": [ "https://opensource.org/licenses/cddl1" ], "isOsiApproved": true, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/CDDL-1.1.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/CDDL-1.1.json", "referenceNumber": 130, "name": "Common Development and Distribution License 1.1", "licenseId": "CDDL-1.1", "seeAlso": [ "http://glassfish.java.net/public/CDDL+GPL_1_1.html", "https://javaee.github.io/glassfish/LICENSE" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/CDL-1.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/CDL-1.0.json", "referenceNumber": 592, "name": "Common Documentation License 1.0", "licenseId": "CDL-1.0", "seeAlso": [ "http://www.opensource.apple.com/cdl/", "https://fedoraproject.org/wiki/Licensing/Common_Documentation_License", "https://www.gnu.org/licenses/license-list.html#ACDL" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/CDLA-Permissive-1.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/CDLA-Permissive-1.0.json", "referenceNumber": 551, "name": "Community Data License Agreement Permissive 1.0", "licenseId": "CDLA-Permissive-1.0", "seeAlso": [ "https://cdla.io/permissive-1-0" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/CDLA-Permissive-2.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/CDLA-Permissive-2.0.json", "referenceNumber": 319, "name": "Community Data License Agreement Permissive 2.0", "licenseId": "CDLA-Permissive-2.0", "seeAlso": [ "https://cdla.dev/permissive-2-0" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/CDLA-Sharing-1.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/CDLA-Sharing-1.0.json", "referenceNumber": 445, "name": "Community Data License Agreement Sharing 1.0", "licenseId": "CDLA-Sharing-1.0", "seeAlso": [ "https://cdla.io/sharing-1-0" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/CECILL-1.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/CECILL-1.0.json", "referenceNumber": 219, "name": "CeCILL Free Software License Agreement v1.0", "licenseId": "CECILL-1.0", "seeAlso": [ "http://www.cecill.info/licences/Licence_CeCILL_V1-fr.html" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/CECILL-1.1.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/CECILL-1.1.json", "referenceNumber": 38, "name": "CeCILL Free Software License Agreement v1.1", "licenseId": "CECILL-1.1", "seeAlso": [ "http://www.cecill.info/licences/Licence_CeCILL_V1.1-US.html" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/CECILL-2.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/CECILL-2.0.json", "referenceNumber": 73, "name": "CeCILL Free Software License Agreement v2.0", "licenseId": "CECILL-2.0", "seeAlso": [ "http://www.cecill.info/licences/Licence_CeCILL_V2-en.html" ], "isOsiApproved": false, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/CECILL-2.1.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/CECILL-2.1.json", "referenceNumber": 393, "name": "CeCILL Free Software License Agreement v2.1", "licenseId": "CECILL-2.1", "seeAlso": [ "http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.html" ], "isOsiApproved": true }, { "reference": "https://spdx.org/licenses/CECILL-B.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/CECILL-B.json", "referenceNumber": 354, "name": "CeCILL-B Free Software License Agreement", "licenseId": "CECILL-B", "seeAlso": [ "http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html" ], "isOsiApproved": false, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/CECILL-C.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/CECILL-C.json", "referenceNumber": 271, "name": "CeCILL-C Free Software License Agreement", "licenseId": "CECILL-C", "seeAlso": [ "http://www.cecill.info/licences/Licence_CeCILL-C_V1-en.html" ], "isOsiApproved": false, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/CERN-OHL-1.1.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/CERN-OHL-1.1.json", "referenceNumber": 32, "name": "CERN Open Hardware Licence v1.1", "licenseId": "CERN-OHL-1.1", "seeAlso": [ "https://www.ohwr.org/project/licenses/wikis/cern-ohl-v1.1" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/CERN-OHL-1.2.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/CERN-OHL-1.2.json", "referenceNumber": 95, "name": "CERN Open Hardware Licence v1.2", "licenseId": "CERN-OHL-1.2", "seeAlso": [ "https://www.ohwr.org/project/licenses/wikis/cern-ohl-v1.2" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/CERN-OHL-P-2.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/CERN-OHL-P-2.0.json", "referenceNumber": 198, "name": "CERN Open Hardware Licence Version 2 - Permissive", "licenseId": "CERN-OHL-P-2.0", "seeAlso": [ "https://www.ohwr.org/project/cernohl/wikis/Documents/CERN-OHL-version-2" ], "isOsiApproved": true }, { "reference": "https://spdx.org/licenses/CERN-OHL-S-2.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/CERN-OHL-S-2.0.json", "referenceNumber": 370, "name": "CERN Open Hardware Licence Version 2 - Strongly Reciprocal", "licenseId": "CERN-OHL-S-2.0", "seeAlso": [ "https://www.ohwr.org/project/cernohl/wikis/Documents/CERN-OHL-version-2" ], "isOsiApproved": true }, { "reference": "https://spdx.org/licenses/CERN-OHL-W-2.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/CERN-OHL-W-2.0.json", "referenceNumber": 82, "name": "CERN Open Hardware Licence Version 2 - Weakly Reciprocal", "licenseId": "CERN-OHL-W-2.0", "seeAlso": [ "https://www.ohwr.org/project/cernohl/wikis/Documents/CERN-OHL-version-2" ], "isOsiApproved": true }, { "reference": "https://spdx.org/licenses/CFITSIO.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/CFITSIO.json", "referenceNumber": 96, "name": "CFITSIO License", "licenseId": "CFITSIO", "seeAlso": [ "https://heasarc.gsfc.nasa.gov/docs/software/fitsio/c/f_user/node9.html", "https://heasarc.gsfc.nasa.gov/docs/software/ftools/fv/doc/license.html" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/check-cvs.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/check-cvs.json", "referenceNumber": 521, "name": "check-cvs License", "licenseId": "check-cvs", "seeAlso": [ "http://cvs.savannah.gnu.org/viewvc/cvs/ccvs/contrib/check_cvs.in?revision\u003d1.1.4.3\u0026view\u003dmarkup\u0026pathrev\u003dcvs1-11-23#l2" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/checkmk.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/checkmk.json", "referenceNumber": 272, "name": "Checkmk License", "licenseId": "checkmk", "seeAlso": [ "https://github.com/libcheck/check/blob/master/checkmk/checkmk.in" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/ClArtistic.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/ClArtistic.json", "referenceNumber": 66, "name": "Clarified Artistic License", "licenseId": "ClArtistic", "seeAlso": [ "http://gianluca.dellavedova.org/2011/01/03/clarified-artistic-license/", "http://www.ncftp.com/ncftp/doc/LICENSE.txt" ], "isOsiApproved": false, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/Clips.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Clips.json", "referenceNumber": 450, "name": "Clips License", "licenseId": "Clips", "seeAlso": [ "https://github.com/DrItanium/maya/blob/master/LICENSE.CLIPS" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/CMU-Mach.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/CMU-Mach.json", "referenceNumber": 410, "name": "CMU Mach License", "licenseId": "CMU-Mach", "seeAlso": [ "https://www.cs.cmu.edu/~410/licenses.html" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/CMU-Mach-nodoc.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/CMU-Mach-nodoc.json", "referenceNumber": 111, "name": "CMU Mach - no notices-in-documentation variant", "licenseId": "CMU-Mach-nodoc", "seeAlso": [ "https://github.com/krb5/krb5/blob/krb5-1.21.2-final/NOTICE#L718-L728", "https://web.mit.edu/kerberos/krb5-1.21/doc/mitK5license.html" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/CNRI-Jython.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/CNRI-Jython.json", "referenceNumber": 509, "name": "CNRI Jython License", "licenseId": "CNRI-Jython", "seeAlso": [ "http://www.jython.org/license.html" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/CNRI-Python.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/CNRI-Python.json", "referenceNumber": 611, "name": "CNRI Python License", "licenseId": "CNRI-Python", "seeAlso": [ "https://opensource.org/licenses/CNRI-Python" ], "isOsiApproved": true }, { "reference": "https://spdx.org/licenses/CNRI-Python-GPL-Compatible.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/CNRI-Python-GPL-Compatible.json", "referenceNumber": 504, "name": "CNRI Python Open Source GPL Compatible License Agreement", "licenseId": "CNRI-Python-GPL-Compatible", "seeAlso": [ "http://www.python.org/download/releases/1.6.1/download_win/" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/COIL-1.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/COIL-1.0.json", "referenceNumber": 286, "name": "Copyfree Open Innovation License", "licenseId": "COIL-1.0", "seeAlso": [ "https://coil.apotheon.org/plaintext/01.0.txt" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/Community-Spec-1.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Community-Spec-1.0.json", "referenceNumber": 631, "name": "Community Specification License 1.0", "licenseId": "Community-Spec-1.0", "seeAlso": [ "https://github.com/CommunitySpecification/1.0/blob/master/1._Community_Specification_License-v1.md" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/Condor-1.1.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Condor-1.1.json", "referenceNumber": 251, "name": "Condor Public License v1.1", "licenseId": "Condor-1.1", "seeAlso": [ "http://research.cs.wisc.edu/condor/license.html#condor", "http://web.archive.org/web/20111123062036/http://research.cs.wisc.edu/condor/license.html#condor" ], "isOsiApproved": false, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/copyleft-next-0.3.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/copyleft-next-0.3.0.json", "referenceNumber": 421, "name": "copyleft-next 0.3.0", "licenseId": "copyleft-next-0.3.0", "seeAlso": [ "https://github.com/copyleft-next/copyleft-next/blob/master/Releases/copyleft-next-0.3.0" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/copyleft-next-0.3.1.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/copyleft-next-0.3.1.json", "referenceNumber": 119, "name": "copyleft-next 0.3.1", "licenseId": "copyleft-next-0.3.1", "seeAlso": [ "https://github.com/copyleft-next/copyleft-next/blob/master/Releases/copyleft-next-0.3.1" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/Cornell-Lossless-JPEG.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Cornell-Lossless-JPEG.json", "referenceNumber": 632, "name": "Cornell Lossless JPEG License", "licenseId": "Cornell-Lossless-JPEG", "seeAlso": [ "https://android.googlesource.com/platform/external/dng_sdk/+/refs/heads/master/source/dng_lossless_jpeg.cpp#16", "https://www.mssl.ucl.ac.uk/~mcrw/src/20050920/proto.h", "https://gitlab.freedesktop.org/libopenraw/libopenraw/blob/master/lib/ljpegdecompressor.cpp#L32" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/CPAL-1.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/CPAL-1.0.json", "referenceNumber": 315, "name": "Common Public Attribution License 1.0", "licenseId": "CPAL-1.0", "seeAlso": [ "https://opensource.org/licenses/CPAL-1.0" ], "isOsiApproved": true, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/CPL-1.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/CPL-1.0.json", "referenceNumber": 135, "name": "Common Public License 1.0", "licenseId": "CPL-1.0", "seeAlso": [ "https://opensource.org/licenses/CPL-1.0" ], "isOsiApproved": true, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/CPOL-1.02.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/CPOL-1.02.json", "referenceNumber": 479, "name": "Code Project Open License 1.02", "licenseId": "CPOL-1.02", "seeAlso": [ "http://www.codeproject.com/info/cpol10.aspx" ], "isOsiApproved": false, "isFsfLibre": false }, { "reference": "https://spdx.org/licenses/Cronyx.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Cronyx.json", "referenceNumber": 377, "name": "Cronyx License", "licenseId": "Cronyx", "seeAlso": [ "https://gitlab.freedesktop.org/xorg/font/alias/-/blob/master/COPYING", "https://gitlab.freedesktop.org/xorg/font/cronyx-cyrillic/-/blob/master/COPYING", "https://gitlab.freedesktop.org/xorg/font/misc-cyrillic/-/blob/master/COPYING", "https://gitlab.freedesktop.org/xorg/font/screen-cyrillic/-/blob/master/COPYING" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/Crossword.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Crossword.json", "referenceNumber": 340, "name": "Crossword License", "licenseId": "Crossword", "seeAlso": [ "https://fedoraproject.org/wiki/Licensing/Crossword" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/CrystalStacker.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/CrystalStacker.json", "referenceNumber": 593, "name": "CrystalStacker License", "licenseId": "CrystalStacker", "seeAlso": [ "https://fedoraproject.org/wiki/Licensing:CrystalStacker?rd\u003dLicensing/CrystalStacker" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/CUA-OPL-1.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/CUA-OPL-1.0.json", "referenceNumber": 553, "name": "CUA Office Public License v1.0", "licenseId": "CUA-OPL-1.0", "seeAlso": [ "https://opensource.org/licenses/CUA-OPL-1.0" ], "isOsiApproved": true }, { "reference": "https://spdx.org/licenses/Cube.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Cube.json", "referenceNumber": 404, "name": "Cube License", "licenseId": "Cube", "seeAlso": [ "https://fedoraproject.org/wiki/Licensing/Cube" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/curl.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/curl.json", "referenceNumber": 604, "name": "curl License", "licenseId": "curl", "seeAlso": [ "https://github.com/bagder/curl/blob/master/COPYING" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/cve-tou.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/cve-tou.json", "referenceNumber": 306, "name": "Common Vulnerability Enumeration ToU License", "licenseId": "cve-tou", "seeAlso": [ "https://www.cve.org/Legal/TermsOfUse" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/D-FSL-1.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/D-FSL-1.0.json", "referenceNumber": 154, "name": "Deutsche Freie Software Lizenz", "licenseId": "D-FSL-1.0", "seeAlso": [ "http://www.dipp.nrw.de/d-fsl/lizenzen/", "http://www.dipp.nrw.de/d-fsl/index_html/lizenzen/de/D-FSL-1_0_de.txt", "http://www.dipp.nrw.de/d-fsl/index_html/lizenzen/en/D-FSL-1_0_en.txt", "https://www.hbz-nrw.de/produkte/open-access/lizenzen/dfsl", "https://www.hbz-nrw.de/produkte/open-access/lizenzen/dfsl/deutsche-freie-software-lizenz", "https://www.hbz-nrw.de/produkte/open-access/lizenzen/dfsl/german-free-software-license", "https://www.hbz-nrw.de/produkte/open-access/lizenzen/dfsl/D-FSL-1_0_de.txt/at_download/file", "https://www.hbz-nrw.de/produkte/open-access/lizenzen/dfsl/D-FSL-1_0_en.txt/at_download/file" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/DEC-3-Clause.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/DEC-3-Clause.json", "referenceNumber": 15, "name": "DEC 3-Clause License", "licenseId": "DEC-3-Clause", "seeAlso": [ "https://gitlab.freedesktop.org/xorg/xserver/-/blob/master/COPYING?ref_type\u003dheads#L239" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/diffmark.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/diffmark.json", "referenceNumber": 292, "name": "diffmark license", "licenseId": "diffmark", "seeAlso": [ "https://fedoraproject.org/wiki/Licensing/diffmark" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/DL-DE-BY-2.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/DL-DE-BY-2.0.json", "referenceNumber": 225, "name": "Data licence Germany – attribution – version 2.0", "licenseId": "DL-DE-BY-2.0", "seeAlso": [ "https://www.govdata.de/dl-de/by-2-0" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/DL-DE-ZERO-2.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/DL-DE-ZERO-2.0.json", "referenceNumber": 341, "name": "Data licence Germany – zero – version 2.0", "licenseId": "DL-DE-ZERO-2.0", "seeAlso": [ "https://www.govdata.de/dl-de/zero-2-0" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/DOC.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/DOC.json", "referenceNumber": 397, "name": "DOC License", "licenseId": "DOC", "seeAlso": [ "http://www.cs.wustl.edu/~schmidt/ACE-copying.html", "https://www.dre.vanderbilt.edu/~schmidt/ACE-copying.html" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/Dotseqn.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Dotseqn.json", "referenceNumber": 132, "name": "Dotseqn License", "licenseId": "Dotseqn", "seeAlso": [ "https://fedoraproject.org/wiki/Licensing/Dotseqn" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/DRL-1.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/DRL-1.0.json", "referenceNumber": 16, "name": "Detection Rule License 1.0", "licenseId": "DRL-1.0", "seeAlso": [ "https://github.com/Neo23x0/sigma/blob/master/LICENSE.Detection.Rules.md" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/DRL-1.1.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/DRL-1.1.json", "referenceNumber": 278, "name": "Detection Rule License 1.1", "licenseId": "DRL-1.1", "seeAlso": [ "https://github.com/SigmaHQ/Detection-Rule-License/blob/6ec7fbde6101d101b5b5d1fcb8f9b69fbc76c04a/LICENSE.Detection.Rules.md" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/DSDP.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/DSDP.json", "referenceNumber": 485, "name": "DSDP License", "licenseId": "DSDP", "seeAlso": [ "https://fedoraproject.org/wiki/Licensing/DSDP" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/dtoa.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/dtoa.json", "referenceNumber": 358, "name": "David M. Gay dtoa License", "licenseId": "dtoa", "seeAlso": [ "https://github.com/SWI-Prolog/swipl-devel/blob/master/src/os/dtoa.c", "https://sourceware.org/git/?p\u003dnewlib-cygwin.git;a\u003dblob;f\u003dnewlib/libc/stdlib/mprec.h;hb\u003dHEAD" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/dvipdfm.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/dvipdfm.json", "referenceNumber": 100, "name": "dvipdfm License", "licenseId": "dvipdfm", "seeAlso": [ "https://fedoraproject.org/wiki/Licensing/dvipdfm" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/ECL-1.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/ECL-1.0.json", "referenceNumber": 124, "name": "Educational Community License v1.0", "licenseId": "ECL-1.0", "seeAlso": [ "https://opensource.org/licenses/ECL-1.0" ], "isOsiApproved": true }, { "reference": "https://spdx.org/licenses/ECL-2.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/ECL-2.0.json", "referenceNumber": 361, "name": "Educational Community License v2.0", "licenseId": "ECL-2.0", "seeAlso": [ "https://opensource.org/licenses/ECL-2.0" ], "isOsiApproved": true, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/eCos-2.0.html", "isDeprecatedLicenseId": true, "detailsUrl": "https://spdx.org/licenses/eCos-2.0.json", "referenceNumber": 372, "name": "eCos license version 2.0", "licenseId": "eCos-2.0", "seeAlso": [ "https://www.gnu.org/licenses/ecos-license.html" ], "isOsiApproved": false, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/EFL-1.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/EFL-1.0.json", "referenceNumber": 335, "name": "Eiffel Forum License v1.0", "licenseId": "EFL-1.0", "seeAlso": [ "http://www.eiffel-nice.org/license/forum.txt", "https://opensource.org/licenses/EFL-1.0" ], "isOsiApproved": true }, { "reference": "https://spdx.org/licenses/EFL-2.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/EFL-2.0.json", "referenceNumber": 88, "name": "Eiffel Forum License v2.0", "licenseId": "EFL-2.0", "seeAlso": [ "http://www.eiffel-nice.org/license/eiffel-forum-license-2.html", "https://opensource.org/licenses/EFL-2.0" ], "isOsiApproved": true, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/eGenix.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/eGenix.json", "referenceNumber": 261, "name": "eGenix.com Public License 1.1.0", "licenseId": "eGenix", "seeAlso": [ "http://www.egenix.com/products/eGenix.com-Public-License-1.1.0.pdf", "https://fedoraproject.org/wiki/Licensing/eGenix.com_Public_License_1.1.0" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/Elastic-2.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Elastic-2.0.json", "referenceNumber": 147, "name": "Elastic License 2.0", "licenseId": "Elastic-2.0", "seeAlso": [ "https://www.elastic.co/licensing/elastic-license", "https://github.com/elastic/elasticsearch/blob/master/licenses/ELASTIC-LICENSE-2.0.txt" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/Entessa.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Entessa.json", "referenceNumber": 546, "name": "Entessa Public License v1.0", "licenseId": "Entessa", "seeAlso": [ "https://opensource.org/licenses/Entessa" ], "isOsiApproved": true }, { "reference": "https://spdx.org/licenses/EPICS.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/EPICS.json", "referenceNumber": 120, "name": "EPICS Open License", "licenseId": "EPICS", "seeAlso": [ "https://epics.anl.gov/license/open.php" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/EPL-1.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/EPL-1.0.json", "referenceNumber": 500, "name": "Eclipse Public License 1.0", "licenseId": "EPL-1.0", "seeAlso": [ "http://www.eclipse.org/legal/epl-v10.html", "https://opensource.org/licenses/EPL-1.0" ], "isOsiApproved": true, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/EPL-2.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/EPL-2.0.json", "referenceNumber": 407, "name": "Eclipse Public License 2.0", "licenseId": "EPL-2.0", "seeAlso": [ "https://www.eclipse.org/legal/epl-2.0", "https://www.opensource.org/licenses/EPL-2.0" ], "isOsiApproved": true, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/ErlPL-1.1.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/ErlPL-1.1.json", "referenceNumber": 466, "name": "Erlang Public License v1.1", "licenseId": "ErlPL-1.1", "seeAlso": [ "http://www.erlang.org/EPLICENSE" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/etalab-2.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/etalab-2.0.json", "referenceNumber": 636, "name": "Etalab Open License 2.0", "licenseId": "etalab-2.0", "seeAlso": [ "https://github.com/DISIC/politique-de-contribution-open-source/blob/master/LICENSE.pdf", "https://raw.githubusercontent.com/DISIC/politique-de-contribution-open-source/master/LICENSE" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/EUDatagrid.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/EUDatagrid.json", "referenceNumber": 228, "name": "EU DataGrid Software License", "licenseId": "EUDatagrid", "seeAlso": [ "http://eu-datagrid.web.cern.ch/eu-datagrid/license.html", "https://opensource.org/licenses/EUDatagrid" ], "isOsiApproved": true, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/EUPL-1.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/EUPL-1.0.json", "referenceNumber": 227, "name": "European Union Public License 1.0", "licenseId": "EUPL-1.0", "seeAlso": [ "http://ec.europa.eu/idabc/en/document/7330.html", "http://ec.europa.eu/idabc/servlets/Doc027f.pdf?id\u003d31096" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/EUPL-1.1.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/EUPL-1.1.json", "referenceNumber": 266, "name": "European Union Public License 1.1", "licenseId": "EUPL-1.1", "seeAlso": [ "https://joinup.ec.europa.eu/software/page/eupl/licence-eupl", "https://joinup.ec.europa.eu/sites/default/files/custom-page/attachment/eupl1.1.-licence-en_0.pdf", "https://opensource.org/licenses/EUPL-1.1" ], "isOsiApproved": true, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/EUPL-1.2.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/EUPL-1.2.json", "referenceNumber": 559, "name": "European Union Public License 1.2", "licenseId": "EUPL-1.2", "seeAlso": [ "https://joinup.ec.europa.eu/page/eupl-text-11-12", "https://joinup.ec.europa.eu/sites/default/files/custom-page/attachment/eupl_v1.2_en.pdf", "https://joinup.ec.europa.eu/sites/default/files/custom-page/attachment/2020-03/EUPL-1.2%20EN.txt", "https://joinup.ec.europa.eu/sites/default/files/inline-files/EUPL%20v1_2%20EN(1).txt", "http://eur-lex.europa.eu/legal-content/EN/TXT/HTML/?uri\u003dCELEX:32017D0863", "https://opensource.org/licenses/EUPL-1.2" ], "isOsiApproved": true, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/Eurosym.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Eurosym.json", "referenceNumber": 63, "name": "Eurosym License", "licenseId": "Eurosym", "seeAlso": [ "https://fedoraproject.org/wiki/Licensing/Eurosym" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/Fair.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Fair.json", "referenceNumber": 570, "name": "Fair License", "licenseId": "Fair", "seeAlso": [ "https://web.archive.org/web/20150926120323/http://fairlicense.org/", "https://opensource.org/licenses/Fair" ], "isOsiApproved": true }, { "reference": "https://spdx.org/licenses/FBM.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/FBM.json", "referenceNumber": 175, "name": "Fuzzy Bitmap License", "licenseId": "FBM", "seeAlso": [ "https://github.com/SWI-Prolog/packages-xpce/blob/161a40cd82004f731ba48024f9d30af388a7edf5/src/img/gifwrite.c#L21-L26" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/FDK-AAC.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/FDK-AAC.json", "referenceNumber": 49, "name": "Fraunhofer FDK AAC Codec Library", "licenseId": "FDK-AAC", "seeAlso": [ "https://fedoraproject.org/wiki/Licensing/FDK-AAC", "https://directory.fsf.org/wiki/License:Fdk" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/Ferguson-Twofish.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Ferguson-Twofish.json", "referenceNumber": 617, "name": "Ferguson Twofish License", "licenseId": "Ferguson-Twofish", "seeAlso": [ "https://github.com/wernerd/ZRTPCPP/blob/6b3cd8e6783642292bad0c21e3e5e5ce45ff3e03/cryptcommon/twofish.c#L113C3-L127" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/Frameworx-1.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Frameworx-1.0.json", "referenceNumber": 259, "name": "Frameworx Open License 1.0", "licenseId": "Frameworx-1.0", "seeAlso": [ "https://opensource.org/licenses/Frameworx-1.0" ], "isOsiApproved": true }, { "reference": "https://spdx.org/licenses/FreeBSD-DOC.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/FreeBSD-DOC.json", "referenceNumber": 333, "name": "FreeBSD Documentation License", "licenseId": "FreeBSD-DOC", "seeAlso": [ "https://www.freebsd.org/copyright/freebsd-doc-license/" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/FreeImage.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/FreeImage.json", "referenceNumber": 181, "name": "FreeImage Public License v1.0", "licenseId": "FreeImage", "seeAlso": [ "http://freeimage.sourceforge.net/freeimage-license.txt" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/FSFAP.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/FSFAP.json", "referenceNumber": 36, "name": "FSF All Permissive License", "licenseId": "FSFAP", "seeAlso": [ "https://www.gnu.org/prep/maintain/html_node/License-Notices-for-Other-Files.html" ], "isOsiApproved": false, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/FSFAP-no-warranty-disclaimer.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/FSFAP-no-warranty-disclaimer.json", "referenceNumber": 536, "name": "FSF All Permissive License (without Warranty)", "licenseId": "FSFAP-no-warranty-disclaimer", "seeAlso": [ "https://git.savannah.gnu.org/cgit/wget.git/tree/util/trunc.c?h\u003dv1.21.3\u0026id\u003d40747a11e44ced5a8ac628a41f879ced3e2ebce9#n6" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/FSFUL.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/FSFUL.json", "referenceNumber": 454, "name": "FSF Unlimited License", "licenseId": "FSFUL", "seeAlso": [ "https://fedoraproject.org/wiki/Licensing/FSF_Unlimited_License" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/FSFULLR.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/FSFULLR.json", "referenceNumber": 422, "name": "FSF Unlimited License (with License Retention)", "licenseId": "FSFULLR", "seeAlso": [ "https://fedoraproject.org/wiki/Licensing/FSF_Unlimited_License#License_Retention_Variant" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/FSFULLRWD.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/FSFULLRWD.json", "referenceNumber": 197, "name": "FSF Unlimited License (With License Retention and Warranty Disclaimer)", "licenseId": "FSFULLRWD", "seeAlso": [ "https://lists.gnu.org/archive/html/autoconf/2012-04/msg00061.html" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/FTL.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/FTL.json", "referenceNumber": 438, "name": "Freetype Project License", "licenseId": "FTL", "seeAlso": [ "http://freetype.fis.uniroma2.it/FTL.TXT", "http://git.savannah.gnu.org/cgit/freetype/freetype2.git/tree/docs/FTL.TXT", "http://gitlab.freedesktop.org/freetype/freetype/-/raw/master/docs/FTL.TXT" ], "isOsiApproved": false, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/Furuseth.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Furuseth.json", "referenceNumber": 380, "name": "Furuseth License", "licenseId": "Furuseth", "seeAlso": [ "https://git.openldap.org/openldap/openldap/-/blob/master/COPYRIGHT?ref_type\u003dheads#L39-51" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/fwlw.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/fwlw.json", "referenceNumber": 529, "name": "fwlw License", "licenseId": "fwlw", "seeAlso": [ "https://mirrors.nic.cz/tex-archive/macros/latex/contrib/fwlw/README" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/GCR-docs.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/GCR-docs.json", "referenceNumber": 115, "name": "Gnome GCR Documentation License", "licenseId": "GCR-docs", "seeAlso": [ "https://github.com/GNOME/gcr/blob/master/docs/COPYING" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/GD.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/GD.json", "referenceNumber": 291, "name": "GD License", "licenseId": "GD", "seeAlso": [ "https://libgd.github.io/manuals/2.3.0/files/license-txt.html" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/GFDL-1.1.html", "isDeprecatedLicenseId": true, "detailsUrl": "https://spdx.org/licenses/GFDL-1.1.json", "referenceNumber": 589, "name": "GNU Free Documentation License v1.1", "licenseId": "GFDL-1.1", "seeAlso": [ "https://www.gnu.org/licenses/old-licenses/fdl-1.1.txt" ], "isOsiApproved": false, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/GFDL-1.1-invariants-only.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/GFDL-1.1-invariants-only.json", "referenceNumber": 307, "name": "GNU Free Documentation License v1.1 only - invariants", "licenseId": "GFDL-1.1-invariants-only", "seeAlso": [ "https://www.gnu.org/licenses/old-licenses/fdl-1.1.txt" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/GFDL-1.1-invariants-or-later.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/GFDL-1.1-invariants-or-later.json", "referenceNumber": 98, "name": "GNU Free Documentation License v1.1 or later - invariants", "licenseId": "GFDL-1.1-invariants-or-later", "seeAlso": [ "https://www.gnu.org/licenses/old-licenses/fdl-1.1.txt" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/GFDL-1.1-no-invariants-only.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/GFDL-1.1-no-invariants-only.json", "referenceNumber": 47, "name": "GNU Free Documentation License v1.1 only - no invariants", "licenseId": "GFDL-1.1-no-invariants-only", "seeAlso": [ "https://www.gnu.org/licenses/old-licenses/fdl-1.1.txt" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/GFDL-1.1-no-invariants-or-later.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/GFDL-1.1-no-invariants-or-later.json", "referenceNumber": 273, "name": "GNU Free Documentation License v1.1 or later - no invariants", "licenseId": "GFDL-1.1-no-invariants-or-later", "seeAlso": [ "https://www.gnu.org/licenses/old-licenses/fdl-1.1.txt" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/GFDL-1.1-only.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/GFDL-1.1-only.json", "referenceNumber": 626, "name": "GNU Free Documentation License v1.1 only", "licenseId": "GFDL-1.1-only", "seeAlso": [ "https://www.gnu.org/licenses/old-licenses/fdl-1.1.txt" ], "isOsiApproved": false, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/GFDL-1.1-or-later.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/GFDL-1.1-or-later.json", "referenceNumber": 644, "name": "GNU Free Documentation License v1.1 or later", "licenseId": "GFDL-1.1-or-later", "seeAlso": [ "https://www.gnu.org/licenses/old-licenses/fdl-1.1.txt" ], "isOsiApproved": false, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/GFDL-1.2.html", "isDeprecatedLicenseId": true, "detailsUrl": "https://spdx.org/licenses/GFDL-1.2.json", "referenceNumber": 520, "name": "GNU Free Documentation License v1.2", "licenseId": "GFDL-1.2", "seeAlso": [ "https://www.gnu.org/licenses/old-licenses/fdl-1.2.txt" ], "isOsiApproved": false, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/GFDL-1.2-invariants-only.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/GFDL-1.2-invariants-only.json", "referenceNumber": 495, "name": "GNU Free Documentation License v1.2 only - invariants", "licenseId": "GFDL-1.2-invariants-only", "seeAlso": [ "https://www.gnu.org/licenses/old-licenses/fdl-1.2.txt" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/GFDL-1.2-invariants-or-later.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/GFDL-1.2-invariants-or-later.json", "referenceNumber": 6, "name": "GNU Free Documentation License v1.2 or later - invariants", "licenseId": "GFDL-1.2-invariants-or-later", "seeAlso": [ "https://www.gnu.org/licenses/old-licenses/fdl-1.2.txt" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/GFDL-1.2-no-invariants-only.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/GFDL-1.2-no-invariants-only.json", "referenceNumber": 77, "name": "GNU Free Documentation License v1.2 only - no invariants", "licenseId": "GFDL-1.2-no-invariants-only", "seeAlso": [ "https://www.gnu.org/licenses/old-licenses/fdl-1.2.txt" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/GFDL-1.2-no-invariants-or-later.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/GFDL-1.2-no-invariants-or-later.json", "referenceNumber": 279, "name": "GNU Free Documentation License v1.2 or later - no invariants", "licenseId": "GFDL-1.2-no-invariants-or-later", "seeAlso": [ "https://www.gnu.org/licenses/old-licenses/fdl-1.2.txt" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/GFDL-1.2-only.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/GFDL-1.2-only.json", "referenceNumber": 648, "name": "GNU Free Documentation License v1.2 only", "licenseId": "GFDL-1.2-only", "seeAlso": [ "https://www.gnu.org/licenses/old-licenses/fdl-1.2.txt" ], "isOsiApproved": false, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/GFDL-1.2-or-later.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/GFDL-1.2-or-later.json", "referenceNumber": 318, "name": "GNU Free Documentation License v1.2 or later", "licenseId": "GFDL-1.2-or-later", "seeAlso": [ "https://www.gnu.org/licenses/old-licenses/fdl-1.2.txt" ], "isOsiApproved": false, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/GFDL-1.3.html", "isDeprecatedLicenseId": true, "detailsUrl": "https://spdx.org/licenses/GFDL-1.3.json", "referenceNumber": 287, "name": "GNU Free Documentation License v1.3", "licenseId": "GFDL-1.3", "seeAlso": [ "https://www.gnu.org/licenses/fdl-1.3.txt" ], "isOsiApproved": false, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/GFDL-1.3-invariants-only.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/GFDL-1.3-invariants-only.json", "referenceNumber": 289, "name": "GNU Free Documentation License v1.3 only - invariants", "licenseId": "GFDL-1.3-invariants-only", "seeAlso": [ "https://www.gnu.org/licenses/fdl-1.3.txt" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/GFDL-1.3-invariants-or-later.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/GFDL-1.3-invariants-or-later.json", "referenceNumber": 497, "name": "GNU Free Documentation License v1.3 or later - invariants", "licenseId": "GFDL-1.3-invariants-or-later", "seeAlso": [ "https://www.gnu.org/licenses/fdl-1.3.txt" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/GFDL-1.3-no-invariants-only.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/GFDL-1.3-no-invariants-only.json", "referenceNumber": 254, "name": "GNU Free Documentation License v1.3 only - no invariants", "licenseId": "GFDL-1.3-no-invariants-only", "seeAlso": [ "https://www.gnu.org/licenses/fdl-1.3.txt" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/GFDL-1.3-no-invariants-or-later.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/GFDL-1.3-no-invariants-or-later.json", "referenceNumber": 207, "name": "GNU Free Documentation License v1.3 or later - no invariants", "licenseId": "GFDL-1.3-no-invariants-or-later", "seeAlso": [ "https://www.gnu.org/licenses/fdl-1.3.txt" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/GFDL-1.3-only.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/GFDL-1.3-only.json", "referenceNumber": 635, "name": "GNU Free Documentation License v1.3 only", "licenseId": "GFDL-1.3-only", "seeAlso": [ "https://www.gnu.org/licenses/fdl-1.3.txt" ], "isOsiApproved": false, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/GFDL-1.3-or-later.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/GFDL-1.3-or-later.json", "referenceNumber": 448, "name": "GNU Free Documentation License v1.3 or later", "licenseId": "GFDL-1.3-or-later", "seeAlso": [ "https://www.gnu.org/licenses/fdl-1.3.txt" ], "isOsiApproved": false, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/Giftware.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Giftware.json", "referenceNumber": 172, "name": "Giftware License", "licenseId": "Giftware", "seeAlso": [ "http://liballeg.org/license.html#allegro-4-the-giftware-license" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/GL2PS.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/GL2PS.json", "referenceNumber": 434, "name": "GL2PS License", "licenseId": "GL2PS", "seeAlso": [ "http://www.geuz.org/gl2ps/COPYING.GL2PS" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/Glide.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Glide.json", "referenceNumber": 189, "name": "3dfx Glide License", "licenseId": "Glide", "seeAlso": [ "http://www.users.on.net/~triforce/glidexp/COPYING.txt" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/Glulxe.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Glulxe.json", "referenceNumber": 85, "name": "Glulxe License", "licenseId": "Glulxe", "seeAlso": [ "https://fedoraproject.org/wiki/Licensing/Glulxe" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/GLWTPL.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/GLWTPL.json", "referenceNumber": 190, "name": "Good Luck With That Public License", "licenseId": "GLWTPL", "seeAlso": [ "https://github.com/me-shaon/GLWTPL/commit/da5f6bc734095efbacb442c0b31e33a65b9d6e85" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/gnuplot.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/gnuplot.json", "referenceNumber": 110, "name": "gnuplot License", "licenseId": "gnuplot", "seeAlso": [ "https://fedoraproject.org/wiki/Licensing/Gnuplot" ], "isOsiApproved": false, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/GPL-1.0.html", "isDeprecatedLicenseId": true, "detailsUrl": "https://spdx.org/licenses/GPL-1.0.json", "referenceNumber": 630, "name": "GNU General Public License v1.0 only", "licenseId": "GPL-1.0", "seeAlso": [ "https://www.gnu.org/licenses/old-licenses/gpl-1.0-standalone.html" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/GPL-1.0+.html", "isDeprecatedLicenseId": true, "detailsUrl": "https://spdx.org/licenses/GPL-1.0+.json", "referenceNumber": 26, "name": "GNU General Public License v1.0 or later", "licenseId": "GPL-1.0+", "seeAlso": [ "https://www.gnu.org/licenses/old-licenses/gpl-1.0-standalone.html" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/GPL-1.0-only.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/GPL-1.0-only.json", "referenceNumber": 12, "name": "GNU General Public License v1.0 only", "licenseId": "GPL-1.0-only", "seeAlso": [ "https://www.gnu.org/licenses/old-licenses/gpl-1.0-standalone.html" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/GPL-1.0-or-later.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/GPL-1.0-or-later.json", "referenceNumber": 642, "name": "GNU General Public License v1.0 or later", "licenseId": "GPL-1.0-or-later", "seeAlso": [ "https://www.gnu.org/licenses/old-licenses/gpl-1.0-standalone.html" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/GPL-2.0.html", "isDeprecatedLicenseId": true, "detailsUrl": "https://spdx.org/licenses/GPL-2.0.json", "referenceNumber": 524, "name": "GNU General Public License v2.0 only", "licenseId": "GPL-2.0", "seeAlso": [ "https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html", "https://opensource.org/licenses/GPL-2.0" ], "isOsiApproved": true, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/GPL-2.0+.html", "isDeprecatedLicenseId": true, "detailsUrl": "https://spdx.org/licenses/GPL-2.0+.json", "referenceNumber": 25, "name": "GNU General Public License v2.0 or later", "licenseId": "GPL-2.0+", "seeAlso": [ "https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html", "https://opensource.org/licenses/GPL-2.0" ], "isOsiApproved": true, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/GPL-2.0-only.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/GPL-2.0-only.json", "referenceNumber": 618, "name": "GNU General Public License v2.0 only", "licenseId": "GPL-2.0-only", "seeAlso": [ "https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html", "https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt", "https://opensource.org/licenses/GPL-2.0" ], "isOsiApproved": true, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/GPL-2.0-or-later.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/GPL-2.0-or-later.json", "referenceNumber": 164, "name": "GNU General Public License v2.0 or later", "licenseId": "GPL-2.0-or-later", "seeAlso": [ "https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html", "https://opensource.org/licenses/GPL-2.0" ], "isOsiApproved": true, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/GPL-2.0-with-autoconf-exception.html", "isDeprecatedLicenseId": true, "detailsUrl": "https://spdx.org/licenses/GPL-2.0-with-autoconf-exception.json", "referenceNumber": 146, "name": "GNU General Public License v2.0 w/Autoconf exception", "licenseId": "GPL-2.0-with-autoconf-exception", "seeAlso": [ "http://ac-archive.sourceforge.net/doc/copyright.html" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/GPL-2.0-with-bison-exception.html", "isDeprecatedLicenseId": true, "detailsUrl": "https://spdx.org/licenses/GPL-2.0-with-bison-exception.json", "referenceNumber": 374, "name": "GNU General Public License v2.0 w/Bison exception", "licenseId": "GPL-2.0-with-bison-exception", "seeAlso": [ "http://git.savannah.gnu.org/cgit/bison.git/tree/data/yacc.c?id\u003d193d7c7054ba7197b0789e14965b739162319b5e#n141" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/GPL-2.0-with-classpath-exception.html", "isDeprecatedLicenseId": true, "detailsUrl": "https://spdx.org/licenses/GPL-2.0-with-classpath-exception.json", "referenceNumber": 331, "name": "GNU General Public License v2.0 w/Classpath exception", "licenseId": "GPL-2.0-with-classpath-exception", "seeAlso": [ "https://www.gnu.org/software/classpath/license.html" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/GPL-2.0-with-font-exception.html", "isDeprecatedLicenseId": true, "detailsUrl": "https://spdx.org/licenses/GPL-2.0-with-font-exception.json", "referenceNumber": 542, "name": "GNU General Public License v2.0 w/Font exception", "licenseId": "GPL-2.0-with-font-exception", "seeAlso": [ "https://www.gnu.org/licenses/gpl-faq.html#FontException" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/GPL-2.0-with-GCC-exception.html", "isDeprecatedLicenseId": true, "detailsUrl": "https://spdx.org/licenses/GPL-2.0-with-GCC-exception.json", "referenceNumber": 68, "name": "GNU General Public License v2.0 w/GCC Runtime Library exception", "licenseId": "GPL-2.0-with-GCC-exception", "seeAlso": [ "https://gcc.gnu.org/git/?p\u003dgcc.git;a\u003dblob;f\u003dgcc/libgcc1.c;h\u003d762f5143fc6eed57b6797c82710f3538aa52b40b;hb\u003dcb143a3ce4fb417c68f5fa2691a1b1b1053dfba9#l10" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/GPL-3.0.html", "isDeprecatedLicenseId": true, "detailsUrl": "https://spdx.org/licenses/GPL-3.0.json", "referenceNumber": 442, "name": "GNU General Public License v3.0 only", "licenseId": "GPL-3.0", "seeAlso": [ "https://www.gnu.org/licenses/gpl-3.0-standalone.html", "https://opensource.org/licenses/GPL-3.0" ], "isOsiApproved": true, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/GPL-3.0+.html", "isDeprecatedLicenseId": true, "detailsUrl": "https://spdx.org/licenses/GPL-3.0+.json", "referenceNumber": 270, "name": "GNU General Public License v3.0 or later", "licenseId": "GPL-3.0+", "seeAlso": [ "https://www.gnu.org/licenses/gpl-3.0-standalone.html", "https://opensource.org/licenses/GPL-3.0" ], "isOsiApproved": true, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/GPL-3.0-only.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/GPL-3.0-only.json", "referenceNumber": 133, "name": "GNU General Public License v3.0 only", "licenseId": "GPL-3.0-only", "seeAlso": [ "https://www.gnu.org/licenses/gpl-3.0-standalone.html", "https://opensource.org/licenses/GPL-3.0" ], "isOsiApproved": true, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/GPL-3.0-or-later.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/GPL-3.0-or-later.json", "referenceNumber": 390, "name": "GNU General Public License v3.0 or later", "licenseId": "GPL-3.0-or-later", "seeAlso": [ "https://www.gnu.org/licenses/gpl-3.0-standalone.html", "https://opensource.org/licenses/GPL-3.0" ], "isOsiApproved": true, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/GPL-3.0-with-autoconf-exception.html", "isDeprecatedLicenseId": true, "detailsUrl": "https://spdx.org/licenses/GPL-3.0-with-autoconf-exception.json", "referenceNumber": 458, "name": "GNU General Public License v3.0 w/Autoconf exception", "licenseId": "GPL-3.0-with-autoconf-exception", "seeAlso": [ "https://www.gnu.org/licenses/autoconf-exception-3.0.html" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/GPL-3.0-with-GCC-exception.html", "isDeprecatedLicenseId": true, "detailsUrl": "https://spdx.org/licenses/GPL-3.0-with-GCC-exception.json", "referenceNumber": 356, "name": "GNU General Public License v3.0 w/GCC Runtime Library exception", "licenseId": "GPL-3.0-with-GCC-exception", "seeAlso": [ "https://www.gnu.org/licenses/gcc-exception-3.1.html" ], "isOsiApproved": true }, { "reference": "https://spdx.org/licenses/Graphics-Gems.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Graphics-Gems.json", "referenceNumber": 574, "name": "Graphics Gems License", "licenseId": "Graphics-Gems", "seeAlso": [ "https://github.com/erich666/GraphicsGems/blob/master/LICENSE.md" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/gSOAP-1.3b.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/gSOAP-1.3b.json", "referenceNumber": 655, "name": "gSOAP Public License v1.3b", "licenseId": "gSOAP-1.3b", "seeAlso": [ "http://www.cs.fsu.edu/~engelen/license.html" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/gtkbook.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/gtkbook.json", "referenceNumber": 237, "name": "gtkbook License", "licenseId": "gtkbook", "seeAlso": [ "https://github.com/slogan621/gtkbook", "https://github.com/oetiker/rrdtool-1.x/blob/master/src/plbasename.c#L8-L11" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/Gutmann.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Gutmann.json", "referenceNumber": 441, "name": "Gutmann License", "licenseId": "Gutmann", "seeAlso": [ "https://www.cs.auckland.ac.nz/~pgut001/dumpasn1.c" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/HaskellReport.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/HaskellReport.json", "referenceNumber": 625, "name": "Haskell Language Report License", "licenseId": "HaskellReport", "seeAlso": [ "https://fedoraproject.org/wiki/Licensing/Haskell_Language_Report_License" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/hdparm.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/hdparm.json", "referenceNumber": 81, "name": "hdparm License", "licenseId": "hdparm", "seeAlso": [ "https://github.com/Distrotech/hdparm/blob/4517550db29a91420fb2b020349523b1b4512df2/LICENSE.TXT" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/Hippocratic-2.1.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Hippocratic-2.1.json", "referenceNumber": 299, "name": "Hippocratic License 2.1", "licenseId": "Hippocratic-2.1", "seeAlso": [ "https://firstdonoharm.dev/version/2/1/license.html", "https://github.com/EthicalSource/hippocratic-license/blob/58c0e646d64ff6fbee275bfe2b9492f914e3ab2a/LICENSE.txt" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/HP-1986.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/HP-1986.json", "referenceNumber": 277, "name": "Hewlett-Packard 1986 License", "licenseId": "HP-1986", "seeAlso": [ "https://sourceware.org/git/?p\u003dnewlib-cygwin.git;a\u003dblob;f\u003dnewlib/libc/machine/hppa/memchr.S;h\u003d1cca3e5e8867aa4bffef1f75a5c1bba25c0c441e;hb\u003dHEAD#l2" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/HP-1989.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/HP-1989.json", "referenceNumber": 639, "name": "Hewlett-Packard 1989 License", "licenseId": "HP-1989", "seeAlso": [ "https://github.com/bleargh45/Data-UUID/blob/master/LICENSE" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/HPND.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/HPND.json", "referenceNumber": 281, "name": "Historical Permission Notice and Disclaimer", "licenseId": "HPND", "seeAlso": [ "https://opensource.org/licenses/HPND", "http://lists.opensource.org/pipermail/license-discuss_lists.opensource.org/2002-November/006304.html" ], "isOsiApproved": true, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/HPND-DEC.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/HPND-DEC.json", "referenceNumber": 577, "name": "Historical Permission Notice and Disclaimer - DEC variant", "licenseId": "HPND-DEC", "seeAlso": [ "https://gitlab.freedesktop.org/xorg/app/xkbcomp/-/blob/master/COPYING?ref_type\u003dheads#L69" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/HPND-doc.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/HPND-doc.json", "referenceNumber": 391, "name": "Historical Permission Notice and Disclaimer - documentation variant", "licenseId": "HPND-doc", "seeAlso": [ "https://gitlab.freedesktop.org/xorg/lib/libxext/-/blob/master/COPYING?ref_type\u003dheads#L185-197", "https://gitlab.freedesktop.org/xorg/lib/libxtst/-/blob/master/COPYING?ref_type\u003dheads#L70-77" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/HPND-doc-sell.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/HPND-doc-sell.json", "referenceNumber": 163, "name": "Historical Permission Notice and Disclaimer - documentation sell variant", "licenseId": "HPND-doc-sell", "seeAlso": [ "https://gitlab.freedesktop.org/xorg/lib/libxtst/-/blob/master/COPYING?ref_type\u003dheads#L108-117", "https://gitlab.freedesktop.org/xorg/lib/libxext/-/blob/master/COPYING?ref_type\u003dheads#L153-162" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/HPND-export-US.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/HPND-export-US.json", "referenceNumber": 214, "name": "HPND with US Government export control warning", "licenseId": "HPND-export-US", "seeAlso": [ "https://www.kermitproject.org/ck90.html#source" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/HPND-export-US-acknowledgement.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/HPND-export-US-acknowledgement.json", "referenceNumber": 610, "name": "HPND with US Government export control warning and acknowledgment", "licenseId": "HPND-export-US-acknowledgement", "seeAlso": [ "https://github.com/krb5/krb5/blob/krb5-1.21.2-final/NOTICE#L831-L852", "https://web.mit.edu/kerberos/krb5-1.21/doc/mitK5license.html" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/HPND-export-US-modify.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/HPND-export-US-modify.json", "referenceNumber": 498, "name": "HPND with US Government export control warning and modification rqmt", "licenseId": "HPND-export-US-modify", "seeAlso": [ "https://github.com/krb5/krb5/blob/krb5-1.21.2-final/NOTICE#L1157-L1182", "https://github.com/pythongssapi/k5test/blob/v0.10.3/K5TEST-LICENSE.txt" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/HPND-export2-US.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/HPND-export2-US.json", "referenceNumber": 33, "name": "HPND with US Government export control and 2 disclaimers", "licenseId": "HPND-export2-US", "seeAlso": [ "https://github.com/krb5/krb5/blob/krb5-1.21.2-final/NOTICE#L111-L133", "https://web.mit.edu/kerberos/krb5-1.21/doc/mitK5license.html" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/HPND-Fenneberg-Livingston.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/HPND-Fenneberg-Livingston.json", "referenceNumber": 145, "name": "Historical Permission Notice and Disclaimer - Fenneberg-Livingston variant", "licenseId": "HPND-Fenneberg-Livingston", "seeAlso": [ "https://github.com/FreeRADIUS/freeradius-client/blob/master/COPYRIGHT#L32", "https://github.com/radcli/radcli/blob/master/COPYRIGHT#L34" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/HPND-INRIA-IMAG.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/HPND-INRIA-IMAG.json", "referenceNumber": 614, "name": "Historical Permission Notice and Disclaimer - INRIA-IMAG variant", "licenseId": "HPND-INRIA-IMAG", "seeAlso": [ "https://github.com/ppp-project/ppp/blob/master/pppd/ipv6cp.c#L75-L83" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/HPND-Intel.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/HPND-Intel.json", "referenceNumber": 195, "name": "Historical Permission Notice and Disclaimer - Intel variant", "licenseId": "HPND-Intel", "seeAlso": [ "https://sourceware.org/git/?p\u003dnewlib-cygwin.git;a\u003dblob;f\u003dnewlib/libc/machine/i960/memcpy.S;hb\u003dHEAD" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/HPND-Kevlin-Henney.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/HPND-Kevlin-Henney.json", "referenceNumber": 428, "name": "Historical Permission Notice and Disclaimer - Kevlin Henney variant", "licenseId": "HPND-Kevlin-Henney", "seeAlso": [ "https://github.com/mruby/mruby/blob/83d12f8d52522cdb7c8cc46fad34821359f453e6/mrbgems/mruby-dir/src/Win/dirent.c#L127-L140" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/HPND-Markus-Kuhn.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/HPND-Markus-Kuhn.json", "referenceNumber": 8, "name": "Historical Permission Notice and Disclaimer - Markus Kuhn variant", "licenseId": "HPND-Markus-Kuhn", "seeAlso": [ "https://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c", "https://sourceware.org/git/?p\u003dbinutils-gdb.git;a\u003dblob;f\u003dreadline/readline/support/wcwidth.c;h\u003d0f5ec995796f4813abbcf4972aec0378ab74722a;hb\u003dHEAD#l55" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/HPND-merchantability-variant.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/HPND-merchantability-variant.json", "referenceNumber": 540, "name": "Historical Permission Notice and Disclaimer - merchantability variant", "licenseId": "HPND-merchantability-variant", "seeAlso": [ "https://sourceware.org/git/?p\u003dnewlib-cygwin.git;a\u003dblob;f\u003dnewlib/libc/misc/fini.c;hb\u003dHEAD" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/HPND-MIT-disclaimer.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/HPND-MIT-disclaimer.json", "referenceNumber": 185, "name": "Historical Permission Notice and Disclaimer with MIT disclaimer", "licenseId": "HPND-MIT-disclaimer", "seeAlso": [ "https://metacpan.org/release/NLNETLABS/Net-DNS-SEC-1.22/source/LICENSE" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/HPND-Pbmplus.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/HPND-Pbmplus.json", "referenceNumber": 603, "name": "Historical Permission Notice and Disclaimer - Pbmplus variant", "licenseId": "HPND-Pbmplus", "seeAlso": [ "https://sourceforge.net/p/netpbm/code/HEAD/tree/super_stable/netpbm.c#l8" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/HPND-sell-MIT-disclaimer-xserver.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/HPND-sell-MIT-disclaimer-xserver.json", "referenceNumber": 125, "name": "Historical Permission Notice and Disclaimer - sell xserver variant with MIT disclaimer", "licenseId": "HPND-sell-MIT-disclaimer-xserver", "seeAlso": [ "https://gitlab.freedesktop.org/xorg/xserver/-/blob/master/COPYING?ref_type\u003dheads#L1781" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/HPND-sell-regexpr.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/HPND-sell-regexpr.json", "referenceNumber": 633, "name": "Historical Permission Notice and Disclaimer - sell regexpr variant", "licenseId": "HPND-sell-regexpr", "seeAlso": [ "https://gitlab.com/bacula-org/bacula/-/blob/Branch-11.0/bacula/LICENSE-FOSS?ref_type\u003dheads#L245" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/HPND-sell-variant.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/HPND-sell-variant.json", "referenceNumber": 344, "name": "Historical Permission Notice and Disclaimer - sell variant", "licenseId": "HPND-sell-variant", "seeAlso": [ "https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/net/sunrpc/auth_gss/gss_generic_token.c?h\u003dv4.19" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/HPND-sell-variant-MIT-disclaimer.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/HPND-sell-variant-MIT-disclaimer.json", "referenceNumber": 160, "name": "HPND sell variant with MIT disclaimer", "licenseId": "HPND-sell-variant-MIT-disclaimer", "seeAlso": [ "https://github.com/sigmavirus24/x11-ssh-askpass/blob/master/README" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/HPND-sell-variant-MIT-disclaimer-rev.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/HPND-sell-variant-MIT-disclaimer-rev.json", "referenceNumber": 609, "name": "HPND sell variant with MIT disclaimer - reverse", "licenseId": "HPND-sell-variant-MIT-disclaimer-rev", "seeAlso": [ "https://github.com/sigmavirus24/x11-ssh-askpass/blob/master/dynlist.c" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/HPND-UC.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/HPND-UC.json", "referenceNumber": 386, "name": "Historical Permission Notice and Disclaimer - University of California variant", "licenseId": "HPND-UC", "seeAlso": [ "https://core.tcl-lang.org/tk/file?name\u003dcompat/unistd.h" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/HPND-UC-export-US.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/HPND-UC-export-US.json", "referenceNumber": 118, "name": "Historical Permission Notice and Disclaimer - University of California, US export warning", "licenseId": "HPND-UC-export-US", "seeAlso": [ "https://github.com/RTimothyEdwards/magic/blob/master/LICENSE" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/HTMLTIDY.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/HTMLTIDY.json", "referenceNumber": 134, "name": "HTML Tidy License", "licenseId": "HTMLTIDY", "seeAlso": [ "https://github.com/htacg/tidy-html5/blob/next/README/LICENSE.md" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/IBM-pibs.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/IBM-pibs.json", "referenceNumber": 102, "name": "IBM PowerPC Initialization and Boot Software", "licenseId": "IBM-pibs", "seeAlso": [ "http://git.denx.de/?p\u003du-boot.git;a\u003dblob;f\u003darch/powerpc/cpu/ppc4xx/miiphy.c;h\u003d297155fdafa064b955e53e9832de93bfb0cfb85b;hb\u003d9fab4bf4cc077c21e43941866f3f2c196f28670d" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/ICU.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/ICU.json", "referenceNumber": 67, "name": "ICU License", "licenseId": "ICU", "seeAlso": [ "http://source.icu-project.org/repos/icu/icu/trunk/license.html" ], "isOsiApproved": true }, { "reference": "https://spdx.org/licenses/IEC-Code-Components-EULA.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/IEC-Code-Components-EULA.json", "referenceNumber": 359, "name": "IEC Code Components End-user licence agreement", "licenseId": "IEC-Code-Components-EULA", "seeAlso": [ "https://www.iec.ch/webstore/custserv/pdf/CC-EULA.pdf", "https://www.iec.ch/CCv1", "https://www.iec.ch/copyright" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/IJG.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/IJG.json", "referenceNumber": 641, "name": "Independent JPEG Group License", "licenseId": "IJG", "seeAlso": [ "http://dev.w3.org/cvsweb/Amaya/libjpeg/Attic/README?rev\u003d1.2" ], "isOsiApproved": false, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/IJG-short.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/IJG-short.json", "referenceNumber": 615, "name": "Independent JPEG Group License - short", "licenseId": "IJG-short", "seeAlso": [ "https://sourceforge.net/p/xmedcon/code/ci/master/tree/libs/ljpg/" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/ImageMagick.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/ImageMagick.json", "referenceNumber": 478, "name": "ImageMagick License", "licenseId": "ImageMagick", "seeAlso": [ "http://www.imagemagick.org/script/license.php" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/iMatix.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/iMatix.json", "referenceNumber": 327, "name": "iMatix Standard Function Library Agreement", "licenseId": "iMatix", "seeAlso": [ "http://legacy.imatix.com/html/sfl/sfl4.htm#license" ], "isOsiApproved": false, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/Imlib2.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Imlib2.json", "referenceNumber": 169, "name": "Imlib2 License", "licenseId": "Imlib2", "seeAlso": [ "http://trac.enlightenment.org/e/browser/trunk/imlib2/COPYING", "https://git.enlightenment.org/legacy/imlib2.git/tree/COPYING" ], "isOsiApproved": false, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/Info-ZIP.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Info-ZIP.json", "referenceNumber": 269, "name": "Info-ZIP License", "licenseId": "Info-ZIP", "seeAlso": [ "http://www.info-zip.org/license.html" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/Inner-Net-2.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Inner-Net-2.0.json", "referenceNumber": 572, "name": "Inner Net License v2.0", "licenseId": "Inner-Net-2.0", "seeAlso": [ "https://fedoraproject.org/wiki/Licensing/Inner_Net_License", "https://sourceware.org/git/?p\u003dglibc.git;a\u003dblob;f\u003dLICENSES;h\u003d530893b1dc9ea00755603c68fb36bd4fc38a7be8;hb\u003dHEAD#l207" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/Intel.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Intel.json", "referenceNumber": 623, "name": "Intel Open Source License", "licenseId": "Intel", "seeAlso": [ "https://opensource.org/licenses/Intel" ], "isOsiApproved": true, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/Intel-ACPI.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Intel-ACPI.json", "referenceNumber": 571, "name": "Intel ACPI Software License Agreement", "licenseId": "Intel-ACPI", "seeAlso": [ "https://fedoraproject.org/wiki/Licensing/Intel_ACPI_Software_License_Agreement" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/Interbase-1.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Interbase-1.0.json", "referenceNumber": 654, "name": "Interbase Public License v1.0", "licenseId": "Interbase-1.0", "seeAlso": [ "https://web.archive.org/web/20060319014854/http://info.borland.com/devsupport/interbase/opensource/IPL.html" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/IPA.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/IPA.json", "referenceNumber": 94, "name": "IPA Font License", "licenseId": "IPA", "seeAlso": [ "https://opensource.org/licenses/IPA" ], "isOsiApproved": true, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/IPL-1.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/IPL-1.0.json", "referenceNumber": 332, "name": "IBM Public License v1.0", "licenseId": "IPL-1.0", "seeAlso": [ "https://opensource.org/licenses/IPL-1.0" ], "isOsiApproved": true, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/ISC.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/ISC.json", "referenceNumber": 488, "name": "ISC License", "licenseId": "ISC", "seeAlso": [ "https://www.isc.org/licenses/", "https://www.isc.org/downloads/software-support-policy/isc-license/", "https://opensource.org/licenses/ISC" ], "isOsiApproved": true, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/ISC-Veillard.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/ISC-Veillard.json", "referenceNumber": 513, "name": "ISC Veillard variant", "licenseId": "ISC-Veillard", "seeAlso": [ "https://raw.githubusercontent.com/GNOME/libxml2/4c2e7c651f6c2f0d1a74f350cbda95f7df3e7017/hash.c", "https://github.com/GNOME/libxml2/blob/master/dict.c", "https://sourceforge.net/p/ctrio/git/ci/master/tree/README" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/Jam.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Jam.json", "referenceNumber": 108, "name": "Jam License", "licenseId": "Jam", "seeAlso": [ "https://www.boost.org/doc/libs/1_35_0/doc/html/jam.html", "https://web.archive.org/web/20160330173339/https://swarm.workshop.perforce.com/files/guest/perforce_software/jam/src/README" ], "isOsiApproved": true }, { "reference": "https://spdx.org/licenses/JasPer-2.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/JasPer-2.0.json", "referenceNumber": 487, "name": "JasPer License", "licenseId": "JasPer-2.0", "seeAlso": [ "http://www.ece.uvic.ca/~mdadams/jasper/LICENSE" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/JPL-image.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/JPL-image.json", "referenceNumber": 363, "name": "JPL Image Use Policy", "licenseId": "JPL-image", "seeAlso": [ "https://www.jpl.nasa.gov/jpl-image-use-policy" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/JPNIC.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/JPNIC.json", "referenceNumber": 83, "name": "Japan Network Information Center License", "licenseId": "JPNIC", "seeAlso": [ "https://gitlab.isc.org/isc-projects/bind9/blob/master/COPYRIGHT#L366" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/JSON.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/JSON.json", "referenceNumber": 65, "name": "JSON License", "licenseId": "JSON", "seeAlso": [ "http://www.json.org/license.html" ], "isOsiApproved": false, "isFsfLibre": false }, { "reference": "https://spdx.org/licenses/Kastrup.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Kastrup.json", "referenceNumber": 226, "name": "Kastrup License", "licenseId": "Kastrup", "seeAlso": [ "https://ctan.math.utah.edu/ctan/tex-archive/macros/generic/kastrup/binhex.dtx" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/Kazlib.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Kazlib.json", "referenceNumber": 232, "name": "Kazlib License", "licenseId": "Kazlib", "seeAlso": [ "http://git.savannah.gnu.org/cgit/kazlib.git/tree/except.c?id\u003d0062df360c2d17d57f6af19b0e444c51feb99036" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/Knuth-CTAN.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Knuth-CTAN.json", "referenceNumber": 290, "name": "Knuth CTAN License", "licenseId": "Knuth-CTAN", "seeAlso": [ "https://ctan.org/license/knuth" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/LAL-1.2.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/LAL-1.2.json", "referenceNumber": 165, "name": "Licence Art Libre 1.2", "licenseId": "LAL-1.2", "seeAlso": [ "http://artlibre.org/licence/lal/licence-art-libre-12/" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/LAL-1.3.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/LAL-1.3.json", "referenceNumber": 600, "name": "Licence Art Libre 1.3", "licenseId": "LAL-1.3", "seeAlso": [ "https://artlibre.org/" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/Latex2e.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Latex2e.json", "referenceNumber": 439, "name": "Latex2e License", "licenseId": "Latex2e", "seeAlso": [ "https://fedoraproject.org/wiki/Licensing/Latex2e" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/Latex2e-translated-notice.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Latex2e-translated-notice.json", "referenceNumber": 620, "name": "Latex2e with translated notice permission", "licenseId": "Latex2e-translated-notice", "seeAlso": [ "https://git.savannah.gnu.org/cgit/indent.git/tree/doc/indent.texi?id\u003da74c6b4ee49397cf330b333da1042bffa60ed14f#n74" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/Leptonica.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Leptonica.json", "referenceNumber": 103, "name": "Leptonica License", "licenseId": "Leptonica", "seeAlso": [ "https://fedoraproject.org/wiki/Licensing/Leptonica" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/LGPL-2.0.html", "isDeprecatedLicenseId": true, "detailsUrl": "https://spdx.org/licenses/LGPL-2.0.json", "referenceNumber": 353, "name": "GNU Library General Public License v2 only", "licenseId": "LGPL-2.0", "seeAlso": [ "https://www.gnu.org/licenses/old-licenses/lgpl-2.0-standalone.html" ], "isOsiApproved": true }, { "reference": "https://spdx.org/licenses/LGPL-2.0+.html", "isDeprecatedLicenseId": true, "detailsUrl": "https://spdx.org/licenses/LGPL-2.0+.json", "referenceNumber": 62, "name": "GNU Library General Public License v2 or later", "licenseId": "LGPL-2.0+", "seeAlso": [ "https://www.gnu.org/licenses/old-licenses/lgpl-2.0-standalone.html" ], "isOsiApproved": true }, { "reference": "https://spdx.org/licenses/LGPL-2.0-only.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/LGPL-2.0-only.json", "referenceNumber": 519, "name": "GNU Library General Public License v2 only", "licenseId": "LGPL-2.0-only", "seeAlso": [ "https://www.gnu.org/licenses/old-licenses/lgpl-2.0-standalone.html" ], "isOsiApproved": true }, { "reference": "https://spdx.org/licenses/LGPL-2.0-or-later.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/LGPL-2.0-or-later.json", "referenceNumber": 366, "name": "GNU Library General Public License v2 or later", "licenseId": "LGPL-2.0-or-later", "seeAlso": [ "https://www.gnu.org/licenses/old-licenses/lgpl-2.0-standalone.html" ], "isOsiApproved": true }, { "reference": "https://spdx.org/licenses/LGPL-2.1.html", "isDeprecatedLicenseId": true, "detailsUrl": "https://spdx.org/licenses/LGPL-2.1.json", "referenceNumber": 656, "name": "GNU Lesser General Public License v2.1 only", "licenseId": "LGPL-2.1", "seeAlso": [ "https://www.gnu.org/licenses/old-licenses/lgpl-2.1-standalone.html", "https://opensource.org/licenses/LGPL-2.1" ], "isOsiApproved": true, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/LGPL-2.1+.html", "isDeprecatedLicenseId": true, "detailsUrl": "https://spdx.org/licenses/LGPL-2.1+.json", "referenceNumber": 64, "name": "GNU Lesser General Public License v2.1 or later", "licenseId": "LGPL-2.1+", "seeAlso": [ "https://www.gnu.org/licenses/old-licenses/lgpl-2.1-standalone.html", "https://opensource.org/licenses/LGPL-2.1" ], "isOsiApproved": true, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/LGPL-2.1-only.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/LGPL-2.1-only.json", "referenceNumber": 177, "name": "GNU Lesser General Public License v2.1 only", "licenseId": "LGPL-2.1-only", "seeAlso": [ "https://www.gnu.org/licenses/old-licenses/lgpl-2.1-standalone.html", "https://opensource.org/licenses/LGPL-2.1" ], "isOsiApproved": true, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/LGPL-2.1-or-later.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/LGPL-2.1-or-later.json", "referenceNumber": 24, "name": "GNU Lesser General Public License v2.1 or later", "licenseId": "LGPL-2.1-or-later", "seeAlso": [ "https://www.gnu.org/licenses/old-licenses/lgpl-2.1-standalone.html", "https://opensource.org/licenses/LGPL-2.1" ], "isOsiApproved": true, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/LGPL-3.0.html", "isDeprecatedLicenseId": true, "detailsUrl": "https://spdx.org/licenses/LGPL-3.0.json", "referenceNumber": 578, "name": "GNU Lesser General Public License v3.0 only", "licenseId": "LGPL-3.0", "seeAlso": [ "https://www.gnu.org/licenses/lgpl-3.0-standalone.html", "https://www.gnu.org/licenses/lgpl+gpl-3.0.txt", "https://opensource.org/licenses/LGPL-3.0" ], "isOsiApproved": true, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/LGPL-3.0+.html", "isDeprecatedLicenseId": true, "detailsUrl": "https://spdx.org/licenses/LGPL-3.0+.json", "referenceNumber": 233, "name": "GNU Lesser General Public License v3.0 or later", "licenseId": "LGPL-3.0+", "seeAlso": [ "https://www.gnu.org/licenses/lgpl-3.0-standalone.html", "https://www.gnu.org/licenses/lgpl+gpl-3.0.txt", "https://opensource.org/licenses/LGPL-3.0" ], "isOsiApproved": true, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/LGPL-3.0-only.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/LGPL-3.0-only.json", "referenceNumber": 3, "name": "GNU Lesser General Public License v3.0 only", "licenseId": "LGPL-3.0-only", "seeAlso": [ "https://www.gnu.org/licenses/lgpl-3.0-standalone.html", "https://www.gnu.org/licenses/lgpl+gpl-3.0.txt", "https://opensource.org/licenses/LGPL-3.0" ], "isOsiApproved": true, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/LGPL-3.0-or-later.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/LGPL-3.0-or-later.json", "referenceNumber": 262, "name": "GNU Lesser General Public License v3.0 or later", "licenseId": "LGPL-3.0-or-later", "seeAlso": [ "https://www.gnu.org/licenses/lgpl-3.0-standalone.html", "https://www.gnu.org/licenses/lgpl+gpl-3.0.txt", "https://opensource.org/licenses/LGPL-3.0" ], "isOsiApproved": true, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/LGPLLR.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/LGPLLR.json", "referenceNumber": 477, "name": "Lesser General Public License For Linguistic Resources", "licenseId": "LGPLLR", "seeAlso": [ "http://www-igm.univ-mlv.fr/~unitex/lgpllr.html" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/Libpng.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Libpng.json", "referenceNumber": 186, "name": "libpng License", "licenseId": "Libpng", "seeAlso": [ "http://www.libpng.org/pub/png/src/libpng-LICENSE.txt" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/libpng-2.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/libpng-2.0.json", "referenceNumber": 257, "name": "PNG Reference Library version 2", "licenseId": "libpng-2.0", "seeAlso": [ "http://www.libpng.org/pub/png/src/libpng-LICENSE.txt" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/libselinux-1.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/libselinux-1.0.json", "referenceNumber": 556, "name": "libselinux public domain notice", "licenseId": "libselinux-1.0", "seeAlso": [ "https://github.com/SELinuxProject/selinux/blob/master/libselinux/LICENSE" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/libtiff.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/libtiff.json", "referenceNumber": 392, "name": "libtiff License", "licenseId": "libtiff", "seeAlso": [ "https://fedoraproject.org/wiki/Licensing/libtiff" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/libutil-David-Nugent.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/libutil-David-Nugent.json", "referenceNumber": 400, "name": "libutil David Nugent License", "licenseId": "libutil-David-Nugent", "seeAlso": [ "http://web.mit.edu/freebsd/head/lib/libutil/login_ok.3", "https://cgit.freedesktop.org/libbsd/tree/man/setproctitle.3bsd" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/LiLiQ-P-1.1.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/LiLiQ-P-1.1.json", "referenceNumber": 43, "name": "Licence Libre du Québec – Permissive version 1.1", "licenseId": "LiLiQ-P-1.1", "seeAlso": [ "https://forge.gouv.qc.ca/licence/fr/liliq-v1-1/", "http://opensource.org/licenses/LiLiQ-P-1.1" ], "isOsiApproved": true }, { "reference": "https://spdx.org/licenses/LiLiQ-R-1.1.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/LiLiQ-R-1.1.json", "referenceNumber": 74, "name": "Licence Libre du Québec – Réciprocité version 1.1", "licenseId": "LiLiQ-R-1.1", "seeAlso": [ "https://www.forge.gouv.qc.ca/participez/licence-logicielle/licence-libre-du-quebec-liliq-en-francais/licence-libre-du-quebec-reciprocite-liliq-r-v1-1/", "http://opensource.org/licenses/LiLiQ-R-1.1" ], "isOsiApproved": true }, { "reference": "https://spdx.org/licenses/LiLiQ-Rplus-1.1.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/LiLiQ-Rplus-1.1.json", "referenceNumber": 40, "name": "Licence Libre du Québec – Réciprocité forte version 1.1", "licenseId": "LiLiQ-Rplus-1.1", "seeAlso": [ "https://www.forge.gouv.qc.ca/participez/licence-logicielle/licence-libre-du-quebec-liliq-en-francais/licence-libre-du-quebec-reciprocite-forte-liliq-r-v1-1/", "http://opensource.org/licenses/LiLiQ-Rplus-1.1" ], "isOsiApproved": true }, { "reference": "https://spdx.org/licenses/Linux-man-pages-1-para.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Linux-man-pages-1-para.json", "referenceNumber": 339, "name": "Linux man-pages - 1 paragraph", "licenseId": "Linux-man-pages-1-para", "seeAlso": [ "https://git.kernel.org/pub/scm/docs/man-pages/man-pages.git/tree/man2/getcpu.2#n4" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/Linux-man-pages-copyleft.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Linux-man-pages-copyleft.json", "referenceNumber": 590, "name": "Linux man-pages Copyleft", "licenseId": "Linux-man-pages-copyleft", "seeAlso": [ "https://www.kernel.org/doc/man-pages/licenses.html" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/Linux-man-pages-copyleft-2-para.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Linux-man-pages-copyleft-2-para.json", "referenceNumber": 86, "name": "Linux man-pages Copyleft - 2 paragraphs", "licenseId": "Linux-man-pages-copyleft-2-para", "seeAlso": [ "https://git.kernel.org/pub/scm/docs/man-pages/man-pages.git/tree/man2/move_pages.2#n5", "https://git.kernel.org/pub/scm/docs/man-pages/man-pages.git/tree/man2/migrate_pages.2#n8" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/Linux-man-pages-copyleft-var.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Linux-man-pages-copyleft-var.json", "referenceNumber": 337, "name": "Linux man-pages Copyleft Variant", "licenseId": "Linux-man-pages-copyleft-var", "seeAlso": [ "https://git.kernel.org/pub/scm/docs/man-pages/man-pages.git/tree/man2/set_mempolicy.2#n5" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/Linux-OpenIB.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Linux-OpenIB.json", "referenceNumber": 613, "name": "Linux Kernel Variant of OpenIB.org license", "licenseId": "Linux-OpenIB", "seeAlso": [ "https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/infiniband/core/sa.h" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/LOOP.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/LOOP.json", "referenceNumber": 607, "name": "Common Lisp LOOP License", "licenseId": "LOOP", "seeAlso": [ "https://gitlab.com/embeddable-common-lisp/ecl/-/blob/develop/src/lsp/loop.lsp", "http://git.savannah.gnu.org/cgit/gcl.git/tree/gcl/lsp/gcl_loop.lsp?h\u003dVersion_2_6_13pre", "https://sourceforge.net/p/sbcl/sbcl/ci/master/tree/src/code/loop.lisp", "https://github.com/cl-adams/adams/blob/master/LICENSE.md", "https://github.com/blakemcbride/eclipse-lisp/blob/master/lisp/loop.lisp", "https://gitlab.common-lisp.net/cmucl/cmucl/-/blob/master/src/code/loop.lisp" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/LPD-document.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/LPD-document.json", "referenceNumber": 522, "name": "LPD Documentation License", "licenseId": "LPD-document", "seeAlso": [ "https://github.com/Cyan4973/xxHash/blob/dev/doc/xxhash_spec.md", "https://www.ietf.org/rfc/rfc1952.txt" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/LPL-1.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/LPL-1.0.json", "referenceNumber": 196, "name": "Lucent Public License Version 1.0", "licenseId": "LPL-1.0", "seeAlso": [ "https://opensource.org/licenses/LPL-1.0" ], "isOsiApproved": true }, { "reference": "https://spdx.org/licenses/LPL-1.02.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/LPL-1.02.json", "referenceNumber": 69, "name": "Lucent Public License v1.02", "licenseId": "LPL-1.02", "seeAlso": [ "http://plan9.bell-labs.com/plan9/license.html", "https://opensource.org/licenses/LPL-1.02" ], "isOsiApproved": true, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/LPPL-1.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/LPPL-1.0.json", "referenceNumber": 215, "name": "LaTeX Project Public License v1.0", "licenseId": "LPPL-1.0", "seeAlso": [ "http://www.latex-project.org/lppl/lppl-1-0.txt" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/LPPL-1.1.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/LPPL-1.1.json", "referenceNumber": 114, "name": "LaTeX Project Public License v1.1", "licenseId": "LPPL-1.1", "seeAlso": [ "http://www.latex-project.org/lppl/lppl-1-1.txt" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/LPPL-1.2.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/LPPL-1.2.json", "referenceNumber": 435, "name": "LaTeX Project Public License v1.2", "licenseId": "LPPL-1.2", "seeAlso": [ "http://www.latex-project.org/lppl/lppl-1-2.txt" ], "isOsiApproved": false, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/LPPL-1.3a.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/LPPL-1.3a.json", "referenceNumber": 18, "name": "LaTeX Project Public License v1.3a", "licenseId": "LPPL-1.3a", "seeAlso": [ "http://www.latex-project.org/lppl/lppl-1-3a.txt" ], "isOsiApproved": false, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/LPPL-1.3c.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/LPPL-1.3c.json", "referenceNumber": 240, "name": "LaTeX Project Public License v1.3c", "licenseId": "LPPL-1.3c", "seeAlso": [ "http://www.latex-project.org/lppl/lppl-1-3c.txt", "https://opensource.org/licenses/LPPL-1.3c" ], "isOsiApproved": true }, { "reference": "https://spdx.org/licenses/lsof.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/lsof.json", "referenceNumber": 605, "name": "lsof License", "licenseId": "lsof", "seeAlso": [ "https://github.com/lsof-org/lsof/blob/master/COPYING" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/Lucida-Bitmap-Fonts.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Lucida-Bitmap-Fonts.json", "referenceNumber": 399, "name": "Lucida Bitmap Fonts License", "licenseId": "Lucida-Bitmap-Fonts", "seeAlso": [ "https://gitlab.freedesktop.org/xorg/font/bh-100dpi/-/blob/master/COPYING?ref_type\u003dheads" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/LZMA-SDK-9.11-to-9.20.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/LZMA-SDK-9.11-to-9.20.json", "referenceNumber": 430, "name": "LZMA SDK License (versions 9.11 to 9.20)", "licenseId": "LZMA-SDK-9.11-to-9.20", "seeAlso": [ "https://www.7-zip.org/sdk.html", "https://sourceforge.net/projects/sevenzip/files/LZMA%20SDK/" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/LZMA-SDK-9.22.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/LZMA-SDK-9.22.json", "referenceNumber": 244, "name": "LZMA SDK License (versions 9.22 and beyond)", "licenseId": "LZMA-SDK-9.22", "seeAlso": [ "https://www.7-zip.org/sdk.html", "https://sourceforge.net/projects/sevenzip/files/LZMA%20SDK/" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/Mackerras-3-Clause.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Mackerras-3-Clause.json", "referenceNumber": 59, "name": "Mackerras 3-Clause License", "licenseId": "Mackerras-3-Clause", "seeAlso": [ "https://github.com/ppp-project/ppp/blob/master/pppd/chap_ms.c#L6-L28" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/Mackerras-3-Clause-acknowledgment.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Mackerras-3-Clause-acknowledgment.json", "referenceNumber": 598, "name": "Mackerras 3-Clause - acknowledgment variant", "licenseId": "Mackerras-3-Clause-acknowledgment", "seeAlso": [ "https://github.com/ppp-project/ppp/blob/master/pppd/auth.c#L6-L28" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/magaz.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/magaz.json", "referenceNumber": 516, "name": "magaz License", "licenseId": "magaz", "seeAlso": [ "https://mirrors.nic.cz/tex-archive/macros/latex/contrib/magaz/magaz.tex" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/mailprio.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/mailprio.json", "referenceNumber": 179, "name": "mailprio License", "licenseId": "mailprio", "seeAlso": [ "https://fossies.org/linux/sendmail/contrib/mailprio" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/MakeIndex.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/MakeIndex.json", "referenceNumber": 206, "name": "MakeIndex License", "licenseId": "MakeIndex", "seeAlso": [ "https://fedoraproject.org/wiki/Licensing/MakeIndex" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/Martin-Birgmeier.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Martin-Birgmeier.json", "referenceNumber": 535, "name": "Martin Birgmeier License", "licenseId": "Martin-Birgmeier", "seeAlso": [ "https://github.com/Perl/perl5/blob/blead/util.c#L6136" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/McPhee-slideshow.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/McPhee-slideshow.json", "referenceNumber": 492, "name": "McPhee Slideshow License", "licenseId": "McPhee-slideshow", "seeAlso": [ "https://mirror.las.iastate.edu/tex-archive/graphics/metapost/contrib/macros/slideshow/slideshow.mp" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/metamail.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/metamail.json", "referenceNumber": 437, "name": "metamail License", "licenseId": "metamail", "seeAlso": [ "https://github.com/Dual-Life/mime-base64/blob/master/Base64.xs#L12" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/Minpack.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Minpack.json", "referenceNumber": 512, "name": "Minpack License", "licenseId": "Minpack", "seeAlso": [ "http://www.netlib.org/minpack/disclaimer", "https://gitlab.com/libeigen/eigen/-/blob/master/COPYING.MINPACK" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/MirOS.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/MirOS.json", "referenceNumber": 183, "name": "The MirOS Licence", "licenseId": "MirOS", "seeAlso": [ "https://opensource.org/licenses/MirOS" ], "isOsiApproved": true }, { "reference": "https://spdx.org/licenses/MIT.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/MIT.json", "referenceNumber": 608, "name": "MIT License", "licenseId": "MIT", "seeAlso": [ "https://opensource.org/license/mit/" ], "isOsiApproved": true, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/MIT-0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/MIT-0.json", "referenceNumber": 395, "name": "MIT No Attribution", "licenseId": "MIT-0", "seeAlso": [ "https://github.com/aws/mit-0", "https://romanrm.net/mit-zero", "https://github.com/awsdocs/aws-cloud9-user-guide/blob/master/LICENSE-SAMPLECODE" ], "isOsiApproved": true }, { "reference": "https://spdx.org/licenses/MIT-advertising.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/MIT-advertising.json", "referenceNumber": 293, "name": "Enlightenment License (e16)", "licenseId": "MIT-advertising", "seeAlso": [ "https://fedoraproject.org/wiki/Licensing/MIT_With_Advertising" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/MIT-CMU.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/MIT-CMU.json", "referenceNumber": 575, "name": "CMU License", "licenseId": "MIT-CMU", "seeAlso": [ "https://fedoraproject.org/wiki/Licensing:MIT?rd\u003dLicensing/MIT#CMU_Style", "https://github.com/python-pillow/Pillow/blob/fffb426092c8db24a5f4b6df243a8a3c01fb63cd/LICENSE" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/MIT-enna.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/MIT-enna.json", "referenceNumber": 638, "name": "enna License", "licenseId": "MIT-enna", "seeAlso": [ "https://fedoraproject.org/wiki/Licensing/MIT#enna" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/MIT-feh.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/MIT-feh.json", "referenceNumber": 53, "name": "feh License", "licenseId": "MIT-feh", "seeAlso": [ "https://fedoraproject.org/wiki/Licensing/MIT#feh" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/MIT-Festival.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/MIT-Festival.json", "referenceNumber": 317, "name": "MIT Festival Variant", "licenseId": "MIT-Festival", "seeAlso": [ "https://github.com/festvox/flite/blob/master/COPYING", "https://github.com/festvox/speech_tools/blob/master/COPYING" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/MIT-Khronos-old.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/MIT-Khronos-old.json", "referenceNumber": 249, "name": "MIT Khronos - old variant", "licenseId": "MIT-Khronos-old", "seeAlso": [ "https://github.com/KhronosGroup/SPIRV-Cross/blob/main/LICENSES/LicenseRef-KhronosFreeUse.txt" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/MIT-Modern-Variant.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/MIT-Modern-Variant.json", "referenceNumber": 424, "name": "MIT License Modern Variant", "licenseId": "MIT-Modern-Variant", "seeAlso": [ "https://fedoraproject.org/wiki/Licensing:MIT#Modern_Variants", "https://ptolemy.berkeley.edu/copyright.htm", "https://pirlwww.lpl.arizona.edu/resources/guide/software/PerlTk/Tixlic.html" ], "isOsiApproved": true }, { "reference": "https://spdx.org/licenses/MIT-open-group.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/MIT-open-group.json", "referenceNumber": 283, "name": "MIT Open Group variant", "licenseId": "MIT-open-group", "seeAlso": [ "https://gitlab.freedesktop.org/xorg/app/iceauth/-/blob/master/COPYING", "https://gitlab.freedesktop.org/xorg/app/xvinfo/-/blob/master/COPYING", "https://gitlab.freedesktop.org/xorg/app/xsetroot/-/blob/master/COPYING", "https://gitlab.freedesktop.org/xorg/app/xauth/-/blob/master/COPYING" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/MIT-testregex.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/MIT-testregex.json", "referenceNumber": 427, "name": "MIT testregex Variant", "licenseId": "MIT-testregex", "seeAlso": [ "https://github.com/dotnet/runtime/blob/55e1ac7c07df62c4108d4acedf78f77574470ce5/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/AttRegexTests.cs#L12-L28" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/MIT-Wu.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/MIT-Wu.json", "referenceNumber": 459, "name": "MIT Tom Wu Variant", "licenseId": "MIT-Wu", "seeAlso": [ "https://github.com/chromium/octane/blob/master/crypto.js" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/MITNFA.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/MITNFA.json", "referenceNumber": 157, "name": "MIT +no-false-attribs license", "licenseId": "MITNFA", "seeAlso": [ "https://fedoraproject.org/wiki/Licensing/MITNFA" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/MMIXware.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/MMIXware.json", "referenceNumber": 474, "name": "MMIXware License", "licenseId": "MMIXware", "seeAlso": [ "https://gitlab.lrz.de/mmix/mmixware/-/blob/master/boilerplate.w" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/Motosoto.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Motosoto.json", "referenceNumber": 627, "name": "Motosoto License", "licenseId": "Motosoto", "seeAlso": [ "https://opensource.org/licenses/Motosoto" ], "isOsiApproved": true }, { "reference": "https://spdx.org/licenses/MPEG-SSG.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/MPEG-SSG.json", "referenceNumber": 417, "name": "MPEG Software Simulation", "licenseId": "MPEG-SSG", "seeAlso": [ "https://sourceforge.net/p/netpbm/code/HEAD/tree/super_stable/converter/ppm/ppmtompeg/jrevdct.c#l1189" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/mpi-permissive.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/mpi-permissive.json", "referenceNumber": 80, "name": "mpi Permissive License", "licenseId": "mpi-permissive", "seeAlso": [ "https://sources.debian.org/src/openmpi/4.1.0-10/ompi/debuggers/msgq_interface.h/?hl\u003d19#L19" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/mpich2.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/mpich2.json", "referenceNumber": 482, "name": "mpich2 License", "licenseId": "mpich2", "seeAlso": [ "https://fedoraproject.org/wiki/Licensing/MIT" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/MPL-1.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/MPL-1.0.json", "referenceNumber": 28, "name": "Mozilla Public License 1.0", "licenseId": "MPL-1.0", "seeAlso": [ "http://www.mozilla.org/MPL/MPL-1.0.html", "https://opensource.org/licenses/MPL-1.0" ], "isOsiApproved": true }, { "reference": "https://spdx.org/licenses/MPL-1.1.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/MPL-1.1.json", "referenceNumber": 619, "name": "Mozilla Public License 1.1", "licenseId": "MPL-1.1", "seeAlso": [ "http://www.mozilla.org/MPL/MPL-1.1.html", "https://opensource.org/licenses/MPL-1.1" ], "isOsiApproved": true, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/MPL-2.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/MPL-2.0.json", "referenceNumber": 263, "name": "Mozilla Public License 2.0", "licenseId": "MPL-2.0", "seeAlso": [ "https://www.mozilla.org/MPL/2.0/", "https://opensource.org/licenses/MPL-2.0" ], "isOsiApproved": true, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/MPL-2.0-no-copyleft-exception.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/MPL-2.0-no-copyleft-exception.json", "referenceNumber": 455, "name": "Mozilla Public License 2.0 (no copyleft exception)", "licenseId": "MPL-2.0-no-copyleft-exception", "seeAlso": [ "https://www.mozilla.org/MPL/2.0/", "https://opensource.org/licenses/MPL-2.0" ], "isOsiApproved": true }, { "reference": "https://spdx.org/licenses/mplus.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/mplus.json", "referenceNumber": 541, "name": "mplus Font License", "licenseId": "mplus", "seeAlso": [ "https://fedoraproject.org/wiki/Licensing:Mplus?rd\u003dLicensing/mplus" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/MS-LPL.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/MS-LPL.json", "referenceNumber": 528, "name": "Microsoft Limited Public License", "licenseId": "MS-LPL", "seeAlso": [ "https://www.openhub.net/licenses/mslpl", "https://github.com/gabegundy/atlserver/blob/master/License.txt", "https://en.wikipedia.org/wiki/Shared_Source_Initiative#Microsoft_Limited_Public_License_(Ms-LPL)" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/MS-PL.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/MS-PL.json", "referenceNumber": 499, "name": "Microsoft Public License", "licenseId": "MS-PL", "seeAlso": [ "http://www.microsoft.com/opensource/licenses.mspx", "https://opensource.org/licenses/MS-PL" ], "isOsiApproved": true, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/MS-RL.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/MS-RL.json", "referenceNumber": 343, "name": "Microsoft Reciprocal License", "licenseId": "MS-RL", "seeAlso": [ "http://www.microsoft.com/opensource/licenses.mspx", "https://opensource.org/licenses/MS-RL" ], "isOsiApproved": true, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/MTLL.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/MTLL.json", "referenceNumber": 137, "name": "Matrix Template Library License", "licenseId": "MTLL", "seeAlso": [ "https://fedoraproject.org/wiki/Licensing/Matrix_Template_Library_License" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/MulanPSL-1.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/MulanPSL-1.0.json", "referenceNumber": 107, "name": "Mulan Permissive Software License, Version 1", "licenseId": "MulanPSL-1.0", "seeAlso": [ "https://license.coscl.org.cn/MulanPSL/", "https://github.com/yuwenlong/longphp/blob/25dfb70cc2a466dc4bb55ba30901cbce08d164b5/LICENSE" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/MulanPSL-2.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/MulanPSL-2.0.json", "referenceNumber": 490, "name": "Mulan Permissive Software License, Version 2", "licenseId": "MulanPSL-2.0", "seeAlso": [ "https://license.coscl.org.cn/MulanPSL2" ], "isOsiApproved": true }, { "reference": "https://spdx.org/licenses/Multics.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Multics.json", "referenceNumber": 573, "name": "Multics License", "licenseId": "Multics", "seeAlso": [ "https://opensource.org/licenses/Multics" ], "isOsiApproved": true }, { "reference": "https://spdx.org/licenses/Mup.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Mup.json", "referenceNumber": 440, "name": "Mup License", "licenseId": "Mup", "seeAlso": [ "https://fedoraproject.org/wiki/Licensing/Mup" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/NAIST-2003.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/NAIST-2003.json", "referenceNumber": 104, "name": "Nara Institute of Science and Technology License (2003)", "licenseId": "NAIST-2003", "seeAlso": [ "https://enterprise.dejacode.com/licenses/public/naist-2003/#license-text", "https://github.com/nodejs/node/blob/4a19cc8947b1bba2b2d27816ec3d0edf9b28e503/LICENSE#L343" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/NASA-1.3.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/NASA-1.3.json", "referenceNumber": 127, "name": "NASA Open Source Agreement 1.3", "licenseId": "NASA-1.3", "seeAlso": [ "http://ti.arc.nasa.gov/opensource/nosa/", "https://opensource.org/licenses/NASA-1.3" ], "isOsiApproved": true, "isFsfLibre": false }, { "reference": "https://spdx.org/licenses/Naumen.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Naumen.json", "referenceNumber": 128, "name": "Naumen Public License", "licenseId": "Naumen", "seeAlso": [ "https://opensource.org/licenses/Naumen" ], "isOsiApproved": true }, { "reference": "https://spdx.org/licenses/NBPL-1.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/NBPL-1.0.json", "referenceNumber": 41, "name": "Net Boolean Public License v1", "licenseId": "NBPL-1.0", "seeAlso": [ "http://www.openldap.org/devel/gitweb.cgi?p\u003dopenldap.git;a\u003dblob;f\u003dLICENSE;hb\u003d37b4b3f6cc4bf34e1d3dec61e69914b9819d8894" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/NCBI-PD.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/NCBI-PD.json", "referenceNumber": 362, "name": "NCBI Public Domain Notice", "licenseId": "NCBI-PD", "seeAlso": [ "https://github.com/ncbi/sra-tools/blob/e8e5b6af4edc460156ad9ce5902d0779cffbf685/LICENSE", "https://github.com/ncbi/datasets/blob/0ea4cd16b61e5b799d9cc55aecfa016d6c9bd2bf/LICENSE.md", "https://github.com/ncbi/gprobe/blob/de64d30fee8b4c4013094d7d3139ea89b5dd1ace/LICENSE", "https://github.com/ncbi/egapx/blob/08930b9dec0c69b2d1a05e5153c7b95ef0a3eb0f/LICENSE", "https://github.com/ncbi/datasets/blob/master/LICENSE.md" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/NCGL-UK-2.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/NCGL-UK-2.0.json", "referenceNumber": 320, "name": "Non-Commercial Government Licence", "licenseId": "NCGL-UK-2.0", "seeAlso": [ "http://www.nationalarchives.gov.uk/doc/non-commercial-government-licence/version/2/" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/NCL.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/NCL.json", "referenceNumber": 153, "name": "NCL Source Code License", "licenseId": "NCL", "seeAlso": [ "https://gitlab.freedesktop.org/pipewire/pipewire/-/blob/master/src/modules/module-filter-chain/pffft.c?ref_type\u003dheads#L1-52" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/NCSA.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/NCSA.json", "referenceNumber": 557, "name": "University of Illinois/NCSA Open Source License", "licenseId": "NCSA", "seeAlso": [ "http://otm.illinois.edu/uiuc_openSource", "https://opensource.org/licenses/NCSA" ], "isOsiApproved": true, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/Net-SNMP.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Net-SNMP.json", "referenceNumber": 234, "name": "Net-SNMP License", "licenseId": "Net-SNMP", "seeAlso": [ "http://net-snmp.sourceforge.net/about/license.html" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/NetCDF.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/NetCDF.json", "referenceNumber": 503, "name": "NetCDF license", "licenseId": "NetCDF", "seeAlso": [ "http://www.unidata.ucar.edu/software/netcdf/copyright.html" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/Newsletr.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Newsletr.json", "referenceNumber": 412, "name": "Newsletr License", "licenseId": "Newsletr", "seeAlso": [ "https://fedoraproject.org/wiki/Licensing/Newsletr" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/NGPL.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/NGPL.json", "referenceNumber": 275, "name": "Nethack General Public License", "licenseId": "NGPL", "seeAlso": [ "https://opensource.org/licenses/NGPL" ], "isOsiApproved": true }, { "reference": "https://spdx.org/licenses/NICTA-1.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/NICTA-1.0.json", "referenceNumber": 311, "name": "NICTA Public Software License, Version 1.0", "licenseId": "NICTA-1.0", "seeAlso": [ "https://opensource.apple.com/source/mDNSResponder/mDNSResponder-320.10/mDNSPosix/nss_ReadMe.txt" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/NIST-PD.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/NIST-PD.json", "referenceNumber": 309, "name": "NIST Public Domain Notice", "licenseId": "NIST-PD", "seeAlso": [ "https://github.com/tcheneau/simpleRPL/blob/e645e69e38dd4e3ccfeceb2db8cba05b7c2e0cd3/LICENSE.txt", "https://github.com/tcheneau/Routing/blob/f09f46fcfe636107f22f2c98348188a65a135d98/README.md" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/NIST-PD-fallback.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/NIST-PD-fallback.json", "referenceNumber": 34, "name": "NIST Public Domain Notice with license fallback", "licenseId": "NIST-PD-fallback", "seeAlso": [ "https://github.com/usnistgov/jsip/blob/59700e6926cbe96c5cdae897d9a7d2656b42abe3/LICENSE", "https://github.com/usnistgov/fipy/blob/86aaa5c2ba2c6f1be19593c5986071cf6568cc34/LICENSE.rst" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/NIST-Software.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/NIST-Software.json", "referenceNumber": 76, "name": "NIST Software License", "licenseId": "NIST-Software", "seeAlso": [ "https://github.com/open-quantum-safe/liboqs/blob/40b01fdbb270f8614fde30e65d30e9da18c02393/src/common/rand/rand_nist.c#L1-L15" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/NLOD-1.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/NLOD-1.0.json", "referenceNumber": 565, "name": "Norwegian Licence for Open Government Data (NLOD) 1.0", "licenseId": "NLOD-1.0", "seeAlso": [ "http://data.norge.no/nlod/en/1.0" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/NLOD-2.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/NLOD-2.0.json", "referenceNumber": 483, "name": "Norwegian Licence for Open Government Data (NLOD) 2.0", "licenseId": "NLOD-2.0", "seeAlso": [ "http://data.norge.no/nlod/en/2.0" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/NLPL.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/NLPL.json", "referenceNumber": 71, "name": "No Limit Public License", "licenseId": "NLPL", "seeAlso": [ "https://fedoraproject.org/wiki/Licensing/NLPL" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/Nokia.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Nokia.json", "referenceNumber": 44, "name": "Nokia Open Source License", "licenseId": "Nokia", "seeAlso": [ "https://opensource.org/licenses/nokia" ], "isOsiApproved": true, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/NOSL.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/NOSL.json", "referenceNumber": 126, "name": "Netizen Open Source License", "licenseId": "NOSL", "seeAlso": [ "http://bits.netizen.com.au/licenses/NOSL/nosl.txt" ], "isOsiApproved": false, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/Noweb.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Noweb.json", "referenceNumber": 534, "name": "Noweb License", "licenseId": "Noweb", "seeAlso": [ "https://fedoraproject.org/wiki/Licensing/Noweb" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/NPL-1.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/NPL-1.0.json", "referenceNumber": 346, "name": "Netscape Public License v1.0", "licenseId": "NPL-1.0", "seeAlso": [ "http://www.mozilla.org/MPL/NPL/1.0/" ], "isOsiApproved": false, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/NPL-1.1.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/NPL-1.1.json", "referenceNumber": 418, "name": "Netscape Public License v1.1", "licenseId": "NPL-1.1", "seeAlso": [ "http://www.mozilla.org/MPL/NPL/1.1/" ], "isOsiApproved": false, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/NPOSL-3.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/NPOSL-3.0.json", "referenceNumber": 579, "name": "Non-Profit Open Software License 3.0", "licenseId": "NPOSL-3.0", "seeAlso": [ "https://opensource.org/licenses/NOSL3.0" ], "isOsiApproved": true }, { "reference": "https://spdx.org/licenses/NRL.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/NRL.json", "referenceNumber": 230, "name": "NRL License", "licenseId": "NRL", "seeAlso": [ "http://web.mit.edu/network/isakmp/nrllicense.html" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/NTP.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/NTP.json", "referenceNumber": 547, "name": "NTP License", "licenseId": "NTP", "seeAlso": [ "https://opensource.org/licenses/NTP" ], "isOsiApproved": true }, { "reference": "https://spdx.org/licenses/NTP-0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/NTP-0.json", "referenceNumber": 460, "name": "NTP No Attribution", "licenseId": "NTP-0", "seeAlso": [ "https://github.com/tytso/e2fsprogs/blob/master/lib/et/et_name.c" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/Nunit.html", "isDeprecatedLicenseId": true, "detailsUrl": "https://spdx.org/licenses/Nunit.json", "referenceNumber": 634, "name": "Nunit License", "licenseId": "Nunit", "seeAlso": [ "https://fedoraproject.org/wiki/Licensing/Nunit" ], "isOsiApproved": false, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/O-UDA-1.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/O-UDA-1.0.json", "referenceNumber": 191, "name": "Open Use of Data Agreement v1.0", "licenseId": "O-UDA-1.0", "seeAlso": [ "https://github.com/microsoft/Open-Use-of-Data-Agreement/blob/v1.0/O-UDA-1.0.md", "https://cdla.dev/open-use-of-data-agreement-v1-0/" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/OAR.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/OAR.json", "referenceNumber": 4, "name": "OAR License", "licenseId": "OAR", "seeAlso": [ "https://sourceware.org/git/?p\u003dnewlib-cygwin.git;a\u003dblob;f\u003dnewlib/libc/string/strsignal.c;hb\u003dHEAD#l35" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/OCCT-PL.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/OCCT-PL.json", "referenceNumber": 596, "name": "Open CASCADE Technology Public License", "licenseId": "OCCT-PL", "seeAlso": [ "http://www.opencascade.com/content/occt-public-license" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/OCLC-2.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/OCLC-2.0.json", "referenceNumber": 308, "name": "OCLC Research Public License 2.0", "licenseId": "OCLC-2.0", "seeAlso": [ "http://www.oclc.org/research/activities/software/license/v2final.htm", "https://opensource.org/licenses/OCLC-2.0" ], "isOsiApproved": true }, { "reference": "https://spdx.org/licenses/ODbL-1.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/ODbL-1.0.json", "referenceNumber": 243, "name": "Open Data Commons Open Database License v1.0", "licenseId": "ODbL-1.0", "seeAlso": [ "http://www.opendatacommons.org/licenses/odbl/1.0/", "https://opendatacommons.org/licenses/odbl/1-0/" ], "isOsiApproved": false, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/ODC-By-1.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/ODC-By-1.0.json", "referenceNumber": 7, "name": "Open Data Commons Attribution License v1.0", "licenseId": "ODC-By-1.0", "seeAlso": [ "https://opendatacommons.org/licenses/by/1.0/" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/OFFIS.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/OFFIS.json", "referenceNumber": 238, "name": "OFFIS License", "licenseId": "OFFIS", "seeAlso": [ "https://sourceforge.net/p/xmedcon/code/ci/master/tree/libs/dicom/README" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/OFL-1.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/OFL-1.0.json", "referenceNumber": 475, "name": "SIL Open Font License 1.0", "licenseId": "OFL-1.0", "seeAlso": [ "http://scripts.sil.org/cms/scripts/page.php?item_id\u003dOFL10_web" ], "isOsiApproved": false, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/OFL-1.0-no-RFN.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/OFL-1.0-no-RFN.json", "referenceNumber": 23, "name": "SIL Open Font License 1.0 with no Reserved Font Name", "licenseId": "OFL-1.0-no-RFN", "seeAlso": [ "http://scripts.sil.org/cms/scripts/page.php?item_id\u003dOFL10_web" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/OFL-1.0-RFN.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/OFL-1.0-RFN.json", "referenceNumber": 11, "name": "SIL Open Font License 1.0 with Reserved Font Name", "licenseId": "OFL-1.0-RFN", "seeAlso": [ "http://scripts.sil.org/cms/scripts/page.php?item_id\u003dOFL10_web" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/OFL-1.1.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/OFL-1.1.json", "referenceNumber": 248, "name": "SIL Open Font License 1.1", "licenseId": "OFL-1.1", "seeAlso": [ "http://scripts.sil.org/cms/scripts/page.php?item_id\u003dOFL_web", "https://opensource.org/licenses/OFL-1.1" ], "isOsiApproved": true, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/OFL-1.1-no-RFN.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/OFL-1.1-no-RFN.json", "referenceNumber": 550, "name": "SIL Open Font License 1.1 with no Reserved Font Name", "licenseId": "OFL-1.1-no-RFN", "seeAlso": [ "http://scripts.sil.org/cms/scripts/page.php?item_id\u003dOFL_web", "https://opensource.org/licenses/OFL-1.1" ], "isOsiApproved": true }, { "reference": "https://spdx.org/licenses/OFL-1.1-RFN.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/OFL-1.1-RFN.json", "referenceNumber": 507, "name": "SIL Open Font License 1.1 with Reserved Font Name", "licenseId": "OFL-1.1-RFN", "seeAlso": [ "http://scripts.sil.org/cms/scripts/page.php?item_id\u003dOFL_web", "https://opensource.org/licenses/OFL-1.1" ], "isOsiApproved": true }, { "reference": "https://spdx.org/licenses/OGC-1.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/OGC-1.0.json", "referenceNumber": 166, "name": "OGC Software License, Version 1.0", "licenseId": "OGC-1.0", "seeAlso": [ "https://www.ogc.org/ogc/software/1.0" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/OGDL-Taiwan-1.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/OGDL-Taiwan-1.0.json", "referenceNumber": 468, "name": "Taiwan Open Government Data License, version 1.0", "licenseId": "OGDL-Taiwan-1.0", "seeAlso": [ "https://data.gov.tw/license" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/OGL-Canada-2.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/OGL-Canada-2.0.json", "referenceNumber": 464, "name": "Open Government Licence - Canada", "licenseId": "OGL-Canada-2.0", "seeAlso": [ "https://open.canada.ca/en/open-government-licence-canada" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/OGL-UK-1.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/OGL-UK-1.0.json", "referenceNumber": 489, "name": "Open Government Licence v1.0", "licenseId": "OGL-UK-1.0", "seeAlso": [ "http://www.nationalarchives.gov.uk/doc/open-government-licence/version/1/" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/OGL-UK-2.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/OGL-UK-2.0.json", "referenceNumber": 467, "name": "Open Government Licence v2.0", "licenseId": "OGL-UK-2.0", "seeAlso": [ "http://www.nationalarchives.gov.uk/doc/open-government-licence/version/2/" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/OGL-UK-3.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/OGL-UK-3.0.json", "referenceNumber": 151, "name": "Open Government Licence v3.0", "licenseId": "OGL-UK-3.0", "seeAlso": [ "http://www.nationalarchives.gov.uk/doc/open-government-licence/version/3/" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/OGTSL.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/OGTSL.json", "referenceNumber": 367, "name": "Open Group Test Suite License", "licenseId": "OGTSL", "seeAlso": [ "http://www.opengroup.org/testing/downloads/The_Open_Group_TSL.txt", "https://opensource.org/licenses/OGTSL" ], "isOsiApproved": true }, { "reference": "https://spdx.org/licenses/OLDAP-1.1.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/OLDAP-1.1.json", "referenceNumber": 180, "name": "Open LDAP Public License v1.1", "licenseId": "OLDAP-1.1", "seeAlso": [ "http://www.openldap.org/devel/gitweb.cgi?p\u003dopenldap.git;a\u003dblob;f\u003dLICENSE;hb\u003d806557a5ad59804ef3a44d5abfbe91d706b0791f" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/OLDAP-1.2.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/OLDAP-1.2.json", "referenceNumber": 229, "name": "Open LDAP Public License v1.2", "licenseId": "OLDAP-1.2", "seeAlso": [ "http://www.openldap.org/devel/gitweb.cgi?p\u003dopenldap.git;a\u003dblob;f\u003dLICENSE;hb\u003d42b0383c50c299977b5893ee695cf4e486fb0dc7" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/OLDAP-1.3.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/OLDAP-1.3.json", "referenceNumber": 224, "name": "Open LDAP Public License v1.3", "licenseId": "OLDAP-1.3", "seeAlso": [ "http://www.openldap.org/devel/gitweb.cgi?p\u003dopenldap.git;a\u003dblob;f\u003dLICENSE;hb\u003de5f8117f0ce088d0bd7a8e18ddf37eaa40eb09b1" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/OLDAP-1.4.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/OLDAP-1.4.json", "referenceNumber": 255, "name": "Open LDAP Public License v1.4", "licenseId": "OLDAP-1.4", "seeAlso": [ "http://www.openldap.org/devel/gitweb.cgi?p\u003dopenldap.git;a\u003dblob;f\u003dLICENSE;hb\u003dc9f95c2f3f2ffb5e0ae55fe7388af75547660941" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/OLDAP-2.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/OLDAP-2.0.json", "referenceNumber": 208, "name": "Open LDAP Public License v2.0 (or possibly 2.0A and 2.0B)", "licenseId": "OLDAP-2.0", "seeAlso": [ "http://www.openldap.org/devel/gitweb.cgi?p\u003dopenldap.git;a\u003dblob;f\u003dLICENSE;hb\u003dcbf50f4e1185a21abd4c0a54d3f4341fe28f36ea" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/OLDAP-2.0.1.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/OLDAP-2.0.1.json", "referenceNumber": 79, "name": "Open LDAP Public License v2.0.1", "licenseId": "OLDAP-2.0.1", "seeAlso": [ "http://www.openldap.org/devel/gitweb.cgi?p\u003dopenldap.git;a\u003dblob;f\u003dLICENSE;hb\u003db6d68acd14e51ca3aab4428bf26522aa74873f0e" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/OLDAP-2.1.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/OLDAP-2.1.json", "referenceNumber": 360, "name": "Open LDAP Public License v2.1", "licenseId": "OLDAP-2.1", "seeAlso": [ "http://www.openldap.org/devel/gitweb.cgi?p\u003dopenldap.git;a\u003dblob;f\u003dLICENSE;hb\u003db0d176738e96a0d3b9f85cb51e140a86f21be715" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/OLDAP-2.2.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/OLDAP-2.2.json", "referenceNumber": 316, "name": "Open LDAP Public License v2.2", "licenseId": "OLDAP-2.2", "seeAlso": [ "http://www.openldap.org/devel/gitweb.cgi?p\u003dopenldap.git;a\u003dblob;f\u003dLICENSE;hb\u003d470b0c18ec67621c85881b2733057fecf4a1acc3" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/OLDAP-2.2.1.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/OLDAP-2.2.1.json", "referenceNumber": 426, "name": "Open LDAP Public License v2.2.1", "licenseId": "OLDAP-2.2.1", "seeAlso": [ "http://www.openldap.org/devel/gitweb.cgi?p\u003dopenldap.git;a\u003dblob;f\u003dLICENSE;hb\u003d4bc786f34b50aa301be6f5600f58a980070f481e" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/OLDAP-2.2.2.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/OLDAP-2.2.2.json", "referenceNumber": 384, "name": "Open LDAP Public License 2.2.2", "licenseId": "OLDAP-2.2.2", "seeAlso": [ "http://www.openldap.org/devel/gitweb.cgi?p\u003dopenldap.git;a\u003dblob;f\u003dLICENSE;hb\u003ddf2cc1e21eb7c160695f5b7cffd6296c151ba188" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/OLDAP-2.3.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/OLDAP-2.3.json", "referenceNumber": 381, "name": "Open LDAP Public License v2.3", "licenseId": "OLDAP-2.3", "seeAlso": [ "http://www.openldap.org/devel/gitweb.cgi?p\u003dopenldap.git;a\u003dblob;f\u003dLICENSE;hb\u003dd32cf54a32d581ab475d23c810b0a7fbaf8d63c3" ], "isOsiApproved": false, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/OLDAP-2.4.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/OLDAP-2.4.json", "referenceNumber": 93, "name": "Open LDAP Public License v2.4", "licenseId": "OLDAP-2.4", "seeAlso": [ "http://www.openldap.org/devel/gitweb.cgi?p\u003dopenldap.git;a\u003dblob;f\u003dLICENSE;hb\u003dcd1284c4a91a8a380d904eee68d1583f989ed386" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/OLDAP-2.5.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/OLDAP-2.5.json", "referenceNumber": 651, "name": "Open LDAP Public License v2.5", "licenseId": "OLDAP-2.5", "seeAlso": [ "http://www.openldap.org/devel/gitweb.cgi?p\u003dopenldap.git;a\u003dblob;f\u003dLICENSE;hb\u003d6852b9d90022e8593c98205413380536b1b5a7cf" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/OLDAP-2.6.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/OLDAP-2.6.json", "referenceNumber": 568, "name": "Open LDAP Public License v2.6", "licenseId": "OLDAP-2.6", "seeAlso": [ "http://www.openldap.org/devel/gitweb.cgi?p\u003dopenldap.git;a\u003dblob;f\u003dLICENSE;hb\u003d1cae062821881f41b73012ba816434897abf4205" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/OLDAP-2.7.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/OLDAP-2.7.json", "referenceNumber": 220, "name": "Open LDAP Public License v2.7", "licenseId": "OLDAP-2.7", "seeAlso": [ "http://www.openldap.org/devel/gitweb.cgi?p\u003dopenldap.git;a\u003dblob;f\u003dLICENSE;hb\u003d47c2415c1df81556eeb39be6cad458ef87c534a2" ], "isOsiApproved": false, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/OLDAP-2.8.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/OLDAP-2.8.json", "referenceNumber": 5, "name": "Open LDAP Public License v2.8", "licenseId": "OLDAP-2.8", "seeAlso": [ "http://www.openldap.org/software/release/license.html" ], "isOsiApproved": true }, { "reference": "https://spdx.org/licenses/OLFL-1.3.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/OLFL-1.3.json", "referenceNumber": 142, "name": "Open Logistics Foundation License Version 1.3", "licenseId": "OLFL-1.3", "seeAlso": [ "https://openlogisticsfoundation.org/licenses/", "https://opensource.org/license/olfl-1-3/" ], "isOsiApproved": true }, { "reference": "https://spdx.org/licenses/OML.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/OML.json", "referenceNumber": 375, "name": "Open Market License", "licenseId": "OML", "seeAlso": [ "https://fedoraproject.org/wiki/Licensing/Open_Market_License" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/OpenPBS-2.3.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/OpenPBS-2.3.json", "referenceNumber": 314, "name": "OpenPBS v2.3 Software License", "licenseId": "OpenPBS-2.3", "seeAlso": [ "https://github.com/adaptivecomputing/torque/blob/master/PBS_License.txt", "https://www.mcs.anl.gov/research/projects/openpbs/PBS_License.txt" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/OpenSSL.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/OpenSSL.json", "referenceNumber": 303, "name": "OpenSSL License", "licenseId": "OpenSSL", "seeAlso": [ "http://www.openssl.org/source/license.html" ], "isOsiApproved": false, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/OpenSSL-standalone.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/OpenSSL-standalone.json", "referenceNumber": 602, "name": "OpenSSL License - standalone", "licenseId": "OpenSSL-standalone", "seeAlso": [ "https://library.netapp.com/ecm/ecm_download_file/ECMP1196395", "https://hstechdocs.helpsystems.com/manuals/globalscape/archive/cuteftp6/open_ssl_license_agreement.htm" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/OpenVision.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/OpenVision.json", "referenceNumber": 588, "name": "OpenVision License", "licenseId": "OpenVision", "seeAlso": [ "https://github.com/krb5/krb5/blob/krb5-1.21.2-final/NOTICE#L66-L98", "https://web.mit.edu/kerberos/krb5-1.21/doc/mitK5license.html", "https://fedoraproject.org/wiki/Licensing:MIT#OpenVision_Variant" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/OPL-1.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/OPL-1.0.json", "referenceNumber": 91, "name": "Open Public License v1.0", "licenseId": "OPL-1.0", "seeAlso": [ "http://old.koalateam.com/jackaroo/OPL_1_0.TXT", "https://fedoraproject.org/wiki/Licensing/Open_Public_License" ], "isOsiApproved": false, "isFsfLibre": false }, { "reference": "https://spdx.org/licenses/OPL-UK-3.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/OPL-UK-3.0.json", "referenceNumber": 480, "name": "United Kingdom Open Parliament Licence v3.0", "licenseId": "OPL-UK-3.0", "seeAlso": [ "https://www.parliament.uk/site-information/copyright-parliament/open-parliament-licence/" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/OPUBL-1.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/OPUBL-1.0.json", "referenceNumber": 329, "name": "Open Publication License v1.0", "licenseId": "OPUBL-1.0", "seeAlso": [ "http://opencontent.org/openpub/", "https://www.debian.org/opl", "https://www.ctan.org/license/opl" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/OSET-PL-2.1.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/OSET-PL-2.1.json", "referenceNumber": 517, "name": "OSET Public License version 2.1", "licenseId": "OSET-PL-2.1", "seeAlso": [ "http://www.osetfoundation.org/public-license", "https://opensource.org/licenses/OPL-2.1" ], "isOsiApproved": true }, { "reference": "https://spdx.org/licenses/OSL-1.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/OSL-1.0.json", "referenceNumber": 162, "name": "Open Software License 1.0", "licenseId": "OSL-1.0", "seeAlso": [ "https://opensource.org/licenses/OSL-1.0" ], "isOsiApproved": true, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/OSL-1.1.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/OSL-1.1.json", "referenceNumber": 586, "name": "Open Software License 1.1", "licenseId": "OSL-1.1", "seeAlso": [ "https://fedoraproject.org/wiki/Licensing/OSL1.1" ], "isOsiApproved": false, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/OSL-2.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/OSL-2.0.json", "referenceNumber": 531, "name": "Open Software License 2.0", "licenseId": "OSL-2.0", "seeAlso": [ "http://web.archive.org/web/20041020171434/http://www.rosenlaw.com/osl2.0.html" ], "isOsiApproved": true, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/OSL-2.1.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/OSL-2.1.json", "referenceNumber": 138, "name": "Open Software License 2.1", "licenseId": "OSL-2.1", "seeAlso": [ "http://web.archive.org/web/20050212003940/http://www.rosenlaw.com/osl21.htm", "https://opensource.org/licenses/OSL-2.1" ], "isOsiApproved": true, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/OSL-3.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/OSL-3.0.json", "referenceNumber": 300, "name": "Open Software License 3.0", "licenseId": "OSL-3.0", "seeAlso": [ "https://web.archive.org/web/20120101081418/http://rosenlaw.com:80/OSL3.0.htm", "https://opensource.org/licenses/OSL-3.0" ], "isOsiApproved": true, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/PADL.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/PADL.json", "referenceNumber": 113, "name": "PADL License", "licenseId": "PADL", "seeAlso": [ "https://git.openldap.org/openldap/openldap/-/blob/master/libraries/libldap/os-local.c?ref_type\u003dheads#L19-23" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/Parity-6.0.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Parity-6.0.0.json", "referenceNumber": 246, "name": "The Parity Public License 6.0.0", "licenseId": "Parity-6.0.0", "seeAlso": [ "https://paritylicense.com/versions/6.0.0.html" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/Parity-7.0.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Parity-7.0.0.json", "referenceNumber": 212, "name": "The Parity Public License 7.0.0", "licenseId": "Parity-7.0.0", "seeAlso": [ "https://paritylicense.com/versions/7.0.0.html" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/PDDL-1.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/PDDL-1.0.json", "referenceNumber": 493, "name": "Open Data Commons Public Domain Dedication \u0026 License 1.0", "licenseId": "PDDL-1.0", "seeAlso": [ "http://opendatacommons.org/licenses/pddl/1.0/", "https://opendatacommons.org/licenses/pddl/" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/PHP-3.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/PHP-3.0.json", "referenceNumber": 584, "name": "PHP License v3.0", "licenseId": "PHP-3.0", "seeAlso": [ "http://www.php.net/license/3_0.txt", "https://opensource.org/licenses/PHP-3.0" ], "isOsiApproved": true }, { "reference": "https://spdx.org/licenses/PHP-3.01.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/PHP-3.01.json", "referenceNumber": 538, "name": "PHP License v3.01", "licenseId": "PHP-3.01", "seeAlso": [ "http://www.php.net/license/3_01.txt" ], "isOsiApproved": true, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/Pixar.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Pixar.json", "referenceNumber": 204, "name": "Pixar License", "licenseId": "Pixar", "seeAlso": [ "https://github.com/PixarAnimationStudios/OpenSubdiv/raw/v3_5_0/LICENSE.txt", "https://graphics.pixar.com/opensubdiv/docs/license.html", "https://github.com/PixarAnimationStudios/OpenSubdiv/blob/v3_5_0/opensubdiv/version.cpp#L2-L22" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/pkgconf.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/pkgconf.json", "referenceNumber": 389, "name": "pkgconf License", "licenseId": "pkgconf", "seeAlso": [ "https://github.com/pkgconf/pkgconf/blob/master/cli/main.c#L8" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/Plexus.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Plexus.json", "referenceNumber": 141, "name": "Plexus Classworlds License", "licenseId": "Plexus", "seeAlso": [ "https://fedoraproject.org/wiki/Licensing/Plexus_Classworlds_License" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/pnmstitch.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/pnmstitch.json", "referenceNumber": 158, "name": "pnmstitch License", "licenseId": "pnmstitch", "seeAlso": [ "https://sourceforge.net/p/netpbm/code/HEAD/tree/super_stable/editor/pnmstitch.c#l2" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/PolyForm-Noncommercial-1.0.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/PolyForm-Noncommercial-1.0.0.json", "referenceNumber": 54, "name": "PolyForm Noncommercial License 1.0.0", "licenseId": "PolyForm-Noncommercial-1.0.0", "seeAlso": [ "https://polyformproject.org/licenses/noncommercial/1.0.0" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/PolyForm-Small-Business-1.0.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/PolyForm-Small-Business-1.0.0.json", "referenceNumber": 594, "name": "PolyForm Small Business License 1.0.0", "licenseId": "PolyForm-Small-Business-1.0.0", "seeAlso": [ "https://polyformproject.org/licenses/small-business/1.0.0" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/PostgreSQL.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/PostgreSQL.json", "referenceNumber": 643, "name": "PostgreSQL License", "licenseId": "PostgreSQL", "seeAlso": [ "http://www.postgresql.org/about/licence", "https://opensource.org/licenses/PostgreSQL" ], "isOsiApproved": true }, { "reference": "https://spdx.org/licenses/PPL.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/PPL.json", "referenceNumber": 580, "name": "Peer Production License", "licenseId": "PPL", "seeAlso": [ "https://wiki.p2pfoundation.net/Peer_Production_License", "http://www.networkcultures.org/_uploads/%233notebook_telekommunist.pdf" ], "isOsiApproved": false, "isFsfLibre": false }, { "reference": "https://spdx.org/licenses/PSF-2.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/PSF-2.0.json", "referenceNumber": 55, "name": "Python Software Foundation License 2.0", "licenseId": "PSF-2.0", "seeAlso": [ "https://opensource.org/licenses/Python-2.0" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/psfrag.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/psfrag.json", "referenceNumber": 555, "name": "psfrag License", "licenseId": "psfrag", "seeAlso": [ "https://fedoraproject.org/wiki/Licensing/psfrag" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/psutils.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/psutils.json", "referenceNumber": 260, "name": "psutils License", "licenseId": "psutils", "seeAlso": [ "https://fedoraproject.org/wiki/Licensing/psutils" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/Python-2.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Python-2.0.json", "referenceNumber": 285, "name": "Python License 2.0", "licenseId": "Python-2.0", "seeAlso": [ "https://opensource.org/licenses/Python-2.0" ], "isOsiApproved": true, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/Python-2.0.1.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Python-2.0.1.json", "referenceNumber": 201, "name": "Python License 2.0.1", "licenseId": "Python-2.0.1", "seeAlso": [ "https://www.python.org/download/releases/2.0.1/license/", "https://docs.python.org/3/license.html", "https://github.com/python/cpython/blob/main/LICENSE" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/python-ldap.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/python-ldap.json", "referenceNumber": 446, "name": "Python ldap License", "licenseId": "python-ldap", "seeAlso": [ "https://github.com/python-ldap/python-ldap/blob/main/LICENCE" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/Qhull.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Qhull.json", "referenceNumber": 326, "name": "Qhull License", "licenseId": "Qhull", "seeAlso": [ "https://fedoraproject.org/wiki/Licensing/Qhull" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/QPL-1.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/QPL-1.0.json", "referenceNumber": 413, "name": "Q Public License 1.0", "licenseId": "QPL-1.0", "seeAlso": [ "http://doc.qt.nokia.com/3.3/license.html", "https://opensource.org/licenses/QPL-1.0", "https://doc.qt.io/archives/3.3/license.html" ], "isOsiApproved": true, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/QPL-1.0-INRIA-2004.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/QPL-1.0-INRIA-2004.json", "referenceNumber": 486, "name": "Q Public License 1.0 - INRIA 2004 variant", "licenseId": "QPL-1.0-INRIA-2004", "seeAlso": [ "https://github.com/maranget/hevea/blob/master/LICENSE" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/radvd.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/radvd.json", "referenceNumber": 433, "name": "radvd License", "licenseId": "radvd", "seeAlso": [ "https://github.com/radvd-project/radvd/blob/master/COPYRIGHT" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/Rdisc.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Rdisc.json", "referenceNumber": 50, "name": "Rdisc License", "licenseId": "Rdisc", "seeAlso": [ "https://fedoraproject.org/wiki/Licensing/Rdisc_License" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/RHeCos-1.1.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/RHeCos-1.1.json", "referenceNumber": 99, "name": "Red Hat eCos Public License v1.1", "licenseId": "RHeCos-1.1", "seeAlso": [ "http://ecos.sourceware.org/old-license.html" ], "isOsiApproved": false, "isFsfLibre": false }, { "reference": "https://spdx.org/licenses/RPL-1.1.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/RPL-1.1.json", "referenceNumber": 205, "name": "Reciprocal Public License 1.1", "licenseId": "RPL-1.1", "seeAlso": [ "https://opensource.org/licenses/RPL-1.1" ], "isOsiApproved": true }, { "reference": "https://spdx.org/licenses/RPL-1.5.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/RPL-1.5.json", "referenceNumber": 52, "name": "Reciprocal Public License 1.5", "licenseId": "RPL-1.5", "seeAlso": [ "https://opensource.org/licenses/RPL-1.5" ], "isOsiApproved": true }, { "reference": "https://spdx.org/licenses/RPSL-1.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/RPSL-1.0.json", "referenceNumber": 637, "name": "RealNetworks Public Source License v1.0", "licenseId": "RPSL-1.0", "seeAlso": [ "https://helixcommunity.org/content/rpsl", "https://opensource.org/licenses/RPSL-1.0" ], "isOsiApproved": true, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/RSA-MD.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/RSA-MD.json", "referenceNumber": 496, "name": "RSA Message-Digest License", "licenseId": "RSA-MD", "seeAlso": [ "http://www.faqs.org/rfcs/rfc1321.html" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/RSCPL.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/RSCPL.json", "referenceNumber": 235, "name": "Ricoh Source Code Public License", "licenseId": "RSCPL", "seeAlso": [ "http://wayback.archive.org/web/20060715140826/http://www.risource.org/RPL/RPL-1.0A.shtml", "https://opensource.org/licenses/RSCPL" ], "isOsiApproved": true }, { "reference": "https://spdx.org/licenses/Ruby.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Ruby.json", "referenceNumber": 223, "name": "Ruby License", "licenseId": "Ruby", "seeAlso": [ "https://www.ruby-lang.org/en/about/license.txt" ], "isOsiApproved": false, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/SAX-PD.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/SAX-PD.json", "referenceNumber": 301, "name": "Sax Public Domain Notice", "licenseId": "SAX-PD", "seeAlso": [ "http://www.saxproject.org/copying.html" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/SAX-PD-2.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/SAX-PD-2.0.json", "referenceNumber": 561, "name": "Sax Public Domain Notice 2.0", "licenseId": "SAX-PD-2.0", "seeAlso": [ "http://www.saxproject.org/copying.html" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/Saxpath.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Saxpath.json", "referenceNumber": 109, "name": "Saxpath License", "licenseId": "Saxpath", "seeAlso": [ "https://fedoraproject.org/wiki/Licensing/Saxpath_License" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/SCEA.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/SCEA.json", "referenceNumber": 35, "name": "SCEA Shared Source License", "licenseId": "SCEA", "seeAlso": [ "http://research.scea.com/scea_shared_source_license.html" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/SchemeReport.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/SchemeReport.json", "referenceNumber": 425, "name": "Scheme Language Report License", "licenseId": "SchemeReport", "seeAlso": [], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/Sendmail.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Sendmail.json", "referenceNumber": 274, "name": "Sendmail License", "licenseId": "Sendmail", "seeAlso": [ "http://www.sendmail.com/pdfs/open_source/sendmail_license.pdf", "https://web.archive.org/web/20160322142305/https://www.sendmail.com/pdfs/open_source/sendmail_license.pdf" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/Sendmail-8.23.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Sendmail-8.23.json", "referenceNumber": 247, "name": "Sendmail License 8.23", "licenseId": "Sendmail-8.23", "seeAlso": [ "https://www.proofpoint.com/sites/default/files/sendmail-license.pdf", "https://web.archive.org/web/20181003101040/https://www.proofpoint.com/sites/default/files/sendmail-license.pdf" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/SGI-B-1.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/SGI-B-1.0.json", "referenceNumber": 476, "name": "SGI Free Software License B v1.0", "licenseId": "SGI-B-1.0", "seeAlso": [ "http://oss.sgi.com/projects/FreeB/SGIFreeSWLicB.1.0.html" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/SGI-B-1.1.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/SGI-B-1.1.json", "referenceNumber": 456, "name": "SGI Free Software License B v1.1", "licenseId": "SGI-B-1.1", "seeAlso": [ "http://oss.sgi.com/projects/FreeB/" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/SGI-B-2.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/SGI-B-2.0.json", "referenceNumber": 405, "name": "SGI Free Software License B v2.0", "licenseId": "SGI-B-2.0", "seeAlso": [ "http://oss.sgi.com/projects/FreeB/SGIFreeSWLicB.2.0.pdf" ], "isOsiApproved": false, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/SGI-OpenGL.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/SGI-OpenGL.json", "referenceNumber": 629, "name": "SGI OpenGL License", "licenseId": "SGI-OpenGL", "seeAlso": [ "https://gitlab.freedesktop.org/mesa/glw/-/blob/master/README?ref_type\u003dheads" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/SGP4.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/SGP4.json", "referenceNumber": 336, "name": "SGP4 Permission Notice", "licenseId": "SGP4", "seeAlso": [ "https://celestrak.org/publications/AIAA/2006-6753/faq.php" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/SHL-0.5.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/SHL-0.5.json", "referenceNumber": 338, "name": "Solderpad Hardware License v0.5", "licenseId": "SHL-0.5", "seeAlso": [ "https://solderpad.org/licenses/SHL-0.5/" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/SHL-0.51.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/SHL-0.51.json", "referenceNumber": 29, "name": "Solderpad Hardware License, Version 0.51", "licenseId": "SHL-0.51", "seeAlso": [ "https://solderpad.org/licenses/SHL-0.51/" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/SimPL-2.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/SimPL-2.0.json", "referenceNumber": 444, "name": "Simple Public License 2.0", "licenseId": "SimPL-2.0", "seeAlso": [ "https://opensource.org/licenses/SimPL-2.0" ], "isOsiApproved": true }, { "reference": "https://spdx.org/licenses/SISSL.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/SISSL.json", "referenceNumber": 268, "name": "Sun Industry Standards Source License v1.1", "licenseId": "SISSL", "seeAlso": [ "http://www.openoffice.org/licenses/sissl_license.html", "https://opensource.org/licenses/SISSL" ], "isOsiApproved": true, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/SISSL-1.2.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/SISSL-1.2.json", "referenceNumber": 502, "name": "Sun Industry Standards Source License v1.2", "licenseId": "SISSL-1.2", "seeAlso": [ "http://gridscheduler.sourceforge.net/Gridengine_SISSL_license.html" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/SL.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/SL.json", "referenceNumber": 645, "name": "SL License", "licenseId": "SL", "seeAlso": [ "https://github.com/mtoyoda/sl/blob/master/LICENSE" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/Sleepycat.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Sleepycat.json", "referenceNumber": 182, "name": "Sleepycat License", "licenseId": "Sleepycat", "seeAlso": [ "https://opensource.org/licenses/Sleepycat" ], "isOsiApproved": true, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/SMLNJ.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/SMLNJ.json", "referenceNumber": 148, "name": "Standard ML of New Jersey License", "licenseId": "SMLNJ", "seeAlso": [ "https://www.smlnj.org/license.html" ], "isOsiApproved": false, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/SMPPL.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/SMPPL.json", "referenceNumber": 250, "name": "Secure Messaging Protocol Public License", "licenseId": "SMPPL", "seeAlso": [ "https://github.com/dcblake/SMP/blob/master/Documentation/License.txt" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/SNIA.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/SNIA.json", "referenceNumber": 518, "name": "SNIA Public License 1.1", "licenseId": "SNIA", "seeAlso": [ "https://fedoraproject.org/wiki/Licensing/SNIA_Public_License" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/snprintf.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/snprintf.json", "referenceNumber": 161, "name": "snprintf License", "licenseId": "snprintf", "seeAlso": [ "https://github.com/openssh/openssh-portable/blob/master/openbsd-compat/bsd-snprintf.c#L2" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/softSurfer.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/softSurfer.json", "referenceNumber": 523, "name": "softSurfer License", "licenseId": "softSurfer", "seeAlso": [ "https://github.com/mm2/Little-CMS/blob/master/src/cmssm.c#L207", "https://fedoraproject.org/wiki/Licensing/softSurfer" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/Soundex.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Soundex.json", "referenceNumber": 368, "name": "Soundex License", "licenseId": "Soundex", "seeAlso": [ "https://metacpan.org/release/RJBS/Text-Soundex-3.05/source/Soundex.pm#L3-11" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/Spencer-86.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Spencer-86.json", "referenceNumber": 472, "name": "Spencer License 86", "licenseId": "Spencer-86", "seeAlso": [ "https://fedoraproject.org/wiki/Licensing/Henry_Spencer_Reg-Ex_Library_License" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/Spencer-94.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Spencer-94.json", "referenceNumber": 378, "name": "Spencer License 94", "licenseId": "Spencer-94", "seeAlso": [ "https://fedoraproject.org/wiki/Licensing/Henry_Spencer_Reg-Ex_Library_License", "https://metacpan.org/release/KNOK/File-MMagic-1.30/source/COPYING#L28" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/Spencer-99.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Spencer-99.json", "referenceNumber": 139, "name": "Spencer License 99", "licenseId": "Spencer-99", "seeAlso": [ "http://www.opensource.apple.com/source/tcl/tcl-5/tcl/generic/regfronts.c" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/SPL-1.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/SPL-1.0.json", "referenceNumber": 280, "name": "Sun Public License v1.0", "licenseId": "SPL-1.0", "seeAlso": [ "https://opensource.org/licenses/SPL-1.0" ], "isOsiApproved": true, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/ssh-keyscan.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/ssh-keyscan.json", "referenceNumber": 294, "name": "ssh-keyscan License", "licenseId": "ssh-keyscan", "seeAlso": [ "https://github.com/openssh/openssh-portable/blob/master/LICENCE#L82" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/SSH-OpenSSH.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/SSH-OpenSSH.json", "referenceNumber": 506, "name": "SSH OpenSSH license", "licenseId": "SSH-OpenSSH", "seeAlso": [ "https://github.com/openssh/openssh-portable/blob/1b11ea7c58cd5c59838b5fa574cd456d6047b2d4/LICENCE#L10" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/SSH-short.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/SSH-short.json", "referenceNumber": 563, "name": "SSH short notice", "licenseId": "SSH-short", "seeAlso": [ "https://github.com/openssh/openssh-portable/blob/1b11ea7c58cd5c59838b5fa574cd456d6047b2d4/pathnames.h", "http://web.mit.edu/kolya/.f/root/athena.mit.edu/sipb.mit.edu/project/openssh/OldFiles/src/openssh-2.9.9p2/ssh-add.1", "https://joinup.ec.europa.eu/svn/lesoll/trunk/italc/lib/src/dsa_key.cpp" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/SSLeay-standalone.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/SSLeay-standalone.json", "referenceNumber": 591, "name": "SSLeay License - standalone", "licenseId": "SSLeay-standalone", "seeAlso": [ "https://www.tq-group.com/filedownloads/files/software-license-conditions/OriginalSSLeay/OriginalSSLeay.pdf" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/SSPL-1.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/SSPL-1.0.json", "referenceNumber": 17, "name": "Server Side Public License, v 1", "licenseId": "SSPL-1.0", "seeAlso": [ "https://www.mongodb.com/licensing/server-side-public-license" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/StandardML-NJ.html", "isDeprecatedLicenseId": true, "detailsUrl": "https://spdx.org/licenses/StandardML-NJ.json", "referenceNumber": 658, "name": "Standard ML of New Jersey License", "licenseId": "StandardML-NJ", "seeAlso": [ "https://www.smlnj.org/license.html" ], "isOsiApproved": false, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/SugarCRM-1.1.3.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/SugarCRM-1.1.3.json", "referenceNumber": 42, "name": "SugarCRM Public License v1.1.3", "licenseId": "SugarCRM-1.1.3", "seeAlso": [ "http://www.sugarcrm.com/crm/SPL" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/Sun-PPP.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Sun-PPP.json", "referenceNumber": 385, "name": "Sun PPP License", "licenseId": "Sun-PPP", "seeAlso": [ "https://github.com/ppp-project/ppp/blob/master/pppd/eap.c#L7-L16" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/Sun-PPP-2000.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Sun-PPP-2000.json", "referenceNumber": 310, "name": "Sun PPP License (2000)", "licenseId": "Sun-PPP-2000", "seeAlso": [ "https://github.com/ppp-project/ppp/blob/master/modules/ppp_ahdlc.c#L7-L19" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/SunPro.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/SunPro.json", "referenceNumber": 57, "name": "SunPro License", "licenseId": "SunPro", "seeAlso": [ "https://github.com/freebsd/freebsd-src/blob/main/lib/msun/src/e_acosh.c", "https://github.com/freebsd/freebsd-src/blob/main/lib/msun/src/e_lgammal.c" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/SWL.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/SWL.json", "referenceNumber": 649, "name": "Scheme Widget Library (SWL) Software License Agreement", "licenseId": "SWL", "seeAlso": [ "https://fedoraproject.org/wiki/Licensing/SWL" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/swrule.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/swrule.json", "referenceNumber": 90, "name": "swrule License", "licenseId": "swrule", "seeAlso": [ "https://ctan.math.utah.edu/ctan/tex-archive/macros/generic/misc/swrule.sty" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/Symlinks.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Symlinks.json", "referenceNumber": 414, "name": "Symlinks License", "licenseId": "Symlinks", "seeAlso": [ "https://www.mail-archive.com/debian-bugs-rc@lists.debian.org/msg11494.html" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/TAPR-OHL-1.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/TAPR-OHL-1.0.json", "referenceNumber": 242, "name": "TAPR Open Hardware License v1.0", "licenseId": "TAPR-OHL-1.0", "seeAlso": [ "https://www.tapr.org/OHL" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/TCL.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/TCL.json", "referenceNumber": 2, "name": "TCL/TK License", "licenseId": "TCL", "seeAlso": [ "http://www.tcl.tk/software/tcltk/license.html", "https://fedoraproject.org/wiki/Licensing/TCL" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/TCP-wrappers.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/TCP-wrappers.json", "referenceNumber": 9, "name": "TCP Wrappers License", "licenseId": "TCP-wrappers", "seeAlso": [ "http://rc.quest.com/topics/openssh/license.php#tcpwrappers" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/TermReadKey.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/TermReadKey.json", "referenceNumber": 256, "name": "TermReadKey License", "licenseId": "TermReadKey", "seeAlso": [ "https://github.com/jonathanstowe/TermReadKey/blob/master/README#L9-L10" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/TGPPL-1.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/TGPPL-1.0.json", "referenceNumber": 101, "name": "Transitive Grace Period Public Licence 1.0", "licenseId": "TGPPL-1.0", "seeAlso": [ "https://fedoraproject.org/wiki/Licensing/TGPPL", "https://tahoe-lafs.org/trac/tahoe-lafs/browser/trunk/COPYING.TGPPL.rst" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/threeparttable.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/threeparttable.json", "referenceNumber": 398, "name": "threeparttable License", "licenseId": "threeparttable", "seeAlso": [ "https://fedoraproject.org/wiki/Licensing/Threeparttable" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/TMate.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/TMate.json", "referenceNumber": 539, "name": "TMate Open Source License", "licenseId": "TMate", "seeAlso": [ "http://svnkit.com/license.html" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/TORQUE-1.1.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/TORQUE-1.1.json", "referenceNumber": 61, "name": "TORQUE v2.5+ Software License v1.1", "licenseId": "TORQUE-1.1", "seeAlso": [ "https://fedoraproject.org/wiki/Licensing/TORQUEv1.1" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/TOSL.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/TOSL.json", "referenceNumber": 267, "name": "Trusster Open Source License", "licenseId": "TOSL", "seeAlso": [ "https://fedoraproject.org/wiki/Licensing/TOSL" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/TPDL.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/TPDL.json", "referenceNumber": 75, "name": "Time::ParseDate License", "licenseId": "TPDL", "seeAlso": [ "https://metacpan.org/pod/Time::ParseDate#LICENSE" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/TPL-1.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/TPL-1.0.json", "referenceNumber": 508, "name": "THOR Public License 1.0", "licenseId": "TPL-1.0", "seeAlso": [ "https://fedoraproject.org/wiki/Licensing:ThorPublicLicense" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/TTWL.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/TTWL.json", "referenceNumber": 87, "name": "Text-Tabs+Wrap License", "licenseId": "TTWL", "seeAlso": [ "https://fedoraproject.org/wiki/Licensing/TTWL", "https://github.com/ap/Text-Tabs/blob/master/lib.modern/Text/Tabs.pm#L148" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/TTYP0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/TTYP0.json", "referenceNumber": 451, "name": "TTYP0 License", "licenseId": "TTYP0", "seeAlso": [ "https://people.mpi-inf.mpg.de/~uwe/misc/uw-ttyp0/" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/TU-Berlin-1.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/TU-Berlin-1.0.json", "referenceNumber": 159, "name": "Technische Universitaet Berlin License 1.0", "licenseId": "TU-Berlin-1.0", "seeAlso": [ "https://github.com/swh/ladspa/blob/7bf6f3799fdba70fda297c2d8fd9f526803d9680/gsm/COPYRIGHT" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/TU-Berlin-2.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/TU-Berlin-2.0.json", "referenceNumber": 624, "name": "Technische Universitaet Berlin License 2.0", "licenseId": "TU-Berlin-2.0", "seeAlso": [ "https://github.com/CorsixTH/deps/blob/fd339a9f526d1d9c9f01ccf39e438a015da50035/licences/libgsm.txt" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/UCAR.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/UCAR.json", "referenceNumber": 78, "name": "UCAR License", "licenseId": "UCAR", "seeAlso": [ "https://github.com/Unidata/UDUNITS-2/blob/master/COPYRIGHT" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/UCL-1.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/UCL-1.0.json", "referenceNumber": 646, "name": "Upstream Compatibility License v1.0", "licenseId": "UCL-1.0", "seeAlso": [ "https://opensource.org/licenses/UCL-1.0" ], "isOsiApproved": true }, { "reference": "https://spdx.org/licenses/ulem.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/ulem.json", "referenceNumber": 566, "name": "ulem License", "licenseId": "ulem", "seeAlso": [ "https://mirrors.ctan.org/macros/latex/contrib/ulem/README" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/UMich-Merit.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/UMich-Merit.json", "referenceNumber": 505, "name": "Michigan/Merit Networks License", "licenseId": "UMich-Merit", "seeAlso": [ "https://github.com/radcli/radcli/blob/master/COPYRIGHT#L64" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/Unicode-3.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Unicode-3.0.json", "referenceNumber": 46, "name": "Unicode License v3", "licenseId": "Unicode-3.0", "seeAlso": [ "https://www.unicode.org/license.txt" ], "isOsiApproved": true }, { "reference": "https://spdx.org/licenses/Unicode-DFS-2015.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Unicode-DFS-2015.json", "referenceNumber": 647, "name": "Unicode License Agreement - Data Files and Software (2015)", "licenseId": "Unicode-DFS-2015", "seeAlso": [ "https://web.archive.org/web/20151224134844/http://unicode.org/copyright.html" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/Unicode-DFS-2016.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Unicode-DFS-2016.json", "referenceNumber": 152, "name": "Unicode License Agreement - Data Files and Software (2016)", "licenseId": "Unicode-DFS-2016", "seeAlso": [ "https://www.unicode.org/license.txt", "http://web.archive.org/web/20160823201924/http://www.unicode.org/copyright.html#License", "http://www.unicode.org/copyright.html" ], "isOsiApproved": true }, { "reference": "https://spdx.org/licenses/Unicode-TOU.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Unicode-TOU.json", "referenceNumber": 606, "name": "Unicode Terms of Use", "licenseId": "Unicode-TOU", "seeAlso": [ "http://web.archive.org/web/20140704074106/http://www.unicode.org/copyright.html", "http://www.unicode.org/copyright.html" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/UnixCrypt.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/UnixCrypt.json", "referenceNumber": 462, "name": "UnixCrypt License", "licenseId": "UnixCrypt", "seeAlso": [ "https://foss.heptapod.net/python-libs/passlib/-/blob/branch/stable/LICENSE#L70", "https://opensource.apple.com/source/JBoss/JBoss-737/jboss-all/jetty/src/main/org/mortbay/util/UnixCrypt.java.auto.html", "https://archive.eclipse.org/jetty/8.0.1.v20110908/xref/org/eclipse/jetty/http/security/UnixCrypt.html" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/Unlicense.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Unlicense.json", "referenceNumber": 411, "name": "The Unlicense", "licenseId": "Unlicense", "seeAlso": [ "https://unlicense.org/" ], "isOsiApproved": true, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/UPL-1.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/UPL-1.0.json", "referenceNumber": 511, "name": "Universal Permissive License v1.0", "licenseId": "UPL-1.0", "seeAlso": [ "https://opensource.org/licenses/UPL" ], "isOsiApproved": true, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/URT-RLE.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/URT-RLE.json", "referenceNumber": 443, "name": "Utah Raster Toolkit Run Length Encoded License", "licenseId": "URT-RLE", "seeAlso": [ "https://sourceforge.net/p/netpbm/code/HEAD/tree/super_stable/converter/other/pnmtorle.c", "https://sourceforge.net/p/netpbm/code/HEAD/tree/super_stable/converter/other/rletopnm.c" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/Vim.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Vim.json", "referenceNumber": 371, "name": "Vim License", "licenseId": "Vim", "seeAlso": [ "http://vimdoc.sourceforge.net/htmldoc/uganda.html" ], "isOsiApproved": false, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/VOSTROM.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/VOSTROM.json", "referenceNumber": 122, "name": "VOSTROM Public License for Open Source", "licenseId": "VOSTROM", "seeAlso": [ "https://fedoraproject.org/wiki/Licensing/VOSTROM" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/VSL-1.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/VSL-1.0.json", "referenceNumber": 510, "name": "Vovida Software License v1.0", "licenseId": "VSL-1.0", "seeAlso": [ "https://opensource.org/licenses/VSL-1.0" ], "isOsiApproved": true }, { "reference": "https://spdx.org/licenses/W3C.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/W3C.json", "referenceNumber": 284, "name": "W3C Software Notice and License (2002-12-31)", "licenseId": "W3C", "seeAlso": [ "http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231.html", "https://opensource.org/licenses/W3C" ], "isOsiApproved": true, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/W3C-19980720.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/W3C-19980720.json", "referenceNumber": 156, "name": "W3C Software Notice and License (1998-07-20)", "licenseId": "W3C-19980720", "seeAlso": [ "http://www.w3.org/Consortium/Legal/copyright-software-19980720.html" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/W3C-20150513.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/W3C-20150513.json", "referenceNumber": 452, "name": "W3C Software Notice and Document License (2015-05-13)", "licenseId": "W3C-20150513", "seeAlso": [ "https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document", "https://www.w3.org/copyright/software-license-2015/", "https://www.w3.org/copyright/software-license-2023/" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/w3m.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/w3m.json", "referenceNumber": 202, "name": "w3m License", "licenseId": "w3m", "seeAlso": [ "https://github.com/tats/w3m/blob/master/COPYING" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/Watcom-1.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Watcom-1.0.json", "referenceNumber": 533, "name": "Sybase Open Watcom Public License 1.0", "licenseId": "Watcom-1.0", "seeAlso": [ "https://opensource.org/licenses/Watcom-1.0" ], "isOsiApproved": true, "isFsfLibre": false }, { "reference": "https://spdx.org/licenses/Widget-Workshop.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Widget-Workshop.json", "referenceNumber": 548, "name": "Widget Workshop License", "licenseId": "Widget-Workshop", "seeAlso": [ "https://github.com/novnc/noVNC/blob/master/core/crypto/des.js#L24" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/Wsuipa.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Wsuipa.json", "referenceNumber": 305, "name": "Wsuipa License", "licenseId": "Wsuipa", "seeAlso": [ "https://fedoraproject.org/wiki/Licensing/Wsuipa" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/WTFPL.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/WTFPL.json", "referenceNumber": 176, "name": "Do What The F*ck You Want To Public License", "licenseId": "WTFPL", "seeAlso": [ "http://www.wtfpl.net/about/", "http://sam.zoy.org/wtfpl/COPYING" ], "isOsiApproved": false, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/wxWindows.html", "isDeprecatedLicenseId": true, "detailsUrl": "https://spdx.org/licenses/wxWindows.json", "referenceNumber": 258, "name": "wxWindows Library License", "licenseId": "wxWindows", "seeAlso": [ "https://opensource.org/licenses/WXwindows" ], "isOsiApproved": true }, { "reference": "https://spdx.org/licenses/X11.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/X11.json", "referenceNumber": 203, "name": "X11 License", "licenseId": "X11", "seeAlso": [ "http://www.xfree86.org/3.3.6/COPYRIGHT2.html#3" ], "isOsiApproved": false, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/X11-distribute-modifications-variant.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/X11-distribute-modifications-variant.json", "referenceNumber": 112, "name": "X11 License Distribution Modification Variant", "licenseId": "X11-distribute-modifications-variant", "seeAlso": [ "https://github.com/mirror/ncurses/blob/master/COPYING" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/Xdebug-1.03.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Xdebug-1.03.json", "referenceNumber": 10, "name": "Xdebug License v 1.03", "licenseId": "Xdebug-1.03", "seeAlso": [ "https://github.com/xdebug/xdebug/blob/master/LICENSE" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/Xerox.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Xerox.json", "referenceNumber": 595, "name": "Xerox License", "licenseId": "Xerox", "seeAlso": [ "https://fedoraproject.org/wiki/Licensing/Xerox" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/Xfig.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Xfig.json", "referenceNumber": 89, "name": "Xfig License", "licenseId": "Xfig", "seeAlso": [ "https://github.com/Distrotech/transfig/blob/master/transfig/transfig.c", "https://fedoraproject.org/wiki/Licensing:MIT#Xfig_Variant", "https://sourceforge.net/p/mcj/xfig/ci/master/tree/src/Makefile.am" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/XFree86-1.1.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/XFree86-1.1.json", "referenceNumber": 562, "name": "XFree86 License 1.1", "licenseId": "XFree86-1.1", "seeAlso": [ "http://www.xfree86.org/current/LICENSE4.html" ], "isOsiApproved": false, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/xinetd.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/xinetd.json", "referenceNumber": 465, "name": "xinetd License", "licenseId": "xinetd", "seeAlso": [ "https://fedoraproject.org/wiki/Licensing/Xinetd_License" ], "isOsiApproved": false, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/xkeyboard-config-Zinoviev.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/xkeyboard-config-Zinoviev.json", "referenceNumber": 140, "name": "xkeyboard-config Zinoviev License", "licenseId": "xkeyboard-config-Zinoviev", "seeAlso": [ "https://gitlab.freedesktop.org/xkeyboard-config/xkeyboard-config/-/blob/master/COPYING?ref_type\u003dheads#L178" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/xlock.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/xlock.json", "referenceNumber": 357, "name": "xlock License", "licenseId": "xlock", "seeAlso": [ "https://fossies.org/linux/tiff/contrib/ras/ras2tif.c" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/Xnet.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Xnet.json", "referenceNumber": 236, "name": "X.Net License", "licenseId": "Xnet", "seeAlso": [ "https://opensource.org/licenses/Xnet" ], "isOsiApproved": true }, { "reference": "https://spdx.org/licenses/xpp.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/xpp.json", "referenceNumber": 312, "name": "XPP License", "licenseId": "xpp", "seeAlso": [ "https://fedoraproject.org/wiki/Licensing/xpp" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/XSkat.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/XSkat.json", "referenceNumber": 544, "name": "XSkat License", "licenseId": "XSkat", "seeAlso": [ "https://fedoraproject.org/wiki/Licensing/XSkat_License" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/xzoom.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/xzoom.json", "referenceNumber": 530, "name": "xzoom License", "licenseId": "xzoom", "seeAlso": [ "https://metadata.ftp-master.debian.org/changelogs//main/x/xzoom/xzoom_0.3-27_copyright" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/YPL-1.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/YPL-1.0.json", "referenceNumber": 491, "name": "Yahoo! Public License v1.0", "licenseId": "YPL-1.0", "seeAlso": [ "http://www.zimbra.com/license/yahoo_public_license_1.0.html" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/YPL-1.1.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/YPL-1.1.json", "referenceNumber": 473, "name": "Yahoo! Public License v1.1", "licenseId": "YPL-1.1", "seeAlso": [ "http://www.zimbra.com/license/yahoo_public_license_1.1.html" ], "isOsiApproved": false, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/Zed.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Zed.json", "referenceNumber": 599, "name": "Zed License", "licenseId": "Zed", "seeAlso": [ "https://fedoraproject.org/wiki/Licensing/Zed" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/Zeeff.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Zeeff.json", "referenceNumber": 218, "name": "Zeeff License", "licenseId": "Zeeff", "seeAlso": [ "ftp://ftp.tin.org/pub/news/utils/newsx/newsx-1.6.tar.gz" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/Zend-2.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Zend-2.0.json", "referenceNumber": 481, "name": "Zend License v2.0", "licenseId": "Zend-2.0", "seeAlso": [ "https://web.archive.org/web/20130517195954/http://www.zend.com/license/2_00.txt" ], "isOsiApproved": false, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/Zimbra-1.3.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Zimbra-1.3.json", "referenceNumber": 379, "name": "Zimbra Public License v1.3", "licenseId": "Zimbra-1.3", "seeAlso": [ "http://web.archive.org/web/20100302225219/http://www.zimbra.com/license/zimbra-public-license-1-3.html" ], "isOsiApproved": false, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/Zimbra-1.4.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Zimbra-1.4.json", "referenceNumber": 304, "name": "Zimbra Public License v1.4", "licenseId": "Zimbra-1.4", "seeAlso": [ "http://www.zimbra.com/legal/zimbra-public-license-1-4" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/Zlib.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Zlib.json", "referenceNumber": 209, "name": "zlib License", "licenseId": "Zlib", "seeAlso": [ "http://www.zlib.net/zlib_license.html", "https://opensource.org/licenses/Zlib" ], "isOsiApproved": true, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/zlib-acknowledgement.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/zlib-acknowledgement.json", "referenceNumber": 348, "name": "zlib/libpng License with Acknowledgement", "licenseId": "zlib-acknowledgement", "seeAlso": [ "https://fedoraproject.org/wiki/Licensing/ZlibWithAcknowledgement" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/ZPL-1.1.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/ZPL-1.1.json", "referenceNumber": 545, "name": "Zope Public License 1.1", "licenseId": "ZPL-1.1", "seeAlso": [ "http://old.zope.org/Resources/License/ZPL-1.1" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/ZPL-2.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/ZPL-2.0.json", "referenceNumber": 51, "name": "Zope Public License 2.0", "licenseId": "ZPL-2.0", "seeAlso": [ "http://old.zope.org/Resources/License/ZPL-2.0", "https://opensource.org/licenses/ZPL-2.0" ], "isOsiApproved": true, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/ZPL-2.1.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/ZPL-2.1.json", "referenceNumber": 352, "name": "Zope Public License 2.1", "licenseId": "ZPL-2.1", "seeAlso": [ "http://old.zope.org/Resources/ZPL/" ], "isOsiApproved": true, "isFsfLibre": true } ], "releaseDate": "2024-05-22" }reuse-tool-4.0.3/src/reuse/resources/licenses.json.license000066400000000000000000000001441464275211500236670ustar00rootroot00000000000000# SPDX-FileCopyrightText: Linux Foundation and its Contributors # # SPDX-License-Identifier: CC0-1.0reuse-tool-4.0.3/src/reuse/spdx.py000066400000000000000000000060741464275211500170740ustar00rootroot00000000000000# SPDX-FileCopyrightText: 2017 Free Software Foundation Europe e.V. # SPDX-FileCopyrightText: 2022 Pietro Albini # # SPDX-License-Identifier: GPL-3.0-or-later """Compilation of the SPDX Document.""" import contextlib import logging import sys from argparse import ArgumentParser, Namespace from gettext import gettext as _ from typing import IO from . import _IGNORE_SPDX_PATTERNS from ._util import PathType from .project import Project from .report import ProjectReport _LOGGER = logging.getLogger(__name__) def add_arguments(parser: ArgumentParser) -> None: """Add arguments to the parser.""" parser.add_argument( "--output", "-o", dest="file", action="store", type=PathType("w") ) parser.add_argument( "--add-license-concluded", action="store_true", help=_( "populate the LicenseConcluded field; note that reuse cannot " "guarantee the field is accurate" ), ) parser.add_argument( "--creator-person", metavar="NAME", help=_("name of the person signing off on the SPDX report"), ) parser.add_argument( "--creator-organization", metavar="NAME", help=_("name of the organization signing off on the SPDX report"), ) def run(args: Namespace, project: Project, out: IO[str] = sys.stdout) -> int: """Print the project's bill of materials.""" # The SPDX spec mandates that a creator must be specified when a license # conclusion is made, so here we enforce that. More context: # https://github.com/fsfe/reuse-tool/issues/586#issuecomment-1310425706 if ( args.add_license_concluded and args.creator_person is None and args.creator_organization is None ): args.parser.error( _( "error: --creator-person=NAME or --creator-organization=NAME" " required when --add-license-concluded is provided" ), ) with contextlib.ExitStack() as stack: if args.file: out = stack.enter_context(args.file.open("w", encoding="utf-8")) if not any( pattern.match(args.file.name) for pattern in _IGNORE_SPDX_PATTERNS ): # pylint: disable=line-too-long _LOGGER.warning( _( "'{path}' does not match a common SPDX file pattern. Find" " the suggested naming conventions here:" " https://spdx.github.io/spdx-spec/conformance/#44-standard-data-format-requirements" ).format(path=out.name) ) report = ProjectReport.generate( project, multiprocessing=not args.no_multiprocessing, add_license_concluded=args.add_license_concluded, ) out.write( report.bill_of_materials( creator_person=args.creator_person, creator_organization=args.creator_organization, ) ) return 0 reuse-tool-4.0.3/src/reuse/supported_licenses.py000066400000000000000000000020201464275211500220130ustar00rootroot00000000000000# SPDX-FileCopyrightText: 2021 Free Software Foundation Europe e.V. # SPDX-FileCopyrightText: 2022 Florian Snow # # SPDX-License-Identifier: GPL-3.0-or-later """supported-licenses command handler""" import sys from argparse import ArgumentParser, Namespace from typing import IO from ._licenses import _LICENSES, _load_license_list from .project import Project # pylint: disable=unused-argument def add_arguments(parser: ArgumentParser) -> None: """Add arguments to the parser.""" # pylint: disable=unused-argument def run(args: Namespace, project: Project, out: IO[str] = sys.stdout) -> int: """Print the supported SPDX licenses list""" licenses = _load_license_list(_LICENSES)[1] for license_id, license_info in licenses.items(): license_name = license_info["name"] license_reference = license_info["reference"] out.write( f"{license_id: <40}\t{license_name: <80}\t" f"{license_reference: <50}\n" ) return 0 reuse-tool-4.0.3/src/reuse/templates/000077500000000000000000000000001464275211500175335ustar00rootroot00000000000000reuse-tool-4.0.3/src/reuse/templates/default_template.jinja2000066400000000000000000000004311464275211500241470ustar00rootroot00000000000000{% for copyright_line in copyright_lines %} {{ copyright_line }} {% endfor %} {% for contributor_line in contributor_lines %} SPDX-FileContributor: {{ contributor_line }} {% endfor %} {% for expression in spdx_expressions %} SPDX-License-Identifier: {{ expression }} {% endfor %} reuse-tool-4.0.3/src/reuse/templates/default_template.jinja2.license000066400000000000000000000001671464275211500255760ustar00rootroot00000000000000SPDX-FileCopyrightText: 2019 Free Software Foundation Europe e.V. SPDX-License-Identifier: CC0-1.0 reuse-tool-4.0.3/src/reuse/vcs.py000066400000000000000000000241531464275211500167070ustar00rootroot00000000000000# SPDX-FileCopyrightText: 2017 Free Software Foundation Europe e.V. # SPDX-FileCopyrightText: © 2020 Liferay, Inc. # SPDX-FileCopyrightText: 2020 John Mulligan # SPDX-FileCopyrightText: 2023 Markus Haug # # SPDX-License-Identifier: GPL-3.0-or-later """This module deals with version control systems.""" from __future__ import annotations import logging import os from abc import ABC, abstractmethod from inspect import isclass from pathlib import Path from typing import TYPE_CHECKING, Generator, Optional, Set, Type from ._util import GIT_EXE, HG_EXE, PIJUL_EXE, StrPath, execute_command if TYPE_CHECKING: from .project import Project _LOGGER = logging.getLogger(__name__) class VCSStrategy(ABC): """Strategy pattern for version control systems.""" EXE: str | None = None @abstractmethod def __init__(self, project: Project): self.project = project @abstractmethod def is_ignored(self, path: StrPath) -> bool: """Is *path* ignored by the VCS?""" @abstractmethod def is_submodule(self, path: StrPath) -> bool: """Is *path* a VCS submodule?""" @classmethod @abstractmethod def in_repo(cls, directory: StrPath) -> bool: """Is *directory* inside of the VCS repository? Raises: NotADirectoryError: if directory is not a directory. """ @classmethod @abstractmethod def find_root(cls, cwd: Optional[StrPath] = None) -> Optional[Path]: """Try to find the root of the project from *cwd*. If none is found, return None. Raises: NotADirectoryError: if directory is not a directory. """ class VCSStrategyNone(VCSStrategy): """Strategy that is used when there is no VCS.""" def __init__(self, project: Project): # pylint: disable=useless-super-delegation super().__init__(project) def is_ignored(self, path: StrPath) -> bool: return False def is_submodule(self, path: StrPath) -> bool: return False @classmethod def in_repo(cls, directory: StrPath) -> bool: return False @classmethod def find_root(cls, cwd: Optional[StrPath] = None) -> Optional[Path]: return None class VCSStrategyGit(VCSStrategy): """Strategy that is used for Git.""" EXE = GIT_EXE def __init__(self, project: Project): super().__init__(project) if not self.EXE: raise FileNotFoundError("Could not find binary for Git") self._all_ignored_files = self._find_all_ignored_files() self._submodules = self._find_submodules() def _find_all_ignored_files(self) -> Set[Path]: """Return a set of all files ignored by git. If a whole directory is ignored, don't return all files inside of it. """ command = [ str(self.EXE), "ls-files", "--exclude-standard", "--ignored", "--others", "--directory", # TODO: This flag is unexpected. I reported it as a bug in Git. # This flag---counter-intuitively---lists untracked directories # that contain ignored files. "--no-empty-directory", # Separate output with \0 instead of \n. "-z", ] result = execute_command(command, _LOGGER, cwd=self.project.root) all_files = result.stdout.decode("utf-8").split("\0") return {Path(file_) for file_ in all_files} def _find_submodules(self) -> Set[Path]: command = [ str(self.EXE), "config", "-z", "--file", ".gitmodules", "--get-regexp", r"\.path$", ] result = execute_command(command, _LOGGER, cwd=self.project.root) # The final element may be an empty string. Filter it. submodule_entries = [ entry for entry in result.stdout.decode("utf-8").split("\0") if entry ] # Each entry looks a little like 'submodule.submodule.path\nmy_path'. return {Path(entry.splitlines()[1]) for entry in submodule_entries} def is_ignored(self, path: StrPath) -> bool: path = self.project.relative_from_root(path) return path in self._all_ignored_files def is_submodule(self, path: StrPath) -> bool: return any( self.project.relative_from_root(path).resolve() == submodule_path.resolve() for submodule_path in self._submodules ) @classmethod def in_repo(cls, directory: StrPath) -> bool: if not Path(directory).is_dir(): raise NotADirectoryError() command = [str(cls.EXE), "status"] result = execute_command(command, _LOGGER, cwd=directory) return not result.returncode @classmethod def find_root(cls, cwd: Optional[StrPath] = None) -> Optional[Path]: if cwd is None: cwd = Path.cwd() if not Path(cwd).is_dir(): raise NotADirectoryError() command = [str(cls.EXE), "rev-parse", "--show-toplevel"] result = execute_command(command, _LOGGER, cwd=cwd) if not result.returncode: path = result.stdout.decode("utf-8")[:-1] return Path(os.path.relpath(path, cwd)) return None class VCSStrategyHg(VCSStrategy): """Strategy that is used for Mercurial.""" EXE = HG_EXE def __init__(self, project: Project): super().__init__(project) if not self.EXE: raise FileNotFoundError("Could not find binary for Mercurial") self._all_ignored_files = self._find_all_ignored_files() def _find_all_ignored_files(self) -> Set[Path]: """Return a set of all files ignored by mercurial. If a whole directory is ignored, don't return all files inside of it. """ command = [ str(self.EXE), "status", "--ignored", # terse is marked 'experimental' in the hg help but is documented # in the man page. It collapses the output of a dir containing only # ignored files to the ignored name like the git command does. # TODO: Re-enable this flag in the future. # "--terse=i", "--no-status", "--print0", ] result = execute_command(command, _LOGGER, cwd=self.project.root) all_files = result.stdout.decode("utf-8").split("\0") return {Path(file_) for file_ in all_files} def is_ignored(self, path: StrPath) -> bool: path = self.project.relative_from_root(path) return path in self._all_ignored_files def is_submodule(self, path: StrPath) -> bool: # TODO: Implement me. return False @classmethod def in_repo(cls, directory: StrPath) -> bool: if not Path(directory).is_dir(): raise NotADirectoryError() command = [str(cls.EXE), "root"] result = execute_command(command, _LOGGER, cwd=directory) return not result.returncode @classmethod def find_root(cls, cwd: Optional[StrPath] = None) -> Optional[Path]: if cwd is None: cwd = Path.cwd() if not Path(cwd).is_dir(): raise NotADirectoryError() command = [str(cls.EXE), "root"] result = execute_command(command, _LOGGER, cwd=cwd) if not result.returncode: path = result.stdout.decode("utf-8")[:-1] return Path(os.path.relpath(path, cwd)) return None class VCSStrategyPijul(VCSStrategy): """Strategy that is used for Pijul.""" EXE = PIJUL_EXE def __init__(self, project: Project): super().__init__(project) if not self.EXE: raise FileNotFoundError("Could not find binary for Pijul") self._all_tracked_files = self._find_all_tracked_files() def _find_all_tracked_files(self) -> Set[Path]: """Return a set of all files tracked by pijul.""" command = [str(self.EXE), "list"] result = execute_command(command, _LOGGER, cwd=self.project.root) all_files = result.stdout.decode("utf-8").splitlines() return {Path(file_) for file_ in all_files} def is_ignored(self, path: StrPath) -> bool: path = self.project.relative_from_root(path) return path not in self._all_tracked_files def is_submodule(self, path: StrPath) -> bool: # not supported in pijul yet return False @classmethod def in_repo(cls, directory: StrPath) -> bool: if not Path(directory).is_dir(): raise NotADirectoryError() command = [str(cls.EXE), "diff", "--short"] result = execute_command(command, _LOGGER, cwd=directory) return not result.returncode @classmethod def find_root(cls, cwd: Optional[StrPath] = None) -> Optional[Path]: if cwd is None: cwd = Path.cwd() # TODO this duplicates pijul's logic. # Maybe it should be replaced by calling pijul, # but there is no matching subcommand yet. path = Path(cwd).resolve() if not path.is_dir(): raise NotADirectoryError() while True: if (path / ".pijul").is_dir(): return path parent = path.parent if parent == path: # We reached the filesystem root return None path = parent def all_vcs_strategies() -> Generator[Type[VCSStrategy], None, None]: """Yield all VCSStrategy classes that aren't the abstract base class.""" for value in globals().values(): if ( isclass(value) and issubclass(value, VCSStrategy) and value is not VCSStrategy ): yield value def find_root(cwd: Optional[StrPath] = None) -> Optional[Path]: """Try to find the root of the project from *cwd*. If none is found, return None. Raises: NotADirectoryError: if directory is not a directory. """ for strategy in all_vcs_strategies(): if strategy.EXE: root = strategy.find_root(cwd=cwd) if root: return root return None reuse-tool-4.0.3/tests/000077500000000000000000000000001464275211500147655ustar00rootroot00000000000000reuse-tool-4.0.3/tests/conftest.py000066400000000000000000000335721464275211500171760ustar00rootroot00000000000000# SPDX-FileCopyrightText: 2017 Free Software Foundation Europe e.V. # SPDX-FileCopyrightText: 2022 Carmen Bianca Bakker # SPDX-FileCopyrightText: 2022 Florian Snow # SPDX-FileCopyrightText: 2023 Matthias Riße # # SPDX-License-Identifier: GPL-3.0-or-later """Global fixtures and configuration.""" # pylint: disable=redefined-outer-name,invalid-name import contextlib import datetime import logging import multiprocessing as mp import os import shutil import subprocess import sys from inspect import cleandoc from io import StringIO from pathlib import Path from typing import Generator from unittest.mock import create_autospec import pytest from jinja2 import Environment os.environ["LC_ALL"] = "C" # A trick that tries to import the installed version of reuse. If that doesn't # work, import from the src directory. If that also doesn't work (for some # reason), then an ImportError is raised. try: # pylint: disable=unused-import import reuse except ImportError: sys.path.append(os.path.join(Path(__file__).parent.parent, "src")) finally: from reuse._util import GIT_EXE, HG_EXE, PIJUL_EXE, setup_logging from reuse.global_licensing import ReuseDep5 CWD = Path.cwd() TESTS_DIRECTORY = Path(__file__).parent.resolve() RESOURCES_DIRECTORY = TESTS_DIRECTORY / "resources" try: import pwd is_root = pwd.getpwuid(os.getuid()).pw_name == "root" is_posix = True except ImportError: is_root = False is_posix = False cpython = pytest.mark.skipif( sys.implementation.name != "cpython", reason="only CPython supported" ) git = pytest.mark.skipif(not GIT_EXE, reason="requires git") no_root = pytest.mark.xfail(is_root, reason="fails when user is root") posix = pytest.mark.skipif(not is_posix, reason="Windows not supported") # REUSE-IgnoreStart def pytest_addoption(parser): """Allows specification of additional commandline options to parse""" parser.addoption("--loglevel", action="store", default="DEBUG") def pytest_configure(config): """Called after command line options have been parsed and all plugins and initial conftest files been loaded. """ loglevel = config.getoption("loglevel") setup_logging(level=logging.getLevelName(loglevel)) def pytest_runtest_setup(item): """Called before running a test.""" # pylint: disable=unused-argument # Make sure to restore CWD os.chdir(CWD) # TODO: Awful workaround. In `main`, this environment variable is set under # certain conditions. This means that all tests that run _after_ that # condition is met also have the environment variable set, because the # environment had been changed. There should be a better way to scope this. with contextlib.suppress(KeyError): del os.environ["_SUPPRESS_DEP5_WARNING"] @pytest.fixture() def git_exe() -> str: """Run the test with git.""" if not GIT_EXE: pytest.skip("cannot run this test without git") return str(GIT_EXE) @pytest.fixture() def hg_exe() -> str: """Run the test with mercurial (hg).""" if not HG_EXE: pytest.skip("cannot run this test without mercurial") return str(HG_EXE) @pytest.fixture() def pijul_exe() -> str: """Run the test with Pijul.""" if not PIJUL_EXE: pytest.skip("cannot run this test without pijul") return str(PIJUL_EXE) @pytest.fixture(params=[True, False]) def multiprocessing(request, monkeypatch) -> Generator[bool, None, None]: """Run the test with or without multiprocessing.""" if not request.param: monkeypatch.delattr(mp, "Pool") yield request.param @pytest.fixture(params=[True, False]) def add_license_concluded(request) -> Generator[bool, None, None]: yield request @pytest.fixture() def empty_directory(tmpdir_factory) -> Path: """Create a temporary empty directory.""" directory = Path(str(tmpdir_factory.mktemp("empty_directory"))) os.chdir(str(directory)) return directory @pytest.fixture() def fake_repository(tmpdir_factory) -> Path: """Create a temporary fake repository.""" directory = Path(str(tmpdir_factory.mktemp("fake_repository"))) for file_ in (RESOURCES_DIRECTORY / "fake_repository").iterdir(): if file_.is_file(): shutil.copy(file_, directory / file_.name) elif file_.is_dir(): shutil.copytree(file_, directory / file_.name) # Get rid of those pesky pyc files. shutil.rmtree(directory / "src/__pycache__", ignore_errors=True) # Adding this here to avoid conflict in main project. (directory / "src/exception.py").write_text( "SPDX-FileCopyrightText: 2017 Jane Doe\n" "SPDX-License-Identifier: GPL-3.0-or-later WITH Autoconf-exception-3.0", encoding="utf-8", ) (directory / "src/custom.py").write_text( "SPDX-FileCopyrightText: 2017 Jane Doe\n" "SPDX-License-Identifier: LicenseRef-custom", encoding="utf-8", ) (directory / "src/multiple_licenses.rs").write_text( "SPDX-FileCopyrightText: 2022 Jane Doe\n" "SPDX-License-Identifier: GPL-3.0-or-later\n" "SPDX-License-Identifier: Apache-2.0 OR CC0-1.0" " WITH Autoconf-exception-3.0\n", encoding="utf-8", ) os.chdir(directory) return directory @pytest.fixture() def fake_repository_reuse_toml(fake_repository) -> Path: """Add REUSE.toml to the fake repo.""" shutil.copy( RESOURCES_DIRECTORY / "REUSE.toml", fake_repository / "REUSE.toml" ) (fake_repository / "doc/index.rst").touch() return fake_repository @pytest.fixture() def fake_repository_dep5(fake_repository) -> Path: """Add .reuse/dep5 to the fake repo.""" (fake_repository / ".reuse").mkdir(exist_ok=True) shutil.copy(RESOURCES_DIRECTORY / "dep5", fake_repository / ".reuse/dep5") (fake_repository / "doc/index.rst").touch() return fake_repository def _repo_contents( fake_repository, ignore_filename=".gitignore", ignore_prefix="" ): """Generate contents for a vcs repository. Currently defaults to git-like behavior for ignoring files with the expectation that other tools can be configured to ignore files by just chanigng the ignore-file-name and enabling git-like behavior with a prefix line in the ignore file. """ gitignore = ignore_prefix + ( "# SPDX-License-Identifier: CC0-1.0\n" "# SPDX-FileCopyrightText: 2017 Jane Doe\n" "*.pyc\nbuild" ) (fake_repository / ignore_filename).write_text(gitignore) (fake_repository / "LICENSES/CC0-1.0.txt").write_text("License text") for file_ in (fake_repository / "src").iterdir(): if file_.suffix == ".py": file_.with_suffix(".pyc").write_text("foo") build_dir = fake_repository / "build" build_dir.mkdir() (build_dir / "hello.py").write_text("foo") @pytest.fixture() def git_repository(fake_repository: Path, git_exe: str) -> Path: """Create a git repository with ignored files.""" os.chdir(fake_repository) _repo_contents(fake_repository) # TODO: To speed this up, maybe directly write to '.gitconfig' instead. subprocess.run([git_exe, "init", str(fake_repository)], check=True) subprocess.run([git_exe, "config", "user.name", "Example"], check=True) subprocess.run( [git_exe, "config", "user.email", "example@example.com"], check=True ) subprocess.run([git_exe, "config", "commit.gpgSign", "false"], check=True) subprocess.run([git_exe, "add", str(fake_repository)], check=True) subprocess.run( [ git_exe, "commit", "-m", "initial", ], check=True, ) return fake_repository @pytest.fixture() def hg_repository(fake_repository: Path, hg_exe: str) -> Path: """Create a mercurial repository with ignored files.""" os.chdir(fake_repository) _repo_contents( fake_repository, ignore_filename=".hgignore", ignore_prefix="syntax:glob", ) subprocess.run([hg_exe, "init", "."], check=True) subprocess.run([hg_exe, "addremove"], check=True) subprocess.run( [ hg_exe, "commit", "--user", "Example ", "-m", "initial", ], check=True, ) return fake_repository @pytest.fixture() def pijul_repository(fake_repository: Path, pijul_exe: str) -> Path: """Create a pijul repository with ignored files.""" os.chdir(fake_repository) _repo_contents( fake_repository, ignore_filename=".ignore", ) subprocess.run([pijul_exe, "init", "."], check=True) subprocess.run([pijul_exe, "add", "--recursive", "."], check=True) subprocess.run( [ pijul_exe, "record", "--all", "--message", "initial", ], check=True, ) return fake_repository @pytest.fixture(params=["submodule-add", "manual"]) def submodule_repository( git_repository: Path, git_exe: str, tmpdir_factory, request ) -> Path: """Create a git repository that contains a submodule.""" header = cleandoc( """ SPDX-FileCopyrightText: 2019 Jane Doe SPDX-License-Identifier: CC0-1.0 """ ) submodule = Path(str(tmpdir_factory.mktemp("submodule"))) (submodule / "foo.py").write_text(header, encoding="utf-8") os.chdir(submodule) subprocess.run([git_exe, "init", str(submodule)], check=True) subprocess.run([git_exe, "config", "user.name", "Example"], check=True) subprocess.run( [git_exe, "config", "user.email", "example@example.com"], check=True ) subprocess.run([git_exe, "add", str(submodule)], check=True) subprocess.run( [ git_exe, "commit", "-m", "initial", ], check=True, ) os.chdir(git_repository) if request.param == "submodule-add": subprocess.run( [ git_exe, # https://git-scm.com/docs/git-config#Documentation/git-config.txt-protocolallow # # This circumvents a bug/behaviour caused by CVE-2022-39253 # where you cannot use `git submodule add repository path` where # repository is a file on the filesystem. "-c", "protocol.file.allow=always", "submodule", "add", str(submodule.resolve()), "submodule", ], check=True, ) elif request.param == "manual": subprocess.run( [git_exe, "clone", str(submodule.resolve()), "submodule"], check=True, ) with open( git_repository / ".gitmodules", mode="a", encoding="utf-8" ) as gitmodules_file: gitmodules_file.write( f"""[submodule "submodule"] path = submodule url = {submodule.resolve().as_posix()} """ ) subprocess.run( [ git_exe, "add", "--no-warn-embedded-repo", ".gitmodules", "submodule", ], check=True, ) subprocess.run( [git_exe, "commit", "-m", "add submodule"], check=True, ) (git_repository / ".gitmodules.license").write_text(header) return git_repository @pytest.fixture(scope="session") def reuse_dep5(): """Create a ReuseDep5 object.""" return ReuseDep5.from_file(RESOURCES_DIRECTORY / "dep5") @pytest.fixture() def stringio(): """Create a StringIO object.""" return StringIO() @pytest.fixture() def binary_string(): """Create a binary string.""" return bytes(range(256)) @pytest.fixture() def template_simple_source(): """Source code of simple Jinja2 template.""" return cleandoc( """ Hello, world! {% for copyright_line in copyright_lines %} {{ copyright_line }} {% endfor %} {% for expression in spdx_expressions %} SPDX-License-Identifier: {{ expression }} {% endfor %} """.replace( "spdx-Lic", "SPDX-Lic" ) ) @pytest.fixture() def template_simple(template_simple_source): """Provide a simple Jinja2 template.""" env = Environment(trim_blocks=True) return env.from_string(template_simple_source) @pytest.fixture() def template_no_spdx_source(): """Source code of Jinja2 template without SPDX lines.""" return "Hello, world" @pytest.fixture() def template_no_spdx(template_no_spdx_source): """Provide a Jinja2 template without SPDX lines.""" env = Environment(trim_blocks=True) return env.from_string(template_no_spdx_source) @pytest.fixture() def template_commented_source(): """Source code of a simple Jinja2 template that is already commented.""" return cleandoc( """ # Hello, world! # {% for copyright_line in copyright_lines %} # {{ copyright_line }} {% endfor %} # {% for expression in spdx_expressions %} # SPDX-License-Identifier: {{ expression }} {% endfor %} """.replace( "spdx-Lic", "SPDX-Lic" ) ) @pytest.fixture() def template_commented(template_commented_source): """Provide a Jinja2 template that is already commented.""" env = Environment(trim_blocks=True) return env.from_string(template_commented_source) @pytest.fixture() def mock_date_today(monkeypatch): """Mock away datetime.date.today to always return 2018.""" date = create_autospec(datetime.date) date.today.return_value = datetime.date(2018, 1, 1) monkeypatch.setattr(datetime, "date", date) @pytest.fixture( params=[[], ["John Doe"], ["John Doe", "Alice Doe"]], ids=["None", "John", "John and Alice"], ) def contributors(request): """Provide contributors for SPDX-FileContributor field generation""" yield request.param # REUSE-IgnoreEnd reuse-tool-4.0.3/tests/resources/000077500000000000000000000000001464275211500167775ustar00rootroot00000000000000reuse-tool-4.0.3/tests/resources/REUSE.toml000066400000000000000000000003371464275211500205620ustar00rootroot00000000000000# SPDX-FileCopyrightText: 2017 Jane Doe # # SPDX-License-Identifier: CC0-1.0 version = 1 [[annotations]] path = "doc/*" precedence = "override" SPDX-FileCopyrightText = "2017 Jane Doe" SPDX-License-Identifier = "CC0-1.0" reuse-tool-4.0.3/tests/resources/dep5000066400000000000000000000002031464275211500175520ustar00rootroot00000000000000Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Files: doc/* Copyright: 2017 Jane Doe License: CC0-1.0 reuse-tool-4.0.3/tests/resources/fake_repository/000077500000000000000000000000001464275211500222045ustar00rootroot00000000000000reuse-tool-4.0.3/tests/resources/fake_repository/LICENSES/000077500000000000000000000000001464275211500234115ustar00rootroot00000000000000reuse-tool-4.0.3/tests/resources/fake_repository/LICENSES/Apache-2.0.txt000066400000000000000000000000161464275211500256250ustar00rootroot00000000000000License text. reuse-tool-4.0.3/tests/resources/fake_repository/LICENSES/Autoconf-exception-3.0.txt000066400000000000000000000000161464275211500302170ustar00rootroot00000000000000Exception textreuse-tool-4.0.3/tests/resources/fake_repository/LICENSES/CC0-1.0.txt000066400000000000000000000000151464275211500250070ustar00rootroot00000000000000License text reuse-tool-4.0.3/tests/resources/fake_repository/LICENSES/GPL-3.0-or-later.txt000066400000000000000000000000151464275211500266110ustar00rootroot00000000000000License text reuse-tool-4.0.3/tests/resources/fake_repository/LICENSES/LicenseRef-custom.txt000066400000000000000000000000001464275211500274670ustar00rootroot00000000000000reuse-tool-4.0.3/tests/resources/fake_repository/doc/000077500000000000000000000000001464275211500227515ustar00rootroot00000000000000reuse-tool-4.0.3/tests/resources/fake_repository/doc/usage.md000066400000000000000000000001201464275211500243700ustar00rootroot00000000000000 reuse-tool-4.0.3/tests/resources/fake_repository/src/000077500000000000000000000000001464275211500227735ustar00rootroot00000000000000reuse-tool-4.0.3/tests/resources/fake_repository/src/custom.py000066400000000000000000000000721464275211500246560ustar00rootroot00000000000000# This file is overridden by the fake_repository fixture. reuse-tool-4.0.3/tests/resources/fake_repository/src/exception.py000066400000000000000000000000721464275211500253420ustar00rootroot00000000000000# This file is overridden by the fake_repository fixture. reuse-tool-4.0.3/tests/resources/fake_repository/src/multiple_licenses.rs000066400000000000000000000000731464275211500270610ustar00rootroot00000000000000// This file is overridden by the fake_repository fixture. reuse-tool-4.0.3/tests/resources/fake_repository/src/source_code.c000066400000000000000000000002341464275211500254300ustar00rootroot00000000000000/* SPDX-FileCopyrightText: 2017 Jane Doe */ /* SPDX-License-Identifier: GPL-3.0-or-later */ #include main() { printf("Hello, world!\n"); } reuse-tool-4.0.3/tests/resources/fake_repository/src/source_code.html000066400000000000000000000001571464275211500261560ustar00rootroot00000000000000

Hello, world!

reuse-tool-4.0.3/tests/resources/fake_repository/src/source_code.jinja2000066400000000000000000000001551464275211500263650ustar00rootroot00000000000000{# SPDX-FileCopyrightText: 2017 Jane Doe SPDX-License-Identifier: GPL-3.0-or-later #}

Hello, world!

reuse-tool-4.0.3/tests/resources/fake_repository/src/source_code.py000066400000000000000000000002461464275211500256410ustar00rootroot00000000000000# SPDX-FileCopyrightText: 2017 Jane Doe # # SPDX-License-Identifier: GPL-3.0-or-later """Module docstring.""" if __name__ == "__main__": print("Hello, world!") reuse-tool-4.0.3/tests/resources/fsfe.png000066400000000000000000000125121464275211500204310ustar00rootroot00000000000000PNG  IHDRmFqbKGD pHYs  tIME4IDATxyu?s3!8$Äke]ETU]u`DD˭E-t]]D]IhaH&h dfr&\L\dLt{UIM%j@3{(]`\or.הPx6ChtJ{ ^XD\jB)#_+ tUxI1KA^E1[ ( mqxM)q:4/$ gS=q64šEQm3Nʥ ;yQ xRC/+eQWj  œLÀ#qݗh=xM s欸yYSĢ WY~=x^ [4{ˌƈlXNՊ-~lsF*|iIɅ-x 08Ֆ=^YM\D,iUowTYB#fAJ`Ţ6O}jŲ]T21G3IbpDO-@\;WOl9׹;x}RnbDTfR9kC)g⺚'7XM\瀥M Ѹs2:OMHH t鞩BI$dmTw%W'~g:ouooBfaqu|IznBB6&s~!ЁG [3od,XTO9>\%9N*={eSqE!tU|3o[H)yhU02VG ѻg=;Ƃ^=Ϸ۝NG^%[*=PQ}l'/vwÎmmD zÂ2cЖpW?@{%6uYbgN`lh^8QzQ m&&O~ԕ0r%1],qEkD.."7s6Ю>618h 4]^BlafEqa"Dw{x{/˿#c(E !Ta4~G@@U(Upǀ+]ռZ80䜥b=]\aXL*r;sm}<5ź]R,FGkw k#hvCwR 0 魳`b;LɸjmTI,ۍ[,ȰctdzX\ '^o+K9>#ډw]Lub;JC[ޖ-)xmzյ,cGLd/`-˳ͻubv Yodwz?j48md}u!rDbp}XlV uE>$˶5rzUY[Ђqs&q9pO/Oߴp|MKӎ^[BW`Dɚ\D6rn/ WYRœr3DAϲ1tc.(m^#-NCwAF( pgB6qFG <NA5 F(DgX6I[ }vv[_^(j hڭe-YK i++%] ̀ ɤr p̤Q|ȶi!re6i1-0 ArXf̸g(^*o}W׺16y3yĿYO%IQXL}L?5l' =3MeBq۶ilY<\j(IilgŸ<'P19 gyٱx;/7iL-Uw*xvڸL62x"f, Mhzׯv3iIy4dq6TkldCdD \ԓ)}-s%,KG҅%;oNGx@wP0Ԩ+src!-JD# t9"]ծlvCy|feDc`кY]^2z6`PQHk&,6kӋU+h;N[Ñ鿥@eC&Wln JV+`$Dz;NoT.PKZ?Ah Ȗ4zAw"V.섫*Uk տ3dqLܪ:/Ah'[*^յIC|5YCaTYWA'Kc~hDtn_4FَzR2<]&U׺+\Z ^IQZcYWIKndΟM!.I,nf">KG}b3r#tEn_k.wt_v韌 UXg%+bƻ dwJ?쇺M;MpPd6`3k]J/B{RPn3ʌ_(CAh(.6TO xFn"_N[g4tmF8}xFcD Q.&ߣ2'ˏ0/ }dSHYeh;]RhXeeXd 3$ksR3sq*{OAWT"Ȓ`^ܵ0|]e,סl,BEr#pэJiy"gG48/ɺX G=UhG./o!PBxWbX<~sEV1GBxX<^U:rQcn6td|61# VrR׀x/Q֏ȃ[Vw= <0@dݶ9<_{)4ӏy%3u?7E"_B{-)uLo `b4=O'?߬wX {˝N8oa:=Tß7;Tymr|DPϸZzXC|մxLuqPi<UHrPYV7 g\Ƣk; @@*thFe:,w`?M!6W?&qOYgtCO t9qj P # SPDX-FileCopyrightText: 2023 Maxim Cournoyer # # SPDX-License-Identifier: GPL-3.0-or-later """All tests for reuse.comment""" # pylint: disable=protected-access,invalid-name,redefined-outer-name from inspect import cleandoc from textwrap import dedent import pytest from reuse.comment import ( CommentCreateError, CommentParseError, CommentStyle, CppCommentStyle, HtmlCommentStyle, LispCommentStyle, PythonCommentStyle, _all_style_classes, ) @pytest.fixture( params=[ Style for Style in _all_style_classes() if Style.can_handle_single() ] ) def SingleStyle(request): """Yield all Style classes that support single-line comments.""" yield request.param @pytest.fixture( params=[Style for Style in _all_style_classes() if Style.can_handle_multi()] ) def MultiStyle(request): """Yield all Style classes that support multi-line comments.""" yield request.param def test_create_comment_generic_single(SingleStyle): """Create a comment for all classes that support single-line comments.""" text = "Hello" expected = ( f"{SingleStyle.SINGLE_LINE}{SingleStyle.INDENT_AFTER_SINGLE}Hello" ) assert SingleStyle.create_comment(text) == expected def test_create_comment_generic_multi(MultiStyle): """Create a comment for all classes that support multi-line comments.""" # pylint: disable=line-too-long text = "Hello" expected = cleandoc( f""" {MultiStyle.MULTI_LINE.start} {MultiStyle.INDENT_BEFORE_MIDDLE}{MultiStyle.MULTI_LINE.middle}{MultiStyle.INDENT_AFTER_MIDDLE}Hello {MultiStyle.INDENT_BEFORE_END}{MultiStyle.MULTI_LINE.end} """ ) assert MultiStyle.create_comment(text, force_multi=True) == expected def test_parse_comment_generic_single(SingleStyle): """Parse a comment for all classes that support single-line comments.""" text = f"{SingleStyle.SINGLE_LINE}{SingleStyle.INDENT_AFTER_SINGLE}Hello" expected = "Hello" assert SingleStyle.parse_comment(text) == expected def test_parse_comment_generic_multi(MultiStyle): """Parse a comment for all classes that support multi-line comments.""" # pylint: disable=line-too-long text = cleandoc( f""" {MultiStyle.MULTI_LINE.start} {MultiStyle.INDENT_BEFORE_MIDDLE}{MultiStyle.MULTI_LINE.middle}{MultiStyle.INDENT_AFTER_MIDDLE}Hello {MultiStyle.INDENT_BEFORE_END}{MultiStyle.MULTI_LINE.end} """ ) expected = "Hello" assert MultiStyle.parse_comment(text) == expected def test_parse_comment_sameline_multi(MultiStyle): """If a multi-line comment style is on a single line, it should still be parsed. """ text = cleandoc( f""" {MultiStyle.MULTI_LINE.start} Hello {MultiStyle.MULTI_LINE.end} """ ) expected = "Hello" assert MultiStyle.parse_comment(text) == expected def test_base_class_throws_errors(): """When trying to do much of anything with the base class, expect errors.""" with pytest.raises(CommentParseError): CommentStyle.parse_comment("hello") with pytest.raises(CommentCreateError): CommentStyle.create_comment("hello") with pytest.raises(CommentParseError): CommentStyle.comment_at_first_character("hello") def test_create_comment_python(): """Create a simple Python comment.""" text = cleandoc( """ Hello world """ ) expected = cleandoc( """ # Hello # # world """ ) assert PythonCommentStyle.create_comment(text) == expected def test_parse_comment_python(): """Parse a simple Python comment.""" text = cleandoc( """ # Hello # # world """ ) expected = cleandoc( """ Hello world """ ) assert PythonCommentStyle.parse_comment(text) == expected def test_parse_comment_python_indented(): """Preserve indentations in Python comments.""" text = cleandoc( """ # def foo(): # print("foo") """ ) expected = cleandoc( """ def foo(): print("foo") """ ) assert PythonCommentStyle.parse_comment(text) == expected def test_create_comment_python_dont_strip_newlines(): """Include newlines in the comment.""" text = "\nhello\n" expected = cleandoc( """ # # hello # """ ) assert PythonCommentStyle.create_comment(text) == expected def test_create_comment_python_force_multi(): """Raise CommentCreateError when creating a multi-line Python comment.""" with pytest.raises(CommentCreateError): PythonCommentStyle.create_comment("hello", force_multi=True) def test_parse_comment_python_fail_on_newline(): """If a provided comment does not start with the comment character, fail.""" text = dedent( """ # # hello # """ ) with pytest.raises(CommentParseError): assert PythonCommentStyle.parse_comment(text) def test_parse_comment_python_not_a_comment(): """Raise CommentParseError when a comment isn't provided.""" text = "Hello world" with pytest.raises(CommentParseError): PythonCommentStyle.parse_comment(text) def test_parse_comment_python_single_line_is_not_comment(): """Raise CommentParseError when a single line is not a comment.""" text = cleandoc( """ # Hello world """ ) with pytest.raises(CommentParseError): PythonCommentStyle.parse_comment(text) def test_parse_comment_python_multi_error(): """Raise CommentParseError when trying to parse a multi-line Python comment. """ with pytest.raises(CommentParseError): PythonCommentStyle._parse_comment_multi("Hello world") def test_create_comment_cpp_single(): """Create a C++ comment with single-line comments.""" text = cleandoc( """ Hello world """ ) expected = cleandoc( """ // Hello // world """ ) assert CppCommentStyle.create_comment(text) == expected def test_parse_comment_cpp_single(): """Parse a C++ comment with single-line comments.""" text = cleandoc( """ // Hello // world """ ) expected = cleandoc( """ Hello world """ ) assert CppCommentStyle.parse_comment(text) == expected def test_create_comment_cpp_multi(): """Create a C++ comment with multi-line comments.""" text = cleandoc( """ Hello world """ ) expected = cleandoc( """ /* * Hello * world */ """ ) assert CppCommentStyle.create_comment(text, force_multi=True) == expected def test_create_comment_cpp_multi_empty_newlines(): """Create a C++ comment that contains empty lines.""" text = cleandoc( """ Hello world """ ) expected = cleandoc( """ /* * Hello * * world */ """ ) assert CppCommentStyle.create_comment(text, force_multi=True) == expected def test_create_comment_cpp_multi_surrounded_by_newlines(): """Create a C++ comment that is surrounded by empty lines.""" text = "\nHello\nworld\n" expected = cleandoc( """ /* * * Hello * world * */ """ ) assert CppCommentStyle.create_comment(text, force_multi=True) == expected def test_create_comment_cpp_multi_contains_ending(): """Raise CommentCreateError when the text contains a comment ending.""" text = cleandoc( """ Hello world */ """ ) with pytest.raises(CommentCreateError): CppCommentStyle.create_comment(text, force_multi=True) def test_parse_comment_cpp_multi(): """Parse a C++ comment with multi-line comments.""" text = cleandoc( """ /* * Hello * world */ """ ) expected = cleandoc( """ Hello world """ ) assert CppCommentStyle.parse_comment(text) == expected def test_parse_comment_cpp_multi_missing_middle(): """Parse a C++ comment even though the middle markers are missing.""" text = cleandoc( """ /* Hello world */ """ ) expected = cleandoc( """ Hello world """ ) assert CppCommentStyle.parse_comment(text) == expected def test_parse_comment_cpp_multi_misaligned_end(): """Parse a C++ comment even though the end is misaligned.""" text = cleandoc( """ /* * Hello * world */ """ ) expected = cleandoc( """ Hello world """ ) assert CppCommentStyle.parse_comment(text) == expected text = cleandoc( """ /* * Hello * world */ """ ) expected = cleandoc( """ Hello world """ ) assert CppCommentStyle.parse_comment(text) == expected def test_parse_comment_cpp_multi_no_middle(): """Parse a C++ comment that has no middle whatsoever.""" text = cleandoc( """ /* Hello * world */ """ ) expected = cleandoc( """ Hello world """ ) assert CppCommentStyle.parse_comment(text) == expected def test_parse_comment_cpp_multi_ends_at_last(): """Parse a C++ comment that treats the last line like a regular line.""" text = cleandoc( """ /* * Hello * world */ """ ) expected = cleandoc( """ Hello world """ ) assert CppCommentStyle.parse_comment(text) == expected def test_parse_comment_cpp_multi_starts_at_first(): """Parse a C++ comment that treats the first line like a regular line.""" text = cleandoc( """ /* Hello * world */ """ ) expected = cleandoc( """ Hello world """ ) assert CppCommentStyle.parse_comment(text) == expected def test_parse_comment_cpp_multi_indented(): """Preserve indentations in C++ comments.""" text = cleandoc( """ /* * Hello * world */ """ ) expected = cleandoc( """ Hello world """ ) assert CppCommentStyle.parse_comment(text) == expected def test_parse_comment_cpp_multi_single_line(): """Parse a single-line multi-line comment.""" text = "/* Hello world */" expected = "Hello world" assert CppCommentStyle.parse_comment(text) == expected def test_parse_comment_cpp_multi_no_start(): """Raise CommentParseError when there is no comment starter.""" text = "Hello world */" with pytest.raises(CommentParseError): CppCommentStyle.parse_comment(text) with pytest.raises(CommentParseError): CppCommentStyle._parse_comment_multi(text) def test_parse_comment_cpp_multi_no_end(): """Raise CommentParseError when there is no comment end.""" text = "/* Hello world" with pytest.raises(CommentParseError): CppCommentStyle.parse_comment(text) def test_parse_comment_cpp_multi_text_after_end(): """Raise CommentParseError when there is stuff after the comment delimiter. """ text = cleandoc( """ /* * Hello * world */ Spam """ ) with pytest.raises(CommentParseError): CppCommentStyle.parse_comment(text) def test_create_comment_html(): """Create an HTML comment.""" text = cleandoc( """ Hello world """ ) expected = cleandoc( """ """ ) assert HtmlCommentStyle.create_comment(text) == expected def test_parse_comment_html(): """Parse an HTML comment.""" text = cleandoc( """ """ ) expected = cleandoc( """ Hello world """ ) assert HtmlCommentStyle.parse_comment(text) == expected def test_create_comment_html_single(): """Creating a single-line HTML comment fails.""" with pytest.raises(CommentCreateError): HtmlCommentStyle._create_comment_single("hello") def test_parse_comment_html_single_line(): """Parse a single-line HTML comment.""" text = "" expected = "Hello world" assert HtmlCommentStyle.parse_comment(text) == expected def test_comment_at_first_character_python(): """Find the comment block at the first character.""" text = cleandoc( """ # Hello # world Spam """ ) expected = cleandoc( """ # Hello # world """ ) assert PythonCommentStyle.comment_at_first_character(text) == expected def test_comment_at_first_character_python_no_comment(): """The text does not start with a comment character.""" with pytest.raises(CommentParseError): PythonCommentStyle.comment_at_first_character(" # Hello world") def test_comment_at_first_character_python_indented_comments(): """Don't handle indented comments.""" text = cleandoc( """ # Hello # world """ ) expected = "# Hello" assert PythonCommentStyle.comment_at_first_character(text) == expected def test_comment_at_first_character_cpp_multi(): """Simple test for a multi-line C++ comment.""" text = cleandoc( """ /* * Hello * world */ Spam """ ) expected = cleandoc( """ /* * Hello * world */ """ ) assert CppCommentStyle.comment_at_first_character(text) == expected def test_comment_at_first_character_cpp_multi_never_ends(): """Expect CommentParseError if the comment never ends.""" text = cleandoc( """ /* * Hello * world /* """ ) with pytest.raises(CommentParseError): CppCommentStyle.comment_at_first_character(text) def test_parse_comment_lisp(): """Parse a simple Lisp comment.""" text = cleandoc( """ ;; Hello ;; ;; world """ ) expected = cleandoc( """ Hello world """ ) assert LispCommentStyle.parse_comment(text) == expected reuse-tool-4.0.3/tests/test_convert_dep5.py000066400000000000000000000202651464275211500210000ustar00rootroot00000000000000# SPDX-FileCopyrightText: 2024 Carmen Bianca BAKKER # # SPDX-License-Identifier: GPL-3.0-or-later """Tests for convert_dep5.""" # pylint: disable=line-too-long from io import StringIO from debian.copyright import Copyright from reuse._util import cleandoc_nl from reuse.convert_dep5 import toml_from_dep5 def test_toml_from_dep5_single_file(): """Correctly convert a DEP5 file with a single file.""" text = StringIO( cleandoc_nl( """ Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Files: hello.txt Copyright: 2018 Jane Doe License: MIT """ ) ) expected = cleandoc_nl( """ version = 1 [[annotations]] path = "hello.txt" precedence = "aggregate" SPDX-FileCopyrightText = "2018 Jane Doe" SPDX-License-Identifier = "MIT" """ ) assert toml_from_dep5(Copyright(text)) == expected def test_toml_from_dep5_asterisks(): """Single asterisks get converted to double asterisks. Double asterisks get left alone. """ text = StringIO( cleandoc_nl( """ Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Files: */**/*** Copyright: 2018 Jane Doe License: MIT """ ) ) expected = cleandoc_nl( """ version = 1 [[annotations]] path = "**/**/***" precedence = "aggregate" SPDX-FileCopyrightText = "2018 Jane Doe" SPDX-License-Identifier = "MIT" """ ) assert toml_from_dep5(Copyright(text)) == expected def test_toml_from_dep5_multiple_files_in_paragraph(): """Correctly convert a DEP5 file with a more files in a paragraph.""" text = StringIO( cleandoc_nl( """ Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Files: hello.txt foo*.txt Copyright: 2018 Jane Doe License: MIT """ ) ) expected = cleandoc_nl( """ version = 1 [[annotations]] path = ["hello.txt", "foo**.txt"] precedence = "aggregate" SPDX-FileCopyrightText = "2018 Jane Doe" SPDX-License-Identifier = "MIT" """ ) assert toml_from_dep5(Copyright(text)) == expected def test_toml_from_dep5_multiple_paragraphs(): """Correctly convert a DEP5 file with multiple paragraphs.""" text = StringIO( cleandoc_nl( """ Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Files: hello.txt Copyright: 2018 Jane Doe License: MIT Files: world.txt Copyright: 2018 John Doe License: 0BSD """ ) ) expected = cleandoc_nl( """ version = 1 [[annotations]] path = "hello.txt" precedence = "aggregate" SPDX-FileCopyrightText = "2018 Jane Doe" SPDX-License-Identifier = "MIT" [[annotations]] path = "world.txt" precedence = "aggregate" SPDX-FileCopyrightText = "2018 John Doe" SPDX-License-Identifier = "0BSD" """ ) assert toml_from_dep5(Copyright(text)) == expected def test_toml_from_dep5_multiple_copyright(): """Correctly convert a DEP5 file with multiple copyright holders.""" text = StringIO( cleandoc_nl( """ Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Files: hello.txt Copyright: 2018 Jane Doe 2018 John Doe License: MIT """ ) ) expected = cleandoc_nl( """ version = 1 [[annotations]] path = "hello.txt" precedence = "aggregate" SPDX-FileCopyrightText = ["2018 Jane Doe", "2018 John Doe"] SPDX-License-Identifier = "MIT" """ ) assert toml_from_dep5(Copyright(text)) == expected def test_toml_from_dep5_comments(): """Optionally include comments.""" text = StringIO( cleandoc_nl( """ Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Files: hello.txt Copyright: 2018 Jane Doe License: MIT Comment: hello Files: world.txt Copyright: 2018 Jane Doe License: MIT """ ) ) expected = cleandoc_nl( """ version = 1 [[annotations]] path = "hello.txt" precedence = "aggregate" SPDX-FileCopyrightText = "2018 Jane Doe" SPDX-License-Identifier = "MIT" SPDX-FileComment = "hello" [[annotations]] path = "world.txt" precedence = "aggregate" SPDX-FileCopyrightText = "2018 Jane Doe" SPDX-License-Identifier = "MIT" """ ) assert toml_from_dep5(Copyright(text)) == expected def test_toml_from_dep5_header(): """Optionally include header fields.""" text = StringIO( cleandoc_nl( """ Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Upstream-Name: Some project Upstream-Contact: Jane Doe Source: https://example.com/ Disclaimer: Some rights reserved Files: hello.txt Copyright: 2018 Jane Doe License: MIT """ ) ) expected = cleandoc_nl( """ version = 1 SPDX-PackageName = "Some project" SPDX-PackageSupplier = "Jane Doe" SPDX-PackageDownloadLocation = "https://example.com/" SPDX-PackageComment = "Some rights reserved" [[annotations]] path = "hello.txt" precedence = "aggregate" SPDX-FileCopyrightText = "2018 Jane Doe" SPDX-License-Identifier = "MIT" """ ) assert toml_from_dep5(Copyright(text)) == expected def test_toml_from_dep5_header_multiple_contacts(): """Return a list of contacts.""" text = StringIO( cleandoc_nl( """ Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Upstream-Contact: Jane Doe John Doe Files: hello.txt Copyright: 2018 Jane Doe License: MIT """ ) ) expected = cleandoc_nl( """ version = 1 SPDX-PackageSupplier = ["Jane Doe", "John Doe"] [[annotations]] path = "hello.txt" precedence = "aggregate" SPDX-FileCopyrightText = "2018 Jane Doe" SPDX-License-Identifier = "MIT" """ ) assert toml_from_dep5(Copyright(text)) == expected def test_toml_from_dep5_man_example(): """Test the example from the man page.""" text = StringIO( cleandoc_nl( """ Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Upstream-Name: Some project Upstream-Contact: Jane Doe Source: https://example.com/ Disclaimer: Some rights reserved Files: hello*.txt Copyright: 2018 Jane Doe License: MIT Comment: hello world Files: foo bar Copyright: 2018 Jane Doe 2019 John Doe License: MIT """ ) ) expected = cleandoc_nl( """ version = 1 SPDX-PackageName = "Some project" SPDX-PackageSupplier = "Jane Doe" SPDX-PackageDownloadLocation = "https://example.com/" SPDX-PackageComment = "Some rights reserved" [[annotations]] path = "hello**.txt" precedence = "aggregate" SPDX-FileCopyrightText = "2018 Jane Doe" SPDX-License-Identifier = "MIT" SPDX-FileComment = "hello world" [[annotations]] path = ["foo", "bar"] precedence = "aggregate" SPDX-FileCopyrightText = ["2018 Jane Doe", "2019 John Doe"] SPDX-License-Identifier = "MIT" """ ) assert toml_from_dep5(Copyright(text)) == expected reuse-tool-4.0.3/tests/test_core.py000066400000000000000000000073771464275211500173440ustar00rootroot00000000000000# SPDX-FileCopyrightText: 2023 Carmen Bianca BAKKER # # SPDX-License-Identifier: GPL-3.0-or-later """Tests for some core components.""" import pytest from reuse import ReuseInfo, SourceType # REUSE-IgnoreStart def test_reuse_info_contains_copyright_or_licensing(): """If either spdx_expressions or copyright_lines is truthy, expect True.""" arguments = [ ({"GPL-3.0-or-later"}, set()), (set(), "SPDX-FileCopyrightText: 2017 Jane Doe"), ({"GPL-3.0-or-later"}, "SPDX-FileCopyrightText: 2017 Jane Doe"), ] for args in arguments: info = ReuseInfo(*args) assert info.contains_copyright_or_licensing() def test_reuse_info_contains_copyright_or_licensing_empty(): """If the ReuseInfo object is completely empty, expect False.""" info = ReuseInfo() assert not info.contains_copyright_or_licensing() def test_reuse_info_contains_copyright_or_licensing_other_truthy(): """If another attribute is truthy, still expect False.""" info = ReuseInfo(contributor_lines={"SPDX-FileContributor: 2017 Jane Doe"}) assert not info.contains_copyright_or_licensing() def test_reuse_info_contains_copyright_xor_licensing(): """A simple xor version of the previous function.""" assert not ReuseInfo().contains_copyright_xor_licensing() assert not ReuseInfo( spdx_expressions={"MIT"}, copyright_lines={"Copyright Jane Doe"} ).contains_copyright_xor_licensing() assert ReuseInfo( spdx_expressions={"MIT"} ).contains_copyright_xor_licensing() assert ReuseInfo( copyright_lines={"Copyright Jane Doe"} ).contains_copyright_xor_licensing() def test_reuse_info_contains_info_simple(): """If any of the non-source files are truthy, expect True.""" assert ReuseInfo(spdx_expressions={"MIT"}).contains_info() assert ReuseInfo( copyright_lines={"SPDX-FileCopyrightText: 2017 Jane Doe"} ).contains_info() assert ReuseInfo( contributor_lines={"SPDX-FileContributor: 2017 John Doe"} ).contains_info() def test_reuse_info_contains_info_empty(): """If the ReuseInfo object is empty, expect False.""" info = ReuseInfo() assert not info.contains_info() def test_reuse_info_contains_info_source_truthy(): """If any of the source information is truthy, still expect False.""" assert not ReuseInfo(source_path="foo.py").contains_info() assert not ReuseInfo(source_type=SourceType.FILE_HEADER).contains_info() def test_reuse_info_copy_simple(): """Get a copy of ReuseInfo with one field replaced.""" info = ReuseInfo( spdx_expressions={"GPL-3.0-or-later"}, copyright_lines={"2017 Jane Doe"}, source_path="foo", ) new_info = info.copy(source_path="bar") assert info != new_info assert info.spdx_expressions == new_info.spdx_expressions assert info.copyright_lines == new_info.copyright_lines assert info.source_path != new_info.source_path assert new_info.source_path == "bar" def test_reuse_info_copy_nonexistent_attribute(): """ Expect a KeyError when trying to copy a nonexistent field into ReuseInfo. """ info = ReuseInfo() with pytest.raises(KeyError): info.copy(foo="bar") def test_reuse_info_union_simple(): """ Get a union of ReuseInfo with one field merged and one remaining equal. """ info1 = ReuseInfo( copyright_lines={"2017 Jane Doe"}, source_path="foo", ) info2 = ReuseInfo(copyright_lines={"2017 John Doe"}, source_path="bar") new_info = info1 | info2 # union and __or__ are equal assert new_info == info1.union(info2) assert sorted(new_info.copyright_lines) == [ "2017 Jane Doe", "2017 John Doe", ] assert new_info.source_path == "foo" # REUSE-IgnoreEnd reuse-tool-4.0.3/tests/test_download.py000066400000000000000000000122741464275211500202130ustar00rootroot00000000000000# SPDX-FileCopyrightText: 2019 Free Software Foundation Europe e.V. # # SPDX-License-Identifier: GPL-3.0-or-later """All tests for reuse.download""" import urllib.request from pathlib import Path from urllib.error import URLError import pytest from reuse.download import download_license, put_license_in_file class MockResponse: """Super simple mocked version of Response.""" def __init__(self, text=None, status_code=None): self.text = text self.status_code = status_code def __enter__(self): return self def __exit__(self, type_, value, traceback): return False def read(self): return self.text.encode("utf-8") def getcode(self): return self.status_code def test_download(monkeypatch): """A straightforward test: Request license text, get license text.""" monkeypatch.setattr( urllib.request, "urlopen", lambda _: MockResponse("hello", 200) ) result = download_license("0BSD") assert result == "hello" def test_download_404(monkeypatch): """If the server returns a 404, there is no license text.""" monkeypatch.setattr( urllib.request, "urlopen", lambda _: MockResponse(status_code=404) ) with pytest.raises(URLError): download_license("does-not-exist") def test_download_exception(monkeypatch): """If urllib raises an exception itself, that exception is not escaped.""" def raise_exception(_): raise URLError("test") monkeypatch.setattr(urllib.request, "urlopen", raise_exception) with pytest.raises(URLError): download_license("hello world") def test_put_simple(fake_repository, monkeypatch): """Straightforward test.""" monkeypatch.setattr( urllib.request, "urlopen", lambda _: MockResponse("hello\n", 200) ) put_license_in_file("0BSD", "LICENSES/0BSD.txt") assert (fake_repository / "LICENSES/0BSD.txt").read_text() == "hello\n" def test_put_file_exists(fake_repository, monkeypatch): """The to-be-downloaded file already exists.""" # pylint: disable=unused-argument monkeypatch.setattr( urllib.request, "urlopen", lambda _: MockResponse("hello\n", 200) ) with pytest.raises(FileExistsError) as exc_info: put_license_in_file("GPL-3.0-or-later", "LICENSES/GPL-3.0-or-later.txt") assert Path(exc_info.value.filename).name == "GPL-3.0-or-later.txt" def test_put_request_exception(fake_repository, monkeypatch): """There was an error while downloading the license file.""" # pylint: disable=unused-argument monkeypatch.setattr( urllib.request, "urlopen", lambda _: MockResponse(status_code=404) ) with pytest.raises(URLError): put_license_in_file("0BSD", "LICENSES/0BSD.txt") def test_put_empty_dir(empty_directory, monkeypatch): """Create a LICENSES/ directory if one does not yet exist.""" monkeypatch.setattr( urllib.request, "urlopen", lambda _: MockResponse("hello\n", 200) ) put_license_in_file("0BSD", "LICENSES/0BSD.txt") assert (empty_directory / "LICENSES").exists() assert (empty_directory / "LICENSES/0BSD.txt").read_text() == "hello\n" def test_put_custom_without_source(fake_repository): """When 'downloading' a LicenseRef license without source, create an empty file. """ put_license_in_file("LicenseRef-hello", "LICENSES/LicenseRef-hello.txt") assert (fake_repository / "LICENSES/LicenseRef-hello.txt").exists() assert (fake_repository / "LICENSES/LicenseRef-hello.txt").read_text() == "" def test_put_custom_with_source(fake_repository): """When 'downloading' a LicenseRef license with source file, copy the source text. """ (fake_repository / "foo.txt").write_text("foo") put_license_in_file( "LicenseRef-hello", "LICENSES/LicenseRef-hello.txt", source=fake_repository / "foo.txt", ) assert (fake_repository / "LICENSES/LicenseRef-hello.txt").exists() assert ( fake_repository / "LICENSES/LicenseRef-hello.txt" ).read_text() == "foo" def test_put_custom_with_source_dir(fake_repository): """When 'downloading' a LicenseRef license with source directory, copy the source text from a matching file in the directory. """ (fake_repository / "lics").mkdir() (fake_repository / "lics/LicenseRef-hello.txt").write_text("foo") put_license_in_file( "LicenseRef-hello", "LICENSES/LicenseRef-hello.txt", source=fake_repository / "lics", ) assert (fake_repository / "LICENSES/LicenseRef-hello.txt").exists() assert ( fake_repository / "LICENSES/LicenseRef-hello.txt" ).read_text() == "foo" def test_put_custom_with_false_source_dir(fake_repository): """When 'downloading' a LicenseRef license with source directory, but the source directory does not contain the license, expect a FileNotFoundError. """ (fake_repository / "lics").mkdir() with pytest.raises(FileNotFoundError) as exc_info: put_license_in_file( "LicenseRef-hello", "LICENSES/LicenseRef-hello.txt", source=fake_repository / "lics", ) assert exc_info.value.filename.endswith( str(Path("lics") / "LicenseRef-hello.txt") ) reuse-tool-4.0.3/tests/test_global_licensing.py000066400000000000000000001101511464275211500216700ustar00rootroot00000000000000# SPDX-FileCopyrightText: 2023 Free Software Foundation Europe e.V. # # SPDX-License-Identifier: GPL-3.0-or-later """Tests for REUSE.toml and .reuse/dep5.""" import shutil from inspect import cleandoc from pathlib import Path import pytest from conftest import RESOURCES_DIRECTORY, posix from debian.copyright import Copyright from license_expression import LicenseSymbol from reuse import ReuseInfo, SourceType from reuse._util import _LICENSING from reuse.global_licensing import ( AnnotationsItem, GlobalLicensingParseError, GlobalLicensingParseTypeError, GlobalLicensingParseValueError, NestedReuseTOML, PrecedenceType, ReuseDep5, ReuseTOML, ) # REUSE-IgnoreStart # pylint: disable=redefined-outer-name,too-many-lines @pytest.fixture() def annotations_item(): return AnnotationsItem({"foo.py"}, "override", {"2023 Jane Doe"}, {"MIT"}) class TestAnnotationsItemValidators: """Test the validators of AnnotationsItem.""" def test_simple(self): """Create an AnnotationsItem, passing all validators.""" item = AnnotationsItem( {"foo.py"}, "override", {"2023 Jane Doe"}, {"MIT"}, ) assert item.paths == {"foo.py"} assert item.precedence == PrecedenceType.OVERRIDE assert item.copyright_lines == {"2023 Jane Doe"} assert item.spdx_expressions == {_LICENSING.parse("MIT")} def test_precedence_defaults_to_closest(self): """If precedence is NOTHING, default to closest.""" item = AnnotationsItem( {"foo.py"}, copyright_lines={"2023 Jane Doe"}, spdx_expressions={"MIT"}, ) assert item.precedence == PrecedenceType.CLOSEST def test_from_list(self): """Convert lists to sets.""" item = AnnotationsItem( ["foo.py"], "override", ["2023 Jane Doe"], ["MIT"], ) assert item.paths == {"foo.py"} assert item.precedence == PrecedenceType.OVERRIDE assert item.copyright_lines == {"2023 Jane Doe"} assert item.spdx_expressions == {_LICENSING.parse("MIT")} def test_str_to_set(self): """Convert strings to sets.""" item = AnnotationsItem( "foo.py", "override", "2023 Jane Doe", "MIT", ) assert item.paths == {"foo.py"} assert item.precedence == PrecedenceType.OVERRIDE assert item.copyright_lines == {"2023 Jane Doe"} assert item.spdx_expressions == {_LICENSING.parse("MIT")} def test_bad_expr(self): """Raise an error on malformed SPDX expressions.""" with pytest.raises(GlobalLicensingParseError): AnnotationsItem( {"foo.py"}, {"MIT OR"}, ) def test_bad_literal(self): """Only a limited set of literal are accepted for precedence.""" with pytest.raises(GlobalLicensingParseValueError): AnnotationsItem( {"foo.py"}, "foobar", ) def test_not_str(self): """Copyright must be a string.""" with pytest.raises(GlobalLicensingParseTypeError): AnnotationsItem( {"foo.py"}, copyright_lines=123, ) def test_not_set_of_str(self): """Copyright must be a set of strings.""" with pytest.raises(GlobalLicensingParseTypeError): AnnotationsItem( {"foo.py"}, copyright_lines={"2023 Jane Doe", 2024}, ) def test_paths_must_not_be_empty(self): """'paths' may not be an empty list.""" with pytest.raises(GlobalLicensingParseValueError): AnnotationsItem( set(), ) def test_everything_except_path_optional(self): """All fields except path are optional.""" AnnotationsItem({"foo.py"}) class TestAnnotationsItemFromDict: """Test AnnotationsItem's from_dict method.""" def test_simple(self): """A simple case.""" item = AnnotationsItem.from_dict( { "path": {"foo.py"}, "precedence": "override", "SPDX-FileCopyrightText": {"2023 Jane Doe"}, "SPDX-License-Identifier": {"MIT"}, } ) assert item.paths == {"foo.py"} assert item.precedence == PrecedenceType.OVERRIDE assert item.copyright_lines == {"2023 Jane Doe"} assert item.spdx_expressions == {_LICENSING.parse("MIT")} def test_implicit_precedence(self): """When precedence is not defined, default to closest.""" item = AnnotationsItem.from_dict( { "path": {"foo.py"}, } ) assert item.precedence == PrecedenceType.CLOSEST def test_trigger_validators(self): """It's possible to trigger the validators by providing a bad value.""" with pytest.raises(GlobalLicensingParseTypeError): AnnotationsItem.from_dict( { "path": {123}, } ) def test_path_missing(self): """If the path key is missing, raise an error.""" with pytest.raises(GlobalLicensingParseValueError): AnnotationsItem.from_dict( { "precedence": "override", "SPDX-FileCopyrightText": {"2023 Jane Doe"}, "SPDX-License-Identifier": {"MIT"}, } ) def test_path_none(self): """If the path key is None, raise an error.""" with pytest.raises(GlobalLicensingParseValueError): AnnotationsItem.from_dict( { "path": None, } ) def test_one_key_missing(self): """If one REUSE info key is missing, raise no error.""" item = AnnotationsItem.from_dict( { "path": {"foo.py"}, "SPDX-License-Identifier": {"MIT"}, } ) assert not item.copyright_lines assert isinstance(item.copyright_lines, set) def test_both_keys_missing(self): """If both REUSE info keys are missing, raise no error.""" item = AnnotationsItem.from_dict( { "path": {"foo.py"}, } ) assert not item.copyright_lines assert not item.spdx_expressions class TestAnnotationsItemMatches: """Test AnnotationsItem's matches method.""" def test_simple(self): """Simple case.""" item = AnnotationsItem(paths=["foo.py"]) assert item.matches("foo.py") assert not item.matches("src/foo.py") assert not item.matches("bar.py") def test_in_directory(self): """Correctly handle pathname separators. Looking at you, Windows.""" item = AnnotationsItem(paths=["src/foo.py"]) assert item.matches("src/foo.py") assert not item.matches("foo.py") def test_all_py(self): """Correctly find all Python files.""" item = AnnotationsItem(paths=["**/*.py"]) assert item.matches("foo.py") assert item.matches(".foo.py") assert item.matches("src/foo.py") assert not item.matches("src/foo.js") def test_only_in_dir(self): """Only find files in a certain directory.""" item = AnnotationsItem(paths=["src/*.py"]) assert not item.matches("foo.py") assert item.matches("src/foo.py") assert not item.matches("src/other/foo.py") def test_asterisk(self): """Match everything in local directory.""" item = AnnotationsItem(paths=["*"]) assert item.matches("foo.py") assert item.matches(".gitignore") assert not item.matches("src/foo.py") assert not item.matches(".foo/bar") def test_asterisk_asterisk(self): """Match everything.""" item = AnnotationsItem(paths=["**"]) assert item.matches("foo.py") assert item.matches(".gitignore") assert item.matches("src/foo.py") assert item.matches(".foo/bar") def test_escape_asterisk(self): """Handle escape asterisk.""" item = AnnotationsItem(paths=[r"\*.py"]) assert item.matches("*.py") assert not item.matches("foo.py") def test_escape_asterisk_asterisk(self): """Handle escape asterisk asterisk.""" item = AnnotationsItem(paths=[r"\**.py"]) assert item.matches("*foo.py") assert not item.matches("foo.py") def test_escape_asterisk_escape_asterisk(self): """Handle escape asterisk escape asterisk.""" item = AnnotationsItem(paths=[r"\*\*.py"]) assert item.matches("**.py") assert not item.matches("foo.py") assert not item.matches("*foo.py") def test_escape_asterisk_asterisk_slash_asterisk(self): """Handle escape asterisk asterisk slash asterisk.""" item = AnnotationsItem(paths=[r"\**/*.py"]) assert item.matches("*foo/foo.py") assert not item.matches("bar/foo.py") def test_escape_asterisk_escape_asterisk_slash_asterisk(self): """Handle escape asterisk escape asterisk slash asterisk.""" item = AnnotationsItem(paths=[r"\*\*/*.py"]) assert item.matches("**/foo.py") assert not item.matches("bar/foo.py") assert not item.matches("*foo/foo.py") def test_escape_escape_asterisk(self): """Handle escape escape asterisk.""" item = AnnotationsItem(paths=[r"\\*.py"]) assert item.matches(r"\foo.py") def test_asterisk_asterisk_asterisk(self): """Handle asterisk asterisk asterisk.""" item = AnnotationsItem(paths=[r"***.py"]) assert item.matches("foo/bar/quz.py") def test_escape_a(self): """Handle escape a.""" item = AnnotationsItem(paths=[r"\a"]) assert item.matches(r"a") assert not item.matches(r"\a") def test_middle_asterisk(self): """See what happens if the asterisk is in the middle of the path.""" item = AnnotationsItem(paths=["foo*bar"]) assert item.matches("foobar") assert item.matches("foo2bar") assert not item.matches("foo") assert not item.matches("bar") assert not item.matches("foo/bar") def test_multiple_paths(self): """Match one of multiple files.""" item = AnnotationsItem(paths=["*.py", "*.js", "README"]) assert item.matches("foo.py") assert item.matches(".foo.py") assert item.matches("foo.js") assert item.matches("README") assert item.matches("README.py") assert not item.matches("README.md") def test_match_all(self): """Match everything.""" item = AnnotationsItem(paths=["**"]) assert item.matches("foo.py") assert item.matches("src/foo.py") assert item.matches(".gitignore") assert item.matches(".foo/bar") class TestReuseTOMLValidators: """Test the validators of ReuseTOML.""" def test_simple(self, annotations_item): """Pass the validators""" result = ReuseTOML( version=1, source="REUSE.toml", annotations=[annotations_item] ) assert result.version == 1 assert result.source == "REUSE.toml" assert result.annotations[0] == annotations_item def test_version_not_int(self, annotations_item): """Version must be an int""" with pytest.raises(GlobalLicensingParseTypeError): ReuseTOML( version=1.2, source="REUSE.toml", annotations=[annotations_item] ) def test_source_not_str(self, annotations_item): """Source must be a str.""" with pytest.raises(GlobalLicensingParseTypeError): ReuseTOML(version=1, source=123, annotations=[annotations_item]) def test_annotations_must_be_list(self, annotations_item): """Annotations must be in a list, not any other collection.""" # TODO: Technically we could change this to 'any collection that is # ordered', but let's not split hairs. with pytest.raises(GlobalLicensingParseTypeError): ReuseTOML( version=1, source="REUSE.toml", annotations=iter([annotations_item]), ) def test_annotations_must_be_object(self): """Annotations must be AnnotationsItem objects.""" with pytest.raises(GlobalLicensingParseTypeError): ReuseTOML( version=1, source="REUSE.toml", annotations=[{"foo": "bar"}] ) class TestReuseTOMLFromDict: """Test the from_dict method of ReuseTOML.""" def test_simple(self, annotations_item): """Simple case.""" result = ReuseTOML.from_dict( { "version": 1, "annotations": [ { "path": {"foo.py"}, "precedence": "override", "SPDX-FileCopyrightText": {"2023 Jane Doe"}, "SPDX-License-Identifier": {"MIT"}, } ], }, "REUSE.toml", ) assert result.version == 1 assert result.source == "REUSE.toml" assert result.annotations[0] == annotations_item def test_no_annotations(self): """It's OK to not provide annotations.""" result = ReuseTOML.from_dict({"version": 1}, source="REUSE.toml") assert result.annotations == [] def test_annotations_empty_list(self): """It's OK if annotations is an empty list.""" result = ReuseTOML.from_dict( {"version": 1, "annotations": []}, source="REUSE.toml" ) assert result.annotations == [] def test_no_version(self): """If the version is missing, raise an error.""" with pytest.raises(GlobalLicensingParseTypeError): ReuseTOML.from_dict( { "annotations": [ { "path": {"foo.py"}, "precedence": "override", "SPDX-FileCopyrightText": {"2023 Jane Doe"}, "SPDX-License-Identifier": {"MIT"}, } ], }, "REUSE.toml", ) class TestReuseTOMLFromToml: """Test the from_toml method of ReuseTOML.""" def test_simple(self, annotations_item): """Simple case""" text = cleandoc( """ version = 1 [[annotations]] path = "foo.py" precedence = "override" SPDX-FileCopyrightText = "2023 Jane Doe" SPDX-License-Identifier = "MIT" """ ) result = ReuseTOML.from_toml(text, "REUSE.toml") assert result.version == 1 assert result.source == "REUSE.toml" assert result.annotations[0] == annotations_item def test_syntax_error(self): """If there is a TOML syntax error, raise a GlobalLicensingParseError""" with pytest.raises(GlobalLicensingParseError): ReuseTOML.from_toml("version = 1,", "REUSE.toml") class TestReuseTOMLEscaping: """Test the escaping functionality in paths in conjunction with reading from TOML. """ def test_escape_asterisk(self): """Handle escape asterisk.""" text = cleandoc( r""" version = 1 [[annotations]] path = "\\*.py" SPDX-FileCopyrightText = "2023 Jane Doe" SPDX-License-Identifier = "MIT" """ ) toml = ReuseTOML.from_toml(text, "REUSE.toml") assert toml.reuse_info_of(r"*.py") assert not toml.reuse_info_of(r"\*.py") assert not toml.reuse_info_of(r"foo.py") assert not toml.reuse_info_of(r"\foo.py") @posix def test_escape_escape(self): """Handle escape escape.""" text = cleandoc( r""" version = 1 [[annotations]] path = "\\\\.py" SPDX-FileCopyrightText = "2023 Jane Doe" SPDX-License-Identifier = "MIT" """ ) toml = ReuseTOML.from_toml(text, "REUSE.toml") assert toml.reuse_info_of(r"\.py") class TestReuseTOMLReuseInfoOf: """Test the reuse_info_of method of ReuseTOML.""" def test_simple(self, annotations_item): """Simple test.""" reuse_toml = ReuseTOML("REUSE.toml", 1, [annotations_item]) assert reuse_toml.reuse_info_of("foo.py") == { PrecedenceType.OVERRIDE: [ ReuseInfo( spdx_expressions={_LICENSING.parse("MIT")}, copyright_lines={"2023 Jane Doe"}, path="foo.py", source_path="REUSE.toml", source_type=SourceType.REUSE_TOML, ) ] } def test_latest_annotations_item(self, annotations_item): """If two items match, use exclusively the latest.""" reuse_toml = ReuseTOML( "REUSE.toml", 1, [ annotations_item, AnnotationsItem( paths={"foo.py"}, precedence="override", copyright_lines={"2023 John Doe"}, spdx_expressions={"0BSD"}, ), ], ) assert reuse_toml.reuse_info_of("foo.py") == { PrecedenceType.OVERRIDE: [ ReuseInfo( spdx_expressions={_LICENSING.parse("0BSD")}, copyright_lines={"2023 John Doe"}, path="foo.py", source_path="REUSE.toml", source_type=SourceType.REUSE_TOML, ) ] } def test_glob_all(self): """When globbing all, match everything.""" reuse_toml = ReuseTOML( "REUSE.toml", 1, [ AnnotationsItem( paths={"**"}, precedence="override", copyright_lines={"2023 Jane Doe"}, spdx_expressions={"MIT"}, ), ], ) # Expected sans path expected = ReuseInfo( spdx_expressions={_LICENSING.parse("MIT")}, copyright_lines={"2023 Jane Doe"}, source_path="REUSE.toml", source_type=SourceType.REUSE_TOML, ) assert reuse_toml.reuse_info_of("foo.py") == { PrecedenceType.OVERRIDE: [expected.copy(path="foo.py")] } assert reuse_toml.reuse_info_of("bar.py") == { PrecedenceType.OVERRIDE: [expected.copy(path="bar.py")] } assert reuse_toml.reuse_info_of("dir/subdir/foo.py") == { PrecedenceType.OVERRIDE: [expected.copy(path="dir/subdir/foo.py")] } def test_glob_py(self): """When globbing Python paths, match only .py files.""" reuse_toml = ReuseTOML( "REUSE.toml", 1, [ AnnotationsItem( paths={"**/*.py"}, precedence="override", copyright_lines={"2023 Jane Doe"}, spdx_expressions={"MIT"}, ), ], ) assert reuse_toml.reuse_info_of("dir/foo.py") == { PrecedenceType.OVERRIDE: [ ReuseInfo( spdx_expressions={_LICENSING.parse("MIT")}, copyright_lines={"2023 Jane Doe"}, path="dir/foo.py", source_path="REUSE.toml", source_type=SourceType.REUSE_TOML, ) ] } assert not reuse_toml.reuse_info_of("foo.c") class TestReuseTOMLFromFile: """Test the from-file method of ReuseTOML.""" def test_simple(self, annotations_item, empty_directory): """Simple case.""" (empty_directory / "REUSE.toml").write_text( cleandoc( """ version = 1 [[annotations]] path = "foo.py" precedence = "override" SPDX-FileCopyrightText = "2023 Jane Doe" SPDX-License-Identifier = "MIT" """ ) ) result = ReuseTOML.from_file("REUSE.toml") assert result.version == 1 assert result.source == "REUSE.toml" assert result.annotations[0] == annotations_item def test_precedence_implicit(self, empty_directory): """When precedence is not set, default to closest.""" (empty_directory / "REUSE.toml").write_text( cleandoc( """ version = 1 [[annotations]] path = "foo.py" SPDX-FileCopyrightText = "2023 Jane Doe" SPDX-License-Identifier = "MIT" """ ) ) result = ReuseTOML.from_file("REUSE.toml") assert result.annotations[0].precedence == PrecedenceType.CLOSEST class TestReuseTOMLDirectory: """Test the directory property of ReuseTOML.""" def test_no_parent(self): """Test what happens if the source has no obvious parent.""" toml = ReuseTOML(source="REUSE.toml", version=1, annotations=[]) assert toml.directory == Path(".") def test_nested(self): """Correctly identify the directory of a nested file.""" toml = ReuseTOML(source="src/REUSE.toml", version=1, annotations=[]) assert toml.directory == Path("src") class TestNestedReuseTOMLFromFile: """Tests for NestedReuseTOML.from_file.""" def test_simple(self, fake_repository_reuse_toml): """Find a single REUSE.toml.""" result = NestedReuseTOML.from_file(fake_repository_reuse_toml) path = fake_repository_reuse_toml / "REUSE.toml" assert result.reuse_tomls == [ReuseTOML.from_file(path)] def test_one_deep(self, empty_directory): """Find a single REUSE.toml deeper in the directory tree.""" (empty_directory / "src").mkdir() path = empty_directory / "src/REUSE.toml" path.write_text("version = 1") result = NestedReuseTOML.from_file(empty_directory) assert result.reuse_tomls == [ReuseTOML.from_file(path)] def test_multiple(self, fake_repository_reuse_toml): """Find multiple REUSE.tomls.""" (fake_repository_reuse_toml / "src/REUSE.toml").write_text( "version = 1" ) result = NestedReuseTOML.from_file(fake_repository_reuse_toml) assert len(result.reuse_tomls) == 2 assert ( ReuseTOML.from_file(fake_repository_reuse_toml / "src/REUSE.toml") ) in result.reuse_tomls assert ( ReuseTOML.from_file(fake_repository_reuse_toml / "REUSE.toml") in result.reuse_tomls ) class TestNestedReuseTOMLFindReuseTomls: """Tests for NestedReuseTOML.find_reuse_tomls.""" def test_simple(self, fake_repository_reuse_toml): """Find a single REUSE.toml.""" result = NestedReuseTOML.find_reuse_tomls(fake_repository_reuse_toml) assert list(result) == [fake_repository_reuse_toml / "REUSE.toml"] def test_one_deep(self, empty_directory): """Find a single REUSE.toml deeper in the directory tree.""" (empty_directory / "src").mkdir() path = empty_directory / "src/REUSE.toml" path.touch() result = NestedReuseTOML.find_reuse_tomls(empty_directory) assert list(result) == [path] def test_multiple(self, fake_repository_reuse_toml): """Find multiple REUSE.tomls.""" (fake_repository_reuse_toml / "src/REUSE.toml").touch() result = NestedReuseTOML.find_reuse_tomls(fake_repository_reuse_toml) assert set(result) == { fake_repository_reuse_toml / "REUSE.toml", fake_repository_reuse_toml / "src/REUSE.toml", } class TestNestedReuseTOMLReuseInfoOf: """Tests for NestedReuseTOML.reuse_info_of.""" def test_simple(self, annotations_item): """Simple case.""" reuse_toml = ReuseTOML("REUSE.toml", 1, [annotations_item]) nested_reuse_toml = NestedReuseTOML(".", [reuse_toml]) assert nested_reuse_toml.reuse_info_of("foo.py") == { PrecedenceType.OVERRIDE: [ ReuseInfo( spdx_expressions={_LICENSING.parse("MIT")}, copyright_lines={"2023 Jane Doe"}, path="foo.py", source_path="REUSE.toml", source_type=SourceType.REUSE_TOML, ) ] } assert not nested_reuse_toml.reuse_info_of("bar.py") def test_no_tomls(self): """Don't break when there are no nested ReuseTOMLs.""" nested_reuse_toml = NestedReuseTOML(".", []) assert not nested_reuse_toml.reuse_info_of("foo.py") def test_skip_outer_closest(self): """If a precedence is set to 'closest', it is ignored unless it is the deepest element. """ outer = ReuseTOML( "REUSE.toml", 1, [ AnnotationsItem( "src/**", precedence=PrecedenceType.CLOSEST, copyright_lines={"Copyright Jane Doe"}, spdx_expressions={"MIT"}, ) ], ) inner = ReuseTOML( "src/REUSE.toml", 1, [ AnnotationsItem( "foo.py", precedence=PrecedenceType.CLOSEST, copyright_lines={"Copyright Alice"}, spdx_expressions={"0BSD"}, ) ], ) toml = NestedReuseTOML(".", [outer, inner]) assert toml.reuse_info_of("src/foo.py") == { PrecedenceType.CLOSEST: [ ReuseInfo( spdx_expressions={_LICENSING.parse("0BSD")}, copyright_lines={"Copyright Alice"}, path="src/foo.py", source_path="src/REUSE.toml", source_type=SourceType.REUSE_TOML, ) ] } assert toml.reuse_info_of("src/bar.py") == { PrecedenceType.CLOSEST: [ ReuseInfo( spdx_expressions={_LICENSING.parse("MIT")}, copyright_lines={"Copyright Jane Doe"}, path="src/bar.py", source_path="REUSE.toml", source_type=SourceType.REUSE_TOML, ) ] } def test_aggregate(self): """If a precedence is set to aggregate, aggregate.""" outer = ReuseTOML( "REUSE.toml", 1, [ AnnotationsItem( "src/**", precedence=PrecedenceType.AGGREGATE, copyright_lines={"Copyright Jane Doe"}, spdx_expressions={"MIT"}, ) ], ) inner = ReuseTOML( "src/REUSE.toml", 1, [ AnnotationsItem( "foo.py", precedence=PrecedenceType.CLOSEST, copyright_lines={"Copyright Alice"}, spdx_expressions={"0BSD"}, ) ], ) toml = NestedReuseTOML(".", [outer, inner]) assert toml.reuse_info_of("src/foo.py") == { PrecedenceType.AGGREGATE: [ ReuseInfo( spdx_expressions={_LICENSING.parse("MIT")}, copyright_lines={"Copyright Jane Doe"}, path="src/foo.py", source_path="REUSE.toml", source_type=SourceType.REUSE_TOML, ) ], PrecedenceType.CLOSEST: [ ReuseInfo( spdx_expressions={_LICENSING.parse("0BSD")}, copyright_lines={"Copyright Alice"}, path="src/foo.py", source_path="src/REUSE.toml", source_type=SourceType.REUSE_TOML, ), ], } def test_toml_precedence(self): """If a precedence is set to toml, ignore deeper TOMLs.""" outer = ReuseTOML( "REUSE.toml", 1, [ AnnotationsItem( "src/**", precedence=PrecedenceType.OVERRIDE, copyright_lines={"Copyright Jane Doe"}, spdx_expressions={"MIT"}, ) ], ) inner = ReuseTOML( "src/REUSE.toml", 1, [ AnnotationsItem( "foo.py", precedence=PrecedenceType.CLOSEST, copyright_lines={"Copyright Alice"}, spdx_expressions={"0BSD"}, ) ], ) toml = NestedReuseTOML(".", [outer, inner]) assert toml.reuse_info_of("src/foo.py") == { PrecedenceType.OVERRIDE: [ ReuseInfo( spdx_expressions={_LICENSING.parse("MIT")}, copyright_lines={"Copyright Jane Doe"}, path="src/foo.py", source_path="REUSE.toml", source_type=SourceType.REUSE_TOML, ), ] } def test_toml_and_aggregate(self): """If the top TOML says aggregate and a deeper TOML has precedence toml, aggregate accordingly. """ outer = ReuseTOML( "REUSE.toml", 1, [ AnnotationsItem( "foo/bar/**", precedence=PrecedenceType.AGGREGATE, copyright_lines={"Copyright Jane Doe"}, spdx_expressions={"MIT"}, ) ], ) mid = ReuseTOML( "foo/REUSE.toml", 1, [ AnnotationsItem( "bar/**", precedence=PrecedenceType.OVERRIDE, copyright_lines={"Copyright Alice"}, spdx_expressions={"0BSD"}, ) ], ) inner = ReuseTOML( "foo/bar/REUSE.toml", 1, [ AnnotationsItem( "foo.py", precedence=PrecedenceType.OVERRIDE, copyright_lines={"Copyright Bob"}, spdx_expressions={"CC0-1.0"}, ) ], ) toml = NestedReuseTOML(".", [outer, mid, inner]) assert toml.reuse_info_of("foo/bar/foo.py") == { PrecedenceType.AGGREGATE: [ ReuseInfo( spdx_expressions={_LICENSING.parse("MIT")}, copyright_lines={"Copyright Jane Doe"}, path="foo/bar/foo.py", source_path="REUSE.toml", source_type=SourceType.REUSE_TOML, ), ], PrecedenceType.OVERRIDE: [ ReuseInfo( spdx_expressions={_LICENSING.parse("0BSD")}, copyright_lines={"Copyright Alice"}, path="foo/bar/foo.py", source_path="foo/REUSE.toml", source_type=SourceType.REUSE_TOML, ), ], } def test_dont_go_up_hierarchy(self): """If a deep REUSE.toml contains instructions for a dir-globbed file, don't match against files named as such in parent directories. """ deep = ReuseTOML( "src/REUSE.toml", 1, [ AnnotationsItem( "**/foo.py", precedence=PrecedenceType.CLOSEST, copyright_lines={"Copyright Alice"}, spdx_expressions={"0BSD"}, ) ], ) toml = NestedReuseTOML(".", [deep]) assert toml.reuse_info_of("src/foo.py") assert toml.reuse_info_of("src/bar/foo.py") assert not toml.reuse_info_of("foo.py") assert not toml.reuse_info_of("doc/foo.py") def test_dont_go_up_directory(self): """If a deep REUSE.toml contains an instruction for '../foo.py', don't match it against anything. """ deep = ReuseTOML( "src/REUSE.toml", 1, [ AnnotationsItem( "../foo.py", precedence=PrecedenceType.CLOSEST, copyright_lines={"Copyright Alice"}, spdx_expressions={"0BSD"}, ) ], ) toml = NestedReuseTOML(".", [deep]) assert not toml.reuse_info_of("src/foo.py") assert not toml.reuse_info_of("foo.py") def test_aggregate_incomplete_info(self): """If one REUSE.toml defines the copyright, and a different one contains the licence, then both bits of information should be used. """ outer = ReuseTOML( "REUSE.toml", 1, [ AnnotationsItem( "src/foo.txt", precedence=PrecedenceType.CLOSEST, spdx_expressions={"MIT"}, ) ], ) inner = ReuseTOML( "src/REUSE.toml", 1, [ AnnotationsItem( "foo.txt", precedence=PrecedenceType.CLOSEST, copyright_lines={"Copyright Jane Doe"}, ) ], ) toml = NestedReuseTOML(".", [outer, inner]) infos = toml.reuse_info_of("src/foo.txt")[PrecedenceType.CLOSEST] assert len(infos) == 2 class TestReuseDep5FromFile: """Tests for ReuseDep5.from_file.""" def test_simple(self, fake_repository_dep5): """No error if everything is good.""" result = ReuseDep5.from_file(fake_repository_dep5 / ".reuse/dep5") assert result.__class__ == ReuseDep5 assert result.dep5_copyright.__class__ == Copyright assert result.source == str(fake_repository_dep5 / ".reuse/dep5") def test_not_exists(self, empty_directory): """Raise FileNotFoundError if .reuse/dep5 doesn't exist.""" with pytest.raises(FileNotFoundError): ReuseDep5.from_file(empty_directory / "foo") def test_unicode_decode_error(self, fake_repository_dep5): """Raise UnicodeDecodeError if file can't be decoded as utf-8.""" shutil.copy( RESOURCES_DIRECTORY / "fsfe.png", fake_repository_dep5 / "fsfe.png" ) with pytest.raises(UnicodeDecodeError): ReuseDep5.from_file(fake_repository_dep5 / "fsfe.png") def test_parse_error(self, empty_directory): """Raise GlobalLicensingParseError on parse error.""" (empty_directory / "foo").write_text("foo") with pytest.raises(GlobalLicensingParseError): ReuseDep5.from_file(empty_directory / "foo") def test_double_copyright_parse_error(self, empty_directory): """Raise GlobalLicensingParseError on double Copyright lines.""" (empty_directory / "foo").write_text( cleandoc( """ Format: something Upstream-Name: example Upstream-Contact: Jane Doe Source: https://example.com Files: * Copyright: Jane Doe Copyright: John Doe License: MIT """ ) ) with pytest.raises(GlobalLicensingParseError): ReuseDep5.from_file(empty_directory / "foo") def test_reuse_dep5_reuse_info_of(reuse_dep5): """Verify that the glob in the dep5 file is matched.""" infos = reuse_dep5.reuse_info_of("doc/foo.rst") assert len(infos) == 1 assert len(infos[PrecedenceType.AGGREGATE]) == 1 result = infos[PrecedenceType.AGGREGATE][0] assert LicenseSymbol("CC0-1.0") in result.spdx_expressions assert "2017 Jane Doe" in result.copyright_lines # REUSE-IgnoreEnd reuse-tool-4.0.3/tests/test_header.py000066400000000000000000000257401464275211500176360ustar00rootroot00000000000000# SPDX-FileCopyrightText: 2019 Free Software Foundation Europe e.V. # SPDX-FileCopyrightText: 2022 Florian Snow # SPDX-FileCopyrightText: 2024 Carmen Bianca BAKKER # # SPDX-License-Identifier: GPL-3.0-or-later """All tests for reuse.header""" from inspect import cleandoc import pytest from reuse import ReuseInfo from reuse.comment import CommentCreateError, CppCommentStyle from reuse.header import ( MissingReuseInfo, add_new_header, create_header, find_and_replace_header, ) # REUSE-IgnoreStart def test_create_header_simple(): """Create a super simple header.""" info = ReuseInfo({"GPL-3.0-or-later"}, {"SPDX-FileCopyrightText: Jane Doe"}) expected = cleandoc( """ # SPDX-FileCopyrightText: Jane Doe # # SPDX-License-Identifier: GPL-3.0-or-later """ ) assert create_header(info).strip() == expected def test_create_header_simple_with_contributor(): """Create a super simple header.""" info = ReuseInfo( {"GPL-3.0-or-later"}, {"SPDX-FileCopyrightText: Jane Doe"}, {"John Doe"} ) expected = cleandoc( """ # SPDX-FileCopyrightText: Jane Doe # SPDX-FileContributor: John Doe # # SPDX-License-Identifier: GPL-3.0-or-later """ ) assert create_header(info).strip() == expected def test_create_header_template_simple(template_simple): """Create a header with a simple template.""" info = ReuseInfo({"GPL-3.0-or-later"}, {"SPDX-FileCopyrightText: Jane Doe"}) expected = cleandoc( """ # Hello, world! # # SPDX-FileCopyrightText: Jane Doe # # SPDX-License-Identifier: GPL-3.0-or-later """ ) assert create_header(info, template=template_simple).strip() == expected def test_create_header_template_no_spdx(template_no_spdx): """Create a header with a template that does not have all REUSE info.""" info = ReuseInfo({"GPL-3.0-or-later"}, {"SPDX-FileCopyrightText: Jane Doe"}) with pytest.raises(MissingReuseInfo): create_header(info, template=template_no_spdx) def test_create_header_template_commented(template_commented): """Create a header with an already-commented template.""" info = ReuseInfo({"GPL-3.0-or-later"}, {"SPDX-FileCopyrightText: Jane Doe"}) expected = cleandoc( """ # Hello, world! # # SPDX-FileCopyrightText: Jane Doe # # SPDX-License-Identifier: GPL-3.0-or-later """ ) assert ( create_header( info, template=template_commented, template_is_commented=True, style=CppCommentStyle, ).strip() == expected ) def test_create_header_already_contains_spdx(): """Create a new header from a header that already contains REUSE info.""" info = ReuseInfo({"GPL-3.0-or-later"}, {"SPDX-FileCopyrightText: Jane Doe"}) existing = cleandoc( """ # SPDX-FileCopyrightText: John Doe # # SPDX-License-Identifier: MIT """ ) expected = cleandoc( """ # SPDX-FileCopyrightText: Jane Doe # SPDX-FileCopyrightText: John Doe # # SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: MIT """ ) assert create_header(info, header=existing).strip() == expected def test_create_header_existing_is_wrong(): """If the existing header contains errors, raise a CommentCreateError.""" info = ReuseInfo({"GPL-3.0-or-later"}, {"SPDX-FileCopyrightText: Jane Doe"}) existing = cleandoc( """ # SPDX-FileCopyrightText: John Doe # # SPDX-License-Identifier: MIT AND OR 0BSD """ ) with pytest.raises(CommentCreateError): create_header(info, header=existing) def test_create_header_old_syntax(): """Old copyright syntax is preserved when creating a new header.""" info = ReuseInfo({"GPL-3.0-or-later"}) existing = cleandoc( """ # Copyright John Doe """ ) expected = cleandoc( """ # Copyright John Doe # # SPDX-License-Identifier: GPL-3.0-or-later """ ) assert create_header(info, header=existing).strip() == expected def test_create_header_remove_fluff(): """Any stuff that isn't REUSE info is removed when using create_header.""" info = ReuseInfo({"GPL-3.0-or-later"}) existing = cleandoc( """ # SPDX-FileCopyrightText: John Doe # # Hello, world! pass """ ) expected = cleandoc( """ # SPDX-FileCopyrightText: John Doe # # SPDX-License-Identifier: GPL-3.0-or-later """ ) assert create_header(info, header=existing).strip() == expected def test_add_new_header_simple(): """Given text that already contains a header, create a new one, and preserve the old one. """ info = ReuseInfo({"GPL-3.0-or-later"}, {"SPDX-FileCopyrightText: Jane Doe"}) text = cleandoc( """ # SPDX-FileCopyrightText: John Doe # # SPDX-License-Identifier: MIT pass """ ) expected = cleandoc( """ # SPDX-FileCopyrightText: Jane Doe # # SPDX-License-Identifier: GPL-3.0-or-later # SPDX-FileCopyrightText: John Doe # # SPDX-License-Identifier: MIT pass """ ) assert add_new_header(text, info) == expected def test_find_and_replace_no_header(): """Given text without header, add a header.""" info = ReuseInfo({"GPL-3.0-or-later"}, {"SPDX-FileCopyrightText: Jane Doe"}) text = "pass" expected = cleandoc( """ # SPDX-FileCopyrightText: Jane Doe # # SPDX-License-Identifier: GPL-3.0-or-later pass """ ) assert ( find_and_replace_header(text, info) == add_new_header(text, info) == expected ) def test_find_and_replace_verbatim(): """Replace a header with itself.""" info = ReuseInfo() text = cleandoc( """ # SPDX-FileCopyrightText: Jane Doe # # SPDX-License-Identifier: GPL-3.0-or-later pass """ ) assert find_and_replace_header(text, info) == text def test_find_and_replace_newline_before_header(): """In a scenario where the header is preceded by whitespace, remove the preceding whitespace. """ info = ReuseInfo({"GPL-3.0-or-later"}, {"SPDX-FileCopyrightText: John Doe"}) text = cleandoc( """ # SPDX-FileCopyrightText: Jane Doe pass """ ) text = "\n" + text expected = cleandoc( """ # SPDX-FileCopyrightText: Jane Doe # SPDX-FileCopyrightText: John Doe # # SPDX-License-Identifier: GPL-3.0-or-later pass """ ) assert find_and_replace_header(text, info) == expected def test_find_and_replace_preserve_preceding(): """When the SPDX header is in the middle of the file, keep it there.""" info = ReuseInfo({"GPL-3.0-or-later"}, {"SPDX-FileCopyrightText: John Doe"}) text = cleandoc( """ # Hello, world! def foo(bar): return bar # SPDX-FileCopyrightText: Jane Doe pass """ ) expected = cleandoc( """ # Hello, world! def foo(bar): return bar # SPDX-FileCopyrightText: Jane Doe # SPDX-FileCopyrightText: John Doe # # SPDX-License-Identifier: GPL-3.0-or-later pass """ ) assert find_and_replace_header(text, info) == expected def test_find_and_replace_keep_shebang(): """When encountering a shebang, keep it and put the REUSE header beneath it. """ info = ReuseInfo({"GPL-3.0-or-later"}, {"SPDX-FileCopyrightText: John Doe"}) text = cleandoc( """ #!/usr/bin/env python3 # SPDX-FileCopyrightText: Jane Doe pass """ ) expected = cleandoc( """ #!/usr/bin/env python3 # SPDX-FileCopyrightText: Jane Doe # SPDX-FileCopyrightText: John Doe # # SPDX-License-Identifier: GPL-3.0-or-later pass """ ) assert find_and_replace_header(text, info) == expected def test_find_and_replace_separate_shebang(): """When the shebang is part of the same comment as the SPDX comment, separate the two. """ info = ReuseInfo({"GPL-3.0-or-later"}) text = cleandoc( """ #!/usr/bin/env python3 #!nix-shell -p python3 # SPDX-FileCopyrightText: Jane Doe pass """ ) expected = cleandoc( """ #!/usr/bin/env python3 #!nix-shell -p python3 # SPDX-FileCopyrightText: Jane Doe # # SPDX-License-Identifier: GPL-3.0-or-later pass """ ) assert find_and_replace_header(text, info) == expected def test_find_and_replace_shebang_but_no_copyright(): """When the file contains a shebang but no copyright information, keep it at the top of the file. """ info = ReuseInfo({"GPL-3.0-or-later"}) text = cleandoc( """ #!/usr/bin/env python3 # Hello, world! pass """ ) expected = cleandoc( """ #!/usr/bin/env python3 # SPDX-License-Identifier: GPL-3.0-or-later # Hello, world! pass """ ) assert find_and_replace_header(text, info) == expected def test_find_and_replace_only_shebang(): """When the file only contains a shebang, add copyright info below it.""" info = ReuseInfo({"GPL-3.0-or-later"}) text = "#!/usr/bin/env python3" expected = ( cleandoc( """ #!/usr/bin/env python3 # SPDX-License-Identifier: GPL-3.0-or-later """ ) + "\n" ) assert find_and_replace_header(text, info) == expected def test_find_and_replace_keep_old_comment(): """When encountering a comment that does not contain copyright and licensing information, preserve it below the REUSE header. """ info = ReuseInfo({"GPL-3.0-or-later"}, {"SPDX-FileCopyrightText: Jane Doe"}) text = cleandoc( """ # Hello, world! pass """ ) expected = cleandoc( """ # SPDX-FileCopyrightText: Jane Doe # # SPDX-License-Identifier: GPL-3.0-or-later # Hello, world! pass """ ) assert find_and_replace_header(text, info) == expected def test_find_and_replace_preserve_newline(): """If the file content ends with a newline, don't remove it.""" info = ReuseInfo() text = ( cleandoc( """ # SPDX-FileCopyrightText: Jane Doe # # SPDX-License-Identifier: GPL-3.0-or-later pass """ ) + "\n" ) assert find_and_replace_header(text, info) == text # REUSE-IgnoreEnd reuse-tool-4.0.3/tests/test_lint.py000066400000000000000000000223271464275211500173520ustar00rootroot00000000000000# SPDX-FileCopyrightText: 2019 Free Software Foundation Europe e.V. # SPDX-FileCopyrightText: 2022 Florian Snow # SPDX-FileCopyrightText: 2024 Nico Rikken # # SPDX-License-Identifier: GPL-3.0-or-later """All tests for reuse.lint""" import re import shutil from conftest import cpython, posix from reuse.lint import format_lines, format_plain from reuse.project import Project from reuse.report import ProjectReport # REUSE-IgnoreStart def test_lint_simple(fake_repository): """Extremely simple test for lint.""" project = Project.from_directory(fake_repository) report = ProjectReport.generate(project) result = format_plain(report) assert result def test_lint_git(git_repository): """Extremely simple test for lint with a git repository.""" project = Project.from_directory(git_repository) report = ProjectReport.generate(project) result = format_plain(report) assert result def test_lint_submodule(submodule_repository): """Extremely simple test for lint with an ignored submodule.""" project = Project.from_directory(submodule_repository) (submodule_repository / "submodule/foo.c").write_text("foo") report = ProjectReport.generate(project) result = format_plain(report) assert result def test_lint_submodule_included(submodule_repository): """Extremely simple test for lint with an included submodule.""" project = Project.from_directory( submodule_repository, include_submodules=True ) (submodule_repository / "submodule/foo.c").write_text("foo") report = ProjectReport.generate(project) result = format_plain(report) assert ":-(" in result def test_lint_empty_directory(empty_directory): """An empty directory is compliant.""" project = Project.from_directory(empty_directory) report = ProjectReport.generate(project) result = format_plain(report) assert result def test_lint_deprecated(fake_repository): """If a repo has a deprecated license, detect it.""" shutil.copy( fake_repository / "LICENSES/GPL-3.0-or-later.txt", fake_repository / "LICENSES/GPL-3.0.txt", ) (fake_repository / "foo.py").write_text( "SPDX-License-Identifier: GPL-3.0\nSPDX-FileCopyrightText: Jane Doe" ) project = Project.from_directory(fake_repository) report = ProjectReport.generate(project) result = format_plain(report) assert ":-(" in result assert "# DEPRECATED LICENSES" in result assert "GPL-3.0" in result assert "Fix deprecated licenses:" in result assert "spdx.org/licenses/#deprecated" in result def test_lint_bad_license(fake_repository): """A bad license is detected.""" (fake_repository / "foo.py").write_text( "SPDX-License-Identifier: bad-license" ) project = Project.from_directory(fake_repository) report = ProjectReport.generate(project) result = format_plain(report) assert ":-(" in result assert "# BAD LICENSES" in result assert "foo.py" in result assert "bad-license" in result assert "Fix bad licenses:" in result assert "reuse.software/faq/#custom-license" in result def test_lint_licenses_without_extension(fake_repository): """A license without file extension is detected.""" (fake_repository / "LICENSES/GPL-3.0-or-later.txt").rename( fake_repository / "LICENSES/GPL-3.0-or-later" ) project = Project.from_directory(fake_repository) report = ProjectReport.generate(project) result = format_plain(report) assert ":-(" in result assert "# LICENSES WITHOUT FILE EXTENSION" in result assert "GPL-3.0-or-later" in result assert "Fix licenses without file extension:" in result def test_lint_missing_licenses(fake_repository): """A missing license is detected.""" (fake_repository / "foo.py").write_text("SPDX-License-Identifier: MIT") project = Project.from_directory(fake_repository) report = ProjectReport.generate(project) result = format_plain(report) assert ":-(" in result assert "# MISSING LICENSES" in result assert "foo.py" in result assert "MIT" in result assert "Fix missing licenses:" in result def test_lint_unused_licenses(fake_repository): """An unused license is detected.""" (fake_repository / "LICENSES/MIT.txt").write_text("foo") project = Project.from_directory(fake_repository) report = ProjectReport.generate(project) result = format_plain(report) assert ":-(" in result assert "# UNUSED LICENSES" in result assert "Unused licenses: MIT" in result assert "Fix unused licenses:" in result @cpython @posix def test_lint_read_errors(fake_repository): """A read error is detected.""" (fake_repository / "foo.py").write_text("foo") (fake_repository / "foo.py").chmod(0o000) project = Project.from_directory(fake_repository) report = ProjectReport.generate(project) result = format_plain(report) assert ":-(" in result assert "# READ ERRORS" in result assert "Could not read:" in result assert "foo.py" in result assert "Fix read errors:" in result def test_lint_files_without_copyright_and_licensing(fake_repository): """A file without copyright and licensing is detected.""" (fake_repository / "foo.py").write_text("foo") project = Project.from_directory(fake_repository) report = ProjectReport.generate(project) result = format_plain(report) assert ":-(" in result assert "# MISSING COPYRIGHT AND LICENSING INFORMATION" in result assert ( "The following files have no copyright and licensing information:" in result ) assert "foo.py" in result assert "Fix missing copyright/licensing information:" in result assert "reuse.software/tutorial" in result def test_lint_json_output(fake_repository): """Test for lint with JSON output.""" (fake_repository / "foo.py").write_text("SPDX-License-Identifier: MIT") project = Project.from_directory(fake_repository) report = ProjectReport.generate(project) json_result = report.to_dict_lint() assert json_result # Test if all the keys are present assert "lint_version" in json_result assert "reuse_spec_version" in json_result assert "reuse_tool_version" in json_result assert "non_compliant" in json_result assert "files" in json_result assert "summary" in json_result assert "recommendations" in json_result # Test length of resulting list values assert len(json_result["files"]) == 9 assert len(json_result["summary"]) == 5 assert len(json_result["recommendations"]) == 2 # Test result assert json_result["summary"]["compliant"] is False # Test license path for test_file in json_result["files"]: if test_file["path"] == str(fake_repository / "foo.py"): assert test_file["licenses"][0]["value"] == "MIT" assert test_file["licenses"][0]["source"] == str( fake_repository / "foo.py" ) if test_file["path"].startswith(str(fake_repository / "doc")): assert test_file["licenses"][0]["value"] == "CC0-1.0" assert test_file["licenses"][0]["source"] == str( fake_repository / ".reuse/dep5" ) def test_lint_lines_output(fake_repository): """Complete test for lint with lines output.""" # Prepare a repository that includes all types of situations: # missing_licenses, unused_licenses, bad_licenses, deprecated_licenses, # licenses_without_extension, files_without_copyright, # files_without_licenses, read_errors (fake_repository / "invalid-license.py").write_text( "SPDX-License-Identifier: invalid" ) (fake_repository / "no-license.py").write_text( "SPDX-FileCopyrightText: Jane Doe" ) (fake_repository / "LICENSES" / "invalid-license-text").write_text( "An invalid license text" ) (fake_repository / "LICENSES" / "Nokia-Qt-exception-1.1.txt").write_text( "Deprecated" ) (fake_repository / "LICENSES" / "MIT").write_text("foo") (fake_repository / "file with spaces.py").write_text("foo") project = Project.from_directory(fake_repository) report = ProjectReport.generate(project) lines_result = format_lines(report) lines_result_lines = lines_result.splitlines() assert len(lines_result_lines) == 12 for line in lines_result_lines: assert re.match(".+: [^:]+", line) assert lines_result.count("invalid-license.py") == 3 assert lines_result.count("no-license.py") == 1 assert lines_result.count("LICENSES") == 6 assert lines_result.count("invalid-license-text") == 3 assert lines_result.count("Nokia-Qt-exception-1.1.txt") == 2 assert lines_result.count("MIT") == 2 assert lines_result.count("file with spaces.py") == 2 @cpython @posix def test_lint_lines_read_errors(fake_repository): """Check read error output""" (fake_repository / "restricted.py").write_text("foo") (fake_repository / "restricted.py").chmod(0o000) project = Project.from_directory(fake_repository) report = ProjectReport.generate(project) result = format_lines(report) print(result) assert len(result.splitlines()) == 1 assert "restricted.py" in result assert "read error" in result # REUSE-IgnoreEnd reuse-tool-4.0.3/tests/test_main.py000066400000000000000000000500631464275211500173260ustar00rootroot00000000000000# SPDX-FileCopyrightText: 2019 Free Software Foundation Europe e.V. # SPDX-FileCopyrightText: 2019 Stefan Bakker # SPDX-FileCopyrightText: © 2020 Liferay, Inc. # SPDX-FileCopyrightText: 2022 Florian Snow # SPDX-FileCopyrightText: 2022 Pietro Albini # SPDX-FileCopyrightText: 2024 Carmen Bianca BAKKER # # SPDX-License-Identifier: GPL-3.0-or-later """Tests for reuse._main: lint, spdx, download""" # pylint: disable=redefined-outer-name,unused-argument import errno import json import os import re import shutil import warnings from inspect import cleandoc from pathlib import Path from typing import Generator, Optional from unittest.mock import create_autospec from urllib.error import URLError import pytest from conftest import RESOURCES_DIRECTORY from freezegun import freeze_time from reuse import download from reuse._main import main from reuse._util import GIT_EXE, HG_EXE, PIJUL_EXE, cleandoc_nl from reuse.report import LINT_VERSION # REUSE-IgnoreStart @pytest.fixture(params=[True, False]) def optional_git_exe( request, monkeypatch ) -> Generator[Optional[str], None, None]: """Run the test with or without git.""" exe = GIT_EXE if request.param else "" monkeypatch.setattr("reuse.vcs.GIT_EXE", exe) monkeypatch.setattr("reuse._util.GIT_EXE", exe) yield exe @pytest.fixture(params=[True, False]) def optional_hg_exe( request, monkeypatch ) -> Generator[Optional[str], None, None]: """Run the test with or without mercurial.""" exe = HG_EXE if request.param else "" monkeypatch.setattr("reuse.vcs.HG_EXE", exe) monkeypatch.setattr("reuse._util.HG_EXE", exe) yield exe @pytest.fixture(params=[True, False]) def optional_pijul_exe( request, monkeypatch ) -> Generator[Optional[str], None, None]: """Run the test with or without Pijul.""" exe = PIJUL_EXE if request.param else "" monkeypatch.setattr("reuse.vcs.PIJUL_EXE", exe) monkeypatch.setattr("reuse._util.PIJUL_EXE", exe) yield exe @pytest.fixture() def mock_put_license_in_file(monkeypatch): """Create a mocked version of put_license_in_file.""" result = create_autospec(download.put_license_in_file) monkeypatch.setattr(download, "put_license_in_file", result) return result def test_lint(fake_repository, stringio, optional_git_exe, optional_hg_exe): """Run a successful lint. The optional VCSs are there to make sure that the test also works if these programs are not installed. """ result = main(["lint"], out=stringio) assert result == 0 assert ":-)" in stringio.getvalue() def test_lint_reuse_toml(fake_repository_reuse_toml, stringio): """Run a simple lint with REUSE.toml.""" result = main(["lint"], out=stringio) assert result == 0 assert ":-)" in stringio.getvalue() def test_lint_dep5(fake_repository_dep5, stringio): """Run a simple lint with .reuse/dep5.""" result = main(["lint"], out=stringio) assert result == 0 assert ":-)" in stringio.getvalue() def test_lint_git(git_repository, stringio): """Run a successful lint.""" result = main(["lint"], out=stringio) assert result == 0 assert ":-)" in stringio.getvalue() def test_lint_submodule(submodule_repository, stringio): """Run a successful lint.""" (submodule_repository / "submodule/foo.c").write_text("foo") result = main(["lint"], out=stringio) assert result == 0 assert ":-)" in stringio.getvalue() def test_lint_submodule_included(submodule_repository, stringio): """Run a successful lint.""" result = main(["--include-submodules", "lint"], out=stringio) assert result == 0 assert ":-)" in stringio.getvalue() def test_lint_submodule_included_fail(submodule_repository, stringio): """Run a failed lint.""" (submodule_repository / "submodule/foo.c").write_text("foo") result = main(["--include-submodules", "lint"], out=stringio) assert result == 1 assert ":-(" in stringio.getvalue() def test_lint_meson_subprojects(fake_repository, stringio): """Verify that subprojects are ignored.""" (fake_repository / "meson.build").write_text( cleandoc( """ SPDX-FileCopyrightText: 2022 Jane Doe SPDX-License-Identifier: CC0-1.0 """ ) ) subprojects_dir = fake_repository / "subprojects" subprojects_dir.mkdir() libfoo_dir = subprojects_dir / "libfoo" libfoo_dir.mkdir() # ./subprojects/foo.wrap has license and linter succeeds (subprojects_dir / "foo.wrap").write_text( cleandoc( """ SPDX-FileCopyrightText: 2022 Jane Doe SPDX-License-Identifier: CC0-1.0 """ ) ) # ./subprojects/libfoo/foo.c misses license but is ignored (libfoo_dir / "foo.c").write_text("foo") result = main(["lint"], out=stringio) assert result == 0 assert ":-)" in stringio.getvalue() def test_lint_meson_subprojects_fail(fake_repository, stringio): """Verify that files in './subprojects' are not ignored.""" (fake_repository / "meson.build").write_text( cleandoc( """ SPDX-FileCopyrightText: 2022 Jane Doe SPDX-License-Identifier: CC0-1.0 """ ) ) subprojects_dir = fake_repository / "subprojects" subprojects_dir.mkdir() # ./subprojects/foo.wrap misses license and linter fails (subprojects_dir / "foo.wrap").write_text("foo") result = main(["lint"], out=stringio) assert result == 1 assert ":-(" in stringio.getvalue() def test_lint_meson_subprojects_included_fail(fake_repository, stringio): """When Meson subprojects are included, fail on errors.""" (fake_repository / "meson.build").write_text( cleandoc( """ SPDX-FileCopyrightText: 2022 Jane Doe SPDX-License-Identifier: CC0-1.0 """ ) ) libfoo_dir = fake_repository / "subprojects/libfoo" libfoo_dir.mkdir(parents=True) # ./subprojects/libfoo/foo.c misses license and linter fails (libfoo_dir / "foo.c").write_text("foo") result = main(["--include-meson-subprojects", "lint"], out=stringio) assert result == 1 assert ":-(" in stringio.getvalue() def test_lint_meson_subprojects_included(fake_repository, stringio): """Successfully lint when Meson subprojects are included.""" (fake_repository / "meson.build").write_text( cleandoc( """ SPDX-FileCopyrightText: 2022 Jane Doe SPDX-License-Identifier: CC0-1.0 """ ) ) libfoo_dir = fake_repository / "subprojects/libfoo" libfoo_dir.mkdir(parents=True) # ./subprojects/libfoo/foo.c has license and linter succeeds (libfoo_dir / "foo.c").write_text( cleandoc( """ SPDX-FileCopyrightText: 2022 Jane Doe SPDX-License-Identifier: GPL-3.0-or-later """ ) ) result = main(["--include-meson-subprojects", "lint"], out=stringio) assert result == 0 assert ":-)" in stringio.getvalue() def test_lint_fail(fake_repository, stringio): """Run a failed lint.""" (fake_repository / "foo.py").write_text("foo") result = main(["lint"], out=stringio) assert result > 0 assert "foo.py" in stringio.getvalue() assert ":-(" in stringio.getvalue() def test_lint_fail_quiet(fake_repository, stringio): """Run a failed lint.""" (fake_repository / "foo.py").write_text("foo") result = main(["lint", "--quiet"], out=stringio) assert result > 0 assert stringio.getvalue() == "" def test_lint_dep5_decode_error(fake_repository_dep5, capsys): """Display an error if dep5 cannot be decoded.""" shutil.copy( RESOURCES_DIRECTORY / "fsfe.png", fake_repository_dep5 / ".reuse/dep5" ) with pytest.raises(SystemExit): main(["lint"]) assert "could not be decoded" in capsys.readouterr().err def test_lint_dep5_parse_error(fake_repository_dep5, capsys): """Display an error if there's a dep5 parse error.""" (fake_repository_dep5 / ".reuse/dep5").write_text("foo") with pytest.raises(SystemExit): main(["lint"]) assert "could not be parsed" in capsys.readouterr().err def test_lint_json(fake_repository, stringio): """Run a failed lint.""" result = main(["lint", "--json"], out=stringio) output = json.loads(stringio.getvalue()) assert result == 0 assert output["lint_version"] == LINT_VERSION assert len(output["files"]) == 8 def test_lint_json_fail(fake_repository, stringio): """Run a failed lint.""" (fake_repository / "foo.py").write_text("foo") result = main(["lint", "--json"], out=stringio) output = json.loads(stringio.getvalue()) assert result > 0 assert output["lint_version"] == LINT_VERSION assert len(output["non_compliant"]["missing_licensing_info"]) == 1 assert len(output["non_compliant"]["missing_copyright_info"]) == 1 assert len(output["files"]) == 9 def test_lint_no_file_extension(fake_repository, stringio): """If a license has no file extension, the lint fails.""" (fake_repository / "LICENSES/CC0-1.0.txt").rename( fake_repository / "LICENSES/CC0-1.0" ) result = main(["lint"], out=stringio) assert result > 0 assert "Licenses without file extension: CC0-1.0" in stringio.getvalue() assert ":-(" in stringio.getvalue() def test_lint_custom_root(fake_repository, stringio): """Use a custom root location.""" result = main(["--root", "doc", "lint"], out=stringio) assert result > 0 assert "usage.md" in stringio.getvalue() assert ":-(" in stringio.getvalue() def test_lint_custom_root_git(git_repository, stringio): """Use a custom root location in a git repo.""" result = main(["--root", "doc", "lint"], out=stringio) assert result > 0 assert "usage.md" in stringio.getvalue() assert ":-(" in stringio.getvalue() def test_lint_custom_root_different_cwd(fake_repository_reuse_toml, stringio): """Use a custom root while CWD is different.""" os.chdir("/") result = main( ["--root", str(fake_repository_reuse_toml), "lint"], out=stringio ) assert result == 0 assert ":-)" in stringio.getvalue() def test_lint_custom_root_is_file(fake_repository, stringio): """Custom root cannot be a file.""" with pytest.raises(SystemExit): main(["--root", ".reuse/dep5", "lint"], out=stringio) def test_lint_custom_root_not_exists(fake_repository, stringio): """Custom root must exist.""" with pytest.raises(SystemExit): main(["--root", "does-not-exist", "lint"], out=stringio) def test_lint_no_multiprocessing(fake_repository, stringio, multiprocessing): """--no-multiprocessing works.""" result = main(["--no-multiprocessing", "lint"], out=stringio) assert result == 0 assert ":-)" in stringio.getvalue() @freeze_time("2024-04-08T17:34:00Z") def test_spdx(fake_repository, stringio): """Compile to an SPDX document.""" os.chdir(str(fake_repository)) result = main(["spdx"], out=stringio) output = stringio.getvalue() # Ensure no LicenseConcluded is included without the flag assert "\nLicenseConcluded: NOASSERTION\n" in output assert "\nLicenseConcluded: GPL-3.0-or-later\n" not in output assert "\nCreator: Person: Anonymous ()\n" in output assert "\nCreator: Organization: Anonymous ()\n" in output assert "\nCreated: 2024-04-08T17:34:00Z\n" in output # TODO: This test is rubbish. assert result == 0 assert output def test_spdx_creator_info(fake_repository, stringio): """Ensure the --creator-* flags are properly formatted""" os.chdir(str(fake_repository)) result = main( [ "spdx", "--creator-person=Jane Doe (jane.doe@example.org)", "--creator-organization=FSFE", ], out=stringio, ) output = stringio.getvalue() assert result == 0 assert "\nCreator: Person: Jane Doe (jane.doe@example.org)\n" in output assert "\nCreator: Organization: FSFE ()\n" in output def test_spdx_add_license_concluded(fake_repository, stringio): """Compile to an SPDX document with the LicenseConcluded field.""" os.chdir(str(fake_repository)) result = main( [ "spdx", "--add-license-concluded", "--creator-person=Jane Doe", "--creator-organization=FSFE", ], out=stringio, ) output = stringio.getvalue() # Ensure no LicenseConcluded is included without the flag assert result == 0 assert "\nLicenseConcluded: NOASSERTION\n" not in output assert "\nLicenseConcluded: GPL-3.0-or-later\n" in output assert "\nCreator: Person: Jane Doe ()\n" in output assert "\nCreator: Organization: FSFE ()\n" in output def test_spdx_add_license_concluded_without_creator_info( fake_repository, stringio ): """Adding LicenseConcluded should require creator information""" os.chdir(str(fake_repository)) with pytest.raises(SystemExit): main(["spdx", "--add-license-concluded"], out=stringio) def test_spdx_no_multiprocessing(fake_repository, stringio, multiprocessing): """--no-multiprocessing works.""" os.chdir(str(fake_repository)) result = main(["--no-multiprocessing", "spdx"], out=stringio) # TODO: This test is rubbish. assert result == 0 assert stringio.getvalue() def test_download(fake_repository, stringio, mock_put_license_in_file): """Straightforward test.""" result = main(["download", "0BSD"], out=stringio) assert result == 0 mock_put_license_in_file.assert_called_with( "0BSD", Path("LICENSES/0BSD.txt").resolve(), source=None ) def test_download_file_exists( fake_repository, stringio, mock_put_license_in_file ): """The to-be-downloaded file already exists.""" mock_put_license_in_file.side_effect = FileExistsError( errno.EEXIST, "", "GPL-3.0-or-later.txt" ) result = main(["download", "GPL-3.0-or-later"], out=stringio) assert result == 1 assert "GPL-3.0-or-later.txt already exists" in stringio.getvalue() def test_download_exception( fake_repository, stringio, mock_put_license_in_file ): """There was an error while downloading the license file.""" mock_put_license_in_file.side_effect = URLError("test") result = main(["download", "0BSD"], out=stringio) assert result == 1 assert "internet" in stringio.getvalue() def test_download_invalid_spdx( fake_repository, stringio, mock_put_license_in_file ): """An invalid SPDX identifier was provided.""" mock_put_license_in_file.side_effect = URLError("test") result = main(["download", "does-not-exist"], out=stringio) assert result == 1 assert "not a valid SPDX License Identifier" in stringio.getvalue() def test_download_custom_output( empty_directory, stringio, mock_put_license_in_file ): """Download the license into a custom file.""" result = main(["download", "-o", "foo", "0BSD"], out=stringio) assert result == 0 mock_put_license_in_file.assert_called_with( "0BSD", destination=Path("foo"), source=None ) def test_download_custom_output_too_many( empty_directory, stringio, mock_put_license_in_file ): """Providing more than one license with a custom output results in an error. """ with pytest.raises(SystemExit): main( ["download", "-o", "foo", "0BSD", "GPL-3.0-or-later"], out=stringio ) def test_download_inside_licenses_dir( fake_repository, stringio, mock_put_license_in_file ): """While inside the LICENSES/ directory, don't create another LICENSES/ directory. """ os.chdir(fake_repository / "LICENSES") result = main(["download", "0BSD"], out=stringio) assert result == 0 mock_put_license_in_file.assert_called_with( "0BSD", destination=Path("0BSD.txt").absolute(), source=None ) def test_download_inside_licenses_dir_in_git( git_repository, stringio, mock_put_license_in_file ): """While inside a random LICENSES/ directory in a Git repository,.use the root LICENSES/ directory. """ (git_repository / "doc/LICENSES").mkdir() os.chdir(git_repository / "doc/LICENSES") result = main(["download", "0BSD"], out=stringio) assert result == 0 mock_put_license_in_file.assert_called_with( "0BSD", destination=Path("../../LICENSES/0BSD.txt"), source=None ) def test_download_different_root( fake_repository, stringio, mock_put_license_in_file ): """Download using a different root.""" (fake_repository / "new_root").mkdir() result = main( [ "--root", str((fake_repository / "new_root").resolve()), "download", "MIT", ], out=stringio, ) assert result == 0 mock_put_license_in_file.assert_called_with( "MIT", Path("new_root/LICENSES/MIT.txt").resolve(), source=None ) def test_download_licenseref_no_source(empty_directory, stringio): """Downloading a LicenseRef license creates an empty file.""" main(["download", "LicenseRef-hello"], out=stringio) assert (empty_directory / "LICENSES/LicenseRef-hello.txt").read_text() == "" def test_download_licenseref_source_file(empty_directory, stringio): """Downloading a LicenseRef license with a source file copies that file's contents. """ (empty_directory / "foo.txt").write_text("foo") main(["download", "--source", "foo.txt", "LicenseRef-hello"], out=stringio) assert ( empty_directory / "LICENSES/LicenseRef-hello.txt" ).read_text() == "foo" def test_download_licenseref_source_dir(empty_directory, stringio): """Downloading a LicenseRef license with a source dir copies the text from the corresponding file in the directory. """ (empty_directory / "lics").mkdir() (empty_directory / "lics/LicenseRef-hello.txt").write_text("foo") main(["download", "--source", "lics", "LicenseRef-hello"], out=stringio) assert ( empty_directory / "LICENSES/LicenseRef-hello.txt" ).read_text() == "foo" def test_download_licenseref_false_source_dir(empty_directory, stringio): """Downloading a LicenseRef license with a source that does not contain the license results in an error. """ (empty_directory / "lics").mkdir() result = main( ["download", "--source", "lics", "LicenseRef-hello"], out=stringio ) assert result != 0 assert ( f"{Path('lics') / 'LicenseRef-hello.txt'} does not exist" in stringio.getvalue() ) def test_supported_licenses(stringio): """Invoke the supported-licenses command and check whether the result contains at least one license in the expected format. """ assert main(["supported-licenses"], out=stringio) == 0 assert re.search( # pylint: disable=line-too-long r"GPL-3\.0-or-later\s+GNU General Public License v3\.0 or later\s+https:\/\/spdx\.org\/licenses\/GPL-3\.0-or-later\.html\s+\n", stringio.getvalue(), ) def test_convert_dep5(fake_repository_dep5, stringio): """Convert a DEP5 repository to a REUSE.toml repository.""" result = main(["convert-dep5"], out=stringio) assert result == 0 assert not (fake_repository_dep5 / ".reuse/dep5").exists() assert (fake_repository_dep5 / "REUSE.toml").exists() assert (fake_repository_dep5 / "REUSE.toml").read_text() == cleandoc_nl( """ version = 1 [[annotations]] path = "doc/**" precedence = "aggregate" SPDX-FileCopyrightText = "2017 Jane Doe" SPDX-License-Identifier = "CC0-1.0" """ ) def test_convert_dep5_no_dep5_file(fake_repository, stringio): """Cannot convert when there is no .reuse/dep5 file.""" with pytest.raises(SystemExit): main(["convert-dep5"], out=stringio) def test_convert_dep5_no_warning(fake_repository_dep5, stringio): """No PendingDeprecationWarning when running convert-dep5.""" with warnings.catch_warnings(record=True) as caught_warnings: result = main(["convert-dep5"], out=stringio) assert result == 0 assert not caught_warnings # REUSE-IgnoreEnd reuse-tool-4.0.3/tests/test_main_annotate.py000066400000000000000000001144031464275211500212160ustar00rootroot00000000000000# SPDX-FileCopyrightText: 2019 Free Software Foundation Europe e.V. # SPDX-FileCopyrightText: 2019 Stefan Bakker # SPDX-FileCopyrightText: 2022 Carmen Bianca Bakker # SPDX-FileCopyrightText: 2022 Florian Snow # SPDX-FileCopyrightText: 2023 Maxim Cournoyer # SPDX-FileCopyrightText: 2024 Rivos Inc. # SPDX-FileCopyrightText: © 2020 Liferay, Inc. # # SPDX-License-Identifier: GPL-3.0-or-later """Tests for reuse._main: annotate""" import logging import stat from inspect import cleandoc import pytest from reuse._main import main # pylint: disable=too-many-lines,unused-argument # REUSE-IgnoreStart # TODO: Replace this test with a monkeypatched test def test_annotate_simple(fake_repository, stringio, mock_date_today): """Add a header to a file that does not have one.""" simple_file = fake_repository / "foo.py" simple_file.write_text("pass") expected = cleandoc( """ # SPDX-FileCopyrightText: 2018 Jane Doe # # SPDX-License-Identifier: GPL-3.0-or-later pass """ ) result = main( [ "annotate", "--license", "GPL-3.0-or-later", "--copyright", "Jane Doe", "foo.py", ], out=stringio, ) assert result == 0 assert simple_file.read_text() == expected def test_annotate_simple_scheme(fake_repository, stringio, mock_date_today): "Add a header to a Scheme file." simple_file = fake_repository / "foo.scm" simple_file.write_text("#t") expected = cleandoc( """ ;;; SPDX-FileCopyrightText: 2018 Jane Doe ;;; ;;; SPDX-License-Identifier: GPL-3.0-or-later #t """ ) result = main( [ "annotate", "--license", "GPL-3.0-or-later", "--copyright", "Jane Doe", "foo.scm", ], out=stringio, ) assert result == 0 assert simple_file.read_text() == expected def test_annotate_scheme_standardised( fake_repository, stringio, mock_date_today ): """The comment block is rewritten/standardised.""" simple_file = fake_repository / "foo.scm" simple_file.write_text( cleandoc( """ ; SPDX-FileCopyrightText: 2018 Jane Doe ; ; SPDX-License-Identifier: GPL-3.0-or-later #t """ ) ) expected = cleandoc( """ ;;; SPDX-FileCopyrightText: 2018 Jane Doe ;;; ;;; SPDX-License-Identifier: GPL-3.0-or-later #t """ ) result = main( [ "annotate", "--license", "GPL-3.0-or-later", "--copyright", "Jane Doe", "foo.scm", ], out=stringio, ) assert result == 0 assert simple_file.read_text() == expected def test_annotate_scheme_standardised2( fake_repository, stringio, mock_date_today ): """The comment block is rewritten/standardised.""" simple_file = fake_repository / "foo.scm" simple_file.write_text( cleandoc( """ ;; SPDX-FileCopyrightText: 2018 Jane Doe ;; ;; SPDX-License-Identifier: GPL-3.0-or-later #t """ ) ) expected = cleandoc( """ ;;; SPDX-FileCopyrightText: 2018 Jane Doe ;;; ;;; SPDX-License-Identifier: GPL-3.0-or-later #t """ ) result = main( [ "annotate", "--license", "GPL-3.0-or-later", "--copyright", "Jane Doe", "foo.scm", ], out=stringio, ) assert result == 0 assert simple_file.read_text() == expected def test_annotate_simple_no_replace(fake_repository, stringio, mock_date_today): """Add a header to a file without replacing the existing header.""" simple_file = fake_repository / "foo.py" simple_file.write_text( cleandoc( """ # SPDX-FileCopyrightText: 2017 John Doe # # SPDX-License-Identifier: MIT pass """ ) ) expected = cleandoc( """ # SPDX-FileCopyrightText: 2018 Jane Doe # # SPDX-License-Identifier: GPL-3.0-or-later # SPDX-FileCopyrightText: 2017 John Doe # # SPDX-License-Identifier: MIT pass """ ) result = main( [ "annotate", "--no-replace", "--license", "GPL-3.0-or-later", "--copyright", "Jane Doe", "foo.py", ], out=stringio, ) assert result == 0 assert simple_file.read_text() == expected def test_annotate_year(fake_repository, stringio): """Add a header to a file with a custom year.""" simple_file = fake_repository / "foo.py" simple_file.write_text("pass") expected = cleandoc( """ # SPDX-FileCopyrightText: 2016 Jane Doe # # SPDX-License-Identifier: GPL-3.0-or-later pass """ ) result = main( [ "annotate", "--year", "2016", "--license", "GPL-3.0-or-later", "--copyright", "Jane Doe", "foo.py", ], out=stringio, ) assert result == 0 assert simple_file.read_text() == expected def test_annotate_no_year(fake_repository, stringio): """Add a header to a file without a year.""" simple_file = fake_repository / "foo.py" simple_file.write_text("pass") expected = cleandoc( """ # SPDX-FileCopyrightText: Jane Doe # # SPDX-License-Identifier: GPL-3.0-or-later pass """ ) result = main( [ "annotate", "--exclude-year", "--license", "GPL-3.0-or-later", "--copyright", "Jane Doe", "foo.py", ], out=stringio, ) assert result == 0 assert simple_file.read_text() == expected @pytest.mark.parametrize( "copyright_prefix", ["--copyright-prefix", "--copyright-style"] ) def test_annotate_copyright_prefix( fake_repository, copyright_prefix, stringio, mock_date_today ): """Add a header with a specific copyright prefix. Also test the old name of the parameter. """ simple_file = fake_repository / "foo.py" simple_file.write_text("pass") expected = cleandoc( """ # Copyright 2018 Jane Doe # # SPDX-License-Identifier: GPL-3.0-or-later pass """ ) result = main( [ "annotate", "--license", "GPL-3.0-or-later", "--copyright", "Jane Doe", copyright_prefix, "string", "foo.py", ], out=stringio, ) assert result == 0 assert simple_file.read_text() == expected def test_annotate_shebang(fake_repository, stringio): """Keep the shebang when annotating.""" simple_file = fake_repository / "foo.py" simple_file.write_text( cleandoc( """ #!/usr/bin/env python3 pass """ ) ) expected = cleandoc( """ #!/usr/bin/env python3 # SPDX-License-Identifier: GPL-3.0-or-later pass """ ) result = main( [ "annotate", "--license", "GPL-3.0-or-later", "foo.py", ], out=stringio, ) assert result == 0 assert simple_file.read_text() == expected def test_annotate_shebang_wrong_comment_style(fake_repository, stringio): """If a comment style does not support the shebang at the top, don't treat the shebang as special. """ simple_file = fake_repository / "foo.html" simple_file.write_text( cleandoc( """ #!/usr/bin/env python3 pass """ ) ) expected = cleandoc( """ #!/usr/bin/env python3 pass """ ) result = main( [ "annotate", "--license", "GPL-3.0-or-later", "foo.html", ], out=stringio, ) assert result == 0 assert simple_file.read_text() == expected def test_annotate_contributors_only( fake_repository, stringio, mock_date_today, contributors ): """Add a header with only contributor information.""" if not contributors: pytest.skip("No contributors to add") simple_file = fake_repository / "foo.py" simple_file.write_text("pass") content = [] for contributor in sorted(contributors): content.append(f"# SPDX-FileContributor: {contributor}") content += ["", "pass"] expected = cleandoc("\n".join(content)) args = [ "annotate", ] for contributor in contributors: args += ["--contributor", contributor] args += ["foo.py"] result = main( args, out=stringio, ) assert result == 0 assert simple_file.read_text() == expected def test_annotate_contributors( fake_repository, stringio, mock_date_today, contributors ): """Add a header with contributor information.""" simple_file = fake_repository / "foo.py" simple_file.write_text("pass") content = ["# SPDX-FileCopyrightText: 2018 Jane Doe"] if contributors: for contributor in sorted(contributors): content.append(f"# SPDX-FileContributor: {contributor}") content += ["#", "# SPDX-License-Identifier: GPL-3.0-or-later", "", "pass"] expected = cleandoc("\n".join(content)) args = [ "annotate", "--license", "GPL-3.0-or-later", "--copyright", "Jane Doe", ] for contributor in contributors: args += ["--contributor", contributor] args += ["foo.py"] result = main( args, out=stringio, ) assert result == 0 assert simple_file.read_text() == expected def test_annotate_specify_style(fake_repository, stringio, mock_date_today): """Add a header to a file that does not have one, using a custom style.""" simple_file = fake_repository / "foo.py" simple_file.write_text("pass") expected = cleandoc( """ // SPDX-FileCopyrightText: 2018 Jane Doe // // SPDX-License-Identifier: GPL-3.0-or-later pass """ ) result = main( [ "annotate", "--license", "GPL-3.0-or-later", "--copyright", "Jane Doe", "--style", "cpp", "foo.py", ], out=stringio, ) assert result == 0 assert simple_file.read_text() == expected def test_annotate_specify_style_unrecognised( fake_repository, stringio, mock_date_today ): """Add a header to a file that is unrecognised.""" simple_file = fake_repository / "hello.foo" simple_file.touch() expected = "# SPDX-FileCopyrightText: 2018 Jane Doe" result = main( [ "annotate", "--copyright", "Jane Doe", "--style", "python", "hello.foo", ], out=stringio, ) assert result == 0 assert simple_file.read_text().strip() == expected def test_annotate_implicit_style(fake_repository, stringio, mock_date_today): """Add a header to a file that has a recognised extension.""" simple_file = fake_repository / "foo.js" simple_file.write_text("pass") expected = cleandoc( """ // SPDX-FileCopyrightText: 2018 Jane Doe // // SPDX-License-Identifier: GPL-3.0-or-later pass """ ) result = main( [ "annotate", "--license", "GPL-3.0-or-later", "--copyright", "Jane Doe", "foo.js", ], out=stringio, ) assert result == 0 assert simple_file.read_text() == expected def test_annotate_implicit_style_filename( fake_repository, stringio, mock_date_today ): """Add a header to a filename that is recognised.""" simple_file = fake_repository / "Makefile" simple_file.write_text("pass") expected = cleandoc( """ # SPDX-FileCopyrightText: 2018 Jane Doe # # SPDX-License-Identifier: GPL-3.0-or-later pass """ ) result = main( [ "annotate", "--license", "GPL-3.0-or-later", "--copyright", "Jane Doe", "Makefile", ], out=stringio, ) assert result == 0 assert simple_file.read_text() == expected def test_annotate_unrecognised_style(fake_repository, capsys): """Add a header to a file that has an unrecognised extension.""" simple_file = fake_repository / "foo.foo" simple_file.write_text("pass") with pytest.raises(SystemExit): main( [ "annotate", "--license", "GPL-3.0-or-later", "--copyright", "Jane Doe", "foo.foo", ], ) stdout = capsys.readouterr().err assert ( "The following files do not have a recognised file extension" in stdout ) assert "foo.foo" in stdout @pytest.mark.parametrize( "skip_unrecognised", ["--skip-unrecognised", "--skip-unrecognized"] ) def test_annotate_skip_unrecognised( fake_repository, skip_unrecognised, stringio ): """Skip file that has an unrecognised extension.""" simple_file = fake_repository / "foo.foo" simple_file.write_text("pass") result = main( [ "annotate", "--license", "GPL-3.0-or-later", "--copyright", "Jane Doe", skip_unrecognised, "foo.foo", ], out=stringio, ) assert result == 0 assert "Skipped unrecognised file 'foo.foo'" in stringio.getvalue() def test_annotate_skip_unrecognised_and_style( fake_repository, stringio, caplog ): """--skip-unrecognised and --style show warning message.""" simple_file = fake_repository / "foo.foo" simple_file.write_text("pass") result = main( [ "annotate", "--license", "GPL-3.0-or-later", "--copyright", "Jane Doe", "--style=c", "--skip-unrecognised", "foo.foo", ], out=stringio, ) assert result == 0 loglevel = logging.getLogger("reuse").level if loglevel > logging.WARNING: pytest.skip( "Test needs LogLevel <= WARNING (e.g. WARNING, INFO, DEBUG)." ) else: assert "no effect" in caplog.text def test_annotate_no_copyright_or_license(fake_repository): """Add a header, but supply no copyright or license.""" simple_file = fake_repository / "foo.py" simple_file.write_text("pass") with pytest.raises(SystemExit): main(["annotate", "foo.py"]) def test_annotate_template_simple( fake_repository, stringio, mock_date_today, template_simple_source ): """Add a header with a custom template.""" simple_file = fake_repository / "foo.py" simple_file.write_text("pass") template_file = fake_repository / ".reuse/templates/mytemplate.jinja2" template_file.parent.mkdir(parents=True, exist_ok=True) template_file.write_text(template_simple_source) expected = cleandoc( """ # Hello, world! # # SPDX-FileCopyrightText: 2018 Jane Doe # # SPDX-License-Identifier: GPL-3.0-or-later pass """ ) result = main( [ "annotate", "--license", "GPL-3.0-or-later", "--copyright", "Jane Doe", "--template", "mytemplate.jinja2", "foo.py", ], out=stringio, ) assert result == 0 assert simple_file.read_text() == expected def test_annotate_template_simple_multiple( fake_repository, stringio, mock_date_today, template_simple_source ): """Add a header with a custom template to multiple files.""" simple_files = [fake_repository / f"foo{i}.py" for i in range(10)] for simple_file in simple_files: simple_file.write_text("pass") template_file = fake_repository / ".reuse/templates/mytemplate.jinja2" template_file.parent.mkdir(parents=True, exist_ok=True) template_file.write_text(template_simple_source) result = main( [ "annotate", "--license", "GPL-3.0-or-later", "--copyright", "Jane Doe", "--template", "mytemplate.jinja2", ] + list(map(str, simple_files)), out=stringio, ) assert result == 0 for simple_file in simple_files: expected = cleandoc( """ # Hello, world! # # SPDX-FileCopyrightText: 2018 Jane Doe # # SPDX-License-Identifier: GPL-3.0-or-later pass """ ) assert simple_file.read_text() == expected def test_annotate_template_no_spdx( fake_repository, stringio, template_no_spdx_source ): """Add a header with a template that lacks REUSE info.""" simple_file = fake_repository / "foo.py" simple_file.write_text("pass") template_file = fake_repository / ".reuse/templates/mytemplate.jinja2" template_file.parent.mkdir(parents=True, exist_ok=True) template_file.write_text(template_no_spdx_source) result = main( [ "annotate", "--license", "GPL-3.0-or-later", "--copyright", "Jane Doe", "--template", "mytemplate.jinja2", "foo.py", ], out=stringio, ) assert result == 1 def test_annotate_template_commented( fake_repository, stringio, mock_date_today, template_commented_source ): """Add a header with a custom template that is already commented.""" simple_file = fake_repository / "foo.c" simple_file.write_text("pass") template_file = ( fake_repository / ".reuse/templates/mytemplate.commented.jinja2" ) template_file.parent.mkdir(parents=True, exist_ok=True) template_file.write_text(template_commented_source) expected = cleandoc( """ # Hello, world! # # SPDX-FileCopyrightText: 2018 Jane Doe # # SPDX-License-Identifier: GPL-3.0-or-later pass """ ) result = main( [ "annotate", "--license", "GPL-3.0-or-later", "--copyright", "Jane Doe", "--template", "mytemplate.commented.jinja2", "foo.c", ], out=stringio, ) assert result == 0 assert simple_file.read_text() == expected def test_annotate_template_nonexistant(fake_repository): """Raise an error when using a header that does not exist.""" simple_file = fake_repository / "foo.py" simple_file.write_text("pass") with pytest.raises(SystemExit): main( [ "annotate", "--license", "GPL-3.0-or-later", "--copyright", "Jane Doe", "--template", "mytemplate.jinja2", "foo.py", ] ) def test_annotate_template_without_extension( fake_repository, stringio, mock_date_today, template_simple_source ): """Find the correct header even when not using an extension.""" simple_file = fake_repository / "foo.py" simple_file.write_text("pass") template_file = fake_repository / ".reuse/templates/mytemplate.jinja2" template_file.parent.mkdir(parents=True, exist_ok=True) template_file.write_text(template_simple_source) expected = cleandoc( """ # Hello, world! # # SPDX-FileCopyrightText: 2018 Jane Doe # # SPDX-License-Identifier: GPL-3.0-or-later pass """ ) result = main( [ "annotate", "--license", "GPL-3.0-or-later", "--copyright", "Jane Doe", "--template", "mytemplate", "foo.py", ], out=stringio, ) assert result == 0 assert simple_file.read_text() == expected def test_annotate_binary( fake_repository, stringio, mock_date_today, binary_string ): """Add a header to a .license file if the file is a binary.""" binary_file = fake_repository / "foo.png" binary_file.write_bytes(binary_string) expected = cleandoc( """ SPDX-FileCopyrightText: 2018 Jane Doe SPDX-License-Identifier: GPL-3.0-or-later """ ) result = main( [ "annotate", "--license", "GPL-3.0-or-later", "--copyright", "Jane Doe", "foo.png", ], out=stringio, ) assert result == 0 assert ( binary_file.with_name(f"{binary_file.name}.license").read_text().strip() == expected ) def test_annotate_uncommentable_json( fake_repository, stringio, mock_date_today ): """Add a header to a .license file if the file is uncommentable, e.g., JSON. """ json_file = fake_repository / "foo.json" json_file.write_text('{"foo": 23, "bar": 42}') expected = cleandoc( """ SPDX-FileCopyrightText: 2018 Jane Doe SPDX-License-Identifier: GPL-3.0-or-later """ ) result = main( [ "annotate", "--license", "GPL-3.0-or-later", "--copyright", "Jane Doe", "foo.json", ], out=stringio, ) assert result == 0 assert ( json_file.with_name(f"{json_file.name}.license").read_text().strip() == expected ) def test_annotate_fallback_dot_license( fake_repository, stringio, mock_date_today ): """Add a header to .license if --fallback-dot-license is given, and no style yet exists. """ (fake_repository / "foo.py").write_text("Foo") (fake_repository / "foo.foo").write_text("Foo") expected_py = cleandoc( """ # SPDX-FileCopyrightText: 2018 Jane Doe # # SPDX-License-Identifier: GPL-3.0-or-later """ ) expected_foo = cleandoc( """ SPDX-FileCopyrightText: 2018 Jane Doe SPDX-License-Identifier: GPL-3.0-or-later """ ) result = main( [ "annotate", "--license", "GPL-3.0-or-later", "--copyright", "Jane Doe", "--fallback-dot-license", "foo.py", "foo.foo", ], out=stringio, ) assert result == 0 assert expected_py in (fake_repository / "foo.py").read_text() assert (fake_repository / "foo.foo.license").exists() assert ( fake_repository / "foo.foo.license" ).read_text().strip() == expected_foo assert ( "'foo.foo' is not recognised; creating 'foo.foo.license'" in stringio.getvalue() ) def test_annotate_force_dot_license(fake_repository, stringio, mock_date_today): """Add a header to a .license file if --force-dot-license is given.""" simple_file = fake_repository / "foo.py" simple_file.write_text("pass") expected = cleandoc( """ SPDX-FileCopyrightText: 2018 Jane Doe SPDX-License-Identifier: GPL-3.0-or-later """ ) result = main( [ "annotate", "--license", "GPL-3.0-or-later", "--copyright", "Jane Doe", "--force-dot-license", "foo.py", ], out=stringio, ) assert result == 0 assert ( simple_file.with_name(f"{simple_file.name}.license").read_text().strip() == expected ) assert simple_file.read_text() == "pass" def test_annotate_force_dot_license_double( fake_repository, stringio, mock_date_today ): """When path.license already exists, don't create path.license.license.""" simple_file = fake_repository / "foo.txt" simple_file_license = fake_repository / "foo.txt.license" simple_file_license_license = fake_repository / "foo.txt.license.license" simple_file.write_text("foo") simple_file_license.write_text("foo") expected = cleandoc( """ SPDX-FileCopyrightText: 2018 Jane Doe SPDX-License-Identifier: GPL-3.0-or-later """ ) result = main( [ "annotate", "--license", "GPL-3.0-or-later", "--copyright", "Jane Doe", "--force-dot-license", "foo.txt", ], out=stringio, ) assert result == 0 assert not simple_file_license_license.exists() assert simple_file_license.read_text().strip() == expected def test_annotate_force_dot_license_unsupported_filetype( fake_repository, stringio, mock_date_today ): """Add a header to a .license file if --force-dot-license is given, with the base file being an otherwise unsupported filetype. """ simple_file = fake_repository / "foo.txt" simple_file.write_text("Preserve this") expected = cleandoc( """ SPDX-FileCopyrightText: 2018 Jane Doe SPDX-License-Identifier: GPL-3.0-or-later """ ) result = main( [ "annotate", "--license", "GPL-3.0-or-later", "--copyright", "Jane Doe", "--force-dot-license", "foo.txt", ], out=stringio, ) assert result == 0 assert ( simple_file.with_name(f"{simple_file.name}.license").read_text().strip() == expected ) assert simple_file.read_text() == "Preserve this" def test_annotate_force_dot_license_doesnt_write_to_file( fake_repository, stringio, mock_date_today ): """Adding a header to a .license file if --force-dot-license is given, doesn't require write permission to the file, just the directory. """ simple_file = fake_repository / "foo.txt" simple_file.write_text("Preserve this") simple_file.chmod(mode=stat.S_IREAD) expected = cleandoc( """ SPDX-FileCopyrightText: 2018 Jane Doe SPDX-License-Identifier: GPL-3.0-or-later """ ) result = main( [ "annotate", "--license", "GPL-3.0-or-later", "--copyright", "Jane Doe", "--force-dot-license", "foo.txt", ], out=stringio, ) assert result == 0 assert ( simple_file.with_name(f"{simple_file.name}.license").read_text().strip() == expected ) assert simple_file.read_text() == "Preserve this" def test_annotate_to_read_only_file_does_not_traceback( fake_repository, stringio, mock_date_today ): """Trying to add a header without having write permission, shouldn't result in a traceback. See issue #398""" _file = fake_repository / "test.sh" _file.write_text("#!/bin/sh") _file.chmod(mode=stat.S_IREAD) with pytest.raises(SystemExit) as info: main( [ "annotate", "--license", "Apache-2.0", "--copyright", "mycorp", "--style", "python", "test.sh", ] ) assert info.value # should not exit with 0 def test_annotate_license_file(fake_repository, stringio, mock_date_today): """Add a header to a .license file if it exists.""" simple_file = fake_repository / "foo.py" simple_file.write_text("foo") license_file = fake_repository / "foo.py.license" license_file.write_text( cleandoc( """ SPDX-FileCopyrightText: 2016 John Doe Hello """ ) ) expected = ( cleandoc( """ SPDX-FileCopyrightText: 2016 John Doe SPDX-FileCopyrightText: 2018 Jane Doe SPDX-License-Identifier: GPL-3.0-or-later """ ) + "\n" ) result = main( [ "annotate", "--license", "GPL-3.0-or-later", "--copyright", "Jane Doe", "foo.py", ], out=stringio, ) assert result == 0 assert license_file.read_text() == expected assert simple_file.read_text() == "foo" def test_annotate_license_file_only_one_newline( fake_repository, stringio, mock_date_today ): """When a header is added to a .license file that already ends with a newline, the new header should end with a single newline. """ simple_file = fake_repository / "foo.py" simple_file.write_text("foo") license_file = fake_repository / "foo.py.license" license_file.write_text( cleandoc( """ SPDX-FileCopyrightText: 2016 John Doe Hello """ ) + "\n" ) expected = ( cleandoc( """ SPDX-FileCopyrightText: 2016 John Doe SPDX-FileCopyrightText: 2018 Jane Doe SPDX-License-Identifier: GPL-3.0-or-later """ ) + "\n" ) result = main( [ "annotate", "--license", "GPL-3.0-or-later", "--copyright", "Jane Doe", "foo.py", ], out=stringio, ) assert result == 0 assert license_file.read_text() == expected assert simple_file.read_text() == "foo" def test_annotate_year_mutually_exclusive(fake_repository): """--exclude-year and --year are mutually exclusive.""" with pytest.raises(SystemExit): main( [ "annotate", "--license", "GPL-3.0-or-later", "--copyright", "Jane Doe", "--exclude-year", "--year", "2020", "src/source_code.py", ] ) def test_annotate_single_multi_line_mutually_exclusive(fake_repository): """--single-line and --multi-line are mutually exclusive.""" with pytest.raises(SystemExit): main( [ "annotate", "--license", "GPL-3.0-or-later", "--copyright", "Jane Doe", "--single-line", "--multi-line", "src/source_code.c", ] ) def test_annotate_skip_force_mutually_exclusive(fake_repository): """--skip-unrecognised and --force-dot-license are mutually exclusive.""" with pytest.raises(SystemExit): main( [ "annotate", "--license", "GPL-3.0-or-later", "--copyright", "Jane Doe", "--force-dot-license", "--skip-unrecognised", "src/source_code.py", ] ) def test_annotate_multi_line_not_supported(fake_repository): """Expect a fail if --multi-line is not supported for a file type.""" with pytest.raises(SystemExit): main( [ "annotate", "--license", "GPL-3.0-or-later", "--copyright", "Jane Doe", "--multi-line", "src/source_code.py", ] ) def test_annotate_multi_line_not_supported_custom_style( fake_repository, capsys ): """--multi-line also fails when used with a style that doesn't support it through --style. """ (fake_repository / "foo.foo").write_text("foo") with pytest.raises(SystemExit): main( [ "annotate", "--license", "GPL-3.0-or-later", "--copyright", "Jane Doe", "--multi-line", "--force-dot-license", "--style", "python", "foo.foo", ], ) assert "'foo.foo' does not support multi-line" in capsys.readouterr().err def test_annotate_single_line_not_supported(fake_repository): """Expect a fail if --single-line is not supported for a file type.""" with pytest.raises(SystemExit): main( [ "annotate", "--license", "GPL-3.0-or-later", "--copyright", "Jane Doe", "--single-line", "src/source_code.html", ] ) def test_annotate_force_multi_line_for_c( fake_repository, stringio, mock_date_today ): """--multi-line forces a multi-line comment for C.""" simple_file = fake_repository / "foo.c" simple_file.write_text("foo") expected = cleandoc( """ /* * SPDX-FileCopyrightText: 2018 Jane Doe * * SPDX-License-Identifier: GPL-3.0-or-later */ foo """ ) result = main( [ "annotate", "--license", "GPL-3.0-or-later", "--copyright", "Jane Doe", "--multi-line", "foo.c", ], out=stringio, ) assert result == 0 assert simple_file.read_text() == expected @pytest.mark.parametrize("line_ending", ["\r\n", "\r", "\n"]) def test_annotate_line_endings( empty_directory, stringio, mock_date_today, line_ending ): """Given a file with a certain type of line ending, preserve it.""" simple_file = empty_directory / "foo.py" simple_file.write_bytes( line_ending.encode("utf-8").join([b"hello", b"world"]) ) expected = cleandoc( """ # SPDX-FileCopyrightText: 2018 Jane Doe # # SPDX-License-Identifier: GPL-3.0-or-later hello world """ ).replace("\n", line_ending) result = main( [ "annotate", "--license", "GPL-3.0-or-later", "--copyright", "Jane Doe", "foo.py", ], out=stringio, ) assert result == 0 with open(simple_file, newline="", encoding="utf-8") as fp: contents = fp.read() assert contents == expected def test_annotate_skip_existing(fake_repository, stringio, mock_date_today): """When annotate --skip-existing on a file that already contains REUSE info, don't write additional information to it. """ for path in ("foo.py", "bar.py"): (fake_repository / path).write_text("pass") expected_foo = cleandoc( """ # SPDX-FileCopyrightText: 2018 Jane Doe # # SPDX-License-Identifier: GPL-3.0-or-later pass """ ) expected_bar = cleandoc( """ # SPDX-FileCopyrightText: 2018 John Doe # # SPDX-License-Identifier: MIT pass """ ) main( [ "annotate", "--license", "GPL-3.0-or-later", "--copyright", "Jane Doe", "foo.py", ], out=stringio, ) result = main( [ "annotate", "--license", "MIT", "--copyright", "John Doe", "--skip-existing", "foo.py", "bar.py", ] ) assert result == 0 assert (fake_repository / "foo.py").read_text() == expected_foo assert (fake_repository / "bar.py").read_text() == expected_bar def test_annotate_recursive(fake_repository, stringio, mock_date_today): """Add a header to a directory recursively.""" (fake_repository / "src/one/two").mkdir(parents=True) (fake_repository / "src/one/two/foo.py").write_text( cleandoc( """ # SPDX-License-Identifier: GPL-3.0-or-later """ ) ) (fake_repository / "src/hello.py").touch() (fake_repository / "src/one/world.py").touch() (fake_repository / "bar").mkdir(parents=True) (fake_repository / "bar/bar.py").touch() result = main( [ "annotate", "--copyright", "Joe Somebody", "--recursive", "src/", ], out=stringio, ) for path in (fake_repository / "src").rglob("src/**"): content = path.read_text() assert "SPDX-FileCopyrightText: 2018 Joe Somebody" in content assert "Joe Somebody" not in (fake_repository / "bar/bar.py").read_text() assert result == 0 def test_annotate_recursive_on_file(fake_repository, stringio, mock_date_today): """Don't expect errors when annotate is run 'recursively' on a file.""" result = main( [ "annotate", "--copyright", "Joe Somebody", "--recursive", "src/source_code.py", ], out=stringio, ) assert ( "Joe Somebody" in (fake_repository / "src/source_code.py").read_text() ) assert result == 0 def test_annotate_exit_if_unrecognised( fake_repository, stringio, mock_date_today ): """Expect error and no edited files if at least one file has not been recognised, with --exit-if-unrecognised enabled.""" (fake_repository / "baz").mkdir(parents=True) (fake_repository / "baz/foo.py").write_text("foo") (fake_repository / "baz/bar.unknown").write_text("bar") (fake_repository / "baz/baz.sh").write_text("baz") with pytest.raises(SystemExit): main( [ "annotate", "--license", "Apache-2.0", "--copyright", "Jane Doe", "--recursive", "--exit-if-unrecognised", "baz/", ] ) assert "Jane Doe" not in (fake_repository / "baz/foo.py").read_text() # REUSE-IgnoreEnd reuse-tool-4.0.3/tests/test_main_annotate_merge.py000066400000000000000000000110371464275211500223740ustar00rootroot00000000000000# SPDX-FileCopyrightText: 2021 Liam Beguin # SPDX-FileCopyrightText: 2024 Rivos Inc. # # SPDX-License-Identifier: GPL-3.0-or-later """Tests for reuse._main: annotate merge-copyrights option""" from inspect import cleandoc from reuse._main import main # pylint: disable=unused-argument # REUSE-IgnoreStart def test_annotate_merge_copyrights_simple(fake_repository, stringio): """Add multiple headers to a file with merge copyrights.""" simple_file = fake_repository / "foo.py" simple_file.write_text("pass") result = main( [ "annotate", "--year", "2016", "--license", "GPL-3.0-or-later", "--copyright", "Mary Sue", "--merge-copyrights", "foo.py", ], out=stringio, ) assert result == 0 assert simple_file.read_text() == cleandoc( """ # SPDX-FileCopyrightText: 2016 Mary Sue # # SPDX-License-Identifier: GPL-3.0-or-later pass """ ) result = main( [ "annotate", "--year", "2018", "--license", "GPL-3.0-or-later", "--copyright", "Mary Sue", "--merge-copyrights", "foo.py", ], out=stringio, ) assert result == 0 assert simple_file.read_text() == cleandoc( """ # SPDX-FileCopyrightText: 2016 - 2018 Mary Sue # # SPDX-License-Identifier: GPL-3.0-or-later pass """ ) def test_annotate_merge_copyrights_multi_prefix(fake_repository, stringio): """Add multiple headers to a file with merge copyrights.""" simple_file = fake_repository / "foo.py" simple_file.write_text("pass") for i in range(0, 3): result = main( [ "annotate", "--year", str(2010 + i), "--license", "GPL-3.0-or-later", "--copyright", "Mary Sue", "foo.py", ], out=stringio, ) assert result == 0 for i in range(0, 5): result = main( [ "annotate", "--year", str(2015 + i), "--license", "GPL-3.0-or-later", "--copyright-prefix", "string-c", "--copyright", "Mary Sue", "foo.py", ], out=stringio, ) assert result == 0 assert simple_file.read_text() == cleandoc( """ # Copyright (C) 2015 Mary Sue # Copyright (C) 2016 Mary Sue # Copyright (C) 2017 Mary Sue # Copyright (C) 2018 Mary Sue # Copyright (C) 2019 Mary Sue # SPDX-FileCopyrightText: 2010 Mary Sue # SPDX-FileCopyrightText: 2011 Mary Sue # SPDX-FileCopyrightText: 2012 Mary Sue # # SPDX-License-Identifier: GPL-3.0-or-later pass """ ) result = main( [ "annotate", "--year", "2018", "--license", "GPL-3.0-or-later", "--copyright", "Mary Sue", "--merge-copyrights", "foo.py", ], out=stringio, ) assert result == 0 assert simple_file.read_text() == cleandoc( """ # Copyright (C) 2010 - 2019 Mary Sue # # SPDX-License-Identifier: GPL-3.0-or-later pass """ ) def test_annotate_merge_copyrights_no_year_in_existing( fake_repository, stringio, mock_date_today ): """This checks the issue reported in . If an existing copyright line doesn't have a year, everything should still work. """ (fake_repository / "foo.py").write_text( cleandoc( """ # SPDX-FileCopyrightText: Jane Doe """ ) ) main( [ "annotate", "--merge-copyrights", "--copyright", "John Doe", "foo.py", ] ) assert ( cleandoc( """ # SPDX-FileCopyrightText: 2018 John Doe # SPDX-FileCopyrightText: Jane Doe """ ) in (fake_repository / "foo.py").read_text() ) # REUSE-IgnoreEnd reuse-tool-4.0.3/tests/test_project.py000066400000000000000000000653431464275211500200570ustar00rootroot00000000000000# SPDX-FileCopyrightText: 2017 Free Software Foundation Europe e.V. # SPDX-FileCopyrightText: 2022 Florian Snow # SPDX-FileCopyrightText: 2023 Carmen Bianca BAKKER # SPDX-FileCopyrightText: © 2020 Liferay, Inc. # # SPDX-License-Identifier: GPL-3.0-or-later """Tests for reuse.project.""" import os import shutil import warnings from inspect import cleandoc from pathlib import Path import pytest from conftest import RESOURCES_DIRECTORY, posix from license_expression import LicenseSymbol from reuse import ReuseInfo, SourceType from reuse._util import _LICENSING from reuse.global_licensing import ( GlobalLicensingParseError, NestedReuseTOML, ReuseDep5, ) from reuse.project import GlobalLicensingConflict, Project # REUSE-IgnoreStart def test_project_not_a_directory(empty_directory): """Cannot create a Project without a valid directory.""" (empty_directory / "foo.py").write_text("foo") with pytest.raises(NotADirectoryError): Project.from_directory(empty_directory / "foo.py") def test_project_not_exists(empty_directory): """Cannot create a Project with a directory that doesn't exist.""" with pytest.raises(FileNotFoundError): Project.from_directory(empty_directory / "foo") def test_project_conflicting_global_licensing(empty_directory): """If both REUSE.toml and .reuse/dep5 exist, expect a GlobalLicensingConflict. """ (empty_directory / "REUSE.toml").write_text("version = 1") (empty_directory / ".reuse").mkdir() (empty_directory / ".reuse/dep5").touch() with pytest.raises(GlobalLicensingConflict): Project.from_directory(empty_directory) def test_all_files(empty_directory): """Given a directory with some files, yield all files.""" (empty_directory / "foo").write_text("foo") (empty_directory / "bar").write_text("foo") project = Project.from_directory(empty_directory) assert {file_.name for file_ in project.all_files()} == {"foo", "bar"} def test_all_files_ignore_dot_license(empty_directory): """When file and file.license are present, only yield file.""" (empty_directory / "foo").write_text("foo") (empty_directory / "foo.license").write_text("foo") project = Project.from_directory(empty_directory) assert {file_.name for file_ in project.all_files()} == {"foo"} def test_all_files_ignore_cal_license(empty_directory): """CAL licenses contain SPDX tags referencing themselves. They should be skipped. """ (empty_directory / "CAL-1.0").write_text("foo") (empty_directory / "CAL-1.0.txt").write_text("foo") (empty_directory / "CAL-1.0-Combined-Work-Exception").write_text("foo") (empty_directory / "CAL-1.0-Combined-Work-Exception.txt").write_text("foo") project = Project.from_directory(empty_directory) assert not list(project.all_files()) def test_all_files_ignore_shl_license(empty_directory): """SHL-2.1 contains an SPDX tag referencing itself. It should be skipped.""" (empty_directory / "SHL-2.1").write_text("foo") (empty_directory / "SHL-2.1.txt").write_text("foo") project = Project.from_directory(empty_directory) assert not list(project.all_files()) def test_all_files_ignore_git(empty_directory): """When the git directory is present, ignore it.""" (empty_directory / ".git").mkdir() (empty_directory / ".git/config").write_text("foo") project = Project.from_directory(empty_directory) assert not list(project.all_files()) def test_all_files_ignore_hg(empty_directory): """When the hg directory is present, ignore it.""" (empty_directory / ".hg").mkdir() (empty_directory / ".hg/config").write_text("foo") project = Project.from_directory(empty_directory) assert not list(project.all_files()) def test_all_files_ignore_license_copying(empty_directory): """When there are files names LICENSE, LICENSE.ext, COPYING, or COPYING.ext, ignore them. """ (empty_directory / "LICENSE").write_text("foo") (empty_directory / "LICENSE.txt").write_text("foo") (empty_directory / "COPYING").write_text("foo") (empty_directory / "COPYING.txt").write_text("foo") project = Project.from_directory(empty_directory) assert not list(project.all_files()) def test_all_files_not_ignore_license_copying_no_ext(empty_directory): """Do not ignore files that start with LICENSE or COPYING and are followed by some non-extension text. """ (empty_directory / "LICENSE_README.md").write_text("foo") (empty_directory / "COPYING2").write_text("foo") project = Project.from_directory(empty_directory) assert len(list(project.all_files())) == 2 @posix def test_all_files_symlinks(empty_directory): """All symlinks must be ignored.""" (empty_directory / "blob").write_text("foo") (empty_directory / "blob.license").write_text( cleandoc( """ SPDX-FileCopyrightText: Jane Doe SPDX-License-Identifier: GPL-3.0-or-later """ ) ) (empty_directory / "symlink").symlink_to("blob") project = Project.from_directory(empty_directory) assert Path("symlink").absolute() not in project.all_files() def test_all_files_ignore_zero_sized(empty_directory): """Empty files should be skipped.""" (empty_directory / "foo").touch() project = Project.from_directory(empty_directory) assert Path("foo").absolute() not in project.all_files() def test_all_files_git_ignored(git_repository): """Given a Git repository where some files are ignored, do not yield those files. """ project = Project.from_directory(git_repository) assert Path("build/hello.py").absolute() not in project.all_files() def test_all_files_git_ignored_different_cwd(git_repository): """Given a Git repository where some files are ignored, do not yield those files. Be in a different CWD during the above. """ os.chdir(git_repository / "LICENSES") project = Project.from_directory(git_repository) assert Path("build/hello.py").absolute() not in project.all_files() def test_all_files_git_ignored_contains_space(git_repository): """Files that contain spaces are also ignored.""" (git_repository / "I contain spaces.pyc").write_text("foo") project = Project.from_directory(git_repository) assert Path("I contain spaces.pyc").absolute() not in project.all_files() @posix def test_all_files_git_ignored_contains_newline(git_repository): """Files that contain newlines are also ignored.""" (git_repository / "hello\nworld.pyc").write_text("foo") project = Project.from_directory(git_repository) assert Path("hello\nworld.pyc").absolute() not in project.all_files() def test_all_files_submodule_is_ignored(submodule_repository): """If a submodule is ignored, all_files should not raise an Exception.""" (submodule_repository / "submodule/foo.py").write_text("foo") gitignore = submodule_repository / ".gitignore" contents = gitignore.read_text() contents += "\nsubmodule/\n" gitignore.write_text(contents) project = Project.from_directory(submodule_repository) assert Path("submodule/foo.py").absolute() not in project.all_files() def test_all_files_hg_ignored(hg_repository): """Given a mercurial repository where some files are ignored, do not yield those files. """ project = Project.from_directory(hg_repository) assert Path("build/hello.py").absolute() not in project.all_files() def test_all_files_hg_ignored_different_cwd(hg_repository): """Given a mercurial repository where some files are ignored, do not yield those files. Be in a different CWD during the above. """ os.chdir(hg_repository / "LICENSES") project = Project.from_directory(hg_repository) assert Path("build/hello.py").absolute() not in project.all_files() def test_all_files_hg_ignored_contains_space(hg_repository): """File names that contain spaces are also ignored.""" (hg_repository / "I contain spaces.pyc").touch() project = Project.from_directory(hg_repository) assert Path("I contain spaces.pyc").absolute() not in project.all_files() @posix def test_all_files_hg_ignored_contains_newline(hg_repository): """File names that contain newlines are also ignored.""" (hg_repository / "hello\nworld.pyc").touch() project = Project.from_directory(hg_repository) assert Path("hello\nworld.pyc").absolute() not in project.all_files() def test_all_files_pijul_ignored(pijul_repository): """Given a pijul repository where some files are ignored, do not yield those files. """ project = Project.from_directory(pijul_repository) assert Path("build/hello.py").absolute() not in project.all_files() def test_all_files_pijul_ignored_different_cwd(pijul_repository): """Given a pijul repository where some files are ignored, do not yield those files. Be in a different CWD during the above. """ os.chdir(pijul_repository / "LICENSES") project = Project.from_directory(pijul_repository) assert Path("build/hello.py").absolute() not in project.all_files() def test_all_files_pijul_ignored_contains_space(pijul_repository): """File names that contain spaces are also ignored.""" (pijul_repository / "I contain spaces.pyc").touch() project = Project.from_directory(pijul_repository) assert Path("I contain spaces.pyc").absolute() not in project.all_files() @posix def test_all_files_pijul_ignored_contains_newline(pijul_repository): """File names that contain newlines are also ignored.""" (pijul_repository / "hello\nworld.pyc").touch() project = Project.from_directory(pijul_repository) assert Path("hello\nworld.pyc").absolute() not in project.all_files() def test_reuse_info_of_file_does_not_exist(fake_repository): """Raise FileNotFoundError when asking for the REUSE info of a file that does not exist. """ project = Project.from_directory(fake_repository) with pytest.raises(FileNotFoundError): project.reuse_info_of(fake_repository / "does_not_exist") def test_reuse_info_of_directory(empty_directory): """Raise IsADirectoryError when calling reuse_info_of on a directory.""" (empty_directory / "src").mkdir() project = Project.from_directory(empty_directory) with pytest.raises((IsADirectoryError, PermissionError)): project.reuse_info_of(empty_directory / "src") def test_reuse_info_of_unlicensed_file(fake_repository): """Return an empty set when asking for the REUSE information of a file that has no REUSE information. """ (fake_repository / "foo.py").write_text("foo") project = Project.from_directory(fake_repository) assert not bool(project.reuse_info_of("foo.py")) def test_reuse_info_of_uncommentable_file(empty_directory): """When a file is marked uncommentable, but does contain REUSE info, read it anyway. """ (empty_directory / "foo.png").write_text("Copyright 2017 Jane Doe") project = Project.from_directory(empty_directory) result = project.reuse_info_of("foo.png") assert len(result) == 1 assert result[0].copyright_lines def test_reuse_info_of_only_copyright(fake_repository): """A file contains only a copyright line. Test whether it correctly picks up on that. """ (fake_repository / "foo.py").write_text( "SPDX-FileCopyrightText: 2017 Jane Doe" ) project = Project.from_directory(fake_repository) reuse_info = project.reuse_info_of("foo.py")[0] assert not any(reuse_info.spdx_expressions) assert len(reuse_info.copyright_lines) == 1 assert ( reuse_info.copyright_lines.pop() == "SPDX-FileCopyrightText: 2017 Jane Doe" ) assert reuse_info.source_type == SourceType.FILE_HEADER assert reuse_info.source_path == "foo.py" assert reuse_info.path == "foo.py" def test_reuse_info_of_toml_precedence(empty_directory): """When the precedence is set to toml, ignore file contents.""" (empty_directory / "REUSE.toml").write_text( cleandoc( """ version = 1 [[annotations]] path = "foo.py" precedence = "override" SPDX-FileCopyrightText = "2017 Jane Doe" SPDX-License-Identifier = "CC0-1.0" """ ) ) (empty_directory / "foo.py").write_text( cleandoc( """ # The below should give a parser error. Not going to happen because # the file is never parsed. SPDX-License-Identifier: ignored AND SPDX-FileCopyrightText: ignored """ ) ) project = Project.from_directory(empty_directory) reuse_infos = project.reuse_info_of("foo.py") assert len(reuse_infos) == 1 reuse_info = reuse_infos[0] assert reuse_info.source_type == SourceType.REUSE_TOML assert reuse_info.source_path == "REUSE.toml" assert reuse_info.path == "foo.py" assert LicenseSymbol("CC0-1.0") in reuse_info.spdx_expressions assert "2017 Jane Doe" in reuse_info.copyright_lines def test_reuse_info_of_closest_precedence(empty_directory): """When the precedence is set to closest, ignore REUSE.toml contents.""" (empty_directory / "REUSE.toml").write_text( cleandoc( """ version = 1 [[annotations]] path = "foo.py" precedence = "closest" SPDX-FileCopyrightText = "2017 Jane Doe" SPDX-License-Identifier = "CC0-1.0" """ ) ) (empty_directory / "foo.py").write_text( cleandoc( """ SPDX-License-Identifier: MIT SPDX-FileCopyrightText: In File """ ) ) project = Project.from_directory(empty_directory) reuse_infos = project.reuse_info_of("foo.py") assert len(reuse_infos) == 1 reuse_info = reuse_infos[0] assert reuse_info.source_type == SourceType.FILE_HEADER assert reuse_info.source_path == "foo.py" assert reuse_info.path == "foo.py" assert LicenseSymbol("MIT") in reuse_info.spdx_expressions assert "SPDX-FileCopyrightText: In File" in reuse_info.copyright_lines def test_reuse_info_of_closest_precedence_empty(empty_directory): """When the precedence is set to closest, but the file is empty, use REUSE.toml contents. """ (empty_directory / "REUSE.toml").write_text( cleandoc( """ version = 1 [[annotations]] path = "foo.py" precedence = "closest" SPDX-FileCopyrightText = "2017 Jane Doe" SPDX-License-Identifier = "CC0-1.0" """ ) ) (empty_directory / "foo.py").touch() project = Project.from_directory(empty_directory) reuse_infos = project.reuse_info_of("foo.py") assert len(reuse_infos) == 1 reuse_info = reuse_infos[0] assert reuse_info.source_type == SourceType.REUSE_TOML assert reuse_info.source_path == "REUSE.toml" assert reuse_info.path == "foo.py" assert LicenseSymbol("CC0-1.0") in reuse_info.spdx_expressions assert "2017 Jane Doe" in reuse_info.copyright_lines def test_reuse_info_of_aggregate_precedence(empty_directory): """When the precedence is set to aggregate, aggregate sources.""" (empty_directory / "REUSE.toml").write_text( cleandoc( """ version = 1 [[annotations]] path = "foo.py" precedence = "aggregate" SPDX-FileCopyrightText = "2017 Jane Doe" SPDX-License-Identifier = "CC0-1.0" """ ) ) (empty_directory / "foo.py").write_text( cleandoc( """ SPDX-License-Identifier: MIT SPDX-FileCopyrightText: In File """ ) ) project = Project.from_directory(empty_directory) reuse_infos = project.reuse_info_of("foo.py") assert len(reuse_infos) == 2 assert reuse_infos[0].source_type != reuse_infos[1].source_type for reuse_info in reuse_infos: if reuse_info.source_type == SourceType.FILE_HEADER: assert reuse_info.source_type assert reuse_info.source_path == "foo.py" assert reuse_info.path == "foo.py" assert LicenseSymbol("MIT") in reuse_info.spdx_expressions assert ( "SPDX-FileCopyrightText: In File" in reuse_info.copyright_lines ) elif reuse_info.source_type == SourceType.REUSE_TOML: assert reuse_info.source_path == "REUSE.toml" assert reuse_info.path == "foo.py" assert LicenseSymbol("CC0-1.0") in reuse_info.spdx_expressions assert "2017 Jane Doe" in reuse_info.copyright_lines else: assert False def test_reuse_info_of_aggregate_and_closest(empty_directory): """A rather tricky case. Top-level REUSE.toml says aggregate. Nearest REUSE.toml says closest. The top-level REUSE.toml info should now be aggregated with the file contents IF they exist. Else, aggregate with the nearest REUSE.toml info. """ (empty_directory / "REUSE.toml").write_text( cleandoc( """ version = 1 [[annotations]] path = "src/foo.py" precedence = "aggregate" SPDX-FileCopyrightText = "2017 Jane Doe" SPDX-License-Identifier = "CC0-1.0" """ ) ) (empty_directory / "src").mkdir() (empty_directory / "src/REUSE.toml").write_text( cleandoc( """ version = 1 [[annotations]] path = "foo.py" precedence = "closest" SPDX-FileCopyrightText = "2017 John Doe" SPDX-License-Identifier = "MIT" """ ) ) (empty_directory / "src/foo.py").touch() project = Project.from_directory(empty_directory) assert project.reuse_info_of("src/foo.py") == [ ReuseInfo( spdx_expressions={_LICENSING.parse("CC0-1.0")}, copyright_lines={"2017 Jane Doe"}, path="src/foo.py", source_path="REUSE.toml", source_type=SourceType.REUSE_TOML, ), ReuseInfo( spdx_expressions={_LICENSING.parse("MIT")}, copyright_lines={"2017 John Doe"}, path="src/foo.py", source_path="src/REUSE.toml", source_type=SourceType.REUSE_TOML, ), ] # Populate the file. (empty_directory / "src/foo.py").write_text( cleandoc( """ # Copyright Example # SPDX-License-Identifier: 0BSD """ ) ) assert project.reuse_info_of("src/foo.py") == [ ReuseInfo( spdx_expressions={_LICENSING.parse("CC0-1.0")}, copyright_lines={"2017 Jane Doe"}, path="src/foo.py", source_path="REUSE.toml", source_type=SourceType.REUSE_TOML, ), ReuseInfo( spdx_expressions={_LICENSING.parse("0BSD")}, copyright_lines={"Copyright Example"}, path="src/foo.py", source_path="src/foo.py", source_type=SourceType.FILE_HEADER, ), ] def test_reuse_info_of_copyright_xor_licensing(empty_directory): """Test a corner case where partial REUSE information is defined inside of a file (copyright xor licensing). Get the missing information from the REUSE.toml. """ (empty_directory / "REUSE.toml").write_text( cleandoc( """ version = 1 [[annotations]] path = "foo.py" SPDX-FileCopyrightText = "2017 Jane Doe" SPDX-License-Identifier = "CC0-1.0" [[annotations]] path = "bar.py" SPDX-License-Identifier = "CC0-1.0" """ ) ) (empty_directory / "foo.py").write_text( cleandoc( """ SPDX-License-Identifier: MIT """ ) ) (empty_directory / "bar.py").write_text( cleandoc( """ SPDX-FileCopyrightText: 2017 John Doe """ ) ) project = Project.from_directory(empty_directory) foo_infos = project.reuse_info_of("foo.py") assert len(foo_infos) == 2 foo_toml_info = [info for info in foo_infos if info.copyright_lines][0] assert foo_toml_info.source_type == SourceType.REUSE_TOML assert not foo_toml_info.spdx_expressions foo_file_info = [info for info in foo_infos if info.spdx_expressions][0] assert foo_file_info.source_type == SourceType.FILE_HEADER assert not foo_file_info.copyright_lines bar_infos = project.reuse_info_of("bar.py") assert len(bar_infos) == 2 bar_toml_info = [info for info in bar_infos if info.spdx_expressions][0] assert bar_toml_info.source_type == SourceType.REUSE_TOML assert not bar_toml_info.copyright_lines bar_file_info = [info for info in bar_infos if info.copyright_lines][0] assert bar_file_info.source_type == SourceType.FILE_HEADER assert not bar_file_info.spdx_expressions def test_reuse_info_of_no_duplicates(empty_directory): """A file contains the same lines twice. The ReuseInfo only contains those lines once. """ spdx_line = "SPDX-License-Identifier: GPL-3.0-or-later\n" copyright_line = ( "SPDX-FileCopyrightText: 2017 Free Software Foundation Europe\n" ) text = spdx_line + copyright_line (empty_directory / "foo.py").write_text(text * 2) project = Project.from_directory(empty_directory) reuse_info = project.reuse_info_of("foo.py")[0] assert len(reuse_info.spdx_expressions) == 1 assert LicenseSymbol("GPL-3.0-or-later") in reuse_info.spdx_expressions assert len(reuse_info.copyright_lines) == 1 assert ( "SPDX-FileCopyrightText: 2017 Free Software Foundation Europe" in reuse_info.copyright_lines ) def test_reuse_info_of_binary_succeeds(fake_repository_dep5): """reuse_info_of succeeds when the target is covered by dep5.""" shutil.copy( RESOURCES_DIRECTORY / "fsfe.png", fake_repository_dep5 / "doc/fsfe.png" ) project = Project.from_directory(fake_repository_dep5) reuse_info = project.reuse_info_of("doc/fsfe.png")[0] assert LicenseSymbol("CC0-1.0") in reuse_info.spdx_expressions assert reuse_info.source_type == SourceType.DEP5 assert reuse_info.path == "doc/fsfe.png" def test_license_file_detected(empty_directory): """Test whether---when given a file and a license file---the license file is detected and read. """ (empty_directory / "foo.py").write_text("foo") (empty_directory / "foo.py.license").write_text( "SPDX-FileCopyrightText: 2017 Jane Doe\nSPDX-License-Identifier: MIT\n" ) project = Project.from_directory(empty_directory) reuse_info = project.reuse_info_of("foo.py")[0] assert "SPDX-FileCopyrightText: 2017 Jane Doe" in reuse_info.copyright_lines assert LicenseSymbol("MIT") in reuse_info.spdx_expressions assert reuse_info.source_type == SourceType.DOT_LICENSE assert reuse_info.path == "foo.py" assert reuse_info.source_path == "foo.py.license" def test_licenses_filename(empty_directory): """Detect the license identifier of a license from its stem.""" (empty_directory / "LICENSES").mkdir() (empty_directory / "LICENSES/foo.txt").write_text("foo") project = Project.from_directory(empty_directory) assert "foo" in project.licenses def test_licenses_no_extension(empty_directory): """Detect the license identifier of a license from its full name if it is in the license list. """ (empty_directory / "LICENSES").mkdir() (empty_directory / "LICENSES/GPL-3.0-or-later").write_text("foo") (empty_directory / "LICENSES/MIT-3.0-or-later").write_text("foo") project = Project.from_directory(empty_directory) assert "GPL-3.0-or-later" in project.licenses assert "MIT-3" in project.licenses def test_licenses_subdirectory(empty_directory): """Find a license in a subdirectory of LICENSES/.""" (empty_directory / "LICENSES/sub").mkdir(parents=True) (empty_directory / "LICENSES/sub/MIT.txt").write_text("foo") project = Project.from_directory(empty_directory) assert "MIT" in project.licenses def test_relative_from_root(empty_directory): """A simple test. Given /path/to/root/src/hello.py, return src/hello.py.""" project = Project.from_directory(empty_directory) assert project.relative_from_root(project.root / "src/hello.py") == Path( "src/hello.py" ) def test_relative_from_root_no_shared_base_path(empty_directory): """A path can still be relative from root if the paths do not have a common prefix. For instance, if root is /path/to/root and given root/src/hello.py from the directory /path/to, return src/hello.py. This is a bit involved, but works out. """ project = Project.from_directory(empty_directory) parent = empty_directory.parent os.chdir(parent) assert project.relative_from_root( Path(f"{project.root.name}/src/hello.py") ) == Path("src/hello.py") def test_find_global_licensing_dep5(fake_repository_dep5): """Find the dep5 file. Also output a PendingDeprecationWarning.""" with warnings.catch_warnings(record=True) as caught_warnings: result = Project.find_global_licensing(fake_repository_dep5) assert result.path == fake_repository_dep5 / ".reuse/dep5" assert result.cls == ReuseDep5 assert len(caught_warnings) == 1 assert issubclass( caught_warnings[0].category, PendingDeprecationWarning ) def test_find_global_licensing_reuse_toml(fake_repository_reuse_toml): """Find the REUSE.toml file.""" result = Project.find_global_licensing(fake_repository_reuse_toml) assert result.path == fake_repository_reuse_toml / "." assert result.cls == NestedReuseTOML def test_find_global_licensing_none(empty_directory): """Find no file.""" result = Project.find_global_licensing(empty_directory) assert result is None def test_find_global_licensing_conflict(fake_repository_dep5): """Expect an error on a conflict""" (fake_repository_dep5 / "REUSE.toml").touch() with pytest.raises(GlobalLicensingConflict): Project.find_global_licensing(fake_repository_dep5) def test_duplicate_field_dep5(empty_directory): """When a duplicate field is in a dep5 file, correctly handle errors.""" dep5_text = cleandoc( """ Format: https://example.com/format/1.0 Upstream-Name: Some project Upstream-Contact: Jane Doe Source: https://example.com/ Files: foo.py Copyright: 2017 Jane Doe Copyright: 2017 John Doe License: GPL-3.0-or-later """ ) (empty_directory / ".reuse").mkdir() (empty_directory / ".reuse/dep5").write_text(dep5_text) with pytest.raises(GlobalLicensingParseError): Project.from_directory(empty_directory) # REUSE-IgnoreEnd reuse-tool-4.0.3/tests/test_report.py000066400000000000000000000374511464275211500177230ustar00rootroot00000000000000# SPDX-FileCopyrightText: 2017 Free Software Foundation Europe e.V. # SPDX-FileCopyrightText: 2022 Florian Snow # SPDX-FileCopyrightText: 2022 Pietro Albini # # SPDX-License-Identifier: GPL-3.0-or-later """Tests for reuse.report""" import os import re import warnings from inspect import cleandoc from textwrap import dedent from conftest import cpython, posix from reuse import SourceType from reuse.project import Project from reuse.report import FileReport, ProjectReport # REUSE-IgnoreStart def test_generate_file_report_file_simple( fake_repository, add_license_concluded ): """An extremely simple generate test, just to see if the function doesn't crash. """ project = Project.from_directory(fake_repository) result = FileReport.generate( project, "src/source_code.py", add_license_concluded=add_license_concluded, ) assert result.licenses_in_file == ["GPL-3.0-or-later"] assert ( result.license_concluded == "GPL-3.0-or-later" if add_license_concluded else "NOASSERTION" ) assert result.copyright == "SPDX-FileCopyrightText: 2017 Jane Doe" assert not result.bad_licenses assert not result.missing_licenses def test_generate_file_report_file_from_different_cwd( fake_repository, add_license_concluded ): """Another simple generate test, but from a different CWD.""" os.chdir("/") project = Project.from_directory(fake_repository) result = FileReport.generate( project, fake_repository / "src/source_code.py", add_license_concluded=add_license_concluded, ) assert result.licenses_in_file == ["GPL-3.0-or-later"] assert ( result.license_concluded == "GPL-3.0-or-later" if add_license_concluded else "NOASSERTION" ) assert result.copyright == "SPDX-FileCopyrightText: 2017 Jane Doe" assert not result.bad_licenses assert not result.missing_licenses def test_generate_file_report_file_missing_license( fake_repository, add_license_concluded ): """Simple generate test with a missing license.""" (fake_repository / "foo.py").write_text( "SPDX-License-Identifier: BSD-3-Clause" ) project = Project.from_directory(fake_repository) result = FileReport.generate( project, "foo.py", add_license_concluded=add_license_concluded ) assert result.copyright == "" assert result.licenses_in_file == ["BSD-3-Clause"] assert ( result.license_concluded == "BSD-3-Clause" if add_license_concluded else "NOASSERTION" ) assert result.missing_licenses == {"BSD-3-Clause"} assert not result.bad_licenses def test_generate_file_report_file_bad_license( fake_repository, add_license_concluded ): """Simple generate test with a bad license.""" (fake_repository / "foo.py").write_text( "SPDX-License-Identifier: fakelicense" ) project = Project.from_directory(fake_repository) result = FileReport.generate( project, "foo.py", add_license_concluded=add_license_concluded ) assert result.copyright == "" assert result.licenses_in_file == ["fakelicense"] assert ( result.license_concluded == "fakelicense" if add_license_concluded else "NOASSERTION" ) assert result.bad_licenses == {"fakelicense"} assert result.missing_licenses == {"fakelicense"} def test_generate_file_report_license_contains_plus( fake_repository, add_license_concluded ): """Given a license expression akin to Apache-1.0+, LICENSES/Apache-1.0.txt should be an appropriate license file. """ (fake_repository / "foo.py").write_text( "SPDX-License-Identifier: Apache-1.0+" ) (fake_repository / "LICENSES/Apache-1.0.txt").touch() project = Project.from_directory(fake_repository) result = FileReport.generate( project, "foo.py", add_license_concluded=add_license_concluded ) assert result.copyright == "" assert result.licenses_in_file == ["Apache-1.0+"] assert ( result.license_concluded == "Apache-1.0+" if add_license_concluded else "NOASSERTION" ) assert not result.bad_licenses assert not result.missing_licenses def test_generate_file_report_exception(fake_repository, add_license_concluded): """Simple generate test to test if the exception is detected.""" project = Project.from_directory(fake_repository) result = FileReport.generate( project, "src/exception.py", add_license_concluded=add_license_concluded ) assert set(result.licenses_in_file) == { "GPL-3.0-or-later", "Autoconf-exception-3.0", } assert ( result.license_concluded == "GPL-3.0-or-later WITH Autoconf-exception-3.0" if add_license_concluded else "NOASSERTION" ) assert result.copyright == "SPDX-FileCopyrightText: 2017 Jane Doe" assert not result.bad_licenses assert not result.missing_licenses def test_generate_file_report_no_licenses( fake_repository, add_license_concluded ): """Test behavior when no license information is present in the file""" (fake_repository / "foo.py").write_text("") project = Project.from_directory(fake_repository) result = FileReport.generate( project, "foo.py", add_license_concluded=add_license_concluded ) assert result.copyright == "" assert not result.licenses_in_file assert ( result.license_concluded == "NONE" if add_license_concluded else "NOASSERTION" ) assert not result.bad_licenses assert not result.missing_licenses def test_generate_file_report_multiple_licenses( fake_repository, add_license_concluded ): """Test that all licenses are included in LicenseConcluded""" project = Project.from_directory(fake_repository) result = FileReport.generate( project, "src/multiple_licenses.rs", add_license_concluded=add_license_concluded, ) assert result.copyright == "SPDX-FileCopyrightText: 2022 Jane Doe" assert set(result.licenses_in_file) == { "GPL-3.0-or-later", "Apache-2.0", "CC0-1.0", "Autoconf-exception-3.0", } assert ( result.license_concluded == "GPL-3.0-or-later AND (Apache-2.0 OR CC0-1.0" " WITH Autoconf-exception-3.0)" if add_license_concluded else "NOASSERTION" ) assert not result.bad_licenses assert not result.missing_licenses def test_generate_file_report_to_dict_lint_source_information( fake_repository_dep5, ): """When a file is covered both by DEP5 and its file header, the lint dict should correctly convey the source information. """ (fake_repository_dep5 / "doc/foo.py").write_text( dedent( """ SPDX-License-Identifier: MIT OR 0BSD SPDX-FileCopyrightText: in file""" ) ) project = Project.from_directory(fake_repository_dep5) with warnings.catch_warnings(record=True): report = FileReport.generate( project, "doc/foo.py", ) result = report.to_dict_lint() assert result["path"] == "doc/foo.py" assert len(result["copyrights"]) == 2 assert ( result["copyrights"][0]["source_type"] != result["copyrights"][1]["source_type"] ) for copyright_ in result["copyrights"]: if copyright_["source_type"] == SourceType.DEP5.value: assert copyright_["source"] == ".reuse/dep5" assert copyright_["value"] == "2017 Jane Doe" elif copyright_["source_type"] == SourceType.FILE_HEADER.value: assert copyright_["source"] == "doc/foo.py" assert copyright_["value"] == "SPDX-FileCopyrightText: in file" assert len(result["spdx_expressions"]) == 2 assert ( result["spdx_expressions"][0]["source_type"] != result["spdx_expressions"][1]["source_type"] ) for expression in result["spdx_expressions"]: if expression["source_type"] == SourceType.DEP5.value: assert expression["source"] == ".reuse/dep5" assert expression["value"] == "CC0-1.0" elif expression["source_type"] == SourceType.FILE_HEADER.value: assert expression["source"] == "doc/foo.py" assert expression["value"] == "MIT OR 0BSD" def test_generate_project_report_simple(fake_repository, multiprocessing): """Simple generate test, just to see if it sort of works.""" project = Project.from_directory(fake_repository) result = ProjectReport.generate(project, multiprocessing=multiprocessing) assert not result.bad_licenses assert not result.licenses_without_extension assert not result.missing_licenses assert not result.unused_licenses assert result.used_licenses assert not result.read_errors assert result.file_reports def test_generate_project_report_licenses_without_extension( fake_repository, multiprocessing ): """Licenses without extension are detected.""" (fake_repository / "LICENSES/CC0-1.0.txt").rename( fake_repository / "LICENSES/CC0-1.0" ) project = Project.from_directory(fake_repository) result = ProjectReport.generate(project, multiprocessing=multiprocessing) assert "CC0-1.0" in result.licenses_without_extension def test_generate_project_report_missing_license( fake_repository, multiprocessing ): """Missing licenses are detected.""" (fake_repository / "LICENSES/GPL-3.0-or-later.txt").unlink() project = Project.from_directory(fake_repository) result = ProjectReport.generate(project, multiprocessing=multiprocessing) assert "GPL-3.0-or-later" in result.missing_licenses assert not result.bad_licenses def test_generate_project_report_bad_license(fake_repository, multiprocessing): """Bad licenses are detected.""" (fake_repository / "LICENSES/bad.txt").write_text("foo") project = Project.from_directory(fake_repository) result = ProjectReport.generate(project, multiprocessing=multiprocessing) assert result.bad_licenses assert not result.missing_licenses def test_generate_project_report_unused_license( fake_repository, multiprocessing ): """Unused licenses are detected.""" (fake_repository / "LICENSES/MIT.txt").write_text("foo") project = Project.from_directory(fake_repository) result = ProjectReport.generate(project, multiprocessing=multiprocessing) assert result.unused_licenses == {"MIT"} def test_generate_project_report_unused_license_plus( fake_repository, multiprocessing ): """Apache-1.0+ is not an unused license if LICENSES/Apache-1.0.txt exists. Furthermore, Apache-1.0+ is separately identified as a used license. """ (fake_repository / "foo.py").write_text( "SPDX-License-Identifier: Apache-1.0+" ) (fake_repository / "bar.py").write_text( "SPDX-License-Identifier: Apache-1.0" ) (fake_repository / "LICENSES/Apache-1.0.txt").touch() project = Project.from_directory(fake_repository) result = ProjectReport.generate(project, multiprocessing=multiprocessing) assert not result.unused_licenses assert {"Apache-1.0", "Apache-1.0+"}.issubset(result.used_licenses) def test_generate_project_report_unused_license_plus_only_plus( fake_repository, multiprocessing ): """If Apache-1.0+ is the only declared license in the project, LICENSES/Apache-1.0.txt should not be an unused license. """ (fake_repository / "foo.py").write_text( "SPDX-License-Identifier: Apache-1.0+" ) (fake_repository / "LICENSES/Apache-1.0.txt").touch() project = Project.from_directory(fake_repository) result = ProjectReport.generate(project, multiprocessing=multiprocessing) assert not result.unused_licenses assert "Apache-1.0+" in result.used_licenses assert "Apache-1.0" not in result.used_licenses def test_generate_project_report_bad_license_in_file( fake_repository, multiprocessing ): """Bad licenses in files are detected.""" (fake_repository / "foo.py").write_text("SPDX-License-Identifier: bad") project = Project.from_directory(fake_repository) result = ProjectReport.generate(project, multiprocessing=multiprocessing) assert "bad" in result.bad_licenses def test_generate_project_report_bad_license_can_also_be_missing( fake_repository, multiprocessing ): """Bad licenses can also be missing licenses.""" (fake_repository / "foo.py").write_text("SPDX-License-Identifier: bad") project = Project.from_directory(fake_repository) result = ProjectReport.generate(project, multiprocessing=multiprocessing) assert "bad" in result.bad_licenses assert "bad" in result.missing_licenses def test_generate_project_report_deprecated_license( fake_repository, multiprocessing ): """Deprecated licenses are detected.""" (fake_repository / "LICENSES/GPL-3.0-or-later.txt").rename( fake_repository / "LICENSES/GPL-3.0.txt" ) project = Project.from_directory(fake_repository) result = ProjectReport.generate(project, multiprocessing=multiprocessing) assert "GPL-3.0" in result.deprecated_licenses @cpython @posix def test_generate_project_report_read_error(fake_repository, multiprocessing): """Files that cannot be read are added to the read error list.""" (fake_repository / "bad").write_text("foo") (fake_repository / "bad").chmod(0o000) project = Project.from_directory(fake_repository) result = ProjectReport.generate(project, multiprocessing=multiprocessing) # pylint: disable=superfluous-parens assert (fake_repository / "bad") in result.read_errors def test_generate_project_report_to_dict_lint(fake_repository, multiprocessing): """Generate dictionary output and verify correct ordering.""" project = Project.from_directory(fake_repository) report = ProjectReport.generate(project, multiprocessing=multiprocessing) result = report.to_dict_lint() # Check if the top three keys are at the beginning of the dictionary assert list(result.keys())[:3] == [ "lint_version", "reuse_spec_version", "reuse_tool_version", ] # Check if the recommendation key is at the bottom of the dictionary assert list(result.keys())[-1] == "recommendations" # Check if the rest of the keys are sorted alphabetically assert list(result.keys())[3:-1] == sorted(list(result.keys())[3:-1]) def test_generate_project_partial_info_in_toml( empty_directory, multiprocessing ): """Some information is in REUSE.toml, and some is inside of the file.""" (empty_directory / "REUSE.toml").write_text( cleandoc( """ version = 1 [[annotations]] path = "foo.py" precedence = "closest" SPDX-FileCopyrightText = "Jane Doe" # This is ignored because it's in the file! SPDX-License-Identifier = "MIT" """ ) ) (empty_directory / "foo.py").write_text("# SPDX-License-Identifier: 0BSD") project = Project.from_directory(empty_directory) report = ProjectReport.generate(project, multiprocessing=multiprocessing) file_report = next( report for report in report.file_reports if report.path.name == "foo.py" ) infos = file_report.reuse_infos assert len(infos) == 2 assert file_report.copyright == "Jane Doe" assert file_report.licenses_in_file == ["0BSD"] def test_bill_of_materials(fake_repository, multiprocessing): """Generate a bill of materials.""" project = Project.from_directory(fake_repository) report = ProjectReport.generate(project, multiprocessing=multiprocessing) # TODO: Actually do something bom = report.bill_of_materials() created_re = re.compile( r"^Created: \d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z$", re.MULTILINE ) assert created_re.search(bom) is not None # REUSE-IgnoreEnd reuse-tool-4.0.3/tests/test_util.py000066400000000000000000000457521464275211500173700ustar00rootroot00000000000000# SPDX-FileCopyrightText: 2017 Free Software Foundation Europe e.V. # SPDX-FileCopyrightText: 2022 Carmen Bianca Bakker # SPDX-FileCopyrightText: 2022 Florian Snow # SPDX-FileCopyrightText: 2022 Nico Rikken # SPDX-FileCopyrightText: 2022 Pietro Albini # SPDX-FileCopyrightText: 2024 Rivos Inc. # SPDX-FileCopyrightText: © 2020 Liferay, Inc. # # SPDX-License-Identifier: GPL-3.0-or-later """Tests for reuse._util""" import os from argparse import ArgumentTypeError from inspect import cleandoc from io import BytesIO from pathlib import Path import pytest from boolean.boolean import ParseError from conftest import no_root, posix from reuse import _util from reuse._util import _LICENSING # REUSE-IgnoreStart def test_extract_expression(): """Parse various expressions.""" expressions = ["GPL-3.0+", "GPL-3.0 AND CC0-1.0", "nonsense"] for expression in expressions: result = _util.extract_reuse_info( f"SPDX-License-Identifier: {expression}" ) assert result.spdx_expressions == {_LICENSING.parse(expression)} def test_extract_expression_from_ascii_art_frame(): """Parse an expression from an ASCII art frame""" result = _util.extract_reuse_info( cleandoc( """ /**********************************\\ |* SPDX-License-Identifier: MIT *| \\**********************************/ """ ) ) assert result.spdx_expressions == {_LICENSING.parse("MIT")} def test_extract_erroneous_expression(): """Parse an incorrect expression.""" expression = "SPDX-License-Identifier: GPL-3.0-or-later AND (MIT OR)" with pytest.raises(ParseError): _util.extract_reuse_info(expression) def test_extract_no_info(): """Given a string without REUSE information, return an empty ReuseInfo object. """ result = _util.extract_reuse_info("") assert result == _util.ReuseInfo() def test_extract_tab(): """A tag followed by a tab is also valid.""" result = _util.extract_reuse_info("SPDX-License-Identifier:\tMIT") assert result.spdx_expressions == {_LICENSING.parse("MIT")} def test_extract_many_whitespace(): """When a tag is followed by a lot of whitespace, the whitespace should be filtered out. """ result = _util.extract_reuse_info("SPDX-License-Identifier: MIT") assert result.spdx_expressions == {_LICENSING.parse("MIT")} def test_extract_bibtex_comment(): """A special case for BibTex comments.""" expression = "@Comment{SPDX-License-Identifier: GPL-3.0-or-later}" result = _util.extract_reuse_info(expression) assert str(list(result.spdx_expressions)[0]) == "GPL-3.0-or-later" def test_extract_copyright(): """Given a file with copyright information, have it return that copyright information. """ copyright_line = "SPDX-FileCopyrightText: 2019 Jane Doe" result = _util.extract_reuse_info(copyright_line) assert result.copyright_lines == {copyright_line} def test_extract_copyright_duplicate(): """When a copyright line is duplicated, only yield one.""" copyright_line = "SPDX-FileCopyrightText: 2019 Jane Doe" result = _util.extract_reuse_info( "\n".join((copyright_line, copyright_line)) ) assert result.copyright_lines == {copyright_line} def test_extract_copyright_tab(): """A tag followed by a tab is also valid.""" copyright_line = "SPDX-FileCopyrightText:\t2019 Jane Doe" result = _util.extract_reuse_info(copyright_line) assert result.copyright_lines == {copyright_line} def test_extract_copyright_many_whitespace(): """When a tag is followed by a lot of whitespace, that is also valid. The whitespace is not filtered out. """ copyright_line = "SPDX-FileCopyrightText: 2019 Jane Doe" result = _util.extract_reuse_info(copyright_line) assert result.copyright_lines == {copyright_line} def test_extract_copyright_variations(): """There are multiple ways to declare copyright. All should be detected.""" text = cleandoc( """ SPDX-FileCopyrightText: 2019 Jane Doe SPDX-FileCopyrightText: © 2019 Jane Doe © 2019 Jane Doe Copyright © 2019 Jane Doe Copyright 2019 Jane Doe Copyright (C) 2019 Jane Doe """ ) result = _util.extract_reuse_info(text) lines = text.splitlines() for line in lines: assert line in result.copyright_lines assert len(lines) == len(result.copyright_lines) def test_extract_with_ignore_block(): """Ensure that the copyright and licensing information inside the ignore block is actually ignored. """ text = cleandoc( """ SPDX-FileCopyrightText: 2019 Jane Doe SPDX-License-Identifier: CC0-1.0 REUSE-IgnoreStart SPDX-FileCopyrightText: 2019 John Doe SPDX-License-Identifier: GPL-3.0-or-later REUSE-IgnoreEnd SPDX-FileCopyrightText: 2019 Eve """ ) result = _util.extract_reuse_info(text) assert len(result.copyright_lines) == 2 assert len(result.spdx_expressions) == 1 def test_extract_sameline_multiline(): """When a copyright line is in a multi-line style comment on a single line, do not include the comment end pattern as part of the copyright. """ text = "" result = _util.extract_reuse_info(text) assert len(result.copyright_lines) == 1 assert result.copyright_lines == {"SPDX-FileCopyrightText: Jane Doe"} def test_extract_special_endings(): """Strip some non-comment-style endings from the end of copyright and licensing information. """ text = cleandoc( """ [Copyright 2019 Ajnulo] :: """ ) result = _util.extract_reuse_info(text) for item in result.copyright_lines: assert ">" not in item assert "] ::" not in item def test_extract_contributors(): """Correctly extract SPDX-FileContributor information from text.""" text = cleandoc( """ # SPDX-FileContributor: Jane Doe """ ) result = _util.extract_reuse_info(text) assert result.contributor_lines == {"Jane Doe"} def test_filter_ignore_block_with_comment_style(): """Test that the ignore block is properly removed if start and end markers are in comment style. """ text = cleandoc( """ Relevant text # REUSE-IgnoreStart Ignored text # REUSE-IgnoreEnd Other relevant text """ ) expected = "Relevant text\n# \nOther relevant text" result = _util.filter_ignore_block(text) assert result == expected def test_filter_ignore_block_non_comment_style(): """Test that the ignore block is properly removed if start and end markers are not comment style. """ text = cleandoc( """ Relevant text REUSE-IgnoreStart Ignored text REUSE-IgnoreEnd Other relevant text """ ) expected = cleandoc( """ Relevant text Other relevant text """ ) result = _util.filter_ignore_block(text) assert result == expected def test_filter_ignore_block_with_ignored_information_on_same_line(): """Test that the ignore block is properly removed if there is information to be ignored on the same line. """ text = cleandoc( """ Relevant text REUSE-IgnoreStart Copyright me Ignored text sdojfsdREUSE-IgnoreEnd Other relevant text """ ) expected = cleandoc( """ Relevant text Other relevant text """ ) result = _util.filter_ignore_block(text) assert result == expected def test_filter_ignore_block_with_relevant_information_on_same_line(): """Test that the ignore block is properly removed if it has relevant information on the same line. """ text = cleandoc( """ Relevant textREUSE-IgnoreStart Ignored text REUSE-IgnoreEndOther relevant text """ ) expected = "Relevant textOther relevant text" result = _util.filter_ignore_block(text) assert result == expected def test_filter_ignore_block_with_beginning_and_end_on_same_line_correct_order(): # pylint: disable=line-too-long """Test that the ignore block is properly removed if it has relevant information on the same line. """ text = cleandoc( """ Relevant textREUSE-IgnoreStartIgnored textREUSE-IgnoreEndOther relevant text """ ) expected = cleandoc( """ Relevant textOther relevant text """ ) result = _util.filter_ignore_block(text) assert result == expected def test_filter_ignore_block_with_beginning_and_end_on_same_line_wrong_order(): """Test that the ignore block is properly removed if it has relevant information on the same line. """ text = "Relevant textREUSE-IgnoreEndOther relevant textREUSE-IgnoreStartIgnored text" # pylint: disable=line-too-long expected = "Relevant textREUSE-IgnoreEndOther relevant text" result = _util.filter_ignore_block(text) assert result == expected def test_filter_ignore_block_without_end(): """Test that the ignore block is properly removed if it has relevant information on the same line. """ text = cleandoc( """ Relevant text REUSE-IgnoreStart Ignored text Other ignored text """ ) expected = "Relevant text\n" result = _util.filter_ignore_block(text) assert result == expected def test_filter_ignore_block_with_multiple_ignore_blocks(): """Test that the ignore block is properly removed if it has relevant information on the same line. """ text = cleandoc( """ Relevant text REUSE-IgnoreStart Ignored text REUSE-IgnoreEnd Other relevant text REUSE-IgnoreStart Other ignored text REUSE-IgnoreEnd Even more relevant text """ ) expected = cleandoc( """ Relevant text Other relevant text Even more relevant text """ ) result = _util.filter_ignore_block(text) assert result == expected def test_make_copyright_line_simple(): """Given a simple statement, make it a copyright line.""" assert _util.make_copyright_line("hello") == "SPDX-FileCopyrightText: hello" def test_make_copyright_line_year(): """Given a simple statement and a year, make it a copyright line.""" assert ( _util.make_copyright_line("hello", year="2019") == "SPDX-FileCopyrightText: 2019 hello" ) def test_make_copyright_line_prefix_spdx(): """Given a simple statement and prefix, make it a copyright line.""" statement = _util.make_copyright_line("hello", copyright_prefix="spdx") assert statement == "SPDX-FileCopyrightText: hello" def test_make_copyright_line_prefix_spdx_year(): """Given a simple statement, prefix and a year, make it a copyright line.""" statement = _util.make_copyright_line( "hello", year=2019, copyright_prefix="spdx" ) assert statement == "SPDX-FileCopyrightText: 2019 hello" def test_make_copyright_line_prefix_spdx_c_year(): """Given a simple statement, prefix and a year, make it a copyright line.""" statement = _util.make_copyright_line( "hello", year=2019, copyright_prefix="spdx-c" ) assert statement == "SPDX-FileCopyrightText: (C) 2019 hello" def test_make_copyright_line_prefix_spdx_symbol_year(): """Given a simple statement, prefix and a year, make it a copyright line.""" statement = _util.make_copyright_line( "hello", year=2019, copyright_prefix="spdx-symbol" ) assert statement == "SPDX-FileCopyrightText: © 2019 hello" def test_make_copyright_line_prefix_string_year(): """Given a simple statement, prefix and a year, make it a copyright line.""" statement = _util.make_copyright_line( "hello", year=2019, copyright_prefix="string" ) assert statement == "Copyright 2019 hello" def test_make_copyright_line_prefix_string_c_year(): """Given a simple statement, prefix and a year, make it a copyright line.""" statement = _util.make_copyright_line( "hello", year=2019, copyright_prefix="string-c" ) assert statement == "Copyright (C) 2019 hello" def test_make_copyright_line_prefix_string_symbol_year(): """Given a simple statement, prefix and a year, make it a copyright line.""" statement = _util.make_copyright_line( "hello", year=2019, copyright_prefix="string-symbol" ) assert statement == "Copyright © 2019 hello" def test_make_copyright_line_prefix_symbol_year(): """Given a simple statement, prefix and a year, make it a copyright line.""" statement = _util.make_copyright_line( "hello", year=2019, copyright_prefix="symbol" ) assert statement == "© 2019 hello" def test_make_copyright_line_existing_spdx_copyright(): """Given a copyright line, do nothing.""" value = "SPDX-FileCopyrightText: hello" assert _util.make_copyright_line(value) == value def test_make_copyright_line_existing_other_copyright(): """Given a non-SPDX copyright line, do nothing.""" value = "© hello" assert _util.make_copyright_line(value) == value def test_make_copyright_line_multine_error(): """Given a multiline argument, expect an error.""" with pytest.raises(RuntimeError): _util.make_copyright_line("hello\nworld") # pylint: disable=unused-argument def test_pathtype_read_simple(fake_repository): """Get a Path to a readable file.""" result = _util.PathType("r")("src/source_code.py") assert result == Path("src/source_code.py") def test_pathtype_read_directory(fake_repository): """Get a Path to a readable directory.""" result = _util.PathType("r")("src") assert result == Path("src") def test_pathtype_read_directory_force_file(fake_repository): """Cannot read a directory when a file is forced.""" with pytest.raises(ArgumentTypeError): _util.PathType("r", force_file=True)("src") @no_root @posix def test_pathtype_read_not_readable(fake_repository): """Cannot read a nonreadable file.""" try: os.chmod("src/source_code.py", 0o000) with pytest.raises(ArgumentTypeError): _util.PathType("r")("src/source_code.py") finally: os.chmod("src/source_code.py", 0o777) def test_pathtype_read_not_exists(empty_directory): """Cannot read a file that does not exist.""" with pytest.raises(ArgumentTypeError): _util.PathType("r")("foo.py") def test_pathtype_read_write_not_exists(empty_directory): """Cannot read/write a file that does not exist.""" with pytest.raises(ArgumentTypeError): _util.PathType("r+")("foo.py") @no_root @posix def test_pathtype_read_write_only_write(empty_directory): """A write-only file loaded with read/write needs both permissions.""" path = Path("foo.py") path.touch() try: path.chmod(0o222) with pytest.raises(ArgumentTypeError): _util.PathType("r+")("foo.py") finally: path.chmod(0o777) @no_root @posix def test_pathtype_read_write_only_read(empty_directory): """A read-only file loaded with read/write needs both permissions.""" path = Path("foo.py") path.touch() try: path.chmod(0o444) with pytest.raises(ArgumentTypeError): _util.PathType("r+")("foo.py") finally: path.chmod(0o777) def test_pathtype_write_not_exists(empty_directory): """Get a Path for a file that does not exist.""" result = _util.PathType("w")("foo.py") assert result == Path("foo.py") def test_pathtype_write_exists(fake_repository): """Get a Path for a file that exists.""" result = _util.PathType("w")("src/source_code.py") assert result == Path("src/source_code.py") def test_pathtype_write_directory(fake_repository): """Cannot write to directory.""" with pytest.raises(ArgumentTypeError): _util.PathType("w")("src") @no_root @posix def test_pathtype_write_exists_but_not_writeable(fake_repository): """Cannot get Path of file that exists but isn't writeable.""" os.chmod("src/source_code.py", 0o000) with pytest.raises(ArgumentTypeError): _util.PathType("w")("src/source_code.py") os.chmod("src/source_code.py", 0o777) @no_root @posix def test_pathtype_write_not_exist_but_directory_not_writeable(fake_repository): """Cannot get Path of file that does not exist but directory isn't writeable. """ os.chmod("src", 0o000) with pytest.raises(ArgumentTypeError): _util.PathType("w")("src/foo.py") os.chmod("src", 0o777) def test_pathtype_invalid_mode(empty_directory): """Only valid modes are 'r' and 'w'.""" with pytest.raises(ValueError): _util.PathType("o") def test_decoded_text_from_binary_simple(): """A unicode string encoded as bytes object decodes back correctly.""" text = "Hello, world ☺" encoded = text.encode("utf-8") assert _util.decoded_text_from_binary(BytesIO(encoded)) == text def test_decoded_text_from_binary_size(): """Only a given amount of bytes is decoded.""" text = "Hello, world ☺" encoded = text.encode("utf-8") assert _util.decoded_text_from_binary(BytesIO(encoded), size=5) == "Hello" def test_decoded_text_from_binary_crlf(): """Given CRLF line endings, convert to LF.""" text = "Hello\r\nworld" encoded = text.encode("utf-8") assert _util.decoded_text_from_binary(BytesIO(encoded)) == "Hello\nworld" def test_similar_spdx_identifiers_typo(): """Given a misspelt SPDX License Identifier, suggest a better one.""" result = _util.similar_spdx_identifiers("GPL-3.0-or-lter") assert "GPL-3.0-or-later" in result assert "AGPL-3.0-or-later" in result assert "LGPL-3.0-or-later" in result def test_similar_spdx_identifiers_prefix(): """Given an incomplete SPDX License Identifier, suggest a better one.""" result = _util.similar_spdx_identifiers("CC0") assert "CC0-1.0" in result def test_detect_line_endings_windows(): """Given a CRLF string, detect the line endings.""" assert _util.detect_line_endings("hello\r\nworld") == "\r\n" def test_detect_line_endings_mac(): """Given a CR string, detect the line endings.""" assert _util.detect_line_endings("hello\rworld") == "\r" def test_detect_line_endings_linux(): """Given a LF string, detect the line endings.""" assert _util.detect_line_endings("hello\nworld") == "\n" def test_detect_line_endings_no_newlines(): """Given a file without line endings, default to os.linesep.""" assert _util.detect_line_endings("hello world") == os.linesep # REUSE-IgnoreEnd reuse-tool-4.0.3/tests/test_vcs.py000066400000000000000000000022311464275211500171670ustar00rootroot00000000000000# SPDX-FileCopyrightText: 2017 Free Software Foundation Europe e.V. # SPDX-FileCopyrightText: © 2020 Liferay, Inc. # SPDX-FileCopyrightText: 2022 Florian Snow # # SPDX-License-Identifier: GPL-3.0-or-later """Tests for reuse.vcs""" import os from pathlib import Path from reuse import vcs def test_find_root_in_git_repo(git_repository): """When using reuse from a child directory in a Git repo, always find the root directory. """ os.chdir("src") result = vcs.find_root() assert Path(result).absolute().resolve() == git_repository def test_find_root_in_hg_repo(hg_repository): """When using reuse from a child directory in a Mercurial repo, always find the root directory. """ os.chdir("src") result = vcs.find_root() assert Path(result).absolute().resolve() == hg_repository def test_find_root_in_pijul_repo(pijul_repository): """When using reuse from a child directory in a Pijul repo, always find the root directory. """ os.chdir("src") result = vcs.find_root() assert Path(result).absolute().resolve() == pijul_repository