reuse-tool-6.2.0/0000775000175000017500000000000015077707000012266 5ustar alexalexreuse-tool-6.2.0/Dockerfile0000664000175000017500000000171015077707000014257 0ustar alexalex# 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.22 AS base RUN apk --no-cache add git mercurial python3 openssh-client libmagic # 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 --all-extras 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-6.2.0/Dockerfile-debian0000664000175000017500000000220015077707000015472 0ustar alexalex# 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:13-slim AS base RUN apt-get update \ && apt-get -y upgrade \ && apt-get -y --no-install-recommends install git mercurial python3 libmagic1 \ && 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 --all-extras 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-6.2.0/tests/0000775000175000017500000000000015077707000013430 5ustar alexalexreuse-tool-6.2.0/tests/test_lint.py0000664000175000017500000003134615077707000016016 0ustar alexalex# SPDX-FileCopyrightText: 2022 Florian Snow # SPDX-FileCopyrightText: 2024 Nico Rikken # SPDX-FileCopyrightText: 2024 Sebastien Morais # SPDX-FileCopyrightText: 2025 Free Software Foundation Europe e.V. # # SPDX-License-Identifier: GPL-3.0-or-later """All tests for reuse.lint.""" import shutil from inspect import cleandoc from pathlib import PurePath from conftest import cpython, posix from reuse._util import cleandoc_nl 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 / "LICENSES/foo.txt").write_text("Hello, world!") project = Project.from_directory(fake_repository) report = ProjectReport.generate(project) result = format_plain(report) assert ":-(" in result assert "# BAD LICENSES" in result assert "foo.txt" 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_invalid_spdx_expressions(fake_repository): """An invalid expression is detected.""" (fake_repository / "foo.py").write_text( cleandoc( """ Copyright Jane Doe SPDX-License-Identifier: MIT OR SPDX-License-Identifier: Apache-2.0 AND SPDX-License-Identifier: 0BSD """ ) ) project = Project.from_directory(fake_repository) report = ProjectReport.generate(project) result = format_plain(report) assert ":-(" in result assert "# INVALID SPDX LICENSE EXPRESSIONS" in result assert "foo.py' contains invalid SPDX License Expressions:" in result assert "Invalid SPDX License Expressions: 2" in result assert "Fix invalid SPDX License Expressions:" 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"] == "foo.py": assert test_file["spdx_expressions"][0]["value"] == "MIT" assert test_file["spdx_expressions"][0]["source"] == "foo.py" assert test_file["spdx_expressions"][0]["is_valid"] if test_file["path"] == "doc/usage.md": assert test_file["spdx_expressions"][0]["value"] == "CC0-1.0" assert test_file["spdx_expressions"][0]["source"] == "doc/usage.md" assert test_file["spdx_expressions"][0]["is_valid"] class TestFormatLines: """Tests for format_lines and format_lines_subset.""" def test_missing_licenses(self, empty_directory, format_lines_func): """List missing licenses.""" (empty_directory / "foo.py").write_text( cleandoc( """ Copyright Jane Doe SPDX-License-Identifier: MIT OR 0BSD """ ) ) project = Project.from_directory(".") report = ProjectReport.generate(project) result = format_lines_func(report) assert result == cleandoc_nl( """ foo.py: missing license '0BSD' foo.py: missing license 'MIT' """ ) @cpython @posix def test_read_errors(self, fake_repository, format_lines_func): """Check read error output""" (fake_repository / "restricted.py").write_text("foo") (fake_repository / "restricted.py").chmod(0o000) project = Project.from_directory(".") report = ProjectReport.generate(project) result = format_lines_func(report) assert result == "restricted.py: read error\n" def test_invalid_spdx_expressions(self, empty_directory, format_lines_func): """List invalid SPDX License Expressions.""" (empty_directory / "foo.py").write_text( cleandoc( """ Copyright Jane Doe SPDX-License-Identifier: MIT OR SPDX-License-Identifier: <> """ ) ) (empty_directory / "bar.py").write_text( cleandoc( """ Copyright John Doe SPDX-License-Identifier: MIT OR """ ) ) project = Project.from_directory(".") report = ProjectReport.generate(project) result = format_lines_func(report) assert result == cleandoc_nl( """ bar.py: invalid SPDX License Expression 'MIT OR' bar.py: no license identifier foo.py: invalid SPDX License Expression '<>' foo.py: invalid SPDX License Expression 'MIT OR' foo.py: no license identifier """ ) def test_no_copyright_or_licensing( self, empty_directory, format_lines_func ): """List files without copyright or licensing.""" (empty_directory / "no_lic.py").write_text("Copyright Jane Doe") (empty_directory / "no_copy.py").write_text( "SPDX-License-Identifier: MIT" ) (empty_directory / "none.py").write_text("Hello, world!") project = Project.from_directory(".") report = ProjectReport.generate(project) result = format_lines_func(report) assert result == cleandoc_nl( """ no_copy.py: missing license 'MIT' no_copy.py: no copyright notice no_lic.py: no license identifier none.py: no license identifier none.py: no copyright notice """ ) def test_bad_license(self, empty_directory): """List bad licenses.""" (empty_directory / "LICENSES").mkdir() (empty_directory / "LICENSES/bad.txt").write_text("Hello, world!") project = Project.from_directory(".") report = ProjectReport.generate(project) result = format_lines(report) path = PurePath("LICENSES/bad.txt") assert result == cleandoc_nl( f""" {path}: bad license 'bad' {path}: unused license """ ) def test_deprecated_license(self, empty_directory): """List deprecated licenses.""" (empty_directory / "LICENSES").mkdir() (empty_directory / "LICENSES/GPL-3.0.txt").write_text("Hello, world!") project = Project.from_directory(".") report = ProjectReport.generate(project) result = format_lines(report) path = PurePath("LICENSES/GPL-3.0.txt") assert result == cleandoc_nl( f""" {path}: deprecated license {path}: unused license """ ) def test_licenses_without_extension(self, empty_directory): """List licenses without extension.""" (empty_directory / "LICENSES").mkdir() (empty_directory / "LICENSES/MIT").write_text("Hello, world!") project = Project.from_directory(".") report = ProjectReport.generate(project) result = format_lines(report) path = PurePath("LICENSES/MIT") assert result == cleandoc_nl( f""" {path}: license without file extension {path}: unused license """ ) # REUSE-IgnoreEnd reuse-tool-6.2.0/tests/test_cli_annotate.py0000664000175000017500000015774015077707000017517 0ustar alexalex# 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 annotate.""" import datetime import os import stat from inspect import cleandoc from pathlib import PurePath from unittest.mock import create_autospec import pytest from click.testing import CliRunner from reuse.cli.main import main from reuse.copyright import CopyrightPrefix # pylint: disable=too-many-public-methods,too-many-lines,unused-argument # REUSE-IgnoreStart class TestAnnotate: """Tests for annotate.""" # TODO: Replace this test with a monkeypatched test def test_simple(self, fake_repository, 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 = CliRunner().invoke( main, [ "annotate", "--license", "GPL-3.0-or-later", "--copyright", "Jane Doe", "foo.py", ], ) assert result.exit_code == 0 assert simple_file.read_text() == expected def test_simple_scheme(self, fake_repository, mock_date_today): "Add a header to a Scheme file." simple_file = fake_repository / "foo.scm" simple_file.write_text("(setq show-trailing-whitespace t)") expected = cleandoc( """ ;;; SPDX-FileCopyrightText: 2018 Jane Doe ;;; ;;; SPDX-License-Identifier: GPL-3.0-or-later (setq show-trailing-whitespace t) """ ) result = CliRunner().invoke( main, [ "annotate", "--license", "GPL-3.0-or-later", "--copyright", "Jane Doe", "foo.scm", ], ) assert result.exit_code == 0 assert simple_file.read_text() == expected def test_scheme_standardised(self, fake_repository, 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 = CliRunner().invoke( main, [ "annotate", "--license", "GPL-3.0-or-later", "--copyright", "Jane Doe", "foo.scm", ], ) assert result.exit_code == 0 assert simple_file.read_text() == expected def test_scheme_standardised2(self, fake_repository, 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 = CliRunner().invoke( main, [ "annotate", "--license", "GPL-3.0-or-later", "--copyright", "Jane Doe", "foo.scm", ], ) assert result.exit_code == 0 assert simple_file.read_text() == expected def test_directory_argument(self, fake_repository): """Directory arguments are ignored.""" result = CliRunner().invoke( main, ["annotate", "--copyright", "Jane Doe", "src"] ) assert result.exit_code == 0 assert result.output == "" assert (fake_repository / "src").is_dir() def test_simple_no_replace(self, fake_repository, 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 = CliRunner().invoke( main, [ "annotate", "--no-replace", "--license", "GPL-3.0-or-later", "--copyright", "Jane Doe", "foo.py", ], ) assert result.exit_code == 0 assert simple_file.read_text() == expected def test_year(self, fake_repository): """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 = CliRunner().invoke( main, [ "annotate", "--year", "2016", "--license", "GPL-3.0-or-later", "--copyright", "Jane Doe", "foo.py", ], ) assert result.exit_code == 0 assert simple_file.read_text() == expected def test_no_year(self, fake_repository): """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 = CliRunner().invoke( main, [ "annotate", "--exclude-year", "--license", "GPL-3.0-or-later", "--copyright", "Jane Doe", "foo.py", ], ) assert result.exit_code == 0 assert simple_file.read_text() == expected @pytest.mark.parametrize( "copyright_prefix", ["--copyright-prefix", "--copyright-style"] ) def test_copyright_prefix( self, fake_repository, copyright_prefix, 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 = CliRunner().invoke( main, [ "annotate", "--license", "GPL-3.0-or-later", "--copyright", "Jane Doe", copyright_prefix, "string", "foo.py", ], ) assert result.exit_code == 0 assert simple_file.read_text() == expected def test_shebang(self, fake_repository): """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 = CliRunner().invoke( main, [ "annotate", "--license", "GPL-3.0-or-later", "foo.py", ], ) assert result.exit_code == 0 assert simple_file.read_text() == expected def test_shebang_wrong_comment_style(self, fake_repository): """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 = CliRunner().invoke( main, [ "annotate", "--license", "GPL-3.0-or-later", "foo.html", ], ) assert result.exit_code == 0 assert simple_file.read_text() == expected def test_markdown(self, fake_repository): """Markdown uses the HTML comment style.""" simple_file = fake_repository / "foo.md" simple_file.write_text( cleandoc( """ # Heading """ ) ) expected = cleandoc( """ # Heading """ ) result = CliRunner().invoke( main, [ "annotate", "--license", "MIT", "foo.md", ], ) assert result.exit_code == 0 assert simple_file.read_text() == expected def test_frontmatter(self, fake_repository): """Keep the frontmatter when annotating.""" simple_file = fake_repository / "foo.md" simple_file.write_text( cleandoc( """ --- description: test --- # Heading """ ) ) expected = cleandoc( """ --- # SPDX-License-Identifier: MIT description: test --- # Heading """ ) result = CliRunner().invoke( main, [ "annotate", "--license", "MIT", "foo.md", ], ) assert result.exit_code == 0 assert simple_file.read_text() == expected def test_frontmatter_wrong_comment_style(self, fake_repository): """If a comment style does not support the frontmatter header at the top, don't treat the shebang as special. """ simple_file = fake_repository / "foo.sh" simple_file.write_text( cleandoc( """ --- description: test --- # Heading """ ) ) expected = cleandoc( """ # SPDX-License-Identifier: MIT --- description: test --- # Heading """ ) result = CliRunner().invoke( main, [ "annotate", "--license", "MIT", "foo.sh", ], ) assert result.exit_code == 0 assert simple_file.read_text() == expected def test_contributors_only( self, fake_repository, 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 = CliRunner().invoke( main, args, ) assert result.exit_code == 0 assert simple_file.read_text() == expected def test_contributors(self, fake_repository, 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 = CliRunner().invoke( main, args, ) assert result.exit_code == 0 assert simple_file.read_text() == expected def test_specify_style(self, fake_repository, mock_date_today): """Add 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 = CliRunner().invoke( main, [ "annotate", "--license", "GPL-3.0-or-later", "--copyright", "Jane Doe", "--style", "cpp", "foo.py", ], ) assert result.exit_code == 0 assert simple_file.read_text() == expected def test_specify_style_unrecognised(self, fake_repository, 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 = CliRunner().invoke( main, [ "annotate", "--copyright", "Jane Doe", "--style", "python", "hello.foo", ], ) assert result.exit_code == 0 assert simple_file.read_text().strip() == expected def test_implicit_style(self, fake_repository, 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 = CliRunner().invoke( main, [ "annotate", "--license", "GPL-3.0-or-later", "--copyright", "Jane Doe", "foo.js", ], ) assert result.exit_code == 0 assert simple_file.read_text() == expected def test_implicit_style_filename(self, fake_repository, 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 = CliRunner().invoke( main, [ "annotate", "--license", "GPL-3.0-or-later", "--copyright", "Jane Doe", "Makefile", ], ) assert result.exit_code == 0 assert simple_file.read_text() == expected def test_unrecognised_style(self, fake_repository): """Add a header to a file that has an unrecognised extension.""" simple_file = fake_repository / "foo.foo" simple_file.write_text("pass") result = CliRunner().invoke( main, [ "annotate", "--license", "GPL-3.0-or-later", "--copyright", "Jane Doe", "foo.foo", ], ) assert result.exit_code != 0 assert ( "The following files do not have a recognised file extension" in result.output ) assert "foo.foo" in result.output @pytest.mark.parametrize( "skip_unrecognised", ["--skip-unrecognised", "--skip-unrecognized"] ) def test_skip_unrecognised(self, fake_repository, skip_unrecognised): """Skip file that has an unrecognised extension.""" simple_file = fake_repository / "foo.foo" simple_file.write_text("pass") result = CliRunner().invoke( main, [ "annotate", "--license", "GPL-3.0-or-later", "--copyright", "Jane Doe", skip_unrecognised, "foo.foo", ], ) assert result.exit_code == 0 assert "Skipped unrecognised file 'foo.foo'" in result.output @pytest.mark.parametrize( "skip_unrecognised", ["--skip-unrecognised", "--skip-unrecognized"] ) def test_skip_unrecognised_and_style_mutex( self, fake_repository, skip_unrecognised ): """--skip-unrecognised and --style are mutually exclusive.""" simple_file = fake_repository / "foo.foo" simple_file.write_text("pass") result = CliRunner().invoke( main, [ "annotate", "--license", "GPL-3.0-or-later", "--copyright", "Jane Doe", "--style=c", skip_unrecognised, "foo.foo", ], ) assert result.exit_code != 0 assert "mutually exclusive with" in result.output def test_no_data_to_add(self, fake_repository): """Add a header, but supply no copyright, license, or contributor.""" simple_file = fake_repository / "foo.py" simple_file.write_text("pass") result = CliRunner().invoke(main, ["annotate", "foo.py"]) assert result.exit_code != 0 assert ( "Option '--copyright', '--license', or '--contributor' is required" in result.output ) def test_template_simple( self, fake_repository, 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 = CliRunner().invoke( main, [ "annotate", "--license", "GPL-3.0-or-later", "--copyright", "Jane Doe", "--template", "mytemplate.jinja2", "foo.py", ], ) assert result.exit_code == 0 assert simple_file.read_text() == expected def test_template_simple_multiple( self, fake_repository, 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 = CliRunner().invoke( main, [ "annotate", "--license", "GPL-3.0-or-later", "--copyright", "Jane Doe", "--template", "mytemplate.jinja2", ] + list(map(str, simple_files)), ) assert result.exit_code == 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_template_no_spdx(self, fake_repository, 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 = CliRunner().invoke( main, [ "annotate", "--license", "GPL-3.0-or-later", "--copyright", "Jane Doe", "--template", "mytemplate.jinja2", "foo.py", ], ) assert result.exit_code == 1 def test_template_commented( self, fake_repository, 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 = CliRunner().invoke( main, [ "annotate", "--license", "GPL-3.0-or-later", "--copyright", "Jane Doe", "--template", "mytemplate.commented.jinja2", "foo.c", ], ) assert result.exit_code == 0 assert simple_file.read_text() == expected def test_template_nonexistant(self, fake_repository): """Raise an error when using a header that does not exist.""" simple_file = fake_repository / "foo.py" simple_file.write_text("pass") result = CliRunner().invoke( main, [ "annotate", "--license", "GPL-3.0-or-later", "--copyright", "Jane Doe", "--template", "mytemplate.jinja2", "foo.py", ], ) assert result.exit_code != 0 assert ( "Template 'mytemplate.jinja2' could not be found" in result.output ) def test_template_without_extension( self, fake_repository, 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 = CliRunner().invoke( main, [ "annotate", "--license", "GPL-3.0-or-later", "--copyright", "Jane Doe", "--template", "mytemplate", "foo.py", ], ) assert result.exit_code == 0 assert simple_file.read_text() == expected def test_binary(self, fake_repository, 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 = CliRunner().invoke( main, [ "annotate", "--license", "GPL-3.0-or-later", "--copyright", "Jane Doe", "foo.png", ], ) assert result.exit_code == 0 assert ( binary_file.with_name(f"{binary_file.name}.license") .read_text() .strip() == expected ) def test_uncommentable_json(self, fake_repository, 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 = CliRunner().invoke( main, [ "annotate", "--license", "GPL-3.0-or-later", "--copyright", "Jane Doe", "foo.json", ], ) assert result.exit_code == 0 assert ( json_file.with_name(f"{json_file.name}.license").read_text().strip() == expected ) def test_fallback_dot_license(self, fake_repository, 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 = CliRunner().invoke( main, [ "annotate", "--license", "GPL-3.0-or-later", "--copyright", "Jane Doe", "--fallback-dot-license", "foo.py", "foo.foo", ], ) assert result.exit_code == 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 result.output ) def test_force_dot_license(self, fake_repository, 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 = CliRunner().invoke( main, [ "annotate", "--license", "GPL-3.0-or-later", "--copyright", "Jane Doe", "--force-dot-license", "foo.py", ], ) assert result.exit_code == 0 assert ( simple_file.with_name(f"{simple_file.name}.license") .read_text() .strip() == expected ) assert simple_file.read_text() == "pass" def test_force_dot_license_double(self, fake_repository, mock_date_today): """If 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 = CliRunner().invoke( main, [ "annotate", "--license", "GPL-3.0-or-later", "--copyright", "Jane Doe", "--force-dot-license", "foo.txt", ], ) assert result.exit_code == 0 assert not simple_file_license_license.exists() assert simple_file_license.read_text().strip() == expected def test_force_dot_license_unsupported_filetype( self, fake_repository, 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 = CliRunner().invoke( main, [ "annotate", "--license", "GPL-3.0-or-later", "--copyright", "Jane Doe", "--force-dot-license", "foo.txt", ], ) assert result.exit_code == 0 assert ( simple_file.with_name(f"{simple_file.name}.license") .read_text() .strip() == expected ) assert simple_file.read_text() == "Preserve this" def test_to_read_only_file_forbidden( self, fake_repository, mock_date_today ): """Cannot add a header without having write permission.""" _file = fake_repository / "test.sh" _file.write_text("#!/bin/sh") _file.chmod(mode=stat.S_IREAD) result = CliRunner().invoke( main, [ "annotate", "--license", "Apache-2.0", "--copyright", "mycorp", "--style", "python", "test.sh", ], ) assert result.exit_code != 0 assert "'test.sh' is not writable." in result.output def test_license_file(self, fake_repository, 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 = CliRunner().invoke( main, [ "annotate", "--license", "GPL-3.0-or-later", "--copyright", "Jane Doe", "foo.py", ], ) assert result.exit_code == 0 assert license_file.read_text() == expected assert simple_file.read_text() == "foo" def test_license_file_only_one_newline( self, fake_repository, 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 = CliRunner().invoke( main, [ "annotate", "--license", "GPL-3.0-or-later", "--copyright", "Jane Doe", "foo.py", ], ) assert result.exit_code == 0 assert license_file.read_text() == expected assert simple_file.read_text() == "foo" def test_year_mutually_exclusive(self, fake_repository): """--exclude-year and --year are mutually exclusive.""" result = CliRunner().invoke( main, [ "annotate", "--license", "GPL-3.0-or-later", "--copyright", "Jane Doe", "--exclude-year", "--year", "2020", "src/source_code.py", ], ) assert result.exit_code != 0 assert "is mutually exclusive with" in result.output def test_single_multi_line_mutually_exclusive(self, fake_repository): """--single-line and --multi-line are mutually exclusive.""" result = CliRunner().invoke( main, [ "annotate", "--license", "GPL-3.0-or-later", "--copyright", "Jane Doe", "--single-line", "--multi-line", "src/source_code.c", ], ) assert result.exit_code != 0 assert "is mutually exclusive with" in result.output def test_skip_force_mutually_exclusive(self, fake_repository): """--skip-unrecognised and --force-dot-license are mutually exclusive""" result = CliRunner().invoke( main, [ "annotate", "--license", "GPL-3.0-or-later", "--copyright", "Jane Doe", "--force-dot-license", "--skip-unrecognised", "src/source_code.py", ], ) assert result.exit_code != 0 assert "is mutually exclusive with" in result.output def test_multi_line_not_supported(self, fake_repository): """Expect a fail if --multi-line is not supported for a file type.""" result = CliRunner().invoke( main, [ "annotate", "--license", "GPL-3.0-or-later", "--copyright", "Jane Doe", "--multi-line", "src/source_code.py", ], ) assert result.exit_code != 0 assert ( "'src/source_code.py' does not support multi-line comments" in result.output ) def test_multi_line_not_supported_custom_style(self, fake_repository): """--multi-line also fails when used with a style that doesn't support it through --style. """ (fake_repository / "foo.foo").write_text("foo") result = CliRunner().invoke( main, [ "annotate", "--license", "GPL-3.0-or-later", "--copyright", "Jane Doe", "--multi-line", "--force-dot-license", "--style", "python", "foo.foo", ], ) assert result.exit_code != 0 assert "'foo.foo' does not support multi-line" in result.output def test_single_line_not_supported(self, fake_repository): """Expect a fail if --single-line is not supported for a file type.""" result = CliRunner().invoke( main, [ "annotate", "--license", "GPL-3.0-or-later", "--copyright", "Jane Doe", "--single-line", "src/source_code.html", ], ) assert result.exit_code != 0 assert ( "'src/source_code.html' does not support single-line comments" in result.output ) def test_force_multi_line_for_c(self, fake_repository, 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 = CliRunner().invoke( main, [ "annotate", "--license", "GPL-3.0-or-later", "--copyright", "Jane Doe", "--multi-line", "foo.c", ], ) assert result.exit_code == 0 assert simple_file.read_text() == expected @pytest.mark.parametrize("line_ending", ["\r\n", "\r", "\n"]) def test_line_endings(self, empty_directory, 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 = CliRunner().invoke( main, [ "annotate", "--license", "GPL-3.0-or-later", "--copyright", "Jane Doe", "foo.py", ], ) assert result.exit_code == 0 with open(simple_file, newline=line_ending, encoding="utf-8") as fp: contents = fp.read() assert contents == expected def test_skip_existing(self, fake_repository, 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 """ ) CliRunner().invoke( main, [ "annotate", "--license", "GPL-3.0-or-later", "--copyright", "Jane Doe", "foo.py", ], ) result = CliRunner().invoke( main, [ "annotate", "--license", "MIT", "--copyright", "John Doe", "--skip-existing", "foo.py", "bar.py", ], ) assert result.exit_code == 0 assert (fake_repository / "foo.py").read_text() == expected_foo assert (fake_repository / "bar.py").read_text() == expected_bar def test_recursive(self, fake_repository, 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 = CliRunner().invoke( main, [ "annotate", "--copyright", "Joe Somebody", "--recursive", "src/", ], ) 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.exit_code == 0 def test_recursive_on_file(self, fake_repository, mock_date_today): """Don't expect errors when annotate is run 'recursively' on a file.""" result = CliRunner().invoke( main, [ "annotate", "--copyright", "Joe Somebody", "--recursive", "src/source_code.py", ], ) assert ( "Joe Somebody" in (fake_repository / "src/source_code.py").read_text() ) assert result.exit_code == 0 def test_exit_if_unrecognised(self, fake_repository, 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") result = CliRunner().invoke( main, [ "annotate", "--license", "Apache-2.0", "--copyright", "Jane Doe", "--recursive", "baz/", ], ) assert result.exit_code != 0 assert ( "The following files do not have a recognised file extension" in result.output ) assert str(PurePath("baz/bar.unknown")) in result.output assert "foo.py" not in result.output assert "Jane Doe" not in (fake_repository / "baz/foo.py").read_text() @pytest.mark.parametrize( "year", ( "abcd", "123", "12345", "1234 until 5678", ), ) def test_wrong_year(self, empty_directory, year): """If inputting a wrong value for --year, expect an error.""" (empty_directory / "foo.py").touch() result = CliRunner().invoke( main, [ "annotate", "--copyright", "Jane Doe", "--year", year, "foo.py", ], ) assert result.exit_code != 0 assert f"'{year}' is not a valid year range." in result.output @pytest.mark.parametrize( "year", ( 1, 12, 123, # Five-digit values are not supported by datetime. ), ) def test_wrong_current_year(self, empty_directory, monkeypatch, year): """In the rare event that the current year is not four digits, expect an error. """ date = create_autospec(datetime.date) date.today.return_value = datetime.date(year, 1, 1) monkeypatch.setattr(datetime, "date", date) (empty_directory / "foo.py").touch() result = CliRunner().invoke( main, [ "annotate", "--copyright", "Jane Doe", "foo.py", ], ) assert result.exit_code != 0 assert ( f"Your operating system's year is set to '{year}'." in result.output ) @pytest.mark.parametrize("encoding", ["utf_8_sig", "utf_16", "utf_32"]) def test_utf_bom(self, empty_directory, mock_date_today, encoding): """If a file uses Unicode encoding with a BOM, preserve the BOM after annotating the file. """ (empty_directory / "foo.py").write_bytes("pass".encode(encoding)) CliRunner().invoke( main, [ "annotate", "--copyright", "Jane Doe", "foo.py", ], ) assert ( (empty_directory / "foo.py").read_bytes() == cleandoc( """ # SPDX-FileCopyrightText: 2018 Jane Doe pass """ ) .replace("\n", os.linesep) .encode(encoding) ) class TestAnnotateMerge: """Test merging copyright statements.""" def test_simple(self, fake_repository): """Add multiple headers to a file with merge copyrights.""" simple_file = fake_repository / "foo.py" simple_file.write_text("pass") result = CliRunner().invoke( main, [ "annotate", "--year", "2016", "--license", "GPL-3.0-or-later", "--copyright", "Mary Sue", "--merge-copyrights", "foo.py", ], ) assert result.exit_code == 0 assert simple_file.read_text() == cleandoc( """ # SPDX-FileCopyrightText: 2016 Mary Sue # # SPDX-License-Identifier: GPL-3.0-or-later pass """ ) result = CliRunner().invoke( main, [ "annotate", "--year", "2018", "--copyright", "Mary Sue", "--merge-copyrights", "foo.py", ], ) assert result.exit_code == 0 assert simple_file.read_text() == cleandoc( """ # SPDX-FileCopyrightText: 2016, 2018 Mary Sue # # SPDX-License-Identifier: GPL-3.0-or-later pass """ ) result = CliRunner().invoke( main, [ "annotate", "--year", "2017", "--copyright", "Mary Sue", "--merge-copyrights", "foo.py", ], ) assert result.exit_code == 0 assert simple_file.read_text() == cleandoc( """ # SPDX-FileCopyrightText: 2016-2018 Mary Sue # # SPDX-License-Identifier: GPL-3.0-or-later pass """ ) def test_multi_prefix(self, fake_repository): """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 = CliRunner().invoke( main, [ "annotate", "--year", str(2010 + i), "--license", "GPL-3.0-or-later", "--copyright", "Mary Sue", "foo.py", ], ) assert result.exit_code == 0 for i in range(0, 5): result = CliRunner().invoke( main, [ "annotate", "--year", str(2015 + i), "--license", "GPL-3.0-or-later", "--copyright-prefix", "string-c", "--copyright", "Mary Sue", "foo.py", ], ) assert result.exit_code == 0 assert simple_file.read_text() == cleandoc( """ # SPDX-FileCopyrightText: 2010 Mary Sue # SPDX-FileCopyrightText: 2011 Mary Sue # SPDX-FileCopyrightText: 2012 Mary Sue # 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-License-Identifier: GPL-3.0-or-later pass """ ) result = CliRunner().invoke( main, [ "annotate", "--year", "2018", "--license", "GPL-3.0-or-later", "--copyright", "Mary Sue", "--merge-copyrights", "foo.py", ], ) assert result.exit_code == 0 assert simple_file.read_text() == cleandoc( """ # Copyright (C) 2010-2012, 2015-2019 Mary Sue # # SPDX-License-Identifier: GPL-3.0-or-later pass """ ) def test_no_year_in_existing(self, fake_repository, 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 """ ) ) CliRunner().invoke( 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() ) def test_all_prefixes(self, fake_repository, mock_date_today): """Test that merging works for all copyright prefixes.""" # TODO: there should probably also be a test for mixing copyright # prefixes, but this behaviour is really unpredictable to me at the # moment, and the whole copyright-line-as-string thing needs # overhauling. simple_file = fake_repository / "foo.py" for prefix in CopyrightPrefix: simple_file.write_text("pass") result = CliRunner().invoke( main, [ "annotate", "--year", "2016", "--license", "GPL-3.0-or-later", "--copyright", "Jane Doe", "--copyright-style", CopyrightPrefix.lowercase_name(prefix.name), "--merge-copyrights", "foo.py", ], ) assert result.exit_code == 0 assert simple_file.read_text(encoding="utf-8") == cleandoc( f""" # {prefix.value} 2016 Jane Doe # # SPDX-License-Identifier: GPL-3.0-or-later pass """ ) result = CliRunner().invoke( main, [ "annotate", "--year", "2018", "--license", "GPL-3.0-or-later", "--copyright", "Jane Doe", "--copyright-style", CopyrightPrefix.lowercase_name(prefix.name), "--merge-copyrights", "foo.py", ], ) assert result.exit_code == 0 assert simple_file.read_text(encoding="utf-8") == cleandoc( f""" # {prefix.value} 2016, 2018 Jane Doe # # SPDX-License-Identifier: GPL-3.0-or-later pass """ ) # REUSE-IgnoreEnd reuse-tool-6.2.0/tests/test_copyright.py0000664000175000017500000011375315077707000017063 0ustar alexalex# 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.copyright""" import re from typing import cast from unittest import mock import pytest from reuse.copyright import ( _LICENSING, COPYRIGHT_NOTICE_PATTERN, CopyrightNotice, CopyrightPrefix, FourDigitString, ReuseInfo, SourceType, SpdxExpression, YearRange, YearRangeSeparator, ) from reuse.exceptions import CopyrightNoticeParseError, YearRangeParseError # pylint: disable=too-many-lines F = FourDigitString # REUSE-IgnoreStart class TestYearRangeInit: """Tests for YearRange initialisation.""" def test_no_start(self): """It is invalid to have no start year.""" # pylint: disable=no-value-for-parameter with pytest.raises(TypeError): YearRange(end="2017") # type: ignore[call-arg] def test_populate_end_if_separator(self): """If a separator is defined, but end is not defined, set end to an empty string. """ years = YearRange(F("2017"), "-") assert years.end == "" class TestYearRangeFromString: """Tests for YearRange.from_string.""" def test_one_year(self): """The simple case, given a four-digit string.""" years = YearRange.from_string("2017") assert years == YearRange(F("2017")) assert years.original == "2017" @pytest.mark.parametrize( "separator", YearRangeSeparator.__args__, # type: ignore ) def test_full_range(self, separator): """For all available separators, parse a range.""" value = f"2017{separator}2020" years = YearRange.from_string(value) assert years.start == "2017" assert years.separator == separator assert years.end == "2020" assert years.original == value @pytest.mark.parametrize( "separator", YearRangeSeparator.__args__, # type: ignore ) def test_spacing_around_separator(self, separator): """If there is spacing around the separator, ignore that.""" value = f"2017 {separator} 2020" years = YearRange.from_string(value) assert years.start == "2017" assert years.separator == separator assert years.end == "2020" assert years.original == value def test_end_is_word(self): """The end date is a word like 'Present'.""" years = YearRange.from_string("2017--Present") assert years == YearRange(F("2017"), "--", "Present") assert years.original == "2017--Present" def test_start_and_separator(self): """Parse start and separator.""" years = YearRange.from_string("2017--") assert years == YearRange(F("2017"), "--") assert years.original == "2017--" @pytest.mark.parametrize( "text", [ "0", "123", "12345", "12345678", "-", "--", "a 1234", "abcd", "Present-2017", "1234 a", "1234 5678", "123-4", "-1234", "2017- 2019", "2017 -2019", "2017 - ", "2017- ", "2017 -", # This one is tricky. I disallow it because it would otherwise catch # something like: Copyright Jane Doe 2017 - some rights reserved. "2017 - Present", ], ) def test_invalid_ranges(self, text): """Invalid ranges cannot be parsed.""" with pytest.raises(YearRangeParseError): YearRange.from_string(text) # type: ignore[arg-type] class TestYearRangeTupleFromString: """Tests for YearRange.tuple_from_string.""" def test_simple(self): """Try various ways of separating year ranges.""" text = ( "2017, 2018,, 2019 2020 ,2021 , 2022 2023\t2024,,2025 2026--2027" ) result = YearRange.tuple_from_string(text) assert result == tuple( [YearRange(F(str(num))) for num in range(2017, 2026)] + [YearRange(F("2026"), "--", "2027")] ) @pytest.mark.parametrize( "separator", YearRangeSeparator.__args__, # type: ignore ) def test_spacing_around_separator(self, separator): """A year range with a separator surrounded by whitespace is not split into two year ranges. """ result = YearRange.tuple_from_string(f"2017 {separator} 2019") assert result == (YearRange(F("2017"), separator, "2019"),) def test_ambiguous_year_range(self): """Sometimes the spacing around the year range does not make it clear what the intended range is. For extracting from tuples, the spacing must _always_ be on both sides. """ result = YearRange.tuple_from_string("2017- 2019") assert result == (YearRange(F("2017"), "-"), YearRange(F("2019"))) with pytest.raises(YearRangeParseError): YearRange.tuple_from_string("2017 -2019") class TestYearRangeToString: """Tests for YearRange.to_string.""" def test_one_year(self): """Create a string for a single-item year range.""" years = YearRange(F("2017")) assert years.to_string() == "2017" def test_year_and_separator(self): """Create a string for a year and a separator, with no end date.""" years = YearRange(F("2017"), "--") assert years.to_string() == "2017--" def test_full_range(self): """Given a range between two years, create a full string.""" years = YearRange(F("2017"), "-", "2025") assert years.to_string() == "2017-2025" def test_no_separator(self): """Given two years but no separator, add a separator anyway.""" years = YearRange(F("2017"), end="2025") assert years.to_string() == "2017-2025" def test_end_is_word(self): """The end year can be a word like 'Present'.""" years = YearRange(F("2017"), "--", "Present") assert years.to_string() == "2017--Present" def test_original(self): """If an original string exists, return it.""" years = YearRange(F("2017")) object.__setattr__(years, "original", "Foo") assert years.to_string() != "Foo" assert years.to_string(original=True) == "Foo" def test_str(self): """str() is identical to to_string.""" years = YearRange(F("2017"), "-", "2025") object.__setattr__(years, "original", "Foo") assert str(years) == years.to_string() class TestYearRangeSorting: """Test whether YearRange sorts correctly.""" def test_no_type_mixing(self): """Can only compare YearRange objects.""" with pytest.raises(TypeError): _ = YearRange(F("2017")) > "2018" # type: ignore[operator] @pytest.mark.parametrize( "first,second", [ ("2017", "2018"), ("0001", "2017"), ("2017-2019", "2018"), ("2017", "2017-2019"), ("2017", "2017-"), ("2017-2018", "2017-2019"), ("2017-2022", "2019-2021"), ("2017-2022", "2019-2025"), ("2017-2019", "2017-Present"), ("2017-2019", "2017-0abcd"), ], ) def test_less_than(self, first, second): """First is less than second.""" first = YearRange.from_string(first) second = YearRange.from_string(second) assert first.__lt__(second) # pylint: disable=unnecessary-dunder-call assert not second.__lt__( # pylint: disable=unnecessary-dunder-call first ) assert first < second assert second > first @pytest.mark.parametrize( "first,second", [ ("2017", "2017"), ("2017-2018", "2017-2018"), ("2017-Present", "2017-Present"), ("2017-2018", "2017--2018"), ("2017-", "2017--"), ], ) def test_equal(self, first, second): """First is equal to second.""" first = YearRange.from_string(first) second = YearRange.from_string(second) assert first == second class TestYearRangeCompact: """Tests for YearRange.compact.""" def test_three_subsequent(self): """A simple case where three years compact into a single range.""" result = YearRange.compact( [YearRange(F("2017")), YearRange(F("2018")), YearRange(F("2019"))] ) assert result == (YearRange(F("2017"), end="2019"),) def test_two_subsequent(self): """Do not compact a two subsequent years into one range.""" result = YearRange.compact([YearRange(F("2017")), YearRange(F("2018"))]) assert result == (YearRange(F("2017")), YearRange(F("2018"))) def test_unsorted(self): """An unsorted list is also compacted correctly.""" result = YearRange.compact( [YearRange(F("2019")), YearRange(F("2017")), YearRange(F("2018"))] ) assert result == (YearRange(F("2017"), end="2019"),) @pytest.mark.parametrize( "years", [ ["2017", "2018-2016"], ["2017-2015", "2018"], ["2017-2015", "2018-2016"], ["2017-Present", "2018-2016"], ["2017-2016", "2019-Present"], ], ) def test_end_less_than_start(self, years): """If the end of a range is less than the start, handle that case by not compacting it.""" years = tuple(YearRange.from_string(item) for item in years) result = YearRange.compact(years) assert result == years def test_remove_useless_range(self): """If a range has a length of 0, compact it.""" result = YearRange.compact([YearRange(F("2017"), end="2017")]) assert result == (YearRange(F("2017")),) @pytest.mark.parametrize( "text", ["2017", "2017-2020", "2017-Present"], ) def test_range_repeated(self, text): """If a range is repeated, only return one.""" years = YearRange.from_string(text) result = YearRange.compact([years, years]) assert result == (years,) def test_two_subsequent_ranges(self): """A case where two ranges can be glued together.""" result = YearRange.compact( [YearRange(F("2017"), end="2019"), YearRange(F("2020"), end="2021")] ) assert result == (YearRange(F("2017"), end="2021"),) def test_encompassed(self): """A case where a range is contained within another.""" result = YearRange.compact( [YearRange(F("2017"), end="2022"), YearRange(F("2019"), end="2021")] ) assert result == (YearRange(F("2017"), end="2022"),) def test_partial_overlap(self): """If there is partial overlap between ranges, compact them.""" result = YearRange.compact( [YearRange(F("2017"), end="2022"), YearRange(F("2019"), end="2025")] ) assert result == (YearRange(F("2017"), end="2025"),) @pytest.mark.parametrize( "text_list,expected", [ (("2017-2022", "2020-2022"), "2017-2022"), (("2017-2022", "2018-2022", "2020-2022"), "2017-2022"), (("2017-Present", "2020-Present"), "2017-Present"), ( ("2017-Present", "2018-Present", "2020-Present"), "2017-Present", ), (("2017-", "2019-"), "2017-"), ], ) def test_same_end(self, text_list, expected): """If the end of various ranges is the same, pick the lowest start.""" result = YearRange.compact( [YearRange.from_string(item) for item in text_list] ) assert result == (YearRange.from_string(expected),) @pytest.mark.parametrize( "text_list", [ ("2017-2020", "2018-Present"), ("2017-Present", "2018-2020"), ("2017", "2017-Present"), ("2017", "2017-"), ], ) def test_leave_string_end_alone(self, text_list): """Don't really bother compacting int-y ends with string-y ends.""" years = tuple(YearRange.from_string(item) for item in text_list) result = YearRange.compact(years) assert result == years def test_different_string_ends(self): """Do not compact ranges which have different string-y ends.""" years = ( YearRange(F("2017"), end="Present"), YearRange(F("2018"), end="Now"), ) result = YearRange.compact(years) assert result == years class TestCopyrightNoticeFromString: """Tests for CopyrightNotice.from_string.""" def test_uses_from_match(self, monkeypatch): """from_string uses from_match under the hood for 99% of the logic.""" text = "SPDX-FileCopyrightText: 2017 Jane Doe " expected = CopyrightNotice( "Jane Doe ", years=(YearRange(F("2017")),), ) from_match = mock.create_autospec(CopyrightNotice.from_match) from_match.return_value = expected monkeypatch.setattr( "reuse.copyright.CopyrightNotice.from_match", from_match ) expected_match = cast( re.Match[str], COPYRIGHT_NOTICE_PATTERN.fullmatch(text) ) notice = CopyrightNotice.from_string(text) # Now the problem is that two identical re.Matches do not equal each # other, so I will compare some of their values, which is just about # close enough. assert len(from_match.call_args_list) == 1 # Called once assert len(from_match.call_args_list[0].args) == 1 # with one argument. used_match = cast(re.Match[str], from_match.call_args_list[0].args[0]) assert isinstance(used_match, re.Match) assert repr(used_match) == repr(expected_match) assert used_match.groups() == expected_match.groups() assert used_match.re == expected_match.re # Check for a correct output. assert notice == expected def test_simple(self): """A simple case of a prefix and a copyright holder.""" notice = CopyrightNotice.from_string("SPDX-FileCopyrightText: Jane Doe") assert notice == CopyrightNotice( "Jane Doe", prefix=CopyrightPrefix.SPDX ) assert notice.original == "SPDX-FileCopyrightText: Jane Doe" @pytest.mark.parametrize("prefix", CopyrightPrefix) def test_all_prefixes(self, prefix): """All prefixes are correctly recognised.""" value = f"{prefix.value} Jane Doe" notice = CopyrightNotice.from_string(value) assert notice == CopyrightNotice("Jane Doe", prefix=prefix) assert notice.original == value @pytest.mark.parametrize("prefix", CopyrightPrefix) def test_spaces_after_copyright(self, prefix): """A space is not necessary after most copyright prefixex, like '©2017 Jane Doe'. However, 'CopyrightJane Doe' is not valid. """ if prefix == CopyrightPrefix.STRING: with pytest.raises(CopyrightNoticeParseError): CopyrightNotice.from_string(f"{prefix.value}Jane Doe") else: notice = CopyrightNotice.from_string(f"{prefix.value}Jane Doe") if prefix in { CopyrightPrefix.SPDX_STRING, CopyrightPrefix.SNIPPET_STRING, }: assert notice.name == "CopyrightJane Doe" assert notice.prefix in { CopyrightPrefix.SPDX, CopyrightPrefix.SNIPPET, } else: assert notice == CopyrightNotice("Jane Doe", prefix=prefix) def test_spacing_after_name(self): """Spacing after the name should be stripped.""" value = "SPDX-FileCopyrightText: Jane Doe \t" notice = CopyrightNotice.from_string(value) assert notice == CopyrightNotice("Jane Doe") assert notice.original == value @pytest.mark.parametrize( "text,prefix", [ ("SPDX-FileCopyrightText:(C)", CopyrightPrefix.SPDX_C), ("SPDX-FileCopyrightText: (C)", CopyrightPrefix.SPDX_C), ("SPDX-FileCopyrightText:©", CopyrightPrefix.SPDX_SYMBOL), ( "SPDX-FileCopyrightText:Copyright(C)", CopyrightPrefix.SPDX_STRING_C, ), ( "SPDX-FileCopyrightText: Copyright(C)", CopyrightPrefix.SPDX_STRING_C, ), ( "SPDX-FileCopyrightText: Copyright (C)", CopyrightPrefix.SPDX_STRING_C, ), ( "SPDX-FileCopyrightText:Copyright©", CopyrightPrefix.SPDX_STRING_SYMBOL, ), ( "SPDX-FileCopyrightText: Copyright©", CopyrightPrefix.SPDX_STRING_SYMBOL, ), ( "SPDX-FileCopyrightText: Copyright ©", CopyrightPrefix.SPDX_STRING_SYMBOL, ), ("Copyright(C)", CopyrightPrefix.STRING_C), ("Copyright (C)", CopyrightPrefix.STRING_C), ("Copyright©", CopyrightPrefix.STRING_SYMBOL), ("Copyright ©", CopyrightPrefix.STRING_SYMBOL), ], ) def test_unexpected_spacing_in_prefix(self, text, prefix): """When there is unexpected spacing in the prefix, recognise the prefix anyway. """ notice = CopyrightNotice.from_string(f"{text} Jane Doe") assert notice == CopyrightNotice("Jane Doe", prefix=prefix) def test_with_year(self): """If a year is given, parse it correctly.""" notice = CopyrightNotice.from_string("Copyright 2017 Jane Doe") assert notice == CopyrightNotice( "Jane Doe", prefix=CopyrightPrefix.STRING, years=(YearRange(F("2017")),), ) @pytest.mark.parametrize( "year", [ "2017, 2022", "2017,2022", "2017 2022", "2017 , 2022", "2017 2022,", "2017,2022,", "2017, 2022,", ], ) def test_two_years_separated(self, year): """There are various ways of separating years with spaces and commas. They are all valid. """ notice = CopyrightNotice.from_string(f"Copyright {year} Jane Doe") assert notice == CopyrightNotice( "Jane Doe", prefix=CopyrightPrefix.STRING, years=(YearRange(F("2017")), YearRange(F("2022"))), ) @pytest.mark.parametrize( "text", [ "12345678", "123", "12345", "1234.5678", "Present-1234", ], ) def test_not_a_year_range(self, text): """If something is not a year range, do not recognise it as such.""" notice = CopyrightNotice.from_string(f"Copyright {text} Jane Doe") assert notice == CopyrightNotice( f"{text} Jane Doe", prefix=CopyrightPrefix.STRING ) @pytest.mark.parametrize( "text", [ "(C) Jane Doe", "2017 Jane Doe", "Copyrighted Jane Doe", "copyright jane doe", ], ) def test_not_a_notice(self, text): """If something is not a notice, do not recognise it as such.""" with pytest.raises(CopyrightNoticeParseError): CopyrightNotice.from_string(text) @pytest.mark.parametrize("year", ["2017", "2017,"]) def test_no_spaces_after_year(self, year): """If there is no space after the year, it is part of the name.""" notice = CopyrightNotice.from_string(f"Copyright {year}Jane Doe") assert notice == CopyrightNotice( f"{year}Jane Doe", prefix=CopyrightPrefix.STRING ) def test_year_range(self): """A simple test for making sure that year ranges are parsed. Otherwise assume that YearRange.from_string works correctly. """ notice = CopyrightNotice.from_string( "Copyright 2017, 2020-2022, 2024--Present Jane Doe" ) assert notice == CopyrightNotice( "Jane Doe", prefix=CopyrightPrefix.STRING, years=( YearRange(F("2017")), YearRange(F("2020"), "-", "2022"), YearRange(F("2024"), "--", "Present"), ), ) @pytest.mark.parametrize("year", [" 2017", ", 2017"]) def test_year_after_name(self, year): """The year can be at the end instead of at the beginning.""" notice = CopyrightNotice.from_string(f"Copyright Jane Doe{year}") assert notice == CopyrightNotice( "Jane Doe", prefix=CopyrightPrefix.STRING, years=(YearRange(F("2017")),), ) def test_years_around_name(self): """There could be years in multiple places in the notice.""" notice = CopyrightNotice.from_string("Copyright 2017 Jane Doe 2019") assert notice == CopyrightNotice( "Jane Doe", prefix=CopyrightPrefix.STRING, years=(YearRange(F("2017")), YearRange(F("2019"))), ) def test_name_around_years(self): """There could be name information around where the year appears.""" notice = CopyrightNotice.from_string( "Copyright Jane Doe 2017, some rights reserved" ) assert notice == CopyrightNotice( "Jane Doe, some rights reserved", prefix=CopyrightPrefix.STRING, years=(YearRange(F("2017")),), ) def test_dash_after_year(self): """An isolated dash after a year should be part of the name, not the year. """ notice = CopyrightNotice.from_string( "Copyright Jane Doe 2017 - All Rights Reserved" ) assert notice == CopyrightNotice( "Jane Doe - All Rights Reserved", prefix=CopyrightPrefix.STRING, years=(YearRange(F("2017")),), ) class TestCopyrightNoticeToString: """Tests for CopyrightNotice.to_string.""" def test_only_name(self): """The simple case where only a copyright holder is provided.""" notice = CopyrightNotice("Jane Doe") assert notice.to_string() == "SPDX-FileCopyrightText: Jane Doe" def test_different_copyright_prefix(self): """When changing prefix, the resulting string is different.""" notice = CopyrightNotice("Jane Doe", prefix=CopyrightPrefix.STRING) assert notice.to_string() == "Copyright Jane Doe" def test_single_year(self): """A simple case where there is one year range.""" notice = CopyrightNotice("Jane Doe", years=(YearRange(F("2017")),)) assert notice.to_string() == "SPDX-FileCopyrightText: 2017 Jane Doe" def test_two_years(self): """A case where there are two year ranges.""" notice = CopyrightNotice( "Jane Doe", years=( YearRange(F("2017")), YearRange(F("2020"), "--", "2022"), ), ) assert ( notice.to_string() == "SPDX-FileCopyrightText: 2017, 2020--2022 Jane Doe" ) def test_original(self): """If an original string exists, return it.""" notice = CopyrightNotice("Jane Doe") object.__setattr__(notice, "original", "Foo") assert notice.to_string() != "Foo" assert notice.to_string(original=True) == "Foo" def test_str(self): """str() is identical to to_string.""" notice = CopyrightNotice("Jane Doe") object.__setattr__(notice, "original", "Foo") assert str(notice) == notice.to_string() class TestCopyrightNoticeOrder: """Tests for sorting CopyrightNotices.""" def test_year_before_name(self): """The years have higher sorting priority than the names.""" assert CopyrightNotice( "Alice", years=(YearRange(F("2025")),) ) > CopyrightNotice("Bob", years=(YearRange(F("2020")),)) def test_only_names(self): """If there are only names, sort by names.""" assert CopyrightNotice("Alice") < CopyrightNotice("Bob") def test_different_year_range_length(self): """If all is equal except one *years* has more items in the tuple, then the bigger tuple is greater than the smaller one. """ assert CopyrightNotice( "Alice", years=(YearRange(F("2024")), YearRange(F("2025"))) ) > CopyrightNotice( "Bob", years=(YearRange(F("2024")),), ) def test_years_before_no_years(self): """If no years are defined, sort them at the end.""" assert CopyrightNotice( "Alice", years=(YearRange(F("2025")),) ) < CopyrightNotice("Bob") def test_only_prefix_different(self): """If only the prefix is different, sort alphabetically by prefix.""" assert CopyrightNotice( "Jane", prefix=CopyrightPrefix.STRING ) < CopyrightNotice("Jane", prefix=CopyrightPrefix.SPDX) class TestCopyrightNoticeMerge: """Tests for CopyrightNotice.merge.""" def test_single(self): """Given a single notice, return it.""" notices = {CopyrightNotice("Jane Doe")} result = CopyrightNotice.merge(notices) assert result == notices def test_empty(self): """Given an empty iterable, return an empty set.""" result = CopyrightNotice.merge([]) assert result == set() def test_two_different(self): """Given two different notices, return them both.""" notices = {CopyrightNotice("Jane Doe"), CopyrightNotice("John Doe")} result = CopyrightNotice.merge(notices) assert result == notices def test_two_with_years(self): """Given two identical notices apart from the years, return one with the years compacted. """ notices = { CopyrightNotice.from_string("Copyright 2017 Jane Doe"), CopyrightNotice.from_string("Copyright 2018 Jane Doe"), } result = CopyrightNotice.merge(notices) assert result == { CopyrightNotice.from_string("Copyright 2017, 2018 Jane Doe") } def test_two_different_prefix(self): """If the prefixes of two notices are different, choose the highest priority prefix. """ members = list(CopyrightPrefix) for i, prefix1 in enumerate(members): for prefix2 in members[i:]: notices = { CopyrightNotice.from_string(f"{prefix1.value} Jane Doe"), CopyrightNotice.from_string(f"{prefix2.value} Jane Doe"), } result = CopyrightNotice.merge(notices) assert result == { CopyrightNotice.from_string(f"{prefix1.value} Jane Doe") } def test_two_same_prefix_one_different(self): """If two prefixes are identical, and one prefix is not, merge into the most common prefix. """ for prefix1 in CopyrightPrefix: for prefix2 in CopyrightPrefix: notices = [ CopyrightNotice.from_string(f"{prefix1.value} Jane Doe"), CopyrightNotice.from_string(f"{prefix1.value} Jane Doe"), CopyrightNotice.from_string(f"{prefix2.value} Jane Doe"), ] result = CopyrightNotice.merge(notices) assert result == { CopyrightNotice.from_string(f"{prefix1.value} Jane Doe") } class TestSpdxExpressionGetExpressionAndIsValid: """Tests for the property :attr:`SpdxExpression._expression`. Simultaneously, test :attr:`SpdxExpression.is_valid`. """ @pytest.mark.parametrize( "text", [ "GPL-3.0-or-later", "GPL-3.0-or-later OR CC0-1.0", "Apache-2.0 AND 0BSD", "(MIT OR 0BSD) AND GPL-3.0-or-later", ], ) def test_valid(self, text): """A valid expression is correctly parsed.""" # pylint: disable=protected-access expression = SpdxExpression(text) assert expression._expression == _LICENSING.parse(text) assert expression.is_valid @pytest.mark.parametrize( "text", [ "MIT OR", "MIT AND", "OR MIT", "AND MIT", "(MIT AND 0BSD", "", "MIT 0BSD", ], ) def test_invalid(self, text): """An invalid expression returns None.""" # pylint: disable=protected-access expression = SpdxExpression(text) assert expression._expression is None assert not expression.is_valid class TestSpdxExpressionLicenses: """Tests for the property :attr:`SpdxExpression.licenses`.""" def test_valid(self): """A valid expression returns all unique licenses in order of appearance. """ expression = SpdxExpression("MIT AND MIT OR 0BSD") assert expression.licenses == ["MIT", "0BSD"] def test_invalid(self): """An invalid expression returns itself in a list.""" expression = SpdxExpression("0BSD AND") assert expression.licenses == ["0BSD AND"] class TestSpdxExpressionCombine: """Tests for :classmethod:`SpdxExpression.combine`.""" def test_valid(self): """Valid expressions are smartly combined.""" assert SpdxExpression.combine( [ SpdxExpression("MIT"), SpdxExpression(" 0BSD "), SpdxExpression("GPL-3.0-or-later OR Apache-2.0"), ] ) == SpdxExpression("MIT AND 0BSD AND (GPL-3.0-or-later OR Apache-2.0)") def test_invalid(self): """Invalid expressions are simply combined by AND operators.""" assert SpdxExpression.combine( [SpdxExpression("0BSD OR"), SpdxExpression("MIT")] ) == SpdxExpression("(0BSD OR) AND (MIT)") class TestSpdxExpressionSimplify: """Tests for :meth:`SpdxExpression.simplify`.""" def test_valid(self): """A valid expression is correctly simplified.""" expression = SpdxExpression( "(MIT OR MIT) AND (GPL-3.0-or-later AND 0BSD) AND GPL-3.0-or-later" ) assert expression.simplify() == SpdxExpression( "0BSD AND GPL-3.0-or-later AND MIT" ) def test_invalid(self): """An invalid expression is returned as-is when simplified.""" text = "MIT OR AND (0BSD OR 0BSD)" assert SpdxExpression(text) == SpdxExpression(text) class TestSpdxExpressionStr: """Tests for SpdxExpression.__str__.""" def test_valid(self): """A valid expression is returned as string.""" expression = SpdxExpression("0BSD AND MIT OR CC0-1.0") assert str(expression) == "(0BSD AND MIT) OR CC0-1.0" def test_invalid(self): """An invalid expression is returned as-is.""" expression = SpdxExpression("0BSD AND") assert str(expression) == "0BSD AND" class TestSpdxExpressionEq: """Tests for SpdxExpression.__eq__.""" def test_both_invalid(self): """If both expressions are invalid, their texts are simply compared.""" assert SpdxExpression("MIT OR") != SpdxExpression("MIT OR ") assert SpdxExpression("MIT OR") == SpdxExpression("MIT OR") @pytest.mark.parametrize( "text", [ "MIT AND 0BSD", "MIT AND 0BSD ", "(MIT AND 0BSD)", ], ) def test_valid(self, text): """If both expressions are valid, the expressions are compared.""" assert SpdxExpression(text) == SpdxExpression("MIT AND 0BSD") def test_not_spdx_expression(self): """Something that isn't an SpdxExpression is never equal to it.""" assert SpdxExpression("MIT") != "MIT" class TestSpdxExpressionSort: """Tests for SpdxExpression.__lt__.""" @pytest.mark.parametrize( "one,two", [ ("0BSD", "MIT"), ("0BSD AND MIT", "MIT AND 0BSD"), ("0BSD AND", "MIT"), ("0BSD", "MIT AND"), ("0BSD AND", "MIT AND"), ], ) def test_simple(self, one, two): """The strings of expressions are correctly compared.""" assert SpdxExpression(one) < SpdxExpression(two) def test_not_spdx_expression(self): """Something that isn't an SpdxExpression can't be sorted relative to it. """ with pytest.raises(TypeError): bool(SpdxExpression("MIT") < "MIT") @pytest.mark.parametrize( "args", [ {"spdx_expressions": {"GPL-3.0-or-later"}, "copyright_notices": set()}, { "spdx_expressions": set(), "copyright_notices": { CopyrightNotice.from_string( "SPDX-FileCopyrightText: 2017 Jane Doe" ) }, }, { "spdx_expressions": {"GPL-3.0-or-later"}, "copyright_notices": { CopyrightNotice.from_string( "SPDX-FileCopyrightText: 2017 Jane Doe" ) }, }, ], ) def test_reuse_info_contains_copyright_or_licensing(args): """If either spdx_expressions or copyright_notices is truthy, then expect True. """ 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={SpdxExpression("MIT")}, copyright_notices={CopyrightNotice.from_string("Copyright Jane Doe")}, ).contains_copyright_xor_licensing() assert ReuseInfo( spdx_expressions={SpdxExpression("MIT")} ).contains_copyright_xor_licensing() assert ReuseInfo( copyright_notices={CopyrightNotice.from_string("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={SpdxExpression("MIT")}).contains_info() assert ReuseInfo( copyright_notices={ CopyrightNotice.from_string("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={SpdxExpression("GPL-3.0-or-later")}, copyright_notices={ CopyrightNotice.from_string("Copyright 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_notices == new_info.copyright_notices 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") class TestReuseInfoUnion: """Tests for ReuseInfo.union.""" def test_simple(self): """ Get a union of ReuseInfo with one field merged and one remaining equal. """ info1 = ReuseInfo( copyright_notices={ CopyrightNotice.from_string("Copyright 2017 Jane Doe") }, source_path="foo", ) info2 = ReuseInfo( copyright_notices={ CopyrightNotice.from_string("Copyright 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_notices) == [ CopyrightNotice.from_string("Copyright 2017 Jane Doe"), CopyrightNotice.from_string("Copyright 2017 John Doe"), ] assert new_info.source_path == "foo" def test_none(self): """If no argument is provided, nothing changes.""" info = ReuseInfo(copyright_notices={CopyrightNotice("Jane Doe")}) result = info.union() assert result == info def test_multiple(self): """If multi arguments are provided, merge them all.""" copyright1 = CopyrightNotice("Jane Doe") copyright2 = CopyrightNotice("John Doe") copyright3 = CopyrightNotice("Alice") info1 = ReuseInfo(copyright_notices={copyright1}) info2 = ReuseInfo(copyright_notices={copyright2}) info3 = ReuseInfo(copyright_notices={copyright3}) result = info1.union(info2, info3) assert result == ReuseInfo( copyright_notices={copyright1, copyright2, copyright3} ) # REUSE-IgnoreEnd reuse-tool-6.2.0/tests/test_cli_spdx.py0000664000175000017500000000652315077707000016654 0ustar alexalex# SPDX-FileCopyrightText: 2019 Free Software Foundation Europe e.V. # SPDX-FileCopyrightText: 2019 Stefan Bakker # SPDX-FileCopyrightText: 2022 Florian Snow # SPDX-FileCopyrightText: 2022 Pietro Albini # SPDX-FileCopyrightText: 2024 Carmen Bianca BAKKER # SPDX-FileCopyrightText: 2024 Skyler Grey # SPDX-FileCopyrightText: © 2020 Liferay, Inc. # # SPDX-License-Identifier: GPL-3.0-or-later """Tests for spdx.""" from click.testing import CliRunner from freezegun import freeze_time from reuse.cli.main import main # pylint: disable=unused-argument class TestSpdx: """Tests for spdx.""" @freeze_time("2024-04-08T17:34:00Z") def test_simple(self, fake_repository): """Compile to an SPDX document.""" result = CliRunner().invoke(main, ["spdx"]) output = result.output # 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.exit_code == 0 def test_creator_info(self, fake_repository): """Ensure the --creator-* flags are properly formatted""" result = CliRunner().invoke( main, [ "spdx", "--creator-person=Jane Doe (jane.doe@example.org)", "--creator-organization=FSFE", ], ) output = result.output assert result.exit_code == 0 assert "\nCreator: Person: Jane Doe (jane.doe@example.org)\n" in output assert "\nCreator: Organization: FSFE ()\n" in output def test_add_license_concluded(self, fake_repository): """Compile to an SPDX document with the LicenseConcluded field.""" result = CliRunner().invoke( main, [ "spdx", "--add-license-concluded", "--creator-person=Jane Doe", "--creator-organization=FSFE", ], ) output = result.output # Ensure no LicenseConcluded is included without the flag assert result.exit_code == 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_add_license_concluded_without_creator_info(self, fake_repository): """Adding LicenseConcluded should require creator information""" result = CliRunner().invoke(main, ["spdx", "--add-license-concluded"]) assert result.exit_code != 0 assert "--add-license-concluded" in result.output def test_spdx_no_multiprocessing(self, fake_repository, multiprocessing): """--no-multiprocessing works.""" result = CliRunner().invoke(main, ["--no-multiprocessing", "spdx"]) # TODO: This test is rubbish. assert result.exit_code == 0 assert result.output reuse-tool-6.2.0/tests/conftest.py0000664000175000017500000005206715077707000015641 0ustar alexalex# 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-FileCopyrightText: 2024 Skyler Grey # # SPDX-License-Identifier: GPL-3.0-or-later """Global fixtures and configuration.""" # pylint: disable=redefined-outer-name,invalid-name import concurrent.futures import contextlib import datetime import importlib import logging import os import shutil import subprocess import sys from collections.abc import Generator from inspect import cleandoc from io import StringIO from pathlib import Path from unittest.mock import create_autospec import pytest from jinja2 import Environment os.environ["LC_ALL"] = "C" os.environ["LANGUAGE"] = "" # 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 import extract, report from reuse._util import setup_logging from reuse.comment import ( EmptyCommentStyle, UncommentableCommentStyle, _all_style_classes, ) from reuse.global_licensing import ReuseDep5 from reuse.lint import format_lines, format_lines_subset from reuse.vcs import GIT_EXE, HG_EXE, JUJUTSU_EXE, PIJUL_EXE try: _chardet = bool(importlib.import_module("chardet")) except ImportError: _chardet = False 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") hg = pytest.mark.skipif(not HG_EXE, reason="requires mercurial") pijul = pytest.mark.skipif(not PIJUL_EXE, reason="requires pijul") no_root = pytest.mark.xfail(is_root, reason="fails when user is root") posix = pytest.mark.skipif(not is_posix, reason="Windows not supported") chardet = pytest.mark.skipif(not _chardet, reason="chardet is not installed") # 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)) # Disable parallelisation during tests. report.ENABLE_PARALLEL = False def pytest_runtest_setup(item): """Called before running a test.""" # pylint: disable=unused-argument # 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"] def pytest_runtest_teardown(item): """Called after running a test.""" # pylint: disable=unused-argument # Make sure to restore CWD os.chdir(CWD) @pytest.fixture(scope="session") 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(params=[True, False]) def optional_git_exe(request, monkeypatch) -> Generator[str | None, None, None]: """Run the test with or without git.""" exe = GIT_EXE if request.param else "" monkeypatch.setattr("reuse.vcs.GIT_EXE", exe) yield exe @pytest.fixture(scope="session") 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(params=[True, False]) def optional_hg_exe(request, monkeypatch) -> Generator[str | None, None, None]: """Run the test with or without mercurial.""" exe = HG_EXE if request.param else "" monkeypatch.setattr("reuse.vcs.HG_EXE", exe) yield exe @pytest.fixture(scope="session") def jujutsu_exe() -> str: """Run the test with Jujutsu.""" if not JUJUTSU_EXE: pytest.skip("cannot run this test without jujutsu") return str(JUJUTSU_EXE) @pytest.fixture(params=[True, False]) def optional_jujutsu_exe( request, monkeypatch ) -> Generator[str | None, None, None]: """Run the test with or without Jujutsu.""" exe = JUJUTSU_EXE if request.param else "" monkeypatch.setattr("reuse.vcs.JUJUTSU_EXE", exe) yield exe @pytest.fixture(scope="session") 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 optional_pijul_exe( request, monkeypatch ) -> Generator[str | None, None, None]: """Run the test with or without Pijul.""" exe = PIJUL_EXE if request.param else "" monkeypatch.setattr("reuse.vcs.PIJUL_EXE", exe) yield exe @pytest.fixture(params=[True, False]) def multiprocessing(request, monkeypatch) -> Generator[bool, None, None]: """Run the test with or without multiprocessing.""" monkeypatch.setattr("reuse.report.ENABLE_PARALLEL", True) if not request.param: monkeypatch.delattr(concurrent.futures, "ProcessPoolExecutor") yield request.param @pytest.fixture( params=["python-magic", "file-magic", "charset_normalizer", "chardet"] ) def encoding_module(request, monkeypatch) -> Generator[bool, None, None]: """Run the test with or without libmagic.""" is_magic = "magic" in request.param if is_magic and not is_posix: pytest.skip("Windows not supported") try: module = importlib.import_module( request.param if not is_magic else "magic" ) # pylint: disable=protected-access if is_magic and extract._detect_magic(module) != request.param: pytest.skip(f"'magic' does not import as {request.param}") monkeypatch.setattr("reuse.extract._ENCODING_MODULE", module) yield request.param except ImportError: pytest.skip(f"'{request.param}' could not be imported") @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(scope="session") def _cached_fake_repository(tmp_path_factory) -> Path: """Create a temporary fake repository.""" directory = tmp_path_factory.mktemp("fake_repository") shutil.copytree( RESOURCES_DIRECTORY / "fake_repository", directory, dirs_exist_ok=True ) # Get rid of those pesky pyc files. shutil.rmtree(directory / "src/__pycache__", ignore_errors=True) return directory @pytest.fixture() def fake_repository(_cached_fake_repository, tmp_path) -> Path: """Create a temporary fake repository.""" shutil.copytree(_cached_fake_repository, tmp_path, dirs_exist_ok=True) os.chdir(tmp_path) return tmp_path @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(scope="session") def _cached_git_repository( _cached_fake_repository: Path, tmp_path_factory, git_exe: str ) -> Path: """Create a git repository with ignored files.""" directory = tmp_path_factory.mktemp("cached_git_directory") shutil.copytree(_cached_fake_repository, directory, dirs_exist_ok=True) os.chdir(directory) _repo_contents(directory) subprocess.run([git_exe, "init", str(directory)], check=True) Path(".git/config").write_text( cleandoc( """ [user] name = Example email = example@example.com [commit] gpgSign = false """ ), encoding="utf-8", ) subprocess.run([git_exe, "add", str(directory)], check=True) subprocess.run( [ git_exe, "commit", "-m", "initial", ], check=True, ) return directory @pytest.fixture() def git_repository(_cached_git_repository, tmp_path) -> Path: """Create a git repository with ignored files.""" shutil.copytree(_cached_git_repository, tmp_path, dirs_exist_ok=True) os.chdir(tmp_path) return tmp_path @pytest.fixture(scope="session") def _cached_hg_repository( _cached_fake_repository: Path, tmp_path_factory, hg_exe: str ) -> Path: """Create a mercurial repository with ignored files.""" directory = tmp_path_factory.mktemp("cached_hg_repository") shutil.copytree(_cached_fake_repository, directory, dirs_exist_ok=True) os.chdir(directory) _repo_contents( directory, 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 directory @pytest.fixture() def hg_repository(_cached_hg_repository, tmp_path) -> Path: """Create a mercurial repository with ignored files.""" shutil.copytree(_cached_hg_repository, tmp_path, dirs_exist_ok=True) os.chdir(tmp_path) return tmp_path @pytest.fixture(scope="session") def _cached_jujutsu_repository( _cached_fake_repository: Path, tmp_path_factory, jujutsu_exe: str ) -> Path: """Create a jujutsu repository with ignored files.""" directory = tmp_path_factory.mktemp("cached_jujutsu_repository") shutil.copytree(_cached_fake_repository, directory, dirs_exist_ok=True) os.chdir(directory) _repo_contents(directory) subprocess.run([jujutsu_exe, "git", "init", str(directory)], check=True) return directory @pytest.fixture() def jujutsu_repository(_cached_jujutsu_repository, tmp_path) -> Path: """Create a jujutsu repository with ignored files.""" shutil.copytree(_cached_jujutsu_repository, tmp_path, dirs_exist_ok=True) os.chdir(tmp_path) return tmp_path @pytest.fixture(scope="session") def _cached_pijul_repository( _cached_fake_repository: Path, tmp_path_factory, pijul_exe: str ) -> Path: """Create a pijul repository with ignored files.""" directory = tmp_path_factory.mktemp("cached_pijul_repository") shutil.copytree(_cached_fake_repository, directory, dirs_exist_ok=True) os.chdir(directory) _repo_contents( directory, 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 directory @pytest.fixture() def pijul_repository(_cached_pijul_repository, tmp_path) -> Path: """Create a pijul repository with ignored files.""" shutil.copytree(_cached_pijul_repository, tmp_path, dirs_exist_ok=True) os.chdir(tmp_path) return tmp_path @pytest.fixture(scope="session", params=["submodule-add", "manual"]) def _cached_submodule_repository( _cached_git_repository: Path, git_exe: str, tmp_path_factory, request ) -> Path: """Create a git repository that contains a submodule.""" directory = tmp_path_factory.mktemp("cached_submodule_repository") shutil.copytree(_cached_git_repository, directory, dirs_exist_ok=True) header = cleandoc( """ SPDX-FileCopyrightText: 2019 Jane Doe SPDX-License-Identifier: CC0-1.0 """ ) submodule = tmp_path_factory.mktemp("submodule") (submodule / "foo.py").write_text(header, encoding="utf-8") os.chdir(submodule) subprocess.run([git_exe, "init", str(submodule)], check=True) Path(".git/config").write_text( cleandoc( """ [user] name = Example email = example@example.com [commit] gpgSign = false """ ), encoding="utf-8", ) subprocess.run([git_exe, "add", str(submodule)], check=True) subprocess.run( [ git_exe, "commit", "-m", "initial", ], check=True, ) os.chdir(directory) 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( directory / ".gitmodules", mode="a", encoding="utf-8" ) as gitmodules_file: gitmodules_file.write( cleandoc( 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, ) (directory / ".gitmodules.license").write_text(header) return directory @pytest.fixture() def submodule_repository(_cached_submodule_repository, tmp_path) -> Path: """Create a git repository that contains a submodule.""" shutil.copytree(_cached_submodule_repository, tmp_path, dirs_exist_ok=True) os.chdir(tmp_path) return tmp_path @pytest.fixture() def subproject_repository(fake_repository: Path) -> Path: """Add a Meson subproject to the fake repo.""" (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") return fake_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 %} """ ) @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) def _filtered_styles(predicate): return [ Style for Style in _all_style_classes() if Style not in (EmptyCommentStyle, UncommentableCommentStyle) and predicate(Style) ] @pytest.fixture(params=_filtered_styles(lambda s: True)) def comment_style(request): """Yield all CommentStyle classes, excluding EmptyCommentStyle and UncommentableCommentStyle. """ yield request.param @pytest.fixture(params=_filtered_styles(lambda s: s.can_handle_single())) def single_style(request): """Yield all CommentStyle classes that support single-line comments.""" yield request.param @pytest.fixture(params=_filtered_styles(lambda s: s.can_handle_multi())) def multi_style(request): """Yield all CommentStyle classes that support multi-line comments.""" yield request.param @pytest.fixture(params=_filtered_styles(lambda s: s.SHEBANGS)) def shebang_style(request): """Yield all CommentStyle classes that support shebangs.""" yield request.param @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 @pytest.fixture(params=["format_lines", "format_lines_subset"]) def format_lines_func(request): """Return format_lines or format_lines_subset.""" if request.param == "format_lines": yield format_lines elif request.param == "format_lines_subset": yield format_lines_subset # REUSE-IgnoreEnd reuse-tool-6.2.0/tests/resources/0000775000175000017500000000000015077707000015442 5ustar alexalexreuse-tool-6.2.0/tests/resources/dep50000664000175000017500000000020315077707000016215 0ustar alexalexFormat: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Files: doc/* Copyright: 2017 Jane Doe License: CC0-1.0 reuse-tool-6.2.0/tests/resources/fake_repository/0000775000175000017500000000000015077707000020647 5ustar alexalexreuse-tool-6.2.0/tests/resources/fake_repository/doc/0000775000175000017500000000000015077707000021414 5ustar alexalexreuse-tool-6.2.0/tests/resources/fake_repository/doc/usage.md0000664000175000017500000000012015077707000023033 0ustar alexalex reuse-tool-6.2.0/tests/resources/fake_repository/src/0000775000175000017500000000000015077707000021436 5ustar alexalexreuse-tool-6.2.0/tests/resources/fake_repository/src/source_code.jinja20000664000175000017500000000015515077707000025030 0ustar alexalex{# SPDX-FileCopyrightText: 2017 Jane Doe SPDX-License-Identifier: GPL-3.0-or-later #}

Hello, world!

reuse-tool-6.2.0/tests/resources/fake_repository/src/multiple_licenses.rs0000664000175000017500000000024415077707000025524 0ustar alexalex// SPDX-FileCopyrightText: 2022 Jane Doe // SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: Apache-2.0 OR CC0-1.0 WITH Autoconf-exception-3.0 reuse-tool-6.2.0/tests/resources/fake_repository/src/custom.py0000664000175000017500000000012715077707000023322 0ustar alexalex# SPDX-FileCopyrightText: 2017 Jane Doe # # SPDX-License-Identifier: LicenseRef-custom reuse-tool-6.2.0/tests/resources/fake_repository/src/exception.py0000664000175000017500000000016215077707000024005 0ustar alexalex# SPDX-FileCopyrightText: 2017 Jane Doe # # SPDX-License-Identifier: GPL-3.0-or-later WITH Autoconf-exception-3.0 reuse-tool-6.2.0/tests/resources/fake_repository/src/source_code.py0000664000175000017500000000024615077707000024304 0ustar alexalex# SPDX-FileCopyrightText: 2017 Jane Doe # # SPDX-License-Identifier: GPL-3.0-or-later """Module docstring.""" if __name__ == "__main__": print("Hello, world!") reuse-tool-6.2.0/tests/resources/fake_repository/src/source_code.c0000664000175000017500000000023415077707000024073 0ustar alexalex/* SPDX-FileCopyrightText: 2017 Jane Doe */ /* SPDX-License-Identifier: GPL-3.0-or-later */ #include main() { printf("Hello, world!\n"); } reuse-tool-6.2.0/tests/resources/fake_repository/src/source_code.html0000664000175000017500000000015715077707000024621 0ustar alexalex

Hello, world!

reuse-tool-6.2.0/tests/resources/fake_repository/LICENSES/0000775000175000017500000000000015077707000022054 5ustar alexalexreuse-tool-6.2.0/tests/resources/fake_repository/LICENSES/LicenseRef-custom.txt0000664000175000017500000000000015077707000026132 0ustar alexalexreuse-tool-6.2.0/tests/resources/fake_repository/LICENSES/GPL-3.0-or-later.txt0000664000175000017500000000001515077707000025254 0ustar alexalexLicense text reuse-tool-6.2.0/tests/resources/fake_repository/LICENSES/CC0-1.0.txt0000664000175000017500000000001515077707000023452 0ustar alexalexLicense text reuse-tool-6.2.0/tests/resources/fake_repository/LICENSES/Autoconf-exception-3.0.txt0000664000175000017500000000001615077707000026662 0ustar alexalexException textreuse-tool-6.2.0/tests/resources/fake_repository/LICENSES/Apache-2.0.txt0000664000175000017500000000001615077707000024270 0ustar alexalexLicense text. reuse-tool-6.2.0/tests/resources/fsfe.png0000664000175000017500000001251215077707000017074 0ustar alexalexPNG  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: 2022 Florian Snow # SPDX-FileCopyrightText: 2024 Skyler Grey # SPDX-FileCopyrightText: © 2020 Liferay, Inc. # # SPDX-License-Identifier: GPL-3.0-or-later """Tests for reuse.vcs""" import os from pathlib import Path from typing import cast 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 = cast(Path, 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 = cast(Path, vcs.find_root()) assert Path(result).absolute().resolve() == hg_repository def test_find_root_in_jujutsu_repo(jujutsu_repository): """When using reuse from a child directory in a Jujutsu repo, always find the root directory. """ os.chdir("src") result = cast(Path, vcs.find_root()) assert Path(result).absolute().resolve() == jujutsu_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 = cast(Path, vcs.find_root()) assert Path(result).absolute().resolve() == pijul_repository reuse-tool-6.2.0/tests/test_covered_files.py0000664000175000017500000003243015077707000017654 0ustar alexalex# 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.covered_files.""" import os from pathlib import Path from conftest import git, hg, pijul, posix from reuse.covered_files import iter_files from reuse.vcs import VCSStrategyGit, VCSStrategyHg, VCSStrategyPijul class TestIterFiles: """Test the iter_files function.""" def test_simple(self, empty_directory): """Given a directory with some files, yield all files.""" (empty_directory / "foo").write_text("foo") (empty_directory / "bar").write_text("foo") assert {file_.name for file_ in iter_files(empty_directory)} == { "foo", "bar", } def test_ignore_dot_license(self, 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") assert {file_.name for file_ in iter_files(empty_directory)} == {"foo"} def test_ignore_cal_license(self, 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" ) assert not list(iter_files(empty_directory)) def test_ignore_shl_license(self, 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") assert not list(iter_files(empty_directory)) def test_ignore_git(self, empty_directory): """When the git directory is present, ignore it.""" (empty_directory / ".git").mkdir() (empty_directory / ".git/config").write_text("foo") assert not list(iter_files(empty_directory)) def test_ignore_hg(self, empty_directory): """When the hg directory is present, ignore it.""" (empty_directory / ".hg").mkdir() (empty_directory / ".hg/config").write_text("foo") assert not list(iter_files(empty_directory)) def test_ignore_license_copying(self, 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") assert not list(iter_files(empty_directory)) def test_not_ignore_license_copying_no_ext(self, 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") assert len(list(iter_files(empty_directory))) == 2 @posix def test_ignore_symlinks(self, empty_directory): """All symlinks must be ignored.""" (empty_directory / "blob").write_text("foo") (empty_directory / "symlink").symlink_to("blob") assert Path("symlink").absolute() not in iter_files(empty_directory) def test_ignore_zero_sized(self, empty_directory): """Empty files should be skipped.""" (empty_directory / "foo").touch() assert Path("foo").absolute() not in iter_files(empty_directory) def test_include_meson_subprojects(self, empty_directory): """include_meson_subprojects is correctly interpreted.""" (empty_directory / "foo.py").write_text("foo.py") subprojects_dir = empty_directory / "subprojects" subprojects_dir.mkdir() libfoo_dir = subprojects_dir / "libfoo" libfoo_dir.mkdir() bar_file = libfoo_dir / "bar.py" bar_file.write_text("pass") assert bar_file not in iter_files(empty_directory) assert bar_file in iter_files( empty_directory, include_meson_subprojects=True ) def test_reuse_toml_ignored(self, empty_directory): """REUSE.toml is ignored.""" (empty_directory / "REUSE.toml").write_text("version = 1") assert not list(iter_files(empty_directory)) assert list(iter_files(empty_directory, include_reuse_tomls=True)) class TestIterFilesSubet: """Tests for subset_files in iter_files.""" def test_single(self, fake_repository): """Only yield the single specified file.""" result = list( iter_files( fake_repository, subset_files={fake_repository / "src/custom.py"}, ) ) assert result == [fake_repository / "src/custom.py"] def test_two(self, fake_repository): """Yield multiple specified files.""" result = set( iter_files( fake_repository, subset_files={ fake_repository / "src/custom.py", fake_repository / "src/exception.py", }, ) ) assert result == { fake_repository / "src/custom.py", fake_repository / "src/exception.py", } def test_non_existent(self, fake_repository): """If a file does not exist, don't yield it.""" result = list( iter_files( fake_repository, subset_files={ fake_repository / "src/custom.py", fake_repository / "not_exist.py", fake_repository / "also/does/not/exist.py", }, ) ) assert result == [fake_repository / "src/custom.py"] def test_outside_cwd(self, fake_repository): """If a file is outside of the project, don't yield it.""" result = list( iter_files( fake_repository, subset_files={ fake_repository / "src/custom.py", (fake_repository / "../outside.py").resolve(), }, ) ) assert result == [fake_repository / "src/custom.py"] def test_empty(self, fake_repository): """If no files are provided, yield nothing.""" result = list(iter_files(fake_repository, subset_files=set())) assert not result def test_list_arg(self, fake_repository): """Also accepts a list argument.""" result = list( iter_files( fake_repository, subset_files=[fake_repository / "src/custom.py"], ) ) assert result == [fake_repository / "src/custom.py"] def test_relative_path(self, fake_repository): """Also handles relative paths.""" result = list( iter_files(fake_repository, subset_files={"src/custom.py"}) ) assert result == [fake_repository / "src/custom.py"] @git class TestAllFilesGit: """Test the iter_files function with git.""" def test_simple(self, git_repository): """Given a Git repository where some files are ignored, do not yield those files. """ assert Path("build/hello.py").absolute() not in iter_files( git_repository, vcs_strategy=VCSStrategyGit(git_repository) ) def test_not_ignored_if_no_strategy(self, git_repository): """If no strategy is provided, the file is not ignored.""" assert Path("build/hello.py").absolute() in iter_files(git_repository) def test_different_cwd(self, 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") assert Path("build/hello.py").absolute() not in iter_files( git_repository, vcs_strategy=VCSStrategyGit(git_repository) ) def test_ignored_contains_space(self, git_repository): """Files that contain spaces are also ignored.""" (git_repository / "I contain spaces.pyc").write_text("foo") assert Path("I contain spaces.pyc").absolute() not in iter_files( git_repository, vcs_strategy=VCSStrategyGit(git_repository) ) @posix def test_ignored_contains_newline(self, git_repository): """Files that contain newlines are also ignored.""" (git_repository / "hello\nworld.pyc").write_text("foo") assert Path("hello\nworld.pyc").absolute() not in iter_files( git_repository, vcs_strategy=VCSStrategyGit(git_repository) ) def test_ignore_submodules(self, submodule_repository): """Normally ignore submodules.""" (submodule_repository / "submodule/foo.py").write_text("foo") assert Path("submodule/foo.py").absolute() not in iter_files( submodule_repository, vcs_strategy=VCSStrategyGit(submodule_repository), ) def test_include_submodules(self, submodule_repository): """If include_submodules is True, include files from the submodule.""" (submodule_repository / "submodule/foo.py").write_text("foo") assert Path("submodule/foo.py").absolute() in iter_files( submodule_repository, include_submodules=True, vcs_strategy=VCSStrategyGit(submodule_repository), ) def test_submodule_is_ignored(self, submodule_repository): """If a submodule is ignored, iter_files shouldn't 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) assert Path("submodule/foo.py").absolute() not in iter_files( submodule_repository, vcs_strategy=VCSStrategyGit(submodule_repository), ) @hg class TestAllFilesHg: """Test the iter_files function with Mercurial.""" def test_simple(self, hg_repository): """Given a mercurial repository where some files are ignored, do not yield those files. """ assert Path("build/hello.py").absolute() not in iter_files( hg_repository, vcs_strategy=VCSStrategyHg(hg_repository) ) def test_different_cwd(self, 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") assert Path("build/hello.py").absolute() not in iter_files( hg_repository, vcs_strategy=VCSStrategyHg(hg_repository) ) def test_ignored_contains_space(self, hg_repository): """File names that contain spaces are also ignored.""" (hg_repository / "I contain spaces.pyc").touch() assert Path("I contain spaces.pyc").absolute() not in iter_files( hg_repository, vcs_strategy=VCSStrategyHg(hg_repository) ) @posix def test_ignored_contains_newline(self, hg_repository): """File names that contain newlines are also ignored.""" (hg_repository / "hello\nworld.pyc").touch() assert Path("hello\nworld.pyc").absolute() not in iter_files( hg_repository, vcs_strategy=VCSStrategyHg(hg_repository) ) @pijul class TestAllFilesPijul: """Test the iter_files function with Pijul.""" def test_simple(self, pijul_repository): """Given a pijul repository where some files are ignored, do not yield those files. """ assert Path("build/hello.py").absolute() not in iter_files( pijul_repository, vcs_strategy=VCSStrategyPijul(pijul_repository) ) def test_iter_files_pijul_ignored_different_cwd(self, 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") assert Path("build/hello.py").absolute() not in iter_files( pijul_repository, vcs_strategy=VCSStrategyPijul(pijul_repository) ) def test_ignored_contains_space(self, pijul_repository): """File names that contain spaces are also ignored.""" (pijul_repository / "I contain spaces.pyc").touch() assert Path("I contain spaces.pyc").absolute() not in iter_files( pijul_repository, vcs_strategy=VCSStrategyPijul(pijul_repository) ) @posix def test_ignored_contains_newline(self, pijul_repository): """File names that contain newlines are also ignored.""" (pijul_repository / "hello\nworld.pyc").touch() assert Path("hello\nworld.pyc").absolute() not in iter_files( pijul_repository, vcs_strategy=VCSStrategyPijul(pijul_repository) ) reuse-tool-6.2.0/tests/test_cli_supported_licenses.py0000664000175000017500000000301715077707000021603 0ustar alexalex# SPDX-FileCopyrightText: 2019 Free Software Foundation Europe e.V. # SPDX-FileCopyrightText: 2021 Michael Weimann # SPDX-FileCopyrightText: 2025 Shun Sakai # # SPDX-License-Identifier: GPL-3.0-or-later """Tests for supported-licenses.""" import json import re from click.testing import CliRunner from reuse.cli.main import main class TestSupportedLicenses: """Tests for supported-licenses.""" def test_simple(self): """Invoke the supported-licenses command and check whether the result contains at least one license in the expected format. """ result = CliRunner().invoke(main, ["supported-licenses"]) assert result.exit_code == 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", result.output, ) def test_json(self): """Output the list as JSON.""" result = CliRunner().invoke(main, ["supported-licenses", "--json"]) output = json.loads(result.output) assert result.exit_code == 0 expected = next( (o for o in output if o["id"] == "GPL-3.0-or-later"), None ) assert expected is not None assert expected["name"] == "GNU General Public License v3.0 or later" assert ( expected["reference"] == "https://spdx.org/licenses/GPL-3.0-or-later.html" ) reuse-tool-6.2.0/tests/test_cli_lint.py0000664000175000017500000002332615077707000016644 0ustar alexalex# SPDX-FileCopyrightText: 2019 Free Software Foundation Europe e.V. # SPDX-FileCopyrightText: 2019 Stefan Bakker # SPDX-FileCopyrightText: 2022 Florian Snow # SPDX-FileCopyrightText: 2022 Pietro Albini # SPDX-FileCopyrightText: 2024 Carmen Bianca BAKKER # SPDX-FileCopyrightText: 2024 Skyler Grey # SPDX-FileCopyrightText: © 2020 Liferay, Inc. # # SPDX-License-Identifier: GPL-3.0-or-later # pylint: disable=unused-argument,too-many-public-methods """Tests for lint.""" import json import os import shutil from inspect import cleandoc from click.testing import CliRunner from conftest import RESOURCES_DIRECTORY from reuse._util import cleandoc_nl from reuse.cli.main import main from reuse.report import LINT_VERSION class TestLint: """Tests for lint.""" def test_simple(self, fake_repository, 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 = CliRunner().invoke(main, ["lint"]) assert result.exit_code == 0 assert ":-)" in result.output def test_reuse_toml(self, fake_repository_reuse_toml): """Run a simple lint with REUSE.toml.""" result = CliRunner().invoke(main, ["lint"]) assert result.exit_code == 0 assert ":-)" in result.output def test_dep5(self, fake_repository_dep5): """Run a simple lint with .reuse/dep5.""" result = CliRunner().invoke(main, ["lint"]) assert result.exit_code == 0 assert ":-)" in result.output def test_git(self, git_repository): """Run a successful lint.""" result = CliRunner().invoke(main, ["lint"]) assert result.exit_code == 0 assert ":-)" in result.output def test_submodule(self, submodule_repository): """Run a successful lint.""" (submodule_repository / "submodule/foo.c").write_text("foo") result = CliRunner().invoke(main, ["lint"]) assert result.exit_code == 0 assert ":-)" in result.output def test_submodule_included(self, submodule_repository): """Run a successful lint.""" result = CliRunner().invoke(main, ["--include-submodules", "lint"]) assert result.exit_code == 0 assert ":-)" in result.output def test_submodule_included_fail(self, submodule_repository): """Run a failed lint.""" (submodule_repository / "submodule/foo.c").write_text("foo") result = CliRunner().invoke(main, ["--include-submodules", "lint"]) assert result.exit_code == 1 assert ":-(" in result.output def test_meson_subprojects(self, fake_repository): """Verify that subprojects are ignored.""" result = CliRunner().invoke(main, ["lint"]) assert result.exit_code == 0 assert ":-)" in result.output def test_meson_subprojects_fail(self, subproject_repository): """Verify that files in './subprojects' are not ignored.""" # ./subprojects/foo.wrap misses license and linter fails (subproject_repository / "subprojects/foo.wrap").write_text("foo") result = CliRunner().invoke(main, ["lint"]) assert result.exit_code == 1 assert ":-(" in result.output def test_meson_subprojects_included_fail(self, subproject_repository): """When Meson subprojects are included, fail on errors.""" result = CliRunner().invoke( main, ["--include-meson-subprojects", "lint"] ) assert result.exit_code == 1 assert ":-(" in result.output def test_meson_subprojects_included(self, subproject_repository): """Successfully lint when Meson subprojects are included.""" # ./subprojects/libfoo/foo.c has license and linter succeeds (subproject_repository / "subprojects/libfoo/foo.c").write_text( cleandoc( """ SPDX-FileCopyrightText: 2022 Jane Doe SPDX-License-Identifier: GPL-3.0-or-later """ ) ) result = CliRunner().invoke( main, ["--include-meson-subprojects", "lint"] ) assert result.exit_code == 0 assert ":-)" in result.output def test_fail(self, fake_repository): """Run a failed lint.""" (fake_repository / "foo.py").write_text("foo") result = CliRunner().invoke(main, ["lint"]) assert result.exit_code > 0 assert "foo.py" in result.output assert ":-(" in result.output def test_fail_quiet(self, fake_repository): """Run a failed lint.""" (fake_repository / "foo.py").write_text("foo") result = CliRunner().invoke(main, ["lint", "--quiet"]) assert result.exit_code > 0 assert result.output == "" def test_dep5_decode_error(self, fake_repository_dep5): """Display an error if dep5 cannot be decoded.""" shutil.copy( RESOURCES_DIRECTORY / "fsfe.png", fake_repository_dep5 / ".reuse/dep5", ) result = CliRunner().invoke(main, ["lint"]) assert result.exit_code != 0 assert str(fake_repository_dep5 / ".reuse/dep5") in result.output assert "could not be parsed" in result.output assert "'utf-8' codec can't decode byte" in result.output def test_dep5_parse_error(self, fake_repository_dep5, capsys): """Display an error if there's a dep5 parse error.""" (fake_repository_dep5 / ".reuse/dep5").write_text("foo") result = CliRunner().invoke(main, ["lint"]) assert result.exit_code != 0 assert str(fake_repository_dep5 / ".reuse/dep5") in result.output assert "could not be parsed" in result.output def test_toml_parse_error_version(self, fake_repository_reuse_toml, capsys): """If version has the wrong type, print an error.""" (fake_repository_reuse_toml / "REUSE.toml").write_text("version = 'a'") result = CliRunner().invoke(main, ["lint"]) assert result.exit_code != 0 assert str(fake_repository_reuse_toml / "REUSE.toml") in result.output assert "could not be parsed" in result.output def test_toml_parse_error_annotation( self, fake_repository_reuse_toml, capsys ): """If there is an error in an annotation, print an error.""" (fake_repository_reuse_toml / "REUSE.toml").write_text( cleandoc_nl( """ version = 1 [[annotations]] path = 1 """ ) ) result = CliRunner().invoke(main, ["lint"]) assert result.exit_code != 0 assert str(fake_repository_reuse_toml / "REUSE.toml") in result.output assert "could not be parsed" in result.output def test_json(self, fake_repository): """Run a failed lint.""" result = CliRunner().invoke(main, ["lint", "--json"]) output = json.loads(result.output) assert result.exit_code == 0 assert output["lint_version"] == LINT_VERSION assert len(output["files"]) == 8 def test_json_fail(self, fake_repository): """Run a failed lint.""" (fake_repository / "foo.py").write_text("foo") result = CliRunner().invoke(main, ["lint", "--json"]) output = json.loads(result.output) assert result.exit_code > 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_no_file_extension(self, fake_repository): """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 = CliRunner().invoke(main, ["lint"]) assert result.exit_code > 0 assert "Licenses without file extension: CC0-1.0" in result.output assert ":-(" in result.output def test_custom_root(self, fake_repository): """Use a custom root location.""" result = CliRunner().invoke(main, ["--root", "doc", "lint"]) assert result.exit_code > 0 assert "usage.md" in result.output assert ":-(" in result.output def test_custom_root_git(self, git_repository): """Use a custom root location in a git repo.""" result = CliRunner().invoke(main, ["--root", "doc", "lint"]) assert result.exit_code > 0 assert "usage.md" in result.output assert ":-(" in result.output def test_custom_root_different_cwd(self, fake_repository_reuse_toml): """Use a custom root while CWD is different.""" os.chdir("/") result = CliRunner().invoke( main, ["--root", str(fake_repository_reuse_toml), "lint"] ) assert result.exit_code == 0 assert ":-)" in result.output def test_custom_root_is_file(self, fake_repository): """Custom root cannot be a file.""" result = CliRunner().invoke(main, ["--root", ".reuse/dep5", "lint"]) assert result.exit_code != 0 def test_custom_root_not_exists(self, fake_repository): """Custom root must exist.""" result = CliRunner().invoke(main, ["--root", "does-not-exist", "lint"]) assert result.exit_code != 0 def test_no_multiprocessing(self, fake_repository, multiprocessing): """--no-multiprocessing works.""" result = CliRunner().invoke(main, ["--no-multiprocessing", "lint"]) assert result.exit_code == 0 assert ":-)" in result.output reuse-tool-6.2.0/tests/test_download.py0000664000175000017500000001303715077707000016654 0ustar alexalex# 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 unittest.mock import MagicMock 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_download_deprecated(monkeypatch): """Adjust the requested file for deprecated licenses.""" mocked = MagicMock(return_value=MockResponse("hello", 200)) monkeypatch.setattr(urllib.request, "urlopen", mocked) download_license("GPL-3.0") assert "deprecated_GPL-3.0" in mocked.call_args[0][0] 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-6.2.0/tests/test_cli_main.py0000664000175000017500000000214115077707000016612 0ustar alexalex# SPDX-FileCopyrightText: 2023 Carmen Bianca BAKKER # SPDX-FileCopyrightText: 2024 Free Software Foundation Europe e.V. # # SPDX-License-Identifier: GPL-3.0-or-later """Tests for reuse.cli.main.""" from click.testing import CliRunner from reuse import __version__ from reuse.cli.main import main class TestMain: """Collect all tests for main.""" def test_help_is_default(self): """--help is optional.""" without_help = CliRunner().invoke(main, []) with_help = CliRunner().invoke(main, ["--help"]) assert without_help.output == with_help.output assert without_help.exit_code in {0, 2} assert with_help.exit_code == 0 assert with_help.output.startswith("Usage: reuse") def test_version(self): """--version returns the correct version.""" result = CliRunner().invoke(main, ["--version"]) assert result.output.startswith(f"reuse, version {__version__}\n") assert "This program is free software:" in result.output assert "GNU General Public License" in result.output reuse-tool-6.2.0/tests/test_cli_download.py0000664000175000017500000002367515077707000017514 0ustar alexalex# SPDX-FileCopyrightText: 2019 Free Software Foundation Europe e.V. # # SPDX-License-Identifier: GPL-3.0-or-later """Tests for download.""" # pylint: disable=redefined-outer-name,unused-argument,unspecified-encoding import errno import os import shutil from pathlib import Path from unittest.mock import create_autospec from urllib.error import URLError import pytest from click.testing import CliRunner from reuse.cli import download from reuse.cli.main import main # REUSE-IgnoreStart @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 class TestDownload: """Tests for download.""" def test_simple(self, empty_directory, mock_put_license_in_file): """Straightforward test.""" result = CliRunner().invoke(main, ["download", "0BSD"]) assert result.exit_code == 0 mock_put_license_in_file.assert_called_with( "0BSD", Path(os.path.realpath("LICENSES/0BSD.txt")), source=None ) def test_strip_plus(self, empty_directory, mock_put_license_in_file): """If downloading LIC+, download LIC instead.""" result = CliRunner().invoke(main, ["download", "EUPL-1.2+"]) assert result.exit_code == 0 mock_put_license_in_file.assert_called_with( "EUPL-1.2", Path(os.path.realpath("LICENSES/EUPL-1.2.txt")), source=None, ) def test_all(self, fake_repository, mock_put_license_in_file): """--all downloads all detected licenses.""" shutil.rmtree("LICENSES") result = CliRunner().invoke(main, ["download", "--all"]) assert result.exit_code == 0 for lic in [ "GPL-3.0-or-later", "LicenseRef-custom", "Autoconf-exception-3.0", "Apache-2.0", "CC0-1.0", ]: mock_put_license_in_file.assert_any_call( lic, Path(os.path.realpath(f"LICENSES/{lic}.txt")), source=None ) def test_all_with_plus(self, fake_repository, mock_put_license_in_file): """--all downloads EUPL-1.2 if EUPL-1.2+ is detected.""" Path("foo.py").write_text("# SPDX-License-Identifier: EUPL-1.2+") result = CliRunner().invoke(main, ["download", "--all"]) assert result.exit_code == 0 mock_put_license_in_file.assert_called_once_with( "EUPL-1.2", Path(os.path.realpath("LICENSES/EUPL-1.2.txt")), source=None, ) def test_all_with_plus_and_non_plus( self, fake_repository, mock_put_license_in_file ): """If both EUPL-1.2 and EUPL-1.2+ is detected, download EUPL-1.2 only once. """ Path("foo.py").write_text( """ # SPDX-License-Identifier: EUPL-1.2+ # SPDX-License-Identifier: EUPL-1.2 """ ) result = CliRunner().invoke(main, ["download", "--all"]) assert result.exit_code == 0 mock_put_license_in_file.assert_called_once_with( "EUPL-1.2", Path(os.path.realpath("LICENSES/EUPL-1.2.txt")), source=None, ) def test_all_and_license_mutually_exclusive(self, empty_directory): """--all and license args are mutually exclusive.""" result = CliRunner().invoke(main, ["download", "--all", "0BSD"]) assert result.exit_code != 0 assert "are mutually exclusive" in result.output def test_all_and_output_mutually_exclusive(self, empty_directory): """--all and --output are mutually exclusive.""" result = CliRunner().invoke( main, ["download", "--all", "--output", "foo"] ) assert result.exit_code != 0 assert "is mutually exclusive with" in result.output def test_file_exists(self, fake_repository, 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 = CliRunner().invoke(main, ["download", "GPL-3.0-or-later"]) assert result.exit_code == 1 assert "GPL-3.0-or-later.txt already exists" in result.output def test_exception(self, empty_directory, mock_put_license_in_file): """There was an error while downloading the license file.""" mock_put_license_in_file.side_effect = URLError("test") result = CliRunner().invoke(main, ["download", "0BSD"]) assert result.exit_code == 1 assert "internet" in result.output def test_invalid_spdx(self, empty_directory, mock_put_license_in_file): """An invalid SPDX identifier was provided.""" mock_put_license_in_file.side_effect = URLError("test") result = CliRunner().invoke(main, ["download", "does-not-exist"]) assert result.exit_code == 1 assert "not a valid SPDX License Identifier" in result.output def test_custom_output(self, empty_directory, mock_put_license_in_file): """Download the license into a custom file.""" result = CliRunner().invoke(main, ["download", "-o", "foo", "0BSD"]) assert result.exit_code == 0 mock_put_license_in_file.assert_called_with( "0BSD", destination=Path("foo"), source=None ) def test_custom_output_too_many( self, empty_directory, mock_put_license_in_file ): """Providing more than one license with a custom output results in an error. """ result = CliRunner().invoke( main, ["download", "-o", "foo", "0BSD", "GPL-3.0-or-later"], ) assert result.exit_code != 0 assert ( "Cannot use '--output' with more than one license" in result.output ) def test_inside_licenses_dir( self, fake_repository, mock_put_license_in_file ): """While inside the LICENSES/ directory, don't create another LICENSES/ directory. """ os.chdir(fake_repository / "LICENSES") result = CliRunner().invoke(main, ["download", "0BSD"]) assert result.exit_code == 0 mock_put_license_in_file.assert_called_with( "0BSD", destination=Path("0BSD.txt").absolute(), source=None ) def test_inside_licenses_dir_in_git( self, git_repository, 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 = CliRunner().invoke(main, ["download", "0BSD"]) assert result.exit_code == 0 mock_put_license_in_file.assert_called_with( "0BSD", destination=Path("../../LICENSES/0BSD.txt"), source=None ) def test_different_root(self, fake_repository, mock_put_license_in_file): """Download using a different root.""" (fake_repository / "new_root").mkdir() result = CliRunner().invoke( main, [ "--root", str((fake_repository / "new_root").resolve()), "download", "MIT", ], ) assert result.exit_code == 0 mock_put_license_in_file.assert_called_with( "MIT", Path("new_root/LICENSES/MIT.txt").resolve(), source=None ) def test_licenseref_no_source(self, empty_directory): """Downloading a LicenseRef license creates an empty file.""" CliRunner().invoke(main, ["download", "LicenseRef-hello"]) assert ( empty_directory / "LICENSES/LicenseRef-hello.txt" ).read_text() == "" def test_licenseref_source_file( self, empty_directory, ): """Downloading a LicenseRef license with a source file copies that file's contents. """ (empty_directory / "foo.txt").write_text("foo") CliRunner().invoke( main, ["download", "--source", "foo.txt", "LicenseRef-hello"], ) assert ( empty_directory / "LICENSES/LicenseRef-hello.txt" ).read_text() == "foo" def test_licenseref_source_dir(self, empty_directory): """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") CliRunner().invoke( main, ["download", "--source", "lics", "LicenseRef-hello"] ) assert ( empty_directory / "LICENSES/LicenseRef-hello.txt" ).read_text() == "foo" def test_licenseref_false_source_dir(self, empty_directory): """Downloading a LicenseRef license with a source that does not contain the license results in an error. """ (empty_directory / "lics").mkdir() result = CliRunner().invoke( main, ["download", "--source", "lics", "LicenseRef-hello"] ) assert result.exit_code == 1 assert ( f"{Path('lics') / 'LicenseRef-hello.txt'} does not exist" in result.output ) class TestSimilarIdentifiers: """Test a private function _similar_spdx_identifiers.""" # pylint: disable=protected-access def test_typo(self): """Given a misspelt SPDX License Identifier, suggest a better one.""" result = download._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_prefix(self): """Given an incomplete SPDX License Identifier, suggest a better one.""" result = download._similar_spdx_identifiers("CC0") assert "CC0-1.0" in result # REUSE-IgnoreEnd reuse-tool-6.2.0/tests/test_cli_convert_dep5.py0000664000175000017500000000312115077707000020262 0ustar alexalex# SPDX-FileCopyrightText: 2019 Free Software Foundation Europe e.V. # # SPDX-License-Identifier: GPL-3.0-or-later """Tests for convert-dep5.""" import warnings from click.testing import CliRunner from reuse._util import cleandoc_nl from reuse.cli.main import main # pylint: disable=unused-argument class TestConvertDep5: """Tests for convert-dep5.""" def test_simple(self, fake_repository_dep5): """Convert a DEP5 repository to a REUSE.toml repository.""" result = CliRunner().invoke(main, ["convert-dep5"]) assert result.exit_code == 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_no_dep5_file(self, fake_repository): """Cannot convert when there is no .reuse/dep5 file.""" result = CliRunner().invoke(main, ["convert-dep5"]) assert result.exit_code != 0 def test_no_warning(self, fake_repository_dep5): """No PendingDeprecationWarning when running convert-dep5.""" with warnings.catch_warnings(record=True) as caught_warnings: result = CliRunner().invoke(main, ["convert-dep5"]) assert result.exit_code == 0 assert not caught_warnings reuse-tool-6.2.0/tests/test_header.py0000664000175000017500000004062515077707000016300 0ustar alexalex# SPDX-FileCopyrightText: 2019 Free Software Foundation Europe e.V. # SPDX-FileCopyrightText: 2022 Florian Snow # SPDX-FileCopyrightText: 2024 Carmen Bianca BAKKER # SPDX-FileCopyrightText: 2025 Rivos Inc. # # SPDX-License-Identifier: GPL-3.0-or-later """All tests for reuse.header""" from inspect import cleandoc import pytest from reuse.comment import CCommentStyle, CppCommentStyle from reuse.copyright import CopyrightNotice, ReuseInfo, SpdxExpression from reuse.exceptions import MissingReuseInfoError from reuse.header import add_new_header, create_header, find_and_replace_header # REUSE-IgnoreStart def test_create_header_simple(): """Create a super simple header.""" info = ReuseInfo( spdx_expressions={SpdxExpression("GPL-3.0-or-later")}, copyright_notices={ CopyrightNotice.from_string("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( spdx_expressions={SpdxExpression("GPL-3.0-or-later")}, copyright_notices={ CopyrightNotice.from_string("SPDX-FileCopyrightText: Jane Doe") }, contributor_lines={"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( spdx_expressions={SpdxExpression("GPL-3.0-or-later")}, copyright_notices={ CopyrightNotice.from_string("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( spdx_expressions={SpdxExpression("GPL-3.0-or-later")}, copyright_notices={ CopyrightNotice.from_string("SPDX-FileCopyrightText: Jane Doe") }, ) with pytest.raises(MissingReuseInfoError): 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( spdx_expressions={SpdxExpression("GPL-3.0-or-later")}, copyright_notices={ CopyrightNotice.from_string("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( spdx_expressions={SpdxExpression("GPL-3.0-or-later")}, copyright_notices={ CopyrightNotice.from_string("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, do not raise a CommentCreateError. """ info = ReuseInfo( spdx_expressions={SpdxExpression("GPL-3.0-or-later")}, copyright_notices={ CopyrightNotice.from_string("SPDX-FileCopyrightText: Jane Doe") }, ) existing = cleandoc( """ # SPDX-FileCopyrightText: John Doe # # SPDX-License-Identifier: MIT AND OR 0BSD """ ) expected = cleandoc( """ # SPDX-FileCopyrightText: Jane Doe # SPDX-FileCopyrightText: John Doe # # SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: MIT AND OR 0BSD """ ) assert create_header(info, header=existing) == expected def test_create_header_old_syntax(): """Old copyright syntax is preserved when creating a new header.""" info = ReuseInfo(spdx_expressions={SpdxExpression("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(spdx_expressions={SpdxExpression("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( spdx_expressions={SpdxExpression("GPL-3.0-or-later")}, copyright_notices={ CopyrightNotice.from_string("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( spdx_expressions={SpdxExpression("GPL-3.0-or-later")}, copyright_notices={ CopyrightNotice.from_string("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_no_header_with_newline(): """Given text that starts with a newline but no header, add a header.""" info = ReuseInfo( spdx_expressions={SpdxExpression("GPL-3.0-or-later")}, copyright_notices={ CopyrightNotice.from_string("SPDX-FileCopyrightText: Jane Doe") }, ) text = "\npass" 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_no_header_multiple_newlines(): """Given text that starts with multiple newlines but no header, add a header.""" info = ReuseInfo( spdx_expressions={SpdxExpression("GPL-3.0-or-later")}, copyright_notices={ CopyrightNotice.from_string("SPDX-FileCopyrightText: Jane Doe") }, ) text = "\n\npass" 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_verbatim_no_newline(): """Do not add an empty line after existing headers.""" 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_preserve_indentation(): """If the first thing in a file is indented, do not change that thing's indentation. """ info = ReuseInfo( spdx_expressions={SpdxExpression("GPL-3.0-or-later")}, copyright_notices={ CopyrightNotice.from_string("SPDX-FileCopyrightText: Jane Doe") }, ) text = ' # Hello\n print("world")' assert find_and_replace_header(text, info) == cleandoc( """ # SPDX-FileCopyrightText: Jane Doe # # SPDX-License-Identifier: GPL-3.0-or-later # Hello print("world") """ ) def test_find_and_replace_newline_before_header(): """In a scenario where the header is preceded by whitespace, remove the preceding whitespace. """ info = ReuseInfo( spdx_expressions={SpdxExpression("GPL-3.0-or-later")}, copyright_notices={ CopyrightNotice.from_string("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( spdx_expressions={SpdxExpression("GPL-3.0-or-later")}, copyright_notices={ CopyrightNotice.from_string("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(shebang_style): """When encountering a shebang, keep it and put the REUSE header beneath it. """ info = ReuseInfo( spdx_expressions={SpdxExpression("GPL-3.0-or-later")}, copyright_notices={ CopyrightNotice.from_string("SPDX-FileCopyrightText: John Doe") }, ) for shebang in shebang_style.SHEBANGS: text = ( f"{shebang} metadata\n\n" + shebang_style.create_comment("SPDX-FileCopyrightText: Jane Doe") + "\n\npass" ) expected = ( f"{shebang} metadata\n\n" + shebang_style.create_comment( "SPDX-FileCopyrightText: Jane Doe\n" "SPDX-FileCopyrightText: John Doe\n\n" "SPDX-License-Identifier: GPL-3.0-or-later" ) + "\n\npass" ) assert ( find_and_replace_header(text, info, style=shebang_style) == 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(spdx_expressions={SpdxExpression("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(shebang_style): """When the file contains a shebang but no copyright information, keep it at the top of the file. """ info = ReuseInfo(spdx_expressions={SpdxExpression("MIT")}) for shebang in shebang_style.SHEBANGS: text = ( f"{shebang} metadata\n\n" + shebang_style.create_comment("Hello, world!") + "\n\npass" ) expected = ( f"{shebang} metadata\n\n" + shebang_style.create_comment("SPDX-License-Identifier: MIT") + "\n\n" + shebang_style.create_comment("Hello, world!") + "\n\npass" ) assert ( find_and_replace_header(text, info, style=shebang_style) == expected ) def test_find_and_replace_only_shebang(shebang_style): """When the file only contains a shebang, add copyright info below it.""" info = ReuseInfo(spdx_expressions={SpdxExpression("MIT")}) for shebang in shebang_style.SHEBANGS: text = f"{shebang} metadata" expected = ( f"{shebang} metadata\n\n" + shebang_style.create_comment("SPDX-License-Identifier: MIT") + "\n" ) assert ( find_and_replace_header(text, info, style=shebang_style) == expected ) def test_find_and_replace_shebang_wrong_style(shebang_style): """When a shebang is used in a file, but the detected comment style doesn't support that shebang, do not put the shebang first. """ info = ReuseInfo(spdx_expressions={SpdxExpression("MIT")}) for shebang in shebang_style.SHEBANGS: text = f"{shebang} metadata" expected = ( CCommentStyle.create_comment("SPDX-License-Identifier: MIT") + "\n\n" + f"{shebang} metadata" ) assert ( find_and_replace_header(text, info, style=CCommentStyle) == 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( spdx_expressions={SpdxExpression("GPL-3.0-or-later")}, copyright_notices={ CopyrightNotice.from_string("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-6.2.0/tests/test_comment.py0000664000175000017500000003512415077707000016510 0ustar alexalex# SPDX-FileCopyrightText: 2019 Free Software Foundation Europe e.V. # SPDX-FileCopyrightText: 2023 Maxim Cournoyer # # SPDX-License-Identifier: GPL-3.0-or-later """All tests for reuse.comment""" # pylint: disable=protected-access from inspect import cleandoc from textwrap import dedent import pytest from reuse.comment import ( BladeCommentStyle, CommentStyle, CppCommentStyle, HtmlCommentStyle, LispCommentStyle, PythonCommentStyle, get_comment_style, ) from reuse.exceptions import CommentCreateError, CommentParseError def test_create_comment_generic_single(single_style): """Create a comment for all classes that support single-line comments.""" text = "Hello" expected = ( f"{single_style.SINGLE_LINE}{single_style.INDENT_AFTER_SINGLE}Hello" ) assert single_style.create_comment(text) == expected def test_create_comment_generic_multi(multi_style): """Create a comment for all classes that support multi-line comments.""" # pylint: disable=line-too-long text = "Hello" expected = cleandoc( f""" {multi_style.MULTI_LINE.start} {multi_style.INDENT_BEFORE_MIDDLE}{multi_style.MULTI_LINE.middle}{multi_style.INDENT_AFTER_MIDDLE}Hello {multi_style.INDENT_BEFORE_END}{multi_style.MULTI_LINE.end} """ ) assert multi_style.create_comment(text, force_multi=True) == expected def test_parse_comment_generic_single(single_style): """Parse a comment for all classes that support single-line comments.""" text = f"{single_style.SINGLE_LINE}{single_style.INDENT_AFTER_SINGLE}Hello" expected = "Hello" assert single_style.parse_comment(text) == expected def test_parse_comment_generic_multi(multi_style): """Parse a comment for all classes that support multi-line comments.""" # pylint: disable=line-too-long text = cleandoc( f""" {multi_style.MULTI_LINE.start} {multi_style.INDENT_BEFORE_MIDDLE}{multi_style.MULTI_LINE.middle}{multi_style.INDENT_AFTER_MIDDLE}Hello {multi_style.INDENT_BEFORE_END}{multi_style.MULTI_LINE.end} """ ) expected = "Hello" assert multi_style.parse_comment(text) == expected def test_parse_comment_sameline_multi(multi_style): """If a multi-line comment style is on a single line, it should still be parsed. """ text = cleandoc( f""" {multi_style.MULTI_LINE.start} Hello {multi_style.MULTI_LINE.end} """ ) expected = "Hello" assert multi_style.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 def test_get_comment_style(): """Select the right style based on the filename""" assert get_comment_style("foo.php") == CppCommentStyle assert get_comment_style("foo.blade.php") == BladeCommentStyle assert get_comment_style("foo.bar.blade.php") == CppCommentStyle assert get_comment_style("foo.php.blade") is None reuse-tool-6.2.0/tests/test_report.py0000664000175000017500000005472415077707000016370 0ustar alexalex# SPDX-FileCopyrightText: 2017, 2025 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.copyright import SourceType from reuse.project import Project from reuse.report import FileReport, ProjectReport, ProjectSubsetReport # REUSE-IgnoreStart class TestGenerateFileReport: """Tests for FileReport.generate.""" def test_file_simple(self, 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.missing_licenses def test_file_from_different_cwd( self, 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.missing_licenses def test_file_missing_license(self, 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"} def test_file_bad_license(self, 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.missing_licenses == {"fakelicense"} def test_license_contains_plus( self, 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.missing_licenses def test_sorted_copyright(self, empty_directory): """The copyright notices are sorted like CopyrightNotice, not as a string. """ (empty_directory / "foo.py").write_text( cleandoc( """ SPDX-FileCopyrightText: 2019 Alice Copyright Bob © 2017 Jane Doe """ ), encoding="utf-8", ) project = Project.from_directory(empty_directory) result = FileReport.generate(project, "foo.py") assert result.copyright == cleandoc( """ © 2017 Jane Doe SPDX-FileCopyrightText: 2019 Alice Copyright Bob """ ) def test_exception(self, 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.missing_licenses def test_no_licenses(self, 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.missing_licenses def test_multiple_licenses(self, 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.missing_licenses def test_invalid_spdx_expression_add_license_concluded( self, fake_repository, add_license_concluded ): """LicenseConcluded is NOASSERTION if there is an invalid SPDX License Expression. """ (fake_repository / "foo.py").write_text( "SPDX-License-Identifier: MIT OR" ) project = Project.from_directory(fake_repository) result = FileReport.generate( project, "foo.py", add_license_concluded=add_license_concluded, ) assert result.license_concluded == "NOASSERTION" def test_invalid_spdx_expression_not_missing_or_in_file( self, fake_repository, add_license_concluded ): """Invalid SPDX expressions should not also be missing or used licenses. """ (fake_repository / "foo.py").write_text( "SPDX-License-Identifier: " ) project = Project.from_directory(fake_repository) result = FileReport.generate( project, "foo.py", add_license_concluded=add_license_concluded, ) assert "" in result.invalid_spdx_expressions assert "" not in result.missing_licenses assert "" not in result.licenses_in_file def test_to_dict_lint_source_information( self, 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"] == "SPDX-FileCopyrightText: 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" assert expression["is_valid"] def test_dict_to_lint_invalid_spdx_expression(self, fake_repository): """If an SPDX License Expression is invalid, dict_to_lint conveys this information. """ (fake_repository / "foo.py").write_text( "SPDX-License-Identifier: MIT OR" ) project = Project.from_directory(fake_repository) report = FileReport.generate( project, "foo.py", ) result = report.to_dict_lint() assert result["path"] == "foo.py" assert len(result["copyrights"]) == 0 assert len(result["spdx_expressions"]) == 1 expression = result["spdx_expressions"][0] assert expression["value"] == "MIT OR" assert not expression["is_valid"] class TestGenerateProjectReport: """Tests for ProjectReport.generate.""" def test_simple(self, 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_licenses_without_extension(self, 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_missing_license(self, 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_bad_license(self, 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_unused_license(self, 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_unused_license_plus(self, 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_unused_license_plus_only_plus( self, 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_bad_license_can_also_be_missing( self, 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.missing_licenses def test_deprecated_license(self, 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 def test_invalid_spdx_expression_not_missing_or_used( self, fake_repository, multiprocessing ): """Invalid SPDX expressions should not also be missing or used licenses. """ (fake_repository / "foo.py").write_text( "SPDX-License-Identifier: " ) project = Project.from_directory(fake_repository) result = ProjectReport.generate( project, multiprocessing=multiprocessing ) assert fake_repository / "foo.py" in result.invalid_spdx_expressions assert ( "" in result.invalid_spdx_expressions[fake_repository / "foo.py"] ) assert "" not in result.missing_licenses assert "" not in result.used_licenses @cpython @posix def test_read_error(self, 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_to_dict_lint(self, 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_partial_info_in_toml(self, 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 == "SPDX-FileCopyrightText: Jane Doe" assert file_report.licenses_in_file == ["0BSD"] class TestProjectSubsetReport: """Tests for ProjectSubsetReport.""" def test_simple(self, fake_repository, multiprocessing): """Simple generate test.""" project = Project.from_directory(fake_repository) result = ProjectSubsetReport.generate( project, {fake_repository / "src/custom.py"}, multiprocessing=multiprocessing, ) assert not result.missing_licenses assert not result.read_errors assert not result.files_without_licenses assert not result.files_without_copyright assert len(result.file_reports) == 1 @cpython @posix def test_read_error(self, 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 = ProjectSubsetReport.generate( project, {fake_repository / "bad"}, multiprocessing=multiprocessing ) # pylint: disable=superfluous-parens assert (fake_repository / "bad") in result.read_errors def test_missing_license(self, fake_repository, multiprocessing): """Missing licenses are detected.""" (fake_repository / "LICENSES/GPL-3.0-or-later.txt").unlink() project = Project.from_directory(fake_repository) result = ProjectSubsetReport.generate( project, {fake_repository / "src/exception.py"}, multiprocessing=multiprocessing, ) assert result.missing_licenses == { "GPL-3.0-or-later": {fake_repository / "src/exception.py"} } def test_missing_copyright_license(self, empty_directory, multiprocessing): """Missing copyright and license is detected.""" (empty_directory / "foo.py").write_text("foo") project = Project.from_directory(empty_directory) result = ProjectSubsetReport.generate( project, {empty_directory / "foo.py"}, multiprocessing=multiprocessing, ) # pylint: disable=superfluous-parens assert (empty_directory / "foo.py") in result.files_without_copyright assert (empty_directory / "foo.py") in result.files_without_licenses 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-6.2.0/tests/test_project.py0000664000175000017500000006262415077707000016521 0ustar alexalex# SPDX-FileCopyrightText: 2017 Free Software Foundation Europe e.V. # SPDX-FileCopyrightText: 2022 Florian Snow # SPDX-FileCopyrightText: 2023 Carmen Bianca BAKKER # SPDX-FileCopyrightText: 2024 Skyler Grey # SPDX-FileCopyrightText: © 2020 Liferay, Inc. # SPDX-FileCopyrightText: 2024 Linnea Gräf # # 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 from unittest import mock import pytest from conftest import RESOURCES_DIRECTORY from reuse.copyright import ( CopyrightNotice, ReuseInfo, SourceType, SpdxExpression, ) from reuse.covered_files import iter_files from reuse.exceptions import ( GlobalLicensingConflictError, GlobalLicensingParseError, ) from reuse.global_licensing import ReuseDep5, ReuseTOML from reuse.project import 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() shutil.copy(RESOURCES_DIRECTORY / "dep5", empty_directory / ".reuse/dep5") with pytest.raises(GlobalLicensingConflictError): Project.from_directory(empty_directory) class TestProjectAllFiles: """Test Project.all_files.""" def test_with_mock(self, monkeypatch, empty_directory): """Instead of testing the entire behaviour, just test that a mock is called and its value is returned. """ mock_iter_files = mock.create_autospec(iter_files) mock_iter_files.return_value = "foo" monkeypatch.setattr("reuse.project.iter_files", mock_iter_files) project = Project.from_directory(empty_directory) result = project.all_files(empty_directory) assert result == "foo" mock_iter_files.assert_called_once_with( empty_directory, include_submodules=project.include_submodules, include_meson_subprojects=project.include_meson_subprojects, vcs_strategy=project.vcs_strategy, ) def test_with_mock_implicit_dir(self, monkeypatch, empty_directory): """If no argument is given to Project.iter_files, project.root is implied. """ mock_iter_files = mock.create_autospec(iter_files) mock_iter_files.return_value = "foo" monkeypatch.setattr("reuse.project.iter_files", mock_iter_files) project = Project.from_directory(empty_directory) result = project.all_files() assert result == "foo" mock_iter_files.assert_called_once_with( empty_directory, include_submodules=project.include_submodules, include_meson_subprojects=project.include_meson_subprojects, vcs_strategy=project.vcs_strategy, ) def test_with_mock_includes(self, monkeypatch, empty_directory): """include_submodules and include_meson_subprojects are true.""" mock_iter_files = mock.create_autospec(iter_files) mock_iter_files.return_value = "foo" monkeypatch.setattr("reuse.project.iter_files", mock_iter_files) project = Project.from_directory( empty_directory, include_submodules=True, include_meson_subprojects=True, ) result = project.all_files() assert result == "foo" mock_iter_files.assert_called_once_with( empty_directory, include_submodules=project.include_submodules, include_meson_subprojects=project.include_meson_subprojects, vcs_strategy=project.vcs_strategy, ) 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_notices 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_notices) == 1 assert reuse_info.copyright_notices.pop() == CopyrightNotice.from_string( "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 SpdxExpression("CC0-1.0") in reuse_info.spdx_expressions assert ( CopyrightNotice.from_string("SPDX-FileCopyrightText: 2017 Jane Doe") in reuse_info.copyright_notices ) 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 SpdxExpression("MIT") in reuse_info.spdx_expressions assert ( CopyrightNotice.from_string("SPDX-FileCopyrightText: In File") in reuse_info.copyright_notices ) 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 SpdxExpression("CC0-1.0") in reuse_info.spdx_expressions assert ( CopyrightNotice.from_string("SPDX-FileCopyrightText: 2017 Jane Doe") in reuse_info.copyright_notices ) 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 SpdxExpression("MIT") in reuse_info.spdx_expressions assert ( CopyrightNotice.from_string("SPDX-FileCopyrightText: In File") in reuse_info.copyright_notices ) elif reuse_info.source_type == SourceType.REUSE_TOML: assert reuse_info.source_path == "REUSE.toml" assert reuse_info.path == "foo.py" assert SpdxExpression("CC0-1.0") in reuse_info.spdx_expressions assert ( CopyrightNotice.from_string( "SPDX-FileCopyrightText: 2017 Jane Doe" ) in reuse_info.copyright_notices ) 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={SpdxExpression("CC0-1.0")}, copyright_notices={ CopyrightNotice.from_string( "SPDX-FileCopyrightText: 2017 Jane Doe" ) }, path="src/foo.py", source_path="REUSE.toml", source_type=SourceType.REUSE_TOML, ), ReuseInfo( spdx_expressions={SpdxExpression("MIT")}, copyright_notices={ CopyrightNotice.from_string( "SPDX-FileCopyrightText: 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={SpdxExpression("CC0-1.0")}, copyright_notices={ CopyrightNotice.from_string( "SPDX-FileCopyrightText: 2017 Jane Doe" ) }, path="src/foo.py", source_path="REUSE.toml", source_type=SourceType.REUSE_TOML, ), ReuseInfo( spdx_expressions={SpdxExpression("0BSD")}, copyright_notices={ CopyrightNotice.from_string("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_notices][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_notices 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_notices bar_file_info = [info for info in bar_infos if info.copyright_notices][0] assert bar_file_info.source_type == SourceType.FILE_HEADER assert not bar_file_info.spdx_expressions def test_reuse_info_of_reuse_toml_dot_license(empty_directory): """Test a corner case where there is REUSE information inside of a file, its .license file, and REUSE.toml. Only the REUSE information from the .license file and REUSE.toml should be applied to this file. """ (empty_directory / "REUSE.toml").write_text( cleandoc( """ version = 1 [[annotations]] path = "*.py" precedence = "aggregate" SPDX-FileCopyrightText = "2017 Jane Doe" SPDX-License-Identifier = "CC0-1.0" """ ) ) (empty_directory / "foo.py").write_text( cleandoc( """ SPDX-FileCopyrightText: NONE """ ) ) (empty_directory / "foo.py.license").write_text( cleandoc( """ SPDX-FileCopyrightText: 2017 John Doe """ ) ) project = Project.from_directory(empty_directory) infos = project.reuse_info_of("foo.py") assert len(infos) == 2 toml_info = [info for info in infos if info.spdx_expressions][0] assert toml_info.source_type == SourceType.REUSE_TOML assert ( CopyrightNotice.from_string("SPDX-FileCopyrightText: 2017 Jane Doe") in toml_info.copyright_notices ) assert "CC0-1.0" in str(toml_info.spdx_expressions) dot_license_info = [info for info in infos if not info.spdx_expressions][0] assert dot_license_info.source_type == SourceType.DOT_LICENSE assert ( CopyrightNotice.from_string("SPDX-FileCopyrightText: 2017 John Doe") in dot_license_info.copyright_notices ) assert not dot_license_info.spdx_expressions def test_reuse_info_of_dot_license_invalid_target(empty_directory): """file.license is an invalid target in REUSE.toml.""" (empty_directory / "REUSE.toml").write_text( cleandoc( """ version = 1 [[annotations]] path = "foo.py.license" SPDX-FileCopyrightText = "2017 Jane Doe" SPDX-License-Identifier = "CC0-1.0" """ ) ) (empty_directory / "foo.py").write_text( cleandoc( """ SPDX-FileCopyrightText: 2017 John Doe SPDX-License-Identifier: MIT """ ) ) (empty_directory / "foo.py.license").write_text( cleandoc( """ Empty """ ) ) project = Project.from_directory(empty_directory) infos = project.reuse_info_of("foo.py") assert len(infos) == 0 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 SpdxExpression("GPL-3.0-or-later") in reuse_info.spdx_expressions assert len(reuse_info.copyright_notices) == 1 assert ( CopyrightNotice.from_string( "SPDX-FileCopyrightText: 2017 Free Software Foundation Europe" ) in reuse_info.copyright_notices ) 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 SpdxExpression("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 ( CopyrightNotice.from_string("SPDX-FileCopyrightText: 2017 Jane Doe") in reuse_info.copyright_notices ) assert SpdxExpression("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 len(result) == 1 dep5 = result[0] assert dep5.path == fake_repository_dep5 / ".reuse/dep5" assert dep5.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 len(result) == 1 toml = result[0] assert toml.path == fake_repository_reuse_toml / "REUSE.toml" assert toml.cls == ReuseTOML def test_find_global_licensing_reuse_toml_multiple(fake_repository_reuse_toml): """Find multiple REUSE.tomls.""" (fake_repository_reuse_toml / "src/REUSE.toml").write_text("version = 1") result = Project.find_global_licensing(fake_repository_reuse_toml) assert len(result) == 2 assert result[0].path == fake_repository_reuse_toml / "REUSE.toml" assert result[1].path == fake_repository_reuse_toml / "src/REUSE.toml" def test_find_global_licensing_none(empty_directory): """Find no file.""" result = Project.find_global_licensing(empty_directory) assert not result def test_find_global_licensing_conflict(fake_repository_dep5): """Expect an error on a conflict""" (fake_repository_dep5 / "REUSE.toml").write_text("version = 1") with pytest.raises(GlobalLicensingConflictError): 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-6.2.0/tests/test_convert_dep5.py0000664000175000017500000002026515077707000017443 0ustar alexalex# 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-6.2.0/tests/test_global_licensing.py0000664000175000017500000012575415077707000020352 0ustar alexalex# 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 reuse.copyright import ( CopyrightNotice, ReuseInfo, SourceType, SpdxExpression, ) from reuse.exceptions import ( GlobalLicensingParseError, GlobalLicensingParseTypeError, GlobalLicensingParseValueError, ) from reuse.global_licensing import ( AnnotationsItem, NestedReuseTOML, PrecedenceType, ReuseDep5, ReuseTOML, ) from reuse.vcs import VCSStrategyGit # 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_notices == { CopyrightNotice.from_string("SPDX-FileCopyrightText: 2023 Jane Doe") } assert item.spdx_expressions == {SpdxExpression("MIT")} def test_precedence_defaults_to_closest(self): """If precedence is NOTHING, default to closest.""" item = AnnotationsItem( {"foo.py"}, copyright_notices={"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_notices == { CopyrightNotice.from_string("SPDX-FileCopyrightText: 2023 Jane Doe") } assert item.spdx_expressions == {SpdxExpression("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_notices == { CopyrightNotice.from_string("SPDX-FileCopyrightText: 2023 Jane Doe") } assert item.spdx_expressions == {SpdxExpression("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_copyright_not_str(self): """Copyright must be a string.""" with pytest.raises(GlobalLicensingParseTypeError): AnnotationsItem( {"foo.py"}, copyright_notices=123, ) def test_copyright_not_set_of_str(self): """Copyright must be a set of strings.""" with pytest.raises(GlobalLicensingParseTypeError): AnnotationsItem( {"foo.py"}, copyright_notices={"2023 Jane Doe", 2024}, ) def test_copyright_already_prefixed(self): """If a notice is prefixed within the string, do not prepend the default SPDX prefix. """ item = AnnotationsItem( "foo.py", copyright_notices={"2023 Jane Doe", "Copyright Alice"}, ) assert item.copyright_notices == { CopyrightNotice.from_string( "SPDX-FileCopyrightText: 2023 Jane Doe" ), CopyrightNotice.from_string("Copyright Alice"), } def test_expression_not_str(self): """SPDX expression must be a string.""" with pytest.raises(GlobalLicensingParseTypeError): AnnotationsItem( {"foo.py"}, spdx_expressions=123, ) def test_expression_not_set_of_str(self): """SPDX expression must be a set of strings.""" with pytest.raises(GlobalLicensingParseTypeError): AnnotationsItem( {"foo.py"}, spdx_expressions={"MIT", 123}, ) 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_notices == { CopyrightNotice.from_string("SPDX-FileCopyrightText: 2023 Jane Doe") } assert item.spdx_expressions == {SpdxExpression("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_notices assert isinstance(item.copyright_notices, 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_notices 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_asterisk_slash(self): """Handle asterisk slash.""" item = AnnotationsItem(paths=[r"*/file"]) assert item.matches("foo/file") 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") assert not 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) as exc_info: ReuseTOML( version=1.2, # type: ignore[arg-type] source="REUSE.toml", annotations=[annotations_item], ) assert exc_info.value.source == "REUSE.toml" def test_source_not_str(self, annotations_item): """Source must be a str.""" with pytest.raises(GlobalLicensingParseTypeError) as exc_info: ReuseTOML( version=1, source=123, # type: ignore[arg-type] annotations=[annotations_item], ) assert exc_info.value.source == 123 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) as exc_info: ReuseTOML( version=1, source="REUSE.toml", annotations=iter([annotations_item]), # type: ignore[arg-type] ) assert exc_info.value.source == "REUSE.toml" def test_annotations_must_be_object(self): """Annotations must be AnnotationsItem objects.""" with pytest.raises(GlobalLicensingParseTypeError) as exc_info: ReuseTOML( version=1, source="REUSE.toml", annotations=[{"foo": "bar"}], # type: ignore[list-item] ) assert exc_info.value.source == "REUSE.toml" 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", ) def test_annotations_error(self): """If there is an error in the annotations, the error get ReuseTOML's source. """ with pytest.raises(GlobalLicensingParseTypeError) as exc_info: ReuseTOML.from_dict( { "version": 1, "annotations": [ { "path": {1}, } ], }, "REUSE.toml", ) assert exc_info.value.source == "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={SpdxExpression("MIT")}, copyright_notices={ CopyrightNotice.from_string( "SPDX-FileCopyrightText: 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_notices={"2023 John Doe"}, spdx_expressions={"0BSD"}, ), ], ) assert reuse_toml.reuse_info_of("foo.py") == { PrecedenceType.OVERRIDE: [ ReuseInfo( spdx_expressions={SpdxExpression("0BSD")}, copyright_notices={ CopyrightNotice.from_string( "SPDX-FileCopyrightText: 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_notices={"2023 Jane Doe"}, spdx_expressions={"MIT"}, ), ], ) # Expected sans path expected = ReuseInfo( spdx_expressions={SpdxExpression("MIT")}, copyright_notices={ CopyrightNotice.from_string( "SPDX-FileCopyrightText: 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_notices={"2023 Jane Doe"}, spdx_expressions={"MIT"}, ), ], ) assert reuse_toml.reuse_info_of("dir/foo.py") == { PrecedenceType.OVERRIDE: [ ReuseInfo( spdx_expressions={SpdxExpression("MIT")}, copyright_notices={ CopyrightNotice.from_string( "SPDX-FileCopyrightText: 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.write_text("version = 1") 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").write_text( "version = 1" ) 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", } def test_with_vcs_strategy(self, git_repository): """Ignore the correct files ignored by the repository.""" (git_repository / "REUSE.toml").write_text("version = 1") (git_repository / "build/REUSE.toml").write_text("version =1") (git_repository / "src/REUSE.toml").write_text("version = 1") result = NestedReuseTOML.find_reuse_tomls( git_repository, vcs_strategy=VCSStrategyGit(git_repository) ) assert set(result) == { git_repository / "REUSE.toml", git_repository / "src/REUSE.toml", } def test_includes_submodule(self, submodule_repository): """include_submodules is correctly implemented.""" (submodule_repository / "REUSE.toml").write_text("version = 1") (submodule_repository / "submodule/REUSE.toml").write_text( "version = 1" ) result_without = NestedReuseTOML.find_reuse_tomls( submodule_repository, vcs_strategy=VCSStrategyGit(submodule_repository), ) assert set(result_without) == {submodule_repository / "REUSE.toml"} result_with = NestedReuseTOML.find_reuse_tomls( submodule_repository, include_submodules=True, vcs_strategy=VCSStrategyGit(submodule_repository), ) assert set(result_with) == { submodule_repository / "REUSE.toml", submodule_repository / "submodule/REUSE.toml", } def test_includes_meson_subprojects(self, subproject_repository): """include_meson_subprojects is correctly implemented.""" (subproject_repository / "REUSE.toml").write_text("version = 1") (subproject_repository / "subprojects/REUSE.toml").write_text( "version = 1" ) (subproject_repository / "subprojects/libfoo/REUSE.toml").write_text( "version = 1" ) result_without = NestedReuseTOML.find_reuse_tomls(subproject_repository) assert set(result_without) == { subproject_repository / "REUSE.toml", subproject_repository / "subprojects/REUSE.toml", } result_with = NestedReuseTOML.find_reuse_tomls( subproject_repository, include_meson_subprojects=True ) assert set(result_with) == { subproject_repository / "REUSE.toml", subproject_repository / "subprojects/REUSE.toml", subproject_repository / "subprojects/libfoo/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={SpdxExpression("MIT")}, copyright_notices={ CopyrightNotice.from_string( "SPDX-FileCopyrightText: 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_notices={"Copyright Jane Doe"}, spdx_expressions={"MIT"}, ) ], ) inner = ReuseTOML( "src/REUSE.toml", 1, [ AnnotationsItem( "foo.py", precedence=PrecedenceType.CLOSEST, copyright_notices={"Copyright Alice"}, spdx_expressions={"0BSD"}, ) ], ) toml = NestedReuseTOML(".", [outer, inner]) assert toml.reuse_info_of("src/foo.py") == { PrecedenceType.CLOSEST: [ ReuseInfo( spdx_expressions={SpdxExpression("0BSD")}, copyright_notices={ CopyrightNotice.from_string("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={SpdxExpression("MIT")}, copyright_notices={ CopyrightNotice.from_string("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_notices={"Copyright Jane Doe"}, spdx_expressions={"MIT"}, ) ], ) inner = ReuseTOML( "src/REUSE.toml", 1, [ AnnotationsItem( "foo.py", precedence=PrecedenceType.CLOSEST, copyright_notices={"Copyright Alice"}, spdx_expressions={"0BSD"}, ) ], ) toml = NestedReuseTOML(".", [outer, inner]) assert toml.reuse_info_of("src/foo.py") == { PrecedenceType.AGGREGATE: [ ReuseInfo( spdx_expressions={SpdxExpression("MIT")}, copyright_notices={ CopyrightNotice.from_string("Copyright Jane Doe") }, path="src/foo.py", source_path="REUSE.toml", source_type=SourceType.REUSE_TOML, ) ], PrecedenceType.CLOSEST: [ ReuseInfo( spdx_expressions={SpdxExpression("0BSD")}, copyright_notices={ CopyrightNotice.from_string("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_notices={"Copyright Jane Doe"}, spdx_expressions={"MIT"}, ) ], ) inner = ReuseTOML( "src/REUSE.toml", 1, [ AnnotationsItem( "foo.py", precedence=PrecedenceType.CLOSEST, copyright_notices={"Copyright Alice"}, spdx_expressions={"0BSD"}, ) ], ) toml = NestedReuseTOML(".", [outer, inner]) assert toml.reuse_info_of("src/foo.py") == { PrecedenceType.OVERRIDE: [ ReuseInfo( spdx_expressions={SpdxExpression("MIT")}, copyright_notices={ CopyrightNotice.from_string("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_notices={"Copyright Jane Doe"}, spdx_expressions={"MIT"}, ) ], ) mid = ReuseTOML( "foo/REUSE.toml", 1, [ AnnotationsItem( "bar/**", precedence=PrecedenceType.OVERRIDE, copyright_notices={"Copyright Alice"}, spdx_expressions={"0BSD"}, ) ], ) inner = ReuseTOML( "foo/bar/REUSE.toml", 1, [ AnnotationsItem( "foo.py", precedence=PrecedenceType.OVERRIDE, copyright_notices={"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={SpdxExpression("MIT")}, copyright_notices={ CopyrightNotice.from_string("Copyright Jane Doe") }, path="foo/bar/foo.py", source_path="REUSE.toml", source_type=SourceType.REUSE_TOML, ), ], PrecedenceType.OVERRIDE: [ ReuseInfo( spdx_expressions={SpdxExpression("0BSD")}, copyright_notices={ CopyrightNotice.from_string("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_notices={"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_notices={"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_notices={"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(GlobalLicensingParseError) as exc_info: ReuseDep5.from_file(fake_repository_dep5 / "fsfe.png") error = exc_info.value assert error.source == str(fake_repository_dep5 / "fsfe.png") assert "'utf-8' codec can't decode byte" in str(error) def test_parse_error(self, empty_directory): """Raise GlobalLicensingParseError on parse error.""" (empty_directory / "foo").write_text("foo") with pytest.raises(GlobalLicensingParseError) as exc_info: ReuseDep5.from_file(empty_directory / "foo") error = exc_info.value assert error.source == str(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) as exc_info: ReuseDep5.from_file(empty_directory / "foo") error = exc_info.value assert error.source == str(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 SpdxExpression("CC0-1.0") in result.spdx_expressions assert ( CopyrightNotice.from_string("SPDX-FileCopyrightText: 2017 Jane Doe") in result.copyright_notices ) # REUSE-IgnoreEnd reuse-tool-6.2.0/tests/test_cli_lint_file.py0000664000175000017500000000474015077707000017642 0ustar alexalex# SPDX-FileCopyrightText: 2024 Free Software Foundation Europe e.V. # # SPDX-License-Identifier: GPL-3.0-or-later """Tests for lint-file.""" # pylint: disable=unused-argument from click.testing import CliRunner from reuse.cli.main import main class TestLintFile: """Tests for lint-file.""" def test_simple(self, fake_repository): """A simple test to make sure it works.""" result = CliRunner().invoke(main, ["lint-file", "src/custom.py"]) assert result.exit_code == 0 assert not result.output def test_quiet_lines_mutually_exclusive(self, empty_directory): """'--quiet' and '--lines' are mutually exclusive.""" (empty_directory / "foo.py").write_text("foo") result = CliRunner().invoke( main, ["lint-file", "--quiet", "--lines", "foo"] ) assert result.exit_code != 0 assert "mutually exclusive" in result.output def test_no_copyright_licensing(self, fake_repository): """A file is correctly spotted when it has no copyright or licensing info. """ (fake_repository / "foo.py").write_text("foo") result = CliRunner().invoke(main, ["lint-file", "foo.py"]) assert result.exit_code == 1 output = result.output assert "foo.py" in output assert "no license identifier" in output assert "no copyright notice" in output def test_path_outside_project(self, empty_directory): """A file can't be outside the project.""" result = CliRunner().invoke(main, ["lint-file", ".."]) assert result.exit_code != 0 assert "'..' is not in" in result.output def test_file_not_exists(self, empty_directory): """A file must exist.""" result = CliRunner().invoke(main, ["lint-file", "foo.py"]) assert "'foo.py' does not exist" in result.output def test_ignored_file(self, fake_repository): """A corner case where a specified file is ignored. It isn't checked at all. """ (fake_repository / "COPYING").write_text("foo") result = CliRunner().invoke(main, ["lint-file", "COPYING"]) assert result.exit_code == 0 def test_file_covered_by_toml(self, fake_repository_reuse_toml): """If a file is covered by REUSE.toml, use its infos.""" (fake_repository_reuse_toml / "doc/foo.md").write_text("foo") result = CliRunner().invoke(main, ["lint-file", "doc/foo.md"]) assert result.exit_code == 0 reuse-tool-6.2.0/tests/test_extract.py0000664000175000017500000006521015077707000016517 0ustar alexalex# 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.extract""" import logging import os import subprocess import sys from inspect import cleandoc from io import BytesIO import pytest from conftest import RESOURCES_DIRECTORY, chardet from reuse.copyright import ( CopyrightNotice, CopyrightPrefix, ReuseInfo, SpdxExpression, ) from reuse.exceptions import NoEncodingModuleError from reuse.extract import ( contains_reuse_info, detect_encoding, detect_newline, extract_reuse_info, filter_ignore_block, get_encoding_module, reuse_info_of_file, set_encoding_module, ) _IGNORE_END = "REUSE-IgnoreEnd" # REUSE-IgnoreStart class TestExtractReuseInfo: """Tests for extract_reuse_info.""" def test_expression(self): """Parse various expressions.""" expressions = ["GPL-3.0+", "GPL-3.0 AND CC0-1.0", "nonsense"] for expression in expressions: result = extract_reuse_info( f"SPDX-License-Identifier: {expression}" ) assert result.spdx_expressions == {SpdxExpression(expression)} @pytest.mark.parametrize( "art", [ cleandoc( r""" /**********************************\ |* SPDX-License-Identifier: MIT *| \**********************************/ """ ), cleandoc( """ ////////////////////////////////// // SPDX-License-Identifier: MIT // ////////////////////////////////// """ ), cleandoc( """ ################################ # SPDX-License-Identifier: MIT # ################################ """ ), # Technically not art, but uses the same prefix-suffix mechanism. '"SPDX-License-Identifier: MIT"', ], ) def test_expression_from_ascii_art_frame(self, art): """Parse an expression from an ASCII art frame. See #343 and #1248 for real-world examples. """ result = extract_reuse_info(art) assert result.spdx_expressions == {SpdxExpression("MIT")} def test_erroneous_expression(self): """Parse an incorrect expression.""" expression = "GPL-3.0-or-later AND (MIT OR)" text = f"SPDX-License-Identifier: {expression}" result = extract_reuse_info(text) expected_expression = SpdxExpression(expression) assert result.spdx_expressions == {expected_expression} assert not expected_expression.is_valid def test_no_info(self): """Given a string without REUSE information, return an empty ReuseInfo object. """ result = extract_reuse_info("") assert result == ReuseInfo() def test_tab(self): """A tag followed by a tab is also valid.""" result = extract_reuse_info("SPDX-License-Identifier:\tMIT") assert result.spdx_expressions == {SpdxExpression("MIT")} def test_many_whitespace(self): """When a tag is followed by a lot of whitespace, the whitespace should be filtered out. """ result = extract_reuse_info("SPDX-License-Identifier: MIT") assert result.spdx_expressions == {SpdxExpression("MIT")} def test_bibtex_comment(self): """A special case for BibTex comments.""" expression = "@Comment{SPDX-License-Identifier: GPL-3.0-or-later}" result = extract_reuse_info(expression) assert str(list(result.spdx_expressions)[0]) == "GPL-3.0-or-later" def test_copyright(self): """Given a file with copyright information, have it return that copyright information. """ notice = "SPDX-FileCopyrightText: 2019 Jane Doe" result = extract_reuse_info(notice) assert result.copyright_notices == {CopyrightNotice.from_string(notice)} def test_copyright_duplicate(self): """When a copyright line is duplicated, only yield one.""" notice = "SPDX-FileCopyrightText: 2019 Jane Doe" result = extract_reuse_info("\n".join((notice, notice))) assert result.copyright_notices == {CopyrightNotice.from_string(notice)} def test_copyright_tab(self): """A tag followed by a tab is also valid.""" notice = "SPDX-FileCopyrightText:\t2019 Jane Doe" result = extract_reuse_info(notice) assert result.copyright_notices == {CopyrightNotice.from_string(notice)} def test_copyright_many_whitespace(self): """When a tag is followed by a lot of whitespace, that is also valid. The whitespace is not filtered out. """ notice = "SPDX-FileCopyrightText: 2019 Jane Doe" result = extract_reuse_info(notice) assert result.copyright_notices == {CopyrightNotice.from_string(notice)} def test_copyright_variations(self): """There are multiple ways to declare copyright. All should be detected. """ text = cleandoc( """ SPDX-FileCopyrightText: 2019 spdx SPDX-FileCopyrightText: (C) 2019 spdx-c SPDX-FileCopyrightText: © 2019 spdx-symbol SPDX-FileCopyrightText: Copyright (C) 2019 spdx-string-c SPDX-FileCopyrightText: Copyright © 2019 spdx-string-symbol Copyright 2019 string Copyright (C) 2019 string-c Copyright © 2019 string-symbol © 2019 symbol """ ) result = extract_reuse_info(text) lines = text.splitlines() for line in lines: assert CopyrightNotice.from_string(line) in result.copyright_notices assert len(lines) == len(result.copyright_notices) def test_sameline_multiline(self): """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 = extract_reuse_info(text) assert len(result.copyright_notices) == 1 assert result.copyright_notices == { CopyrightNotice.from_string("SPDX-FileCopyrightText: Jane Doe") } def test_special_endings(self): """Strip some non-comment-style endings from the end of copyright and licensing information. """ text = cleandoc( """ [Copyright 2019 Ajnulo] :: """ ) result = extract_reuse_info(text) for item in result.copyright_notices: assert ">" not in str(item) assert "] ::" not in str(item) def test_special_ending_with_spacing_after(self): """Strip spacing after a special ending.""" text = " \t" result = extract_reuse_info(text) assert result.copyright_notices == { CopyrightNotice.from_string("Copyright 2019 Jane Doe") } def test_contributors(self): """Correctly extract SPDX-FileContributor information from text.""" text = cleandoc( """ # SPDX-FileContributor: Jane Doe """ ) result = extract_reuse_info(text) assert result.contributor_lines == {"Jane Doe"} @pytest.mark.usefixtures("encoding_module") class TestDetectEncoding: """Tests for detect_encoding.""" @pytest.mark.parametrize( "encoding", [ "utf_8", "utf_8_sig", "utf_16", "utf_32", "iso8859_1", ], ) def test_simple(self, encoding): """Given some text, correctly detect the decoding.""" text = cleandoc( """ # Copyright © 1911 Émile Verhaeren Si nos coeurs ont brûlé en des jours exaltants D'une amour claire autant que haute, L'âge aujourd'hui nous fait lâches et indulgents Et paisibles devant nos fautes. Tu ne nous grandis plus, ô jeune volonté, Par ton ardeur non asservie, Et c'est de calme doux et de pâle bonté Que se colore notre vie. Nous sommes au couchant de ton soleil, amour, Et nous masquons notre faiblesse Avec les mots banals et les pauvres discours D'une vaine et lente sagesse. Oh ! que nous serait triste et honteux l'avenir, Si dans notre hiver et nos brumes N'éclatait point, tel un flambeau, le souvenir Des âmes fières que nous fûmes. """ ) encoded = text.encode(encoding) result = detect_encoding(encoded) if encoding != "iso8859_1": assert result == encoding else: # A special case where cp1252 is a superset of iso8859_1. assert result in ["iso8859_1", "cp1252"] assert encoded.decode(result) == text def test_binary(self): """A binary file has no encoding.""" with open(RESOURCES_DIRECTORY / "fsfe.png", "rb") as fp: assert detect_encoding(fp.read()) is None def test_never_ascii(self): """When something could be encoded in ASCII, expect UTF-8 instead.""" text = cleandoc( """ Beautiful is better than ugly. Explicit is better than implicit. Simple is better than complex. Complex is better than complicated. Flat is better than nested. Sparse is better than dense. Readability counts. Special cases aren't special enough to break the rules. Although practicality beats purity. Errors should never pass silently. Unless explicitly silenced. In the face of ambiguity, refuse the temptation to guess. There should be one-- and preferably only one --obvious way to do it Although that way may not be obvious at first unless you're Dutch. Now is better than never. Although never is often better than *right* now. If the implementation is hard to explain, it's a bad idea. If the implementation is easy to explain, it may be a good idea. Namespaces are one honking great idea -- let's do more of those! """ ).encode("ascii") assert detect_encoding(text) == "utf_8" def test_empty_is_utf_8(self): """An empty file is assumed to be encoded UTF-8.""" assert detect_encoding(b"") == "utf_8" def test_encoding_no_encoding_module(self, monkeypatch): """This should never happen because it would fail on import, but expect an error if no encoding module is available. """ monkeypatch.setattr("reuse.extract._ENCODING_MODULE", None) with pytest.raises(NoEncodingModuleError): detect_encoding(b"Hello, world!") class TestReuseInfoOfFile: """Tests for reuse_info_of_file.""" def test_with_ignore_block(self): """Ensure that the copyright and licensing information inside the ignore block is actually ignored. """ buffer = BytesIO( cleandoc( f""" 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 {_IGNORE_END} SPDX-FileCopyrightText: 2019 Eve """ ).encode("utf-8") ) result = reuse_info_of_file(buffer, chunk_size=10) assert len(result.copyright_notices) == 2 assert len(result.spdx_expressions) == 1 def test_different_buffer(self): """Even with a very small buffer, the entire file is correctly read and parsed. """ buffer = BytesIO( cleandoc( """ SPDX-FileCopyrightText: 2019 Jane Doe SPDX-FileCopyrightText: 2019 John Doe SPDX-FileCopyrightText: 2019 Eve SPDX-License-Identifier: GPL-3.0-or-later SPDX-License-Identifier: CC0-1.0 """ ).encode("utf-8") ) result = reuse_info_of_file(buffer, chunk_size=5, line_size=50) assert len(result.copyright_notices) == 3 assert len(result.spdx_expressions) == 2 def test_too_small_line_size(self): """If the line is too long (or line_size too small), then some lines won't be correctly parsed. """ buffer = BytesIO(b"Copyright Jane Doe") result = reuse_info_of_file(buffer, chunk_size=10, line_size=4) assert result.copyright_notices == { CopyrightNotice("Jane", prefix=CopyrightPrefix.STRING) } def test_binary(self, caplog): """If the file is a binary, return an empty ReuseInfo and log.""" caplog.set_level(logging.INFO) path = RESOURCES_DIRECTORY / "fsfe.png" with path.open("rb") as fp: result = reuse_info_of_file(fp) assert result == ReuseInfo() assert f"'{path}' was detected as a binary file" in caplog.text def test_log(self, caplog, encoding_module): """Log the extraction to with level logging.DEBUG""" caplog.set_level(logging.DEBUG, logger="reuse.extract") buffer = BytesIO(b"# Copyright Jane Doe") buffer.name = "foo.py" reuse_info_of_file(buffer) assert len(caplog.records) == 1 assert caplog.records[0].levelname == "DEBUG" assert caplog.records[0].msg == ( f"extracting REUSE information from 'foo.py'" f" (encoding 'utf_8', encoding module '{encoding_module}'," f" newline {repr(os.linesep)})" ) @pytest.mark.parametrize("newline", ["\r\n", "\r", "\n"]) def test_all_newlines(self, newline): """Can lint files with any newline.""" text = cleandoc( """ SPDX-FileCopyrightText: Jane Doe SPDX-FileCopyrightText: John Doe """ ).replace("\n", newline) buffer = BytesIO(text.encode("utf-8")) result = reuse_info_of_file(buffer) assert result == ReuseInfo( copyright_notices={ CopyrightNotice("Jane Doe"), CopyrightNotice("John Doe"), } ) @pytest.mark.parametrize( "encoding", [ "utf_8", "utf_8_sig", "utf_16", "utf_32", "iso8859_1", ], ) def test_encodings(self, encoding): """Can lint files with any encoding.""" text = cleandoc( """ SPDX-FileCopyrightText: Jane Doe SPDX-FileCopyrightText: John Doe """ ) buffer = BytesIO(text.encode(encoding)) result = reuse_info_of_file(buffer) assert result == ReuseInfo( copyright_notices={ CopyrightNotice("Jane Doe"), CopyrightNotice("John Doe"), } ) class TestFilterIgnoreBlock: """Tests for filter_ignore_block.""" def test_with_comment_style(self): """Test that the ignore block is properly removed if start and end markers are in comment style. """ text = cleandoc( f""" Relevant text # REUSE-IgnoreStart Ignored text # {_IGNORE_END} Other relevant text """ ) expected = "Relevant text\n# \nOther relevant text" result = filter_ignore_block(text) assert result == (expected, False) def test_non_comment_style(self): """Test that the ignore block is properly removed if start and end markers are not comment style. """ text = cleandoc( f""" Relevant text REUSE-IgnoreStart Ignored text {_IGNORE_END} Other relevant text """ ) expected = cleandoc( """ Relevant text Other relevant text """ ) result = filter_ignore_block(text) assert result == (expected, False) def test_with_ignored_information_on_same_line(self): """Test that the ignore block is properly removed if there is information to be ignored on the same line. """ text = cleandoc( f""" Relevant text REUSE-IgnoreStart Copyright me Ignored text sdojfsd{_IGNORE_END} Other relevant text """ ) expected = cleandoc( """ Relevant text Other relevant text """ ) result = filter_ignore_block(text) assert result == (expected, False) def test_with_relevant_information_on_same_line(self): """Test that the ignore block is properly removed if it has relevant information on the same line. """ text = cleandoc( f""" Relevant textREUSE-IgnoreStart Ignored text {_IGNORE_END}Other relevant text """ ) expected = "Relevant textOther relevant text" result = filter_ignore_block(text) assert result == (expected, False) def test_with_beginning_and_end_on_same_line_correct_order( self, ): """Test that the ignore block is properly removed if it has relevant information on the same line. """ text = cleandoc( f""" Relevant textREUSE-IgnoreStartIgnored text{_IGNORE_END}Other relevant text """ ) expected = cleandoc( """ Relevant textOther relevant text """ ) result = filter_ignore_block(text) assert result == (expected, False) def test_with_beginning_and_end_on_same_line_wrong_order(self): """Test that the ignore block is properly removed if it has relevant information on the same line. """ text = f"Relevant text{_IGNORE_END}Other relevant textREUSE-IgnoreStartIgnored text" # pylint: disable=line-too-long expected = f"Relevant text{_IGNORE_END}Other relevant text" result = filter_ignore_block(text) assert result == (expected, True) def test_end_start_end(self): """Test that an ignore block is properly removed even if the string starts with an end instruction. """ text = cleandoc( f""" {_IGNORE_END} Relevant text REUSE-IgnoreStart IgnoredText REUSE-IgnoreEnd More relevant text """ ) expected = cleandoc( f""" {_IGNORE_END} Relevant text More relevant text """ ) result = filter_ignore_block(text) assert result == (expected, False) def test_without_end(self): """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 = filter_ignore_block(text) assert result == (expected, True) def test_with_multiple_ignore_blocks(self): """Test that the ignore block is properly removed if it has relevant information on the same line. """ text = cleandoc( f""" Relevant text REUSE-IgnoreStart Ignored text {_IGNORE_END} Other relevant text REUSE-IgnoreStart Other ignored text {_IGNORE_END} Even more relevant text """ ) expected = cleandoc( """ Relevant text Other relevant text Even more relevant text """ ) result = filter_ignore_block(text) assert result == (expected, False) def test_only_start(self): """If the only thing in the string is 'REUSE-IgnoreStart', correctly set *in_ignore_block*. """ text = "REUSE-IgnoreStart" expected = "" result = filter_ignore_block(text) assert result == (expected, True) def test_only_end(self): """If the only thing in the string is 'REUSE-IgnoreEnd', correctly set *in_ignore_block*. """ text = "REUSE-IgnoreEnd" # REUSE-IgnoreStart expected = "" result = filter_ignore_block(text, in_ignore_block=True) assert result == (expected, False) class TestDetectNewLine: """Tests for detect_newline.""" @pytest.mark.parametrize("newline", ["\r\n", "\r", "\n"]) @pytest.mark.parametrize( "encoding", ["utf_8", "utf_8_sig", "utf_16", "utf_16_be", "utf_32", "iso8859_1"], ) def test_simple(self, newline, encoding): """Test whether newline is correctly spotted.""" assert ( detect_newline( f"hello{newline}world".encode(encoding), encoding=encoding ) == newline ) def test_no_newlines(self): """Given a file without line endings, default to os.linesep.""" assert detect_newline(b"hello world") == os.linesep class TestContainsReuseInfo: """Tests for contain_reuse_info.""" @pytest.mark.parametrize( "text", [ "SPDX-FileCopyrightText: Jane Doe", "SPDX-License-Identifier: MIT", "SPDX-FileCopyrightText: Jane Doe\nSPDX-License-Identifier: MIT", ], ) def test_simple(self, text): """If a text contains a license, a copyright notice, or both, expect True. """ assert contains_reuse_info(text) def test_no_info(self): """If there is no info, expect False.""" assert not contains_reuse_info("Hello, world!") def test_ignore_block(self): """If the info is in an ignore block, expect False.""" assert not contains_reuse_info( cleandoc( f""" REUSE-IgnoreStart Copyright Jane Doe {_IGNORE_END} """ ) ) class TestEncodingModule: """Tests for picking the correct encoding module.""" def test_wrong_env(self): """If REUSE_ENCODING_MODULE is set to an unsupported value, exit.""" env = os.environ.copy() env["REUSE_ENCODING_MODULE"] = "foo" result = subprocess.run( [sys.executable, "-c", "import reuse.extract"], env=env, stderr=subprocess.PIPE, stdout=subprocess.PIPE, check=False, ) assert result.returncode != 0 assert result.stdout.decode("utf-8").strip() == ( "REUSE_ENCODING_MODULE must have a value in ['python-magic'," " 'file-magic', 'charset_normalizer', 'chardet']; it has 'foo'." " Aborting." ) def test_correct_env(self, encoding_module): """If REUSE_ENCODING_MODULE is set to a valid value, use the correct module. """ env = os.environ.copy() env["REUSE_ENCODING_MODULE"] = encoding_module result = subprocess.run( [ sys.executable, "-c", "import reuse.extract;" "print(reuse.extract._get_encoding_module_name())", ], env=env, stderr=subprocess.PIPE, stdout=subprocess.PIPE, check=False, ) assert result.returncode == 0 assert result.stdout.decode("utf-8").strip() == encoding_module def test_magic_env(self, encoding_module): """If REUSE_ENCODING_MODULE is 'magic', import python-magic for backwards compatibility. """ if encoding_module != "python-magic": pytest.skip("this test only works with python-magic") env = os.environ.copy() env["REUSE_ENCODING_MODULE"] = "magic" result = subprocess.run( [ sys.executable, "-c", "import reuse.extract;" "print(reuse.extract._get_encoding_module_name())", ], env=env, stderr=subprocess.PIPE, stdout=subprocess.PIPE, check=False, ) assert result.returncode == 0 assert result.stdout == b"python-magic\n" @chardet def test_pick_module(self): """If REUSE_ENCODING_MODULE is set to a correct value, correctly select that encoding module. """ env = os.environ.copy() env["REUSE_ENCODING_MODULE"] = "chardet" result = subprocess.run( [ sys.executable, "-c", "import reuse.extract;" "print(reuse.extract._ENCODING_MODULE.__name__, end='')", ], env=env, stderr=subprocess.PIPE, stdout=subprocess.PIPE, check=False, ) assert result.returncode == 0 assert result.stdout == b"chardet" def test_get_encoding_module(self, encoding_module): """Test whether get_encoding_module returns the correct module.""" result = get_encoding_module().__name__ if "magic" in encoding_module: assert result == "magic" else: assert result == encoding_module def test_set_wrong_encoding_module_(self): """If setting to an unsupported module, expect an error.""" with pytest.raises(NoEncodingModuleError): set_encoding_module("foo") # type: ignore[arg-type] # Reuse-IgnoreEnd reuse-tool-6.2.0/.editorconfig0000664000175000017500000000054415077707000014746 0ustar alexalex# 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-6.2.0/src/0000775000175000017500000000000015077707000013055 5ustar alexalexreuse-tool-6.2.0/src/reuse/0000775000175000017500000000000015077707000014200 5ustar alexalexreuse-tool-6.2.0/src/reuse/_util.py0000664000175000017500000001146615077707000015676 0ustar alexalex# 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: 2024 Skyler Grey # SPDX-FileCopyrightText: © 2020 Liferay, Inc. # # SPDX-License-Identifier: GPL-3.0-or-later """Misc. utilities for reuse.""" import logging import os import subprocess from hashlib import sha1 from inspect import cleandoc from pathlib import Path from typing import IO, Any from .types import StrPath # REUSE-IgnoreStart 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: StrPath | None = 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: None | int | IO[Any] = kwargs.get("stdout", subprocess.PIPE) stderr: 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: StrPath | None = 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 _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 _strip_plus_from_identifier(spdx_identifier: str) -> str: """Strip final plus from identifier. >>> _strip_plus_from_identifier("EUPL-1.2+") 'EUPL-1.2' >>> _strip_plus_from_identifier("EUPL-1.2") 'EUPL-1.2' """ if spdx_identifier.endswith("+"): return spdx_identifier[:-1] return spdx_identifier def _add_plus_to_identifier(spdx_identifier: str) -> str: """Add final plus to identifier. >>> _add_plus_to_identifier("EUPL-1.2") 'EUPL-1.2+' >>> _add_plus_to_identifier("EUPL-1.2+") 'EUPL-1.2+' """ if spdx_identifier.endswith("+"): return spdx_identifier return f"{spdx_identifier}+" def relative_from_root(path: Path, root: Path) -> Path: """A helper function to get *path* relative to *root*.""" path_parts = path.parts root_parts = root.parts root_parts_len = len(root_parts) # This is rather strangely more performant than `path.relative_to(root)`. if path_parts[:root_parts_len] == root_parts: return Path(*path_parts[root_parts_len:]) return Path(os.path.relpath(str(path), start=str(root))) 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() 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-6.2.0/src/reuse/convert_dep5.py0000664000175000017500000000631015077707000017147 0ustar alexalex# 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 from collections.abc import Iterable from typing import Any, Optional, TypeVar, cast import tomlkit from debian.copyright import Copyright, FilesParagraph, Header from .global_licensing import REUSE_TOML_VERSION _SINGLE_ASTERISK_PATTERN = re.compile(r"(? 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, str | list[str]]: result: dict[str, 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, ) -> 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) -> str | list[str]: return _collapse_list_if_one_item( [_convert_asterisk(path) for path in list(paragraph.files)] ) def _comment_from_paragraph(paragraph: FilesParagraph) -> str | None: return cast(Optional[str], paragraph.comment) def _annotations_from_paragraphs( paragraphs: Iterable[FilesParagraph], ) -> list[dict[str, 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) reuse-tool-6.2.0/src/reuse/lint.py0000664000175000017500000002772615077707000015536 0ustar alexalex# 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 from collections import defaultdict from io import StringIO from itertools import chain from pathlib import Path from textwrap import TextWrapper from typing import Any from . import __REUSE_version__ from .i18n import _ from .report import ProjectReport, ProjectReportSubsetProtocol # 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") output.write( _("The following licenses are not valid SPDX licenses:") + "\n" ) for path in sorted(report.bad_licenses.values()): output.write(f"* {path}\n") output.write("\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") # 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") # 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") # 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") # 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") if report.invalid_spdx_expressions: output.write("# " + _("INVALID SPDX LICENSE EXPRESSIONS") + "\n\n") for path, expressions in sorted( report.invalid_spdx_expressions.items() ): output.write( _("'{}' contains invalid SPDX License Expressions:").format( path ) + "\n" ) for expression in sorted(expressions): output.write(f"* {expression}\n") output.write("\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("# " + _("SUMMARY")) output.write("\n\n") total_files = len(report.file_reports) summary_contents = { _("Bad licenses:"): ", ".join(sorted(report.bad_licenses)), _("Deprecated licenses:"): ", ".join( sorted(report.deprecated_licenses) ), _("Licenses without file extension:"): ", ".join( sorted(report.licenses_without_extension) ), _("Missing licenses:"): ", ".join(sorted(report.missing_licenses)), _("Unused licenses:"): ", ".join(sorted(report.unused_licenses)), _("Used licenses:"): ", ".join(sorted(report.used_licenses)), _("Read errors:"): str(len(report.read_errors)), _("Invalid SPDX License Expressions:"): str( len( list( chain.from_iterable( report.invalid_spdx_expressions.values() ) ) ) ), _( "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 _output_lines_dict(format_dict: dict[str, list[str]]) -> str: output = StringIO() for path, items in sorted(format_dict.items()): for item in items: output.write(f"{path}: {item}\n") return output.getvalue() def _format_lines_subset_dict( report: ProjectReportSubsetProtocol, ) -> defaultdict[str, list[str]]: result_dict = defaultdict(list) # Missing licenses for lic, files in sorted(report.missing_licenses.items()): for path in files: result_dict[str(path)].append( _("missing license '{lic}'").format(lic=lic) ) # Read errors for path in report.read_errors: result_dict[str(path)].append(_("read error").format(path=path)) for path, expressions in report.invalid_spdx_expressions.items(): for expression in sorted(expressions): result_dict[str(path)].append( _("invalid SPDX License Expression '{expression}'").format( expression=expression ) ) # Without licenses for path in report.files_without_licenses: result_dict[str(path)].append(_("no license identifier")) # Without copyright for path in report.files_without_copyright: result_dict[str(path)].append(_("no copyright notice")) return result_dict def format_lines_subset(report: ProjectReportSubsetProtocol) -> str: """Formats a subset of a report, namely missing licenses, read errors, invalid SPDX License Expressions, files without licenses, and files without copyright. Args: report: A populated report. Returns: String (in plaintext) that can be output to sys.stdout """ return _output_lines_dict(_format_lines_subset_dict(report)) def format_lines(report: ProjectReport) -> str: """Formats report as plaintext strings to be printed to sys.stdout. Sorting of output is not guaranteed. Args: report: A populated report. Returns: String (in plaintext) that can be output to sys.stdout """ def license_path(lic: str) -> str: """Resolve a license identifier to a license path.""" return str(report.licenses.get(lic)) result_dict: defaultdict[str, list[str]] = defaultdict(list) # Bad licenses for lic, path in report.bad_licenses.items(): result_dict[str(path)].append(_("bad license '{lic}'").format(lic=lic)) # Deprecated licenses for lic in report.deprecated_licenses: lic_path = license_path(lic) result_dict[lic_path].append(_("deprecated license")) # Licenses without extension for lic in report.licenses_without_extension: lic_path = license_path(lic) result_dict[lic_path].append(_("license without file extension")) # Unused licenses for lic in report.unused_licenses: lic_path = license_path(lic) result_dict[lic_path].append(_("unused license")) subset_dict = _format_lines_subset_dict(report) for key, value in subset_dict.items(): result_dict[key].extend(value) return _output_lines_dict(result_dict) reuse-tool-6.2.0/src/reuse/templates/0000775000175000017500000000000015077707000016176 5ustar alexalexreuse-tool-6.2.0/src/reuse/templates/default_template.jinja20000664000175000017500000000043115077707000022612 0ustar alexalex{% 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-6.2.0/src/reuse/templates/default_template.jinja2.license0000664000175000017500000000016715077707000024241 0ustar alexalexSPDX-FileCopyrightText: 2019 Free Software Foundation Europe e.V. SPDX-License-Identifier: CC0-1.0 reuse-tool-6.2.0/src/reuse/vcs.py0000664000175000017500000003407615077707000015357 0ustar alexalex# SPDX-FileCopyrightText: 2017 Free Software Foundation Europe e.V. # SPDX-FileCopyrightText: 2020 John Mulligan # SPDX-FileCopyrightText: 2023 Markus Haug # SPDX-FileCopyrightText: 2024 Skyler Grey # SPDX-FileCopyrightText: 2025 Jonas Fierlings # SPDX-FileCopyrightText: © 2020 Liferay, Inc. # # SPDX-License-Identifier: GPL-3.0-or-later """This module deals with version control systems.""" from __future__ import annotations import logging import os import shutil from abc import ABC, abstractmethod from collections.abc import Generator from inspect import isclass from pathlib import Path from typing import TYPE_CHECKING from ._util import execute_command, relative_from_root from .types import StrPath if TYPE_CHECKING: from .project import Project _LOGGER = logging.getLogger(__name__) GIT_EXE = shutil.which("git") HG_EXE = shutil.which("hg") JUJUTSU_EXE = shutil.which("jj") PIJUL_EXE = shutil.which("pijul") def _find_ancestor( directory: StrPath, ancestor: str, is_directory: bool = True ) -> Path | None: path = Path(directory).resolve() for parent in [path] + list(path.parents): if (parent / ancestor).is_dir() or ( (parent / ancestor).exists() and not is_directory ): return parent / ancestor return None class VCSStrategy(ABC): """Strategy pattern for version control systems.""" EXE: str | None = None def __init__(self, root: StrPath): self.root = Path(root) @abstractmethod def is_ignored(self, path: Path) -> 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: StrPath | None = None) -> Path | None: """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 is_ignored(self, path: Path) -> 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: StrPath | None = None) -> Path | None: return None class VCSStrategyGit(VCSStrategy): """Strategy that is used for Git.""" EXE = GIT_EXE def __init__(self, root: StrPath): super().__init__(root) 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.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.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: Path) -> bool: path = relative_from_root(path, self.root) return path in self._all_ignored_files def is_submodule(self, path: StrPath) -> bool: return any( relative_from_root(Path(path), self.root).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() if _find_ancestor(directory, ".git", is_directory=False): command = [str(cls.EXE), "rev-parse", "--is-inside-work-tree"] result = execute_command(command, _LOGGER, cwd=directory) return not result.returncode return False @classmethod def find_root(cls, cwd: StrPath | None = None) -> Path | None: if cwd is None: cwd = Path.cwd() if not Path(cwd).is_dir(): raise NotADirectoryError() if not _find_ancestor(cwd, ".git", is_directory=False): return None 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, root: StrPath): super().__init__(root) 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.root) all_files = result.stdout.decode("utf-8").split("\0") return {Path(file_) for file_ in all_files} def is_ignored(self, path: Path) -> bool: path = relative_from_root(path, self.root) 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() if _find_ancestor(directory, ".hg"): command = [str(cls.EXE), "root"] result = execute_command(command, _LOGGER, cwd=directory) return not result.returncode return False @classmethod def find_root(cls, cwd: StrPath | None = None) -> Path | None: if cwd is None: cwd = Path.cwd() if not Path(cwd).is_dir(): raise NotADirectoryError() if not _find_ancestor(cwd, ".hg"): return None 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 VCSStrategyJujutsu(VCSStrategy): """Strategy that is used for Jujutsu.""" EXE = JUJUTSU_EXE def __init__(self, root: StrPath): super().__init__(root) if not self.EXE: raise FileNotFoundError("Could not find binary for Jujutsu") self._all_tracked_files = self._find_all_tracked_files() def _find_all_tracked_files(self) -> set[Path]: """ Return a set of all files tracked in the current jj revision """ version = self._version() # TODO: Remove the version check once most distributions ship jj 0.19.0 # or higher. if version is None or version >= (0, 19, 0): command = [str(self.EXE), "file", "list"] else: command = [str(self.EXE), "files"] result = execute_command(command, _LOGGER, cwd=self.root) all_files = result.stdout.decode("utf-8").split("\n") return {Path(file_) for file_ in all_files if file_} def _version(self) -> tuple[int, int, int] | None: """ Returns the (major, minor, patch) version of the jujutsu executable, or None if the version components cannot be determined. """ result = execute_command( [str(self.EXE), "--version"], _LOGGER, cwd=self.root ) lines = result.stdout.decode("utf-8").split("\n") # Output has the form `jj major.minor.patch[-hash]\n`. try: line = lines[0] version = line.split(" ")[-1] without_hash = version.split("-")[0] components = without_hash.split(".") return (int(components[0]), int(components[1]), int(components[2])) except (IndexError, ValueError) as e: _LOGGER.debug("unable to parse jj version: %s", e) return None def is_ignored(self, path: Path) -> bool: path = relative_from_root(path, self.root) for tracked in self._all_tracked_files: if tracked.parts[: len(path.parts)] == path.parts: # We can't check only if the path is in our tracked files as we # must support directories as well as files # # We'll consider a directory "tracked" if there are any tracked # files inside it return False return True def is_submodule(self, path: StrPath) -> bool: return False @classmethod def in_repo(cls, directory: StrPath) -> bool: if not Path(directory).is_dir(): raise NotADirectoryError() if _find_ancestor(directory, ".jj"): command = [str(cls.EXE), "root"] result = execute_command(command, _LOGGER, cwd=directory) return not result.returncode return False @classmethod def find_root(cls, cwd: StrPath | None = None) -> Path | None: if cwd is None: cwd = Path.cwd() if not Path(cwd).is_dir(): raise NotADirectoryError() if not _find_ancestor(cwd, ".jj"): return None 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, root: StrPath): super().__init__(root) 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.root) all_files = result.stdout.decode("utf-8").splitlines() return {Path(file_) for file_ in all_files} def is_ignored(self, path: Path) -> bool: path = relative_from_root(path, self.root) 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() if _find_ancestor(directory, ".pijul"): command = [str(cls.EXE), "diff", "--short"] result = execute_command(command, _LOGGER, cwd=directory) return not result.returncode return False @classmethod def find_root(cls, cwd: StrPath | None = None) -> Path | None: 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() dot_pijul = _find_ancestor(path, ".pijul") if dot_pijul is not None: return dot_pijul.parent return None def all_vcs_strategies() -> Generator[type[VCSStrategy]]: """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: StrPath | None = None) -> Path | None: """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-6.2.0/src/reuse/_licenses.py0000664000175000017500000000410315077707000016514 0ustar alexalex# 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 _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, 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, 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-6.2.0/src/reuse/project.py0000664000175000017500000004430715077707000016230 0ustar alexalex# 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-FileCopyrightText: 2024 Kerry McAdams # SPDX-FileCopyrightText: 2024 Linnea Gräf # # SPDX-License-Identifier: GPL-3.0-or-later """Module that contains the central Project class.""" import errno import glob import logging import os import warnings from collections import defaultdict from collections.abc import Collection, Iterator from pathlib import Path from typing import NamedTuple import attrs from ._licenses import EXCEPTION_MAP, LICENSE_MAP from ._util import _determine_license_path, relative_from_root from .copyright import ReuseInfo, SourceType from .covered_files import iter_files from .exceptions import ( GlobalLicensingConflictError, SpdxIdentifierNotFoundError, ) from .extract import _LICENSEREF_PATTERN, CHUNK_SIZE, reuse_info_of_file from .global_licensing import ( GlobalLicensing, NestedReuseTOML, PrecedenceType, ReuseDep5, ReuseTOML, ) from .i18n import _ from .types import StrPath from .vcs import VCSStrategy, VCSStrategyNone, all_vcs_strategies _LOGGER = logging.getLogger(__name__) class GlobalLicensingFound(NamedTuple): path: Path cls: type[GlobalLicensing] # TODO: The information (root, include_submodules, include_meson_subprojects, # vcs_strategy) is passed to SO MANY PLACES. Maybe Project should be simplified # to contain exclusively those values, or maybe these values should be extracted # out of Project to simplify passing this information around. @attrs.define class Project: """Simple object that holds the project's root, which is necessary for many interactions. """ root: Path = attrs.field(converter=Path) include_submodules: bool = False include_meson_subprojects: bool = False vcs_strategy: VCSStrategy = attrs.field() global_licensing: GlobalLicensing | None = None # TODO: I want to get rid of these, or somehow refactor this mess. license_map: dict[str, dict] = attrs.field() licenses: dict[str, Path] = attrs.field(factory=dict) licenses_without_extension: dict[str, Path] = attrs.field( init=False, factory=dict ) @vcs_strategy.default def _default_vcs_strategy(self) -> VCSStrategy: return VCSStrategyNone(self.root) @license_map.default def _default_license_map(self) -> dict[str, dict]: license_map = LICENSE_MAP.copy() license_map.update(EXCEPTION_MAP) return license_map @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. GlobalLicensingConflictError: 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: GlobalLicensing | None = None found = cls.find_global_licensing( root, include_submodules=include_submodules, include_meson_subprojects=include_meson_subprojects, vcs_strategy=vcs_strategy, ) if found: global_licensing = cls._global_licensing_from_found( found, str(root) ) 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: StrPath | None = None) -> Iterator[Path]: """Yield all files in *directory* and its subdirectories. The files that are not yielded are those explicitly ignored by the REUSE Specification. That means: - LICENSE/COPYING files. - VCS directories. - .license files. - .spdx files. - Files ignored by VCS. - Symlinks. - Submodules (depending on the value of :attr:`include_submodules`). - Meson subprojects (depending on the value of :attr:`include_meson_subprojects`). - 0-sized files. Args: directory: The directory in which to search. """ if directory is None: directory = self.root return iter_files( directory, include_submodules=self.include_submodules, include_meson_subprojects=self.include_meson_subprojects, vcs_strategy=self.vcs_strategy, ) def subset_files( self, files: Collection[StrPath], directory: StrPath | None = None ) -> Iterator[Path]: """Like :meth:`all_files`, but all files that are not in *files* are filtered out. Args: files: A collection of paths relative to the current working directory. Any files that are not in this collection are not yielded. directory: The directory in which to search. """ if directory is None: directory = self.root return iter_files( directory=directory, subset_files=files, include_submodules=self.include_submodules, include_meson_subprojects=self.include_meson_subprojects, vcs_strategy=self.vcs_strategy, ) 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) path = _determine_license_path(path) # 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(original_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) ) else: with path.open("rb", buffering=CHUNK_SIZE) as fp: file_result = reuse_info_of_file(fp) if file_result.contains_info(): source_type = SourceType.FILE_HEADER if path.suffix == ".license": source_type = SourceType.DOT_LICENSE file_result = file_result.copy( path=relative_from_root( original_path, self.root ).as_posix(), source_path=relative_from_root(path, self.root).as_posix(), source_type=source_type, ) 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_notices: result.append( closest.copy( copyright_notices=set(), ) ) elif file_result.spdx_expressions: result.append( closest.copy( spdx_expressions=set(), ) ) return result def relative_from_root(self, path: Path) -> 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, include_submodules: bool = False, include_meson_subprojects: bool = False, vcs_strategy: VCSStrategy | None = None, ) -> list[GlobalLicensingFound]: """Find the path and corresponding class of a project directory's :class:`GlobalLicensing`. Raises: GlobalLicensingConflictError: if more than one global licensing config file is present. """ candidates: list[GlobalLicensingFound] = [] 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, ) candidates = [GlobalLicensingFound(dep5_path, ReuseDep5)] reuse_toml_candidates = [ GlobalLicensingFound(path, ReuseTOML) for path in NestedReuseTOML.find_reuse_tomls( root, include_submodules=include_submodules, include_meson_subprojects=include_meson_subprojects, vcs_strategy=vcs_strategy, ) ] if reuse_toml_candidates: if candidates: raise GlobalLicensingConflictError( _( "Found both '{new_path}' and '{old_path}'. You" " cannot keep both files simultaneously; they are" " not intercompatible." ).format( new_path=reuse_toml_candidates[0].path, old_path=dep5_path, ) ) candidates = reuse_toml_candidates return candidates @classmethod def _global_licensing_from_found( cls, found: list[GlobalLicensingFound], root: StrPath ) -> GlobalLicensing: if len(found) == 1 and found[0].cls == ReuseDep5: return ReuseDep5.from_file(found[0].path) # This is an impossible scenario at time of writing. if not all(item.cls == ReuseTOML for item in found): raise NotImplementedError() tomls = [ReuseTOML.from_file(item.path) for item in found] return NestedReuseTOML(reuse_tomls=tomls, source=str(root)) 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 SpdxIdentifierNotFoundError(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 SpdxIdentifierNotFoundError( 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) try: identifier = self._identifier_of_license(path) except SpdxIdentifierNotFoundError: 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) -> 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(root) _LOGGER.info( _( "project '{}' is not a VCS repository or required VCS" " software is not installed" ).format(root) ) return VCSStrategyNone(root) reuse-tool-6.2.0/src/reuse/report.py0000664000175000017500000007537515077707000016106 0ustar alexalex# 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-FileCopyrightText: 2024 Kerry McAdams # SPDX-FileCopyrightText: 2024 Sebastien Morais # SPDX-FileCopyrightText: 2025 Simon Barth # # 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 random from collections import defaultdict from collections.abc import Collection, Generator from concurrent.futures import ProcessPoolExecutor from functools import cached_property from hashlib import md5 from io import StringIO from os import cpu_count from pathlib import Path, PurePath from typing import Any, Final, NamedTuple, Optional, Protocol, cast from uuid import uuid4 from . import __REUSE_version__, __version__ from ._util import ( _add_plus_to_identifier, _checksum, _strip_plus_from_identifier, ) from .copyright import SpdxExpression from .extract import _LICENSEREF_PATTERN from .global_licensing import ReuseDep5 from .i18n import _ from .project import Project, ReuseInfo from .types import StrPath _LOGGER = logging.getLogger(__name__) LINT_VERSION = "1.0" _CPU_COUNT: Final[int] = cpu_count() or 1 #: This variable exists to be able to override parallelisation. If set to #: :const:`False`, generating :meth:`FileReport.generate` will not use #: parallelisation. ENABLE_PARALLEL = True # REUSE-IgnoreStart 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, 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: ReuseDep5 | None = 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: Exception | None def _generate_file_reports( project: Project, do_checksum: bool = True, subset_files: Collection[StrPath] | None = None, multiprocessing: bool = _CPU_COUNT > 1, add_license_concluded: bool = False, ) -> Generator[_MultiprocessingResult, None, None]: """Create a :class:`FileReport` for every file in the project, filtered by *subset_files*. """ container = _MultiprocessingContainer( project, do_checksum, add_license_concluded ) files = ( project.subset_files(subset_files) if subset_files is not None else project.all_files() ) if multiprocessing and ENABLE_PARALLEL: files_set = frozenset(files) with ProcessPoolExecutor() as executor: yield from executor.map( container, files_set, chunksize=max(1, int(len(files_set) / _CPU_COUNT / 4)), ) else: yield from map(container, files) def _process_error(error: Exception, path: StrPath) -> None: # Facilitate better debugging by being able to quit the program. if isinstance(error, (bdb.BdbQuit, KeyboardInterrupt)): raise error if isinstance(error, (OSError, UnicodeError)): _LOGGER.error( _("Could not read '{path}'").format(path=path), exc_info=error, ) else: _LOGGER.error( _("Unexpected error occurred while parsing '{path}'").format( path=path ), exc_info=error, ) class ProjectReportSubsetProtocol(Protocol): """A :class:`Protocol` that defines a subset of functionality of :class:`ProjectReport`, implemented by :class:`ProjectSubsetReport`. """ path: StrPath read_errors: set[Path] file_reports: set["FileReport"] @property def missing_licenses(self) -> dict[str, set[Path]]: """Files which refer to a license which do not exist in the LICENSES/ directory. """ @property def invalid_spdx_expressions(self) -> dict[Path, set[str]]: """Invalid expressions by file.""" @property def files_without_licenses(self) -> set[Path]: """Set of paths that have no licensing information.""" @property def files_without_copyright(self) -> set[Path]: """Set of paths that have no copyright information.""" @property def is_compliant(self) -> bool: """Whether the report subset is compliant with the REUSE Spec.""" class ProjectReport: """Object that holds linting report about the project.""" def __init__(self, do_checksum: bool = True): self.path: StrPath = "" self.licenses: dict[str, Path] = {} 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._license_map: dict[str, dict] = {} 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": { "bad_licenses": list(sorted(self.bad_licenses)), "deprecated_licenses": list( sorted(str(file) for file in self.deprecated_licenses) ), "licenses_without_extension": list( sorted(self.licenses_without_extension) ), "missing_licenses": list(sorted(self.missing_licenses)), "unused_licenses": list( sorted(str(file) for file in self.unused_licenses) ), "read_errors": list( sorted(str(file) for file in self.read_errors) ), "missing_copyright_info": list( sorted(str(file) for file in self.files_without_copyright) ), "missing_licensing_info": list( sorted(str(file) for file in self.files_without_licenses) ), }, "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(sorted(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: str | None = None, creator_organization: str | None = 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, add_license_concluded: bool = False, ) -> "ProjectReport": """Generate a :class:`ProjectReport` from a :class:`Project`. Args: project: The :class:`Project` to lint. do_checksum: Generate a checksum of every file. If this is :const:`False`, generate a random checksum for every file. multiprocessing: Whether to use multiprocessing. add_license_concluded: Whether to aggregate all found SPDX expressions into a concluded license. """ project_report = cls(do_checksum=do_checksum) project_report.path = project.root project_report.licenses = project.licenses project_report._license_map = project.license_map project_report.licenses_without_extension = ( project.licenses_without_extension ) results = _generate_file_reports( project, do_checksum=do_checksum, multiprocessing=multiprocessing, add_license_concluded=add_license_concluded, ) for result in results: if result.error: _process_error(result.error, result.path) project_report.read_errors.add(Path(result.path)) continue file_report = cast(FileReport, result.report) project_report.file_reports.add(file_report) return project_report @cached_property def used_licenses(self) -> set[str]: """Set of license identifiers that are found in file reports.""" return { lic for file_report in self.file_reports for lic in file_report.licenses_in_file } @cached_property def bad_licenses(self) -> dict[str, Path]: """Licenses in LICENSES/ which are not valid SPDX licenses.""" return { lic: path for lic, path in self.licenses.items() if lic not in self._license_map } @cached_property def deprecated_licenses(self) -> set[str]: """Licenses whose SPDX License identifier has been deprecated.""" return { lic for lic in self.licenses if lic in self._license_map and self._license_map[lic]["isDeprecatedLicenseId"] } @cached_property def unused_licenses(self) -> set[str]: """Set of license identifiers that are not found in any file report.""" return { lic for lic in self.licenses if not any( identifier in self.used_licenses for identifier in (lic, _add_plus_to_identifier(lic)) ) } @cached_property def missing_licenses(self) -> dict[str, set[Path]]: """Files which refer to a license which do not exist in the LICENSES/ directory. """ result = defaultdict(set) for file_report in self.file_reports: for missing_license in file_report.missing_licenses: result[missing_license].add(file_report.path) return result @cached_property def invalid_spdx_expressions(self) -> dict[Path, set[str]]: """Invalid expressions by file.""" return { file_report.path: file_report.invalid_spdx_expressions for file_report in self.file_reports if file_report.invalid_spdx_expressions } @cached_property def files_without_licenses(self) -> set[Path]: """Set of paths that have no licensing information.""" return { file_report.path for file_report in self.file_reports if not file_report.licenses_in_file } @cached_property def files_without_copyright(self) -> set[Path]: """Set of paths that have no copyright information.""" return { file_report.path for file_report in self.file_reports if not file_report.copyright } @cached_property def is_compliant(self) -> bool: """Whether the report is compliant with the REUSE Spec.""" return not any( ( self.missing_licenses, self.unused_licenses, self.bad_licenses, self.deprecated_licenses, self.licenses_without_extension, self.read_errors, self.invalid_spdx_expressions, self.files_without_copyright, self.files_without_licenses, ) ) @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.invalid_spdx_expressions: recommendations.append( _( "Fix invalid SPDX License Expressions: In one or more files" " there are SPDX License Expressions which cannot be" " parse. Check whether the value that follows" " 'SPDX-License-Identifier:' is correct. If the detected" " expression is not meant to be valid, put it between" " 'REUSE-IgnoreStart' and 'REUSE-IgnoreEnd' comments." ) ) 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 ProjectSubsetReport: """Like a :class:`ProjectReport`, but for a subset of the files using a subset of features. """ def __init__(self) -> None: self.path: StrPath = "" self.read_errors: set[Path] = set() self.file_reports: set[FileReport] = set() @classmethod def generate( cls, project: Project, subset_files: Collection[StrPath], multiprocessing: bool = _CPU_COUNT > 1, ) -> "ProjectSubsetReport": """Generate a :class:`ProjectSubsetReport` from a :class:`Project`. Args: project: The :class:`Project` to lint. subset_files: Only lint the files in this list. multiprocessing: Whether to use multiprocessing. """ subset_report = cls() subset_report.path = project.root results = _generate_file_reports( project, do_checksum=False, subset_files=subset_files, multiprocessing=multiprocessing, add_license_concluded=False, ) for result in results: if result.error: _process_error(result.error, result.path) subset_report.read_errors.add(Path(result.path)) continue file_report = cast(FileReport, result.report) subset_report.file_reports.add(file_report) return subset_report @property def missing_licenses(self) -> dict[str, set[Path]]: """Files which refer to a license which do not exist in the LICENSES/ directory. """ result = defaultdict(set) for file_report in self.file_reports: for missing_license in file_report.missing_licenses: result[missing_license].add(file_report.path) return result @property def invalid_spdx_expressions(self) -> dict[Path, set[str]]: """Invalid expressions by file.""" return { file_report.path: file_report.invalid_spdx_expressions for file_report in self.file_reports if file_report.invalid_spdx_expressions } @property def files_without_licenses(self) -> set[Path]: """Set of paths that have no licensing information.""" return { file_report.path for file_report in self.file_reports if not file_report.licenses_in_file } @property def files_without_copyright(self) -> set[Path]: """Set of paths that have no copyright information.""" return { file_report.path for file_report in self.file_reports if not file_report.copyright } @property def is_compliant(self) -> bool: """Whether the report subset is compliant with the REUSE Spec.""" return not any( ( self.missing_licenses, self.files_without_copyright, self.files_without_licenses, self.read_errors, ) ) 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: str | None = None self.chk_sum: str | None = None self.licenses_in_file: list[str] = [] self.license_concluded: str = "" self.copyright: str = "" self.missing_licenses: set[str] = set() self.invalid_spdx_expressions: 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 { "path": PurePath(self.name).as_posix(), "copyrights": [ { "value": str(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_notices ], "spdx_expressions": [ { "value": str(expression), "is_valid": expression.is_valid, "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.""" # pylint: disable=too-many-branches 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: if not expression.is_valid: report.invalid_spdx_expressions.add(str(expression)) continue for identifier in expression.licenses: # A license expression akin to Apache-1.0+ should register # correctly if LICENSES/Apache-1.0.txt exists. identifiers = {identifier} if ( plus_identifier := _strip_plus_from_identifier( identifier ) ) != identifier: identifiers.add(plus_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" elif report.invalid_spdx_expressions: report.license_concluded = "NOASSERTION" 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 = str( SpdxExpression.combine( list( expression for reuse_info in reuse_infos for expression in reuse_info.spdx_expressions ) ).simplify() ) # Copyright text report.copyright = "\n".join( map( str, sorted( line for reuse_info in reuse_infos for line in reuse_info.copyright_notices ), ) ) # 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: str | None) -> 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-IgnoreEnd reuse-tool-6.2.0/src/reuse/__main__.py0000664000175000017500000000043015077707000016267 0ustar alexalex# SPDX-FileCopyrightText: 2019 Free Software Foundation Europe e.V. # # SPDX-License-Identifier: GPL-3.0-or-later """Entry module for reuse.""" if __name__ == "__main__": from .cli.main import main # pylint: disable=no-value-for-parameter main() reuse-tool-6.2.0/src/reuse/copyright.py0000664000175000017500000007217215077707000016573 0ustar alexalex# 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 """Utilities related to the parsing and storing of copyright notices.""" import difflib import logging import re from collections import Counter, defaultdict from collections.abc import Iterable from dataclasses import InitVar, dataclass, field from enum import Enum, unique from functools import cached_property from io import StringIO from itertools import chain from typing import Any, Literal, NewType, cast from license_expression import ( ExpressionError, LicenseExpression, Licensing, combine_expressions, ) from .exceptions import CopyrightNoticeParseError, YearRangeParseError # REUSE-IgnoreStart _LOGGER = logging.getLogger(__name__) _LICENSING = Licensing() #: A string that is four digits long. FourDigitString = NewType("FourDigitString", str) #: A range separator between two years. YearRangeSeparator = Literal[ "--", # ascii en dash "–", # en dash "-", # ascii dash ] def is_four_digits(value: str) -> FourDigitString | Literal[False]: """Identify a string as a four-digit string. Return the string as :type:`FourDigitString` if it is one. >>> is_four_digits("1234") '1234' >>> is_four_digits("abcd") False >>> is_four_digits("12345") False """ if value.isdigit() and len(value) == 4: return FourDigitString(value) return False def validate_four_digits(value: str) -> FourDigitString: """Validate whether a given string is a :type:`FourDigitString`. >>> validate_four_digits("1234") '1234' >>> validate_four_digits("abcd") Traceback (most recent call last): ... ValueError: 'abcd' is not a four-digit year. >>> validate_four_digits("12345") Traceback (most recent call last): ... ValueError: '12345' is not a four-digit year. Raises: ValueError: The string is not four digits. """ if not (result := is_four_digits(value)): raise ValueError(f"'{value}' is not a four-digit year.") return result _ANY_SEPARATOR = ( r"(?:" + r"|".join(YearRangeSeparator.__args__) + r")" # type: ignore ) #: A regex pattern to match e.g. '2017-2020'. YEAR_RANGE_PATTERN = re.compile( r"(?P\d{4})" r"(?:" r"(?:(?P" + _ANY_SEPARATOR + r")" r"(?P\S+)?)" r"|" r"(?:\s+(?P" + _ANY_SEPARATOR + r")" r"\s+(?P\d{4}))" r")?" ) _YEAR_RANGE_PATTERN_ANONYMISED = re.sub( r"\(\?P<\w+>", r"(?:", YEAR_RANGE_PATTERN.pattern ) _SYMBOL_OR_C_SUBPATTERN = r"(©|\([Cc]\))" _STRING_SUBPATTERN = ( r"(Copyright((\s*" + _SYMBOL_OR_C_SUBPATTERN + r")|(?=\s)))" ) #: A regex pattern to match a complete and valid REUSE copyright notice. COPYRIGHT_NOTICE_PATTERN = re.compile( r"(?P(" r"SPDX-(File|Snippet)CopyrightText:" + r"(\s*(" + _SYMBOL_OR_C_SUBPATTERN + "|" + _STRING_SUBPATTERN + "))?" + r"|" + _STRING_SUBPATTERN + r"|" r"©" r"))" r"\s*" r"(?P.*?)" r"\s*" ) _YEARS_PATTERN = re.compile( r"(?P(^|,?\s+))(?P" + _YEAR_RANGE_PATTERN_ANONYMISED + r"((\s*,\s*|\s+)" + _YEAR_RANGE_PATTERN_ANONYMISED + r")*)(?P,?(\s+|$))" ) _COMMA_SPACE_PATTERN = re.compile(r"^,?\s+") _LOOKBEHINDS = "".join( rf"(? str: """Given an uppercase NAME, return name. Underscores are converted to dashes. >>> CopyrightPrefix.lowercase_name("SPDX_STRING") 'spdx-string' """ return name.lower().replace("_", "-") @staticmethod def uppercase_name(name: str) -> str: """Given a lowercase name, return NAME. Dashes are converted to underscores. >>> CopyrightPrefix.uppercase_name("spdx-string") 'SPDX_STRING' """ return name.upper().replace("-", "_") @dataclass(frozen=True) class YearRange: """Represents a year range, such as '2017-2025', or '2017'. This only represents a single range; multiple separated ranges should be put in a collection (typically a tuple). """ #: The first year in the range. If it is only a single year, this is the #: only relevant value. start: FourDigitString #: The separator between :attr:`start` and :attr:`end`. If no value for #: :attr:`end` is provided, a range into infinity is implied, and #: :attr:`end` becomes an empty string. separator: YearRangeSeparator | None = field(default=None, compare=False) #: The second year in the range. This can also be a word like 'Present'. #: This is bad practice, but still supported. end: FourDigitString | str | None = None #: If parsed from a string, this contains the original string. original: str | None = field( default=None, init=False, repr=False, compare=False ) def __post_init__(self) -> None: if self.separator is not None and self.end is None: object.__setattr__(self, "end", "") # TODO: In Python 3.11, return Self @classmethod def from_string(cls, value: str) -> "YearRange": """Create a :class:`YearRange` object from a string. Raises: YearRangeParseError: The string is not a valid year range. """ re_result = YEAR_RANGE_PATTERN.fullmatch(value) if not re_result: raise YearRangeParseError(f"'{value}' is not a valid year range.") groups = re_result.groupdict() start = groups["start"] separator = groups["separator_nonspaced"] or groups["separator_spaced"] end = groups["end_nonspaced"] or groups["end_spaced"] # Mypy is disabled for this because the values are enforced by the # regex. This could be cleaner, but would require a lot of useless code # to validate what the regex already enforces. result = cls(start, separator, end) # type: ignore object.__setattr__(result, "original", value) return result @classmethod def tuple_from_string(cls, value: str) -> tuple["YearRange", ...]: """Create a tuple of :class:`YearRange` objects from a string containing multiple ranges. Raises: YearRangeParseError: The substring is not a valid year range. """ years: list[YearRange] = [] for year in _YEAR_RANGE_SPLIT_REGEX.split(value): if not year: continue years.append(YearRange.from_string(year)) return tuple(years) def __str__(self) -> str: result = StringIO() result.write(self.start) if self.separator: result.write(self.separator) if self.end: # Use a default separator if one is not defined. if not self.separator: result.write("-") result.write(self.end) return result.getvalue() def to_string(self, original: bool = False) -> str: """Converts the internal representation of the date range into a string. If *original* is :const:`True`, :attr:`original` is returned if it exists. If :attr:`start` and :attr:`end` are provided without :attr:`separator`, ``-`` will be used as default separator in the output. This method is identical to calling :func:`str` on this object, provided *original* is :const:`False`. """ if original and self.original is not None: return self.original return str(self) def __lt__(self, other: Any) -> bool: # pylint: disable=too-many-return-statements if not isinstance(other, YearRange): return NotImplemented # Start year determines most of the storting. if self.start < other.start: return True if self.start > other.start: return False # Ranges with end dates are sorted after those who don't. if self.end is None and other.end is not None: return True if self.end is not None and other.end is not None: # Non-digit ends are sorted after digit ends. if not is_four_digits(self.end) and is_four_digits(other.end): return False if is_four_digits(self.end) and not is_four_digits(other.end): return True return self.end < other.end # No comparing on separators. return False # TODO: In Python 3.11, use Self @classmethod def compact(cls, ranges: Iterable["YearRange"]) -> tuple["YearRange", ...]: """Given an iterable of :class:`YearRange`, compact them such that a new more concise list is returne without losing information. This process also sorts the ranges, such that ranges with lower starts come before ranges with higher starts. - Consecutive years (e.g. 2017, 2018, 2019) are turned into a single range (2017-2019). - Two consecutive years (e.g. 2017, 2018) are NOT turned turned into a single range. - Consecutive ranges (e.g. 2017-2019, 2020-2022) are turned into a single range (2017-2022). - Overlapping ranges (e.g. 2017-2022, 2019-2021) are turned into a single range (2017-2022). - Repeated ranges are removed. - Ranges with non-year ends (e.g. 2017-Present, 2020-Present) are only turned into a single range with ranges that have identical ends (2017-Present). """ ranges = sorted(ranges) compacted: list[YearRange] = [] if not ranges: return tuple() # TODO: In Python 3.11, use Self def filter_same_end(ranges: Iterable[YearRange]) -> list[YearRange]: """If some year ranges have the same end, then only take the ones with the lowest start. """ result: list[YearRange] = [] ends: defaultdict[str | None, list[YearRange]] = defaultdict(list) for item in ranges: ends[item.end].append(item) for key, range_list in ends.items(): if key is None: for item in range_list: result.append(item) else: # *ranges* is sorted, so take the first item with the lowest # start. result.append(range_list[0]) return sorted(result) ranges = filter_same_end(ranges) current_start: int = int(ranges[0].start) current_end: str = ( ranges[0].end if ranges[0].end is not None else ranges[0].start ) # TODO: In Python 3.11, use Self def add_to_compacted( start: int, end: str, next_range: YearRange | None ) -> None: nonlocal compacted if is_four_digits(end): if int(end) - start == 0: compacted.append(cls(validate_four_digits(str(start)))) elif int(end) - start == 1: compacted.append(cls(validate_four_digits(str(start)))) compacted.append(cls(validate_four_digits(end))) else: compacted.append( cls( validate_four_digits(str(start)), end=end, ) ) else: compacted.append(cls(validate_four_digits(str(start)), end=end)) nonlocal current_start nonlocal current_end if next_range is not None: current_start = int(next_range.start) current_end = ( next_range.end if next_range.end is not None else next_range.start ) next_start: int | None = None next_end: str | None = None for next_range in ranges[1:]: next_start = int(next_range.start) next_end = ( next_range.end if next_range.end is not None else next_range.start ) current_end_int: int | None = ( int(current_end) if is_four_digits(current_end) else None ) next_end_int: int | None = ( int(next_end) if is_four_digits(next_end) else None ) # The end lines up with next start. if ( current_end_int is not None and current_end_int + 1 >= next_start ): if next_end_int is not None: # In a strange scenario where the next range's end is BEFORE # its start, just save our progress and continue the loop. if next_end_int < next_start: add_to_compacted(current_start, current_end, next_range) # Increment the end. elif next_end_int >= current_end_int: current_end = next_end else: add_to_compacted(current_start, current_end, next_range) add_to_compacted(current_start, current_end, None) # If the beforelast range's end was int-y, and the last range's end is # string-y, we need to separately add the last range. if ( next_end is not None and is_four_digits(current_end) and not is_four_digits(next_end) ): add_to_compacted(cast(int, next_start), next_end, None) return tuple(compacted) def _most_common_prefix( copyright_notices: Iterable["CopyrightNotice"], ) -> CopyrightPrefix: """Given a number of :class:`CopyrightNotice`s, find the most common one. If there is a tie for the most common prefix, return enum which is defined before all others in :class:`CopyrightPrefix`. """ counter = Counter(notice.prefix for notice in copyright_notices) max_count = max(counter.values()) most_common = {key for key, value in counter.items() if value == max_count} # One prefix is more common than all others. if len(most_common) == 1: return next(iter(most_common)) # Enums preserve order of their members. Return the first match. for prefix in CopyrightPrefix: if prefix in most_common: return prefix # This shouldn't be reached. return CopyrightPrefix.SPDX @dataclass(frozen=True) class CopyrightNotice: """Represents a single copyright notice.""" #: The copyright holder. Strictly, this is all text in the copyright notice #: which is not part of *years*. name: str #: The prefix with which the copyright statement begins. prefix: CopyrightPrefix = CopyrightPrefix.SPDX #: The dates associated with the copyright notice. years: tuple[YearRange, ...] = field(default_factory=tuple) #: If parsed from a string, this contains the original string. original: str | None = field( default=None, init=False, repr=False, compare=False ) # TODO: In Python 3.11, return Self. @classmethod def from_string(cls, value: str) -> "CopyrightNotice": """Create a :class:`CopyrightNotice` object from a string. Raises: CopyrightNoticeParseError: The string is not a valid copyright notice. """ re_result = COPYRIGHT_NOTICE_PATTERN.fullmatch(value) if not re_result: raise CopyrightNoticeParseError( f"'{value}' is not a copyright notice." ) return cls.from_match(re_result) @staticmethod def _detect_prefix(prefix: str) -> CopyrightPrefix: """Given a matched prefix from :const:`COPYRIGHT_NOTICE_PATTERN`, detect the associated prefix. """ prefix_lower = prefix.lower() # String-match the prefix. for prefix_enum in ( cast(CopyrightPrefix, item) for item in reversed(CopyrightPrefix) ): # lower() is used to match (C) as well as (c). if prefix_lower == prefix_enum.value.lower(): return prefix_enum # The prefix could not be string-matched, most likely because there # was unexpected spacing in the prefix. Get a close match using # difflib. matches = difflib.get_close_matches( prefix, # TODO: In Python 3.11, this list comprehension is not needed. [item.value for item in CopyrightPrefix], n=1, cutoff=0.2, ) if matches: return CopyrightPrefix(matches[0]) # This shouldn't happen, but if no prefix could be found, # default to SPDX. return CopyrightPrefix.SPDX @classmethod def from_match(cls, value: re.Match) -> "CopyrightNotice": """Create a :class:`CopyrightNotice` object from a regular expression match using the :const:`COPYRIGHT_NOTICE_PATTERN` :class:`re.Pattern`. """ prefix = cls._detect_prefix(value.group("prefix")) re_text = value.group("text") year_ranges_substrings = list(_YEARS_PATTERN.finditer(re_text)) start_ends: list[tuple[int, int]] = [ (match.start("prefix"), match.end("years")) for match in year_ranges_substrings ] name_parts: list[str] = [] last = 0 for start, end in start_ends: name_parts.append(re_text[last:start]) last = end name_parts.append(re_text[last:]) name = "".join(name_parts) # Remove ', ' from the start of the name, which appears in e.g. # 'Copyright 2017, Jane Doe'. name = _COMMA_SPACE_PATTERN.sub("", name) years: tuple[YearRange, ...] = tuple() if year_ranges_substrings: years = tuple( chain.from_iterable( YearRange.tuple_from_string(match.group("years")) for match in year_ranges_substrings ) ) result = cls( name=name, prefix=prefix, years=years, ) object.__setattr__(result, "original", value.string) return result @classmethod def merge( cls, copyright_notices: Iterable["CopyrightNotice"] ) -> set["CopyrightNotice"]: """Given an iterable of :class:`CopyrightNotice`, merge all notices which have the same name. The years are compacted, and from the :class:`CopyrightPrefix` prefixes in *copyright_notices*, the most common is chosen. If there is a tie in frequency, choose the one which appears first in the enum. """ matches: defaultdict[str, list[CopyrightNotice]] = defaultdict(list) result: set[CopyrightNotice] = set() for notice in copyright_notices: matches[notice.name].append(notice) for key, value in matches.items(): result.add( cls( key, prefix=_most_common_prefix(value), years=YearRange.compact( chain.from_iterable(notice.years for notice in value) ), ) ) return result def __str__(self) -> str: result = StringIO() result.write(self.prefix.value) if self.years: result.write(" ") result.write( ", ".join(str(date_range) for date_range in self.years) ) result.write(f" {self.name}") return result.getvalue() def __lt__(self, other: "CopyrightNotice") -> bool: def norm(item: Any | None) -> tuple[int, Any]: """If no item is defined, return a tuple that sorts _after_ items that are defined. """ return (0, item) if item else (1, "") return ( norm(self.years), self.name, self.prefix.value, ) < ( norm(other.years), other.name, other.prefix.value, ) def to_string(self, original: bool = False) -> str: """Converts the internal representation of the copyright notice into a string. If *original* is :const:`True`, :attr:`original` is returned if it exists. This method is identical to calling :func:`str` on this object, provided *original* is :const:`False`. """ if original and self.original is not None: return self.original return str(self) @dataclass(frozen=True) class SpdxExpression: """A simple dataclass that contains an SPDX License Expression. Use :meth:`SpdxExpression.__str__` to get a string representation of the expression. """ #: A string representing an SPDX License Expression. It may be invalid. text: InitVar[str] _text: str = field(init=False, repr=True) def __post_init__(self, text: str) -> None: object.__setattr__(self, "_text", text) @cached_property def is_valid(self) -> bool: """If :attr:`text` is a valid SPDX License Expression, this property is :const:`True`. To be 'valid', it has to follow the grammar and syntax of the SPDX specification. The licenses and exceptions need not appear on the license list. """ return self._expression is not None @cached_property def _expression(self) -> LicenseExpression | None: """A parsed :class:`LicenseExpression` from :attr:`text`. If :attr:`text` could not be parsed, *_expression*'s value is :const:`None`. """ try: return _LICENSING.parse(self._text, simple=True) except ExpressionError: return None @cached_property def licenses(self) -> list[str]: """Return a list of licenses used in the expression, in order of appearance, without duplicates. If the expression is invalid, the list contains a single item :attr:`text`. """ if self._expression is not None: return _LICENSING.license_keys(self._expression) return [self._text] @classmethod def combine( cls, spdx_expressions: Iterable["SpdxExpression"], ) -> "SpdxExpression": """Combine the *spdx_expressions* into a single :class:`SpdxExpression`, joined by AND operators. """ is_valid = True for expression in spdx_expressions: if not expression.is_valid: is_valid = False if is_valid: return cls( str( combine_expressions( list( # pylint: disable=protected-access expression._expression for expression in spdx_expressions ) ) ) ) return cls( " AND ".join(f"({expression})" for expression in spdx_expressions) ) def simplify(self) -> "SpdxExpression": """If the expression is valid, return a new :class:`SpdxExpression` which is 'simplified', meaning that boolean operators are collapsed. 'MIT OR MIT' simplifies to 'MIT', and so forth. If the expression is not valid, ``self`` is returned. """ if self.is_valid: return self.__class__( str(cast(LicenseExpression, self._expression).simplify()) ) return self def __str__(self) -> str: """Return a string representation of the expression if it is valid. Otherwise, return :attr:`text`. """ if self._expression is not None: return str(self._expression) return self._text def __eq__(self, other: Any) -> bool: if not isinstance(other, SpdxExpression): return NotImplemented if self._expression is not None and other._expression is not None: return self._expression == other._expression return self._text == other._text def __lt__(self, other: Any) -> bool: if not isinstance(other, SpdxExpression): return NotImplemented return str(self) < str(other) 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" @dataclass(frozen=True, kw_only=True) class ReuseInfo: """Simple dataclass holding licensing and copyright information""" spdx_expressions: set[SpdxExpression] = field(default_factory=set) copyright_notices: set[CopyrightNotice] = field(default_factory=set) contributor_lines: set[str] = field(default_factory=set) path: str | None = None source_path: str | None = None source_type: SourceType | None = 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, *other: "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(s) in *other*. All non-set attributes are set to their values in *self*. >>> one = ReuseInfo(copyright_notices={CopyrightNotice("Jane Doe")}, ... source_path="foo.py") >>> two = ReuseInfo(copyright_notices={CopyrightNotice("John Doe")}, ... source_path="bar.py") >>> result = one.union(two) >>> print([notice.name for notice in sorted(result.copyright_notices)]) ['Jane Doe', 'John Doe'] >>> print(result.source_path) foo.py """ if not other: return self new_kwargs = {} for key, attr_val in self.__dict__.items(): if isinstance(attr_val, set): new_kwargs[key] = attr_val.union( *(getattr(info, key) for info in other) ) 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_notices* is non-empty.""" return bool(self.spdx_expressions or self.copyright_notices) def contains_copyright_xor_licensing(self) -> bool: """One of *spdx_expressions* or *copyright_notices* is non-empty.""" return bool(self.spdx_expressions) ^ bool(self.copyright_notices) 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) # REUSE-IgnoreEnd reuse-tool-6.2.0/src/reuse/py.typed0000664000175000017500000000017215077707000015677 0ustar alexalex# SPDX-FileCopyrightText: 2023 Carmen Bianca BAKKER # # SPDX-License-Identifier: GPL-3.0-or-later reuse-tool-6.2.0/src/reuse/exceptions.py0000664000175000017500000000434315077707000016737 0ustar alexalex# SPDX-FileCopyrightText: 2017 Free Software Foundation Europe e.V. # # SPDX-License-Identifier: GPL-3.0-or-later """All exceptions owned by :mod:`reuse`. These exceptions all inherit :class:`ReuseError`. """ from typing import Any class ReuseError(Exception): """Base exception.""" class SpdxIdentifierNotFoundError(ReuseError): """Could not find SPDX identifier for license file.""" class GlobalLicensingParseError(ReuseError): """An exception representing any kind of error that occurs when trying to parse a :class:`reuse.global_licensing.GlobalLicensing` file. """ def __init__(self, *args: Any, source: str | None = None): super().__init__(*args) self.source = source class GlobalLicensingParseTypeError(GlobalLicensingParseError, TypeError): """An exception representing a type error while trying to parse a :class:`reuse.global_licensing.GlobalLicensing` file. """ class GlobalLicensingParseValueError(GlobalLicensingParseError, ValueError): """An exception representing a value error while trying to parse a :class:`reuse.global_licensing.GlobalLicensing` file. """ class GlobalLicensingConflictError(ReuseError): """There are two global licensing files in the project that are not compatible. """ class MissingReuseInfoError(ReuseError): """Some REUSE information is missing from the result.""" class CommentError(ReuseError): """An error occurred during an interaction with a comment.""" class CommentCreateError(CommentError): """An error occurred during the creation of a comment.""" class CommentParseError(CommentError): """An error occurred during the parsing of a comment.""" class CopyrightNoticeParseError(ReuseError): """Error for parsing a :class:`reuse.copyright.CopyrightNotice` from a string. """ class YearRangeParseError(CopyrightNoticeParseError): """Error for parsing a :class:`reuse.copyright.YearRange` from a string. Because a year range is typically a constituent part of a copyright notice, this error is a subclass of :class:`CopyrightNoticeParseError`. """ class NoEncodingModuleError(ReuseError): """No module that can detect the encoding of a file is importable.""" reuse-tool-6.2.0/src/reuse/__init__.py0000664000175000017500000000216515077707000016315 0ustar alexalex# 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. """ from importlib.metadata import PackageNotFoundError, version try: __version__ = version("reuse") except PackageNotFoundError: # package is not installed __version__ = "6.2.0" __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.3" reuse-tool-6.2.0/src/reuse/resources/0000775000175000017500000000000015077707000016212 5ustar alexalexreuse-tool-6.2.0/src/reuse/resources/licenses.json0000664000175000017500000115647115077707000020731 0ustar alexalex{ "licenseListVersion": "3.27.0", "licenses": [ { "reference": "https://spdx.org/licenses/0BSD.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/0BSD.json", "referenceNumber": 316, "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": 61, "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": 424, "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": 252, "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": 315, "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": 658, "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": 499, "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": 492, "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": 554, "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": 76, "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": 7, "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": 480, "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": 41, "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": 682, "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": 343, "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": 84, "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": 38, "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": 415, "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": 24, "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": 427, "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": 191, "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": 469, "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": 495, "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": 437, "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": 194, "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": 644, "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": 439, "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": 15, "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": 25, "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": 218, "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": 74, "name": "Any OSI License", "licenseId": "any-OSI", "seeAlso": [ "https://metacpan.org/pod/Exporter::Tidy#LICENSE" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/any-OSI-perl-modules.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/any-OSI-perl-modules.json", "referenceNumber": 230, "name": "Any OSI License - Perl Modules", "licenseId": "any-OSI-perl-modules", "seeAlso": [ "https://metacpan.org/release/JUERD/Exporter-Tidy-0.09/view/Tidy.pm#LICENSE", "https://metacpan.org/pod/Qmail::Deliverable::Client#LICENSE", "https://metacpan.org/pod/Net::MQTT::Simple#LICENSE" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/Apache-1.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Apache-1.0.json", "referenceNumber": 379, "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": 111, "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": 162, "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", "https://opensource.org/license/apache-2-0" ], "isOsiApproved": true, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/APAFML.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/APAFML.json", "referenceNumber": 474, "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": 127, "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": 155, "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": 86, "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": 23, "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": 265, "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": 568, "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": 649, "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": 291, "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": 20, "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": 217, "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/Artistic-dist.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Artistic-dist.json", "referenceNumber": 511, "name": "Artistic License 1.0 (dist)", "licenseId": "Artistic-dist", "seeAlso": [ "https://github.com/pexip/os-perl/blob/833cf4c86cc465ccfc627ff16db67e783156a248/debian/copyright#L2720-L2845" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/Aspell-RU.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Aspell-RU.json", "referenceNumber": 231, "name": "Aspell Russian License", "licenseId": "Aspell-RU", "seeAlso": [ "https://ftp.gnu.org/gnu/aspell/dict/ru/aspell6-ru-0.99f7-1.tar.bz2" ], "isOsiApproved": false }, { "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": 340, "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": 153, "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": 311, "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": 505, "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": 420, "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": 167, "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": 556, "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": 47, "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": 208, "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": 156, "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": 325, "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": 680, "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": 51, "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": 92, "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/Boehm-GC-without-fee.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Boehm-GC-without-fee.json", "referenceNumber": 466, "name": "Boehm-Demers-Weiser GC License (without fee)", "licenseId": "Boehm-GC-without-fee", "seeAlso": [ "https://github.com/MariaDB/server/blob/11.6/libmysqld/lib_sql.cc" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/Borceux.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Borceux.json", "referenceNumber": 335, "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": 198, "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": 675, "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": 286, "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": 430, "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": 477, "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": 543, "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": 622, "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": 531, "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": 584, "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-pkgconf-disclaimer.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/BSD-2-Clause-pkgconf-disclaimer.json", "referenceNumber": 624, "name": "BSD 2-Clause pkgconf disclaimer variant", "licenseId": "BSD-2-Clause-pkgconf-disclaimer", "seeAlso": [ "https://github.com/audacious-media-player/audacious/blob/master/src/audacious/main.cc", "https://github.com/audacious-media-player/audacious/blob/master/COPYING" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/BSD-2-Clause-Views.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/BSD-2-Clause-Views.json", "referenceNumber": 536, "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": 567, "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": 277, "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": 159, "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": 259, "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": 205, "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": 643, "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": 6, "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": 497, "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": 498, "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": 108, "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": 239, "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": 606, "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": 637, "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": 240, "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": 227, "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": 269, "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": 21, "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": 434, "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": 685, "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": 345, "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": 506, "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": 535, "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": 163, "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": 383, "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": 450, "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": 602, "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": 422, "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": 130, "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": 234, "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": 412, "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": 243, "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": 660, "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": 305, "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": 569, "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": 483, "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": 401, "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": 581, "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": 97, "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": 559, "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": 441, "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": 292, "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": 126, "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": 576, "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": 107, "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": 648, "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": 458, "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": 410, "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": 436, "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": 366, "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": 66, "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": 428, "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": 553, "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": 49, "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": 686, "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": 324, "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": 560, "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": 442, "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": 334, "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": 215, "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": 94, "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": 185, "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": 577, "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": 53, "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": 510, "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": 199, "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": 356, "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": 301, "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": 671, "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": 659, "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": 359, "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": 279, "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": 636, "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": 89, "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": 118, "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": 587, "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": 394, "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": 457, "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": 610, "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": 11, "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": 384, "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": 260, "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": 197, "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": 149, "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": 631, "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": 79, "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": 493, "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": 683, "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": 571, "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": 256, "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": 273, "name": "Creative Commons Public Domain Dedication and Certification", "licenseId": "CC-PDDC", "seeAlso": [ "https://creativecommons.org/licenses/publicdomain/" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/CC-PDM-1.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/CC-PDM-1.0.json", "referenceNumber": 547, "name": "Creative Commons Public Domain Mark 1.0 Universal", "licenseId": "CC-PDM-1.0", "seeAlso": [ "https://creativecommons.org/publicdomain/mark/1.0/", "https://creativecommons.org/share-your-work/cclicenses/" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/CC-SA-1.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/CC-SA-1.0.json", "referenceNumber": 85, "name": "Creative Commons Share Alike 1.0 Generic", "licenseId": "CC-SA-1.0", "seeAlso": [ "https://creativecommons.org/licenses/sa/1.0/legalcode" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/CC0-1.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/CC0-1.0.json", "referenceNumber": 369, "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": 407, "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": 124, "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": 385, "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": 454, "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": 520, "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": 548, "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": 468, "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": 100, "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": 370, "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": 95, "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": 425, "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": 45, "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": 398, "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": 318, "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": 200, "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": 175, "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": 219, "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": 207, "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": 377, "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": 389, "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": 690, "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": 65, "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": 178, "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": 391, "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": 138, "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": 352, "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": 673, "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": 526, "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": 695, "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": 114, "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": 122, "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": 583, "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": 331, "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": 147, "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": 367, "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": 250, "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": 32, "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": 347, "name": "Crossword License", "licenseId": "Crossword", "seeAlso": [ "https://fedoraproject.org/wiki/Licensing/Crossword" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/CryptoSwift.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/CryptoSwift.json", "referenceNumber": 323, "name": "CryptoSwift License", "licenseId": "CryptoSwift", "seeAlso": [ "https://github.com/krzyzanowskim/CryptoSwift/blob/main/LICENSE" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/CrystalStacker.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/CrystalStacker.json", "referenceNumber": 449, "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": 298, "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": 140, "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": 160, "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": 216, "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": 545, "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": 164, "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": 50, "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": 530, "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": 139, "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": 31, "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/DocBook-DTD.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/DocBook-DTD.json", "referenceNumber": 603, "name": "DocBook DTD License", "licenseId": "DocBook-DTD", "seeAlso": [ "http://www.docbook.org/xml/simple/1.1/docbook-simple-1.1.zip" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/DocBook-Schema.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/DocBook-Schema.json", "referenceNumber": 184, "name": "DocBook Schema License", "licenseId": "DocBook-Schema", "seeAlso": [ "https://github.com/docbook/xslt10-stylesheets/blob/efd62655c11cc8773708df7a843613fa1e932bf8/xsl/assembly/schema/docbook51b7.rnc" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/DocBook-Stylesheet.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/DocBook-Stylesheet.json", "referenceNumber": 494, "name": "DocBook Stylesheet License", "licenseId": "DocBook-Stylesheet", "seeAlso": [ "http://www.docbook.org/xml/5.0/docbook-5.0.zip" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/DocBook-XML.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/DocBook-XML.json", "referenceNumber": 672, "name": "DocBook XML License", "licenseId": "DocBook-XML", "seeAlso": [ "https://github.com/docbook/xslt10-stylesheets/blob/efd62655c11cc8773708df7a843613fa1e932bf8/xsl/COPYING#L27" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/Dotseqn.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Dotseqn.json", "referenceNumber": 257, "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": 446, "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": 135, "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": 336, "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": 578, "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": 319, "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": 641, "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": 338, "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": 647, "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": 145, "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": 604, "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": 613, "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": 396, "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": 40, "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": 158, "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": 558, "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": 326, "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", "https://www.eclipse.org/legal/epl-v20.html", "https://projects.eclipse.org/license/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": 541, "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": 363, "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": 262, "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": 405, "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": 393, "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": 596, "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": 299, "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": 190, "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": 476, "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": 44, "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": 662, "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": 376, "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": 645, "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": 264, "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": 561, "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": 629, "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": 59, "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": 322, "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/FSFULLRSD.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/FSFULLRSD.json", "referenceNumber": 300, "name": "FSF Unlimited License (with License Retention and Short Disclaimer)", "licenseId": "FSFULLRSD", "seeAlso": [ "https://git.savannah.gnu.org/cgit/gnulib.git/tree/modules/COPYING?id\u003d7b08932179d0d6b017f7df01a2ddf6e096b038e3" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/FSFULLRWD.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/FSFULLRWD.json", "referenceNumber": 245, "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/FSL-1.1-ALv2.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/FSL-1.1-ALv2.json", "referenceNumber": 585, "name": "Functional Source License, Version 1.1, ALv2 Future License", "licenseId": "FSL-1.1-ALv2", "seeAlso": [ "https://fsl.software/FSL-1.1-ALv2.template.md" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/FSL-1.1-MIT.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/FSL-1.1-MIT.json", "referenceNumber": 639, "name": "Functional Source License, Version 1.1, MIT Future License", "licenseId": "FSL-1.1-MIT", "seeAlso": [ "https://fsl.software/FSL-1.1-MIT.template.md" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/FTL.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/FTL.json", "referenceNumber": 417, "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": 72, "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/Game-Programming-Gems.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Game-Programming-Gems.json", "referenceNumber": 246, "name": "Game Programming Gems License", "licenseId": "Game-Programming-Gems", "seeAlso": [ "https://github.com/OGRECave/ogre/blob/master/OgreMain/include/OgreSingleton.h#L28C3-L35C46" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/GCR-docs.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/GCR-docs.json", "referenceNumber": 270, "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": 549, "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/generic-xts.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/generic-xts.json", "referenceNumber": 132, "name": "Generic XTS License", "licenseId": "generic-xts", "seeAlso": [ "https://github.com/mhogomchungu/zuluCrypt/blob/master/external_libraries/tcplay/generic_xts.c" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/GFDL-1.1.html", "isDeprecatedLicenseId": true, "detailsUrl": "https://spdx.org/licenses/GFDL-1.1.json", "referenceNumber": 533, "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": 271, "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": 538, "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": 609, "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": 689, "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": 456, "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": 67, "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": 350, "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": 192, "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": 261, "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": 101, "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": 244, "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": 595, "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": 488, "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": 652, "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": 69, "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": 550, "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": 516, "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": 73, "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": 223, "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": 633, "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": 519, "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": 360, "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": 71, "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": 635, "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": 27, "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": 247, "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": 10, "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": 177, "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": 152, "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": 68, "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": 688, "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": 144, "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": 461, "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", "https://github.com/openjdk/jdk/blob/6162e2c5213c5dd7c1127fd9616b543efa898962/LICENSE" ], "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": 99, "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", "https://github.com/openjdk/jdk/blob/6162e2c5213c5dd7c1127fd9616b543efa898962/LICENSE" ], "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": 618, "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": 358, "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": 171, "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": 151, "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": 525, "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": 503, "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": 131, "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": 632, "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": 467, "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": 650, "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": 601, "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": 255, "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": 668, "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": 465, "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": 524, "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": 605, "name": "Haskell Language Report License", "licenseId": "HaskellReport", "seeAlso": [ "https://fedoraproject.org/wiki/Licensing/Haskell_Language_Report_License" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/HDF5.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/HDF5.json", "referenceNumber": 19, "name": "HDF5 License", "licenseId": "HDF5", "seeAlso": [ "https://github.com/HDFGroup/hdf5/?tab\u003dLicense-1-ov-file#readme" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/hdparm.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/hdparm.json", "referenceNumber": 283, "name": "hdparm License", "licenseId": "hdparm", "seeAlso": [ "https://github.com/Distrotech/hdparm/blob/4517550db29a91420fb2b020349523b1b4512df2/LICENSE.TXT" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/HIDAPI.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/HIDAPI.json", "referenceNumber": 310, "name": "HIDAPI License", "licenseId": "HIDAPI", "seeAlso": [ "https://github.com/signal11/hidapi/blob/master/LICENSE-orig.txt" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/Hippocratic-2.1.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Hippocratic-2.1.json", "referenceNumber": 87, "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": 282, "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": 8, "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": 209, "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": 112, "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": 600, "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": 306, "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": 459, "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": 487, "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": 172, "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": 1, "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": 445, "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": 233, "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": 228, "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": 528, "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": 623, "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": 157, "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": 313, "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-Netrek.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/HPND-Netrek.json", "referenceNumber": 387, "name": "Historical Permission Notice and Disclaimer - Netrek variant", "licenseId": "HPND-Netrek", "seeAlso": [], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/HPND-Pbmplus.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/HPND-Pbmplus.json", "referenceNumber": 339, "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": 341, "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": 681, "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": 13, "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", "https://github.com/kfish/xsel/blob/master/COPYING" ], "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": 225, "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": 357, "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": 210, "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": 143, "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": 478, "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": 242, "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": 289, "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": 399, "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": 512, "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": 694, "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": 472, "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": 482, "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": 552, "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": 52, "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": 328, "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/InnoSetup.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/InnoSetup.json", "referenceNumber": 354, "name": "Inno Setup License", "licenseId": "InnoSetup", "seeAlso": [ "https://github.com/jrsoftware/issrc/blob/HEAD/license.txt" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/Intel.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Intel.json", "referenceNumber": 419, "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": 206, "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": 532, "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": 186, "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": 591, "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": 58, "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": 317, "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": 475, "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": 103, "name": "JasPer License", "licenseId": "JasPer-2.0", "seeAlso": [ "http://www.ece.uvic.ca/~mdadams/jasper/LICENSE" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/jove.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/jove.json", "referenceNumber": 642, "name": "Jove License", "licenseId": "jove", "seeAlso": [ "https://github.com/jonmacs/jove/blob/4_17/LICENSE" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/JPL-image.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/JPL-image.json", "referenceNumber": 321, "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": 655, "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": 54, "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": 491, "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": 312, "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": 332, "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": 134, "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": 521, "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": 43, "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": 523, "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": 137, "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": 676, "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": 409, "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": 329, "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": 75, "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": 677, "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": 448, "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": 297, "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": 187, "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": 9, "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": 169, "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": 634, "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": 502, "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": 123, "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": 62, "name": "libpng License", "licenseId": "Libpng", "seeAlso": [ "http://www.libpng.org/pub/png/src/libpng-LICENSE.txt" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/libpng-1.6.35.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/libpng-1.6.35.json", "referenceNumber": 429, "name": "PNG Reference Library License v1 (for libpng 0.5 through 1.6.35)", "licenseId": "libpng-1.6.35", "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": 226, "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": 263, "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": 35, "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": 402, "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": 232, "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": 229, "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": 238, "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": 78, "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": 640, "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": 592, "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": 202, "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": 513, "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": 237, "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": 5, "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": 136, "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": 656, "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": 63, "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": 542, "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": 486, "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": 280, "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": 33, "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": 563, "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": 661, "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": 349, "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": 504, "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": 539, "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": 433, "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": 373, "name": "magaz License", "licenseId": "magaz", "seeAlso": [ "https://mirrors.nic.cz/tex-archive/macros/latex/contrib/magaz/magaz.tex", "https://mirrors.ctan.org/macros/latex/contrib/version/version.sty" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/mailprio.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/mailprio.json", "referenceNumber": 381, "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": 165, "name": "MakeIndex License", "licenseId": "MakeIndex", "seeAlso": [ "https://fedoraproject.org/wiki/Licensing/MakeIndex" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/man2html.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/man2html.json", "referenceNumber": 120, "name": "man2html License", "licenseId": "man2html", "seeAlso": [ "http://primates.ximian.com/~flucifredi/man/man-1.6g.tar.gz", "https://github.com/hamano/man2html/blob/master/man2html.c", "https://docs.oracle.com/cd/E81115_01/html/E81116/licenses.html" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/Martin-Birgmeier.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Martin-Birgmeier.json", "referenceNumber": 361, "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": 489, "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": 455, "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": 28, "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/MIPS.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/MIPS.json", "referenceNumber": 351, "name": "MIPS License", "licenseId": "MIPS", "seeAlso": [ "https://sourceware.org/cgit/binutils-gdb/tree/include/coff/sym.h#n11" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/MirOS.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/MirOS.json", "referenceNumber": 692, "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": 515, "name": "MIT License", "licenseId": "MIT", "seeAlso": [ "https://opensource.org/license/mit/", "http://opensource.org/licenses/MIT" ], "isOsiApproved": true, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/MIT-0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/MIT-0.json", "referenceNumber": 173, "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": 440, "name": "Enlightenment License (e16)", "licenseId": "MIT-advertising", "seeAlso": [ "https://fedoraproject.org/wiki/Licensing/MIT_With_Advertising" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/MIT-Click.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/MIT-Click.json", "referenceNumber": 438, "name": "MIT Click License", "licenseId": "MIT-Click", "seeAlso": [ "https://github.com/kohler/t1utils/blob/master/LICENSE" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/MIT-CMU.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/MIT-CMU.json", "referenceNumber": 287, "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": 580, "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": 408, "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": 18, "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": 508, "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": 304, "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": 404, "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/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": 496, "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": 355, "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": 473, "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": 663, "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": 507, "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": 303, "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": 213, "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": 102, "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": 665, "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": 679, "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": 599, "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": 174, "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": 17, "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": 674, "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": 698, "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": 276, "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": 588, "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": 320, "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": 182, "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": 60, "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": 288, "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": 462, "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": 432, "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": 307, "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": 460, "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": 696, "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": 392, "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": 154, "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": 148, "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": true, "detailsUrl": "https://spdx.org/licenses/Net-SNMP.json", "referenceNumber": 638, "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": 626, "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": 607, "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": 64, "name": "Nethack General Public License", "licenseId": "NGPL", "seeAlso": [ "https://opensource.org/licenses/NGPL" ], "isOsiApproved": true }, { "reference": "https://spdx.org/licenses/ngrep.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/ngrep.json", "referenceNumber": 16, "name": "ngrep License", "licenseId": "ngrep", "seeAlso": [ "https://github.com/jpr5/ngrep/blob/master/LICENSE" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/NICTA-1.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/NICTA-1.0.json", "referenceNumber": 406, "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": 98, "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": 616, "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": 447, "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": 249, "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": 687, "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": 161, "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": 464, "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": 471, "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": 77, "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": 372, "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": 518, "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": 195, "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": 146, "name": "NRL License", "licenseId": "NRL", "seeAlso": [ "http://web.mit.edu/network/isakmp/nrllicense.html" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/NTIA-PD.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/NTIA-PD.json", "referenceNumber": 426, "name": "NTIA Public Domain Notice", "licenseId": "NTIA-PD", "seeAlso": [ "https://raw.githubusercontent.com/NTIA/itm/refs/heads/master/LICENSE.md", "https://raw.githubusercontent.com/NTIA/scos-sensor/refs/heads/master/LICENSE.md" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/NTP.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/NTP.json", "referenceNumber": 621, "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": 566, "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": 203, "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": 485, "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": 251, "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": 371, "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": 274, "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": 397, "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": 46, "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": 368, "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": 589, "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": 653, "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": 201, "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": 608, "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": 204, "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": 82, "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": 612, "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": 129, "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": 544, "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": 168, "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": 400, "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": 570, "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": 534, "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": 333, "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": 281, "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": 386, "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": 105, "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": 657, "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": 654, "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": 170, "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": 667, "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": 378, "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": 314, "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": 411, "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": 382, "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": 443, "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": 344, "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": 574, "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": 364, "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": 121, "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": 116, "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": 2, "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": 275, "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": 128, "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": 36, "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": 614, "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": 285, "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": 414, "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": 183, "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": 651, "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": 453, "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": 179, "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": 29, "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": 3, "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": 284, "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": 241, "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": 235, "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": 684, "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": 133, "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": 221, "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": 435, "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": 670, "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": 181, "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": 691, "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": 119, "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": 30, "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": 697, "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": 150, "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": 211, "name": "Python Software Foundation License 2.0", "licenseId": "PSF-2.0", "seeAlso": [ "https://opensource.org/licenses/Python-2.0", "https://matplotlib.org/stable/project/license.html" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/psfrag.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/psfrag.json", "referenceNumber": 423, "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": 500, "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": 628, "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": 586, "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": 630, "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": 590, "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": 693, "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": 117, "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": 678, "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": 4, "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": 258, "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": 57, "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": 413, "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": 104, "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": 12, "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": 166, "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": 490, "name": "Ruby License", "licenseId": "Ruby", "seeAlso": [ "https://www.ruby-lang.org/en/about/license.txt" ], "isOsiApproved": false, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/Ruby-pty.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Ruby-pty.json", "referenceNumber": 509, "name": "Ruby pty extension license", "licenseId": "Ruby-pty", "seeAlso": [ "https://github.com/ruby/ruby/blob/9f6deaa6888a423720b4b127b5314f0ad26cc2e6/ext/pty/pty.c#L775-L786", "https://github.com/ruby/ruby/commit/0a64817fb80016030c03518fb9459f63c11605ea#diff-ef5fa30838d6d0cecad9e675cc50b24628cfe2cb277c346053fafcc36c91c204", "https://github.com/ruby/ruby/commit/0a64817fb80016030c03518fb9459f63c11605ea#diff-fedf217c1ce44bda01f0a678d3ff8b198bed478754d699c527a698ad933979a0" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/SAX-PD.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/SAX-PD.json", "referenceNumber": 22, "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": 346, "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": 390, "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": 484, "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": 91, "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": 266, "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": 55, "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/Sendmail-Open-Source-1.1.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Sendmail-Open-Source-1.1.json", "referenceNumber": 620, "name": "Sendmail Open Source License v1.1", "licenseId": "Sendmail-Open-Source-1.1", "seeAlso": [ "https://github.com/trusteddomainproject/OpenDMARC/blob/master/LICENSE.Sendmail" ], "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": 56, "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": 296, "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": 617, "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": 34, "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": 572, "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": 267, "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": 582, "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": 452, "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": 110, "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": 253, "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": 83, "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": 42, "name": "Sleepycat License", "licenseId": "Sleepycat", "seeAlso": [ "https://opensource.org/licenses/Sleepycat" ], "isOsiApproved": true, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/SMAIL-GPL.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/SMAIL-GPL.json", "referenceNumber": 546, "name": "SMAIL General Public License", "licenseId": "SMAIL-GPL", "seeAlso": [ "https://sources.debian.org/copyright/license/debianutils/4.11.2/" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/SMLNJ.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/SMLNJ.json", "referenceNumber": 81, "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": 579, "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": 224, "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": 594, "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/SOFA.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/SOFA.json", "referenceNumber": 375, "name": "SOFA Software License", "licenseId": "SOFA", "seeAlso": [ "http://www.iausofa.org/tandc.html" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/softSurfer.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/softSurfer.json", "referenceNumber": 593, "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": 374, "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": 193, "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": 451, "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": 220, "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": 342, "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": 537, "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": 463, "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": 573, "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": 96, "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": 664, "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": 501, "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": 222, "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/SUL-1.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/SUL-1.0.json", "referenceNumber": 557, "name": "Sustainable Use License v1.0", "licenseId": "SUL-1.0", "seeAlso": [ "https://github.com/n8n-io/n8n/blob/master/LICENSE.md" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/Sun-PPP.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Sun-PPP.json", "referenceNumber": 39, "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": 70, "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": 395, "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": 196, "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": 348, "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": 517, "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": 80, "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": 625, "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": 278, "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": 619, "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": 142, "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/ThirdEye.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/ThirdEye.json", "referenceNumber": 403, "name": "ThirdEye License", "licenseId": "ThirdEye", "seeAlso": [ "https://sourceware.org/cgit/binutils-gdb/tree/include/coff/symconst.h#n11" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/threeparttable.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/threeparttable.json", "referenceNumber": 14, "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": 176, "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": 214, "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": 416, "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": 666, "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": 540, "name": "THOR Public License 1.0", "licenseId": "TPL-1.0", "seeAlso": [ "https://fedoraproject.org/wiki/Licensing:ThorPublicLicense" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/TrustedQSL.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/TrustedQSL.json", "referenceNumber": 37, "name": "TrustedQSL License", "licenseId": "TrustedQSL", "seeAlso": [ "https://sourceforge.net/p/trustedqsl/tqsl/ci/master/tree/LICENSE.txt" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/TTWL.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/TTWL.json", "referenceNumber": 598, "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": 236, "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": 106, "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": 669, "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/Ubuntu-font-1.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Ubuntu-font-1.0.json", "referenceNumber": 268, "name": "Ubuntu Font Licence v1.0", "licenseId": "Ubuntu-font-1.0", "seeAlso": [ "https://ubuntu.com/legal/font-licence", "https://assets.ubuntu.com/v1/81e5605d-ubuntu-font-licence-1.0.txt" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/UCAR.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/UCAR.json", "referenceNumber": 353, "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": 611, "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": 514, "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": 48, "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": 308, "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": 254, "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": 309, "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": 115, "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": 180, "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": 337, "name": "The Unlicense", "licenseId": "Unlicense", "seeAlso": [ "https://unlicense.org/" ], "isOsiApproved": true, "isFsfLibre": true }, { "reference": "https://spdx.org/licenses/Unlicense-libtelnet.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Unlicense-libtelnet.json", "referenceNumber": 113, "name": "Unlicense - libtelnet variant", "licenseId": "Unlicense-libtelnet", "seeAlso": [ "https://github.com/seanmiddleditch/libtelnet/blob/develop/COPYING" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/Unlicense-libwhirlpool.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Unlicense-libwhirlpool.json", "referenceNumber": 565, "name": "Unlicense - libwhirlpool variant", "licenseId": "Unlicense-libwhirlpool", "seeAlso": [ "https://github.com/dfateyev/libwhirlpool/blob/master/README#L27" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/UPL-1.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/UPL-1.0.json", "referenceNumber": 88, "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": 380, "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": 327, "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": 575, "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": 562, "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": 479, "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": 365, "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": 295, "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": true }, { "reference": "https://spdx.org/licenses/w3m.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/w3m.json", "referenceNumber": 141, "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": 527, "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": 522, "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": 564, "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": 418, "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/wwl.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/wwl.json", "referenceNumber": 627, "name": "WWL License", "licenseId": "wwl", "seeAlso": [ "http://www.db.net/downloads/wwl+db-1.3.tgz" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/wxWindows.html", "isDeprecatedLicenseId": true, "detailsUrl": "https://spdx.org/licenses/wxWindows.json", "referenceNumber": 431, "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": 0, "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": 302, "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/X11-swapped.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/X11-swapped.json", "referenceNumber": 248, "name": "X11 swapped final paragraphs", "licenseId": "X11-swapped", "seeAlso": [ "https://github.com/fedeinthemix/chez-srfi/blob/master/srfi/LICENSE" ], "isOsiApproved": false }, { "reference": "https://spdx.org/licenses/Xdebug-1.03.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Xdebug-1.03.json", "referenceNumber": 109, "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": 615, "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": 125, "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": 646, "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": 93, "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": 212, "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": 362, "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": 470, "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": 290, "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": 293, "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": 90, "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": 294, "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": 481, "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": 189, "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": 551, "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": 444, "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": 26, "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": 330, "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": 421, "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": 188, "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": 597, "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": 555, "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": 272, "name": "Zope Public License 2.1", "licenseId": "ZPL-2.1", "seeAlso": [ "http://old.zope.org/Resources/ZPL/" ], "isOsiApproved": true, "isFsfLibre": true } ], "releaseDate": "2025-07-01T00:00:00Z" }reuse-tool-6.2.0/src/reuse/resources/exceptions.json.license0000664000175000017500000000014415077707000022706 0ustar alexalex# SPDX-FileCopyrightText: Linux Foundation and its Contributors # # SPDX-License-Identifier: CC0-1.0reuse-tool-6.2.0/src/reuse/resources/licenses.json.license0000664000175000017500000000014415077707000022332 0ustar alexalex# SPDX-FileCopyrightText: Linux Foundation and its Contributors # # SPDX-License-Identifier: CC0-1.0reuse-tool-6.2.0/src/reuse/resources/exceptions.json0000664000175000017500000011203615077707000021271 0ustar alexalex{ "licenseListVersion": "3.27.0", "exceptions": [ { "reference": "https://spdx.org/licenses/389-exception.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/389-exception.json", "referenceNumber": 36, "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": "https://spdx.org/licenses/Asterisk-exception.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Asterisk-exception.json", "referenceNumber": 16, "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": "https://spdx.org/licenses/Asterisk-linking-protocols-exception.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Asterisk-linking-protocols-exception.json", "referenceNumber": 22, "name": "Asterisk linking protocols exception", "licenseExceptionId": "Asterisk-linking-protocols-exception", "seeAlso": [ "https://github.com/asterisk/asterisk/blob/115d7c01e32ccf4566a99e9d74e2b88830985a0b/LICENSE#L27" ] }, { "reference": "https://spdx.org/licenses/Autoconf-exception-2.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Autoconf-exception-2.0.json", "referenceNumber": 2, "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": "https://spdx.org/licenses/Autoconf-exception-3.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Autoconf-exception-3.0.json", "referenceNumber": 51, "name": "Autoconf exception 3.0", "licenseExceptionId": "Autoconf-exception-3.0", "seeAlso": [ "http://www.gnu.org/licenses/autoconf-exception-3.0.html" ] }, { "reference": "https://spdx.org/licenses/Autoconf-exception-generic.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Autoconf-exception-generic.json", "referenceNumber": 73, "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": "https://spdx.org/licenses/Autoconf-exception-generic-3.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Autoconf-exception-generic-3.0.json", "referenceNumber": 40, "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": "https://spdx.org/licenses/Autoconf-exception-macro.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Autoconf-exception-macro.json", "referenceNumber": 63, "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": "https://spdx.org/licenses/Bison-exception-1.24.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Bison-exception-1.24.json", "referenceNumber": 56, "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": "https://spdx.org/licenses/Bison-exception-2.2.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Bison-exception-2.2.json", "referenceNumber": 28, "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": "https://spdx.org/licenses/Bootloader-exception.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Bootloader-exception.json", "referenceNumber": 65, "name": "Bootloader Distribution Exception", "licenseExceptionId": "Bootloader-exception", "seeAlso": [ "https://github.com/pyinstaller/pyinstaller/blob/develop/COPYING.txt" ] }, { "reference": "https://spdx.org/licenses/CGAL-linking-exception.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/CGAL-linking-exception.json", "referenceNumber": 74, "name": "CGAL Linking Exception", "licenseExceptionId": "CGAL-linking-exception", "seeAlso": [ "https://github.com/openscad/openscad/blob/openscad-2021.01/COPYING#L3", "https://github.com/floriankirsch/OpenCSG/blob/opencsg-1-4-2-release/license.txt#L3" ] }, { "reference": "https://spdx.org/licenses/Classpath-exception-2.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Classpath-exception-2.0.json", "referenceNumber": 67, "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": "https://spdx.org/licenses/CLISP-exception-2.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/CLISP-exception-2.0.json", "referenceNumber": 10, "name": "CLISP exception 2.0", "licenseExceptionId": "CLISP-exception-2.0", "seeAlso": [ "http://sourceforge.net/p/clisp/clisp/ci/default/tree/COPYRIGHT" ] }, { "reference": "https://spdx.org/licenses/cryptsetup-OpenSSL-exception.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/cryptsetup-OpenSSL-exception.json", "referenceNumber": 46, "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", "https://github.com/ocaml-omake/omake/blob/master/LICENSE.OMake#L20" ] }, { "reference": "https://spdx.org/licenses/Digia-Qt-LGPL-exception-1.1.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Digia-Qt-LGPL-exception-1.1.json", "referenceNumber": 48, "name": "Digia Qt LGPL Exception version 1.1", "licenseExceptionId": "Digia-Qt-LGPL-exception-1.1", "seeAlso": [ "https://src.fedoraproject.org/rpms/qtlockedfile/blob/rawhide/f/LGPL_EXCEPTION" ] }, { "reference": "https://spdx.org/licenses/DigiRule-FOSS-exception.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/DigiRule-FOSS-exception.json", "referenceNumber": 53, "name": "DigiRule FOSS License Exception", "licenseExceptionId": "DigiRule-FOSS-exception", "seeAlso": [ "http://www.digirulesolutions.com/drupal/foss" ] }, { "reference": "https://spdx.org/licenses/eCos-exception-2.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/eCos-exception-2.0.json", "referenceNumber": 61, "name": "eCos exception 2.0", "licenseExceptionId": "eCos-exception-2.0", "seeAlso": [ "http://ecos.sourceware.org/license-overview.html" ] }, { "reference": "https://spdx.org/licenses/erlang-otp-linking-exception.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/erlang-otp-linking-exception.json", "referenceNumber": 13, "name": "Erlang/OTP Linking Exception", "licenseExceptionId": "erlang-otp-linking-exception", "seeAlso": [ "https://www.gnu.org/licenses/gpl-faq.en.html#GPLIncompatibleLibs", "https://erlang.org/pipermail/erlang-questions/2012-May/066355.html", "https://gitea.osmocom.org/erlang/osmo_ss7/src/commit/2286c1b8738d715950026650bf53f19a69d6ed0e/src/ss7_links.erl#L20" ] }, { "reference": "https://spdx.org/licenses/Fawkes-Runtime-exception.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Fawkes-Runtime-exception.json", "referenceNumber": 21, "name": "Fawkes Runtime Exception", "licenseExceptionId": "Fawkes-Runtime-exception", "seeAlso": [ "http://www.fawkesrobotics.org/about/license/" ] }, { "reference": "https://spdx.org/licenses/FLTK-exception.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/FLTK-exception.json", "referenceNumber": 66, "name": "FLTK exception", "licenseExceptionId": "FLTK-exception", "seeAlso": [ "http://www.fltk.org/COPYING.php" ] }, { "reference": "https://spdx.org/licenses/fmt-exception.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/fmt-exception.json", "referenceNumber": 77, "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": "https://spdx.org/licenses/Font-exception-2.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Font-exception-2.0.json", "referenceNumber": 35, "name": "Font exception 2.0", "licenseExceptionId": "Font-exception-2.0", "seeAlso": [ "http://www.gnu.org/licenses/gpl-faq.html#FontException" ] }, { "reference": "https://spdx.org/licenses/freertos-exception-2.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/freertos-exception-2.0.json", "referenceNumber": 23, "name": "FreeRTOS Exception 2.0", "licenseExceptionId": "freertos-exception-2.0", "seeAlso": [ "https://web.archive.org/web/20060809182744/http://www.freertos.org/a00114.html" ] }, { "reference": "https://spdx.org/licenses/GCC-exception-2.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/GCC-exception-2.0.json", "referenceNumber": 14, "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": "https://spdx.org/licenses/GCC-exception-2.0-note.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/GCC-exception-2.0-note.json", "referenceNumber": 20, "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": "https://spdx.org/licenses/GCC-exception-3.1.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/GCC-exception-3.1.json", "referenceNumber": 25, "name": "GCC Runtime Library exception 3.1", "licenseExceptionId": "GCC-exception-3.1", "seeAlso": [ "http://www.gnu.org/licenses/gcc-exception-3.1.html" ] }, { "reference": "https://spdx.org/licenses/Gmsh-exception.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Gmsh-exception.json", "referenceNumber": 26, "name": "Gmsh exception", "licenseExceptionId": "Gmsh-exception", "seeAlso": [ "https://gitlab.onelab.info/gmsh/gmsh/-/raw/master/LICENSE.txt" ] }, { "reference": "https://spdx.org/licenses/GNAT-exception.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/GNAT-exception.json", "referenceNumber": 69, "name": "GNAT exception", "licenseExceptionId": "GNAT-exception", "seeAlso": [ "https://github.com/AdaCore/florist/blob/master/libsrc/posix-configurable_file_limits.adb" ] }, { "reference": "https://spdx.org/licenses/GNOME-examples-exception.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/GNOME-examples-exception.json", "referenceNumber": 76, "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": "https://spdx.org/licenses/GNU-compiler-exception.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/GNU-compiler-exception.json", "referenceNumber": 58, "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": "https://spdx.org/licenses/gnu-javamail-exception.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/gnu-javamail-exception.json", "referenceNumber": 64, "name": "GNU JavaMail exception", "licenseExceptionId": "gnu-javamail-exception", "seeAlso": [ "http://www.gnu.org/software/classpathx/javamail/javamail.html" ] }, { "reference": "https://spdx.org/licenses/GPL-3.0-389-ds-base-exception.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/GPL-3.0-389-ds-base-exception.json", "referenceNumber": 18, "name": "GPL-3.0 389 DS Base Exception", "licenseExceptionId": "GPL-3.0-389-ds-base-exception", "seeAlso": [] }, { "reference": "https://spdx.org/licenses/GPL-3.0-interface-exception.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/GPL-3.0-interface-exception.json", "referenceNumber": 78, "name": "GPL-3.0 Interface Exception", "licenseExceptionId": "GPL-3.0-interface-exception", "seeAlso": [ "https://www.gnu.org/licenses/gpl-faq.en.html#LinkingOverControlledInterface" ] }, { "reference": "https://spdx.org/licenses/GPL-3.0-linking-exception.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/GPL-3.0-linking-exception.json", "referenceNumber": 68, "name": "GPL-3.0 Linking Exception", "licenseExceptionId": "GPL-3.0-linking-exception", "seeAlso": [ "https://www.gnu.org/licenses/gpl-faq.en.html#GPLIncompatibleLibs" ] }, { "reference": "https://spdx.org/licenses/GPL-3.0-linking-source-exception.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/GPL-3.0-linking-source-exception.json", "referenceNumber": 62, "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": "https://spdx.org/licenses/GPL-CC-1.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/GPL-CC-1.0.json", "referenceNumber": 33, "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": "https://spdx.org/licenses/GStreamer-exception-2005.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/GStreamer-exception-2005.json", "referenceNumber": 4, "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": "https://spdx.org/licenses/GStreamer-exception-2008.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/GStreamer-exception-2008.json", "referenceNumber": 41, "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": "https://spdx.org/licenses/harbour-exception.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/harbour-exception.json", "referenceNumber": 59, "name": "harbour exception", "licenseExceptionId": "harbour-exception", "seeAlso": [ "https://github.com/harbour/core/blob/master/LICENSE.txt#L44-L66" ] }, { "reference": "https://spdx.org/licenses/i2p-gpl-java-exception.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/i2p-gpl-java-exception.json", "referenceNumber": 9, "name": "i2p GPL+Java Exception", "licenseExceptionId": "i2p-gpl-java-exception", "seeAlso": [ "http://geti2p.net/en/get-involved/develop/licenses#java_exception" ] }, { "reference": "https://spdx.org/licenses/Independent-modules-exception.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Independent-modules-exception.json", "referenceNumber": 45, "name": "Independent Module Linking exception", "licenseExceptionId": "Independent-modules-exception", "seeAlso": [ "https://gitlab.com/freepascal.org/fpc/source/-/blob/release_3_2_2/rtl/COPYING.FPC" ] }, { "reference": "https://spdx.org/licenses/KiCad-libraries-exception.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/KiCad-libraries-exception.json", "referenceNumber": 44, "name": "KiCad Libraries Exception", "licenseExceptionId": "KiCad-libraries-exception", "seeAlso": [ "https://www.kicad.org/libraries/license/" ] }, { "reference": "https://spdx.org/licenses/LGPL-3.0-linking-exception.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/LGPL-3.0-linking-exception.json", "referenceNumber": 32, "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": "https://spdx.org/licenses/libpri-OpenH323-exception.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/libpri-OpenH323-exception.json", "referenceNumber": 19, "name": "libpri OpenH323 exception", "licenseExceptionId": "libpri-OpenH323-exception", "seeAlso": [ "https://github.com/asterisk/libpri/blob/1.6.0/README#L19-L22" ] }, { "reference": "https://spdx.org/licenses/Libtool-exception.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Libtool-exception.json", "referenceNumber": 71, "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": "https://spdx.org/licenses/Linux-syscall-note.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Linux-syscall-note.json", "referenceNumber": 37, "name": "Linux Syscall Note", "licenseExceptionId": "Linux-syscall-note", "seeAlso": [ "https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/COPYING" ] }, { "reference": "https://spdx.org/licenses/LLGPL.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/LLGPL.json", "referenceNumber": 24, "name": "LLGPL Preamble", "licenseExceptionId": "LLGPL", "seeAlso": [ "http://opensource.franz.com/preamble.html" ] }, { "reference": "https://spdx.org/licenses/LLVM-exception.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/LLVM-exception.json", "referenceNumber": 72, "name": "LLVM Exception", "licenseExceptionId": "LLVM-exception", "seeAlso": [ "http://llvm.org/foundation/relicensing/LICENSE.txt" ] }, { "reference": "https://spdx.org/licenses/LZMA-exception.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/LZMA-exception.json", "referenceNumber": 30, "name": "LZMA exception", "licenseExceptionId": "LZMA-exception", "seeAlso": [ "http://nsis.sourceforge.net/Docs/AppendixI.html#I.6" ] }, { "reference": "https://spdx.org/licenses/mif-exception.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/mif-exception.json", "referenceNumber": 29, "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": "https://spdx.org/licenses/mxml-exception.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/mxml-exception.json", "referenceNumber": 38, "name": "mxml Exception", "licenseExceptionId": "mxml-exception", "seeAlso": [ "https://github.com/michaelrsweet/mxml/blob/master/NOTICE", "https://github.com/michaelrsweet/mxml/blob/master/LICENSE" ] }, { "reference": "https://spdx.org/licenses/Nokia-Qt-exception-1.1.html", "isDeprecatedLicenseId": true, "detailsUrl": "https://spdx.org/licenses/Nokia-Qt-exception-1.1.json", "referenceNumber": 47, "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": "https://spdx.org/licenses/OCaml-LGPL-linking-exception.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/OCaml-LGPL-linking-exception.json", "referenceNumber": 42, "name": "OCaml LGPL Linking Exception", "licenseExceptionId": "OCaml-LGPL-linking-exception", "seeAlso": [ "https://caml.inria.fr/ocaml/license.en.html" ] }, { "reference": "https://spdx.org/licenses/OCCT-exception-1.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/OCCT-exception-1.0.json", "referenceNumber": 17, "name": "Open CASCADE Exception 1.0", "licenseExceptionId": "OCCT-exception-1.0", "seeAlso": [ "http://www.opencascade.com/content/licensing" ] }, { "reference": "https://spdx.org/licenses/OpenJDK-assembly-exception-1.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/OpenJDK-assembly-exception-1.0.json", "referenceNumber": 11, "name": "OpenJDK Assembly exception 1.0", "licenseExceptionId": "OpenJDK-assembly-exception-1.0", "seeAlso": [ "http://openjdk.java.net/legal/assembly-exception.html" ] }, { "reference": "https://spdx.org/licenses/openvpn-openssl-exception.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/openvpn-openssl-exception.json", "referenceNumber": 3, "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": "https://spdx.org/licenses/PCRE2-exception.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/PCRE2-exception.json", "referenceNumber": 12, "name": "PCRE2 exception", "licenseExceptionId": "PCRE2-exception", "seeAlso": [ "https://www.pcre.org/licence.txt" ] }, { "reference": "https://spdx.org/licenses/polyparse-exception.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/polyparse-exception.json", "referenceNumber": 54, "name": "Polyparse Exception", "licenseExceptionId": "polyparse-exception", "seeAlso": [ "https://hackage.haskell.org/package/polyparse-1.13/src/COPYRIGHT" ] }, { "reference": "https://spdx.org/licenses/PS-or-PDF-font-exception-20170817.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/PS-or-PDF-font-exception-20170817.json", "referenceNumber": 43, "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": "https://spdx.org/licenses/QPL-1.0-INRIA-2004-exception.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/QPL-1.0-INRIA-2004-exception.json", "referenceNumber": 50, "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": "https://spdx.org/licenses/Qt-GPL-exception-1.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Qt-GPL-exception-1.0.json", "referenceNumber": 34, "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": "https://spdx.org/licenses/Qt-LGPL-exception-1.1.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Qt-LGPL-exception-1.1.json", "referenceNumber": 39, "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": "https://spdx.org/licenses/Qwt-exception-1.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Qwt-exception-1.0.json", "referenceNumber": 79, "name": "Qwt exception 1.0", "licenseExceptionId": "Qwt-exception-1.0", "seeAlso": [ "http://qwt.sourceforge.net/qwtlicense.html" ] }, { "reference": "https://spdx.org/licenses/romic-exception.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/romic-exception.json", "referenceNumber": 6, "name": "Romic Exception", "licenseExceptionId": "romic-exception", "seeAlso": [ "https://web.archive.org/web/20210124015834/http://mo.morsi.org/blog/2009/08/13/lesser_affero_gplv3/", "https://sourceforge.net/p/romic/code/ci/3ab2856180cf0d8b007609af53154cf092efc58f/tree/COPYING", "https://github.com/moll/node-mitm/blob/bbf24b8bd7596dc6e091e625363161ce91984fc7/LICENSE#L8-L11", "https://github.com/zenbones/SmallMind/blob/3c62b5995fe7f27c453f140ff9b60560a0893f2a/COPYRIGHT#L25-L30", "https://github.com/CubeArtisan/cubeartisan/blob/2c6ab53455237b88a3ea07be02a838a135c4ab79/LICENSE.LESSER#L10-L15", "https://github.com/savearray2/py.js/blob/b781273c08c8afa89f4954de4ecf42ec01429bae/README.md#license" ] }, { "reference": "https://spdx.org/licenses/RRDtool-FLOSS-exception-2.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/RRDtool-FLOSS-exception-2.0.json", "referenceNumber": 7, "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": "https://spdx.org/licenses/SANE-exception.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/SANE-exception.json", "referenceNumber": 27, "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": "https://spdx.org/licenses/SHL-2.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/SHL-2.0.json", "referenceNumber": 5, "name": "Solderpad Hardware License v2.0", "licenseExceptionId": "SHL-2.0", "seeAlso": [ "https://solderpad.org/licenses/SHL-2.0/" ] }, { "reference": "https://spdx.org/licenses/SHL-2.1.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/SHL-2.1.json", "referenceNumber": 1, "name": "Solderpad Hardware License v2.1", "licenseExceptionId": "SHL-2.1", "seeAlso": [ "https://solderpad.org/licenses/SHL-2.1/" ] }, { "reference": "https://spdx.org/licenses/stunnel-exception.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/stunnel-exception.json", "referenceNumber": 49, "name": "stunnel Exception", "licenseExceptionId": "stunnel-exception", "seeAlso": [ "https://github.com/mtrojnar/stunnel/blob/master/COPYING.md" ] }, { "reference": "https://spdx.org/licenses/SWI-exception.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/SWI-exception.json", "referenceNumber": 15, "name": "SWI exception", "licenseExceptionId": "SWI-exception", "seeAlso": [ "https://github.com/SWI-Prolog/packages-clpqr/blob/bfa80b9270274f0800120d5b8e6fef42ac2dc6a5/clpqr/class.pl" ] }, { "reference": "https://spdx.org/licenses/Swift-exception.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Swift-exception.json", "referenceNumber": 52, "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": "https://spdx.org/licenses/Texinfo-exception.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Texinfo-exception.json", "referenceNumber": 60, "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": "https://spdx.org/licenses/u-boot-exception-2.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/u-boot-exception-2.0.json", "referenceNumber": 8, "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": "https://spdx.org/licenses/UBDL-exception.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/UBDL-exception.json", "referenceNumber": 75, "name": "Unmodified Binary Distribution exception", "licenseExceptionId": "UBDL-exception", "seeAlso": [ "https://github.com/ipxe/ipxe/blob/master/COPYING.UBDL" ] }, { "reference": "https://spdx.org/licenses/Universal-FOSS-exception-1.0.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/Universal-FOSS-exception-1.0.json", "referenceNumber": 70, "name": "Universal FOSS Exception, Version 1.0", "licenseExceptionId": "Universal-FOSS-exception-1.0", "seeAlso": [ "https://oss.oracle.com/licenses/universal-foss-exception/" ] }, { "reference": "https://spdx.org/licenses/vsftpd-openssl-exception.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/vsftpd-openssl-exception.json", "referenceNumber": 55, "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": "https://spdx.org/licenses/WxWindows-exception-3.1.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/WxWindows-exception-3.1.json", "referenceNumber": 31, "name": "WxWindows Library Exception 3.1", "licenseExceptionId": "WxWindows-exception-3.1", "seeAlso": [ "http://www.opensource.org/licenses/WXwindows" ] }, { "reference": "https://spdx.org/licenses/x11vnc-openssl-exception.html", "isDeprecatedLicenseId": false, "detailsUrl": "https://spdx.org/licenses/x11vnc-openssl-exception.json", "referenceNumber": 57, "name": "x11vnc OpenSSL Exception", "licenseExceptionId": "x11vnc-openssl-exception", "seeAlso": [ "https://github.com/LibVNC/x11vnc/blob/master/src/8to24.c#L22" ] } ], "releaseDate": "2025-07-01T00:00:00Z" }reuse-tool-6.2.0/src/reuse/cli/0000775000175000017500000000000015077707000014747 5ustar alexalexreuse-tool-6.2.0/src/reuse/cli/main.py0000664000175000017500000001064415077707000016252 0ustar alexalex# 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-FileCopyrightText: 2024 Kerry McAdams # SPDX-FileCopyrightText: 2024 Emil Velikov # # SPDX-License-Identifier: GPL-3.0-or-later """Entry function for reuse.""" import gettext import logging import os import warnings from pathlib import Path import click from click.formatting import wrap_text from .. import __REUSE_version__ from .._util import setup_logging from ..i18n import _ from .common import ClickObj _PACKAGE_PATH = os.path.dirname(os.path.dirname(__file__)) _LOCALE_DIR = os.path.join(_PACKAGE_PATH, "locale") if gettext.find("reuse", localedir=_LOCALE_DIR): gettext.bindtextdomain("reuse", _LOCALE_DIR) # This is needed to make Click recognise our translations. Our own # translations use the class-based API. gettext.textdomain("reuse") _VERSION_TEXT = ( _("%(prog)s, version %(version)s") + "\n\n" + _( "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." ) + "\n\n" + _( "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." ) + "\n\n" + _( "You should have received a copy of the GNU General Public License" " along with this program. If not, see" " ." ) ) _HELP = ( _( "reuse is a tool for compliance with the REUSE" " recommendations. See for more" " information, and for the online" " documentation." ) + "\n\n" + _( "This version of reuse is compatible with version {} of the REUSE" " Specification." ).format(__REUSE_version__) + "\n\n" + _("Support the FSFE's work:") + "\n\n" # Indent next paragraph. + " " + _( "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 ." ) ) @click.group(name="reuse", help=_HELP) @click.option( "--debug", is_flag=True, help=_("Enable debug statements."), ) @click.option( "--suppress-deprecation", is_flag=True, help=_("Hide deprecation warnings."), ) @click.option( "--include-submodules", is_flag=True, help=_("Do not skip over Git submodules."), ) @click.option( "--include-meson-subprojects", is_flag=True, help=_("Do not skip over Meson subprojects."), ) @click.option( "--no-multiprocessing", is_flag=True, help=_("Do not use multiprocessing."), ) @click.option( "--root", type=click.Path( exists=True, file_okay=False, path_type=Path, ), default=None, help=_("Define root of project."), ) @click.version_option( package_name="reuse", message=wrap_text(_VERSION_TEXT, preserve_paragraphs=True), ) @click.pass_context def main( ctx: click.Context, debug: bool, suppress_deprecation: bool, include_submodules: bool, include_meson_subprojects: bool, no_multiprocessing: bool, root: Path | None, ) -> None: # pylint: disable=missing-function-docstring,too-many-arguments setup_logging(level=logging.DEBUG if debug else logging.WARNING) # Very stupid workaround to not print a DEP5 deprecation warning in the # middle of ccompileonversion to REUSE.toml. if ctx.invoked_subcommand == "convert-dep5": os.environ["_SUPPRESS_DEP5_WARNING"] = "1" if not suppress_deprecation: warnings.filterwarnings("default", module="reuse") ctx.obj = ClickObj( root=root, include_submodules=include_submodules, include_meson_subprojects=include_meson_subprojects, no_multiprocessing=no_multiprocessing, ) reuse-tool-6.2.0/src/reuse/cli/convert_dep5.py0000664000175000017500000000216715077707000017724 0ustar alexalex# SPDX-FileCopyrightText: 2024 Carmen Bianca BAKKER # SPDX-FileCopyrightText: 2024 Free Software Foundation Europe e.V. # # SPDX-License-Identifier: GPL-3.0-or-later """Click code for convert-dep5 subcommand.""" from typing import cast import click from ..convert_dep5 import toml_from_dep5 from ..global_licensing import ReuseDep5 from ..i18n import _ from .common import ClickObj from .main import main _HELP = _( "Convert .reuse/dep5 into a REUSE.toml file. The generated file is placed" " in the project root and is semantically identical. The .reuse/dep5 file" " is subsequently deleted." ) @main.command(name="convert-dep5", help=_HELP) @click.pass_obj def convert_dep5(obj: ClickObj) -> None: # pylint: disable=missing-function-docstring project = obj.project if not (project.root / ".reuse/dep5").exists(): raise click.UsageError(_("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() reuse-tool-6.2.0/src/reuse/cli/spdx.py0000664000175000017500000000635515077707000016310 0ustar alexalex# SPDX-FileCopyrightText: 2017 Free Software Foundation Europe e.V. # SPDX-FileCopyrightText: 2022 Pietro Albini # # SPDX-License-Identifier: GPL-3.0-or-later """Click code for spdx subcommand.""" import contextlib import logging import sys import click from ..covered_files import _IGNORE_SPDX_PATTERNS from ..i18n import _ from ..report import ProjectReport from .common import ClickObj from .main import main _LOGGER = logging.getLogger(__name__) _HELP = _("Generate an SPDX bill of materials.") @main.command(name="spdx", help=_HELP) @click.option( "--output", "-o", type=click.File("w", encoding="utf-8", lazy=True), # Default is stdout. default=None, help=_("File to write to."), ) @click.option( "--add-license-concluded", is_flag=True, help=_( "Populate the LicenseConcluded field; note that reuse cannot guarantee" " that the field is accurate." ), ) @click.option( "--add-licence-concluded", "add_license_concluded", hidden=True, ) @click.option( "--creator-person", type=str, help=_("Name of the person signing off on the SPDX report."), ) @click.option( "--creator-organization", help=_("Name of the organization signing off on the SPDX report."), ) @click.option( "--creator-organisation", "creator_organization", hidden=True, ) @click.pass_obj def spdx( obj: ClickObj, output: click.File | None, add_license_concluded: bool, creator_person: str | None, creator_organization: str | None, ) -> None: # pylint: disable=missing-function-docstring # 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 ( add_license_concluded and creator_person is None and creator_organization is None ): raise click.UsageError( _( "'--creator-person' or '--creator-organization'" " is required when '--add-license-concluded' is provided." ) ) if ( output is not None and output.name != "-" and not any( pattern.match(output.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=output.name) ) report = ProjectReport.generate( obj.project, multiprocessing=not obj.no_multiprocessing, add_license_concluded=add_license_concluded, ) with contextlib.ExitStack() as stack: if output is not None: out = stack.enter_context(output.open()) # type: ignore else: out = sys.stdout click.echo( report.bill_of_materials( creator_person=creator_person, creator_organization=creator_organization, ), file=out, ) reuse-tool-6.2.0/src/reuse/cli/lint.py0000664000175000017500000000652115077707000016273 0ustar alexalex# 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-FileCopyrightText: 2025 ASCIIMoth # # SPDX-License-Identifier: GPL-3.0-or-later # pylint: disable=unused-argument """Click code for lint subcommand.""" import sys import click from .. import __REUSE_version__ from ..i18n import _ from ..lint import format_json, format_lines, format_plain from ..report import ProjectReport from .common import ClickObj, MutexOption from .main import main _OUTPUT_MUTEX = ["quiet", "json", "plain", "lines"] _HELP = ( _( "Lint the project directory for REUSE compliance. This version of the" " tool checks against version {reuse_version} of the REUSE" " Specification. You can find the latest version of the specification" " at ." ).format(reuse_version=__REUSE_version__) + "\n\n" + _("Specifically, the following criteria are checked:") + "\n\n\b\n" + click.wrap_text( _( "- Are there any bad (unrecognised, not compliant with SPDX)" " licenses in the project?" ) ) + "\n" + click.wrap_text(_("- Are there any deprecated licenses in the project?")) + "\n" + click.wrap_text( _( "- Are there any license files in the LICENSES/ directory" " without file extension?" ) ) + "\n" + click.wrap_text( _( "- Are any licenses referred to inside of the project, but" " not included in the LICENSES/ directory?" ) ) + "\n" + click.wrap_text( _( "- Are any licenses included in the LICENSES/ directory that" " are not used inside of the project?" ) ) + "\n" + click.wrap_text(_("- Are there any read errors?")) + "\n" + click.wrap_text( _("- Do all files have valid copyright and licensing information?") ) ) @main.command(name="lint", help=_HELP) @click.option( "--quiet", "-q", cls=MutexOption, mutually_exclusive=_OUTPUT_MUTEX, is_flag=True, help=_("Prevent output."), ) @click.option( "--json", "-j", cls=MutexOption, mutually_exclusive=_OUTPUT_MUTEX, is_flag=True, help=_("Format output as JSON."), ) @click.option( "--plain", "-p", cls=MutexOption, mutually_exclusive=_OUTPUT_MUTEX, is_flag=True, help=_("Format output as plain text. (default)"), ) @click.option( "--lines", "-l", cls=MutexOption, mutually_exclusive=_OUTPUT_MUTEX, is_flag=True, help=_("Format output as errors per line."), ) @click.pass_obj def lint( obj: ClickObj, quiet: bool, json: bool, plain: bool, lines: bool ) -> None: # pylint: disable=missing-function-docstring report = ProjectReport.generate( obj.project, do_checksum=False, multiprocessing=not obj.no_multiprocessing, ) if quiet: pass elif json: click.echo(format_json(report), nl=False) elif lines: click.echo(format_lines(report), nl=False) else: click.echo(format_plain(report), nl=False) sys.exit(0 if report.is_compliant else 1) reuse-tool-6.2.0/src/reuse/cli/lint_file.py0000664000175000017500000000420715077707000017271 0ustar alexalex# SPDX-FileCopyrightText: 2024 Kerry McAdams # SPDX-FileCopyrightText: 2024 Free Software Foundation Europe e.V. # # SPDX-License-Identifier: GPL-3.0-or-later """Click code for lint-file subcommand.""" # pylint: disable=unused-argument import sys from collections.abc import Collection from pathlib import Path import click from ..i18n import _ from ..lint import format_lines_subset from ..report import ProjectSubsetReport from .common import ClickObj, MutexOption from .main import main _OUTPUT_MUTEX = ["quiet", "lines"] _HELP = _( "Lint individual files for REUSE compliance. The specified FILEs are" " checked for the presence of copyright and licensing information, and" " whether the found licenses are included in the LICENSES/ directory." ) @main.command(name="lint-file", help=_HELP) @click.option( "--quiet", "-q", cls=MutexOption, mutually_exclusive=_OUTPUT_MUTEX, is_flag=True, help=_("Prevent output."), ) @click.option( "--lines", "-l", cls=MutexOption, mutually_exclusive=_OUTPUT_MUTEX, is_flag=True, help=_("Format output as errors per line. (default)"), ) @click.argument( "files", # TRANSLATORS: You may translate this. Please preserve capital letters. metavar=_("FILE"), type=click.Path(exists=True, path_type=Path), nargs=-1, ) @click.pass_obj def lint_file( obj: ClickObj, quiet: bool, lines: bool, files: Collection[Path] ) -> None: # pylint: disable=missing-function-docstring project = obj.project subset_files = {Path(file_) for file_ in files} for file_ in subset_files: if not file_.resolve().is_relative_to(project.root.resolve()): raise click.UsageError( _("'{file}' is not inside of '{root}'.").format( file=file_, root=project.root ) ) report = ProjectSubsetReport.generate( project, subset_files, multiprocessing=not obj.no_multiprocessing, ) if quiet: pass else: click.echo(format_lines_subset(report), nl=False) sys.exit(0 if report.is_compliant else 1) reuse-tool-6.2.0/src/reuse/cli/__init__.py0000664000175000017500000000046215077707000017062 0ustar alexalex# SPDX-FileCopyrightText: 2024 Free Software Foundation Europe e.V. # # SPDX-License-Identifier: GPL-3.0-or-later """All command-line functionality.""" from . import ( annotate, convert_dep5, download, lint, lint_file, main, spdx, supported_licenses, ) reuse-tool-6.2.0/src/reuse/cli/annotate.py0000664000175000017500000003737115077707000017145 0ustar alexalex# 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 """Click code for annotate subcommand.""" import datetime import logging import os import sys from collections.abc import Collection, Iterable, Sequence from pathlib import Path from typing import Any, cast import click from jinja2 import Environment, FileSystemLoader, Template from jinja2.exceptions import TemplateNotFound from .._annotate import add_header_to_file from .._util import _determine_license_path, _determine_license_suffix_path from ..comment import ( NAME_STYLE_MAP, CommentStyle, get_comment_style, has_style, is_uncommentable, ) from ..copyright import ( CopyrightNotice, CopyrightPrefix, ReuseInfo, SpdxExpression, YearRange, validate_four_digits, ) from ..exceptions import YearRangeParseError from ..extract import HEURISTICS_CHUNK_SIZE, detect_encoding, detect_newline from ..i18n import _ from ..project import Project from .common import ClickObj, MutexOption, spdx_identifier from .main import main _LOGGER = logging.getLogger(__name__) def test_mandatory_option_required( copyright_: Any, license_: Any, contributor: Any, ) -> None: """Raise a parser error if one of the mandatory options is not provided.""" if not any((copyright_, license_, contributor)): raise click.UsageError( _( "Option '--copyright', '--license', or '--contributor' is" " required." ) ) def all_paths( paths: Collection[Path], recursive: bool, project: Project, ) -> list[Path]: """Return a set of all provided paths, converted into .license paths if they exist. If *recursive* is enabled, all files belonging to *project* that are recursive children of *paths* are also added. Directories are filtered out. """ if recursive: result: set[Path] = set() all_files = [path.resolve() for path in project.all_files()] for path in paths: if path.is_file(): result.add(path) else: result |= { child for child in all_files if path.resolve() in child.parents } else: result = set(paths) return [_determine_license_path(path) for path in result if path.is_file()] def verify_paths_comment_style( style: Any, fallback_dot_license: Any, skip_unrecognised: Any, force_dot_license: Any, 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 style and not fallback_dot_license and not skip_unrecognised and not force_dot_license ): unrecognised_files: set[Path] = set() for path in paths: if not has_style(path): unrecognised_files.add(path) if unrecognised_files: raise click.UsageError( "{}\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 verify_paths_line_handling( single_line: bool, multi_line: bool, forced_style: str | None, 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: type[CommentStyle] | None = None if forced_style is not None: style = NAME_STYLE_MAP.get(forced_style) if style is None: style = get_comment_style(path) # This shouldn't happen because of prior tests, so let's not bother with # this case. if style is None: continue # TODO: list all non-functional paths if single_line and not style.can_handle_single(): raise click.UsageError( _( "'{path}' does not support single-line comments, please" " do not use '--single-line'." ).format(path=path.as_posix()) ) if multi_line and not style.can_handle_multi(): raise click.UsageError( _( "'{path}' does not support multi-line comments, please" " do not use '--multi-line'." ).format(path=path.as_posix()) ) 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 get_template( template_str: str | None, project: Project ) -> tuple[Template | None, 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: Template | None = None commented = False if template_str: try: template = cast(Template, find_template(project, template_str)) except TemplateNotFound as error: raise click.UsageError( _("Template '{template}' could not be found.").format( template=template_str ) ) from error if ".commented" in Path(cast(str, template.name)).suffixes: commented = True return template, commented def get_years(year: str | None, exclude_year: bool) -> tuple[YearRange, ...]: """Get the year. Normally it is today's year. If --year is specified, get a full tuple of ranges from that one. If --exclude-year is specified, return an empty tuple. """ result: tuple[YearRange, ...] = tuple() if not exclude_year: if year: try: result = YearRange.tuple_from_string(year) except YearRangeParseError as error: raise click.UsageError( _("'{year}' is not a valid year range.").format(year=year) ) from error else: try: current_year = str(datetime.date.today().year) result = (YearRange(validate_four_digits(current_year)),) except ValueError as error: raise click.UsageError( _( "Your operating system's year is set to '{year}'. This" " is not four digits, and not supported." ).format(year=current_year) ) from error return result def get_reuse_info( copyrights: Collection[str], licenses: Collection[SpdxExpression], contributors: Collection[str], copyright_prefix: str | None, years: tuple[YearRange, ...], ) -> ReuseInfo: """Create a ReuseInfo object from --license, --copyright, and --contributor. """ prefix = ( CopyrightPrefix[CopyrightPrefix.uppercase_name(copyright_prefix)] if copyright_prefix is not None else CopyrightPrefix.SPDX ) copyright_notices = { CopyrightNotice(item, years=years, prefix=prefix) for item in copyrights } return ReuseInfo( spdx_expressions=set(licenses), copyright_notices=copyright_notices, contributor_lines=set(contributors), ) _YEAR_MUTEX = ["years", "exclude_year"] _LINE_MUTEX = ["single_line", "multi_line"] _STYLE_MUTEX = [ "force_dot_license", "fallback_dot_license", "skip_unrecognised", ] _HELP = ( _("Add copyright and licensing into the headers of 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." ) ) @main.command(name="annotate", help=_HELP) @click.option( "--copyright", "-c", "copyrights", # TRANSLATORS: You may translate this. Please preserve capital letters. metavar=_("COPYRIGHT"), type=str, multiple=True, help=_("Copyright holder, repeatable."), ) @click.option( "--license", "-l", "licenses", # TRANSLATORS: You may translate this. Please preserve capital letters. metavar=_("SPDX_IDENTIFIER"), type=spdx_identifier, multiple=True, help=_("SPDX License Identifier, repeatable."), ) @click.option( "--contributor", "contributors", # TRANSLATORS: You may translate this. Please preserve capital letters. metavar=_("CONTRIBUTOR"), type=str, multiple=True, help=_("File contributor, repeatable."), ) @click.option( "--year", "-y", "years", # TRANSLATORS: You may translate this. Please preserve capital letters. metavar=_("YEAR"), cls=MutexOption, mutually_exclusive=_YEAR_MUTEX, type=str, help=_( "Year of copyright notice. You may define multiple years or a range" " of years." ), ) @click.option( "--style", "-s", cls=MutexOption, mutually_exclusive=["skip_unrecognised"], type=click.Choice(list(NAME_STYLE_MAP)), help=_("Comment style to use."), ) @click.option( "--copyright-prefix", type=click.Choice( [ CopyrightPrefix.lowercase_name(prefix.name) for prefix in CopyrightPrefix ] ), help=_("Copyright prefix to use."), ) @click.option( "--copyright-style", "copyright_prefix", hidden=True, ) @click.option( "--template", "-t", "template_str", # TRANSLATORS: You may translate this. Please preserve capital letters. metavar=_("TEMPLATE"), type=str, help=_("Name of template to use."), ) @click.option( "--exclude-year", cls=MutexOption, mutually_exclusive=_YEAR_MUTEX, is_flag=True, help=_("Do not include year in copyright notice."), ) @click.option( "--merge-copyrights", is_flag=True, help=_( "Merge copyright notices if they are identical except for their years." ), ) @click.option( "--single-line", cls=MutexOption, mutually_exclusive=_LINE_MUTEX, is_flag=True, help=_("Force single-line comment style."), ) @click.option( "--multi-line", cls=MutexOption, mutually_exclusive=_LINE_MUTEX, is_flag=True, help=_("Force multi-line comment style."), ) @click.option( "--recursive", "-r", is_flag=True, help=_("Add headers to all files under specified directories recursively."), ) @click.option( "--no-replace", is_flag=True, help=_("Do not replace the first header in the file; just add a new one."), ) @click.option( "--force-dot-license", cls=MutexOption, mutually_exclusive=_STYLE_MUTEX, is_flag=True, help=_("Always write a .license file instead of a header inside the file."), ) @click.option( "--fallback-dot-license", cls=MutexOption, mutually_exclusive=_STYLE_MUTEX, is_flag=True, help=_("Write a .license file to files with unrecognised comment styles."), ) @click.option( "--skip-unrecognised", cls=MutexOption, mutually_exclusive=_STYLE_MUTEX, is_flag=True, help=_("Skip files with unrecognised comment styles."), ) @click.option( "--skip-unrecognized", "skip_unrecognised", is_flag=True, hidden=True, ) @click.option( "--skip-existing", is_flag=True, help=_("Skip files that already contain REUSE information."), ) @click.argument( "paths", # TRANSLATORS: You may translate this. Please preserve capital letters. metavar=_("PATH"), type=click.Path(exists=True, writable=True, path_type=Path), nargs=-1, ) @click.pass_obj def annotate( obj: ClickObj, copyrights: Sequence[str], licenses: Sequence[SpdxExpression], contributors: Sequence[str], years: str | None, style: str | None, copyright_prefix: str | None, template_str: str | None, exclude_year: bool, merge_copyrights: bool, single_line: bool, multi_line: bool, recursive: bool, no_replace: bool, force_dot_license: bool, fallback_dot_license: bool, skip_unrecognised: bool, skip_existing: bool, paths: Sequence[Path], ) -> None: # pylint: disable=too-many-arguments,too-many-locals,missing-function-docstring project = obj.project test_mandatory_option_required(copyrights, licenses, contributors) paths = all_paths(paths, recursive, project) verify_paths_comment_style( style, fallback_dot_license, skip_unrecognised, force_dot_license, paths ) # Verify line handling and comment styles before proceeding. verify_paths_line_handling(single_line, multi_line, style, paths) template, commented = get_template(template_str, project) years_tuple = get_years(years, exclude_year) reuse_info = get_reuse_info( copyrights, licenses, contributors, copyright_prefix, years_tuple ) result = 0 for path in paths: with path.open("rb") as fp: chunk = fp.read(HEURISTICS_CHUNK_SIZE) encoding = detect_encoding(chunk) newline = ( detect_newline(chunk, encoding=encoding) if encoding is not None else os.linesep ) if encoding is None or is_uncommentable(path) or force_dot_license: new_path = _determine_license_suffix_path(path) if encoding is None: _LOGGER.info( _( "'{path}' is a binary, therefore using '{new_path}'" " for the header" ).format(path=path, new_path=new_path) ) encoding = "utf_8" path = Path(new_path) path.touch() result += add_header_to_file( path=path, reuse_info=reuse_info, template=template, template_is_commented=commented, style=style, encoding=encoding, newline=newline, force_multi=multi_line, skip_existing=skip_existing, skip_unrecognised=skip_unrecognised, fallback_dot_license=fallback_dot_license, merge_copyrights=merge_copyrights, replace=not no_replace, out=sys.stdout, ) sys.exit(min(result, 1)) reuse-tool-6.2.0/src/reuse/cli/download.py0000664000175000017500000001254415077707000017136 0ustar alexalex# SPDX-FileCopyrightText: 2019 Free Software Foundation Europe e.V. # SPDX-FileCopyrightText: 2023 Nico Rikken # # SPDX-License-Identifier: GPL-3.0-or-later """Click code for download subcommand.""" import logging import sys from collections.abc import Collection from difflib import SequenceMatcher from pathlib import Path from typing import IO from urllib.error import URLError import click from .._licenses import ALL_MAP, ALL_NON_DEPRECATED_MAP from .._util import _strip_plus_from_identifier from ..download import _path_to_license_file, put_license_in_file from ..i18n import _ from ..report import ProjectReport from ..types import StrPath from .common import ClickObj, MutexOption from .main import main _LOGGER = logging.getLogger(__name__) def _similar_spdx_identifiers(identifier: str) -> list[str]: """Given an incorrect SPDX identifier, return a list of similar ones.""" suggestions: list[str] = [] 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." ) ) out.write("\n") def _already_exists(path: StrPath) -> None: click.echo( _("Error: {spdx_identifier} already exists.").format( spdx_identifier=path ) ) def _not_found(path: StrPath) -> None: click.echo(_("Error: {path} does not exist.").format(path=path)) def _could_not_download(identifier: str) -> None: click.echo(_("Error: Failed to download license.")) click.echo("") if identifier not in ALL_MAP: _print_incorrect_spdx_identifier(identifier, out=sys.stdout) else: click.echo(_("Is your internet connection working?")) def _successfully_downloaded(destination: StrPath) -> None: click.echo( _("Successfully downloaded {spdx_identifier}.").format( spdx_identifier=destination ) ) _ALL_MUTEX = ["all_", "output"] _HELP = ( _("Download a license and place it in the LICENSES/ directory.") + "\n\n" + _( "LICENSE must be a valid SPDX License Identifier. You may specify" " LICENSE multiple times to download multiple licenses." ) ) @main.command(name="download", help=_HELP) @click.option( "--all", "all_", cls=MutexOption, mutually_exclusive=_ALL_MUTEX, is_flag=True, help=_("Download all missing licenses detected in the project."), ) @click.option( "--output", "-o", cls=MutexOption, mutually_exclusive=_ALL_MUTEX, type=click.Path(dir_okay=False, writable=True, path_type=Path), help=_("Path to download to."), ) @click.option( "--source", type=click.Path(exists=True, readable=True, path_type=Path), help=_( "Source from which to copy custom LicenseRef- licenses, either" " a directory that contains the file or the file itself." ), ) @click.argument( "licenses", # TRANSLATORS: You may translate this. Please preserve capital letters. metavar=_("LICENSE"), type=str, nargs=-1, ) @click.pass_obj def download( obj: ClickObj, licenses: Collection[str], all_: bool, output: Path | None, source: Path | None, ) -> None: # pylint: disable=missing-function-docstring if all_ and licenses: raise click.UsageError( _( "The 'LICENSE' argument and '--all' option are mutually" " exclusive." ) ) if all_: # TODO: This is fairly inefficient, but gets the job done. report = ProjectReport.generate(obj.project, do_checksum=False) licenses = report.missing_licenses.keys() if len(licenses) > 1 and output: raise click.UsageError( _("Cannot use '--output' with more than one license.") ) licenses = {_strip_plus_from_identifier(lic) for lic in licenses} return_code = 0 for lic in licenses: destination: Path = output # type: ignore if destination is None: destination = _path_to_license_file(lic, obj.project) try: put_license_in_file(lic, destination=destination, source=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) sys.exit(return_code) reuse-tool-6.2.0/src/reuse/cli/supported_licenses.py0000664000175000017500000000306215077707000021234 0ustar alexalex# SPDX-FileCopyrightText: 2021 Free Software Foundation Europe e.V. # SPDX-FileCopyrightText: 2021 Michael Weimann # SPDX-FileCopyrightText: 2022 Florian Snow # SPDX-FileCopyrightText: 2025 Shun Sakai # # SPDX-License-Identifier: GPL-3.0-or-later """Click code for supported-licenses subcommand.""" import json import click from .._licenses import _LICENSES, _load_license_list from ..i18n import _ from .common import ClickObj from .main import main _HELP = _("List all licenses on the SPDX License List.") @main.command(name="supported-licenses", help=_HELP) @click.option( "--json", "-j", "format_json", is_flag=True, help=_("Format output as JSON."), ) @click.pass_obj def supported_licenses(_obj: ClickObj, format_json: bool) -> None: # pylint: disable=missing-function-docstring licenses = _load_license_list(_LICENSES)[1] if format_json: result = [ { "id": license_id, "name": license_info["name"], "reference": license_info["reference"], } for license_id, license_info in licenses.items() ] click.echo(json.dumps(result, indent=2), nl=False) else: for license_id, license_info in licenses.items(): license_name = license_info["name"] license_reference = license_info["reference"] click.echo( f"{license_id: <40}\t{license_name: <80}\t" f"{license_reference: <50}" ) reuse-tool-6.2.0/src/reuse/cli/common.py0000664000175000017500000000672515077707000016623 0ustar alexalex# SPDX-FileCopyrightText: 2024 Free Software Foundation Europe e.V. # # SPDX-License-Identifier: GPL-3.0-or-later """Utilities that are common to multiple CLI commands.""" from collections.abc import Mapping from dataclasses import dataclass from functools import cached_property from pathlib import Path from typing import Any import click from ..copyright import SpdxExpression from ..exceptions import GlobalLicensingConflictError, GlobalLicensingParseError from ..i18n import _ from ..project import Project from ..vcs import find_root @dataclass() class ClickObj: """A dataclass holding necessary context and options.""" root: Path | None = None include_submodules: bool = False include_meson_subprojects: bool = False no_multiprocessing: bool = True @cached_property def project(self) -> Project: """Generate a project object on demand.""" root = self.root if root is None: root = find_root() if root is None: root = Path.cwd() try: return Project.from_directory( root, include_submodules=self.include_submodules, include_meson_subprojects=self.include_meson_subprojects, ) # FileNotFoundError and NotADirectoryError don't need to be caught # because argparse already made sure of these things. except GlobalLicensingParseError as error: raise click.UsageError( _( "'{path}' could not be parsed. We received the" " following error message: {message}" ).format(path=error.source, message=str(error)) ) from error except (GlobalLicensingConflictError, OSError) as error: raise click.UsageError(str(error)) from error class MutexOption(click.Option): """Enable declaring mutually exclusive options.""" def __init__(self, *args: Any, **kwargs: Any): self.mutually_exclusive: set[str] = set( kwargs.pop("mutually_exclusive", []) ) super().__init__(*args, **kwargs) # If self is in mutex, remove it. self.mutually_exclusive -= {self.name} @staticmethod def _get_long_name(ctx: click.Context, name: str) -> str: """Given the option name, get the long name of the option. For example, 'output' return '--output'. """ param = next( param for param in ctx.command.params if param.name == name ) return param.opts[0] def handle_parse_result( self, ctx: click.Context, opts: Mapping[str, Any], args: list[str] ) -> tuple[Any, list[str]]: if self.mutually_exclusive.intersection(opts) and self.name in opts: raise click.UsageError( _("'{name}' is mutually exclusive with: {opts}").format( name=self._get_long_name(ctx, str(self.name)), opts=", ".join( f"'{self._get_long_name(ctx, opt)}'" for opt in self.mutually_exclusive ), ) ) return super().handle_parse_result(ctx, opts, args) def spdx_identifier(text: str) -> SpdxExpression: """Factory for creating SPDX expressions.""" expression = SpdxExpression(text) if not expression.is_valid: raise click.UsageError( _("'{}' is not a valid SPDX expression.").format(text) ) return expression reuse-tool-6.2.0/src/reuse/_annotate.py0000664000175000017500000001254615077707000016532 0ustar alexalex# 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 logging import sys from typing import IO, cast from jinja2 import Environment, FileSystemLoader, Template from jinja2.exceptions import TemplateNotFound from ._util import _determine_license_suffix_path from .comment import ( NAME_STYLE_MAP, CommentStyle, EmptyCommentStyle, get_comment_style, ) from .copyright import ReuseInfo from .exceptions import CommentCreateError, MissingReuseInfoError from .extract import contains_reuse_info from .header import add_new_header, find_and_replace_header from .i18n import _ from .project import Project from .types import StrPath _LOGGER = logging.getLogger(__name__) 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: Template | None, template_is_commented: bool, style: str | None, encoding: str = "utf-8", newline: str = "\n", 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: type[CommentStyle] | None = 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, encoding=encoding) 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 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 MissingReuseInfoError: 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=encoding, newline=newline) 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 reuse-tool-6.2.0/src/reuse/download.py0000664000175000017500000000715515077707000016371 0ustar alexalex# 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 urllib.request from pathlib import Path from urllib.error import URLError from urllib.parse import urljoin from ._licenses import ALL_NON_DEPRECATED_MAP from ._util import find_licenses_directory from .extract import _LICENSEREF_PATTERN from .project import Project from .types import StrPath 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. """ if spdx_identifier not in ALL_NON_DEPRECATED_MAP: spdx_identifier = f"deprecated_{spdx_identifier}" # 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: Path | None = project.root # Hack if ( root and 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: StrPath | None = 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) reuse-tool-6.2.0/src/reuse/comment.py0000664000175000017500000007627015077707000016230 0ustar alexalex# 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, 2025 Florian Snow # SPDX-FileCopyrightText: 2022 Nico Rikken # SPDX-FileCopyrightText: 2022 Sebastian Crane # SPDX-FileCopyrightText: 2022 Stefan Hynek # SPDX-FileCopyrightText: 2022 Arnouet Engelen # 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-FileCopyrightText: 2024 Anthony Loiseau # SPDX-FileCopyrightText: 2024 Yongmin Hong # SPDX-FileCopyrightText: 2025 Raphael Schlarb # SPDX-FileCopyrightText: 2025 András Nagy # SPDX-FileCopyrightText: 2025 Kiko Fernandez-Reyes # SPDX-FileCopyrightText: 2025 Hatzka # SPDX-FileCopyrightText: 2025 Johannes HAMPP # SPDX-FileCopyrightText: 2025 Simon Barth # SPDX-FileCopyrightText: 2025 Maximilian Franzke # SPDX-FileCopyrightText: 2025 Sacha-Élie Ayoun # SPDX-FileCopyrightText: 2025 Thomas Gilon # SPDX-FileCopyrightText: 2025 Manlio Perillo # SPDX-FileCopyrightText: 2025 Matthias Schoettle # # SPDX-License-Identifier: GPL-3.0-or-later # pylint: disable=too-many-lines """Module for parsing and creating comments. Just enough to deal with comment headers, in any case. """ import logging import operator import re from pathlib import Path from textwrap import dedent from typing import NamedTuple from .exceptions import CommentCreateError, CommentParseError from .types import StrPath _LOGGER = logging.getLogger(__name__) 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: re.Pattern | None = 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(): if cls.SINGLE_LINE_REGEXP: if match := cls.SINGLE_LINE_REGEXP.match(line): line = line.removeprefix(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.removeprefix(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: int | None = 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 BladeCommentStyle(CommentStyle): """Laravel Blade Template comment style.""" _shorthand = "blade" MULTI_LINE = MultiLineSegments("{{--", "", "--}}") 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 = " " SHEBANGS = ["cabal-version:"] 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} def get_comment_style(path: StrPath) -> type[CommentStyle] | None: """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 = EXTENSION_COMMENT_STYLE_MAP_LOWERCASE.get( "".join(path.suffixes).lower() ) if style is None: style = 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 reuse-tool-6.2.0/src/reuse/extract.py0000664000175000017500000004354715077707000016241 0ustar alexalex# 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: 2024 Skyler Grey # SPDX-FileCopyrightText: © 2020 Liferay, Inc. # SPDX-FileCopyrightText: 2025 Simon Barth # # SPDX-License-Identifier: GPL-3.0-or-later """Utilities related to the extraction of REUSE information out of files.""" import codecs import contextlib import importlib import logging import os import platform import re import sys from encodings import aliases, normalize_encoding from itertools import chain from types import ModuleType from typing import BinaryIO, Generator, Literal, NamedTuple, cast from .comment import _all_style_classes from .copyright import ( COPYRIGHT_NOTICE_PATTERN, CopyrightNotice, ReuseInfo, SpdxExpression, ) from .exceptions import NoEncodingModuleError from .i18n import _ _LOGGER = logging.getLogger(__name__) _ENCODING_MODULES = { # pylint: disable=invalid-name "python-magic": "magic", "file-magic": "magic", "charset_normalizer": "charset_normalizer", "chardet": "chardet", } if _env_encoding_module := os.environ.get("REUSE_ENCODING_MODULE"): # Backwards compatibility. In v6.1.2, 'magic' used to mean 'python-magic'. if _env_encoding_module == "magic": _env_encoding_module = "python-magic" if _env_encoding_module not in _ENCODING_MODULES: print( # TRANSLATORS: Do not translate REUSE_ENCODING_MODULE. _( "REUSE_ENCODING_MODULE must have a value in {modules}; it has" " '{env_module}'. Aborting." ).format( modules=list(_ENCODING_MODULES.keys()), env_module=_env_encoding_module, ) ) sys.exit(1) _ENCODING_MODULES = { # pylint: disable=invalid-name _env_encoding_module: ( "magic" if "magic" in _env_encoding_module else _env_encoding_module ) } _ENCODING_MODULE: ModuleType | None = None _MAGIC = None for _module in _ENCODING_MODULES.values(): if _module == "magic" and platform.system() == "Windows": continue try: _ENCODING_MODULE = importlib.import_module(_module) break except ImportError: continue else: raise NoEncodingModuleError( _( "No supported module that can detect the encoding of files could be" " successfully imported. Re-read the installation instructions for" " the reuse package, or try the following:" ) + "\n\n" + _( "- If you are running a Linux distribution, try your equivalent of" " `apt install file` or `dnf install file`." ) + "\n" + _( "- Run ` pipx install reuse[charset-normalizer]`. Replace 'pipx'" " with 'pip' if you are not using pipx." ) ) def _detect_magic(module: ModuleType) -> Literal["python-magic", "file-magic"]: if hasattr(module, "from_buffer"): return "python-magic" return "file-magic" def get_encoding_module() -> ModuleType: """Get the module used to detect the encodings of files.""" return cast(ModuleType, _ENCODING_MODULE) def _get_encoding_module_name() -> str | None: module = get_encoding_module() result = getattr(module, "__name__", None) if result == "magic": return _detect_magic(module) return result def set_encoding_module(name: str) -> ModuleType: """Set the module used to detect the encodings of files, and return the module. """ if name not in _ENCODING_MODULES: raise NoEncodingModuleError(f"'{name}' is not a valid encoding module.") try: # pylint: disable=global-statement global _ENCODING_MODULE _ENCODING_MODULE = importlib.import_module(name) return _ENCODING_MODULE except ImportError as err: raise NoEncodingModuleError(f"'{name}' could not be imported.") from err if _get_encoding_module_name() == "python-magic": _MAGIC = get_encoding_module().Magic(mime_encoding=True) REUSE_IGNORE_START = "REUSE-IgnoreStart" REUSE_IGNORE_END = "REUSE-IgnoreEnd" # REUSE-IgnoreStart SPDX_SNIPPET_INDICATOR = b"SPDX-SnippetBegin" _START_PATTERN = r"(?:^.*?)" _END_PATTERN = r"\s*(?:{})*\s*$".format( "|".join( set( 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. ( # ex: r'"\s*/*>', r"'\s*/*>", # ex: [SPDX-License-Identifier: GPL-3.0-or-later] :: r"\]\s*::", ), ) ) ) ) _ALL_MATCH_PATTERN = re.compile( r"^(?P.*?)(?:SPDX-\S+:|Copyright|©).*$", re.MULTILINE, ) _COPYRIGHT_NOTICE_PATTERN = re.compile( _START_PATTERN + COPYRIGHT_NOTICE_PATTERN.pattern + _END_PATTERN, ) _LICENSE_IDENTIFIER_PATTERN = re.compile( _START_PATTERN + r"SPDX-License-Identifier:\s*(?P.*?)" + _END_PATTERN, ) _CONTRIBUTOR_PATTERN = re.compile( _START_PATTERN + r"SPDX-FileContributor:\s*(?P.*?)" + _END_PATTERN, ) # The keys match the relevant attributes of ReuseInfo. _SPDX_TAGS: dict[str, re.Pattern] = { "spdx_expressions": _LICENSE_IDENTIFIER_PATTERN, "contributor_lines": _CONTRIBUTOR_PATTERN, } _LICENSEREF_PATTERN = re.compile(r"LicenseRef-[a-zA-Z0-9-.]+$") _NEWLINE_PATTERN = re.compile(r"\r\n?") _LINE_ENDINGS = ("\r\n", "\r", "\n") _LINE_ENDINGS_ASCII = tuple(ending.encode("ascii") for ending in _LINE_ENDINGS) _LINE_ENDINGS_UTF_16_LE = tuple( ending.encode("utf_16_le") for ending in _LINE_ENDINGS ) _LINE_ENDINGS_UTF_32_LE = tuple( ending.encode("utf_32_le") for ending in _LINE_ENDINGS ) _LINE_ENDING_ENCODINGS_ASCII = set() for _name in set(chain.from_iterable(aliases.aliases.items())): with contextlib.suppress(Exception): if codecs.encode("\r\n", _name) == b"\r\n": _LINE_ENDING_ENCODINGS_ASCII.add(_name) _LINE_ENDING_ENCODINGS_ASCII.add("utf_8_sig") _LINE_ENDING_ENCODINGS_UTF_16_LE = { "u16", "utf16", "utf_16", "unicodelittleunmarked", "utf_16le", "utf_16_le", } _LINE_ENDING_ENCODINGS_UTF_32_LE = { "u32", "utf32", "utf_32", "utf_32le", "utf_32_le", } #: Default chunk size for reading files. CHUNK_SIZE = 1024 * 64 #: Default line size for reading files. LINE_SIZE = 1024 #: Default chunk size used to heuristically detect file type, encoding, et #: cetera. HEURISTICS_CHUNK_SIZE = 1024 * 2 class FilterBlock(NamedTuple): """A simple tuple that holds a block of text, and whether that block of text is in an ignore block. """ text: str in_ignore_block: bool def filter_ignore_block( text: str, in_ignore_block: bool = False ) -> FilterBlock: """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. Args: text: The text out of which the ignore blocks must be filtered. in_ignore_block: Whether the text is already in an ignore block. This is useful when you parse subsequent chunks of text, and one chunk does not close the ignore block. Returns: A :class:`FilterBlock` tuple that contains the filtered text and a boolean that signals whether the ignore block is still open. """ ignore_start: int | None = None if not in_ignore_block else 0 ignore_end: int | None = 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 ignore_start is None: return FilterBlock(text, False) if ignore_end is None: return FilterBlock(text[:ignore_start], True) if ignore_start < ignore_end: text_before_block = text[:ignore_start] text_after_block, in_ignore_block = filter_ignore_block( text[ignore_end:], False ) return FilterBlock( text_before_block + text_after_block, in_ignore_block ) 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) text_before_block = text[:ignore_start] text_after_block, in_ignore_block = filter_ignore_block( rest[ignore_end:] ) return FilterBlock( text_before_block + text_after_block, in_ignore_block ) return FilterBlock(text[:ignore_start], True) def extract_reuse_info(text: str) -> ReuseInfo: """Extract REUSE information from a multi-line text block. Raises: ExpressionError: if an SPDX expression could not be parsed. ParseError: if an SPDX expression could not be parsed. """ notices: set[CopyrightNotice] = set() expressions: set[SpdxExpression] = set() contributors: set[str] = set() for possible in _ALL_MATCH_PATTERN.finditer(text): possible_text = possible.group() prefix = possible.group("prefix").strip() reversed_prefix = prefix[::-1] possible_text = possible_text.removesuffix(reversed_prefix) if match := _COPYRIGHT_NOTICE_PATTERN.match(possible_text): notices.add(CopyrightNotice.from_match(match)) elif match := _LICENSE_IDENTIFIER_PATTERN.match(possible_text): expressions.add(SpdxExpression(match.group("value"))) elif match := _CONTRIBUTOR_PATTERN.match(possible_text): contributors.add(match.group("value")) return ReuseInfo( spdx_expressions=expressions, copyright_notices=notices, contributor_lines=contributors, ) def _read_chunks( fp: BinaryIO, chunk_size: int = CHUNK_SIZE, line_size: int = LINE_SIZE, newline: bytes = b"\n", ) -> Generator[bytes, None, None]: """Read and yield somewhat equal-sized chunks from (realistically) a file. The chunks always split at a newline where possible. An amount of bytes equal to *chunk_size* is always read into the chunk if *fp* contains that many bytes. An additional *line_size* or lesser amount of bytes is also read into the chunk, up to the next newline character. *newline* is the line separator that is (expected to be) used in the input. """ newline_len = len(newline) while True: chunk = fp.read(chunk_size) if not chunk: break end_chunk_pos = fp.tell() remainder = fp.read(line_size) newline_idx = remainder.find(newline) if newline_idx != -1: remainder = remainder[: newline_idx + newline_len] fp.seek(end_chunk_pos + newline_idx + newline_len) chunk += remainder yield chunk def _detect_encoding_magic(mime_encoding: str, chunk: bytes) -> str | None: if mime_encoding == "binary": return None if mime_encoding == "utf-8" and chunk[:3] == b"\xef\xbb\xbf": mime_encoding += "-sig" # Python and magic disagree on what 'le' means. For magic, it means a UTF-16 # block prefixed with a BOM. For Python, that's what 'utf-16' is, and # 'utf_16_le' is a little endian block _without_ BOM prefix. elif mime_encoding == "utf-16le" and chunk[:2] == b"\xff\xfe": mime_encoding = "utf-16" elif mime_encoding == "utf-32le" and chunk[:4] == b"\xff\xfe\x00\x00": mime_encoding = "utf-32" else: # This nifty function gets the (in Python) standardised name for an # encoding. 'iso-8859-1' becomes 'iso8859-1'. try: codec_info = codecs.lookup(mime_encoding) mime_encoding = codec_info.name except LookupError: # Fallback. mime_encoding = "utf-8" return normalize_encoding(mime_encoding) def _detect_encoding_python_magic(chunk: bytes) -> str | None: result: str = _MAGIC.from_buffer(chunk) # type: ignore[union-attr] return _detect_encoding_magic(result, chunk) def _detect_encoding_file_magic(chunk: bytes) -> str | None: result: str = get_encoding_module().detect_from_content(chunk).encoding return _detect_encoding_magic(result, chunk) def _detect_encoding_charset_normalizer(chunk: bytes) -> str | None: matches = get_encoding_module().from_bytes( # type: ignore[union-attr] chunk, ) best = matches.best() if best is not None: result: str = best.encoding if result == "utf_8" and best.bom: result += "_sig" return result return None def _detect_encoding_chardet(chunk: bytes) -> str | None: dict_ = get_encoding_module().detect(chunk) # type: ignore[union-attr] result: str | None = dict_.get("encoding") if result is None: return None try: codec_info = codecs.lookup(result) result = codec_info.name except LookupError: # Fallback. result = "utf-8" return normalize_encoding(result) def detect_encoding(chunk: bytes) -> str | None: """Find the encoding of the bytes chunk, and return it as normalised name. See :func:`encodings.normalize_encoding`. If no encoding could be found, return :const:`None`. If the chunk is empty or the encoding of the chunk is ASCII, ``'utf_8'`` is returned. """ # If the file is empty, assume UTF-8. if not chunk: return "utf_8" result: str | None = None if _get_encoding_module_name() == "python-magic": result = _detect_encoding_python_magic(chunk) elif _get_encoding_module_name() == "file-magic": result = _detect_encoding_file_magic(chunk) elif _get_encoding_module_name() == "charset_normalizer": result = _detect_encoding_charset_normalizer(chunk) elif _get_encoding_module_name() == "chardet": result = _detect_encoding_chardet(chunk) else: # This code should technically never be reached. raise NoEncodingModuleError() if result in ["ascii", "us_ascii"]: result = "utf_8" return result def detect_newline(chunk: bytes, encoding: str = "ascii") -> str: """Return one of ``'\\n'``, ``'\\r'`` or ``'\\r\\n'`` depending on the line endings used in *chunk*. Return :const:`os.linesep` if there are no line endings. """ line_endings: tuple[bytes, ...] | None = None encoding = normalize_encoding(encoding.lower()) # This step is part optimalisation, part dealing with BOMs. if encoding in _LINE_ENDING_ENCODINGS_ASCII: line_endings = _LINE_ENDINGS_ASCII elif encoding in _LINE_ENDING_ENCODINGS_UTF_16_LE: line_endings = _LINE_ENDINGS_UTF_16_LE elif encoding in _LINE_ENDING_ENCODINGS_UTF_32_LE: line_endings = _LINE_ENDINGS_UTF_32_LE if line_endings is not None: for line_ending_bytes in line_endings: if line_ending_bytes in chunk: return line_ending_bytes.decode(encoding) else: for line_ending_str in _LINE_ENDINGS: if line_ending_str.encode(encoding) in chunk: return line_ending_str return os.linesep def reuse_info_of_file( fp: BinaryIO, chunk_size: int = CHUNK_SIZE, line_size: int = LINE_SIZE, ) -> ReuseInfo: """Read from *fp* to extract REUSE information. It is read in chunks of *chunk_size*, additionally reading up to *line_size* until the next newline. This function decodes the binary data into UTF-8 and removes REUSE ignore blocks before attempting to extract the REUSE information. """ position = fp.tell() heuristics_chunk = fp.read(HEURISTICS_CHUNK_SIZE) fp.seek(position) # Reset position. encoding = detect_encoding(heuristics_chunk) filename = getattr(fp, "name", None) if encoding is None: if filename: _LOGGER.info( _( "'{path}' was detected as a binary file; not searching its" " contents for REUSE information." ).format(path=filename) ) return ReuseInfo() newline = detect_newline(heuristics_chunk, encoding=encoding) if filename: _LOGGER.debug( _( "extracting REUSE information from '{path}'" " (encoding {encoding}, encoding module {module}," " newline {newline})" ).format( path=filename, encoding=repr(encoding), module=repr(_get_encoding_module_name()), newline=repr(newline), ) ) in_ignore_block = False reuse_infos: list[ReuseInfo] = [] for chunk in _read_chunks( fp, chunk_size=chunk_size, line_size=line_size, newline=newline.encode(encoding), ): text = chunk.decode(encoding, errors="replace") text = _NEWLINE_PATTERN.sub("\n", text) text, in_ignore_block = filter_ignore_block(text, in_ignore_block) reuse_infos.append(extract_reuse_info(text)) return ReuseInfo().union(*reuse_infos) def contains_reuse_info(text: str) -> bool: """The text contains REUSE info.""" return bool(extract_reuse_info(filter_ignore_block(text).text)) # REUSE-IgnoreEnd reuse-tool-6.2.0/src/reuse/types.py0000664000175000017500000000044115077707000015715 0ustar alexalex# SPDX-FileCopyrightText: 2017 Free Software Foundation Europe e.V. # # SPDX-License-Identifier: GPL-3.0-or-later """Some typing definitions.""" from os import PathLike from typing import Union #: Something that looks like a path. StrPath = Union[str, PathLike[str]] reuse-tool-6.2.0/src/reuse/global_licensing.py0000664000175000017500000005434615077707000020061 0ustar alexalex# 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 functools import logging import re from abc import ABC, abstractmethod from collections import defaultdict from collections.abc import Callable, Collection, Generator, Iterable from enum import Enum from pathlib import Path, PurePath from typing import Any, TypeVar, cast import attrs import tomlkit from attr.validators import _InstanceOfValidator as _AttrInstanceOfValidator from debian.copyright import Copyright from debian.copyright import Error as DebianError from .copyright import CopyrightNotice, ReuseInfo, SourceType, SpdxExpression from .covered_files import is_path_ignored from .exceptions import ( CopyrightNoticeParseError, GlobalLicensingParseError, GlobalLicensingParseTypeError, GlobalLicensingParseValueError, ) from .i18n import _ from .types import StrPath from .vcs import VCSStrategy _LOGGER = logging.getLogger(__name__) _T = TypeVar("_T") #: Current version of REUSE.toml. REUSE_TOML_VERSION = 1 #: Relation between Python attribute names and TOML keys. _TOML_KEYS = { "paths": "path", "precedence": "precedence", "_copyright_notices": "SPDX-FileCopyrightText", "_spdx_expressions": "SPDX-License-Identifier", } 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" @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 isinstance(instance, AnnotationsItem): attr_name = _TOML_KEYS[attribute.name] else: attr_name = attribute.name source = getattr(instance, "source", None) 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__), ), source=source, ) 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__), ), source=source, ) if not self.optional and not value: raise GlobalLicensingParseValueError( _("{attr_name} must not be empty.").format( attr_name=repr(attr_name), ), source=source, ) 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__), ), source=getattr(inst, "source", None), ) 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 error: 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 error def _to_set(value: _T | Iterable[_T] | None) -> set[_T]: if value is None: return set() # Special case for strings. if isinstance(value, str): return {cast(_T, value)} if hasattr(value, "__iter__"): return set(value) return {value} # The attrs library infers __init__ parameter types from the converter's # signature. The signature of _to_set confuses mypy, so this wrapper exposes a # simpler signature just for use with attrs. def _to_set_any(value: Any | None) -> set[Any]: return cast(set[Any], _to_set(value)) def _to_set_of_expr( value: str | Iterable[str] | None, ) -> set[SpdxExpression]: value = _to_set(value) return {SpdxExpression(expression) for expression in value} def _to_set_of_notice( value: str | Iterable[str] | None, ) -> set[CopyrightNotice]: value = _to_set(value) result = set() for notice in value: try: result.add(CopyrightNotice.from_string(notice)) except CopyrightNoticeParseError as error: try: result.add( CopyrightNotice.from_string( f"SPDX-FileCopyrightText: {notice}" ) ) except CopyrightNoticeParseError: raise GlobalLicensingParseValueError( _("Could not parse '{notice}'").format(notice=notice) ) from error return result @attrs.define(frozen=True) 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, **kwargs: Any) -> "GlobalLicensing": """Parse the file and create a :class:`GlobalLicensing` object from its contents. Raises: FileNotFoundError: file doesn't exist. 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(frozen=True) class ReuseDep5(GlobalLicensing): """A soft wrapper around :class:`Copyright`.""" dep5_copyright: Copyright @classmethod def from_file(cls, path: StrPath, **kwargs: Any) -> "ReuseDep5": path = Path(path) try: with path.open(encoding="utf-8") as fp: return cls(str(path), Copyright(fp)) except UnicodeDecodeError as error: raise GlobalLicensingParseError( str(error), source=str(path) ) from error # TODO: Remove ValueError once # # is closed except (DebianError, ValueError) as error: raise GlobalLicensingParseError( str(error), source=str(path) ) 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=_to_set_of_expr(result.license.synopsis), copyright_notices=_to_set_of_notice( 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(frozen=True) class AnnotationsItem: """A class that maps to a single [[annotations]] table element in REUSE.toml. """ paths: set[str] = attrs.field( converter=_to_set_any, validator=_validate_collection_of(set, str, optional=False), ) precedence: PrecedenceType = attrs.field( converter=_str_to_global_precedence, default=PrecedenceType.CLOSEST ) _copyright_notices: set[str] = attrs.field( alias="copyright_notices", converter=_to_set_any, validator=_validate_collection_of(set, str, optional=True), default=None, ) _spdx_expressions: set[str] = attrs.field( alias="spdx_expressions", converter=_to_set_any, validator=_validate_collection_of(set, str, optional=True), default=None, ) def __attrs_post_init__(self) -> None: # Immediately trigger cached properties to get error as needed. _ = self.copyright_notices _ = self.spdx_expressions @functools.cached_property def copyright_notices(self) -> set[CopyrightNotice]: return _to_set_of_notice(self._copyright_notices) @functools.cached_property def spdx_expressions(self) -> set[SpdxExpression]: return _to_set_of_expr(self._spdx_expressions) @functools.cached_property def _paths_regex(self) -> re.Pattern: def translate(path: str) -> str: # pylint: disable=too-many-branches blocks = [] escaping = False globstar = False prev_char = "" for char in path: if char == "\\": if prev_char == "\\" and escaping: escaping = False blocks.append("\\\\") 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: if prev_char == "*": blocks.append("[^/]*") 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})$" return 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(_TOML_KEYS["paths"]) precedence = values.get(_TOML_KEYS["precedence"]) if precedence is not None: new_dict["precedence"] = precedence new_dict["copyright_notices"] = values.get( _TOML_KEYS["_copyright_notices"] ) new_dict["spdx_expressions"] = values.get( _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(frozen=True) 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", []) try: annotations = [ AnnotationsItem.from_dict(annotation) for annotation in annotation_dicts ] except GlobalLicensingParseError as error: error.source = source raise error from error 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), source=source ) from error return cls.from_dict(tomldict, source) @classmethod def from_file(cls, path: StrPath, **kwargs: Any) -> "ReuseTOML": try: with Path(path).open(encoding="utf-8") as fp: return cls.from_toml(fp.read(), str(path)) except UnicodeDecodeError as error: raise GlobalLicensingParseError( str(error), source=str(path) ) from error def find_annotations_item(self, path: StrPath) -> AnnotationsItem | None: """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_notices=item.copyright_notices, 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(frozen=True) 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, **kwargs: Any) -> "NestedReuseTOML": """TODO: *path* is a directory instead of a file.""" include_submodules: bool = kwargs.get("include_submodules", False) include_meson_subprojects: bool = kwargs.get( "include_meson_subprojects", False ) vcs_strategy: VCSStrategy | None = kwargs.get("vcs_strategy") tomls = [ ReuseTOML.from_file(toml_path) for toml_path in cls.find_reuse_tomls( path, include_submodules=include_submodules, include_meson_subprojects=include_meson_subprojects, vcs_strategy=vcs_strategy, ) ] 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_notices=set(), spdx_expressions=set() ) if not copyright_found and info.copyright_notices: new_info = new_info.copy( copyright_notices=info.copyright_notices ) 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, include_submodules: bool = False, include_meson_subprojects: bool = False, vcs_strategy: VCSStrategy | None = None, ) -> Generator[Path, None, None]: """Find all REUSE.toml files in *path*. *path* should be the root of the directory. If it is not, REUSE.toml files which are in ignored directories may not be correctly ignored. """ path = Path(path) reuse_tomls = path.rglob("REUSE.toml") for item in reuse_tomls: if is_path_ignored( item, include_submodules=include_submodules, include_meson_subprojects=include_meson_subprojects, include_reuse_tomls=True, vcs_strategy=vcs_strategy, ): continue rel = item.relative_to(path) parts = rel.parts for directory in ( path.joinpath(*parts[:i]) for i in range(1, len(parts)) ): if is_path_ignored( directory, include_submodules=include_submodules, include_meson_subprojects=include_meson_subprojects, vcs_strategy=vcs_strategy, ): break else: yield item def _find_relevant_tomls(self, path: StrPath) -> list[ReuseTOML]: found = [] for toml in self.reuse_tomls: if PurePath(path).is_relative_to(toml.directory): 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-6.2.0/src/reuse/i18n.py0000664000175000017500000000221615077707000015332 0ustar alexalex# SPDX-FileCopyrightText: 2024 Carmen Bianca BAKKER # SPDX-FileCopyrightText: 2024 Free Software Foundation Europe e.V. # # SPDX-License-Identifier: GPL-3.0-or-later """:mod:`gettext` plumbing of :mod:`reuse`.""" import gettext as _gettext_module import os _PACKAGE_PATH = os.path.dirname(__file__) _LOCALE_DIR = os.path.join(_PACKAGE_PATH, "locale") #: Translations object used throughout :mod:`reuse`. The translations #: are sourced from ``reuse/locale//LC_MESSAGES/reuse.mo``. TRANSLATIONS: _gettext_module.NullTranslations = _gettext_module.translation( "reuse", localedir=_LOCALE_DIR, fallback=True ) #: :meth:`gettext.NullTranslations.gettext` of :data:`TRANSLATIONS` _ = TRANSLATIONS.gettext #: :meth:`gettext.NullTranslations.gettext` of :data:`TRANSLATIONS` gettext = TRANSLATIONS.gettext #: :meth:`gettext.NullTranslations.ngettext` of :data:`TRANSLATIONS` ngettext = TRANSLATIONS.ngettext #: :meth:`gettext.NullTranslations.pgettext` of :data:`TRANSLATIONS` pgettext = TRANSLATIONS.pgettext #: :meth:`gettext.NullTranslations.npgettext` of :data:`TRANSLATIONS` npgettext = TRANSLATIONS.npgettext reuse-tool-6.2.0/src/reuse/covered_files.py0000664000175000017500000001314215077707000017364 0ustar alexalex# SPDX-FileCopyrightText: 2017 Free Software Foundation Europe e.V. # # SPDX-License-Identifier: GPL-3.0-or-later """The REUSE Specification has a concept called Covered Files; files which must contain licensing information. Some files in a project are not Covered Files, and thus needn't contain licensing information. This module contains all that logic. """ import contextlib import logging import os import re import stat from collections.abc import Collection, Generator from pathlib import Path from typing import cast from .types import StrPath from .vcs import VCSStrategy _LOGGER = logging.getLogger(__name__) _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 = [ # LICENSE, LICENSE-MIT, LICENSE.txt re.compile(r"^LICEN[CS]E([-\.].*)?$"), re.compile(r"^COPYING([-\.].*)?$"), # ".git" as file happens in submodules re.compile(r"^\.git$"), re.compile(r"^\.hgtags$"), re.compile(r".*\.license$"), re.compile(r"^REUSE\.toml$"), # 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) def is_path_ignored( path: Path, subset_files: Collection[StrPath] | None = None, include_submodules: bool = False, include_meson_subprojects: bool = False, include_reuse_tomls: bool = False, vcs_strategy: VCSStrategy | None = None, ) -> bool: """Is *path* ignored by some mechanism?""" # pylint: disable=too-many-return-statements,too-many-branches name = path.name # Only stat the file once instead of multiple times. stat_result = path.lstat() # Symlink. if stat.S_ISLNK(stat_result.st_mode): _LOGGER.debug("skipping symlink '%s'", path) return True # File. if stat.S_ISREG(stat_result.st_mode): if subset_files is not None and path.resolve() not in subset_files: return True for pattern in _IGNORE_FILE_PATTERNS: if pattern.match(name) and ( name != "REUSE.toml" or not include_reuse_tomls ): return True # Suppressing this error because I simply don't want to deal # with that here. with contextlib.suppress(OSError): if stat_result.st_size == 0: _LOGGER.debug("skipping 0-sized file '%s'", path) return True # Directory. elif stat.S_ISDIR(stat_result.st_mode): if subset_files is not None and not any( Path(file_).is_relative_to(path.resolve()) for file_ in subset_files ): return True for pattern in _IGNORE_DIR_PATTERNS: if pattern.match(name): return True if not include_meson_subprojects: for pattern in _IGNORE_MESON_PARENT_DIR_PATTERNS: if pattern.match(path.parent.name): _LOGGER.info( "ignoring '%s' because it is a Meson subproject", path ) return True if ( not include_submodules and vcs_strategy and vcs_strategy.is_submodule(path) ): _LOGGER.info("ignoring '%s' because it is a submodule", path) return True if vcs_strategy and vcs_strategy.is_ignored(path): return True return False def iter_files( directory: StrPath, subset_files: Collection[StrPath] | None = None, include_submodules: bool = False, include_meson_subprojects: bool = False, include_reuse_tomls: bool = False, vcs_strategy: VCSStrategy | None = None, ) -> Generator[Path, None, None]: """Yield all Covered Files in *directory* and its subdirectories according to the REUSE Specification. """ directory = Path(directory) if subset_files is not None: subset_files = cast( set[Path], {Path(file_).resolve() for file_ in subset_files} ) for root_str, dirs, files in os.walk(directory): root = Path(root_str) # Don't walk ignored directories for dir_ in list(dirs): the_dir = root / dir_ if is_path_ignored( the_dir, subset_files=subset_files, include_submodules=include_submodules, include_meson_subprojects=include_meson_subprojects, include_reuse_tomls=include_reuse_tomls, vcs_strategy=vcs_strategy, ): _LOGGER.debug("ignoring '%s'", the_dir) dirs.remove(dir_) # Filter files. for file_ in files: the_file = root / file_ if is_path_ignored( the_file, subset_files=subset_files, include_submodules=include_submodules, include_meson_subprojects=include_meson_subprojects, include_reuse_tomls=include_reuse_tomls, vcs_strategy=vcs_strategy, ): _LOGGER.debug("ignoring '%s'", the_file) continue yield the_file reuse-tool-6.2.0/src/reuse/header.py0000664000175000017500000002707015077707000016010 0ustar alexalex# 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-FileCopyrightText: 2025 Rivos Inc. # SPDX-FileCopyrightText: 2025 Matthias Schoettle # # SPDX-License-Identifier: GPL-3.0-or-later """Functions for manipulating the comment headers of files.""" import logging import re from collections.abc import Sequence from typing import NamedTuple, cast from jinja2 import Environment, PackageLoader, Template from .comment import ( CommentStyle, EmptyCommentStyle, HtmlCommentStyle, PythonCommentStyle, ) from .copyright import CopyrightNotice, ReuseInfo from .exceptions import CommentParseError, MissingReuseInfoError from .extract import contains_reuse_info, extract_reuse_info from .i18n import _ _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 _FrontmatterCommentStyle(CommentStyle): """Frontmatter comment style. Used specifically for e.g. Markdown.""" SHORTHAND = "frontmatter" SINGLE_LINE = "#" INDENT_AFTER_SINGLE = " " SHEBANGS = ["---"] def _create_new_header( reuse_info: ReuseInfo, template: Template | None = None, template_is_commented: bool = False, style: type[CommentStyle] | None = None, force_multi: bool = False, ) -> str: """Format a new header from scratch. Raises: CommentCreateError: if a comment could not be created. MissingReuseInfoError: 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=map(str, sorted(reuse_info.copyright_notices)), 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_notices != new_reuse_info.copyright_notices 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 MissingReuseInfoError() return result # pylint: disable=too-many-arguments def create_header( reuse_info: ReuseInfo, header: str | None = None, template: Template | None = None, template_is_commented: bool = False, style: type[CommentStyle] | None = 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. MissingReuseInfoError: 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: existing_spdx = extract_reuse_info(header) if merge_copyrights: spdx_copyrights = CopyrightNotice.merge( reuse_info.copyright_notices.union( existing_spdx.copyright_notices ) ) else: spdx_copyrights = reuse_info.copyright_notices.union( existing_spdx.copyright_notices ) # TODO: This behaviour does not match the docstring. reuse_info = existing_spdx | reuse_info reuse_info = reuse_info.copy(copyright_notices=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: type[CommentStyle] | None = 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: MissingReuseInfoError: 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 MissingReuseInfoError() 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(keepends=True): if line.startswith(prefix): shebang_lines.append(line) text = text.replace(line, "", 1) else: break shebang = "".join(shebang_lines) return (shebang, text) def place_header( header: str, before: str, after: str, has_existing_header: bool, double_newline_after_before: bool = True, ) -> str: """Construct the resulting file with the header and the rest of the text in the file. """ new_text = f"{header}\n" if before.strip(): newlines = "\n\n" if double_newline_after_before else "\n" new_text = f"{before.rstrip()}{newlines}{new_text}" if after.strip(): # Create space between header and following code only if a newline # doesn't already exist, and there wasn't previously a header. if not has_existing_header and not after.startswith("\n"): separator = "\n" else: separator = "" new_text = f"{new_text}{separator}{after}" return new_text # pylint: disable=too-many-arguments def find_and_replace_header( text: str, reuse_info: ReuseInfo, template: Template | None = None, template_is_commented: bool = False, style: type[CommentStyle] | None = 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. MissingReuseInfoError: if the generated comment is missing SPDX information. """ if style is None: style = PythonCommentStyle # Workaround: Treat Markdown files with frontmatter with the Frontmatter # style instead. frontmatter = text.startswith("---") if style is HtmlCommentStyle and frontmatter: style = _FrontmatterCommentStyle try: before, header, after = _find_first_spdx_comment(text, style=style) except MissingReuseInfoError: 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 new_header = create_header( reuse_info, header, template=template, template_is_commented=template_is_commented, style=style, force_multi=force_multi, merge_copyrights=merge_copyrights, ) return place_header( new_header, before, after, bool(header), double_newline_after_before=not frontmatter, ) # pylint: disable=too-many-arguments def add_new_header( text: str, reuse_info: ReuseInfo, template: Template | None = None, template_is_commented: bool = False, style: type[CommentStyle] | None = 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, ) return place_header(header, shebang, text, False) reuse-tool-6.2.0/.pre-commit-hooks.yaml0000664000175000017500000000116615077707000016431 0ustar alexalex# SPDX-FileCopyrightText: © 2020 Liferay, Inc. # # SPDX-License-Identifier: GPL-3.0-or-later - id: reuse name: reuse lint entry: reuse args: ["lint"] language: python additional_dependencies: [".[charset-normalizer,chardet]"] pass_filenames: false description: "Lint the project directory for compliance with the REUSE Specification." - id: reuse-lint-file name: reuse lint-file entry: reuse args: ["lint-file"] language: python additional_dependencies: [".[charset-normalizer,chardet]"] description: "Lint the changed files for compliance with the REUSE Specification." reuse-tool-6.2.0/_build.py0000664000175000017500000000417515077707000014105 0ustar alexalex#!/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-6.2.0/pyproject.toml0000664000175000017500000001223215077707000015202 0ustar alexalex# 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 = "6.2.0" 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.10" Jinja2 = ">=3.0.0" license-expression = ">=21.6.14" python-debian = ">=0.1.48" # TODO: Consider removing this dependency in favour of tomllib when dropping # Python 3.10. tomlkit = ">=0.8" attrs = ">=23.2" click = ">=8.1" # TODO: In the future, with PEP 631, I can declare "python-magic>=0.4.12 ; extra # not in (x, y, z)", making it conditionally optional. # # Hi maintainers! python-magic is strictly speaking optional, and will not # import if libmagic is not available. One of the other modules below will be # used as fallback, in the below order. If you do not want a dependency on # python-magic, you can patch out this requirement and instead hard-require one # of the fallbacks. python-magic = ">=0.4.12" # Annoyingly, file-magic has the same module namespace as python-magic # ('magic'). If both are installed simultaneously, it is not self-evident which # of the two is imported. file-magic is the 'official' magic module. file-magic = { version = ">=0.4.1", optional = true } charset-normalizer = { version = ">=2.0.5", optional = true } chardet = { version = ">=3.0.2", optional = true } [tool.poetry.extras] file-magic = ["file-magic"] charset-normalizer = ["charset-normalizer"] chardet = ["chardet"] [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 = ">=3.0.2", 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.cli.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 = "v6.2.0" 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}"$', ] "docs/conf.py" = [ 'release = "{pep440_version}"$', ] "README.md" = [ 'rev: {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$', ] check_untyped_defs = true [[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-6.2.0/.prettierignore0000664000175000017500000000050515077707000015331 0ustar alexalex# 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-6.2.0/.prettierrc.yaml0000664000175000017500000000056515077707000015421 0ustar alexalex# 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-6.2.0/changelog.d/0000775000175000017500000000000015077707000014437 5ustar alexalexreuse-tool-6.2.0/changelog.d/changed/0000775000175000017500000000000015077707000016030 5ustar alexalexreuse-tool-6.2.0/changelog.d/changed/.protokolo.toml0000664000175000017500000000025515077707000021035 0ustar alexalex# SPDX-FileCopyrightText: 2024 Free Software Foundation Europe e.V. # # SPDX-License-Identifier: CC0-1.0 [protokolo.section] title = "Changed" order = 2 reuse-tool-6.2.0/changelog.d/security/0000775000175000017500000000000015077707000016306 5ustar alexalexreuse-tool-6.2.0/changelog.d/security/.protokolo.toml0000664000175000017500000000025615077707000021314 0ustar alexalex# SPDX-FileCopyrightText: 2024 Free Software Foundation Europe e.V. # # SPDX-License-Identifier: CC0-1.0 [protokolo.section] title = "Security" order = 6 reuse-tool-6.2.0/changelog.d/removed/0000775000175000017500000000000015077707000016100 5ustar alexalexreuse-tool-6.2.0/changelog.d/removed/.protokolo.toml0000664000175000017500000000025515077707000021105 0ustar alexalex# SPDX-FileCopyrightText: 2024 Free Software Foundation Europe e.V. # # SPDX-License-Identifier: CC0-1.0 [protokolo.section] title = "Removed" order = 4 reuse-tool-6.2.0/changelog.d/added/0000775000175000017500000000000015077707000015500 5ustar alexalexreuse-tool-6.2.0/changelog.d/added/.protokolo.toml0000664000175000017500000000025315077707000020503 0ustar alexalex# SPDX-FileCopyrightText: 2024 Free Software Foundation Europe e.V. # # SPDX-License-Identifier: CC0-1.0 [protokolo.section] title = "Added" order = 1 reuse-tool-6.2.0/changelog.d/.protokolo.toml0000664000175000017500000000027215077707000017443 0ustar alexalex# SPDX-FileCopyrightText: 2024 Free Software Foundation Europe e.V. # # SPDX-License-Identifier: CC0-1.0 [protokolo.section] title = "${version} - ${date}" level = 2 reuse-tool-6.2.0/changelog.d/deprecated/0000775000175000017500000000000015077707000016537 5ustar alexalexreuse-tool-6.2.0/changelog.d/deprecated/.protokolo.toml0000664000175000017500000000026015077707000021540 0ustar alexalex# SPDX-FileCopyrightText: 2024 Free Software Foundation Europe e.V. # # SPDX-License-Identifier: CC0-1.0 [protokolo.section] title = "Deprecated" order = 3 reuse-tool-6.2.0/changelog.d/fixed/0000775000175000017500000000000015077707000015536 5ustar alexalexreuse-tool-6.2.0/changelog.d/fixed/.protokolo.toml0000664000175000017500000000025315077707000020541 0ustar alexalex# SPDX-FileCopyrightText: 2024 Free Software Foundation Europe e.V. # # SPDX-License-Identifier: CC0-1.0 [protokolo.section] title = "Fixed" order = 5 reuse-tool-6.2.0/CODE_OF_CONDUCT.md0000664000175000017500000000046515077707000015072 0ustar alexalex 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-6.2.0/AUTHORS.rst0000664000175000017500000001404115077707000014145 0ustar alexalex.. 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 - Roberto Bauglir - 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 - Manlio Perillo - Mauro Aranda - Maxim Cournoyer - Mikko Piuhola - Raniere Silva - Robert Cohn - Simon Schliesky - Stefan Bakker - T. E. Kalayci - Thomas Bach - Walter Paulo - Wolfgang Traylor - Xinglu Chen - ethulhu - gfbdrgng - mdolling - psykose - Adrián Chaves - Alvar Penning - Aminda Suomalainen - Andrey Bienkowski - 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 - Kerry McAdams - 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 - Romain Tartière - Ryan Schmidt - Sebastian Crane - Sebastien Morais - Vishesh Handa - Vlad-Stefan Harbuz - Yaman Qalieh - criadoperez - nautilusx - pukkamustard - rajivsunar07 <56905029+rajivsunar07@users.noreply.github.com> - Сергій - Mersho - Skyler Grey - Emil Velikov - Linnea Gräf - Arnout Engelen - Raphael Schlarb - Matthias Schoettle - András Nagy - Kiko Fernandez-Reyes - Charlie Jenkins - Hatzka - Jonas Fierlings - ASCIIMoth - Johannes HAMPP - Simon Barth - Maximilian Franzke - Sacha-Élie Ayoun - Thomas Gilon - Yongmin Hong reuse-tool-6.2.0/README.md0000664000175000017500000002724015077707000013552 0ustar alexalex # 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.3 - Python: 3.10+ ## 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 ### Dependencies Unless you install via a package manager, it may be helpful to be aware of the following system dependencies of `reuse`: - Python 3.10+ - libmagic - Version control systems - Git - Mercurial 4.3+ - Pijul - Jujutsu Excepting Python, these dependencies are all _optional_. `reuse` will still work if they are not installed. If a version control system (VCS) is not installed, then `reuse` will not correctly ignore files which are ignored by the VCS, for example via `.gitignore`. If libmagic is not installed, then a slower mechanism will be used to detect the encodings of files. You may need to explicitly install the fall-back. When installing `reuse` as Python package, install `reuse[charset-normalizer]` instead. For example: `pipx install reuse[charset-normalizer]`. ### 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! For Debian and derivatives: ```bash apt install reuse ``` For Fedora and derivatives: ```bash dnf install reuse ``` An automatically generated list of available packages 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\Python310\Scripts`, depending on the Python version you have installed. To upgrade reuse, run this command: ```bash pipx upgrade reuse ``` ### 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.3 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. - `lint` --- Verify the project for REUSE compliance. - `lint-file` --- Verify REUSE compliance of individual files. - `spdx` --- Generate an SPDX Document of all files in the project. - `supported-licenses` --- Prints all licenses supported by REUSE. - `convert-dep5` --- Convert .reuse/dep5 to REUSE.toml. ### 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: v6.2.0 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. If you instead want to only lint files that were changed in your commit, you can use the following configuration: ```yaml repos: - repo: https://github.com/fsfe/reuse-tool rev: v6.2.0 hooks: - id: reuse-lint-file ``` ### Shell completion In order to enable shell completion, you need to generate the shell completion script. You do this with `_REUSE_COMPLETE=bash_source reuse`. Replace `bash` with `zsh` or `fish` as needed, or any other shells supported by the Python `click` library. You can then source the output in your shell rc file, like so (e.g.`~/.bashrc`): ```bash eval "$(_REUSE_COMPLETE=bash_source reuse)" ``` Alternatively, you can place the generated completion script in `${XDG_DATA_HOME}/bash-completion/completions/reuse`. ## Maintainers - Carmen Bianca Bakker - Florian Snow ### 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-6.2.0/.github/0000775000175000017500000000000015077707000013626 5ustar alexalexreuse-tool-6.2.0/.github/workflows/0000775000175000017500000000000015077707000015663 5ustar alexalexreuse-tool-6.2.0/.github/workflows/license_list_up_to_date.py0000664000175000017500000000422115077707000023114 0ustar alexalex# 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-6.2.0/.github/workflows/test.yaml0000664000175000017500000000700015077707000017523 0ustar alexalex# 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.10", "3.13"] os: [ubuntu-24.04] include: - python-version: "3.10" os: macos-latest - python-version: "3.10" 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 --all-extras - name: Run tests with pytest run: | poetry run pytest -vv --cov=reuse pylint: runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v2 - name: Set up Python uses: actions/setup-python@v2 with: python-version: "3.10" - 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-24.04 steps: - uses: actions/checkout@v2 - name: Set up Python uses: actions/setup-python@v2 with: python-version: "3.10" - 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-24.04 steps: - uses: actions/checkout@v2 - name: Set up Python uses: actions/setup-python@v2 with: python-version: "3.10" - 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-24.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-24.04 steps: - uses: actions/checkout@v2 - name: Set up Python uses: actions/setup-python@v2 with: python-version: "3.10" - 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-24.04 steps: - uses: actions/checkout@v2 - name: Set up Python uses: actions/setup-python@v2 with: python-version: "3.10" - 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-6.2.0/.github/workflows/third_party_lint.py0000664000175000017500000000770415077707000021624 0ustar alexalex#!/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-6.2.0/.github/workflows/gettext.yaml0000664000175000017500000000451015077707000020233 0ustar alexalex# 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-24.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 poetry, gettext, and wlc run: sudo apt-get install -y python3-poetry gettext wlc # We mostly install reuse to install the click dependency. - name: Install reuse run: poetry install --no-interaction --only main - 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: poetry 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 po/reuse.pot | 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-6.2.0/.github/workflows/jujutsu.yaml0000664000175000017500000000211415077707000020256 0ustar alexalex# SPDX-FileCopyrightText: 2023 Free Software Foundation Europe e.V. # SPDX-FileCopyrightText: 2024 Skyler Grey # # SPDX-License-Identifier: GPL-3.0-or-later name: Test with Jujutsu # These tests are run exclusively on the main branch to reduce CPU time wasted # on every single PR that very likely does not affect Jujutsu functionality. on: push: branches: - main paths: - "src/reuse/**.py" - "tests/**.py" jobs: test-jujutsu: runs-on: ubuntu-24.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 - name: Set up Jujutsu run: | cargo install cargo-binstall cargo binstall --strategies crate-meta-data jj-cli --no-confirm export PATH=~/.cargo/bin:$PATH - name: Run tests with pytest run: | poetry run pytest -vv --cov=reuse reuse-tool-6.2.0/.github/workflows/license_list_up_to_date.yaml0000664000175000017500000000112715077707000023430 0ustar alexalex# 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-24.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-6.2.0/.github/workflows/docker.yaml0000664000175000017500000000700615077707000020021 0ustar alexalex# 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-24.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-24.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-6.2.0/.github/workflows/pijul.yaml0000664000175000017500000000246615077707000017702 0ustar alexalex# 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 Pijul # 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-24.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 -vv --cov=reuse reuse-tool-6.2.0/.github/workflows/close_inactive_issues.yaml0000664000175000017500000000616615077707000023142 0ustar alexalex# SPDX-FileCopyrightText: 2025 Free Software Foundation Europe e.V. # # SPDX-License-Identifier: GPL-3.0-or-later name: Close inactive issues on: schedule: - cron: "22 2 * * *" permissions: actions: write contents: write issues: write pull-requests: write jobs: close-issues: runs-on: ubuntu-latest permissions: issues: write pull-requests: write steps: - uses: actions/stale@v9 with: days-before-issue-stale: 360 days-before-issue-close: 30 operations-per-run: 80 remove-stale-when-updated: false exempt-all-issue-assignees: true stale-issue-label: "stale" close-issue-label: "unresolved" stale-issue-message: "Thank you for your time and contributions! Unfortunately, this issue has been inactive for quite a while which means we probably can't manage the time to deal with it. That's why we're marking it as stale. We want to keep things tidy and focus on active discussions, but we’re always happy to revisit if this is still relevant!\n\nIf you’d like to keep this open, please add a comment to let us know and remove the label stale. Otherwise, this issue will most likely be automatically closed soon." close-issue-message: "Since there hasn't been any recent activity after the last message, we're going to go ahead and close this issue. Feel free to reopen this and remove the labels stale and unresolved if it's urgent.\n\nWe truly appreciate your contributions and engagement!\n\nThank you and happy hacking!" days-before-pr-stale: -1 days-before-pr-close: -1 stale-pr-label: "stale" close-pr-label: "unresolved" stale-pr-message: "Thank you so much for your contribution! We really appreciate your time and effort on this! However, this pull request has been inactive for a while, which means we have not been able to prioritize it. It also means there are most likely merge conflicts or required updates to bring it in line with the latest changes. To keep things organized and focus on active contributions, we're marking this as stale.\n\nIf this is still relevant and you'd like to keep it open, please update the branch and remove the label stale. Otherwise, this PR may be automatically closed soon. We're always happy to revisit if needed!" close-pr-message: "Since there hasn't been any recent activity after the last message, we're going to go ahead and close this pull request. If this is still relevant to you, feel free to reopen it and update the branch to resolve any conflicts. In that case, please also remove the labels stale and unresolved.\n\nWe truly appreciate your contributions and engagement!\n\nThank you and happy hacking!" repo-token: ${{ secrets.GITHUB_TOKEN }} reuse-tool-6.2.0/.github/workflows/third_party_lint.yaml0000664000175000017500000000403215077707000022125 0ustar alexalex# 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-24.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.10" - 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-24.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.10" - 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-6.2.0/.github/pull_request_template.md0000664000175000017500000000124315077707000020567 0ustar alexalex - [ ] 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-6.2.0/.github/FUNDING.yml0000664000175000017500000000041715077707000015445 0ustar alexalex# SPDX-FileCopyrightText: 2025 Free Software Foundation Europe e.V. # # SPDX-License-Identifier: CC0-1.0 # These are supported funding model platforms github: [fsfe] custom: ["https://my.fsfe.org/donate?referrer=https://github.com/fsfe/reuse-tool"] reuse-tool-6.2.0/REUSE.toml0000664000175000017500000000313615077707000014051 0ustar alexalex# SPDX-FileCopyrightText: 2023 Free Software Foundation Europe e.V. # # SPDX-License-Identifier: CC0-1.0 version = 1 [[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 = "override" SPDX-FileCopyrightText = "REUSE contributors" SPDX-License-Identifier = "GPL-3.0-or-later" [[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-6.2.0/LICENSES/0000775000175000017500000000000015077707000013473 5ustar alexalexreuse-tool-6.2.0/LICENSES/GPL-3.0-or-later.txt0000664000175000017500000010451515077707000016705 0ustar alexalex 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-6.2.0/LICENSES/CC0-1.0.txt0000664000175000017500000001561015077707000015100 0ustar alexalexCreative 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-6.2.0/LICENSES/CC-BY-SA-4.0.txt0000664000175000017500000004724315077707000015643 0ustar alexalexAttribution-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-6.2.0/LICENSES/Apache-2.0.txt0000664000175000017500000002613615077707000015722 0ustar alexalex 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-6.2.0/po/0000775000175000017500000000000015077707000012704 5ustar alexalexreuse-tool-6.2.0/po/sq.po0000664000175000017500000010230115077707000013664 0ustar alexalex# 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: 2025-10-07 21:23+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" "Language: sq\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" #: src/reuse/lint.py:40 msgid "BAD LICENSES" msgstr "" #: src/reuse/lint.py:42 msgid "The following licenses are not valid SPDX licenses:" msgstr "" #: src/reuse/lint.py:50 msgid "DEPRECATED LICENSES" msgstr "" #: src/reuse/lint.py:52 msgid "The following licenses are deprecated by SPDX:" msgstr "" #: src/reuse/lint.py:60 msgid "LICENSES WITHOUT FILE EXTENSION" msgstr "" #: src/reuse/lint.py:62 msgid "The following licenses have no file extension:" msgstr "" #: src/reuse/lint.py:70 msgid "MISSING LICENSES" msgstr "" #: src/reuse/lint.py:72 msgid "'{}' found in:" msgstr "" #: src/reuse/lint.py:79 msgid "UNUSED LICENSES" msgstr "" #: src/reuse/lint.py:80 msgid "The following licenses are not used:" msgstr "" #: src/reuse/lint.py:87 msgid "READ ERRORS" msgstr "" #: src/reuse/lint.py:88 msgid "Could not read:" msgstr "" #: src/reuse/lint.py:94 msgid "INVALID SPDX LICENSE EXPRESSIONS" msgstr "" #: src/reuse/lint.py:99 msgid "'{}' contains invalid SPDX License Expressions:" msgstr "" #: src/reuse/lint.py:124 msgid "MISSING COPYRIGHT AND LICENSING INFORMATION" msgstr "" #: src/reuse/lint.py:130 msgid "The following files have no copyright and licensing information:" msgstr "" #: src/reuse/lint.py:141 msgid "The following files have no copyright information:" msgstr "" #: src/reuse/lint.py:150 msgid "The following files have no licensing information:" msgstr "" #: src/reuse/lint.py:157 msgid "SUMMARY" msgstr "" #: src/reuse/lint.py:162 msgid "Bad licenses:" msgstr "" #: src/reuse/lint.py:163 msgid "Deprecated licenses:" msgstr "" #: src/reuse/lint.py:166 msgid "Licenses without file extension:" msgstr "" #: src/reuse/lint.py:169 msgid "Missing licenses:" msgstr "" #: src/reuse/lint.py:170 msgid "Unused licenses:" msgstr "" #: src/reuse/lint.py:171 msgid "Used licenses:" msgstr "" #: src/reuse/lint.py:172 msgid "Read errors:" msgstr "" #: src/reuse/lint.py:173 msgid "Invalid SPDX License Expressions:" msgstr "" #: src/reuse/lint.py:183 msgid "Files with copyright information:" msgstr "" #: src/reuse/lint.py:187 msgid "Files with license information:" msgstr "" #: src/reuse/lint.py:204 msgid "" "Congratulations! Your project is compliant with version {} of the REUSE " "Specification :-)" msgstr "" #: src/reuse/lint.py:211 msgid "" "Unfortunately, your project is not compliant with version {} of the REUSE " "Specification :-(" msgstr "" #: src/reuse/lint.py:218 msgid "RECOMMENDATIONS" msgstr "" #: src/reuse/lint.py:286 #, python-brace-format msgid "missing license '{lic}'" msgstr "" #: src/reuse/lint.py:291 msgid "read error" msgstr "" #: src/reuse/lint.py:296 #, python-brace-format msgid "invalid SPDX License Expression '{expression}'" msgstr "" #: src/reuse/lint.py:303 msgid "no license identifier" msgstr "" #: src/reuse/lint.py:307 msgid "no copyright notice" msgstr "" #: src/reuse/lint.py:345 #, python-brace-format msgid "bad license '{lic}'" msgstr "" #: src/reuse/lint.py:350 msgid "deprecated license" msgstr "" #: src/reuse/lint.py:355 msgid "license without file extension" msgstr "" #: src/reuse/lint.py:360 msgid "unused license" msgstr "" #: src/reuse/project.py:253 #, python-brace-format msgid "'{path}' covered by {global_path}" msgstr "" #: src/reuse/project.py:261 #, python-brace-format msgid "" "'{path}' is covered exclusively by REUSE.toml. Not reading the file contents." 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:355 #, 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:419 #, python-brace-format msgid "{path} does not have a file extension" msgstr "" #: src/reuse/project.py:429 #, 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:441 #, python-brace-format msgid "" "{identifier} is the SPDX License Identifier of both {path} and {other_path}" msgstr "" #: src/reuse/project.py:480 msgid "" "project '{}' is not a VCS repository or required VCS software is not " "installed" msgstr "" #: src/reuse/extract.py:49 #, python-brace-format msgid "" "REUSE_ENCODING_MODULE must have a value in {modules}; it has '{env_module}'. " "Aborting." msgstr "" #: src/reuse/extract.py:69 msgid "" "No supported module that can detect the encoding of files could be " "successfully imported. Re-read the installation instructions for the reuse " "package, or try the following:" msgstr "" #: src/reuse/extract.py:75 msgid "" "- If you are running a Linux distribution, try your equivalent of `apt " "install file` or `dnf install file`." msgstr "" #: src/reuse/extract.py:80 msgid "" "- Run ` pipx install reuse[charset-normalizer]`. Replace 'pipx' with 'pip' " "if you are not using pipx." msgstr "" #: src/reuse/extract.py:451 #, python-brace-format msgid "" "'{path}' was detected as a binary file; not searching its contents for REUSE " "information." msgstr "" #: src/reuse/extract.py:462 #, python-brace-format msgid "" "extracting REUSE information from '{path}' (encoding {encoding}, encoding " "module {module}, newline {newline})" msgstr "" #: src/reuse/header.py:87 msgid "generated comment is missing copyright lines or license expressions" msgstr "" #: src/reuse/report.py:160 #, python-brace-format msgid "Could not read '{path}'" msgstr "" #: src/reuse/report.py:165 #, python-brace-format msgid "Unexpected error occurred while parsing '{path}'" msgstr "" #: src/reuse/report.py:521 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:532 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:543 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:552 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:564 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:575 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:584 msgid "" "Fix invalid SPDX License Expressions: In one or more files there are SPDX " "License Expressions which cannot be parse. Check whether the value that " "follows 'SPDX-License-Identifier:' is correct. If the detected expression is " "not meant to be valid, put it between 'REUSE-IgnoreStart' and 'REUSE-" "IgnoreEnd' comments." msgstr "" #: src/reuse/report.py:595 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/cli/lint.py:28 #, python-brace-format msgid "" "Lint the project directory for REUSE compliance. This version of the tool " "checks against version {reuse_version} of the REUSE Specification. You can " "find the latest version of the specification at ." msgstr "" #: src/reuse/cli/lint.py:34 msgid "Specifically, the following criteria are checked:" msgstr "" #: src/reuse/cli/lint.py:38 msgid "" "- Are there any bad (unrecognised, not compliant with SPDX) licenses in the " "project?" msgstr "" #: src/reuse/cli/lint.py:43 msgid "- Are there any deprecated licenses in the project?" msgstr "" #: src/reuse/cli/lint.py:47 msgid "" "- Are there any license files in the LICENSES/ directory without file " "extension?" msgstr "" #: src/reuse/cli/lint.py:54 msgid "" "- Are any licenses referred to inside of the project, but not included in " "the LICENSES/ directory?" msgstr "" #: src/reuse/cli/lint.py:61 msgid "" "- Are any licenses included in the LICENSES/ directory that are not used " "inside of the project?" msgstr "" #: src/reuse/cli/lint.py:66 msgid "- Are there any read errors?" msgstr "" #: src/reuse/cli/lint.py:69 msgid "- Do all files have valid copyright and licensing information?" msgstr "" #: src/reuse/cli/lint.py:81 src/reuse/cli/lint_file.py:38 msgid "Prevent output." msgstr "" #: src/reuse/cli/lint.py:89 src/reuse/cli/supported_licenses.py:28 msgid "Format output as JSON." msgstr "" #: src/reuse/cli/lint.py:97 msgid "Format output as plain text. (default)" msgstr "" #: src/reuse/cli/lint.py:105 msgid "Format output as errors per line." msgstr "" #: src/reuse/cli/convert_dep5.py:19 msgid "" "Convert .reuse/dep5 into a REUSE.toml file. The generated file is placed in " "the project root and is semantically identical. The .reuse/dep5 file is " "subsequently deleted." msgstr "" #: src/reuse/cli/convert_dep5.py:31 msgid "No '.reuse/dep5' file." msgstr "" #: src/reuse/cli/lint_file.py:25 msgid "" "Lint individual files for REUSE compliance. The specified FILEs are checked " "for the presence of copyright and licensing information, and whether the " "found licenses are included in the LICENSES/ directory." msgstr "" #: src/reuse/cli/lint_file.py:46 msgid "Format output as errors per line. (default)" msgstr "" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/lint_file.py:51 msgid "FILE" msgstr "" #: src/reuse/cli/lint_file.py:65 #, python-brace-format msgid "'{file}' is not inside of '{root}'." msgstr "" #: src/reuse/cli/spdx.py:22 msgid "Generate an SPDX bill of materials." msgstr "" #: src/reuse/cli/spdx.py:32 msgid "File to write to." msgstr "" #: src/reuse/cli/spdx.py:38 msgid "" "Populate the LicenseConcluded field; note that reuse cannot guarantee that " "the field is accurate." msgstr "" #: src/reuse/cli/spdx.py:50 msgid "Name of the person signing off on the SPDX report." msgstr "" #: src/reuse/cli/spdx.py:54 msgid "Name of the organization signing off on the SPDX report." msgstr "" #: src/reuse/cli/spdx.py:81 msgid "" "'--creator-person' or '--creator-organization' is required when '--add-" "license-concluded' is provided." msgstr "" #: src/reuse/cli/spdx.py:96 #, 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 "" #: src/reuse/cli/main.py:36 #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/decorators.py:465 #, python-format msgid "%(prog)s, version %(version)s" msgstr "" #: src/reuse/cli/main.py:39 msgid "" "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." msgstr "" #: src/reuse/cli/main.py:46 msgid "" "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." msgstr "" #: src/reuse/cli/main.py:53 msgid "" "You should have received a copy of the GNU General Public License along with " "this program. If not, see ." msgstr "" #: src/reuse/cli/main.py:61 msgid "" "reuse is a tool for compliance with the REUSE recommendations. See for more information, and " "for the online documentation." msgstr "" #: src/reuse/cli/main.py:68 msgid "" "This version of reuse is compatible with version {} of the REUSE " "Specification." msgstr "" #: src/reuse/cli/main.py:72 msgid "Support the FSFE's work:" msgstr "" #: src/reuse/cli/main.py:77 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/cli/main.py:88 msgid "Enable debug statements." msgstr "" #: src/reuse/cli/main.py:93 msgid "Hide deprecation warnings." msgstr "" #: src/reuse/cli/main.py:98 msgid "Do not skip over Git submodules." msgstr "" #: src/reuse/cli/main.py:103 msgid "Do not skip over Meson subprojects." msgstr "" #: src/reuse/cli/main.py:108 msgid "Do not use multiprocessing." msgstr "" #: src/reuse/cli/main.py:118 msgid "Define root of project." msgstr "" #: src/reuse/cli/common.py:51 #, python-brace-format msgid "" "'{path}' could not be parsed. We received the following error message: " "{message}" msgstr "" #: src/reuse/cli/common.py:87 #, python-brace-format msgid "'{name}' is mutually exclusive with: {opts}" msgstr "" #: src/reuse/cli/common.py:103 msgid "'{}' is not a valid SPDX expression." msgstr "" #: src/reuse/cli/download.py:54 msgid "'{}' is not a valid SPDX License Identifier." msgstr "" #: src/reuse/cli/download.py:61 msgid "Did you mean:" msgstr "" #: src/reuse/cli/download.py:68 msgid "" "See for a list of valid SPDX License " "Identifiers." msgstr "" #: src/reuse/cli/download.py:77 #, python-brace-format msgid "Error: {spdx_identifier} already exists." msgstr "" #: src/reuse/cli/download.py:84 #, python-brace-format msgid "Error: {path} does not exist." msgstr "" #: src/reuse/cli/download.py:88 msgid "Error: Failed to download license." msgstr "" #: src/reuse/cli/download.py:93 msgid "Is your internet connection working?" msgstr "" #: src/reuse/cli/download.py:98 #, python-brace-format msgid "Successfully downloaded {spdx_identifier}." msgstr "" #: src/reuse/cli/download.py:108 msgid "Download a license and place it in the LICENSES/ directory." msgstr "" #: src/reuse/cli/download.py:111 msgid "" "LICENSE must be a valid SPDX License Identifier. You may specify LICENSE " "multiple times to download multiple licenses." msgstr "" #: src/reuse/cli/download.py:124 msgid "Download all missing licenses detected in the project." msgstr "" #: src/reuse/cli/download.py:132 msgid "Path to download to." msgstr "" #: src/reuse/cli/download.py:138 msgid "" "Source from which to copy custom LicenseRef- licenses, either a directory " "that contains the file or the file itself." msgstr "" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/download.py:145 msgid "LICENSE" msgstr "" #: src/reuse/cli/download.py:161 msgid "The 'LICENSE' argument and '--all' option are mutually exclusive." msgstr "" #: src/reuse/cli/download.py:173 msgid "Cannot use '--output' with more than one license." msgstr "" #: src/reuse/cli/annotate.py:66 msgid "Option '--copyright', '--license', or '--contributor' is required." msgstr "" #: src/reuse/cli/annotate.py:127 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/cli/annotate.py:160 #, python-brace-format msgid "" "'{path}' does not support single-line comments, please do not use '--single-" "line'." msgstr "" #: src/reuse/cli/annotate.py:167 #, python-brace-format msgid "" "'{path}' does not support multi-line comments, please do not use '--multi-" "line'." msgstr "" #: src/reuse/cli/annotate.py:213 #, python-brace-format msgid "Template '{template}' could not be found." msgstr "" #: src/reuse/cli/annotate.py:236 #, python-brace-format msgid "'{year}' is not a valid year range." msgstr "" #: src/reuse/cli/annotate.py:245 #, python-brace-format msgid "" "Your operating system's year is set to '{year}'. This is not four digits, " "and not supported." msgstr "" #: src/reuse/cli/annotate.py:287 msgid "Add copyright and licensing into the headers of files." msgstr "" #: src/reuse/cli/annotate.py:290 msgid "" "By using --copyright and --license, you can specify which copyright holders " "and licenses to add to the headers of the given files." msgstr "" #: src/reuse/cli/annotate.py:296 msgid "" "By using --contributor, you can specify people or entity that contributed " "but are not copyright holder of the given files." msgstr "" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:309 msgid "COPYRIGHT" msgstr "" #: src/reuse/cli/annotate.py:312 msgid "Copyright holder, repeatable." msgstr "" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:319 msgid "SPDX_IDENTIFIER" msgstr "" #: src/reuse/cli/annotate.py:322 msgid "SPDX License Identifier, repeatable." msgstr "" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:328 msgid "CONTRIBUTOR" msgstr "" #: src/reuse/cli/annotate.py:331 msgid "File contributor, repeatable." msgstr "" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:338 msgid "YEAR" msgstr "" #: src/reuse/cli/annotate.py:343 msgid "" "Year of copyright notice. You may define multiple years or a range of years." msgstr "" #: src/reuse/cli/annotate.py:353 msgid "Comment style to use." msgstr "" #: src/reuse/cli/annotate.py:363 msgid "Copyright prefix to use." msgstr "" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:375 msgid "TEMPLATE" msgstr "" #: src/reuse/cli/annotate.py:377 msgid "Name of template to use." msgstr "" #: src/reuse/cli/annotate.py:384 msgid "Do not include year in copyright notice." msgstr "" #: src/reuse/cli/annotate.py:390 msgid "Merge copyright notices if they are identical except for their years." msgstr "" #: src/reuse/cli/annotate.py:398 msgid "Force single-line comment style." msgstr "" #: src/reuse/cli/annotate.py:405 msgid "Force multi-line comment style." msgstr "" #: src/reuse/cli/annotate.py:411 msgid "Add headers to all files under specified directories recursively." msgstr "" #: src/reuse/cli/annotate.py:416 msgid "Do not replace the first header in the file; just add a new one." msgstr "" #: src/reuse/cli/annotate.py:423 msgid "Always write a .license file instead of a header inside the file." msgstr "" #: src/reuse/cli/annotate.py:430 msgid "Write a .license file to files with unrecognised comment styles." msgstr "" #: src/reuse/cli/annotate.py:437 msgid "Skip files with unrecognised comment styles." msgstr "" #: src/reuse/cli/annotate.py:448 msgid "Skip files that already contain REUSE information." msgstr "" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:453 msgid "PATH" msgstr "" #: src/reuse/cli/annotate.py:510 #, python-brace-format msgid "'{path}' is a binary, therefore using '{new_path}' for the header" msgstr "" #: src/reuse/cli/supported_licenses.py:19 msgid "List all licenses on the SPDX License List." msgstr "" #: src/reuse/global_licensing.py:92 #, python-brace-format msgid "" "{attr_name} must be a {type_name} (got {value} that is a {value_class})." msgstr "" #: src/reuse/global_licensing.py:106 #, 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:118 #, python-brace-format msgid "{attr_name} must not be empty." msgstr "" #: src/reuse/global_licensing.py:142 #, python-brace-format msgid "{name} must be a {type} (got {value} that is a {value_type})." msgstr "" #: src/reuse/global_licensing.py:166 #, python-brace-format msgid "" "The value of 'precedence' must be one of {precedence_vals} (got {received})" msgstr "" #: src/reuse/global_licensing.py:219 #, python-brace-format msgid "Could not parse '{notice}'" msgstr "" #: src/reuse/_annotate.py:94 #, python-brace-format msgid "Skipped unrecognised file '{path}'" msgstr "" #: src/reuse/_annotate.py:100 #, python-brace-format msgid "'{path}' is not recognised; creating '{path}.license'" msgstr "" #: src/reuse/_annotate.py:116 #, python-brace-format msgid "Skipped file '{path}' already containing REUSE information" msgstr "" #: src/reuse/_annotate.py:145 #, python-brace-format msgid "Error: Could not create comment for '{path}'" msgstr "" #: src/reuse/_annotate.py:152 #, 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:163 #, python-brace-format msgid "Successfully changed header of {path}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:162 msgid "Repeat for confirmation" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:178 msgid "Error: The value you entered was invalid." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:180 #, python-brace-format msgid "Error: {e.message}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:191 msgid "Error: The two entered values do not match." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:247 msgid "Error: invalid input" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:866 msgid "Press any key to continue..." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:332 #, python-brace-format msgid "" "Choose from:\n" "\t{choices}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:369 msgid "{value!r} is not {choice}." msgid_plural "{value!r} is not one of {choices}." msgstr[0] "" msgstr[1] "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:460 msgid "{value!r} does not match the format {format}." msgid_plural "{value!r} does not match the formats {formats}." msgstr[0] "" msgstr[1] "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:482 msgid "{value!r} is not a valid {number_type}." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:538 #, python-brace-format msgid "{value} is not in the range {range}." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:719 msgid "{value!r} is not a valid boolean. Recognized values: {states}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:747 msgid "{value!r} is not a valid UUID." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:937 msgid "file" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:939 msgid "directory" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:941 msgid "path" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:988 msgid "{name} {filename!r} does not exist." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:997 msgid "{name} {filename!r} is a file." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:1005 msgid "{name} {filename!r} is a directory." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:1014 msgid "{name} {filename!r} is not readable." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:1023 msgid "{name} {filename!r} is not writable." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:1032 msgid "{name} {filename!r} is not executable." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:1099 #, python-brace-format msgid "{len_type} values are required, but {len_value} was given." msgid_plural "{len_type} values are required, but {len_value} were given." msgstr[0] "" msgstr[1] "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/shell_completion.py:332 msgid "Shell completion is not supported for Bash versions older than 4.4." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/shell_completion.py:339 msgid "Couldn't detect Bash version, shell completion is not supported." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:50 #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:89 #, python-brace-format msgid "Error: {message}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:81 #, python-brace-format msgid "Try '{command} {option}' for help." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:130 #, python-brace-format msgid "Invalid value: {message}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:132 #, python-brace-format msgid "Invalid value for {param_hint}: {message}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:190 msgid "Missing argument" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:192 msgid "Missing option" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:194 msgid "Missing parameter" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:196 #, python-brace-format msgid "Missing {param_type}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:203 #, python-brace-format msgid "Missing parameter: {param_name}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:223 #, python-brace-format msgid "No such option: {name}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:235 #, python-brace-format msgid "Did you mean {possibility}?" msgid_plural "(Possible options: {possibilities})" msgstr[0] "" msgstr[1] "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:282 msgid "unknown error" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:289 msgid "Could not open file {filename!r}: {message}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1104 #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1141 #, python-brace-format msgid "{text} {deprecated_message}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1160 msgid "Options" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1222 #, python-brace-format msgid "Got unexpected extra argument ({args})" msgid_plural "Got unexpected extra arguments ({args})" msgstr[0] "" msgstr[1] "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1241 msgid "DeprecationWarning: The command {name!r} is deprecated.{extra_message}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1425 msgid "Aborted!" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1799 msgid "Commands" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1830 msgid "Missing command." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1908 msgid "No such command {name!r}." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:2332 msgid "Value must be an iterable." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:2355 #, python-brace-format msgid "Takes {nargs} values but 1 was given." msgid_plural "Takes {nargs} values but {len} were given." msgstr[0] "" msgstr[1] "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:2505 msgid "" "DeprecationWarning: The {param_type} {name!r} is deprecated.{extra_message}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:2956 #, python-brace-format msgid "env var: {var}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:2959 #, python-brace-format msgid "default: {default}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:3023 msgid "(dynamic)" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/parser.py:199 msgid "Argument {name!r} takes {nargs} values." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/parser.py:381 msgid "Option {name!r} does not take a value." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/parser.py:444 msgid "Option {name!r} requires an argument." msgid_plural "Option {name!r} requires {nargs} arguments." msgstr[0] "" msgstr[1] "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/_termui_impl.py:608 #, python-brace-format msgid "{editor}: Editing failed" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/_termui_impl.py:612 #, python-brace-format msgid "{editor}: Editing failed: {e}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/decorators.py:522 msgid "Show the version and exit." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/decorators.py:548 msgid "Show this message and exit." msgstr "" reuse-tool-6.2.0/po/pt.po0000664000175000017500000014674015077707000013703 0ustar alexalex# 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: 2025-10-07 21:23+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/lint.py:40 #, fuzzy msgid "BAD LICENSES" msgstr "LICENÇAS NÃO USADAS" #: src/reuse/lint.py:42 #, fuzzy msgid "The following licenses are not valid SPDX licenses:" msgstr "As seguintes licenças não estão a ser usadas:" #: src/reuse/lint.py:50 msgid "DEPRECATED LICENSES" msgstr "LICENÇAS DESCONTINUADAS" #: src/reuse/lint.py:52 msgid "The following licenses are deprecated by SPDX:" msgstr "As seguintes licenças foram descontinuadas pelo SPDX:" #: src/reuse/lint.py:60 msgid "LICENSES WITHOUT FILE EXTENSION" msgstr "LICENÇAS SEM EXTENSÃO DE FICHEIRO" #: src/reuse/lint.py:62 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:70 msgid "MISSING LICENSES" msgstr "LICENÇAS EM FALTA" #: src/reuse/lint.py:72 msgid "'{}' found in:" msgstr "'{}' encontrado em:" #: src/reuse/lint.py:79 msgid "UNUSED LICENSES" msgstr "LICENÇAS NÃO USADAS" #: src/reuse/lint.py:80 msgid "The following licenses are not used:" msgstr "As seguintes licenças não estão a ser usadas:" #: src/reuse/lint.py:87 msgid "READ ERRORS" msgstr "ERROS DE LEITURA" #: src/reuse/lint.py:88 msgid "Could not read:" msgstr "Não foi possível ler:" #: src/reuse/lint.py:94 msgid "INVALID SPDX LICENSE EXPRESSIONS" msgstr "" #: src/reuse/lint.py:99 #, fuzzy msgid "'{}' contains invalid SPDX License Expressions:" msgstr "'{}' não é uma expressão SPDX válida; a abortar" #: src/reuse/lint.py:124 msgid "MISSING COPYRIGHT AND LICENSING INFORMATION" msgstr "INFORMAÇÃO EM FALTA SOBRE DIREITOS DE AUTOR E LICENCIAMENTO" #: src/reuse/lint.py:130 #, fuzzy msgid "The following files have no copyright and licensing information:" msgstr "Os seguintes ficheiros não contêm informação de direitos de autor:" #: src/reuse/lint.py:141 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:150 msgid "The following files have no licensing information:" msgstr "Os seguintes ficheiros não contêm informação de licenciamento:" #: src/reuse/lint.py:157 msgid "SUMMARY" msgstr "RESUMO" #: src/reuse/lint.py:162 msgid "Bad licenses:" msgstr "Licenças irregulares:" #: src/reuse/lint.py:163 msgid "Deprecated licenses:" msgstr "Licenças descontinuadas:" #: src/reuse/lint.py:166 msgid "Licenses without file extension:" msgstr "Licenças sem extensão de ficheiro:" #: src/reuse/lint.py:169 msgid "Missing licenses:" msgstr "Licenças em falta:" #: src/reuse/lint.py:170 msgid "Unused licenses:" msgstr "Licenças não usadas:" #: src/reuse/lint.py:171 msgid "Used licenses:" msgstr "Licenças usadas:" #: src/reuse/lint.py:172 #, fuzzy msgid "Read errors:" msgstr "Erros de leitura: {count}" #: src/reuse/lint.py:173 #, fuzzy msgid "Invalid SPDX License Expressions:" msgstr "'{}' não é uma expressão SPDX válida; a abortar" #: src/reuse/lint.py:183 #, fuzzy msgid "Files with copyright information:" msgstr "Ficheiros com informação de direitos de autor: {count} / {total}" #: src/reuse/lint.py:187 #, fuzzy msgid "Files with license information:" msgstr "Ficheiros com informação de licenciamento: {count} / {total}" #: src/reuse/lint.py:204 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:211 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:218 msgid "RECOMMENDATIONS" msgstr "" #: src/reuse/lint.py:286 #, fuzzy, python-brace-format msgid "missing license '{lic}'" msgstr "'{}' não é um Identificador de Licença SPDX válido." #: src/reuse/lint.py:291 #, fuzzy msgid "read error" msgstr "Erros de leitura: {count}" #: src/reuse/lint.py:296 #, fuzzy, python-brace-format msgid "invalid SPDX License Expression '{expression}'" msgstr "'{}' não é uma expressão SPDX válida; a abortar" #: src/reuse/lint.py:303 #, fuzzy msgid "no license identifier" msgstr "'{}' não é um Identificador de Licença SPDX válido." #: src/reuse/lint.py:307 #, fuzzy msgid "no copyright notice" msgstr "'{}' não é um Identificador de Licença SPDX válido." #: src/reuse/lint.py:345 #, fuzzy, python-brace-format msgid "bad license '{lic}'" msgstr "Licenças não usadas:" #: src/reuse/lint.py:350 #, fuzzy msgid "deprecated license" msgstr "Licenças descontinuadas:" #: src/reuse/lint.py:355 #, fuzzy msgid "license without file extension" msgstr "Licenças sem extensão de ficheiro:" #: src/reuse/lint.py:360 #, fuzzy msgid "unused license" msgstr "Licenças não usadas:" #: src/reuse/project.py:253 #, fuzzy, python-brace-format msgid "'{path}' covered by {global_path}" msgstr "'{path}' abrangido por .reuse/dep5" #: src/reuse/project.py:261 #, python-brace-format msgid "" "'{path}' is covered exclusively by REUSE.toml. Not reading the file contents." 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:355 #, 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:419 #, python-brace-format msgid "{path} does not have a file extension" msgstr "{path} não tem extensão de ficheiro" #: src/reuse/project.py:429 #, 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:441 #, 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:480 msgid "" "project '{}' is not a VCS repository or required VCS software is not " "installed" msgstr "" #: src/reuse/extract.py:49 #, python-brace-format msgid "" "REUSE_ENCODING_MODULE must have a value in {modules}; it has '{env_module}'. " "Aborting." msgstr "" #: src/reuse/extract.py:69 msgid "" "No supported module that can detect the encoding of files could be " "successfully imported. Re-read the installation instructions for the reuse " "package, or try the following:" msgstr "" #: src/reuse/extract.py:75 msgid "" "- If you are running a Linux distribution, try your equivalent of `apt " "install file` or `dnf install file`." msgstr "" #: src/reuse/extract.py:80 msgid "" "- Run ` pipx install reuse[charset-normalizer]`. Replace 'pipx' with 'pip' " "if you are not using pipx." msgstr "" #: src/reuse/extract.py:451 #, python-brace-format msgid "" "'{path}' was detected as a binary file; not searching its contents for REUSE " "information." msgstr "" #: src/reuse/extract.py:462 #, python-brace-format msgid "" "extracting REUSE information from '{path}' (encoding {encoding}, encoding " "module {module}, newline {newline})" msgstr "" #: src/reuse/header.py:87 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/report.py:160 #, python-brace-format msgid "Could not read '{path}'" msgstr "Não foi possível ler '{path}'" #: src/reuse/report.py:165 #, python-brace-format msgid "Unexpected error occurred while parsing '{path}'" msgstr "Ocorreu um erro inesperado ao analisar (parse) '{path}'" #: src/reuse/report.py:521 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:532 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:543 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:552 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:564 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:575 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:584 msgid "" "Fix invalid SPDX License Expressions: In one or more files there are SPDX " "License Expressions which cannot be parse. Check whether the value that " "follows 'SPDX-License-Identifier:' is correct. If the detected expression is " "not meant to be valid, put it between 'REUSE-IgnoreStart' and 'REUSE-" "IgnoreEnd' comments." msgstr "" #: src/reuse/report.py:595 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/cli/lint.py:28 #, python-brace-format msgid "" "Lint the project directory for REUSE compliance. This version of the tool " "checks against version {reuse_version} of the REUSE Specification. You can " "find the latest version of the specification at ." msgstr "" #: src/reuse/cli/lint.py:34 msgid "Specifically, the following criteria are checked:" msgstr "" #: src/reuse/cli/lint.py:38 msgid "" "- Are there any bad (unrecognised, not compliant with SPDX) licenses in the " "project?" msgstr "" #: src/reuse/cli/lint.py:43 #, fuzzy msgid "- Are there any deprecated licenses in the project?" msgstr "Qual é o endereço do projecto na internet?" #: src/reuse/cli/lint.py:47 msgid "" "- Are there any license files in the LICENSES/ directory without file " "extension?" msgstr "" #: src/reuse/cli/lint.py:54 msgid "" "- Are any licenses referred to inside of the project, but not included in " "the LICENSES/ directory?" msgstr "" #: src/reuse/cli/lint.py:61 msgid "" "- Are any licenses included in the LICENSES/ directory that are not used " "inside of the project?" msgstr "" #: src/reuse/cli/lint.py:66 msgid "- Are there any read errors?" msgstr "" #: src/reuse/cli/lint.py:69 #, fuzzy msgid "- Do all files have valid copyright and licensing information?" msgstr "" "Os seguintes ficheiros não contêm informação de direitos de autor nem de " "licenciamento:" #: src/reuse/cli/lint.py:81 src/reuse/cli/lint_file.py:38 msgid "Prevent output." msgstr "" #: src/reuse/cli/lint.py:89 src/reuse/cli/supported_licenses.py:28 msgid "Format output as JSON." msgstr "" #: src/reuse/cli/lint.py:97 msgid "Format output as plain text. (default)" msgstr "" #: src/reuse/cli/lint.py:105 msgid "Format output as errors per line." msgstr "" #: src/reuse/cli/convert_dep5.py:19 msgid "" "Convert .reuse/dep5 into a REUSE.toml file. The generated file is placed in " "the project root and is semantically identical. The .reuse/dep5 file is " "subsequently deleted." msgstr "" #: src/reuse/cli/convert_dep5.py:31 #, fuzzy msgid "No '.reuse/dep5' file." msgstr "A criar .reuse/dep5" #: src/reuse/cli/lint_file.py:25 msgid "" "Lint individual files for REUSE compliance. The specified FILEs are checked " "for the presence of copyright and licensing information, and whether the " "found licenses are included in the LICENSES/ directory." msgstr "" #: src/reuse/cli/lint_file.py:46 msgid "Format output as errors per line. (default)" msgstr "" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/lint_file.py:51 msgid "FILE" msgstr "" #: src/reuse/cli/lint_file.py:65 #, python-brace-format msgid "'{file}' is not inside of '{root}'." msgstr "" #: src/reuse/cli/spdx.py:22 #, fuzzy msgid "Generate an SPDX bill of materials." msgstr "imprimir a lista de materiais do projecto em formato SPDX" #: src/reuse/cli/spdx.py:32 msgid "File to write to." msgstr "" #: src/reuse/cli/spdx.py:38 msgid "" "Populate the LicenseConcluded field; note that reuse cannot guarantee that " "the field is accurate." msgstr "" #: src/reuse/cli/spdx.py:50 msgid "Name of the person signing off on the SPDX report." msgstr "" #: src/reuse/cli/spdx.py:54 msgid "Name of the organization signing off on the SPDX report." msgstr "" #: src/reuse/cli/spdx.py:81 msgid "" "'--creator-person' or '--creator-organization' is required when '--add-" "license-concluded' is provided." msgstr "" #: src/reuse/cli/spdx.py:96 #, 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 "" #: src/reuse/cli/main.py:36 #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/decorators.py:465 #, fuzzy, python-format msgid "%(prog)s, version %(version)s" msgstr "%(prog)s: erro: %(message)s\n" #: src/reuse/cli/main.py:39 msgid "" "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." msgstr "" #: src/reuse/cli/main.py:46 msgid "" "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." msgstr "" #: src/reuse/cli/main.py:53 msgid "" "You should have received a copy of the GNU General Public License along with " "this program. If not, see ." msgstr "" #: src/reuse/cli/main.py:61 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/cli/main.py:68 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/cli/main.py:72 msgid "Support the FSFE's work:" msgstr "Apoiar o trabalho da FSFE:" #: src/reuse/cli/main.py:77 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/cli/main.py:88 #, fuzzy msgid "Enable debug statements." msgstr "activar expressões de depuração" #: src/reuse/cli/main.py:93 msgid "Hide deprecation warnings." msgstr "" #: src/reuse/cli/main.py:98 #, fuzzy msgid "Do not skip over Git submodules." msgstr "não ignorar sub-módulos do Git" #: src/reuse/cli/main.py:103 #, fuzzy msgid "Do not skip over Meson subprojects." msgstr "não ignorar sub-módulos do Git" #: src/reuse/cli/main.py:108 #, fuzzy msgid "Do not use multiprocessing." msgstr "não usar multi-processamento" #: src/reuse/cli/main.py:118 #, fuzzy msgid "Define root of project." msgstr "definir a raíz do projecto" #: src/reuse/cli/common.py:51 #, python-brace-format msgid "" "'{path}' could not be parsed. We received the following error message: " "{message}" msgstr "" #: src/reuse/cli/common.py:87 #, python-brace-format msgid "'{name}' is mutually exclusive with: {opts}" msgstr "" #: src/reuse/cli/common.py:103 #, fuzzy msgid "'{}' is not a valid SPDX expression." msgstr "'{}' não é uma expressão SPDX válida; a abortar" #: src/reuse/cli/download.py:54 msgid "'{}' is not a valid SPDX License Identifier." msgstr "'{}' não é um Identificador de Licença SPDX válido." #: src/reuse/cli/download.py:61 msgid "Did you mean:" msgstr "" #: src/reuse/cli/download.py:68 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/cli/download.py:77 #, python-brace-format msgid "Error: {spdx_identifier} already exists." msgstr "Erro: {spdx_identifier} já existe." #: src/reuse/cli/download.py:84 #, fuzzy, python-brace-format msgid "Error: {path} does not exist." msgstr "'{path}' não termina em .spdx" #: src/reuse/cli/download.py:88 msgid "Error: Failed to download license." msgstr "Erro: Falha ao descarregar a licença." #: src/reuse/cli/download.py:93 msgid "Is your internet connection working?" msgstr "A ligação à Internet está a funcionar?" #: src/reuse/cli/download.py:98 #, python-brace-format msgid "Successfully downloaded {spdx_identifier}." msgstr "{spdx_identifier} transferido com êxito." #: src/reuse/cli/download.py:108 #, 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/cli/download.py:111 msgid "" "LICENSE must be a valid SPDX License Identifier. You may specify LICENSE " "multiple times to download multiple licenses." msgstr "" #: src/reuse/cli/download.py:124 #, fuzzy msgid "Download all missing licenses detected in the project." msgstr "descarregar todas as licenças detectadas como em falta no projecto" #: src/reuse/cli/download.py:132 msgid "Path to download to." msgstr "" #: src/reuse/cli/download.py:138 msgid "" "Source from which to copy custom LicenseRef- licenses, either a directory " "that contains the file or the file itself." msgstr "" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/download.py:145 #, fuzzy msgid "LICENSE" msgstr "LICENÇAS IRREGULARES" #: src/reuse/cli/download.py:161 #, fuzzy msgid "The 'LICENSE' argument and '--all' option are mutually exclusive." msgstr "as opções --exclude-year e --year são mutuamente exclusivas" #: src/reuse/cli/download.py:173 #, fuzzy 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/cli/annotate.py:66 #, fuzzy msgid "Option '--copyright', '--license', or '--contributor' is required." msgstr "é requerida uma das opções --copyright ou --license" #: src/reuse/cli/annotate.py:127 #, 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/cli/annotate.py:160 #, python-brace-format msgid "" "'{path}' does not support single-line comments, please do not use '--single-" "line'." msgstr "" #: src/reuse/cli/annotate.py:167 #, python-brace-format msgid "" "'{path}' does not support multi-line comments, please do not use '--multi-" "line'." msgstr "" #: src/reuse/cli/annotate.py:213 #, fuzzy, python-brace-format msgid "Template '{template}' could not be found." msgstr "o modelo {template} não foi encontrado" #: src/reuse/cli/annotate.py:236 #, fuzzy, python-brace-format msgid "'{year}' is not a valid year range." msgstr "'{}' não é uma expressão SPDX válida; a abortar" #: src/reuse/cli/annotate.py:245 #, python-brace-format msgid "" "Your operating system's year is set to '{year}'. This is not four digits, " "and not supported." msgstr "" #: src/reuse/cli/annotate.py:287 #, fuzzy msgid "Add copyright and licensing into the headers of files." msgstr "adicionar direitos de autor e licenciamento ao cabeçalho dos ficheiros" #: src/reuse/cli/annotate.py:290 msgid "" "By using --copyright and --license, you can specify which copyright holders " "and licenses to add to the headers of the given files." msgstr "" #: src/reuse/cli/annotate.py:296 msgid "" "By using --contributor, you can specify people or entity that contributed " "but are not copyright holder of the given files." msgstr "" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:309 msgid "COPYRIGHT" msgstr "" #: src/reuse/cli/annotate.py:312 #, fuzzy msgid "Copyright holder, repeatable." msgstr "declaração de direitos de autor (repetível)" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:319 msgid "SPDX_IDENTIFIER" msgstr "" #: src/reuse/cli/annotate.py:322 #, fuzzy msgid "SPDX License Identifier, repeatable." msgstr "Identificador SPDX (repetível)" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:328 msgid "CONTRIBUTOR" msgstr "" #: src/reuse/cli/annotate.py:331 #, fuzzy msgid "File contributor, repeatable." msgstr "Identificador SPDX (repetível)" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:338 msgid "YEAR" msgstr "" #: src/reuse/cli/annotate.py:343 msgid "" "Year of copyright notice. You may define multiple years or a range of years." msgstr "" #: src/reuse/cli/annotate.py:353 #, fuzzy msgid "Comment style to use." msgstr "estilo de comentário a usar (opcional)" #: src/reuse/cli/annotate.py:363 #, fuzzy msgid "Copyright prefix to use." msgstr "estilo de comentário a usar (opcional)" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:375 msgid "TEMPLATE" msgstr "" #: src/reuse/cli/annotate.py:377 #, fuzzy msgid "Name of template to use." msgstr "nome do modelo a usar (opcional)" #: src/reuse/cli/annotate.py:384 #, fuzzy msgid "Do not include year in copyright notice." msgstr "não incluir o ano na declaração" #: src/reuse/cli/annotate.py:390 #, fuzzy msgid "Merge copyright notices if they are identical except for their years." msgstr "ano da declaração de direitos de autor (opcional)" #: src/reuse/cli/annotate.py:398 #, fuzzy msgid "Force single-line comment style." msgstr "estilo de comentário a usar (opcional)" #: src/reuse/cli/annotate.py:405 #, fuzzy msgid "Force multi-line comment style." msgstr "estilo de comentário a usar (opcional)" #: src/reuse/cli/annotate.py:411 msgid "Add headers to all files under specified directories recursively." msgstr "" #: src/reuse/cli/annotate.py:416 msgid "Do not replace the first header in the file; just add a new one." msgstr "" #: src/reuse/cli/annotate.py:423 msgid "Always write a .license file instead of a header inside the file." msgstr "" #: src/reuse/cli/annotate.py:430 msgid "Write a .license file to files with unrecognised comment styles." msgstr "" #: src/reuse/cli/annotate.py:437 msgid "Skip files with unrecognised comment styles." msgstr "" #: src/reuse/cli/annotate.py:448 #, fuzzy msgid "Skip files that already contain REUSE information." msgstr "Ficheiros com informação de licenciamento: {count} / {total}" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:453 msgid "PATH" msgstr "" #: src/reuse/cli/annotate.py:510 #, 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/cli/supported_licenses.py:19 msgid "List all licenses on the SPDX License List." msgstr "" #: src/reuse/global_licensing.py:92 #, python-brace-format msgid "" "{attr_name} must be a {type_name} (got {value} that is a {value_class})." msgstr "" #: src/reuse/global_licensing.py:106 #, 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:118 #, python-brace-format msgid "{attr_name} must not be empty." msgstr "" #: src/reuse/global_licensing.py:142 #, python-brace-format msgid "{name} must be a {type} (got {value} that is a {value_type})." msgstr "" #: src/reuse/global_licensing.py:166 #, python-brace-format msgid "" "The value of 'precedence' must be one of {precedence_vals} (got {received})" msgstr "" #: src/reuse/global_licensing.py:219 #, fuzzy, python-brace-format msgid "Could not parse '{notice}'" msgstr "Não foi possível executar parse '{expression}'" #: src/reuse/_annotate.py:94 #, python-brace-format msgid "Skipped unrecognised file '{path}'" msgstr "" #: src/reuse/_annotate.py:100 #, python-brace-format msgid "'{path}' is not recognised; creating '{path}.license'" msgstr "" #: src/reuse/_annotate.py:116 #, fuzzy, python-brace-format msgid "Skipped file '{path}' already containing REUSE information" msgstr "Ficheiros com informação de licenciamento: {count} / {total}" #: src/reuse/_annotate.py:145 #, 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:152 #, 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:163 #, python-brace-format msgid "Successfully changed header of {path}" msgstr "O cabeçalho de {path} foi alterado com êxito" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:162 msgid "Repeat for confirmation" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:178 msgid "Error: The value you entered was invalid." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:180 #, python-brace-format msgid "Error: {e.message}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:191 msgid "Error: The two entered values do not match." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:247 msgid "Error: invalid input" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:866 msgid "Press any key to continue..." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:332 #, python-brace-format msgid "" "Choose from:\n" "\t{choices}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:369 msgid "{value!r} is not {choice}." msgid_plural "{value!r} is not one of {choices}." msgstr[0] "" msgstr[1] "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:460 msgid "{value!r} does not match the format {format}." msgid_plural "{value!r} does not match the formats {formats}." msgstr[0] "" msgstr[1] "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:482 msgid "{value!r} is not a valid {number_type}." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:538 #, python-brace-format msgid "{value} is not in the range {range}." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:719 msgid "{value!r} is not a valid boolean. Recognized values: {states}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:747 msgid "{value!r} is not a valid UUID." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:937 msgid "file" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:939 msgid "directory" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:941 msgid "path" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:988 #, fuzzy msgid "{name} {filename!r} does not exist." msgstr "'{path}' não termina em .spdx" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:997 msgid "{name} {filename!r} is a file." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:1005 #, fuzzy msgid "{name} {filename!r} is a directory." msgstr "'{}' não é uma pasta" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:1014 msgid "{name} {filename!r} is not readable." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:1023 msgid "{name} {filename!r} is not writable." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:1032 msgid "{name} {filename!r} is not executable." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:1099 #, python-brace-format msgid "{len_type} values are required, but {len_value} was given." msgid_plural "{len_type} values are required, but {len_value} were given." msgstr[0] "" msgstr[1] "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/shell_completion.py:332 msgid "Shell completion is not supported for Bash versions older than 4.4." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/shell_completion.py:339 msgid "Couldn't detect Bash version, shell completion is not supported." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:50 #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:89 #, python-brace-format msgid "Error: {message}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:81 #, python-brace-format msgid "Try '{command} {option}' for help." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:130 #, python-brace-format msgid "Invalid value: {message}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:132 #, python-brace-format msgid "Invalid value for {param_hint}: {message}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:190 #, fuzzy msgid "Missing argument" msgstr "argumentos posicionais" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:192 #, fuzzy msgid "Missing option" msgstr "Licenças em falta:" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:194 msgid "Missing parameter" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:196 #, python-brace-format msgid "Missing {param_type}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:203 #, python-brace-format msgid "Missing parameter: {param_name}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:223 #, python-brace-format msgid "No such option: {name}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:235 #, python-brace-format msgid "Did you mean {possibility}?" msgid_plural "(Possible options: {possibilities})" msgstr[0] "" msgstr[1] "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:282 msgid "unknown error" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:289 msgid "Could not open file {filename!r}: {message}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1104 #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1141 #, python-brace-format msgid "{text} {deprecated_message}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1160 msgid "Options" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1222 #, fuzzy, python-brace-format msgid "Got unexpected extra argument ({args})" msgid_plural "Got unexpected extra arguments ({args})" msgstr[0] "é esperado um argumento" msgstr[1] "é esperado um argumento" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1241 msgid "DeprecationWarning: The command {name!r} is deprecated.{extra_message}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1425 msgid "Aborted!" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1799 #, fuzzy msgid "Commands" msgstr "sub-comandos" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1830 #, fuzzy msgid "Missing command." msgstr "Licenças em falta:" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1908 msgid "No such command {name!r}." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:2332 msgid "Value must be an iterable." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:2355 #, python-brace-format msgid "Takes {nargs} values but 1 was given." msgid_plural "Takes {nargs} values but {len} were given." msgstr[0] "" msgstr[1] "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:2505 msgid "" "DeprecationWarning: The {param_type} {name!r} is deprecated.{extra_message}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:2956 #, python-brace-format msgid "env var: {var}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:2959 #, python-brace-format msgid "default: {default}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:3023 msgid "(dynamic)" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/parser.py:199 msgid "Argument {name!r} takes {nargs} values." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/parser.py:381 msgid "Option {name!r} does not take a value." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/parser.py:444 msgid "Option {name!r} requires an argument." msgid_plural "Option {name!r} requires {nargs} arguments." msgstr[0] "" msgstr[1] "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/_termui_impl.py:608 #, python-brace-format msgid "{editor}: Editing failed" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/_termui_impl.py:612 #, python-brace-format msgid "{editor}: Editing failed: {e}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/decorators.py:522 #, fuzzy msgid "Show the version and exit." msgstr "mostrar esta mensagem de ajuda e sair" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/decorators.py:548 #, fuzzy msgid "Show this message and exit." msgstr "mostrar esta mensagem de ajuda e sair" #, fuzzy, python-brace-format #~ msgid "{path}: read error\n" #~ msgstr "Licenças descontinuadas:" #, fuzzy, python-brace-format #~ msgid "{lic_path}: deprecated license\n" #~ msgstr "Licenças descontinuadas:" #, fuzzy, python-brace-format #~ msgid "{lic_path}: license without file extension\n" #~ msgstr "Licenças sem extensão de ficheiro:" #, fuzzy, python-brace-format #~ msgid "{lic_path}: unused license\n" #~ msgstr "Licenças não usadas:" #, 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" #, python-brace-format #~ msgid "Could not parse '{expression}'" #~ msgstr "Não foi possível executar parse '{expression}'" #, fuzzy, python-brace-format #~ msgid "(Deprecated) {text}" #~ msgstr "Licenças descontinuadas:" #, fuzzy #~ msgid "Year of copyright statement." #~ msgstr "ano da declaração de direitos de autor (opcional)" #, python-brace-format #~ msgid "determining identifier of '{path}'" #~ msgstr "a determinar o identificador de '{path}'" #~ msgid "can't write to '{}'" #~ msgstr "não é possível escrever em '{}'" #~ msgid "show program's version number and exit" #~ msgstr "mostrar o número de versão do programa e sair" #~ msgid "download a license and place it in the LICENSES/ directory" #~ msgstr "descarregar uma licença e guardá-la na pasta LICENSES/" #~ msgid "list all non-compliant files" #~ msgstr "listar todos os ficheiros não conformes" #, fuzzy, 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 there any deprecated licenses in the project?\n" #~ "\n" #~ "- Are there any license files in the LICENSES/ directory without file " #~ "extension?\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" #~ "- Are there any read errors?\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?" #~ msgid "print the project's bill of materials in SPDX format" #~ msgstr "imprimir a lista de materiais do projecto em formato SPDX" #~ msgid "'{}' is not a file" #~ msgstr "'{}' não é um ficheiro" #~ msgid "can't open '{}'" #~ msgstr "não é possível abrir '{}'" #~ msgid "can't write to directory '{}'" #~ msgstr "não é possível escrever no directório '{}'" #~ msgid "can't read or write '{}'" #~ msgstr "não é possível ler ou escrever em '{}'" #~ msgid "SPDX License Identifier of license" #~ msgstr "Identificador de Licença SPDX da licença" #~ msgid "the following arguments are required: license" #~ msgstr "são requeridos os seguintes argumentos: licença" #~ msgid "usage: " #~ msgstr "uso: " #~ msgid ".__call__() not defined" #~ msgstr ".__call__() não definido" #, python-format #~ msgid "unknown parser %(parser_name)r (choices: %(choices)s)" #~ msgstr "analisador desconhecido %(parser_name)r (alternativas: %(choices)s)" #, python-format #~ msgid "argument \"-\" with mode %r" #~ msgstr "argumento \"-\" com modo %r" #, python-format #~ msgid "can't open '%(filename)s': %(error)s" #~ msgstr "não é possível abrir '%(filename)s': %(error)s" #, 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" #~ msgid "'required' is an invalid argument for positionals" #~ msgstr "'required' não é um argumento válido para posicionais" #, 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" #, python-format #~ msgid "dest= is required for options like %r" #~ msgstr "é requerido dest= para opções do tipo %r" #, python-format #~ msgid "invalid conflict_resolution value: %r" #~ msgstr "valor de conflict_resolution inválido: %r" #, 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" #~ msgid "mutually exclusive arguments must be optional" #~ msgstr "argumentos mutuamente exclusivos têm que ser opcionais" #~ msgid "cannot have multiple subparser arguments" #~ msgstr "não pode haver argumentos múltiplos de sub-análise (subparser)" #, python-format #~ msgid "unrecognized arguments: %s" #~ msgstr "argumentos não reconhecidos: %s" #, python-format #~ msgid "not allowed with argument %s" #~ msgstr "não permitido com o argumento %s" #, python-format #~ msgid "ignored explicit argument %r" #~ msgstr "argumento explícito %r ignorado" #, python-format #~ msgid "the following arguments are required: %s" #~ msgstr "são requeridos os seguintes argumentos: %s" #, python-format #~ msgid "one of the arguments %s is required" #~ msgstr "é requerido um dos argumentos %s" #~ msgid "expected at most one argument" #~ msgstr "é esperado um argumento, no máximo" #~ msgid "expected at least one argument" #~ msgstr "é esperado um argumento, no mínimo" #, python-format #~ msgid "expected %s argument" #~ msgid_plural "expected %s arguments" #~ msgstr[0] "é esperado %s argumento" #~ msgstr[1] "são esperados %s argumentos" #, python-format #~ msgid "ambiguous option: %(option)s could match %(matches)s" #~ msgstr "opção ambígua: %(option)s pode ser igual a %(matches)s" #, python-format #~ msgid "unexpected option string: %s" #~ msgstr "linha de opções não esperada: %s" #, python-format #~ msgid "%r is not callable" #~ msgstr "%r não é invocável" #, python-format #~ msgid "invalid %(type)s value: %(value)r" #~ msgstr "valor %(type)s inválido: %(value)r" #, python-format #~ msgid "invalid choice: %(value)r (choose from %(choices)s)" #~ msgstr "alternativa inválida: %(value)r (escolher de %(choices)s)" #~ 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 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" #~ 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-6.2.0/po/fr.po0000664000175000017500000020246115077707000013660 0ustar alexalex# 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: 2025-10-07 21:23+0000\n" "PO-Revision-Date: 2025-04-26 21:20+0000\n" "Last-Translator: Sébastien Helleu \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.12-dev\n" #: src/reuse/lint.py:40 #, fuzzy msgid "BAD LICENSES" msgstr "LICENCES INUTILISÉES" #: src/reuse/lint.py:42 #, fuzzy msgid "The following licenses are not valid SPDX licenses:" msgstr "Les licences suivantes ne sont pas utilisées :" #: src/reuse/lint.py:50 msgid "DEPRECATED LICENSES" msgstr "LICENCES OBSOLÈTES" #: src/reuse/lint.py:52 msgid "The following licenses are deprecated by SPDX:" msgstr "Les licences suivantes sont rendues obsolètes par SPDX :" #: src/reuse/lint.py:60 msgid "LICENSES WITHOUT FILE EXTENSION" msgstr "LICENCES SANS EXTENSION DE FICHIER" #: src/reuse/lint.py:62 msgid "The following licenses have no file extension:" msgstr "Les licences suivantes n'ont pas d'extension de fichier :" #: src/reuse/lint.py:70 msgid "MISSING LICENSES" msgstr "LICENCES MANQUANTES" #: src/reuse/lint.py:72 msgid "'{}' found in:" msgstr "'{}' trouvé dans :" #: src/reuse/lint.py:79 msgid "UNUSED LICENSES" msgstr "LICENCES INUTILISÉES" #: src/reuse/lint.py:80 msgid "The following licenses are not used:" msgstr "Les licences suivantes ne sont pas utilisées :" #: src/reuse/lint.py:87 msgid "READ ERRORS" msgstr "ERREURS DE LECTURE" #: src/reuse/lint.py:88 msgid "Could not read:" msgstr "Illisibles :" #: src/reuse/lint.py:94 msgid "INVALID SPDX LICENSE EXPRESSIONS" msgstr "" #: src/reuse/lint.py:99 #, fuzzy msgid "'{}' contains invalid SPDX License Expressions:" msgstr "'{}' n'est pas une expression SPDX valide." #: src/reuse/lint.py:124 msgid "MISSING COPYRIGHT AND LICENSING INFORMATION" msgstr "INFORMATION DE DROITS D'AUTEUR ET DE LICENCE MANQUANTE" #: src/reuse/lint.py:130 #, fuzzy msgid "The following files have no copyright and licensing information:" msgstr "" "Les fichiers suivants ne contiennent pas de données de droits d'auteur :" #: src/reuse/lint.py:141 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:150 msgid "The following files have no licensing information:" msgstr "Les fichiers suivants ne contiennent pas de données de licence :" #: src/reuse/lint.py:157 msgid "SUMMARY" msgstr "RÉSUMÉ" #: src/reuse/lint.py:162 msgid "Bad licenses:" msgstr "Mauvaises licences :" #: src/reuse/lint.py:163 msgid "Deprecated licenses:" msgstr "Licences obsolètes :" #: src/reuse/lint.py:166 msgid "Licenses without file extension:" msgstr "Licences sans extension de fichier :" #: src/reuse/lint.py:169 msgid "Missing licenses:" msgstr "Licences manquantes :" #: src/reuse/lint.py:170 msgid "Unused licenses:" msgstr "Licences inutilisées :" #: src/reuse/lint.py:171 msgid "Used licenses:" msgstr "Licences utilisées :" #: src/reuse/lint.py:172 msgid "Read errors:" msgstr "Erreurs de lecture :" #: src/reuse/lint.py:173 #, fuzzy msgid "Invalid SPDX License Expressions:" msgstr "'{}' n'est pas une expression SPDX valide." #: src/reuse/lint.py:183 #, fuzzy msgid "Files with copyright information:" msgstr "Fichiers contenant des droits d'auteur :" #: src/reuse/lint.py:187 #, fuzzy msgid "Files with license information:" msgstr "Fichiers contenant des licences :" #: src/reuse/lint.py:204 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:211 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:218 msgid "RECOMMENDATIONS" msgstr "RECOMMANDATIONS" #: src/reuse/lint.py:286 #, fuzzy, python-brace-format msgid "missing license '{lic}'" msgstr "{path} : la licence {lic} est manquante\n" #: src/reuse/lint.py:291 #, fuzzy msgid "read error" msgstr "Erreurs de lecture :" #: src/reuse/lint.py:296 #, fuzzy, python-brace-format msgid "invalid SPDX License Expression '{expression}'" msgstr "'{}' n'est pas une expression SPDX valide." #: src/reuse/lint.py:303 #, fuzzy msgid "no license identifier" msgstr "{path}  : pas d'identifiant de licence\n" #: src/reuse/lint.py:307 #, fuzzy msgid "no copyright notice" msgstr "{path} : pas de copyright\n" #: src/reuse/lint.py:345 #, fuzzy, python-brace-format msgid "bad license '{lic}'" msgstr "{path} : mauvaise licence {lic}\n" #: src/reuse/lint.py:350 #, fuzzy msgid "deprecated license" msgstr "Licences obsolètes :" #: src/reuse/lint.py:355 #, fuzzy msgid "license without file extension" msgstr "Licences sans extension de fichier :" #: src/reuse/lint.py:360 #, fuzzy msgid "unused license" msgstr "Licences inutilisées :" #: src/reuse/project.py:253 #, python-brace-format msgid "'{path}' covered by {global_path}" msgstr "'{path}' est couvert par {global_path}" #: src/reuse/project.py:261 #, fuzzy, python-brace-format msgid "" "'{path}' is covered exclusively by REUSE.toml. Not reading the file contents." msgstr "" "'{path}' est couvert en exclusivité par REUSE.toml. Contenu du fichier non " "lu." #: src/reuse/project.py:334 #, fuzzy msgid "" "'.reuse/dep5' is deprecated. You are recommended to instead use REUSE.toml. " "Use `reuse convert-dep5` to convert." msgstr "" "'.reuse/dep5' est déprécié. L'utilisation de REUSE.toml est recommandée. " "Utilisez `reuse convert-dep5` pour convertir." #: src/reuse/project.py:355 #, fuzzy, python-brace-format msgid "" "Found both '{new_path}' and '{old_path}'. You cannot keep both files " "simultaneously; they are not intercompatible." msgstr "" "'{new_path}' et '{old_path}' ont tous les deux été trouvés. Vous ne pouvez " "pas guarder les deux fichiers en même temps, ils ne sont pas inter-" "compatibles." #: src/reuse/project.py:419 #, python-brace-format msgid "{path} does not have a file extension" msgstr "{path} n'a pas d'extension de fichier" #: src/reuse/project.py:429 #, 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:441 #, 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:480 #, fuzzy msgid "" "project '{}' is not a VCS repository or required VCS software is not " "installed" msgstr "" "le projet '{}' n'est pas un dépôt VCS ou le logiciel VCS requis n'est pas " "installé" #: src/reuse/extract.py:49 #, python-brace-format msgid "" "REUSE_ENCODING_MODULE must have a value in {modules}; it has '{env_module}'. " "Aborting." msgstr "" #: src/reuse/extract.py:69 msgid "" "No supported module that can detect the encoding of files could be " "successfully imported. Re-read the installation instructions for the reuse " "package, or try the following:" msgstr "" #: src/reuse/extract.py:75 msgid "" "- If you are running a Linux distribution, try your equivalent of `apt " "install file` or `dnf install file`." msgstr "" #: src/reuse/extract.py:80 msgid "" "- Run ` pipx install reuse[charset-normalizer]`. Replace 'pipx' with 'pip' " "if you are not using pipx." msgstr "" #: src/reuse/extract.py:451 #, fuzzy, python-brace-format msgid "" "'{path}' was detected as a binary file; not searching its contents for REUSE " "information." msgstr "" "'{path}' a été détecté comme étant un fichier binaire, les informations " "REUSE n'y sont pas recherchées." #: src/reuse/extract.py:462 #, python-brace-format msgid "" "extracting REUSE information from '{path}' (encoding {encoding}, encoding " "module {module}, newline {newline})" msgstr "" #: src/reuse/header.py:87 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/report.py:160 #, python-brace-format msgid "Could not read '{path}'" msgstr "Lecture de '{path}' impossible" #: src/reuse/report.py:165 #, python-brace-format msgid "Unexpected error occurred while parsing '{path}'" msgstr "Erreur inattendue lors de l'analyse de '{path}'" #: src/reuse/report.py:521 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 "" "Corrigez les mauvaises licences : Au moins une licence du dossier LICENSES " "et/ou fournie par l'étiquette 'SPDX-License-Identifier' est invalide. Soit " "il ne s'agit pas d'identifiants de licence SPDX valides, soit ces " "identifiants personnalisés ne commencent pas par 'LicenseRef-'. FAQ à propos " "des licences personnalisées : https://reuse.software/faq/#custom-license" #: src/reuse/report.py:532 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 "" "Corrigez les licences dépréciées : Au moins une licence du dossier LICENSES " "et/ou fournie par une étiquette 'SPDX-License-Identifier' ou par '.reuse/" "dep5' a été dépréciée par SPDX. La liste des licences dépréciées ainsi que " "leur nouvel identifiant recommandé peut être trouvé ici : " #: src/reuse/report.py:543 #, fuzzy 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 "" "Corrigez les fichiers de licence sans extension : Au moins un fichier de " "licence dans le dossier 'LICENSES' n'a pas l'extension de fichier '.txt'. " "Veuillez renommes ce(s) fichier(s)." #: src/reuse/report.py:552 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 "" "Corriger les licences manquantes : Au moins une licence identifiée par une " "étiquette 'SPDX-License-Identifier' n'a pas son fichier texte associé dans " "le dossier 'LICENSES'. Pour les identifiants de licence SPDX, vous pouvez " "exécuter la commande 'reuse download --all' pour simplement récupérer les " "fichiers licence manquants. Pour les licences personnalisées (commençant par " "'LicenseRef-'), vous devez ajouter ces fichiers vous-même." #: src/reuse/report.py:564 #, fuzzy 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 "" "Corrigez les licences non trouvées : Au moins un fichier de licence dans le " "répertoire 'LICENSES' n'est référencé par aucun fichier, par ex. par une " "étiquette 'SPDX-License-Identifier'. Vérifiez que vous avez correctement " "étiqueté les fichiers concernés par ces licences, ou supprimez ces fichiers " "de licence inutiles si vous êtes sûr qu'aucun document n'est concerné par " "ces licences." #: src/reuse/report.py:575 #, fuzzy 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 "" "Corrigez les erreurs de lecture : Au moins un fichier dans votre dossier ne " "peut pas être lu par l'outil. Vérifiez ces permissions. Vous trouverez les " "fichiers concernés en tête de la sortie, avec les messages d'erreur." #: src/reuse/report.py:584 msgid "" "Fix invalid SPDX License Expressions: In one or more files there are SPDX " "License Expressions which cannot be parse. Check whether the value that " "follows 'SPDX-License-Identifier:' is correct. If the detected expression is " "not meant to be valid, put it between 'REUSE-IgnoreStart' and 'REUSE-" "IgnoreEnd' comments." msgstr "" #: src/reuse/report.py:595 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 "" "Corrigez les copyrights et licences manquantes : L'outil n'a pas pu trouver " "le copyright et/ou la licence d'au moins un fichier. Ils sont typiquement " "identifiés par les étiquettes 'SPDX-FileCopyrightText' et 'SPDX-License-" "Identifier' dans chaque fichier. Le tutoriel donne d'autres moyens de les " "ajouter : " #: src/reuse/cli/lint.py:28 #, python-brace-format msgid "" "Lint the project directory for REUSE compliance. This version of the tool " "checks against version {reuse_version} of the REUSE Specification. You can " "find the latest version of the specification at ." msgstr "" "Vérifier le répertoire du projet pour la conformité REUSE. Cette version de " "l'outil vérifie la spécification REUSE dans sa version {reuse_version}. Vous " "pouvez trouver la dernière version de la spécification ici : ." #: src/reuse/cli/lint.py:34 msgid "Specifically, the following criteria are checked:" msgstr "Plus précisément, les critères suivants sont vérifiés :" #: src/reuse/cli/lint.py:38 msgid "" "- Are there any bad (unrecognised, not compliant with SPDX) licenses in the " "project?" msgstr "" "- Y a-t-il des mauvaises licences (inconnues, non conformes aux licences " "SPDX) dans le projet ?" #: src/reuse/cli/lint.py:43 msgid "- Are there any deprecated licenses in the project?" msgstr "- Y a-t-il des licences dépréciées dans le projet ?" #: src/reuse/cli/lint.py:47 msgid "" "- Are there any license files in the LICENSES/ directory without file " "extension?" msgstr "" "- Y a-t-il des fichiers de licence dans le répertoire LICENSES/ sans " "extension de fichier ?" #: src/reuse/cli/lint.py:54 msgid "" "- Are any licenses referred to inside of the project, but not included in " "the LICENSES/ directory?" msgstr "" "- Est-ce que des licences sont référencées à l'intérieur du projet, mais non " "incluses dans le répertoire LICENSES/ ?" #: src/reuse/cli/lint.py:61 msgid "" "- Are any licenses included in the LICENSES/ directory that are not used " "inside of the project?" msgstr "" "- Est-ce que des licences incluses dans le répertoire LICENSES/ ne sont pas " "utilisées dans le projet ?" #: src/reuse/cli/lint.py:66 msgid "- Are there any read errors?" msgstr "- Y a-t-il des erreurs de lecture ?" #: src/reuse/cli/lint.py:69 msgid "- Do all files have valid copyright and licensing information?" msgstr "" "- Tous les fichiers ont-ils un droit d'auteur valide et des informations de " "licence ?" #: src/reuse/cli/lint.py:81 src/reuse/cli/lint_file.py:38 msgid "Prevent output." msgstr "Empêcher la sortie." #: src/reuse/cli/lint.py:89 src/reuse/cli/supported_licenses.py:28 msgid "Format output as JSON." msgstr "Appliquer le format JSON à la sortie." #: src/reuse/cli/lint.py:97 msgid "Format output as plain text. (default)" msgstr "Appliquer le format texte brut pour la sortie. (par défaut)" #: src/reuse/cli/lint.py:105 msgid "Format output as errors per line." msgstr "Générer une ligne par erreur." #: src/reuse/cli/convert_dep5.py:19 msgid "" "Convert .reuse/dep5 into a REUSE.toml file. The generated file is placed in " "the project root and is semantically identical. The .reuse/dep5 file is " "subsequently deleted." msgstr "" "Convertir .reuse/dep5 en fichier REUSE.toml. Le fichier généré est placé " "dans la racine du projet et est sémantiquement équivalent. Le fichier .reuse/" "dep5 est donc supprimé." #: src/reuse/cli/convert_dep5.py:31 msgid "No '.reuse/dep5' file." msgstr "Aucun fichier '.reuse/dep5'." #: src/reuse/cli/lint_file.py:25 msgid "" "Lint individual files for REUSE compliance. The specified FILEs are checked " "for the presence of copyright and licensing information, and whether the " "found licenses are included in the LICENSES/ directory." msgstr "" "Vérifier les fichiers individuels pour la conformité REUSE. La présence de " "droit d'auteur et de licence est recherchée dans les fichiers et les " "licences trouvées doivent être présentes dans le répertoire LICENSES/." #: src/reuse/cli/lint_file.py:46 msgid "Format output as errors per line. (default)" msgstr "Générer une ligne par erreur. (par défaut)" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/lint_file.py:51 msgid "FILE" msgstr "FICHIER" #: src/reuse/cli/lint_file.py:65 #, python-brace-format msgid "'{file}' is not inside of '{root}'." msgstr "'{file}' n'est pas à l'intérieur de '{root}'." #: src/reuse/cli/spdx.py:22 msgid "Generate an SPDX bill of materials." msgstr "Générer la nomenclature du projet au format SPDX." #: src/reuse/cli/spdx.py:32 msgid "File to write to." msgstr "Fichier dans lequel écrire." #: src/reuse/cli/spdx.py:38 msgid "" "Populate the LicenseConcluded field; note that reuse cannot guarantee that " "the field is accurate." msgstr "" "Compléter le champ LicenseConcluded ; notez que reuse ne garantit pas que le " "champ soit correct." #: src/reuse/cli/spdx.py:50 msgid "Name of the person signing off on the SPDX report." msgstr "Nom de la personne signataire du rapport SPDX." #: src/reuse/cli/spdx.py:54 msgid "Name of the organization signing off on the SPDX report." msgstr "Nom de l'organisation signataire du rapport SPDX." #: src/reuse/cli/spdx.py:81 msgid "" "'--creator-person' or '--creator-organization' is required when '--add-" "license-concluded' is provided." msgstr "" "'--creator-person' ou '--creator-organization' est nécessaire lorsque '--add-" "license-concluded' est fourni." #: src/reuse/cli/spdx.py:96 #, 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" #: src/reuse/cli/main.py:36 #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/decorators.py:465 #, python-format msgid "%(prog)s, version %(version)s" msgstr "%(prog)s, version %(version)s" #: src/reuse/cli/main.py:39 msgid "" "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." msgstr "" "Ce programme est un logiciel libre : vous pouvez le redistribuer et/ou le " "modifier sous les termes de la licence publique générale GNU telle que " "publiée par la Free Software Foundation, soit la version 3 de la licence, " "soit (à votre choix) toute version ultérieure." #: src/reuse/cli/main.py:46 msgid "" "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." msgstr "" "Ce programme est distribué dans l'espoir qu'il sera utile, mais SANS aucune " "GARANTIE ; sans même la garantie implicite de COMMERCIALISATION ou " "d'ADÉQUATION À UN USAGE PARTICULIER. Voir la licence publique générale GNU " "pour plus de détails." #: src/reuse/cli/main.py:53 msgid "" "You should have received a copy of the GNU General Public License along with " "this program. If not, see ." msgstr "" "Vous devriez avoir reçu une copie de la licence générale publique GNU avec " "ce programme. Si ce n'est pas le cas, consultez ." #: src/reuse/cli/main.py:61 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/cli/main.py:68 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/cli/main.py:72 msgid "Support the FSFE's work:" msgstr "Soutenir le travail de la FSFE :" #: src/reuse/cli/main.py:77 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/cli/main.py:88 msgid "Enable debug statements." msgstr "Activer les instructions de débogage." #: src/reuse/cli/main.py:93 msgid "Hide deprecation warnings." msgstr "Masquer les avertissements de dépréciation." #: src/reuse/cli/main.py:98 msgid "Do not skip over Git submodules." msgstr "Ne pas omettre les sous-modules Git." #: src/reuse/cli/main.py:103 msgid "Do not skip over Meson subprojects." msgstr "Ne pas omettre les sous-projets Meson." #: src/reuse/cli/main.py:108 msgid "Do not use multiprocessing." msgstr "Ne pas utiliser le multiprocessing." #: src/reuse/cli/main.py:118 msgid "Define root of project." msgstr "Définir la racine du projet." #: src/reuse/cli/common.py:51 #, python-brace-format msgid "" "'{path}' could not be parsed. We received the following error message: " "{message}" msgstr "" "'{path}' ne peut pas être traité. Nous avons reçu le message d'erreur " "suivant : {message}" #: src/reuse/cli/common.py:87 #, python-brace-format msgid "'{name}' is mutually exclusive with: {opts}" msgstr "'{name}' est mutuellement exclusif avec : {opts}" #: src/reuse/cli/common.py:103 msgid "'{}' is not a valid SPDX expression." msgstr "'{}' n'est pas une expression SPDX valide." #: src/reuse/cli/download.py:54 msgid "'{}' is not a valid SPDX License Identifier." msgstr "'{}' n'est pas un identifiant de licence SPDX valide." #: src/reuse/cli/download.py:61 msgid "Did you mean:" msgstr "Vouliez-vous dire :" #: src/reuse/cli/download.py:68 msgid "" "See for a list of valid SPDX License " "Identifiers." msgstr "" "Consultez pour une liste des identifiants de " "licence SPDX valides." #: src/reuse/cli/download.py:77 #, python-brace-format msgid "Error: {spdx_identifier} already exists." msgstr "Erreur : {spdx_identifier} existe déjà." #: src/reuse/cli/download.py:84 #, python-brace-format msgid "Error: {path} does not exist." msgstr "Erreur : '{path}' n'existe pas." #: src/reuse/cli/download.py:88 msgid "Error: Failed to download license." msgstr "Erreur : échec du téléchargement de licence." #: src/reuse/cli/download.py:93 msgid "Is your internet connection working?" msgstr "Votre connexion internet fonctionne-t-elle ?" #: src/reuse/cli/download.py:98 #, python-brace-format msgid "Successfully downloaded {spdx_identifier}." msgstr "Téléchargement de {spdx_identifier} terminé." #: src/reuse/cli/download.py:108 msgid "Download a license and place it in the LICENSES/ directory." msgstr "Télécharge une licence dans le répertoire LICENSES." #: src/reuse/cli/download.py:111 msgid "" "LICENSE must be a valid SPDX License Identifier. You may specify LICENSE " "multiple times to download multiple licenses." msgstr "" "LICENSE doit être un identifiant de licence SPDX valide. Vous pouvez " "spécifier LICENSE plusieurs fois pour télécharger plusieurs licences." #: src/reuse/cli/download.py:124 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/cli/download.py:132 msgid "Path to download to." msgstr "Chemin pour le téléchargement." #: src/reuse/cli/download.py:138 msgid "" "Source from which to copy custom LicenseRef- licenses, either a directory " "that contains the file or the file itself." msgstr "" "Source pour la copie des licences personnalisées LicenseRef-, au choix un " "dossier contenant le fichier ou bien directement un fichier." #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/download.py:145 msgid "LICENSE" msgstr "LICENCE" #: src/reuse/cli/download.py:161 msgid "The 'LICENSE' argument and '--all' option are mutually exclusive." msgstr "Les options 'LICENSE' et '--all' sont mutuellement exclusives." #: src/reuse/cli/download.py:173 msgid "Cannot use '--output' with more than one license." msgstr "'--output' ne peut pas être utilisé avec plus d'une licence." #: src/reuse/cli/annotate.py:66 msgid "Option '--copyright', '--license', or '--contributor' is required." msgstr "L'option '--copyright', '--license' ou '--contributor' est nécessaire." #: src/reuse/cli/annotate.py:127 msgid "" "The following files do not have a recognised file extension. Please use '--" "style', '--force-dot-license', '--fallback-dot-license', or '--skip-" "unrecognised':" msgstr "" "Les fichiers suivants n'ont pas une extension reconnue. Merci d'utiliser '--" "style', '--force-dot-license', '--fallback-dot-license' ou '--skip-" "unrecognised' :" #: src/reuse/cli/annotate.py:160 #, python-brace-format msgid "" "'{path}' does not support single-line comments, please do not use '--single-" "line'." msgstr "" "'{path}' ne supporte pas les commentaires mono-lignes, merci de ne pas " "utiliser '--single-line'." #: src/reuse/cli/annotate.py:167 #, python-brace-format msgid "" "'{path}' does not support multi-line comments, please do not use '--multi-" "line'." msgstr "" "'{path}' ne supporte pas les commentaires multi-lignes, merci de ne pas " "utiliser '--multi-line'." #: src/reuse/cli/annotate.py:213 #, python-brace-format msgid "Template '{template}' could not be found." msgstr "Le modèle '{template}' est introuvable." #: src/reuse/cli/annotate.py:236 #, fuzzy, python-brace-format msgid "'{year}' is not a valid year range." msgstr "{value!r} n'est pas un booléen valide." #: src/reuse/cli/annotate.py:245 #, python-brace-format msgid "" "Your operating system's year is set to '{year}'. This is not four digits, " "and not supported." msgstr "" #: src/reuse/cli/annotate.py:287 msgid "Add copyright and licensing into the headers of files." msgstr "" "Ajouter les informations de droits d'auteur et de licence dans les en-têtes " "des fichiers." #: src/reuse/cli/annotate.py:290 msgid "" "By using --copyright and --license, you can specify which copyright holders " "and licenses to add to the headers of the given files." msgstr "" "En utilisant --copyright et --license, vous pouvez spécifier quel titulaire " "du droit d'auteur et de licence à ajouter dans l'en-tête des fichiers." #: src/reuse/cli/annotate.py:296 msgid "" "By using --contributor, you can specify people or entity that contributed " "but are not copyright holder of the given files." msgstr "" "En utilisant --contributor, vous pouvez indiquer les personnes ou entités " "qui ont contribué mais ne sont pas détentrices des droits d'auteur des " "fichiers." #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:309 msgid "COPYRIGHT" msgstr "COPYRIGHT" #: src/reuse/cli/annotate.py:312 #, fuzzy msgid "Copyright holder, repeatable." msgstr "Déclaration de droits d'auteur, répétable." #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:319 msgid "SPDX_IDENTIFIER" msgstr "SPDX_IDENTIFIER" #: src/reuse/cli/annotate.py:322 msgid "SPDX License Identifier, repeatable." msgstr "Identifiant de licence SPDX, répétable." #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:328 msgid "CONTRIBUTOR" msgstr "CONTRIBUTEUR" #: src/reuse/cli/annotate.py:331 msgid "File contributor, repeatable." msgstr "Contributeur au fichier, répétable." #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:338 msgid "YEAR" msgstr "ANNÉE" #: src/reuse/cli/annotate.py:343 msgid "" "Year of copyright notice. You may define multiple years or a range of years." msgstr "" #: src/reuse/cli/annotate.py:353 msgid "Comment style to use." msgstr "Style de commentaire à utiliser." #: src/reuse/cli/annotate.py:363 msgid "Copyright prefix to use." msgstr "Préfixe de droits d'auteur à utiliser." #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:375 msgid "TEMPLATE" msgstr "TEMPLATE" #: src/reuse/cli/annotate.py:377 msgid "Name of template to use." msgstr "Nom de modèle à utiliser." #: src/reuse/cli/annotate.py:384 #, fuzzy msgid "Do not include year in copyright notice." msgstr "Ne pas inclure d'année dans la déclaration." #: src/reuse/cli/annotate.py:390 #, fuzzy msgid "Merge copyright notices if they are identical except for their years." msgstr "" "Fusionner les lignes de droits d'auteur si les déclarations de droits " "d'auteur sont identiques." #: src/reuse/cli/annotate.py:398 msgid "Force single-line comment style." msgstr "Forcer le style de commentaire monoligne." #: src/reuse/cli/annotate.py:405 msgid "Force multi-line comment style." msgstr "Forcer le style de commentaire multiligne." #: src/reuse/cli/annotate.py:411 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/cli/annotate.py:416 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/cli/annotate.py:423 msgid "Always write a .license file instead of a header inside the file." msgstr "" "Toujours écrire un fichier .license au lieu d'un en-tête dans le fichier." #: src/reuse/cli/annotate.py:430 msgid "Write a .license file to files with unrecognised comment styles." msgstr "" "Écrire un fichier .license pour les fichiers au style de commentaire inconnu." #: src/reuse/cli/annotate.py:437 msgid "Skip files with unrecognised comment styles." msgstr "" "Ignorer les fichiers comportant des styles de commentaires non reconnus." #: src/reuse/cli/annotate.py:448 msgid "Skip files that already contain REUSE information." msgstr "Ignorer les fichiers qui contiennent déjà les données REUSE." #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:453 msgid "PATH" msgstr "CHEMIN" #: src/reuse/cli/annotate.py:510 #, 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/cli/supported_licenses.py:19 msgid "List all licenses on the SPDX License List." msgstr "Lister toutes les licences SPDX." #: src/reuse/global_licensing.py:92 #, fuzzy, python-brace-format msgid "" "{attr_name} must be a {type_name} (got {value} that is a {value_class})." msgstr "" "{attr_name} doit être un(e) {type_name} (obtenu {value} qui est un(e) " "{value_class})." #: src/reuse/global_licensing.py:106 #, fuzzy, python-brace-format msgid "" "Item in {attr_name} collection must be a {type_name} (got {item_value} that " "is a {item_class})." msgstr "" "Les éléments de la collection {attr_name} doivent être des {type_name} " "(obtenu {item_value} qui et un(e) {item_class})." #: src/reuse/global_licensing.py:118 #, python-brace-format msgid "{attr_name} must not be empty." msgstr "{attr_name} ne doit pas être vide." #: src/reuse/global_licensing.py:142 #, fuzzy, python-brace-format msgid "{name} must be a {type} (got {value} that is a {value_type})." msgstr "" "{name} doit être un(e) {type} (obtenu {value} qui est un {value_type})." #: src/reuse/global_licensing.py:166 #, fuzzy, python-brace-format msgid "" "The value of 'precedence' must be one of {precedence_vals} (got {received})" msgstr "" "La valeur de 'precedence' doit être parmi {precedence_vals} (obtenu " "{received})" #: src/reuse/global_licensing.py:219 #, fuzzy, python-brace-format msgid "Could not parse '{notice}'" msgstr "Analyse de la syntaxe de '{expression}' impossible" #: src/reuse/_annotate.py:94 #, fuzzy, python-brace-format msgid "Skipped unrecognised file '{path}'" msgstr "Le fichier {path} non reconnu a été ignoré" #: src/reuse/_annotate.py:100 #, python-brace-format msgid "'{path}' is not recognised; creating '{path}.license'" msgstr "'{path}' non reconnu, création de '{path}.license'" #: src/reuse/_annotate.py:116 #, 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:145 #, 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:152 #, 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:163 #, python-brace-format msgid "Successfully changed header of {path}" msgstr "En-tête de {path} modifié avec succès" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:162 msgid "Repeat for confirmation" msgstr "Répétez pour confirmation" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:178 msgid "Error: The value you entered was invalid." msgstr "Erreur : la valeur que vous avez entré est invalide." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:180 #, python-brace-format msgid "Error: {e.message}" msgstr "Erreur : {e.message}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:191 msgid "Error: The two entered values do not match." msgstr "Erreur : les deux valeurs entrées ne correspondent pas." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:247 msgid "Error: invalid input" msgstr "Erreur : entrée invalide" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:866 msgid "Press any key to continue..." msgstr "Pressez n'importe quelle touche pour continuer..." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:332 #, python-brace-format msgid "" "Choose from:\n" "\t{choices}" msgstr "" "Choisissez parmi :\n" "\t{choices}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:369 msgid "{value!r} is not {choice}." msgid_plural "{value!r} is not one of {choices}." msgstr[0] "{value!r} n'est pas {choice}." msgstr[1] "{value!r} n'est pas un de {choices}." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:460 msgid "{value!r} does not match the format {format}." msgid_plural "{value!r} does not match the formats {formats}." msgstr[0] "{value!r} ne correspond pas au format {format}." msgstr[1] "{value!r} ne correspond pas aux formats {formats}." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:482 msgid "{value!r} is not a valid {number_type}." msgstr "{value!r} n'est pas un {number_type} valide." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:538 #, python-brace-format msgid "{value} is not in the range {range}." msgstr "{value} n'est pas dans l'intervalle {range}." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:719 #, fuzzy msgid "{value!r} is not a valid boolean. Recognized values: {states}" msgstr "{value!r} n'est pas un booléen valide." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:747 msgid "{value!r} is not a valid UUID." msgstr "{value!r} n'est pas un UUID valide." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:937 msgid "file" msgstr "fichier" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:939 msgid "directory" msgstr "répertoire" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:941 msgid "path" msgstr "chemin" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:988 msgid "{name} {filename!r} does not exist." msgstr "{name} {filename!r} n'existe pas." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:997 msgid "{name} {filename!r} is a file." msgstr "{name} {filename!r} est un fichier." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:1005 #, fuzzy msgid "{name} {filename!r} is a directory." msgstr "{name} '{filename}' est un répertoire." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:1014 msgid "{name} {filename!r} is not readable." msgstr "{name} {filename!r} n'est pas lisible." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:1023 msgid "{name} {filename!r} is not writable." msgstr "{name} {filename!r} ne peut pas être écrit." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:1032 msgid "{name} {filename!r} is not executable." msgstr "{name} {filename!r} n'est pas exécutable." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:1099 #, python-brace-format msgid "{len_type} values are required, but {len_value} was given." msgid_plural "{len_type} values are required, but {len_value} were given." msgstr[0] "{len_type} valeurs sont nécessaires, mais {len_value} a été donnée." msgstr[1] "" "{len_type} valeurs sont nécessaires, mais {len_value} ont été données." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/shell_completion.py:332 msgid "Shell completion is not supported for Bash versions older than 4.4." msgstr "" "La complétion du shell n'est pas supportée pour les version de Bash " "antérieures à 4.4." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/shell_completion.py:339 msgid "Couldn't detect Bash version, shell completion is not supported." msgstr "" "Impossible de détecter la version de Bash, la complétion du shell n'est pas " "supportée." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:50 #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:89 #, python-brace-format msgid "Error: {message}" msgstr "Erreur : {message}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:81 #, python-brace-format msgid "Try '{command} {option}' for help." msgstr "Essayez '{command} {option}' pour de l'aide." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:130 #, python-brace-format msgid "Invalid value: {message}" msgstr "Valeur invalide : {message}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:132 #, python-brace-format msgid "Invalid value for {param_hint}: {message}" msgstr "Valeur invalide pour {param_hint} : {message}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:190 msgid "Missing argument" msgstr "Paramètre manquant" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:192 msgid "Missing option" msgstr "Option manquante" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:194 msgid "Missing parameter" msgstr "Paramètre manquant" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:196 #, python-brace-format msgid "Missing {param_type}" msgstr "{param_type} manquant" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:203 #, python-brace-format msgid "Missing parameter: {param_name}" msgstr "Paramètre manquant : {param_name}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:223 #, python-brace-format msgid "No such option: {name}" msgstr "Pas de telle option : {name}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:235 #, python-brace-format msgid "Did you mean {possibility}?" msgid_plural "(Possible options: {possibilities})" msgstr[0] "Vouliez-vous dire {possibility} ?" msgstr[1] "(options possibles : {possibilities})" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:282 msgid "unknown error" msgstr "erreur inconnue" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:289 msgid "Could not open file {filename!r}: {message}" msgstr "Impossible d'ouvrir le fichier {filename!r} : {message}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1104 #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1141 #, python-brace-format msgid "{text} {deprecated_message}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1160 msgid "Options" msgstr "Options" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1222 #, python-brace-format msgid "Got unexpected extra argument ({args})" msgid_plural "Got unexpected extra arguments ({args})" msgstr[0] "Option supplémentaire inattendue ({args})" msgstr[1] "Options supplémentaires inattendues ({args})" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1241 #, fuzzy msgid "DeprecationWarning: The command {name!r} is deprecated.{extra_message}" msgstr "Avertissement de dépréciation : la commande {name!r} est dépréciée." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1425 msgid "Aborted!" msgstr "Avorté !" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1799 msgid "Commands" msgstr "Commandes" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1830 msgid "Missing command." msgstr "Commande manquante." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1908 msgid "No such command {name!r}." msgstr "Pas de telle commande {name!r}." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:2332 msgid "Value must be an iterable." msgstr "La valeur doit être itérable." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:2355 #, python-brace-format msgid "Takes {nargs} values but 1 was given." msgid_plural "Takes {nargs} values but {len} were given." msgstr[0] "Prend des valeurs {nargs} mais 1 a été donnée." msgstr[1] "Prend des valeurs {nargs} mais {len} ont été données." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:2505 #, fuzzy msgid "" "DeprecationWarning: The {param_type} {name!r} is deprecated.{extra_message}" msgstr "Avertissement de dépréciation : la commande {name!r} est dépréciée." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:2956 #, python-brace-format msgid "env var: {var}" msgstr "variable d'environnement : {var}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:2959 #, python-brace-format msgid "default: {default}" msgstr "défaut : {default}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:3023 msgid "(dynamic)" msgstr "(dynamique)" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/parser.py:199 msgid "Argument {name!r} takes {nargs} values." msgstr "L'option {name!r} prend {nargs} valeurs." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/parser.py:381 msgid "Option {name!r} does not take a value." msgstr "L'option {name!r} ne prend pas de valeur." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/parser.py:444 msgid "Option {name!r} requires an argument." msgid_plural "Option {name!r} requires {nargs} arguments." msgstr[0] "L'option {name!r} a besoin d'un paramètre." msgstr[1] "L'option {name!r} a besoin de {nargs} paramètres." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/_termui_impl.py:608 #, python-brace-format msgid "{editor}: Editing failed" msgstr "{editor} : l'édition a échoué" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/_termui_impl.py:612 #, python-brace-format msgid "{editor}: Editing failed: {e}" msgstr "{editor} : l'édition a échoué : {e}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/decorators.py:522 msgid "Show the version and exit." msgstr "Afficher la version et quitter." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/decorators.py:548 msgid "Show this message and exit." msgstr "Afficher ce message et quitter." #, python-brace-format #~ msgid "{path}: read error\n" #~ msgstr "{path} : erreur de lecture\n" #, python-brace-format #~ msgid "{lic_path}: deprecated license\n" #~ msgstr "{lic_path} : licence dépréciée\n" #, fuzzy, python-brace-format #~ msgid "{lic_path}: license without file extension\n" #~ msgstr "{lic_path} : licence sans extension de fichier\n" #, python-brace-format #~ msgid "{lic_path}: unused license\n" #~ msgstr "{lic_path} : licence inutilisée\n" #, 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é" #, python-brace-format #~ msgid "Could not parse '{expression}'" #~ msgstr "Analyse de la syntaxe de '{expression}' impossible" #, python-brace-format #~ msgid "(Deprecated) {text}" #~ msgstr "(Déprécie) {text}" #~ msgid "required" #~ msgstr "nécessaire" #~ msgid "Year of copyright statement." #~ msgstr "Année de déclaration de droits d'auteur." #, python-brace-format #~ msgid "determining identifier of '{path}'" #~ msgstr "résolution de l'identifiant de '{path}'" #~ 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" #~ msgid "can't write to '{}'" #~ msgstr "écriture impossible dans '{}'" #~ msgid "show program's version number and exit" #~ msgstr "voir la version du programme et quitter" #~ 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 "" #~ "Ajoute un copyright et une licence dans l'entête d'un ou plusieurs " #~ "fichiers.\n" #~ "\n" #~ "En utilisant --copyright et --license, vous pouvez spécifier les " #~ "détenteurs de copyrights et les licences à ajouter dans les entêtes des " #~ "fichiers spécifiés.\n" #~ "\n" #~ "En utilisant --contributor, vous pouvez spécifier les personnes ou " #~ "entités ayant contribué aux fichiers spécifiés sans être détenteurs de " #~ "copyright." #~ msgid "download a license and place it in the LICENSES/ directory" #~ msgstr "télécharge une licence et la placer dans le répertoire LICENSES" #~ msgid "list all non-compliant files" #~ msgstr "liste tous les fichiers non-conformes" #, fuzzy, 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 there any deprecated licenses in the project?\n" #~ "\n" #~ "- Are there any license files in the LICENSES/ directory without file " #~ "extension?\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" #~ "- Are there any read errors?\n" #~ "\n" #~ "- Do all files have valid copyright and licensing information?" #~ msgstr "" #~ "Vérifie 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 ?" #~ msgid "print the project's bill of materials in SPDX format" #~ msgstr "imprime la nomenclature du projet au format SPDX" #~ msgid "convert .reuse/dep5 to REUSE.toml" #~ msgstr "convertit .reuse/dep5 en REUSE.toml" #~ msgid "'{}' is not a file" #~ msgstr "'{}' n'est pas un fichier" #~ msgid "can't open '{}'" #~ msgstr "'{}' ne peut être ouvert" #~ msgid "can't write to directory '{}'" #~ msgstr "écriture impossible dans le répertoire '{}'" #~ msgid "can't read or write '{}'" #~ msgstr "lecture ou écriture impossible pour '{}'" #~ msgid "SPDX License Identifier of license" #~ msgstr "Identification de la licence SPDX" #~ 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" #~ msgid "the following arguments are required: license" #~ msgstr "les arguments suivants sont nécessaires : licence" #~ msgid "usage: " #~ msgstr "usage : " #~ msgid ".__call__() not defined" #~ msgstr ".__call__() est indéfini" #, python-format #~ msgid "unknown parser %(parser_name)r (choices: %(choices)s)" #~ msgstr "analyseur %(parser_name)r inconnu (choix : %(choices)s)" #, python-format #~ msgid "argument \"-\" with mode %r" #~ msgstr "argument \"-\" avec le mode %r" #, python-format #~ msgid "can't open '%(filename)s': %(error)s" #~ msgstr "'%(filename)s' ne peut pas être ouvert : %(error)s" #, python-format #~ msgid "cannot merge actions - two groups are named %r" #~ msgstr "impossible de fusionner les actions - deux groupes sont nommés %r" #~ msgid "'required' is an invalid argument for positionals" #~ msgstr "'required' est un argument invalide pour les positionnels" #, 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" #, python-format #~ msgid "dest= is required for options like %r" #~ msgstr "dest= est nécessaire pour les options comme %r" #, python-format #~ msgid "invalid conflict_resolution value: %r" #~ msgstr "valeur de résolution de conflit invalide : %r" #, 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" #~ msgid "mutually exclusive arguments must be optional" #~ msgstr "les arguments mutuellement exclusifs doivent être facultatifs" #~ msgid "cannot have multiple subparser arguments" #~ msgstr "impossible de considérer des arguments de sous-analyse multiples" #, python-format #~ msgid "unrecognized arguments: %s" #~ msgstr "arguments non reconnus : %s" #, python-format #~ msgid "not allowed with argument %s" #~ msgstr "non autorisé avec l'argument %s" #, python-format #~ msgid "ignored explicit argument %r" #~ msgstr "l'argument explicite %r est ignoré" #, python-format #~ msgid "the following arguments are required: %s" #~ msgstr "les arguments suivants sont nécessaires : %s" #, python-format #~ msgid "one of the arguments %s is required" #~ msgstr "un des arguments %s est nécessaire" #~ msgid "expected at most one argument" #~ msgstr "un argument au plus est attendu" #~ msgid "expected at least one argument" #~ msgstr "un argument au moins est attendu" #, 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" #, python-format #~ msgid "ambiguous option: %(option)s could match %(matches)s" #~ msgstr "option ambigüe : %(option)s ne correspond pas à %(matches)s" #, python-format #~ msgid "unexpected option string: %s" #~ msgstr "option inattendue : %s" #, python-format #~ msgid "%r is not callable" #~ msgstr "%r ne peut être appelé" #, python-format #~ msgid "invalid %(type)s value: %(value)r" #~ msgstr "valeur %(type)s invalide : %(value)r" #, python-format #~ msgid "invalid choice: %(value)r (choose from %(choices)s)" #~ msgstr "choix non valide : %(value)r (choisir parmi %(choices)s)" #, fuzzy, python-brace-format #~ msgid "'{path}' could not be decoded as UTF-8." #~ msgstr "'{path}' n'a pas pu être lu en UTF-8." #, 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 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 "" #~ "--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-6.2.0/po/nl.po0000664000175000017500000015721515077707000013670 0ustar alexalex# 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: 2025-10-07 21:23+0000\n" "PO-Revision-Date: 2025-05-23 13:01+0000\n" "Last-Translator: Emily \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 5.12-dev\n" #: src/reuse/lint.py:40 #, fuzzy msgid "BAD LICENSES" msgstr "ONGEBRUIKTE LICENTIES" #: src/reuse/lint.py:42 #, fuzzy msgid "The following licenses are not valid SPDX licenses:" msgstr "De volgende licenties zijn niet gebruikt:" #: src/reuse/lint.py:50 msgid "DEPRECATED LICENSES" msgstr "VEROUDERDE LICENTIES" #: src/reuse/lint.py:52 msgid "The following licenses are deprecated by SPDX:" msgstr "De volgende licenties zijn verouderd door SPDX:" #: src/reuse/lint.py:60 msgid "LICENSES WITHOUT FILE EXTENSION" msgstr "LICENTIES ZONDER BESTANDSEXTENSIE" #: src/reuse/lint.py:62 msgid "The following licenses have no file extension:" msgstr "De volgende licenties hebben geen bestandsextensie:" #: src/reuse/lint.py:70 msgid "MISSING LICENSES" msgstr "ONTBREKENDE LICENTIES" #: src/reuse/lint.py:72 msgid "'{}' found in:" msgstr "'{}' gevonden in:" #: src/reuse/lint.py:79 msgid "UNUSED LICENSES" msgstr "ONGEBRUIKTE LICENTIES" #: src/reuse/lint.py:80 msgid "The following licenses are not used:" msgstr "De volgende licenties zijn niet gebruikt:" #: src/reuse/lint.py:87 msgid "READ ERRORS" msgstr "LEES FOUTEN" #: src/reuse/lint.py:88 msgid "Could not read:" msgstr "Kon niet lezen:" #: src/reuse/lint.py:94 msgid "INVALID SPDX LICENSE EXPRESSIONS" msgstr "" #: src/reuse/lint.py:99 #, fuzzy msgid "'{}' contains invalid SPDX License Expressions:" msgstr "'{}' is geen geldige SPDX-uitdrukking, aan het afbreken" #: src/reuse/lint.py:124 msgid "MISSING COPYRIGHT AND LICENSING INFORMATION" msgstr "AUTEURSRECHT- EN LICENTIE-INFORMATIE ONTBREEKT" #: src/reuse/lint.py:130 #, fuzzy msgid "The following files have no copyright and licensing information:" msgstr "De volgende bestanden hebben geen auteursrechtinformatie:" #: src/reuse/lint.py:141 msgid "The following files have no copyright information:" msgstr "De volgende bestanden hebben geen auteursrechtinformatie:" #: src/reuse/lint.py:150 msgid "The following files have no licensing information:" msgstr "De volgende bestanden bevatten geen licentie-informatie:" #: src/reuse/lint.py:157 msgid "SUMMARY" msgstr "SAMENVATTING" #: src/reuse/lint.py:162 msgid "Bad licenses:" msgstr "Slechte licenties:" #: src/reuse/lint.py:163 msgid "Deprecated licenses:" msgstr "Verouderde licenties:" #: src/reuse/lint.py:166 msgid "Licenses without file extension:" msgstr "Licenties zonder bestandsextensie:" #: src/reuse/lint.py:169 msgid "Missing licenses:" msgstr "Ontbrekende licenties:" #: src/reuse/lint.py:170 msgid "Unused licenses:" msgstr "Ongebruikte licenties:" #: src/reuse/lint.py:171 msgid "Used licenses:" msgstr "Gebruikte licenties:" #: src/reuse/lint.py:172 #, fuzzy msgid "Read errors:" msgstr "Lees fouten: {count}" #: src/reuse/lint.py:173 #, fuzzy msgid "Invalid SPDX License Expressions:" msgstr "'{}' is geen geldige SPDX-uitdrukking, aan het afbreken" #: src/reuse/lint.py:183 #, fuzzy msgid "Files with copyright information:" msgstr "Bestanden met auteursrechtinformatie: {count} / {total}" #: src/reuse/lint.py:187 #, fuzzy msgid "Files with license information:" msgstr "Bestanden met licentie-informatie: {count} / {total}" #: src/reuse/lint.py:204 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:211 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:218 msgid "RECOMMENDATIONS" msgstr "" #: src/reuse/lint.py:286 #, fuzzy, python-brace-format msgid "missing license '{lic}'" msgstr "'{}' is geen geldige SPDX Licentie Identificatie." #: src/reuse/lint.py:291 #, fuzzy msgid "read error" msgstr "Lees fouten: {count}" #: src/reuse/lint.py:296 #, fuzzy, python-brace-format msgid "invalid SPDX License Expression '{expression}'" msgstr "'{}' is geen geldige SPDX-uitdrukking, aan het afbreken" #: src/reuse/lint.py:303 #, fuzzy msgid "no license identifier" msgstr "'{}' is geen geldige SPDX Licentie Identificatie." #: src/reuse/lint.py:307 #, fuzzy msgid "no copyright notice" msgstr "'{}' is geen geldige SPDX Licentie Identificatie." #: src/reuse/lint.py:345 #, fuzzy, python-brace-format msgid "bad license '{lic}'" msgstr "Ongebruikte licenties:" #: src/reuse/lint.py:350 #, fuzzy msgid "deprecated license" msgstr "Verouderde licenties:" #: src/reuse/lint.py:355 #, fuzzy msgid "license without file extension" msgstr "Licenties zonder bestandsextensie:" #: src/reuse/lint.py:360 #, fuzzy msgid "unused license" msgstr "Ongebruikte licenties:" #: src/reuse/project.py:253 #, fuzzy, python-brace-format msgid "'{path}' covered by {global_path}" msgstr "'{path}' valt onder .reuse/dep5" #: src/reuse/project.py:261 #, python-brace-format msgid "" "'{path}' is covered exclusively by REUSE.toml. Not reading the file contents." 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:355 #, 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:419 #, 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:429 #, 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:441 #, 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:480 msgid "" "project '{}' is not a VCS repository or required VCS software is not " "installed" msgstr "" #: src/reuse/extract.py:49 #, python-brace-format msgid "" "REUSE_ENCODING_MODULE must have a value in {modules}; it has '{env_module}'. " "Aborting." msgstr "" #: src/reuse/extract.py:69 msgid "" "No supported module that can detect the encoding of files could be " "successfully imported. Re-read the installation instructions for the reuse " "package, or try the following:" msgstr "" #: src/reuse/extract.py:75 msgid "" "- If you are running a Linux distribution, try your equivalent of `apt " "install file` or `dnf install file`." msgstr "" #: src/reuse/extract.py:80 msgid "" "- Run ` pipx install reuse[charset-normalizer]`. Replace 'pipx' with 'pip' " "if you are not using pipx." msgstr "" #: src/reuse/extract.py:451 #, python-brace-format msgid "" "'{path}' was detected as a binary file; not searching its contents for REUSE " "information." msgstr "" #: src/reuse/extract.py:462 #, python-brace-format msgid "" "extracting REUSE information from '{path}' (encoding {encoding}, encoding " "module {module}, newline {newline})" msgstr "" #: src/reuse/header.py:87 msgid "generated comment is missing copyright lines or license expressions" msgstr "" "gegenereerd commentaar mist auteursrechtregels of licentie-uitdrukkingen" #: src/reuse/report.py:160 #, python-brace-format msgid "Could not read '{path}'" msgstr "Kon '{path}' niet lezen" #: src/reuse/report.py:165 #, python-brace-format msgid "Unexpected error occurred while parsing '{path}'" msgstr "Onverwachte fout vond plaats tijdens het parsen van '{path}'" #: src/reuse/report.py:521 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:532 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:543 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:552 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:564 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:575 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:584 msgid "" "Fix invalid SPDX License Expressions: In one or more files there are SPDX " "License Expressions which cannot be parse. Check whether the value that " "follows 'SPDX-License-Identifier:' is correct. If the detected expression is " "not meant to be valid, put it between 'REUSE-IgnoreStart' and 'REUSE-" "IgnoreEnd' comments." msgstr "" #: src/reuse/report.py:595 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/cli/lint.py:28 #, python-brace-format msgid "" "Lint the project directory for REUSE compliance. This version of the tool " "checks against version {reuse_version} of the REUSE Specification. You can " "find the latest version of the specification at ." msgstr "" #: src/reuse/cli/lint.py:34 msgid "Specifically, the following criteria are checked:" msgstr "" #: src/reuse/cli/lint.py:38 msgid "" "- Are there any bad (unrecognised, not compliant with SPDX) licenses in the " "project?" msgstr "" #: src/reuse/cli/lint.py:43 #, fuzzy msgid "- Are there any deprecated licenses in the project?" msgstr "Wat is het internetadres van het project?" #: src/reuse/cli/lint.py:47 msgid "" "- Are there any license files in the LICENSES/ directory without file " "extension?" msgstr "" #: src/reuse/cli/lint.py:54 msgid "" "- Are any licenses referred to inside of the project, but not included in " "the LICENSES/ directory?" msgstr "" #: src/reuse/cli/lint.py:61 msgid "" "- Are any licenses included in the LICENSES/ directory that are not used " "inside of the project?" msgstr "" #: src/reuse/cli/lint.py:66 msgid "- Are there any read errors?" msgstr "" #: src/reuse/cli/lint.py:69 #, fuzzy msgid "- Do all files have valid copyright and licensing information?" msgstr "" "De volgende bestanden bevatten geen auteursrecht- en licentie-informatie:" #: src/reuse/cli/lint.py:81 src/reuse/cli/lint_file.py:38 msgid "Prevent output." msgstr "" #: src/reuse/cli/lint.py:89 src/reuse/cli/supported_licenses.py:28 msgid "Format output as JSON." msgstr "" #: src/reuse/cli/lint.py:97 msgid "Format output as plain text. (default)" msgstr "" #: src/reuse/cli/lint.py:105 msgid "Format output as errors per line." msgstr "" #: src/reuse/cli/convert_dep5.py:19 msgid "" "Convert .reuse/dep5 into a REUSE.toml file. The generated file is placed in " "the project root and is semantically identical. The .reuse/dep5 file is " "subsequently deleted." msgstr "" #: src/reuse/cli/convert_dep5.py:31 #, fuzzy msgid "No '.reuse/dep5' file." msgstr ".reuse/dep5 aan het creëren" #: src/reuse/cli/lint_file.py:25 msgid "" "Lint individual files for REUSE compliance. The specified FILEs are checked " "for the presence of copyright and licensing information, and whether the " "found licenses are included in the LICENSES/ directory." msgstr "" #: src/reuse/cli/lint_file.py:46 msgid "Format output as errors per line. (default)" msgstr "" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/lint_file.py:51 msgid "FILE" msgstr "" #: src/reuse/cli/lint_file.py:65 #, python-brace-format msgid "'{file}' is not inside of '{root}'." msgstr "" #: src/reuse/cli/spdx.py:22 #, fuzzy msgid "Generate an SPDX bill of materials." msgstr "print de materiaallijst van het project in SPDX-formaat" #: src/reuse/cli/spdx.py:32 msgid "File to write to." msgstr "" #: src/reuse/cli/spdx.py:38 msgid "" "Populate the LicenseConcluded field; note that reuse cannot guarantee that " "the field is accurate." msgstr "" #: src/reuse/cli/spdx.py:50 msgid "Name of the person signing off on the SPDX report." msgstr "" #: src/reuse/cli/spdx.py:54 msgid "Name of the organization signing off on the SPDX report." msgstr "" #: src/reuse/cli/spdx.py:81 msgid "" "'--creator-person' or '--creator-organization' is required when '--add-" "license-concluded' is provided." msgstr "" #: src/reuse/cli/spdx.py:96 #, 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 "" #: src/reuse/cli/main.py:36 #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/decorators.py:465 #, fuzzy, python-format msgid "%(prog)s, version %(version)s" msgstr "%(prog)s: fout: %(message)s\n" #: src/reuse/cli/main.py:39 msgid "" "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." msgstr "" #: src/reuse/cli/main.py:46 msgid "" "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." msgstr "" #: src/reuse/cli/main.py:53 msgid "" "You should have received a copy of the GNU General Public License along with " "this program. If not, see ." msgstr "" #: src/reuse/cli/main.py:61 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/cli/main.py:68 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/cli/main.py:72 msgid "Support the FSFE's work:" msgstr "Ondersteun het werk van de FSFE:" #: src/reuse/cli/main.py:77 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/cli/main.py:88 #, fuzzy msgid "Enable debug statements." msgstr "zet debug statements aan" #: src/reuse/cli/main.py:93 msgid "Hide deprecation warnings." msgstr "" #: src/reuse/cli/main.py:98 #, fuzzy msgid "Do not skip over Git submodules." msgstr "sla Git-submodules niet over" #: src/reuse/cli/main.py:103 #, fuzzy msgid "Do not skip over Meson subprojects." msgstr "sla Git-submodules niet over" #: src/reuse/cli/main.py:108 #, fuzzy msgid "Do not use multiprocessing." msgstr "gebruik geen multiprocessing" #: src/reuse/cli/main.py:118 #, fuzzy msgid "Define root of project." msgstr "bepaal de root van het project" #: src/reuse/cli/common.py:51 #, python-brace-format msgid "" "'{path}' could not be parsed. We received the following error message: " "{message}" msgstr "" #: src/reuse/cli/common.py:87 #, python-brace-format msgid "'{name}' is mutually exclusive with: {opts}" msgstr "" #: src/reuse/cli/common.py:103 #, fuzzy msgid "'{}' is not a valid SPDX expression." msgstr "'{}' is geen geldige SPDX-uitdrukking, aan het afbreken" #: src/reuse/cli/download.py:54 msgid "'{}' is not a valid SPDX License Identifier." msgstr "'{}' is geen geldige SPDX Licentie Identificatie." #: src/reuse/cli/download.py:61 msgid "Did you mean:" msgstr "" #: src/reuse/cli/download.py:68 msgid "" "See for a list of valid SPDX License " "Identifiers." msgstr "" "Zie voor een lijst met geldige SPDX Licentie " "Identificaties." #: src/reuse/cli/download.py:77 #, python-brace-format msgid "Error: {spdx_identifier} already exists." msgstr "Fout: {spdx_identifier} bestaat al." #: src/reuse/cli/download.py:84 #, fuzzy, python-brace-format msgid "Error: {path} does not exist." msgstr "'{path}' eindigt niet met .spdx" #: src/reuse/cli/download.py:88 msgid "Error: Failed to download license." msgstr "Fout: downloaden van licentie mislukt." #: src/reuse/cli/download.py:93 msgid "Is your internet connection working?" msgstr "Werkt uw internetverbinding?" #: src/reuse/cli/download.py:98 #, python-brace-format msgid "Successfully downloaded {spdx_identifier}." msgstr "{spdx_identifier} met succes gedowload." #: src/reuse/cli/download.py:108 #, 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/cli/download.py:111 msgid "" "LICENSE must be a valid SPDX License Identifier. You may specify LICENSE " "multiple times to download multiple licenses." msgstr "" #: src/reuse/cli/download.py:124 #, fuzzy msgid "Download all missing licenses detected in the project." msgstr "" "download alle ontbrekende licenties die in het project zijn gedetecteerd" #: src/reuse/cli/download.py:132 msgid "Path to download to." msgstr "" #: src/reuse/cli/download.py:138 msgid "" "Source from which to copy custom LicenseRef- licenses, either a directory " "that contains the file or the file itself." msgstr "" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/download.py:145 #, fuzzy msgid "LICENSE" msgstr "SLECHTE LICENTIES" #: src/reuse/cli/download.py:161 #, fuzzy msgid "The 'LICENSE' argument and '--all' option are mutually exclusive." msgstr "de opties --exclude-year en --year sluiten elkaar uit" #: src/reuse/cli/download.py:173 #, fuzzy msgid "Cannot use '--output' with more than one license." msgstr "kan --output niet met meer dan een licentie gebruiken" #: src/reuse/cli/annotate.py:66 msgid "Option '--copyright', '--license', or '--contributor' is required." msgstr "De optie '--copyright', ' --license' of '--contributor' is vereist." #: src/reuse/cli/annotate.py:127 #, 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/cli/annotate.py:160 #, python-brace-format msgid "" "'{path}' does not support single-line comments, please do not use '--single-" "line'." msgstr "" #: src/reuse/cli/annotate.py:167 #, python-brace-format msgid "" "'{path}' does not support multi-line comments, please do not use '--multi-" "line'." msgstr "" #: src/reuse/cli/annotate.py:213 #, fuzzy, python-brace-format msgid "Template '{template}' could not be found." msgstr "sjabloon {template} kon niet worden gevonden" #: src/reuse/cli/annotate.py:236 #, fuzzy, python-brace-format msgid "'{year}' is not a valid year range." msgstr "'{}' is geen geldige SPDX-uitdrukking, aan het afbreken" #: src/reuse/cli/annotate.py:245 #, python-brace-format msgid "" "Your operating system's year is set to '{year}'. This is not four digits, " "and not supported." msgstr "" #: src/reuse/cli/annotate.py:287 #, fuzzy msgid "Add copyright and licensing into the headers of files." msgstr "" "voeg auteursrechts- en licentie-informatie toe aan de headers van bestanden" #: src/reuse/cli/annotate.py:290 msgid "" "By using --copyright and --license, you can specify which copyright holders " "and licenses to add to the headers of the given files." msgstr "" #: src/reuse/cli/annotate.py:296 msgid "" "By using --contributor, you can specify people or entity that contributed " "but are not copyright holder of the given files." msgstr "" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:309 msgid "COPYRIGHT" msgstr "" #: src/reuse/cli/annotate.py:312 #, fuzzy msgid "Copyright holder, repeatable." msgstr "auteursrechtverklaring (herhaalbaar)" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:319 msgid "SPDX_IDENTIFIER" msgstr "" #: src/reuse/cli/annotate.py:322 #, fuzzy msgid "SPDX License Identifier, repeatable." msgstr "SPDX Identificatie (herhaalbaar)" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:328 msgid "CONTRIBUTOR" msgstr "" #: src/reuse/cli/annotate.py:331 #, fuzzy msgid "File contributor, repeatable." msgstr "SPDX Identificatie (herhaalbaar)" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:338 msgid "YEAR" msgstr "" #: src/reuse/cli/annotate.py:343 msgid "" "Year of copyright notice. You may define multiple years or a range of years." msgstr "" #: src/reuse/cli/annotate.py:353 #, fuzzy msgid "Comment style to use." msgstr "te gebruiken commentaarstijl (optie)" #: src/reuse/cli/annotate.py:363 #, fuzzy msgid "Copyright prefix to use." msgstr "te gebruiken commentaarstijl (optie)" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:375 msgid "TEMPLATE" msgstr "" #: src/reuse/cli/annotate.py:377 #, fuzzy msgid "Name of template to use." msgstr "naam van het te gebruiken sjabloon (optie)" #: src/reuse/cli/annotate.py:384 #, fuzzy msgid "Do not include year in copyright notice." msgstr "voeg geen jaar toe aan verklaring" #: src/reuse/cli/annotate.py:390 #, fuzzy msgid "Merge copyright notices if they are identical except for their years." msgstr "jaar van auteursrechtverklaring (optie)" #: src/reuse/cli/annotate.py:398 #, fuzzy msgid "Force single-line comment style." msgstr "te gebruiken commentaarstijl (optie)" #: src/reuse/cli/annotate.py:405 #, fuzzy msgid "Force multi-line comment style." msgstr "te gebruiken commentaarstijl (optie)" #: src/reuse/cli/annotate.py:411 msgid "Add headers to all files under specified directories recursively." msgstr "" #: src/reuse/cli/annotate.py:416 msgid "Do not replace the first header in the file; just add a new one." msgstr "" #: src/reuse/cli/annotate.py:423 msgid "Always write a .license file instead of a header inside the file." msgstr "" #: src/reuse/cli/annotate.py:430 msgid "Write a .license file to files with unrecognised comment styles." msgstr "" #: src/reuse/cli/annotate.py:437 msgid "Skip files with unrecognised comment styles." msgstr "" #: src/reuse/cli/annotate.py:448 #, fuzzy msgid "Skip files that already contain REUSE information." msgstr "Bestanden met licentie-informatie: {count} / {total}" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:453 msgid "PATH" msgstr "" #: src/reuse/cli/annotate.py:510 #, 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/cli/supported_licenses.py:19 msgid "List all licenses on the SPDX License List." msgstr "" #: src/reuse/global_licensing.py:92 #, python-brace-format msgid "" "{attr_name} must be a {type_name} (got {value} that is a {value_class})." msgstr "" #: src/reuse/global_licensing.py:106 #, 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:118 #, python-brace-format msgid "{attr_name} must not be empty." msgstr "" #: src/reuse/global_licensing.py:142 #, python-brace-format msgid "{name} must be a {type} (got {value} that is a {value_type})." msgstr "" #: src/reuse/global_licensing.py:166 #, python-brace-format msgid "" "The value of 'precedence' must be one of {precedence_vals} (got {received})" msgstr "" #: src/reuse/global_licensing.py:219 #, fuzzy, python-brace-format msgid "Could not parse '{notice}'" msgstr "Kon '{expression}' niet parsen" #: src/reuse/_annotate.py:94 #, python-brace-format msgid "Skipped unrecognised file '{path}'" msgstr "" #: src/reuse/_annotate.py:100 #, python-brace-format msgid "'{path}' is not recognised; creating '{path}.license'" msgstr "" #: src/reuse/_annotate.py:116 #, fuzzy, python-brace-format msgid "Skipped file '{path}' already containing REUSE information" msgstr "Bestanden met licentie-informatie: {count} / {total}" #: src/reuse/_annotate.py:145 #, python-brace-format msgid "Error: Could not create comment for '{path}'" msgstr "Fout: Kon geen commentaar voor '{path}' creëren" #: src/reuse/_annotate.py:152 #, 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:163 #, python-brace-format msgid "Successfully changed header of {path}" msgstr "Succesvolle verandering van de header van {path}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:162 msgid "Repeat for confirmation" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:178 msgid "Error: The value you entered was invalid." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:180 #, python-brace-format msgid "Error: {e.message}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:191 msgid "Error: The two entered values do not match." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:247 msgid "Error: invalid input" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:866 msgid "Press any key to continue..." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:332 #, python-brace-format msgid "" "Choose from:\n" "\t{choices}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:369 msgid "{value!r} is not {choice}." msgid_plural "{value!r} is not one of {choices}." msgstr[0] "" msgstr[1] "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:460 msgid "{value!r} does not match the format {format}." msgid_plural "{value!r} does not match the formats {formats}." msgstr[0] "" msgstr[1] "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:482 msgid "{value!r} is not a valid {number_type}." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:538 #, python-brace-format msgid "{value} is not in the range {range}." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:719 msgid "{value!r} is not a valid boolean. Recognized values: {states}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:747 msgid "{value!r} is not a valid UUID." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:937 msgid "file" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:939 msgid "directory" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:941 msgid "path" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:988 #, fuzzy msgid "{name} {filename!r} does not exist." msgstr "'{path}' eindigt niet met .spdx" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:997 msgid "{name} {filename!r} is a file." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:1005 #, fuzzy msgid "{name} {filename!r} is a directory." msgstr "'{}' is geen map" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:1014 msgid "{name} {filename!r} is not readable." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:1023 msgid "{name} {filename!r} is not writable." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:1032 msgid "{name} {filename!r} is not executable." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:1099 #, python-brace-format msgid "{len_type} values are required, but {len_value} was given." msgid_plural "{len_type} values are required, but {len_value} were given." msgstr[0] "" msgstr[1] "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/shell_completion.py:332 msgid "Shell completion is not supported for Bash versions older than 4.4." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/shell_completion.py:339 msgid "Couldn't detect Bash version, shell completion is not supported." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:50 #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:89 #, python-brace-format msgid "Error: {message}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:81 #, python-brace-format msgid "Try '{command} {option}' for help." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:130 #, python-brace-format msgid "Invalid value: {message}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:132 #, python-brace-format msgid "Invalid value for {param_hint}: {message}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:190 #, fuzzy msgid "Missing argument" msgstr "positionele argumenten" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:192 #, fuzzy msgid "Missing option" msgstr "Ontbrekende licenties:" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:194 msgid "Missing parameter" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:196 #, python-brace-format msgid "Missing {param_type}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:203 #, python-brace-format msgid "Missing parameter: {param_name}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:223 #, python-brace-format msgid "No such option: {name}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:235 #, python-brace-format msgid "Did you mean {possibility}?" msgid_plural "(Possible options: {possibilities})" msgstr[0] "" msgstr[1] "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:282 msgid "unknown error" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:289 msgid "Could not open file {filename!r}: {message}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1104 #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1141 #, python-brace-format msgid "{text} {deprecated_message}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1160 msgid "Options" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1222 #, fuzzy, python-brace-format msgid "Got unexpected extra argument ({args})" msgid_plural "Got unexpected extra arguments ({args})" msgstr[0] "verwachtte één argument" msgstr[1] "verwachtte één argument" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1241 msgid "DeprecationWarning: The command {name!r} is deprecated.{extra_message}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1425 msgid "Aborted!" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1799 #, fuzzy msgid "Commands" msgstr "subcommando's" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1830 #, fuzzy msgid "Missing command." msgstr "Ontbrekende licenties:" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1908 msgid "No such command {name!r}." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:2332 msgid "Value must be an iterable." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:2355 #, python-brace-format msgid "Takes {nargs} values but 1 was given." msgid_plural "Takes {nargs} values but {len} were given." msgstr[0] "" msgstr[1] "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:2505 msgid "" "DeprecationWarning: The {param_type} {name!r} is deprecated.{extra_message}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:2956 #, python-brace-format msgid "env var: {var}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:2959 #, python-brace-format msgid "default: {default}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:3023 msgid "(dynamic)" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/parser.py:199 msgid "Argument {name!r} takes {nargs} values." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/parser.py:381 msgid "Option {name!r} does not take a value." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/parser.py:444 msgid "Option {name!r} requires an argument." msgid_plural "Option {name!r} requires {nargs} arguments." msgstr[0] "" msgstr[1] "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/_termui_impl.py:608 #, python-brace-format msgid "{editor}: Editing failed" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/_termui_impl.py:612 #, python-brace-format msgid "{editor}: Editing failed: {e}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/decorators.py:522 #, fuzzy msgid "Show the version and exit." msgstr "dit helpbericht laten zien en verlaten" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/decorators.py:548 #, fuzzy msgid "Show this message and exit." msgstr "dit helpbericht laten zien en verlaten" #, fuzzy, python-brace-format #~ msgid "{path}: read error\n" #~ msgstr "Verouderde licenties:" #, fuzzy, python-brace-format #~ msgid "{lic_path}: deprecated license\n" #~ msgstr "Verouderde licenties:" #, fuzzy, python-brace-format #~ msgid "{lic_path}: license without file extension\n" #~ msgstr "Licenties zonder bestandsextensie:" #, fuzzy, python-brace-format #~ msgid "{lic_path}: unused license\n" #~ msgstr "Ongebruikte licenties:" #, 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" #, python-brace-format #~ msgid "Could not parse '{expression}'" #~ msgstr "Kon '{expression}' niet parsen" #, fuzzy, python-brace-format #~ msgid "(Deprecated) {text}" #~ msgstr "Verouderde licenties:" #, fuzzy #~ msgid "Year of copyright statement." #~ msgstr "jaar van auteursrechtverklaring (optie)" #, python-brace-format #~ msgid "determining identifier of '{path}'" #~ msgstr "identificatie van '{path}' bepalen" #~ msgid "can't write to '{}'" #~ msgstr "kan niet schrijven naar '{}'" #~ msgid "show program's version number and exit" #~ msgstr "versienummer van het programma laten zien en verlaten" #~ msgid "download a license and place it in the LICENSES/ directory" #~ msgstr "download een licentie en plaats het in de LICENSES/-map" #~ msgid "list all non-compliant files" #~ msgstr "lijst maken van alle bestanden die tekortschieten" #, fuzzy, 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 there any deprecated licenses in the project?\n" #~ "\n" #~ "- Are there any license files in the LICENSES/ directory without file " #~ "extension?\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" #~ "- Are there any read errors?\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?" #~ msgid "print the project's bill of materials in SPDX format" #~ msgstr "print de materiaallijst van het project in SPDX-formaat" #~ msgid "'{}' is not a file" #~ msgstr "'{}' is geen bestand" #~ msgid "can't open '{}'" #~ msgstr "kan '{}' niet openen" #~ msgid "can't write to directory '{}'" #~ msgstr "kan niet schrijven naar map '{}'" #~ msgid "can't read or write '{}'" #~ msgstr "kan '{}' niet lezen of schrijven" #~ msgid "SPDX License Identifier of license" #~ msgstr "SPDX Licentie Identificatie of licentie" #~ msgid "the following arguments are required: license" #~ msgstr "de volgende argumenten zijn verplicht: licentie" #~ msgid "usage: " #~ msgstr "gebruik: " #~ msgid ".__call__() not defined" #~ msgstr ".__call__() is niet gedefinieerd" #, python-format #~ msgid "unknown parser %(parser_name)r (choices: %(choices)s)" #~ msgstr "onbekende parser %(parser_name)r (keuzes: %(choices)s)" #, python-format #~ msgid "argument \"-\" with mode %r" #~ msgstr "argument \"-\" met mode %r" #, python-format #~ msgid "can't open '%(filename)s': %(error)s" #~ msgstr "kan '%(filename)s' niet openen: %(error)s" #, python-format #~ msgid "cannot merge actions - two groups are named %r" #~ msgstr "kan acties niet samenvoegen - twee groepen delen de naam %r" #~ msgid "'required' is an invalid argument for positionals" #~ msgstr "'required' is een ongeldig argument voor positionele argumenten" #, 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" #, python-format #~ msgid "dest= is required for options like %r" #~ msgstr "dest= is benodigd voor opties zoals %r" #, python-format #~ msgid "invalid conflict_resolution value: %r" #~ msgstr "ongeldige conflictresolutiewaarde: %r" #, python-format #~ msgid "conflicting option string: %s" #~ msgid_plural "conflicting option strings: %s" #~ msgstr[0] "tegenstrijdige optiestring: %s" #~ msgstr[1] "tegenstrijdige optiestrings: %s" #~ msgid "mutually exclusive arguments must be optional" #~ msgstr "argumenten die elkaar uitsluiten moeten optioneel zijn" #~ msgid "cannot have multiple subparser arguments" #~ msgstr "kan niet meerdere subparser-argumenten hebben" #, python-format #~ msgid "unrecognized arguments: %s" #~ msgstr "niet erkende argumenten: %s" #, python-format #~ msgid "not allowed with argument %s" #~ msgstr "niet toegestaan met argument %s" #, python-format #~ msgid "ignored explicit argument %r" #~ msgstr "expliciet argument %r genegeerd" #, python-format #~ msgid "the following arguments are required: %s" #~ msgstr "de volgende argumenten zijn verplicht: %s" #, python-format #~ msgid "one of the arguments %s is required" #~ msgstr "één van de argumenten %s is benodigd" #~ msgid "expected at most one argument" #~ msgstr "verwachtte maximaal één argument" #~ msgid "expected at least one argument" #~ msgstr "verwachtte minimaal één argument" #, python-format #~ msgid "expected %s argument" #~ msgid_plural "expected %s arguments" #~ msgstr[0] "verwachtte %s argument" #~ msgstr[1] "verwachtte %s argumenten" #, python-format #~ msgid "ambiguous option: %(option)s could match %(matches)s" #~ msgstr "" #~ "dubbelzinnige optie: %(option)s zou ook gelijk kunnen zijn aan %(matches)s" #, python-format #~ msgid "unexpected option string: %s" #~ msgstr "onverwachtte optiestring: %s" #, python-format #~ msgid "%r is not callable" #~ msgstr "%r is niet callable" #, python-format #~ msgid "invalid %(type)s value: %(value)r" #~ msgstr "ongeldige %(type)s waarde: %(value)r" #, python-format #~ msgid "invalid choice: %(value)r (choose from %(choices)s)" #~ msgstr "ongeldige keuze: %(value)r (kiezen uit %(choices)s)" #, fuzzy, python-brace-format #~ msgid "'{path}' could not be decoded as UTF-8." #~ msgstr "%s kon niet gedecodeerd worden" #~ 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 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" #~ 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-6.2.0/po/aln.po0000664000175000017500000010230215077707000014014 0ustar alexalex# 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: 2025-10-07 21:23+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" "Language: aln\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" #: src/reuse/lint.py:40 msgid "BAD LICENSES" msgstr "" #: src/reuse/lint.py:42 msgid "The following licenses are not valid SPDX licenses:" msgstr "" #: src/reuse/lint.py:50 msgid "DEPRECATED LICENSES" msgstr "" #: src/reuse/lint.py:52 msgid "The following licenses are deprecated by SPDX:" msgstr "" #: src/reuse/lint.py:60 msgid "LICENSES WITHOUT FILE EXTENSION" msgstr "" #: src/reuse/lint.py:62 msgid "The following licenses have no file extension:" msgstr "" #: src/reuse/lint.py:70 msgid "MISSING LICENSES" msgstr "" #: src/reuse/lint.py:72 msgid "'{}' found in:" msgstr "" #: src/reuse/lint.py:79 msgid "UNUSED LICENSES" msgstr "" #: src/reuse/lint.py:80 msgid "The following licenses are not used:" msgstr "" #: src/reuse/lint.py:87 msgid "READ ERRORS" msgstr "" #: src/reuse/lint.py:88 msgid "Could not read:" msgstr "" #: src/reuse/lint.py:94 msgid "INVALID SPDX LICENSE EXPRESSIONS" msgstr "" #: src/reuse/lint.py:99 msgid "'{}' contains invalid SPDX License Expressions:" msgstr "" #: src/reuse/lint.py:124 msgid "MISSING COPYRIGHT AND LICENSING INFORMATION" msgstr "" #: src/reuse/lint.py:130 msgid "The following files have no copyright and licensing information:" msgstr "" #: src/reuse/lint.py:141 msgid "The following files have no copyright information:" msgstr "" #: src/reuse/lint.py:150 msgid "The following files have no licensing information:" msgstr "" #: src/reuse/lint.py:157 msgid "SUMMARY" msgstr "" #: src/reuse/lint.py:162 msgid "Bad licenses:" msgstr "" #: src/reuse/lint.py:163 msgid "Deprecated licenses:" msgstr "" #: src/reuse/lint.py:166 msgid "Licenses without file extension:" msgstr "" #: src/reuse/lint.py:169 msgid "Missing licenses:" msgstr "" #: src/reuse/lint.py:170 msgid "Unused licenses:" msgstr "" #: src/reuse/lint.py:171 msgid "Used licenses:" msgstr "" #: src/reuse/lint.py:172 msgid "Read errors:" msgstr "" #: src/reuse/lint.py:173 msgid "Invalid SPDX License Expressions:" msgstr "" #: src/reuse/lint.py:183 msgid "Files with copyright information:" msgstr "" #: src/reuse/lint.py:187 msgid "Files with license information:" msgstr "" #: src/reuse/lint.py:204 msgid "" "Congratulations! Your project is compliant with version {} of the REUSE " "Specification :-)" msgstr "" #: src/reuse/lint.py:211 msgid "" "Unfortunately, your project is not compliant with version {} of the REUSE " "Specification :-(" msgstr "" #: src/reuse/lint.py:218 msgid "RECOMMENDATIONS" msgstr "" #: src/reuse/lint.py:286 #, python-brace-format msgid "missing license '{lic}'" msgstr "" #: src/reuse/lint.py:291 msgid "read error" msgstr "" #: src/reuse/lint.py:296 #, python-brace-format msgid "invalid SPDX License Expression '{expression}'" msgstr "" #: src/reuse/lint.py:303 msgid "no license identifier" msgstr "" #: src/reuse/lint.py:307 msgid "no copyright notice" msgstr "" #: src/reuse/lint.py:345 #, python-brace-format msgid "bad license '{lic}'" msgstr "" #: src/reuse/lint.py:350 msgid "deprecated license" msgstr "" #: src/reuse/lint.py:355 msgid "license without file extension" msgstr "" #: src/reuse/lint.py:360 msgid "unused license" msgstr "" #: src/reuse/project.py:253 #, python-brace-format msgid "'{path}' covered by {global_path}" msgstr "" #: src/reuse/project.py:261 #, python-brace-format msgid "" "'{path}' is covered exclusively by REUSE.toml. Not reading the file contents." 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:355 #, 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:419 #, python-brace-format msgid "{path} does not have a file extension" msgstr "" #: src/reuse/project.py:429 #, 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:441 #, python-brace-format msgid "" "{identifier} is the SPDX License Identifier of both {path} and {other_path}" msgstr "" #: src/reuse/project.py:480 msgid "" "project '{}' is not a VCS repository or required VCS software is not " "installed" msgstr "" #: src/reuse/extract.py:49 #, python-brace-format msgid "" "REUSE_ENCODING_MODULE must have a value in {modules}; it has '{env_module}'. " "Aborting." msgstr "" #: src/reuse/extract.py:69 msgid "" "No supported module that can detect the encoding of files could be " "successfully imported. Re-read the installation instructions for the reuse " "package, or try the following:" msgstr "" #: src/reuse/extract.py:75 msgid "" "- If you are running a Linux distribution, try your equivalent of `apt " "install file` or `dnf install file`." msgstr "" #: src/reuse/extract.py:80 msgid "" "- Run ` pipx install reuse[charset-normalizer]`. Replace 'pipx' with 'pip' " "if you are not using pipx." msgstr "" #: src/reuse/extract.py:451 #, python-brace-format msgid "" "'{path}' was detected as a binary file; not searching its contents for REUSE " "information." msgstr "" #: src/reuse/extract.py:462 #, python-brace-format msgid "" "extracting REUSE information from '{path}' (encoding {encoding}, encoding " "module {module}, newline {newline})" msgstr "" #: src/reuse/header.py:87 msgid "generated comment is missing copyright lines or license expressions" msgstr "" #: src/reuse/report.py:160 #, python-brace-format msgid "Could not read '{path}'" msgstr "" #: src/reuse/report.py:165 #, python-brace-format msgid "Unexpected error occurred while parsing '{path}'" msgstr "" #: src/reuse/report.py:521 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:532 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:543 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:552 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:564 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:575 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:584 msgid "" "Fix invalid SPDX License Expressions: In one or more files there are SPDX " "License Expressions which cannot be parse. Check whether the value that " "follows 'SPDX-License-Identifier:' is correct. If the detected expression is " "not meant to be valid, put it between 'REUSE-IgnoreStart' and 'REUSE-" "IgnoreEnd' comments." msgstr "" #: src/reuse/report.py:595 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/cli/lint.py:28 #, python-brace-format msgid "" "Lint the project directory for REUSE compliance. This version of the tool " "checks against version {reuse_version} of the REUSE Specification. You can " "find the latest version of the specification at ." msgstr "" #: src/reuse/cli/lint.py:34 msgid "Specifically, the following criteria are checked:" msgstr "" #: src/reuse/cli/lint.py:38 msgid "" "- Are there any bad (unrecognised, not compliant with SPDX) licenses in the " "project?" msgstr "" #: src/reuse/cli/lint.py:43 msgid "- Are there any deprecated licenses in the project?" msgstr "" #: src/reuse/cli/lint.py:47 msgid "" "- Are there any license files in the LICENSES/ directory without file " "extension?" msgstr "" #: src/reuse/cli/lint.py:54 msgid "" "- Are any licenses referred to inside of the project, but not included in " "the LICENSES/ directory?" msgstr "" #: src/reuse/cli/lint.py:61 msgid "" "- Are any licenses included in the LICENSES/ directory that are not used " "inside of the project?" msgstr "" #: src/reuse/cli/lint.py:66 msgid "- Are there any read errors?" msgstr "" #: src/reuse/cli/lint.py:69 msgid "- Do all files have valid copyright and licensing information?" msgstr "" #: src/reuse/cli/lint.py:81 src/reuse/cli/lint_file.py:38 msgid "Prevent output." msgstr "" #: src/reuse/cli/lint.py:89 src/reuse/cli/supported_licenses.py:28 msgid "Format output as JSON." msgstr "" #: src/reuse/cli/lint.py:97 msgid "Format output as plain text. (default)" msgstr "" #: src/reuse/cli/lint.py:105 msgid "Format output as errors per line." msgstr "" #: src/reuse/cli/convert_dep5.py:19 msgid "" "Convert .reuse/dep5 into a REUSE.toml file. The generated file is placed in " "the project root and is semantically identical. The .reuse/dep5 file is " "subsequently deleted." msgstr "" #: src/reuse/cli/convert_dep5.py:31 msgid "No '.reuse/dep5' file." msgstr "" #: src/reuse/cli/lint_file.py:25 msgid "" "Lint individual files for REUSE compliance. The specified FILEs are checked " "for the presence of copyright and licensing information, and whether the " "found licenses are included in the LICENSES/ directory." msgstr "" #: src/reuse/cli/lint_file.py:46 msgid "Format output as errors per line. (default)" msgstr "" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/lint_file.py:51 msgid "FILE" msgstr "" #: src/reuse/cli/lint_file.py:65 #, python-brace-format msgid "'{file}' is not inside of '{root}'." msgstr "" #: src/reuse/cli/spdx.py:22 msgid "Generate an SPDX bill of materials." msgstr "" #: src/reuse/cli/spdx.py:32 msgid "File to write to." msgstr "" #: src/reuse/cli/spdx.py:38 msgid "" "Populate the LicenseConcluded field; note that reuse cannot guarantee that " "the field is accurate." msgstr "" #: src/reuse/cli/spdx.py:50 msgid "Name of the person signing off on the SPDX report." msgstr "" #: src/reuse/cli/spdx.py:54 msgid "Name of the organization signing off on the SPDX report." msgstr "" #: src/reuse/cli/spdx.py:81 msgid "" "'--creator-person' or '--creator-organization' is required when '--add-" "license-concluded' is provided." msgstr "" #: src/reuse/cli/spdx.py:96 #, 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 "" #: src/reuse/cli/main.py:36 #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/decorators.py:465 #, python-format msgid "%(prog)s, version %(version)s" msgstr "" #: src/reuse/cli/main.py:39 msgid "" "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." msgstr "" #: src/reuse/cli/main.py:46 msgid "" "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." msgstr "" #: src/reuse/cli/main.py:53 msgid "" "You should have received a copy of the GNU General Public License along with " "this program. If not, see ." msgstr "" #: src/reuse/cli/main.py:61 msgid "" "reuse is a tool for compliance with the REUSE recommendations. See for more information, and " "for the online documentation." msgstr "" #: src/reuse/cli/main.py:68 msgid "" "This version of reuse is compatible with version {} of the REUSE " "Specification." msgstr "" #: src/reuse/cli/main.py:72 msgid "Support the FSFE's work:" msgstr "" #: src/reuse/cli/main.py:77 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/cli/main.py:88 msgid "Enable debug statements." msgstr "" #: src/reuse/cli/main.py:93 msgid "Hide deprecation warnings." msgstr "" #: src/reuse/cli/main.py:98 msgid "Do not skip over Git submodules." msgstr "" #: src/reuse/cli/main.py:103 msgid "Do not skip over Meson subprojects." msgstr "" #: src/reuse/cli/main.py:108 msgid "Do not use multiprocessing." msgstr "" #: src/reuse/cli/main.py:118 msgid "Define root of project." msgstr "" #: src/reuse/cli/common.py:51 #, python-brace-format msgid "" "'{path}' could not be parsed. We received the following error message: " "{message}" msgstr "" #: src/reuse/cli/common.py:87 #, python-brace-format msgid "'{name}' is mutually exclusive with: {opts}" msgstr "" #: src/reuse/cli/common.py:103 msgid "'{}' is not a valid SPDX expression." msgstr "" #: src/reuse/cli/download.py:54 msgid "'{}' is not a valid SPDX License Identifier." msgstr "" #: src/reuse/cli/download.py:61 msgid "Did you mean:" msgstr "" #: src/reuse/cli/download.py:68 msgid "" "See for a list of valid SPDX License " "Identifiers." msgstr "" #: src/reuse/cli/download.py:77 #, python-brace-format msgid "Error: {spdx_identifier} already exists." msgstr "" #: src/reuse/cli/download.py:84 #, python-brace-format msgid "Error: {path} does not exist." msgstr "" #: src/reuse/cli/download.py:88 msgid "Error: Failed to download license." msgstr "" #: src/reuse/cli/download.py:93 msgid "Is your internet connection working?" msgstr "" #: src/reuse/cli/download.py:98 #, python-brace-format msgid "Successfully downloaded {spdx_identifier}." msgstr "" #: src/reuse/cli/download.py:108 msgid "Download a license and place it in the LICENSES/ directory." msgstr "" #: src/reuse/cli/download.py:111 msgid "" "LICENSE must be a valid SPDX License Identifier. You may specify LICENSE " "multiple times to download multiple licenses." msgstr "" #: src/reuse/cli/download.py:124 msgid "Download all missing licenses detected in the project." msgstr "" #: src/reuse/cli/download.py:132 msgid "Path to download to." msgstr "" #: src/reuse/cli/download.py:138 msgid "" "Source from which to copy custom LicenseRef- licenses, either a directory " "that contains the file or the file itself." msgstr "" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/download.py:145 msgid "LICENSE" msgstr "" #: src/reuse/cli/download.py:161 msgid "The 'LICENSE' argument and '--all' option are mutually exclusive." msgstr "" #: src/reuse/cli/download.py:173 msgid "Cannot use '--output' with more than one license." msgstr "" #: src/reuse/cli/annotate.py:66 msgid "Option '--copyright', '--license', or '--contributor' is required." msgstr "" #: src/reuse/cli/annotate.py:127 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/cli/annotate.py:160 #, python-brace-format msgid "" "'{path}' does not support single-line comments, please do not use '--single-" "line'." msgstr "" #: src/reuse/cli/annotate.py:167 #, python-brace-format msgid "" "'{path}' does not support multi-line comments, please do not use '--multi-" "line'." msgstr "" #: src/reuse/cli/annotate.py:213 #, python-brace-format msgid "Template '{template}' could not be found." msgstr "" #: src/reuse/cli/annotate.py:236 #, python-brace-format msgid "'{year}' is not a valid year range." msgstr "" #: src/reuse/cli/annotate.py:245 #, python-brace-format msgid "" "Your operating system's year is set to '{year}'. This is not four digits, " "and not supported." msgstr "" #: src/reuse/cli/annotate.py:287 msgid "Add copyright and licensing into the headers of files." msgstr "" #: src/reuse/cli/annotate.py:290 msgid "" "By using --copyright and --license, you can specify which copyright holders " "and licenses to add to the headers of the given files." msgstr "" #: src/reuse/cli/annotate.py:296 msgid "" "By using --contributor, you can specify people or entity that contributed " "but are not copyright holder of the given files." msgstr "" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:309 msgid "COPYRIGHT" msgstr "" #: src/reuse/cli/annotate.py:312 msgid "Copyright holder, repeatable." msgstr "" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:319 msgid "SPDX_IDENTIFIER" msgstr "" #: src/reuse/cli/annotate.py:322 msgid "SPDX License Identifier, repeatable." msgstr "" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:328 msgid "CONTRIBUTOR" msgstr "" #: src/reuse/cli/annotate.py:331 msgid "File contributor, repeatable." msgstr "" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:338 msgid "YEAR" msgstr "" #: src/reuse/cli/annotate.py:343 msgid "" "Year of copyright notice. You may define multiple years or a range of years." msgstr "" #: src/reuse/cli/annotate.py:353 msgid "Comment style to use." msgstr "" #: src/reuse/cli/annotate.py:363 msgid "Copyright prefix to use." msgstr "" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:375 msgid "TEMPLATE" msgstr "" #: src/reuse/cli/annotate.py:377 msgid "Name of template to use." msgstr "" #: src/reuse/cli/annotate.py:384 msgid "Do not include year in copyright notice." msgstr "" #: src/reuse/cli/annotate.py:390 msgid "Merge copyright notices if they are identical except for their years." msgstr "" #: src/reuse/cli/annotate.py:398 msgid "Force single-line comment style." msgstr "" #: src/reuse/cli/annotate.py:405 msgid "Force multi-line comment style." msgstr "" #: src/reuse/cli/annotate.py:411 msgid "Add headers to all files under specified directories recursively." msgstr "" #: src/reuse/cli/annotate.py:416 msgid "Do not replace the first header in the file; just add a new one." msgstr "" #: src/reuse/cli/annotate.py:423 msgid "Always write a .license file instead of a header inside the file." msgstr "" #: src/reuse/cli/annotate.py:430 msgid "Write a .license file to files with unrecognised comment styles." msgstr "" #: src/reuse/cli/annotate.py:437 msgid "Skip files with unrecognised comment styles." msgstr "" #: src/reuse/cli/annotate.py:448 msgid "Skip files that already contain REUSE information." msgstr "" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:453 msgid "PATH" msgstr "" #: src/reuse/cli/annotate.py:510 #, python-brace-format msgid "'{path}' is a binary, therefore using '{new_path}' for the header" msgstr "" #: src/reuse/cli/supported_licenses.py:19 msgid "List all licenses on the SPDX License List." msgstr "" #: src/reuse/global_licensing.py:92 #, python-brace-format msgid "" "{attr_name} must be a {type_name} (got {value} that is a {value_class})." msgstr "" #: src/reuse/global_licensing.py:106 #, 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:118 #, python-brace-format msgid "{attr_name} must not be empty." msgstr "" #: src/reuse/global_licensing.py:142 #, python-brace-format msgid "{name} must be a {type} (got {value} that is a {value_type})." msgstr "" #: src/reuse/global_licensing.py:166 #, python-brace-format msgid "" "The value of 'precedence' must be one of {precedence_vals} (got {received})" msgstr "" #: src/reuse/global_licensing.py:219 #, python-brace-format msgid "Could not parse '{notice}'" msgstr "" #: src/reuse/_annotate.py:94 #, python-brace-format msgid "Skipped unrecognised file '{path}'" msgstr "" #: src/reuse/_annotate.py:100 #, python-brace-format msgid "'{path}' is not recognised; creating '{path}.license'" msgstr "" #: src/reuse/_annotate.py:116 #, python-brace-format msgid "Skipped file '{path}' already containing REUSE information" msgstr "" #: src/reuse/_annotate.py:145 #, python-brace-format msgid "Error: Could not create comment for '{path}'" msgstr "" #: src/reuse/_annotate.py:152 #, 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:163 #, python-brace-format msgid "Successfully changed header of {path}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:162 msgid "Repeat for confirmation" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:178 msgid "Error: The value you entered was invalid." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:180 #, python-brace-format msgid "Error: {e.message}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:191 msgid "Error: The two entered values do not match." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:247 msgid "Error: invalid input" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:866 msgid "Press any key to continue..." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:332 #, python-brace-format msgid "" "Choose from:\n" "\t{choices}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:369 msgid "{value!r} is not {choice}." msgid_plural "{value!r} is not one of {choices}." msgstr[0] "" msgstr[1] "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:460 msgid "{value!r} does not match the format {format}." msgid_plural "{value!r} does not match the formats {formats}." msgstr[0] "" msgstr[1] "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:482 msgid "{value!r} is not a valid {number_type}." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:538 #, python-brace-format msgid "{value} is not in the range {range}." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:719 msgid "{value!r} is not a valid boolean. Recognized values: {states}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:747 msgid "{value!r} is not a valid UUID." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:937 msgid "file" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:939 msgid "directory" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:941 msgid "path" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:988 msgid "{name} {filename!r} does not exist." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:997 msgid "{name} {filename!r} is a file." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:1005 msgid "{name} {filename!r} is a directory." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:1014 msgid "{name} {filename!r} is not readable." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:1023 msgid "{name} {filename!r} is not writable." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:1032 msgid "{name} {filename!r} is not executable." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:1099 #, python-brace-format msgid "{len_type} values are required, but {len_value} was given." msgid_plural "{len_type} values are required, but {len_value} were given." msgstr[0] "" msgstr[1] "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/shell_completion.py:332 msgid "Shell completion is not supported for Bash versions older than 4.4." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/shell_completion.py:339 msgid "Couldn't detect Bash version, shell completion is not supported." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:50 #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:89 #, python-brace-format msgid "Error: {message}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:81 #, python-brace-format msgid "Try '{command} {option}' for help." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:130 #, python-brace-format msgid "Invalid value: {message}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:132 #, python-brace-format msgid "Invalid value for {param_hint}: {message}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:190 msgid "Missing argument" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:192 msgid "Missing option" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:194 msgid "Missing parameter" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:196 #, python-brace-format msgid "Missing {param_type}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:203 #, python-brace-format msgid "Missing parameter: {param_name}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:223 #, python-brace-format msgid "No such option: {name}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:235 #, python-brace-format msgid "Did you mean {possibility}?" msgid_plural "(Possible options: {possibilities})" msgstr[0] "" msgstr[1] "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:282 msgid "unknown error" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:289 msgid "Could not open file {filename!r}: {message}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1104 #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1141 #, python-brace-format msgid "{text} {deprecated_message}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1160 msgid "Options" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1222 #, python-brace-format msgid "Got unexpected extra argument ({args})" msgid_plural "Got unexpected extra arguments ({args})" msgstr[0] "" msgstr[1] "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1241 msgid "DeprecationWarning: The command {name!r} is deprecated.{extra_message}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1425 msgid "Aborted!" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1799 msgid "Commands" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1830 msgid "Missing command." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1908 msgid "No such command {name!r}." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:2332 msgid "Value must be an iterable." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:2355 #, python-brace-format msgid "Takes {nargs} values but 1 was given." msgid_plural "Takes {nargs} values but {len} were given." msgstr[0] "" msgstr[1] "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:2505 msgid "" "DeprecationWarning: The {param_type} {name!r} is deprecated.{extra_message}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:2956 #, python-brace-format msgid "env var: {var}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:2959 #, python-brace-format msgid "default: {default}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:3023 msgid "(dynamic)" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/parser.py:199 msgid "Argument {name!r} takes {nargs} values." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/parser.py:381 msgid "Option {name!r} does not take a value." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/parser.py:444 msgid "Option {name!r} requires an argument." msgid_plural "Option {name!r} requires {nargs} arguments." msgstr[0] "" msgstr[1] "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/_termui_impl.py:608 #, python-brace-format msgid "{editor}: Editing failed" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/_termui_impl.py:612 #, python-brace-format msgid "{editor}: Editing failed: {e}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/decorators.py:522 msgid "Show the version and exit." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/decorators.py:548 msgid "Show this message and exit." msgstr "" reuse-tool-6.2.0/po/reuse.pot0000664000175000017500000010327415077707000014562 0ustar alexalex# 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: 2025-10-07 21:23+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" "#-#-#-#-# click.pot (PACKAGE VERSION) #-#-#-#-#\n" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2025-10-07 21:23+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/lint.py:40 msgid "BAD LICENSES" msgstr "" #: src/reuse/lint.py:42 msgid "The following licenses are not valid SPDX licenses:" msgstr "" #: src/reuse/lint.py:50 msgid "DEPRECATED LICENSES" msgstr "" #: src/reuse/lint.py:52 msgid "The following licenses are deprecated by SPDX:" msgstr "" #: src/reuse/lint.py:60 msgid "LICENSES WITHOUT FILE EXTENSION" msgstr "" #: src/reuse/lint.py:62 msgid "The following licenses have no file extension:" msgstr "" #: src/reuse/lint.py:70 msgid "MISSING LICENSES" msgstr "" #: src/reuse/lint.py:72 msgid "'{}' found in:" msgstr "" #: src/reuse/lint.py:79 msgid "UNUSED LICENSES" msgstr "" #: src/reuse/lint.py:80 msgid "The following licenses are not used:" msgstr "" #: src/reuse/lint.py:87 msgid "READ ERRORS" msgstr "" #: src/reuse/lint.py:88 msgid "Could not read:" msgstr "" #: src/reuse/lint.py:94 msgid "INVALID SPDX LICENSE EXPRESSIONS" msgstr "" #: src/reuse/lint.py:99 msgid "'{}' contains invalid SPDX License Expressions:" msgstr "" #: src/reuse/lint.py:124 msgid "MISSING COPYRIGHT AND LICENSING INFORMATION" msgstr "" #: src/reuse/lint.py:130 msgid "The following files have no copyright and licensing information:" msgstr "" #: src/reuse/lint.py:141 msgid "The following files have no copyright information:" msgstr "" #: src/reuse/lint.py:150 msgid "The following files have no licensing information:" msgstr "" #: src/reuse/lint.py:157 msgid "SUMMARY" msgstr "" #: src/reuse/lint.py:162 msgid "Bad licenses:" msgstr "" #: src/reuse/lint.py:163 msgid "Deprecated licenses:" msgstr "" #: src/reuse/lint.py:166 msgid "Licenses without file extension:" msgstr "" #: src/reuse/lint.py:169 msgid "Missing licenses:" msgstr "" #: src/reuse/lint.py:170 msgid "Unused licenses:" msgstr "" #: src/reuse/lint.py:171 msgid "Used licenses:" msgstr "" #: src/reuse/lint.py:172 msgid "Read errors:" msgstr "" #: src/reuse/lint.py:173 msgid "Invalid SPDX License Expressions:" msgstr "" #: src/reuse/lint.py:183 msgid "Files with copyright information:" msgstr "" #: src/reuse/lint.py:187 msgid "Files with license information:" msgstr "" #: src/reuse/lint.py:204 msgid "" "Congratulations! Your project is compliant with version {} of the REUSE " "Specification :-)" msgstr "" #: src/reuse/lint.py:211 msgid "" "Unfortunately, your project is not compliant with version {} of the REUSE " "Specification :-(" msgstr "" #: src/reuse/lint.py:218 msgid "RECOMMENDATIONS" msgstr "" #: src/reuse/lint.py:286 #, python-brace-format msgid "missing license '{lic}'" msgstr "" #: src/reuse/lint.py:291 msgid "read error" msgstr "" #: src/reuse/lint.py:296 #, python-brace-format msgid "invalid SPDX License Expression '{expression}'" msgstr "" #: src/reuse/lint.py:303 msgid "no license identifier" msgstr "" #: src/reuse/lint.py:307 msgid "no copyright notice" msgstr "" #: src/reuse/lint.py:345 #, python-brace-format msgid "bad license '{lic}'" msgstr "" #: src/reuse/lint.py:350 msgid "deprecated license" msgstr "" #: src/reuse/lint.py:355 msgid "license without file extension" msgstr "" #: src/reuse/lint.py:360 msgid "unused license" msgstr "" #: src/reuse/project.py:253 #, python-brace-format msgid "'{path}' covered by {global_path}" msgstr "" #: src/reuse/project.py:261 #, python-brace-format msgid "" "'{path}' is covered exclusively by REUSE.toml. Not reading the file contents." 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:355 #, 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:419 #, python-brace-format msgid "{path} does not have a file extension" msgstr "" #: src/reuse/project.py:429 #, 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:441 #, python-brace-format msgid "" "{identifier} is the SPDX License Identifier of both {path} and {other_path}" msgstr "" #: src/reuse/project.py:480 msgid "" "project '{}' is not a VCS repository or required VCS software is not " "installed" msgstr "" #: src/reuse/extract.py:49 #, python-brace-format msgid "" "REUSE_ENCODING_MODULE must have a value in {modules}; it has '{env_module}'. " "Aborting." msgstr "" #: src/reuse/extract.py:69 msgid "" "No supported module that can detect the encoding of files could be " "successfully imported. Re-read the installation instructions for the reuse " "package, or try the following:" msgstr "" #: src/reuse/extract.py:75 msgid "" "- If you are running a Linux distribution, try your equivalent of `apt " "install file` or `dnf install file`." msgstr "" #: src/reuse/extract.py:80 msgid "" "- Run ` pipx install reuse[charset-normalizer]`. Replace 'pipx' with 'pip' " "if you are not using pipx." msgstr "" #: src/reuse/extract.py:451 #, python-brace-format msgid "" "'{path}' was detected as a binary file; not searching its contents for REUSE " "information." msgstr "" #: src/reuse/extract.py:462 #, python-brace-format msgid "" "extracting REUSE information from '{path}' (encoding {encoding}, encoding " "module {module}, newline {newline})" msgstr "" #: src/reuse/header.py:87 msgid "generated comment is missing copyright lines or license expressions" msgstr "" #: src/reuse/report.py:160 #, python-brace-format msgid "Could not read '{path}'" msgstr "" #: src/reuse/report.py:165 #, python-brace-format msgid "Unexpected error occurred while parsing '{path}'" msgstr "" #: src/reuse/report.py:521 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:532 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:543 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:552 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:564 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:575 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:584 msgid "" "Fix invalid SPDX License Expressions: In one or more files there are SPDX " "License Expressions which cannot be parse. Check whether the value that " "follows 'SPDX-License-Identifier:' is correct. If the detected expression is " "not meant to be valid, put it between 'REUSE-IgnoreStart' and 'REUSE-" "IgnoreEnd' comments." msgstr "" #: src/reuse/report.py:595 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/cli/lint.py:28 #, python-brace-format msgid "" "Lint the project directory for REUSE compliance. This version of the tool " "checks against version {reuse_version} of the REUSE Specification. You can " "find the latest version of the specification at ." msgstr "" #: src/reuse/cli/lint.py:34 msgid "Specifically, the following criteria are checked:" msgstr "" #: src/reuse/cli/lint.py:38 msgid "" "- Are there any bad (unrecognised, not compliant with SPDX) licenses in the " "project?" msgstr "" #: src/reuse/cli/lint.py:43 msgid "- Are there any deprecated licenses in the project?" msgstr "" #: src/reuse/cli/lint.py:47 msgid "" "- Are there any license files in the LICENSES/ directory without file " "extension?" msgstr "" #: src/reuse/cli/lint.py:54 msgid "" "- Are any licenses referred to inside of the project, but not included in " "the LICENSES/ directory?" msgstr "" #: src/reuse/cli/lint.py:61 msgid "" "- Are any licenses included in the LICENSES/ directory that are not used " "inside of the project?" msgstr "" #: src/reuse/cli/lint.py:66 msgid "- Are there any read errors?" msgstr "" #: src/reuse/cli/lint.py:69 msgid "- Do all files have valid copyright and licensing information?" msgstr "" #: src/reuse/cli/lint.py:81 src/reuse/cli/lint_file.py:38 msgid "Prevent output." msgstr "" #: src/reuse/cli/lint.py:89 src/reuse/cli/supported_licenses.py:28 msgid "Format output as JSON." msgstr "" #: src/reuse/cli/lint.py:97 msgid "Format output as plain text. (default)" msgstr "" #: src/reuse/cli/lint.py:105 msgid "Format output as errors per line." msgstr "" #: src/reuse/cli/convert_dep5.py:19 msgid "" "Convert .reuse/dep5 into a REUSE.toml file. The generated file is placed in " "the project root and is semantically identical. The .reuse/dep5 file is " "subsequently deleted." msgstr "" #: src/reuse/cli/convert_dep5.py:31 msgid "No '.reuse/dep5' file." msgstr "" #: src/reuse/cli/lint_file.py:25 msgid "" "Lint individual files for REUSE compliance. The specified FILEs are checked " "for the presence of copyright and licensing information, and whether the " "found licenses are included in the LICENSES/ directory." msgstr "" #: src/reuse/cli/lint_file.py:46 msgid "Format output as errors per line. (default)" msgstr "" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/lint_file.py:51 msgid "FILE" msgstr "" #: src/reuse/cli/lint_file.py:65 #, python-brace-format msgid "'{file}' is not inside of '{root}'." msgstr "" #: src/reuse/cli/spdx.py:22 msgid "Generate an SPDX bill of materials." msgstr "" #: src/reuse/cli/spdx.py:32 msgid "File to write to." msgstr "" #: src/reuse/cli/spdx.py:38 msgid "" "Populate the LicenseConcluded field; note that reuse cannot guarantee that " "the field is accurate." msgstr "" #: src/reuse/cli/spdx.py:50 msgid "Name of the person signing off on the SPDX report." msgstr "" #: src/reuse/cli/spdx.py:54 msgid "Name of the organization signing off on the SPDX report." msgstr "" #: src/reuse/cli/spdx.py:81 msgid "" "'--creator-person' or '--creator-organization' is required when '--add-" "license-concluded' is provided." msgstr "" #: src/reuse/cli/spdx.py:96 #, 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 "" #: src/reuse/cli/main.py:36 #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/decorators.py:465 #, python-format msgid "%(prog)s, version %(version)s" msgstr "" #: src/reuse/cli/main.py:39 msgid "" "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." msgstr "" #: src/reuse/cli/main.py:46 msgid "" "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." msgstr "" #: src/reuse/cli/main.py:53 msgid "" "You should have received a copy of the GNU General Public License along with " "this program. If not, see ." msgstr "" #: src/reuse/cli/main.py:61 msgid "" "reuse is a tool for compliance with the REUSE recommendations. See for more information, and " "for the online documentation." msgstr "" #: src/reuse/cli/main.py:68 msgid "" "This version of reuse is compatible with version {} of the REUSE " "Specification." msgstr "" #: src/reuse/cli/main.py:72 msgid "Support the FSFE's work:" msgstr "" #: src/reuse/cli/main.py:77 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/cli/main.py:88 msgid "Enable debug statements." msgstr "" #: src/reuse/cli/main.py:93 msgid "Hide deprecation warnings." msgstr "" #: src/reuse/cli/main.py:98 msgid "Do not skip over Git submodules." msgstr "" #: src/reuse/cli/main.py:103 msgid "Do not skip over Meson subprojects." msgstr "" #: src/reuse/cli/main.py:108 msgid "Do not use multiprocessing." msgstr "" #: src/reuse/cli/main.py:118 msgid "Define root of project." msgstr "" #: src/reuse/cli/common.py:51 #, python-brace-format msgid "" "'{path}' could not be parsed. We received the following error message: " "{message}" msgstr "" #: src/reuse/cli/common.py:87 #, python-brace-format msgid "'{name}' is mutually exclusive with: {opts}" msgstr "" #: src/reuse/cli/common.py:103 msgid "'{}' is not a valid SPDX expression." msgstr "" #: src/reuse/cli/download.py:54 msgid "'{}' is not a valid SPDX License Identifier." msgstr "" #: src/reuse/cli/download.py:61 msgid "Did you mean:" msgstr "" #: src/reuse/cli/download.py:68 msgid "" "See for a list of valid SPDX License " "Identifiers." msgstr "" #: src/reuse/cli/download.py:77 #, python-brace-format msgid "Error: {spdx_identifier} already exists." msgstr "" #: src/reuse/cli/download.py:84 #, python-brace-format msgid "Error: {path} does not exist." msgstr "" #: src/reuse/cli/download.py:88 msgid "Error: Failed to download license." msgstr "" #: src/reuse/cli/download.py:93 msgid "Is your internet connection working?" msgstr "" #: src/reuse/cli/download.py:98 #, python-brace-format msgid "Successfully downloaded {spdx_identifier}." msgstr "" #: src/reuse/cli/download.py:108 msgid "Download a license and place it in the LICENSES/ directory." msgstr "" #: src/reuse/cli/download.py:111 msgid "" "LICENSE must be a valid SPDX License Identifier. You may specify LICENSE " "multiple times to download multiple licenses." msgstr "" #: src/reuse/cli/download.py:124 msgid "Download all missing licenses detected in the project." msgstr "" #: src/reuse/cli/download.py:132 msgid "Path to download to." msgstr "" #: src/reuse/cli/download.py:138 msgid "" "Source from which to copy custom LicenseRef- licenses, either a directory " "that contains the file or the file itself." msgstr "" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/download.py:145 msgid "LICENSE" msgstr "" #: src/reuse/cli/download.py:161 msgid "The 'LICENSE' argument and '--all' option are mutually exclusive." msgstr "" #: src/reuse/cli/download.py:173 msgid "Cannot use '--output' with more than one license." msgstr "" #: src/reuse/cli/annotate.py:66 msgid "Option '--copyright', '--license', or '--contributor' is required." msgstr "" #: src/reuse/cli/annotate.py:127 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/cli/annotate.py:160 #, python-brace-format msgid "" "'{path}' does not support single-line comments, please do not use '--single-" "line'." msgstr "" #: src/reuse/cli/annotate.py:167 #, python-brace-format msgid "" "'{path}' does not support multi-line comments, please do not use '--multi-" "line'." msgstr "" #: src/reuse/cli/annotate.py:213 #, python-brace-format msgid "Template '{template}' could not be found." msgstr "" #: src/reuse/cli/annotate.py:236 #, python-brace-format msgid "'{year}' is not a valid year range." msgstr "" #: src/reuse/cli/annotate.py:245 #, python-brace-format msgid "" "Your operating system's year is set to '{year}'. This is not four digits, " "and not supported." msgstr "" #: src/reuse/cli/annotate.py:287 msgid "Add copyright and licensing into the headers of files." msgstr "" #: src/reuse/cli/annotate.py:290 msgid "" "By using --copyright and --license, you can specify which copyright holders " "and licenses to add to the headers of the given files." msgstr "" #: src/reuse/cli/annotate.py:296 msgid "" "By using --contributor, you can specify people or entity that contributed " "but are not copyright holder of the given files." msgstr "" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:309 msgid "COPYRIGHT" msgstr "" #: src/reuse/cli/annotate.py:312 msgid "Copyright holder, repeatable." msgstr "" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:319 msgid "SPDX_IDENTIFIER" msgstr "" #: src/reuse/cli/annotate.py:322 msgid "SPDX License Identifier, repeatable." msgstr "" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:328 msgid "CONTRIBUTOR" msgstr "" #: src/reuse/cli/annotate.py:331 msgid "File contributor, repeatable." msgstr "" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:338 msgid "YEAR" msgstr "" #: src/reuse/cli/annotate.py:343 msgid "" "Year of copyright notice. You may define multiple years or a range of years." msgstr "" #: src/reuse/cli/annotate.py:353 msgid "Comment style to use." msgstr "" #: src/reuse/cli/annotate.py:363 msgid "Copyright prefix to use." msgstr "" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:375 msgid "TEMPLATE" msgstr "" #: src/reuse/cli/annotate.py:377 msgid "Name of template to use." msgstr "" #: src/reuse/cli/annotate.py:384 msgid "Do not include year in copyright notice." msgstr "" #: src/reuse/cli/annotate.py:390 msgid "Merge copyright notices if they are identical except for their years." msgstr "" #: src/reuse/cli/annotate.py:398 msgid "Force single-line comment style." msgstr "" #: src/reuse/cli/annotate.py:405 msgid "Force multi-line comment style." msgstr "" #: src/reuse/cli/annotate.py:411 msgid "Add headers to all files under specified directories recursively." msgstr "" #: src/reuse/cli/annotate.py:416 msgid "Do not replace the first header in the file; just add a new one." msgstr "" #: src/reuse/cli/annotate.py:423 msgid "Always write a .license file instead of a header inside the file." msgstr "" #: src/reuse/cli/annotate.py:430 msgid "Write a .license file to files with unrecognised comment styles." msgstr "" #: src/reuse/cli/annotate.py:437 msgid "Skip files with unrecognised comment styles." msgstr "" #: src/reuse/cli/annotate.py:448 msgid "Skip files that already contain REUSE information." msgstr "" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:453 msgid "PATH" msgstr "" #: src/reuse/cli/annotate.py:510 #, python-brace-format msgid "'{path}' is a binary, therefore using '{new_path}' for the header" msgstr "" #: src/reuse/cli/supported_licenses.py:19 msgid "List all licenses on the SPDX License List." msgstr "" #: src/reuse/global_licensing.py:92 #, python-brace-format msgid "" "{attr_name} must be a {type_name} (got {value} that is a {value_class})." msgstr "" #: src/reuse/global_licensing.py:106 #, 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:118 #, python-brace-format msgid "{attr_name} must not be empty." msgstr "" #: src/reuse/global_licensing.py:142 #, python-brace-format msgid "{name} must be a {type} (got {value} that is a {value_type})." msgstr "" #: src/reuse/global_licensing.py:166 #, python-brace-format msgid "" "The value of 'precedence' must be one of {precedence_vals} (got {received})" msgstr "" #: src/reuse/global_licensing.py:219 #, python-brace-format msgid "Could not parse '{notice}'" msgstr "" #: src/reuse/_annotate.py:94 #, python-brace-format msgid "Skipped unrecognised file '{path}'" msgstr "" #: src/reuse/_annotate.py:100 #, python-brace-format msgid "'{path}' is not recognised; creating '{path}.license'" msgstr "" #: src/reuse/_annotate.py:116 #, python-brace-format msgid "Skipped file '{path}' already containing REUSE information" msgstr "" #: src/reuse/_annotate.py:145 #, python-brace-format msgid "Error: Could not create comment for '{path}'" msgstr "" #: src/reuse/_annotate.py:152 #, 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:163 #, python-brace-format msgid "Successfully changed header of {path}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:162 msgid "Repeat for confirmation" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:178 msgid "Error: The value you entered was invalid." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:180 #, python-brace-format msgid "Error: {e.message}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:191 msgid "Error: The two entered values do not match." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:247 msgid "Error: invalid input" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:866 msgid "Press any key to continue..." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:332 #, python-brace-format msgid "" "Choose from:\n" "\t{choices}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:369 msgid "{value!r} is not {choice}." msgid_plural "{value!r} is not one of {choices}." msgstr[0] "" msgstr[1] "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:460 msgid "{value!r} does not match the format {format}." msgid_plural "{value!r} does not match the formats {formats}." msgstr[0] "" msgstr[1] "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:482 msgid "{value!r} is not a valid {number_type}." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:538 #, python-brace-format msgid "{value} is not in the range {range}." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:719 msgid "{value!r} is not a valid boolean. Recognized values: {states}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:747 msgid "{value!r} is not a valid UUID." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:937 msgid "file" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:939 msgid "directory" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:941 msgid "path" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:988 msgid "{name} {filename!r} does not exist." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:997 msgid "{name} {filename!r} is a file." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:1005 msgid "{name} {filename!r} is a directory." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:1014 msgid "{name} {filename!r} is not readable." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:1023 msgid "{name} {filename!r} is not writable." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:1032 msgid "{name} {filename!r} is not executable." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:1099 #, python-brace-format msgid "{len_type} values are required, but {len_value} was given." msgid_plural "{len_type} values are required, but {len_value} were given." msgstr[0] "" msgstr[1] "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/shell_completion.py:332 msgid "Shell completion is not supported for Bash versions older than 4.4." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/shell_completion.py:339 msgid "Couldn't detect Bash version, shell completion is not supported." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:50 #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:89 #, python-brace-format msgid "Error: {message}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:81 #, python-brace-format msgid "Try '{command} {option}' for help." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:130 #, python-brace-format msgid "Invalid value: {message}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:132 #, python-brace-format msgid "Invalid value for {param_hint}: {message}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:190 msgid "Missing argument" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:192 msgid "Missing option" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:194 msgid "Missing parameter" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:196 #, python-brace-format msgid "Missing {param_type}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:203 #, python-brace-format msgid "Missing parameter: {param_name}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:223 #, python-brace-format msgid "No such option: {name}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:235 #, python-brace-format msgid "Did you mean {possibility}?" msgid_plural "(Possible options: {possibilities})" msgstr[0] "" msgstr[1] "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:282 msgid "unknown error" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:289 msgid "Could not open file {filename!r}: {message}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1104 #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1141 #, python-brace-format msgid "{text} {deprecated_message}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1160 msgid "Options" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1222 #, python-brace-format msgid "Got unexpected extra argument ({args})" msgid_plural "Got unexpected extra arguments ({args})" msgstr[0] "" msgstr[1] "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1241 msgid "DeprecationWarning: The command {name!r} is deprecated.{extra_message}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1425 msgid "Aborted!" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1799 msgid "Commands" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1830 msgid "Missing command." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1908 msgid "No such command {name!r}." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:2332 msgid "Value must be an iterable." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:2355 #, python-brace-format msgid "Takes {nargs} values but 1 was given." msgid_plural "Takes {nargs} values but {len} were given." msgstr[0] "" msgstr[1] "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:2505 msgid "" "DeprecationWarning: The {param_type} {name!r} is deprecated.{extra_message}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:2956 #, python-brace-format msgid "env var: {var}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:2959 #, python-brace-format msgid "default: {default}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:3023 msgid "(dynamic)" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/parser.py:199 msgid "Argument {name!r} takes {nargs} values." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/parser.py:381 msgid "Option {name!r} does not take a value." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/parser.py:444 msgid "Option {name!r} requires an argument." msgid_plural "Option {name!r} requires {nargs} arguments." msgstr[0] "" msgstr[1] "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/_termui_impl.py:608 #, python-brace-format msgid "{editor}: Editing failed" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/_termui_impl.py:612 #, python-brace-format msgid "{editor}: Editing failed: {e}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/decorators.py:522 msgid "Show the version and exit." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/decorators.py:548 msgid "Show this message and exit." msgstr "" reuse-tool-6.2.0/po/ru.po0000664000175000017500000021512615077707000013701 0ustar alexalex# 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: 2025-10-07 21:23+0000\n" "PO-Revision-Date: 2025-01-14 06:00+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.10-dev\n" #: src/reuse/lint.py:40 #, fuzzy msgid "BAD LICENSES" msgstr "НЕИСПОЛЬЗОВАННЫЕ ЛИЦЕНЗИИ" #: src/reuse/lint.py:42 #, fuzzy msgid "The following licenses are not valid SPDX licenses:" msgstr "Следующие лицензии не используются:" #: src/reuse/lint.py:50 msgid "DEPRECATED LICENSES" msgstr "УСТАРЕВШИЕ ЛИЦЕНЗИИ" #: src/reuse/lint.py:52 msgid "The following licenses are deprecated by SPDX:" msgstr "Следующие лицензии устарели в SPDX:" #: src/reuse/lint.py:60 msgid "LICENSES WITHOUT FILE EXTENSION" msgstr "ЛИЦЕНЗИИ БЕЗ РАСШИРЕНИЯ ФАЙЛА" #: src/reuse/lint.py:62 msgid "The following licenses have no file extension:" msgstr "Следующие лицензии не имеют расширения файла:" #: src/reuse/lint.py:70 msgid "MISSING LICENSES" msgstr "ОТСУТСТВУЮЩИЕ ЛИЦЕНЗИИ" #: src/reuse/lint.py:72 msgid "'{}' found in:" msgstr "'{}' найдено в:" #: src/reuse/lint.py:79 msgid "UNUSED LICENSES" msgstr "НЕИСПОЛЬЗОВАННЫЕ ЛИЦЕНЗИИ" #: src/reuse/lint.py:80 msgid "The following licenses are not used:" msgstr "Следующие лицензии не используются:" #: src/reuse/lint.py:87 msgid "READ ERRORS" msgstr "ОШИБКИ ЧТЕНИЯ" #: src/reuse/lint.py:88 msgid "Could not read:" msgstr "Не удалось прочитать:" #: src/reuse/lint.py:94 msgid "INVALID SPDX LICENSE EXPRESSIONS" msgstr "" #: src/reuse/lint.py:99 #, fuzzy msgid "'{}' contains invalid SPDX License Expressions:" msgstr "'{}' не является допустимым выражением SPDX." #: src/reuse/lint.py:124 msgid "MISSING COPYRIGHT AND LICENSING INFORMATION" msgstr "ОТСУТСТВИЕ ИНФОРМАЦИИ ОБ АВТОРСКИХ ПРАВАХ И ЛИЦЕНЗИРОВАНИИ" #: src/reuse/lint.py:130 #, fuzzy msgid "The following files have no copyright and licensing information:" msgstr "Следующие файлы не содержат информации об авторских правах:" #: src/reuse/lint.py:141 msgid "The following files have no copyright information:" msgstr "Следующие файлы не содержат информации об авторских правах:" #: src/reuse/lint.py:150 msgid "The following files have no licensing information:" msgstr "Следующие файлы не содержат информации о лицензировании:" #: src/reuse/lint.py:157 msgid "SUMMARY" msgstr "РЕЗЮМЕ" #: src/reuse/lint.py:162 msgid "Bad licenses:" msgstr "Плохие лицензии:" #: src/reuse/lint.py:163 msgid "Deprecated licenses:" msgstr "Утраченные лицензии:" #: src/reuse/lint.py:166 msgid "Licenses without file extension:" msgstr "Лицензии без расширения файла:" #: src/reuse/lint.py:169 msgid "Missing licenses:" msgstr "Отсутствующие лицензии:" #: src/reuse/lint.py:170 msgid "Unused licenses:" msgstr "Неиспользованные лицензии:" #: src/reuse/lint.py:171 msgid "Used licenses:" msgstr "Используемые лицензии:" #: src/reuse/lint.py:172 msgid "Read errors:" msgstr "Читайте ошибки:" #: src/reuse/lint.py:173 #, fuzzy msgid "Invalid SPDX License Expressions:" msgstr "'{}' не является допустимым выражением SPDX." #: src/reuse/lint.py:183 msgid "Files with copyright information:" msgstr "Файлы с информацией об авторских правах:" #: src/reuse/lint.py:187 msgid "Files with license information:" msgstr "Файлы с информацией о лицензии:" #: src/reuse/lint.py:204 msgid "" "Congratulations! Your project is compliant with version {} of the REUSE " "Specification :-)" msgstr "Поздравляем! Ваш проект соответствует версии {} спецификации REUSE :-)" #: src/reuse/lint.py:211 msgid "" "Unfortunately, your project is not compliant with version {} of the REUSE " "Specification :-(" msgstr "" "К сожалению, ваш проект не соответствует версии {} спецификации REUSE :-(" #: src/reuse/lint.py:218 msgid "RECOMMENDATIONS" msgstr "РЕКОМЕНДАЦИИ" #: src/reuse/lint.py:286 #, fuzzy, python-brace-format msgid "missing license '{lic}'" msgstr "{path}: отсутствует лицензия {lic}\n" #: src/reuse/lint.py:291 #, fuzzy msgid "read error" msgstr "Читайте ошибки:" #: src/reuse/lint.py:296 #, fuzzy, python-brace-format msgid "invalid SPDX License Expression '{expression}'" msgstr "'{}' не является допустимым выражением SPDX." #: src/reuse/lint.py:303 #, fuzzy msgid "no license identifier" msgstr "{path}: нет идентификатора лицензии\n" #: src/reuse/lint.py:307 #, fuzzy msgid "no copyright notice" msgstr "{path}: нет уведомления об авторских правах\n" #: src/reuse/lint.py:345 #, fuzzy, python-brace-format msgid "bad license '{lic}'" msgstr "{path}: плохая лицензия {lic}\n" #: src/reuse/lint.py:350 #, fuzzy msgid "deprecated license" msgstr "Утраченные лицензии:" #: src/reuse/lint.py:355 #, fuzzy msgid "license without file extension" msgstr "Лицензии без расширения файла:" #: src/reuse/lint.py:360 #, fuzzy msgid "unused license" msgstr "Неиспользованные лицензии:" #: src/reuse/project.py:253 #, python-brace-format msgid "'{path}' covered by {global_path}" msgstr "'{path}' покрыт {global_path}" #: src/reuse/project.py:261 #, python-brace-format msgid "" "'{path}' is covered exclusively by REUSE.toml. Not reading the file contents." msgstr "" "'{path}' покрывается исключительно REUSE.toml. Не читать содержимое файла." #: 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:355 #, 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:419 #, python-brace-format msgid "{path} does not have a file extension" msgstr "У {path} нет расширения файла" #: src/reuse/project.py:429 #, 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:441 #, 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:480 msgid "" "project '{}' is not a VCS repository or required VCS software is not " "installed" msgstr "" "Проект '{}' не является репозиторием VCS или в нем не установлено " "необходимое программное обеспечение VCS" #: src/reuse/extract.py:49 #, python-brace-format msgid "" "REUSE_ENCODING_MODULE must have a value in {modules}; it has '{env_module}'. " "Aborting." msgstr "" #: src/reuse/extract.py:69 msgid "" "No supported module that can detect the encoding of files could be " "successfully imported. Re-read the installation instructions for the reuse " "package, or try the following:" msgstr "" #: src/reuse/extract.py:75 msgid "" "- If you are running a Linux distribution, try your equivalent of `apt " "install file` or `dnf install file`." msgstr "" #: src/reuse/extract.py:80 msgid "" "- Run ` pipx install reuse[charset-normalizer]`. Replace 'pipx' with 'pip' " "if you are not using pipx." msgstr "" #: src/reuse/extract.py:451 #, python-brace-format msgid "" "'{path}' was detected as a binary file; not searching its contents for REUSE " "information." msgstr "" "'{path}' был обнаружен как двоичный файл; поиск информации о REUSE в его " "содержимом не производится." #: src/reuse/extract.py:462 #, python-brace-format msgid "" "extracting REUSE information from '{path}' (encoding {encoding}, encoding " "module {module}, newline {newline})" msgstr "" #: src/reuse/header.py:87 msgid "generated comment is missing copyright lines or license expressions" msgstr "" "В сгенерированном комментарии отсутствуют строки об авторских правах или " "выражениях лицензии" #: src/reuse/report.py:160 #, python-brace-format msgid "Could not read '{path}'" msgstr "Не удалось прочитать '{path}'" #: src/reuse/report.py:165 #, python-brace-format msgid "Unexpected error occurred while parsing '{path}'" msgstr "При разборе '{path}' произошла непредвиденная ошибка" #: src/reuse/report.py:521 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:532 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:543 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:552 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:564 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:575 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:584 msgid "" "Fix invalid SPDX License Expressions: In one or more files there are SPDX " "License Expressions which cannot be parse. Check whether the value that " "follows 'SPDX-License-Identifier:' is correct. If the detected expression is " "not meant to be valid, put it between 'REUSE-IgnoreStart' and 'REUSE-" "IgnoreEnd' comments." msgstr "" #: src/reuse/report.py:595 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/cli/lint.py:28 #, python-brace-format msgid "" "Lint the project directory for REUSE compliance. This version of the tool " "checks against version {reuse_version} of the REUSE Specification. You can " "find the latest version of the specification at ." msgstr "" "Проверка каталога проекта на соответствие требованиям REUSE. Эта версия " "инструмента проверяет версию {reuse_version} спецификации REUSE. Последнюю " "версию спецификации можно найти по адресу ." #: src/reuse/cli/lint.py:34 msgid "Specifically, the following criteria are checked:" msgstr "В частности, проверяются следующие критерии:" #: src/reuse/cli/lint.py:38 msgid "" "- Are there any bad (unrecognised, not compliant with SPDX) licenses in the " "project?" msgstr "" "- Есть ли в проекте плохие (непризнанные, не соответствующие SPDX) лицензии?" #: src/reuse/cli/lint.py:43 msgid "- Are there any deprecated licenses in the project?" msgstr "- Есть ли в проекте устаревшие лицензии?" #: src/reuse/cli/lint.py:47 msgid "" "- Are there any license files in the LICENSES/ directory without file " "extension?" msgstr "- Есть ли в каталоге LICENSES/ файлы лицензий без расширения?" #: src/reuse/cli/lint.py:54 msgid "" "- Are any licenses referred to inside of the project, but not included in " "the LICENSES/ directory?" msgstr "" "- Есть ли лицензии, на которые ссылаются внутри проекта, но которые не " "включены в каталог LICENSES/?" #: src/reuse/cli/lint.py:61 msgid "" "- Are any licenses included in the LICENSES/ directory that are not used " "inside of the project?" msgstr "" "- Включены ли в каталог LICENSES/ какие-либо лицензии, которые не " "используются внутри проекта?" #: src/reuse/cli/lint.py:66 msgid "- Are there any read errors?" msgstr "- Есть ли ошибки чтения?" #: src/reuse/cli/lint.py:69 msgid "- Do all files have valid copyright and licensing information?" msgstr "" "- Все ли файлы содержат достоверную информацию об авторских правах и " "лицензировании?" #: src/reuse/cli/lint.py:81 src/reuse/cli/lint_file.py:38 msgid "Prevent output." msgstr "Предотвращение выхода." #: src/reuse/cli/lint.py:89 src/reuse/cli/supported_licenses.py:28 msgid "Format output as JSON." msgstr "Формат как JSON." #: src/reuse/cli/lint.py:97 msgid "Format output as plain text. (default)" msgstr "Форматирование вывода как обычного текста. (по умолчанию)" #: src/reuse/cli/lint.py:105 msgid "Format output as errors per line." msgstr "Форматируйте вывод как ошибки в строке." #: src/reuse/cli/convert_dep5.py:19 msgid "" "Convert .reuse/dep5 into a REUSE.toml file. The generated file is placed in " "the project root and is semantically identical. The .reuse/dep5 file is " "subsequently deleted." msgstr "" "Преобразуйте файл .reuse/dep5 в файл REUSE.toml. Созданный файл помещается в " "корень проекта и является семантически идентичным. Файл .reuse/dep5 " "впоследствии удаляется." #: src/reuse/cli/convert_dep5.py:31 msgid "No '.reuse/dep5' file." msgstr "Файл '.reuse/dep5' отсутствует." #: src/reuse/cli/lint_file.py:25 msgid "" "Lint individual files for REUSE compliance. The specified FILEs are checked " "for the presence of copyright and licensing information, and whether the " "found licenses are included in the LICENSES/ directory." msgstr "" "Проверка отдельных файлов на соответствие стандарту REUSE. Указанные ФАЙЛЫ " "проверяются на наличие информации об авторских правах и лицензировании, а " "также на то, включены ли найденные лицензии в каталог LICENSES/." #: src/reuse/cli/lint_file.py:46 msgid "Format output as errors per line. (default)" msgstr "Форматировать вывод в виде ошибок в строке. (по умолчанию)" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/lint_file.py:51 msgid "FILE" msgstr "ФАЙЛ" #: src/reuse/cli/lint_file.py:65 #, python-brace-format msgid "'{file}' is not inside of '{root}'." msgstr "'{file}' не находится внутри '{root}'." #: src/reuse/cli/spdx.py:22 msgid "Generate an SPDX bill of materials." msgstr "Создать ведомость материалов в формате SPDX." #: src/reuse/cli/spdx.py:32 msgid "File to write to." msgstr "Файл для записи." #: src/reuse/cli/spdx.py:38 msgid "" "Populate the LicenseConcluded field; note that reuse cannot guarantee that " "the field is accurate." msgstr "" "Заполните поле LicenseConcluded; обратите внимание, что повторное " "использование не может гарантировать точность поля." #: src/reuse/cli/spdx.py:50 msgid "Name of the person signing off on the SPDX report." msgstr "Имя лица, подписавшего отчет SPDX." #: src/reuse/cli/spdx.py:54 msgid "Name of the organization signing off on the SPDX report." msgstr "Название организации, подписавшей отчет SPDX." #: src/reuse/cli/spdx.py:81 msgid "" "'--creator-person' or '--creator-organization' is required when '--add-" "license-concluded' is provided." msgstr "" "'--creator-person' или '--creator-organization' требуется, если указано '--" "add-license-concluded'." #: src/reuse/cli/spdx.py:96 #, 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" #: src/reuse/cli/main.py:36 #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/decorators.py:465 #, python-format msgid "%(prog)s, version %(version)s" msgstr "%(prog)s, версия %(version)s" #: src/reuse/cli/main.py:39 msgid "" "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." msgstr "" "Эта программа является свободным программным обеспечением: вы можете " "распространять ее и/или изменять в соответствии с условиями Стандартной " "общественной лицензии GNU, опубликованной Фондом свободного программного " "обеспечения, либо версии 3 этой лицензии, либо (по вашему выбору) любой " "более поздней версии." #: src/reuse/cli/main.py:46 msgid "" "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." msgstr "" "Эта программа распространяется в надежде, что она окажется полезной, но БЕЗ " "КАКИХ-ЛИБО ГАРАНТИЙ; даже без подразумеваемых гарантий ТОВАРНОЙ ПРИГОДНОСТИ " "или ПРИГОДНОСТИ ДЛЯ КАКОЙ-ЛИБО ЦЕЛИ. Более подробную информацию см. в " "Стандартной общественной лицензии GNU." #: src/reuse/cli/main.py:53 msgid "" "You should have received a copy of the GNU General Public License along with " "this program. If not, see ." msgstr "" "Вместе с этой программой вы должны были получить копию Стандартной " "общественной лицензии GNU. Если нет, смотрите ." #: src/reuse/cli/main.py:61 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/cli/main.py:68 msgid "" "This version of reuse is compatible with version {} of the REUSE " "Specification." msgstr "" "Эта версия повторного использования совместима с версией {} спецификации " "REUSE." #: src/reuse/cli/main.py:72 msgid "Support the FSFE's work:" msgstr "Поддержите работу ФСПО:" #: src/reuse/cli/main.py:77 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/cli/main.py:88 msgid "Enable debug statements." msgstr "Включить отладочные операторы." #: src/reuse/cli/main.py:93 msgid "Hide deprecation warnings." msgstr "Скрыть предупреждения об устаревании." #: src/reuse/cli/main.py:98 msgid "Do not skip over Git submodules." msgstr "Не пропускайте подмодули Git." #: src/reuse/cli/main.py:103 msgid "Do not skip over Meson subprojects." msgstr "Не пропускайте подпроекты \"Мезон\"." #: src/reuse/cli/main.py:108 msgid "Do not use multiprocessing." msgstr "Не используйте многопроцессорную обработку." #: src/reuse/cli/main.py:118 msgid "Define root of project." msgstr "Определите корень проекта." #: src/reuse/cli/common.py:51 #, python-brace-format msgid "" "'{path}' could not be parsed. We received the following error message: " "{message}" msgstr "" "'{path}' не может быть разобран. Мы получили следующее сообщение об ошибке: " "{message}" #: src/reuse/cli/common.py:87 #, python-brace-format msgid "'{name}' is mutually exclusive with: {opts}" msgstr "'{name}' является взаимоисключающим с: {opts}" #: src/reuse/cli/common.py:103 msgid "'{}' is not a valid SPDX expression." msgstr "'{}' не является допустимым выражением SPDX." #: src/reuse/cli/download.py:54 msgid "'{}' is not a valid SPDX License Identifier." msgstr "'{}' не является действительным идентификатором лицензии SPDX." #: src/reuse/cli/download.py:61 msgid "Did you mean:" msgstr "Вы имели в виду:" #: src/reuse/cli/download.py:68 msgid "" "See for a list of valid SPDX License " "Identifiers." msgstr "" "Список допустимых идентификаторов лицензий SPDX см. в ." #: src/reuse/cli/download.py:77 #, python-brace-format msgid "Error: {spdx_identifier} already exists." msgstr "Ошибка: {spdx_identifier} уже существует." #: src/reuse/cli/download.py:84 #, python-brace-format msgid "Error: {path} does not exist." msgstr "Ошибка: {path} не существует." #: src/reuse/cli/download.py:88 msgid "Error: Failed to download license." msgstr "Ошибка: Не удалось загрузить лицензию." #: src/reuse/cli/download.py:93 msgid "Is your internet connection working?" msgstr "Работает ли ваше интернет-соединение?" #: src/reuse/cli/download.py:98 #, python-brace-format msgid "Successfully downloaded {spdx_identifier}." msgstr "Успешно загружен {spdx_identifier}." #: src/reuse/cli/download.py:108 msgid "Download a license and place it in the LICENSES/ directory." msgstr "Загрузите лицензию и поместите ее в каталог LICENSES/." #: src/reuse/cli/download.py:111 msgid "" "LICENSE must be a valid SPDX License Identifier. You may specify LICENSE " "multiple times to download multiple licenses." msgstr "" "LICENSE должен быть действительным идентификатором лицензии SPDX. Вы можете " "указать LICENSE несколько раз, чтобы загрузить несколько лицензий." #: src/reuse/cli/download.py:124 msgid "Download all missing licenses detected in the project." msgstr "Загрузите все недостающие лицензии, обнаруженные в проекте." #: src/reuse/cli/download.py:132 msgid "Path to download to." msgstr "Путь для загрузки." #: src/reuse/cli/download.py:138 msgid "" "Source from which to copy custom LicenseRef- licenses, either a directory " "that contains the file or the file itself." msgstr "" "Источник, из которого копируются пользовательские лицензии LicenseRef-, либо " "каталог, содержащий файл, либо сам файл." #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/download.py:145 msgid "LICENSE" msgstr "ЛИЦЕНЗИЯ" #: src/reuse/cli/download.py:161 msgid "The 'LICENSE' argument and '--all' option are mutually exclusive." msgstr "Аргумент ' ЛИЦЕНЗИЯ' и опция '--все' являются взаимоисключающими." #: src/reuse/cli/download.py:173 msgid "Cannot use '--output' with more than one license." msgstr "Невозможно использовать '--output' с более чем одной лицензией." #: src/reuse/cli/annotate.py:66 msgid "Option '--copyright', '--license', or '--contributor' is required." msgstr "" "Требуется опция '-- авторское право', '--лицензия' или '--контрибутор'." #: src/reuse/cli/annotate.py:127 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/cli/annotate.py:160 #, python-brace-format msgid "" "'{path}' does not support single-line comments, please do not use '--single-" "line'." msgstr "" "'{path}' не поддерживает однострочные комментарии, поэтому не используйте '--" "single-line'." #: src/reuse/cli/annotate.py:167 #, python-brace-format msgid "" "'{path}' does not support multi-line comments, please do not use '--multi-" "line'." msgstr "" "'{path}' не поддерживает многострочные комментарии, поэтому не используйте " "'--multi-line'." #: src/reuse/cli/annotate.py:213 #, python-brace-format msgid "Template '{template}' could not be found." msgstr "Шаблон '{template}' не найден." #: src/reuse/cli/annotate.py:236 #, fuzzy, python-brace-format msgid "'{year}' is not a valid year range." msgstr "{value!r} не является допустимым булевым числом." #: src/reuse/cli/annotate.py:245 #, python-brace-format msgid "" "Your operating system's year is set to '{year}'. This is not four digits, " "and not supported." msgstr "" #: src/reuse/cli/annotate.py:287 msgid "Add copyright and licensing into the headers of files." msgstr "" "Добавьте в заголовки файлов информацию об авторских правах и лицензировании." #: src/reuse/cli/annotate.py:290 msgid "" "By using --copyright and --license, you can specify which copyright holders " "and licenses to add to the headers of the given files." msgstr "" "Используя --copyright и --license, вы можете указать, каких правообладателей " "и лицензии следует добавить в заголовки заданных файлов." #: src/reuse/cli/annotate.py:296 msgid "" "By using --contributor, you can specify people or entity that contributed " "but are not copyright holder of the given files." msgstr "" "Используя команду --contributor, вы можете указать людей или организации, " "которые внесли свой вклад, но не являются правообладателями данных файлов." #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:309 msgid "COPYRIGHT" msgstr "КОПИРАЙТ" #: src/reuse/cli/annotate.py:312 #, fuzzy msgid "Copyright holder, repeatable." msgstr "Заявление об авторских правах, повторяемое." #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:319 msgid "SPDX_IDENTIFIER" msgstr "SPDX_ИДЕНТИФИКАТОР" #: src/reuse/cli/annotate.py:322 msgid "SPDX License Identifier, repeatable." msgstr "Идентификатор лицензии SPDX, повторяемый." #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:328 msgid "CONTRIBUTOR" msgstr "КОНТРИБЬЮТОР" #: src/reuse/cli/annotate.py:331 msgid "File contributor, repeatable." msgstr "Вкладчик файлов, повторяющийся." #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:338 msgid "YEAR" msgstr "ГОД" #: src/reuse/cli/annotate.py:343 msgid "" "Year of copyright notice. You may define multiple years or a range of years." msgstr "" #: src/reuse/cli/annotate.py:353 msgid "Comment style to use." msgstr "Используйте стиль комментариев." #: src/reuse/cli/annotate.py:363 msgid "Copyright prefix to use." msgstr "Используемый префикс авторского права." #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:375 msgid "TEMPLATE" msgstr "ОБРАЗЕЦ" #: src/reuse/cli/annotate.py:377 msgid "Name of template to use." msgstr "Название используемого шаблона." #: src/reuse/cli/annotate.py:384 #, fuzzy msgid "Do not include year in copyright notice." msgstr "Не указывайте год в заявлении об авторских правах." #: src/reuse/cli/annotate.py:390 #, fuzzy msgid "Merge copyright notices if they are identical except for their years." msgstr "" "Объедините строки с авторскими правами, если заявления об авторских правах " "идентичны." #: src/reuse/cli/annotate.py:398 msgid "Force single-line comment style." msgstr "Принудительный стиль однострочных комментариев." #: src/reuse/cli/annotate.py:405 msgid "Force multi-line comment style." msgstr "Принудительный стиль многострочных комментариев." #: src/reuse/cli/annotate.py:411 msgid "Add headers to all files under specified directories recursively." msgstr "Рекурсивно добавляет заголовки ко всем файлам в указанных каталогах." #: src/reuse/cli/annotate.py:416 msgid "Do not replace the first header in the file; just add a new one." msgstr "Не заменяйте первый заголовок в файле, просто добавьте новый." #: src/reuse/cli/annotate.py:423 msgid "Always write a .license file instead of a header inside the file." msgstr "Всегда пишите файл .license вместо заголовка внутри файла." #: src/reuse/cli/annotate.py:430 msgid "Write a .license file to files with unrecognised comment styles." msgstr "Запись файла .license в файлы с нераспознанными стилями комментариев." #: src/reuse/cli/annotate.py:437 msgid "Skip files with unrecognised comment styles." msgstr "Пропуск файлов с нераспознанными стилями комментариев." #: src/reuse/cli/annotate.py:448 msgid "Skip files that already contain REUSE information." msgstr "Пропустить файлы, которые уже содержат информацию REUSE." #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:453 #, fuzzy msgid "PATH" msgstr "PATH" #: src/reuse/cli/annotate.py:510 #, python-brace-format msgid "'{path}' is a binary, therefore using '{new_path}' for the header" msgstr "" "'{path}' - двоичный файл, поэтому для заголовка используется '{new_path}'" #: src/reuse/cli/supported_licenses.py:19 msgid "List all licenses on the SPDX License List." msgstr "Перечислите все лицензии в списке лицензий SPDX." #: src/reuse/global_licensing.py:92 #, 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:106 #, 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:118 #, python-brace-format msgid "{attr_name} must not be empty." msgstr "{attr_name} не должно быть пустым." #: src/reuse/global_licensing.py:142 #, 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:166 #, python-brace-format msgid "" "The value of 'precedence' must be one of {precedence_vals} (got {received})" msgstr "" "Значение '\"Привилегия\" должно быть одним из {precedence_vals} (получено " "{received})" #: src/reuse/global_licensing.py:219 #, fuzzy, python-brace-format msgid "Could not parse '{notice}'" msgstr "Не удалось разобрать '{expression}'" #: src/reuse/_annotate.py:94 #, python-brace-format msgid "Skipped unrecognised file '{path}'" msgstr "Пропущен нераспознанный файл '{path}'" #: src/reuse/_annotate.py:100 #, python-brace-format msgid "'{path}' is not recognised; creating '{path}.license'" msgstr "'{path}' не распознан; создаем '{path}. лицензия'" #: src/reuse/_annotate.py:116 #, python-brace-format msgid "Skipped file '{path}' already containing REUSE information" msgstr "Пропущенный файл '{path}' уже содержит информацию о REUSE" #: src/reuse/_annotate.py:145 #, python-brace-format msgid "Error: Could not create comment for '{path}'" msgstr "Ошибка: Не удалось создать комментарий для '{path}'" #: src/reuse/_annotate.py:152 #, 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:163 #, python-brace-format msgid "Successfully changed header of {path}" msgstr "Успешно изменен заголовок {path}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:162 msgid "Repeat for confirmation" msgstr "Повторить для подтверждения" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:178 msgid "Error: The value you entered was invalid." msgstr "Ошибка: Введенное значение недействительно." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:180 #, python-brace-format msgid "Error: {e.message}" msgstr "Ошибка: {e.message}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:191 msgid "Error: The two entered values do not match." msgstr "Ошибка: Два введенных значения не совпадают." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:247 msgid "Error: invalid input" msgstr "Ошибка: недопустимый ввод" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:866 msgid "Press any key to continue..." msgstr "Нажмите любую клавишу, чтобы продолжить..." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:332 #, python-brace-format msgid "" "Choose from:\n" "\t{choices}" msgstr "" "Выберите из:\n" "{choices}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:369 msgid "{value!r} is not {choice}." msgid_plural "{value!r} is not one of {choices}." msgstr[0] "{value!r} не является {choice}." msgstr[1] "{value!r} не является одним из {choices}." msgstr[2] "{value!r} не является одним из {choices}." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:460 msgid "{value!r} does not match the format {format}." msgid_plural "{value!r} does not match the formats {formats}." msgstr[0] "{value!r} не соответствует формату {format}." msgstr[1] "{value!r} не соответствует форматам {formats}." msgstr[2] "{ value!r} не соответствует форматам {formats}." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:482 msgid "{value!r} is not a valid {number_type}." msgstr "{value!r} не является допустимым {number_type}." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:538 #, python-brace-format msgid "{value} is not in the range {range}." msgstr "{value} не входит в диапазон {range}." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:719 #, fuzzy msgid "{value!r} is not a valid boolean. Recognized values: {states}" msgstr "{value!r} не является допустимым булевым числом." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:747 msgid "{value!r} is not a valid UUID." msgstr "{value!r} не является действительным UUID." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:937 msgid "file" msgstr "файл" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:939 msgid "directory" msgstr "каталог" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:941 #, fuzzy msgid "path" msgstr "path" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:988 msgid "{name} {filename!r} does not exist." msgstr "{name} {filename!r} не существует." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:997 msgid "{name} {filename!r} is a file." msgstr "{name}filename!r} - это файл." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:1005 #, fuzzy msgid "{name} {filename!r} is a directory." msgstr "{name} '{filename}' - это каталог." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:1014 msgid "{name} {filename!r} is not readable." msgstr "{name}filename!r} не читается." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:1023 msgid "{name} {filename!r} is not writable." msgstr "{name}filename!r} не является критичной." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:1032 msgid "{name} {filename!r} is not executable." msgstr "{name}filename!r} не подлежит исполнению." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:1099 #, python-brace-format msgid "{len_type} values are required, but {len_value} was given." msgid_plural "{len_type} values are required, but {len_value} were given." msgstr[0] "Требуется значение {len_type}, но было указано {len_value}." msgstr[1] "Требуется значение {len_type}, но было указано {len_value}." msgstr[2] "{len_type} значения необходимы, но {len_value} были даны." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/shell_completion.py:332 msgid "Shell completion is not supported for Bash versions older than 4.4." msgstr "Завершение оболочки не поддерживается для версий Bash старше 4.4." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/shell_completion.py:339 msgid "Couldn't detect Bash version, shell completion is not supported." msgstr "" "Не удалось определить версию Bash, завершение оболочки не поддерживается." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:50 #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:89 #, python-brace-format msgid "Error: {message}" msgstr "Ошибка: {message}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:81 #, python-brace-format msgid "Try '{command} {option}' for help." msgstr "Попробуйте '{command} {option}' для помощи." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:130 #, python-brace-format msgid "Invalid value: {message}" msgstr "Неверное значение: {message}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:132 #, python-brace-format msgid "Invalid value for {param_hint}: {message}" msgstr "Недопустимое значение для {param_hint}: {message}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:190 msgid "Missing argument" msgstr "Отсутствующий аргумент" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:192 msgid "Missing option" msgstr "Отсутствующая опция" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:194 msgid "Missing parameter" msgstr "Отсутствующий параметр" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:196 #, python-brace-format msgid "Missing {param_type}" msgstr "Отсутствует {param_type}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:203 #, python-brace-format msgid "Missing parameter: {param_name}" msgstr "Пропущенный параметр: {param_name}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:223 #, python-brace-format msgid "No such option: {name}" msgstr "Нет такой опции: {name}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:235 #, python-brace-format msgid "Did you mean {possibility}?" msgid_plural "(Possible options: {possibilities})" msgstr[0] "Вы имели в виду {possibility}?" msgstr[1] "(Возможных вариантов: {possibilities})" msgstr[2] "(Возможных вариантов: {possibilities})" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:282 msgid "unknown error" msgstr "неизвестная ошибка" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:289 msgid "Could not open file {filename!r}: {message}" msgstr "Не удалось открыть файл {filename!r}: {message}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1104 #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1141 #, python-brace-format msgid "{text} {deprecated_message}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1160 msgid "Options" msgstr "Параметры" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1222 #, python-brace-format msgid "Got unexpected extra argument ({args})" msgid_plural "Got unexpected extra arguments ({args})" msgstr[0] "Получен неожиданный дополнительный аргумент ({args})" msgstr[1] "Получили неожиданных дополнительных аргументов ({args})" msgstr[2] "Получили неожиданных дополнительных аргументов ({args})" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1241 #, fuzzy msgid "DeprecationWarning: The command {name!r} is deprecated.{extra_message}" msgstr "DeprecationWarning: Команда {name!r} устарела." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1425 msgid "Aborted!" msgstr "Прервано!" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1799 msgid "Commands" msgstr "Команды" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1830 msgid "Missing command." msgstr "Отсутствующая команда." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1908 msgid "No such command {name!r}." msgstr "Нет такой команды {name!r}." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:2332 msgid "Value must be an iterable." msgstr "Значение должно быть итерируемым." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:2355 #, python-brace-format msgid "Takes {nargs} values but 1 was given." msgid_plural "Takes {nargs} values but {len} were given." msgstr[0] "Принимает значения {nargs}, но было задано 1." msgstr[1] "Принимает значения {nargs}, но было задано {len}." msgstr[2] "Принимает значений {nargs}, но было задано {len}." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:2505 #, fuzzy msgid "" "DeprecationWarning: The {param_type} {name!r} is deprecated.{extra_message}" msgstr "DeprecationWarning: Команда {name!r} устарела." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:2956 #, fuzzy, python-brace-format msgid "env var: {var}" msgstr "env var: {var}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:2959 #, python-brace-format msgid "default: {default}" msgstr "по умолчанию: {default}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:3023 msgid "(dynamic)" msgstr "(динамика)" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/parser.py:199 msgid "Argument {name!r} takes {nargs} values." msgstr "Аргумент {name!r} принимает значения {nargs}." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/parser.py:381 msgid "Option {name!r} does not take a value." msgstr "Опция {name!r} не принимает значения." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/parser.py:444 msgid "Option {name!r} requires an argument." msgid_plural "Option {name!r} requires {nargs} arguments." msgstr[0] "Опция {name!r} требует аргумента." msgstr[1] "Опция {name!r} требует аргументов {nargs}." msgstr[2] "Опция {name!r} требует аргументов {nargs}." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/_termui_impl.py:608 #, python-brace-format msgid "{editor}: Editing failed" msgstr "{editor}: Редактирование не удалось" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/_termui_impl.py:612 #, python-brace-format msgid "{editor}: Editing failed: {e}" msgstr "{editor}: Редактирование не удалось: {e}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/decorators.py:522 msgid "Show the version and exit." msgstr "Показать версию и выйти." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/decorators.py:548 msgid "Show this message and exit." msgstr "Покажите это сообщение и выйдите." #, python-brace-format #~ msgid "{path}: read error\n" #~ msgstr "{path}: ошибка чтения\n" #, python-brace-format #~ msgid "{lic_path}: deprecated license\n" #~ msgstr "{lic_path}: устаревшая лицензия\n" #, python-brace-format #~ msgid "{lic_path}: license without file extension\n" #~ msgstr "{lic_path}: лицензия без расширения файла\n" #, python-brace-format #~ msgid "{lic_path}: unused license\n" #~ msgstr "{lic_path}: неиспользуемая лицензия\n" #, python-brace-format #~ msgid "" #~ "'{path}' holds an SPDX expression that cannot be parsed, skipping the file" #~ msgstr "" #~ "'{path}' содержит выражение SPDX, которое не может быть разобрано, что " #~ "приводит к пропуску файла" #, python-brace-format #~ msgid "Could not parse '{expression}'" #~ msgstr "Не удалось разобрать '{expression}'" #, python-brace-format #~ msgid "(Deprecated) {text}" #~ msgstr "(Исправлено) {text}" #~ msgid "required" #~ msgstr "требуется" #~ msgid "Year of copyright statement." #~ msgstr "Год утверждения авторских прав." #, python-brace-format #~ msgid "determining identifier of '{path}'" #~ msgstr "определяющий идентификатор '{path}'" #~ msgid "--skip-unrecognised has no effect when used together with --style" #~ msgstr "" #~ "--skip-unrecognised не имеет эффекта, если используется вместе с --style" #~ msgid "can't write to '{}'" #~ msgstr "Невозможно записать в '{}'" #~ msgid "show program's version number and exit" #~ 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." #~ msgstr "" #~ "Добавление авторских прав и лицензий в заголовок одного или нескольких " #~ "файлов.\n" #~ "\n" #~ "Используя команды --copyright и --license, вы можете указать, какие " #~ "авторские права и лицензии следует добавить в заголовки заданных файлов.\n" #~ "\n" #~ "Используя команду --contributor, вы можете указать людей или организации, " #~ "которые внесли свой вклад, но не являются владельцами авторских прав на " #~ "данные файлы." #~ msgid "download a license and place it in the LICENSES/ directory" #~ msgstr "загрузите лицензию и поместите ее в каталог LICENSES/" #~ msgid "list all non-compliant files" #~ msgstr "список всех файлов, не соответствующих требованиям" #, fuzzy, 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 there any deprecated licenses in the project?\n" #~ "\n" #~ "- Are there any license files in the LICENSES/ directory without file " #~ "extension?\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" #~ "- Are there any read errors?\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" #~ "- Все ли файлы содержат достоверную информацию об авторских правах и " #~ "лицензировании?" #~ msgid "print the project's bill of materials in SPDX format" #~ msgstr "распечатать ведомость материалов проекта в формате SPDX" #~ msgid "convert .reuse/dep5 to REUSE.toml" #~ msgstr "Преобразование .reuse/dep5 в REUSE.toml" #~ msgid "'{}' is not a file" #~ msgstr "'{}' не является файлом" #~ msgid "can't open '{}'" #~ msgstr "Невозможно открыть '{}'" #~ msgid "can't write to directory '{}'" #~ msgstr "Невозможно записать в каталог '{}'" #~ msgid "can't read or write '{}'" #~ msgstr "Невозможно прочитать или записать '{}'" #~ msgid "SPDX License Identifier of license" #~ msgstr "Лицензия SPDX Идентификатор лицензии" #~ msgid "--output has no effect when used together with --all" #~ msgstr "--output не имеет эффекта, если используется вместе с --all" #~ msgid "the following arguments are required: license" #~ msgstr "необходимы следующие аргументы: лицензия" #~ msgid "usage: " #~ msgstr "использование: " #~ msgid ".__call__() not defined" #~ msgstr ".__call__() не определено" #, python-format #~ msgid "unknown parser %(parser_name)r (choices: %(choices)s)" #~ msgstr "" #~ "неизвестный синтаксический анализатор %(parser_name)r (варианты: " #~ "%(choices)s)" #, python-format #~ msgid "argument \"-\" with mode %r" #~ msgstr "аргумент \"-\" с режимом %r" #, python-format #~ msgid "can't open '%(filename)s': %(error)s" #~ msgstr "Невозможно открыть '%(filename)s': %(error)s" #, python-format #~ msgid "cannot merge actions - two groups are named %r" #~ msgstr "Невозможно объединить действия - две группы названы %r" #~ msgid "'required' is an invalid argument for positionals" #~ msgstr "'\"Обязательный\" - недопустимый аргумент для позиционирования" #, python-format #~ msgid "" #~ "invalid option string %(option)r: must start with a character " #~ "%(prefix_chars)r" #~ msgstr "" #~ "Недопустимая строка опций %(option)r: должна начинаться с символа " #~ "%(prefix_chars)r" #, python-format #~ msgid "dest= is required for options like %r" #~ msgstr "dest= требуется для опций типа %r" #, python-format #~ msgid "invalid conflict_resolution value: %r" #~ msgstr "Недопустимое значение конфликтного_разрешения: %r" #, python-format #~ msgid "conflicting option string: %s" #~ msgid_plural "conflicting option strings: %s" #~ msgstr[0] "" #~ "одна,двадцать одна,тридцать одна,сорок одна,пятьдесят одна,шестьдесят " #~ "одна,семьдесят одна,восемдесят одна,девяносто одна, сто одна " #~ "противоречащая строка опций: %s" #~ msgstr[1] "" #~ "две,три,четыре,двадцать две,двадцать три,двадцать четыре,тридцать две," #~ "тридцать три,тридцать четыре,сорок две конфликтующих строк опций: %s" #~ msgstr[2] "" #~ "ноль,пять,шесть,семь,восемь,девять,десять,одинадцать,двенадцать," #~ "тринадцать конфликтующих строк опций: %s" #~ msgid "mutually exclusive arguments must be optional" #~ msgstr "взаимоисключающие аргументы должны быть необязательными" #~ msgid "cannot have multiple subparser arguments" #~ msgstr "не может иметь несколько аргументов подпарсера" #, python-format #~ msgid "unrecognized arguments: %s" #~ msgstr "нераспознанные аргументы: %s" #, python-format #~ msgid "not allowed with argument %s" #~ msgstr "не разрешено с аргументом %s" #, python-format #~ msgid "ignored explicit argument %r" #~ msgstr "проигнорирован явный аргумент %r" #, python-format #~ msgid "the following arguments are required: %s" #~ msgstr "требуются следующие аргументы: %s" #, python-format #~ msgid "one of the arguments %s is required" #~ msgstr "требуется один из аргументов %s" #~ msgid "expected at most one argument" #~ msgstr "ожидается не более одного аргумента" #~ msgid "expected at least one argument" #~ msgstr "ожидал по крайней мере один аргумент" #, python-format #~ msgid "expected %s argument" #~ msgid_plural "expected %s arguments" #~ msgstr[0] "" #~ "один,двадцать один,тридцать один,сорок один,пятьдесят один,шестьдесят " #~ "один,семдесят один,восемдесят один,девяносто один,сто один ожидаемый " #~ "аргумент %s" #~ msgstr[1] "" #~ "два,три,четыре,двадцать два,двадцать три,двадцать четыре,тридцать два," #~ "тридцать три,тридцать четыре,сорок два ожидаемых %s аргументов" #~ msgstr[2] "" #~ "ноль,пять,шесть,семь,восемь,девять,десять,одинадцать,двенадцать," #~ "тринадцать ожидаемых %s аргументов" #, python-format #~ msgid "ambiguous option: %(option)s could match %(matches)s" #~ msgstr "Неоднозначная опция: %(option)s может соответствовать %(matches)s" #, python-format #~ msgid "unexpected option string: %s" #~ msgstr "Неожиданная строка опции: %s" #, python-format #~ msgid "%r is not callable" #~ msgstr "%r не является вызываемым" #, python-format #~ msgid "invalid %(type)s value: %(value)r" #~ msgstr "Недопустимое значение %(type)s: %(value)r" #, python-format #~ msgid "invalid choice: %(value)r (choose from %(choices)s)" #~ msgstr "Неверный выбор: %(value)r (выберите из %(choices)s" #, python-brace-format #~ msgid "'{path}' could not be decoded as UTF-8." #~ msgstr "'{path}' не может быть декодирован как UTF-8." #, 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-6.2.0/po/de.po0000664000175000017500000016137615077707000013652 0ustar alexalex# 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: 2025-10-07 21:23+0000\n" "PO-Revision-Date: 2025-07-11 11:01+0000\n" "Last-Translator: Bonnie \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.13-dev\n" #: src/reuse/lint.py:40 #, fuzzy msgid "BAD LICENSES" msgstr "NICHT VERWENDETE LIZENZEN" #: src/reuse/lint.py:42 #, fuzzy msgid "The following licenses are not valid SPDX licenses:" msgstr "Die folgenden Lizenzen werden nicht benutzt:" #: src/reuse/lint.py:50 msgid "DEPRECATED LICENSES" msgstr "VERALTETE LIZENZEN" #: src/reuse/lint.py:52 msgid "The following licenses are deprecated by SPDX:" msgstr "Die folgenden Lizenzen wurden von SPDX als veraltetet gekennzeichnet:" #: src/reuse/lint.py:60 msgid "LICENSES WITHOUT FILE EXTENSION" msgstr "LIZENZEN OHNE DATEIENDUNG" #: src/reuse/lint.py:62 msgid "The following licenses have no file extension:" msgstr "Die folgenden Lizenzen haben keine Dateiendung:" #: src/reuse/lint.py:70 msgid "MISSING LICENSES" msgstr "FEHLENDE LIZENZEN" #: src/reuse/lint.py:72 msgid "'{}' found in:" msgstr "'{}' gefunden in:" #: src/reuse/lint.py:79 msgid "UNUSED LICENSES" msgstr "NICHT VERWENDETE LIZENZEN" #: src/reuse/lint.py:80 msgid "The following licenses are not used:" msgstr "Die folgenden Lizenzen werden nicht benutzt:" #: src/reuse/lint.py:87 msgid "READ ERRORS" msgstr "LESEFEHLER" #: src/reuse/lint.py:88 msgid "Could not read:" msgstr "Unlesbar:" #: src/reuse/lint.py:94 msgid "INVALID SPDX LICENSE EXPRESSIONS" msgstr "" #: src/reuse/lint.py:99 #, fuzzy msgid "'{}' contains invalid SPDX License Expressions:" msgstr "'{}' ist kein gültiger SPDX-Ausdruck, breche ab" #: src/reuse/lint.py:124 msgid "MISSING COPYRIGHT AND LICENSING INFORMATION" msgstr "FEHLENDE URHEBERRECHTS- UND LIZENZINFORMATIONEN" #: src/reuse/lint.py:130 #, fuzzy msgid "The following files have no copyright and licensing information:" msgstr "Die folgenden Dateien haben keine Urheberrechtsinformationen:" #: src/reuse/lint.py:141 msgid "The following files have no copyright information:" msgstr "Die folgenden Dateien haben keine Urheberrechtsinformationen:" #: src/reuse/lint.py:150 msgid "The following files have no licensing information:" msgstr "Die folgenden Dateien haben keine Lizenzinformationen:" #: src/reuse/lint.py:157 msgid "SUMMARY" msgstr "ZUSAMMENFASSUNG" #: src/reuse/lint.py:162 msgid "Bad licenses:" msgstr "Falsche Lizenzen:" #: src/reuse/lint.py:163 msgid "Deprecated licenses:" msgstr "Veraltete Lizenzen:" #: src/reuse/lint.py:166 msgid "Licenses without file extension:" msgstr "Lizenzen ohne Dateiendung:" #: src/reuse/lint.py:169 msgid "Missing licenses:" msgstr "Fehlende Lizenzen:" #: src/reuse/lint.py:170 msgid "Unused licenses:" msgstr "Unbenutzte Lizenzen:" #: src/reuse/lint.py:171 msgid "Used licenses:" msgstr "Verwendete Lizenzen:" #: src/reuse/lint.py:172 msgid "Read errors:" msgstr "Lesefehler:" #: src/reuse/lint.py:173 #, fuzzy msgid "Invalid SPDX License Expressions:" msgstr "'{}' ist kein gültiger SPDX-Ausdruck, breche ab" #: src/reuse/lint.py:183 #, fuzzy msgid "Files with copyright information:" msgstr "Dateien mit Urheberrechtsinformationen:" #: src/reuse/lint.py:187 #, fuzzy msgid "Files with license information:" msgstr "Dateien mit Lizenzinformationen:" #: src/reuse/lint.py:204 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:211 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:218 msgid "RECOMMENDATIONS" msgstr "EMPFEHLUNGEN" #: src/reuse/lint.py:286 #, fuzzy, python-brace-format msgid "missing license '{lic}'" msgstr "'{}' ist kein gültiger SPDX-Lizenz-Identifikator." #: src/reuse/lint.py:291 #, fuzzy msgid "read error" msgstr "Lesefehler:" #: src/reuse/lint.py:296 #, fuzzy, python-brace-format msgid "invalid SPDX License Expression '{expression}'" msgstr "'{}' ist kein gültiger SPDX-Ausdruck, breche ab" #: src/reuse/lint.py:303 #, fuzzy msgid "no license identifier" msgstr "'{}' ist kein gültiger SPDX-Lizenz-Identifikator." #: src/reuse/lint.py:307 #, fuzzy msgid "no copyright notice" msgstr "'{}' ist kein gültiger SPDX-Lizenz-Identifikator." #: src/reuse/lint.py:345 #, fuzzy, python-brace-format msgid "bad license '{lic}'" msgstr "Unbenutzte Lizenzen:" #: src/reuse/lint.py:350 #, fuzzy msgid "deprecated license" msgstr "Veraltete Lizenzen:" #: src/reuse/lint.py:355 #, fuzzy msgid "license without file extension" msgstr "Lizenzen ohne Dateiendung:" #: src/reuse/lint.py:360 #, fuzzy msgid "unused license" msgstr "Unbenutzte Lizenzen:" #: src/reuse/project.py:253 #, fuzzy, python-brace-format msgid "'{path}' covered by {global_path}" msgstr "'{path}' abgedeckt durch .reuse/dep5" #: src/reuse/project.py:261 #, python-brace-format msgid "" "'{path}' is covered exclusively by REUSE.toml. Not reading the file contents." 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:355 #, 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:419 #, python-brace-format msgid "{path} does not have a file extension" msgstr "{path} hat keine Dateiendung" #: src/reuse/project.py:429 #, 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:441 #, 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:480 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/extract.py:49 #, python-brace-format msgid "" "REUSE_ENCODING_MODULE must have a value in {modules}; it has '{env_module}'. " "Aborting." msgstr "" #: src/reuse/extract.py:69 msgid "" "No supported module that can detect the encoding of files could be " "successfully imported. Re-read the installation instructions for the reuse " "package, or try the following:" msgstr "" #: src/reuse/extract.py:75 msgid "" "- If you are running a Linux distribution, try your equivalent of `apt " "install file` or `dnf install file`." msgstr "" #: src/reuse/extract.py:80 msgid "" "- Run ` pipx install reuse[charset-normalizer]`. Replace 'pipx' with 'pip' " "if you are not using pipx." msgstr "" #: src/reuse/extract.py:451 #, 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/extract.py:462 #, python-brace-format msgid "" "extracting REUSE information from '{path}' (encoding {encoding}, encoding " "module {module}, newline {newline})" msgstr "" #: src/reuse/header.py:87 msgid "generated comment is missing copyright lines or license expressions" msgstr "" "Dem generierten Kommentar fehlen Zeilen zum Urheberrecht oder Lizenzausdrücke" #: src/reuse/report.py:160 #, python-brace-format msgid "Could not read '{path}'" msgstr "Konnte '{path}' nicht lesen" #: src/reuse/report.py:165 #, python-brace-format msgid "Unexpected error occurred while parsing '{path}'" msgstr "Unerwarteter Fehler beim Parsen von '{path}' aufgetreten" #: src/reuse/report.py:521 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:532 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:543 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:552 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:564 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:575 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:584 msgid "" "Fix invalid SPDX License Expressions: In one or more files there are SPDX " "License Expressions which cannot be parse. Check whether the value that " "follows 'SPDX-License-Identifier:' is correct. If the detected expression is " "not meant to be valid, put it between 'REUSE-IgnoreStart' and 'REUSE-" "IgnoreEnd' comments." msgstr "" #: src/reuse/report.py:595 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 "" "Korrigiere fehlende Copyright-/Lizenzinformationen: In einer oder mehreren " "Dateien fehlen Copyright- und/oder Lizenzinformationen. Typischerweise kann " "das korrigiert werden, indem die 'SPDX-FileCopyrightText'- und 'SPDX-License-" "Identifier'-Tags den Dateien hinzugefügt werden. Das Tutorial erklärt " "weitere Wege das zu erreichen: " #: src/reuse/cli/lint.py:28 #, python-brace-format msgid "" "Lint the project directory for REUSE compliance. This version of the tool " "checks against version {reuse_version} of the REUSE Specification. You can " "find the latest version of the specification at ." msgstr "" #: src/reuse/cli/lint.py:34 msgid "Specifically, the following criteria are checked:" msgstr "" #: src/reuse/cli/lint.py:38 msgid "" "- Are there any bad (unrecognised, not compliant with SPDX) licenses in the " "project?" msgstr "" #: src/reuse/cli/lint.py:43 #, fuzzy msgid "- Are there any deprecated licenses in the project?" msgstr "Was ist die Internetadresse des Projekts?" #: src/reuse/cli/lint.py:47 msgid "" "- Are there any license files in the LICENSES/ directory without file " "extension?" msgstr "" #: src/reuse/cli/lint.py:54 msgid "" "- Are any licenses referred to inside of the project, but not included in " "the LICENSES/ directory?" msgstr "" #: src/reuse/cli/lint.py:61 msgid "" "- Are any licenses included in the LICENSES/ directory that are not used " "inside of the project?" msgstr "" #: src/reuse/cli/lint.py:66 msgid "- Are there any read errors?" msgstr "" #: src/reuse/cli/lint.py:69 #, fuzzy msgid "- Do all files have valid copyright and licensing information?" msgstr "" "Die folgenden Dateien haben keine Urheberrechts- und Lizenzinformationen:" #: src/reuse/cli/lint.py:81 src/reuse/cli/lint_file.py:38 #, fuzzy msgid "Prevent output." msgstr "Verhindert Ausgabe" #: src/reuse/cli/lint.py:89 src/reuse/cli/supported_licenses.py:28 #, fuzzy msgid "Format output as JSON." msgstr "formatiert Ausgabe als JSON" #: src/reuse/cli/lint.py:97 #, fuzzy msgid "Format output as plain text. (default)" msgstr "formatiert Ausgabe als rohen Text" #: src/reuse/cli/lint.py:105 #, fuzzy msgid "Format output as errors per line." msgstr "formatiert Ausgabe als rohen Text" #: src/reuse/cli/convert_dep5.py:19 msgid "" "Convert .reuse/dep5 into a REUSE.toml file. The generated file is placed in " "the project root and is semantically identical. The .reuse/dep5 file is " "subsequently deleted." msgstr "" #: src/reuse/cli/convert_dep5.py:31 #, fuzzy msgid "No '.reuse/dep5' file." msgstr "Erstelle .reuse/dep5" #: src/reuse/cli/lint_file.py:25 msgid "" "Lint individual files for REUSE compliance. The specified FILEs are checked " "for the presence of copyright and licensing information, and whether the " "found licenses are included in the LICENSES/ directory." msgstr "" #: src/reuse/cli/lint_file.py:46 #, fuzzy msgid "Format output as errors per line. (default)" msgstr "formatiert Ausgabe als rohen Text" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/lint_file.py:51 msgid "FILE" msgstr "" #: src/reuse/cli/lint_file.py:65 #, python-brace-format msgid "'{file}' is not inside of '{root}'." msgstr "" #: src/reuse/cli/spdx.py:22 #, fuzzy msgid "Generate an SPDX bill of materials." msgstr "Komponentenliste im SPDX-Format ausgeben" #: src/reuse/cli/spdx.py:32 msgid "File to write to." msgstr "" #: src/reuse/cli/spdx.py:38 msgid "" "Populate the LicenseConcluded field; note that reuse cannot guarantee that " "the field is accurate." msgstr "" #: src/reuse/cli/spdx.py:50 msgid "Name of the person signing off on the SPDX report." msgstr "" #: src/reuse/cli/spdx.py:54 msgid "Name of the organization signing off on the SPDX report." msgstr "" #: src/reuse/cli/spdx.py:81 msgid "" "'--creator-person' or '--creator-organization' is required when '--add-" "license-concluded' is provided." msgstr "" #: src/reuse/cli/spdx.py:96 #, 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 "" #: src/reuse/cli/main.py:36 #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/decorators.py:465 #, fuzzy, python-format msgid "%(prog)s, version %(version)s" msgstr "%(prog)s: Fehler: %(message)s\n" #: src/reuse/cli/main.py:39 msgid "" "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." msgstr "" #: src/reuse/cli/main.py:46 msgid "" "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." msgstr "" #: src/reuse/cli/main.py:53 msgid "" "You should have received a copy of the GNU General Public License along with " "this program. If not, see ." msgstr "" #: src/reuse/cli/main.py:61 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/cli/main.py:68 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/cli/main.py:72 msgid "Support the FSFE's work:" msgstr "Die Arbeit der FSFE unterstützen:" #: src/reuse/cli/main.py:77 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/cli/main.py:88 #, fuzzy msgid "Enable debug statements." msgstr "Debug-Statements aktivieren" #: src/reuse/cli/main.py:93 #, fuzzy msgid "Hide deprecation warnings." msgstr "„Veraltet“-Warnung verbergen" #: src/reuse/cli/main.py:98 #, fuzzy msgid "Do not skip over Git submodules." msgstr "Git-Submodules nicht überspringen" #: src/reuse/cli/main.py:103 #, fuzzy msgid "Do not skip over Meson subprojects." msgstr "Meson-Teilprojekte nicht überspringen" #: src/reuse/cli/main.py:108 #, fuzzy msgid "Do not use multiprocessing." msgstr "kein Multiprocessing verwenden" #: src/reuse/cli/main.py:118 #, fuzzy msgid "Define root of project." msgstr "Stammverzeichnis des Projekts bestimmen" #: src/reuse/cli/common.py:51 #, 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/cli/common.py:87 #, python-brace-format msgid "'{name}' is mutually exclusive with: {opts}" msgstr "" #: src/reuse/cli/common.py:103 #, fuzzy msgid "'{}' is not a valid SPDX expression." msgstr "'{}' ist kein gültiger SPDX-Ausdruck, breche ab" #: src/reuse/cli/download.py:54 msgid "'{}' is not a valid SPDX License Identifier." msgstr "'{}' ist kein gültiger SPDX-Lizenz-Identifikator." #: src/reuse/cli/download.py:61 #, fuzzy msgid "Did you mean:" msgstr "Meinten Sie:" #: src/reuse/cli/download.py:68 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/cli/download.py:77 #, python-brace-format msgid "Error: {spdx_identifier} already exists." msgstr "Fehler: {spdx_identifier} existiert bereits." #: src/reuse/cli/download.py:84 #, fuzzy, python-brace-format msgid "Error: {path} does not exist." msgstr "Fehler: {path} existiert nicht." #: src/reuse/cli/download.py:88 msgid "Error: Failed to download license." msgstr "Fehler: Lizenz konnte nicht heruntergeladen werden." #: src/reuse/cli/download.py:93 msgid "Is your internet connection working?" msgstr "Funktioniert Ihre Internetverbindung?" #: src/reuse/cli/download.py:98 #, python-brace-format msgid "Successfully downloaded {spdx_identifier}." msgstr "{spdx_identifier} erfolgreich heruntergeladen." #: src/reuse/cli/download.py:108 #, 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/cli/download.py:111 msgid "" "LICENSE must be a valid SPDX License Identifier. You may specify LICENSE " "multiple times to download multiple licenses." msgstr "" #: src/reuse/cli/download.py:124 #, fuzzy msgid "Download all missing licenses detected in the project." msgstr "lade alle fehlenden Lizenzen herunter, die im Projekt gefunden wurden" #: src/reuse/cli/download.py:132 msgid "Path to download to." msgstr "" #: src/reuse/cli/download.py:138 msgid "" "Source from which to copy custom LicenseRef- licenses, either a directory " "that contains the file or the file itself." msgstr "" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/download.py:145 #, fuzzy msgid "LICENSE" msgstr "FALSCHE LIZENZEN" #: src/reuse/cli/download.py:161 #, fuzzy msgid "The 'LICENSE' argument and '--all' option are mutually exclusive." msgstr "" "Die Optionen --single-line und --multi-line schließen sich gegenseitig aus" #: src/reuse/cli/download.py:173 #, fuzzy msgid "Cannot use '--output' with more than one license." msgstr "Kann --output nicht mit mehr als einer Lizenz verwenden" #: src/reuse/cli/annotate.py:66 msgid "Option '--copyright', '--license', or '--contributor' is required." msgstr "" "Option ‚--copyright‘, ‚--license‘ oder ‚--contributor‘ ist erforderlich." #: src/reuse/cli/annotate.py:127 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}' Die folgenden Dateien haben keine erkannte Dateiendung. Bitte " "verwenden Sie --style, ' --explicit-license', oder '--Überspringen-nicht-" "erkannt'" #: src/reuse/cli/annotate.py:160 #, python-brace-format msgid "" "'{path}' does not support single-line comments, please do not use '--single-" "line'." msgstr "" #: src/reuse/cli/annotate.py:167 #, python-brace-format msgid "" "'{path}' does not support multi-line comments, please do not use '--multi-" "line'." msgstr "" #: src/reuse/cli/annotate.py:213 #, python-brace-format msgid "Template '{template}' could not be found." msgstr "Vorlage ‚{template}‘ konnte nicht gefunden werden." #: src/reuse/cli/annotate.py:236 #, fuzzy, python-brace-format msgid "'{year}' is not a valid year range." msgstr "'{}' ist kein gültiger SPDX-Ausdruck, breche ab" #: src/reuse/cli/annotate.py:245 #, python-brace-format msgid "" "Your operating system's year is set to '{year}'. This is not four digits, " "and not supported." msgstr "" #: src/reuse/cli/annotate.py:287 #, fuzzy msgid "Add copyright and licensing into the headers of files." msgstr "" "schreibe Urheberrechts- und Lizenzinformationen in die Kopfzeilen von Dateien" #: src/reuse/cli/annotate.py:290 msgid "" "By using --copyright and --license, you can specify which copyright holders " "and licenses to add to the headers of the given files." msgstr "" #: src/reuse/cli/annotate.py:296 msgid "" "By using --contributor, you can specify people or entity that contributed " "but are not copyright holder of the given files." msgstr "" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:309 msgid "COPYRIGHT" msgstr "" #: src/reuse/cli/annotate.py:312 #, fuzzy msgid "Copyright holder, repeatable." msgstr "Urheberrechtsinformation, wiederholbar" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:319 msgid "SPDX_IDENTIFIER" msgstr "" #: src/reuse/cli/annotate.py:322 #, fuzzy msgid "SPDX License Identifier, repeatable." msgstr "SPDX-Lizenz-Identifikator, wiederholbar" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:328 msgid "CONTRIBUTOR" msgstr "" #: src/reuse/cli/annotate.py:331 #, fuzzy msgid "File contributor, repeatable." msgstr "Dateimitwirkender, wiederholbar" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:338 msgid "YEAR" msgstr "" #: src/reuse/cli/annotate.py:343 msgid "" "Year of copyright notice. You may define multiple years or a range of years." msgstr "" #: src/reuse/cli/annotate.py:353 #, fuzzy msgid "Comment style to use." msgstr "zu benutzender Kommentarstil, optional" #: src/reuse/cli/annotate.py:363 #, fuzzy msgid "Copyright prefix to use." msgstr "zu benutzender Kommentarstil, optional" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:375 msgid "TEMPLATE" msgstr "" #: src/reuse/cli/annotate.py:377 #, fuzzy msgid "Name of template to use." msgstr "Name der zu verwendenden Vorlage, optional" #: src/reuse/cli/annotate.py:384 #, fuzzy msgid "Do not include year in copyright notice." msgstr "füge kein Jahr in Angabe hinzu" #: src/reuse/cli/annotate.py:390 #, fuzzy msgid "Merge copyright notices if they are identical except for their years." msgstr "Jahr der Urheberrechtsinformation, optional" #: src/reuse/cli/annotate.py:398 #, fuzzy msgid "Force single-line comment style." msgstr "zu benutzender Kommentarstil, optional" #: src/reuse/cli/annotate.py:405 #, fuzzy msgid "Force multi-line comment style." msgstr "zu benutzender Kommentarstil, optional" #: src/reuse/cli/annotate.py:411 msgid "Add headers to all files under specified directories recursively." msgstr "" #: src/reuse/cli/annotate.py:416 msgid "Do not replace the first header in the file; just add a new one." msgstr "" #: src/reuse/cli/annotate.py:423 msgid "Always write a .license file instead of a header inside the file." msgstr "" #: src/reuse/cli/annotate.py:430 msgid "Write a .license file to files with unrecognised comment styles." msgstr "" #: src/reuse/cli/annotate.py:437 msgid "Skip files with unrecognised comment styles." msgstr "" #: src/reuse/cli/annotate.py:448 #, fuzzy msgid "Skip files that already contain REUSE information." msgstr "Dateien mit Lizenzinformationen:" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:453 msgid "PATH" msgstr "" #: src/reuse/cli/annotate.py:510 #, 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/cli/supported_licenses.py:19 #, fuzzy msgid "List all licenses on the SPDX License List." msgstr "Listet alle unterstützten SPDX-Lizenzen auf" #: src/reuse/global_licensing.py:92 #, python-brace-format msgid "" "{attr_name} must be a {type_name} (got {value} that is a {value_class})." msgstr "" #: src/reuse/global_licensing.py:106 #, 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:118 #, python-brace-format msgid "{attr_name} must not be empty." msgstr "" #: src/reuse/global_licensing.py:142 #, python-brace-format msgid "{name} must be a {type} (got {value} that is a {value_type})." msgstr "" #: src/reuse/global_licensing.py:166 #, python-brace-format msgid "" "The value of 'precedence' must be one of {precedence_vals} (got {received})" msgstr "" #: src/reuse/global_licensing.py:219 #, fuzzy, python-brace-format msgid "Could not parse '{notice}'" msgstr "Kann '{expression}' nicht parsen" #: src/reuse/_annotate.py:94 #, python-brace-format msgid "Skipped unrecognised file '{path}'" msgstr "" #: src/reuse/_annotate.py:100 #, python-brace-format msgid "'{path}' is not recognised; creating '{path}.license'" msgstr "" #: src/reuse/_annotate.py:116 #, fuzzy, python-brace-format msgid "Skipped file '{path}' already containing REUSE information" msgstr "Dateien mit Lizenzinformationen:" #: src/reuse/_annotate.py:145 #, python-brace-format msgid "Error: Could not create comment for '{path}'" msgstr "Fehler: Kann kein Kommentar für '{path}' erstellen" #: src/reuse/_annotate.py:152 #, 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:163 #, python-brace-format msgid "Successfully changed header of {path}" msgstr "Kopfzeilen von {path} erfolgreich geändert" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:162 msgid "Repeat for confirmation" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:178 msgid "Error: The value you entered was invalid." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:180 #, python-brace-format msgid "Error: {e.message}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:191 msgid "Error: The two entered values do not match." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:247 msgid "Error: invalid input" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:866 msgid "Press any key to continue..." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:332 #, python-brace-format msgid "" "Choose from:\n" "\t{choices}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:369 msgid "{value!r} is not {choice}." msgid_plural "{value!r} is not one of {choices}." msgstr[0] "" msgstr[1] "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:460 msgid "{value!r} does not match the format {format}." msgid_plural "{value!r} does not match the formats {formats}." msgstr[0] "" msgstr[1] "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:482 msgid "{value!r} is not a valid {number_type}." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:538 #, python-brace-format msgid "{value} is not in the range {range}." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:719 msgid "{value!r} is not a valid boolean. Recognized values: {states}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:747 msgid "{value!r} is not a valid UUID." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:937 msgid "file" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:939 msgid "directory" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:941 msgid "path" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:988 #, fuzzy msgid "{name} {filename!r} does not exist." msgstr "Fehler: {path} existiert nicht." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:997 msgid "{name} {filename!r} is a file." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:1005 #, fuzzy msgid "{name} {filename!r} is a directory." msgstr "'{}' ist kein Verzeichnis" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:1014 msgid "{name} {filename!r} is not readable." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:1023 msgid "{name} {filename!r} is not writable." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:1032 msgid "{name} {filename!r} is not executable." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:1099 #, python-brace-format msgid "{len_type} values are required, but {len_value} was given." msgid_plural "{len_type} values are required, but {len_value} were given." msgstr[0] "" msgstr[1] "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/shell_completion.py:332 msgid "Shell completion is not supported for Bash versions older than 4.4." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/shell_completion.py:339 msgid "Couldn't detect Bash version, shell completion is not supported." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:50 #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:89 #, python-brace-format msgid "Error: {message}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:81 #, python-brace-format msgid "Try '{command} {option}' for help." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:130 #, python-brace-format msgid "Invalid value: {message}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:132 #, python-brace-format msgid "Invalid value for {param_hint}: {message}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:190 #, fuzzy msgid "Missing argument" msgstr "Positions-Argumente" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:192 #, fuzzy msgid "Missing option" msgstr "Fehlende Lizenzen:" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:194 msgid "Missing parameter" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:196 #, python-brace-format msgid "Missing {param_type}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:203 #, python-brace-format msgid "Missing parameter: {param_name}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:223 #, python-brace-format msgid "No such option: {name}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:235 #, fuzzy, python-brace-format msgid "Did you mean {possibility}?" msgid_plural "(Possible options: {possibilities})" msgstr[0] "Meinten Sie:" msgstr[1] "Meinten Sie:" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:282 msgid "unknown error" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:289 msgid "Could not open file {filename!r}: {message}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1104 #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1141 #, python-brace-format msgid "{text} {deprecated_message}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1160 msgid "Options" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1222 #, fuzzy, python-brace-format msgid "Got unexpected extra argument ({args})" msgid_plural "Got unexpected extra arguments ({args})" msgstr[0] "erwartete ein Argument" msgstr[1] "erwartete ein Argument" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1241 msgid "DeprecationWarning: The command {name!r} is deprecated.{extra_message}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1425 msgid "Aborted!" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1799 #, fuzzy msgid "Commands" msgstr "Unterkommandos" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1830 #, fuzzy msgid "Missing command." msgstr "Fehlende Lizenzen:" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1908 msgid "No such command {name!r}." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:2332 msgid "Value must be an iterable." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:2355 #, python-brace-format msgid "Takes {nargs} values but 1 was given." msgid_plural "Takes {nargs} values but {len} were given." msgstr[0] "" msgstr[1] "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:2505 msgid "" "DeprecationWarning: The {param_type} {name!r} is deprecated.{extra_message}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:2956 #, python-brace-format msgid "env var: {var}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:2959 #, python-brace-format msgid "default: {default}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:3023 msgid "(dynamic)" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/parser.py:199 msgid "Argument {name!r} takes {nargs} values." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/parser.py:381 msgid "Option {name!r} does not take a value." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/parser.py:444 msgid "Option {name!r} requires an argument." msgid_plural "Option {name!r} requires {nargs} arguments." msgstr[0] "" msgstr[1] "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/_termui_impl.py:608 #, python-brace-format msgid "{editor}: Editing failed" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/_termui_impl.py:612 #, python-brace-format msgid "{editor}: Editing failed: {e}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/decorators.py:522 #, fuzzy msgid "Show the version and exit." msgstr "zeige diese Hilfsnachricht und beende" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/decorators.py:548 #, fuzzy msgid "Show this message and exit." msgstr "zeige diese Hilfsnachricht und beende" #, fuzzy, python-brace-format #~ msgid "{path}: read error\n" #~ msgstr "Veraltete Lizenzen:" #, fuzzy, python-brace-format #~ msgid "{lic_path}: deprecated license\n" #~ msgstr "Veraltete Lizenzen:" #, fuzzy, python-brace-format #~ msgid "{lic_path}: license without file extension\n" #~ msgstr "Lizenzen ohne Dateiendung:" #, fuzzy, python-brace-format #~ msgid "{lic_path}: unused license\n" #~ msgstr "Unbenutzte Lizenzen:" #, 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" #, python-brace-format #~ msgid "Could not parse '{expression}'" #~ msgstr "Kann '{expression}' nicht parsen" #, fuzzy, python-brace-format #~ msgid "(Deprecated) {text}" #~ msgstr "Veraltete Lizenzen:" #, fuzzy #~ msgid "Year of copyright statement." #~ msgstr "Jahr der Urheberrechtsinformation, optional" #, python-brace-format #~ msgid "determining identifier of '{path}'" #~ msgstr "erkenne Identifikator von '{path}'" #, fuzzy #~ msgid "--skip-unrecognised has no effect when used together with --style" #~ msgstr "--output hat keinen Effekt, wenn es zusammen mit --all benutzt wird" #~ msgid "can't write to '{}'" #~ msgstr "kann nicht in '{}' schreiben" #~ msgid "show program's version number and exit" #~ msgstr "zeige die Versionsnummer des Programms und beende" #~ msgid "download a license and place it in the LICENSES/ directory" #~ msgstr "lade eine Datei herunter und speichere sie im Verzeichnis LICENSES/" #~ msgid "list all non-compliant files" #~ msgstr "alle nicht-konformen Dateien zeigen" #, fuzzy, 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 there any deprecated licenses in the project?\n" #~ "\n" #~ "- Are there any license files in the LICENSES/ directory without file " #~ "extension?\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" #~ "- Are there any read errors?\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?" #~ msgid "print the project's bill of materials in SPDX format" #~ msgstr "Komponentenliste im SPDX-Format ausgeben" #~ msgid "'{}' is not a file" #~ msgstr "'{}' ist keine Datei" #~ msgid "can't open '{}'" #~ msgstr "kann '{}' nicht öffnen" #~ msgid "can't write to directory '{}'" #~ msgstr "kann nicht in Verzeichnis '{}' schreiben" #~ msgid "can't read or write '{}'" #~ msgstr "kann '{}' nicht lesen oder schreiben" #~ msgid "SPDX License Identifier of license" #~ msgstr "SPDX-Lizenz-Identifikator der Lizenz" #~ msgid "--output has no effect when used together with --all" #~ msgstr "--output hat keinen Effekt, wenn es zusammen mit --all benutzt wird" #~ msgid "the following arguments are required: license" #~ msgstr "Die folgenden Argumente sind erforderlich: license" #~ msgid "usage: " #~ msgstr "Benutzung: " #~ msgid ".__call__() not defined" #~ msgstr ".__call__() nicht definiert" #, python-format #~ msgid "unknown parser %(parser_name)r (choices: %(choices)s)" #~ msgstr "unbekannter Parser %(parser_name)r (Auswahl: %(choices)s)" #, python-format #~ msgid "argument \"-\" with mode %r" #~ msgstr "Argument \"-\" mit Modus %r" #, python-format #~ msgid "can't open '%(filename)s': %(error)s" #~ msgstr "Kann '%(filename)s' nicht öffnen: %(error)s" #, python-format #~ msgid "cannot merge actions - two groups are named %r" #~ msgstr "Kann Aktionen nicht zusammenführen - zwei Gruppen heißen %r" #~ msgid "'required' is an invalid argument for positionals" #~ msgstr "'required' ist ein ungültiges Argument für Positionsangaben" #, 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" #, python-format #~ msgid "dest= is required for options like %r" #~ msgstr "dest= ist erforderlich für Optionen wie %r" #, python-format #~ msgid "invalid conflict_resolution value: %r" #~ msgstr "Ungültiger Wert für conflict_resolution: %r" #, 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" #~ msgid "mutually exclusive arguments must be optional" #~ msgstr "Sich gegenseitig ausschließende Argumente müssen optional sein" #~ msgid "cannot have multiple subparser arguments" #~ msgstr "mehrere Subparser-Argumente sind nicht möglich" #, python-format #~ msgid "unrecognized arguments: %s" #~ msgstr "unbekannte Argumente: %s" #, python-format #~ msgid "not allowed with argument %s" #~ msgstr "nicht erlaubt mit Argument %s" #, python-format #~ msgid "ignored explicit argument %r" #~ msgstr "explizites Argument %r ignoriert" #, python-format #~ msgid "the following arguments are required: %s" #~ msgstr "die folgenden Argumente sind erforderlich: %s" #, python-format #~ msgid "one of the arguments %s is required" #~ msgstr "eines der Argumente %s ist erforderlich" #~ msgid "expected at most one argument" #~ msgstr "erwartete höchstens ein Argument" #~ msgid "expected at least one argument" #~ msgstr "erwartete mindestens ein Argument" #, python-format #~ msgid "expected %s argument" #~ msgid_plural "expected %s arguments" #~ msgstr[0] "erwartete %s Argument" #~ msgstr[1] "erwartete %s Argumente" #, python-format #~ msgid "ambiguous option: %(option)s could match %(matches)s" #~ msgstr "mehrdeutige Option: %(option)s könnte %(matches)s bedeuten" #, python-format #~ msgid "unexpected option string: %s" #~ msgstr "unerwarteter Options-String: %s" #, python-format #~ msgid "%r is not callable" #~ msgstr "%r ist nicht aufrufbar" #, python-format #~ msgid "invalid %(type)s value: %(value)r" #~ msgstr "ungültiger %(type)s Wert: %(value)r" #, python-format #~ msgid "invalid choice: %(value)r (choose from %(choices)s)" #~ msgstr "ungültige Auswahl: %(value)r (wähle von %(choices)s)" #, fuzzy, python-brace-format #~ msgid "'{path}' could not be decoded as UTF-8." #~ msgstr "'{dep5}' konnte nicht als UTF-8 decodiert werden." #, 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 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 "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-6.2.0/po/gl.po0000664000175000017500000014543515077707000013662 0ustar alexalex# 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: 2025-10-07 21:23+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/lint.py:40 #, fuzzy msgid "BAD LICENSES" msgstr "LICENZAS SEN USO" #: src/reuse/lint.py:42 #, fuzzy msgid "The following licenses are not valid SPDX licenses:" msgstr "As seguintes licenzas non se usan:" #: src/reuse/lint.py:50 msgid "DEPRECATED LICENSES" msgstr "LICENZAS OBSOLETAS" #: src/reuse/lint.py:52 msgid "The following licenses are deprecated by SPDX:" msgstr "As seguintes licenzas son obsoletas para SPDX:" #: src/reuse/lint.py:60 msgid "LICENSES WITHOUT FILE EXTENSION" msgstr "LICENZAS SEN EXTENSIÓN DE ARQUIVO" #: src/reuse/lint.py:62 msgid "The following licenses have no file extension:" msgstr "As seguintes licenzas non teñen extesión de arquivo:" #: src/reuse/lint.py:70 msgid "MISSING LICENSES" msgstr "LICENZAS NON ATOPADAS" #: src/reuse/lint.py:72 msgid "'{}' found in:" msgstr "'{}' atopado en:" #: src/reuse/lint.py:79 msgid "UNUSED LICENSES" msgstr "LICENZAS SEN USO" #: src/reuse/lint.py:80 msgid "The following licenses are not used:" msgstr "As seguintes licenzas non se usan:" #: src/reuse/lint.py:87 msgid "READ ERRORS" msgstr "ERROS DE LECTURA" #: src/reuse/lint.py:88 msgid "Could not read:" msgstr "Non se pode ler:" #: src/reuse/lint.py:94 msgid "INVALID SPDX LICENSE EXPRESSIONS" msgstr "" #: src/reuse/lint.py:99 #, fuzzy msgid "'{}' contains invalid SPDX License Expressions:" msgstr "'{}' non é unha expresión SPDX válida, cancelando" #: src/reuse/lint.py:124 msgid "MISSING COPYRIGHT AND LICENSING INFORMATION" msgstr "NON SE ATOPA INFORMACIÓN DE LICENZA OU COPYRIGHT" #: src/reuse/lint.py:130 #, fuzzy msgid "The following files have no copyright and licensing information:" msgstr "Os seguintes arquivos non teñen información de copyright:" #: src/reuse/lint.py:141 msgid "The following files have no copyright information:" msgstr "Os seguintes arquivos non teñen información de copyright:" #: src/reuse/lint.py:150 msgid "The following files have no licensing information:" msgstr "Os seguintes arquivos non teñen información de licenza:" #: src/reuse/lint.py:157 msgid "SUMMARY" msgstr "RESUMO" #: src/reuse/lint.py:162 msgid "Bad licenses:" msgstr "Licenzas defectuosas:" #: src/reuse/lint.py:163 msgid "Deprecated licenses:" msgstr "Licenzas obsoletas:" #: src/reuse/lint.py:166 msgid "Licenses without file extension:" msgstr "Licenzas sen extensión de arquivo:" #: src/reuse/lint.py:169 msgid "Missing licenses:" msgstr "Licenzas non atopadas:" #: src/reuse/lint.py:170 msgid "Unused licenses:" msgstr "Licenzas non usadas:" #: src/reuse/lint.py:171 msgid "Used licenses:" msgstr "Licenzas usadas:" #: src/reuse/lint.py:172 #, fuzzy msgid "Read errors:" msgstr "Erros de lectura: {count}" #: src/reuse/lint.py:173 #, fuzzy msgid "Invalid SPDX License Expressions:" msgstr "'{}' non é unha expresión SPDX válida, cancelando" #: src/reuse/lint.py:183 #, fuzzy msgid "Files with copyright information:" msgstr "Arquivos con información de copyright: {count} / {total}" #: src/reuse/lint.py:187 #, fuzzy msgid "Files with license information:" msgstr "Arquivos con información de licenza: {count} / {total}" #: src/reuse/lint.py:204 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:211 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:218 msgid "RECOMMENDATIONS" msgstr "" #: src/reuse/lint.py:286 #, fuzzy, python-brace-format msgid "missing license '{lic}'" msgstr "'{}' non é un Identificador de Licenza SPDX válido." #: src/reuse/lint.py:291 #, fuzzy msgid "read error" msgstr "Erros de lectura: {count}" #: src/reuse/lint.py:296 #, fuzzy, python-brace-format msgid "invalid SPDX License Expression '{expression}'" msgstr "'{}' non é unha expresión SPDX válida, cancelando" #: src/reuse/lint.py:303 #, fuzzy msgid "no license identifier" msgstr "'{}' non é un Identificador de Licenza SPDX válido." #: src/reuse/lint.py:307 #, fuzzy msgid "no copyright notice" msgstr "'{}' non é un Identificador de Licenza SPDX válido." #: src/reuse/lint.py:345 #, fuzzy, python-brace-format msgid "bad license '{lic}'" msgstr "Licenzas non usadas:" #: src/reuse/lint.py:350 #, fuzzy msgid "deprecated license" msgstr "Licenzas obsoletas:" #: src/reuse/lint.py:355 #, fuzzy msgid "license without file extension" msgstr "Licenzas sen extensión de arquivo:" #: src/reuse/lint.py:360 #, fuzzy msgid "unused license" msgstr "Licenzas non usadas:" #: src/reuse/project.py:253 #, fuzzy, python-brace-format msgid "'{path}' covered by {global_path}" msgstr "'{path}' cuberto por .reuse/dep5" #: src/reuse/project.py:261 #, python-brace-format msgid "" "'{path}' is covered exclusively by REUSE.toml. Not reading the file contents." 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:355 #, 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:419 #, python-brace-format msgid "{path} does not have a file extension" msgstr "{path} non ten extensión de arquivo" #: src/reuse/project.py:429 #, 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:441 #, 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:480 msgid "" "project '{}' is not a VCS repository or required VCS software is not " "installed" msgstr "" #: src/reuse/extract.py:49 #, python-brace-format msgid "" "REUSE_ENCODING_MODULE must have a value in {modules}; it has '{env_module}'. " "Aborting." msgstr "" #: src/reuse/extract.py:69 msgid "" "No supported module that can detect the encoding of files could be " "successfully imported. Re-read the installation instructions for the reuse " "package, or try the following:" msgstr "" #: src/reuse/extract.py:75 msgid "" "- If you are running a Linux distribution, try your equivalent of `apt " "install file` or `dnf install file`." msgstr "" #: src/reuse/extract.py:80 msgid "" "- Run ` pipx install reuse[charset-normalizer]`. Replace 'pipx' with 'pip' " "if you are not using pipx." msgstr "" #: src/reuse/extract.py:451 #, python-brace-format msgid "" "'{path}' was detected as a binary file; not searching its contents for REUSE " "information." msgstr "" #: src/reuse/extract.py:462 #, python-brace-format msgid "" "extracting REUSE information from '{path}' (encoding {encoding}, encoding " "module {module}, newline {newline})" msgstr "" #: src/reuse/header.py:87 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/report.py:160 #, python-brace-format msgid "Could not read '{path}'" msgstr "Non se pode ler '{path}'" #: src/reuse/report.py:165 #, python-brace-format msgid "Unexpected error occurred while parsing '{path}'" msgstr "Aconteceu un erro inesperado lendo '{path}'" #: src/reuse/report.py:521 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:532 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:543 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:552 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:564 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:575 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:584 msgid "" "Fix invalid SPDX License Expressions: In one or more files there are SPDX " "License Expressions which cannot be parse. Check whether the value that " "follows 'SPDX-License-Identifier:' is correct. If the detected expression is " "not meant to be valid, put it between 'REUSE-IgnoreStart' and 'REUSE-" "IgnoreEnd' comments." msgstr "" #: src/reuse/report.py:595 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/cli/lint.py:28 #, python-brace-format msgid "" "Lint the project directory for REUSE compliance. This version of the tool " "checks against version {reuse_version} of the REUSE Specification. You can " "find the latest version of the specification at ." msgstr "" #: src/reuse/cli/lint.py:34 msgid "Specifically, the following criteria are checked:" msgstr "" #: src/reuse/cli/lint.py:38 msgid "" "- Are there any bad (unrecognised, not compliant with SPDX) licenses in the " "project?" msgstr "" #: src/reuse/cli/lint.py:43 #, fuzzy msgid "- Are there any deprecated licenses in the project?" msgstr "Cal é o enderezo en internet do proxecto?" #: src/reuse/cli/lint.py:47 msgid "" "- Are there any license files in the LICENSES/ directory without file " "extension?" msgstr "" #: src/reuse/cli/lint.py:54 msgid "" "- Are any licenses referred to inside of the project, but not included in " "the LICENSES/ directory?" msgstr "" #: src/reuse/cli/lint.py:61 msgid "" "- Are any licenses included in the LICENSES/ directory that are not used " "inside of the project?" msgstr "" #: src/reuse/cli/lint.py:66 msgid "- Are there any read errors?" msgstr "" #: src/reuse/cli/lint.py:69 #, fuzzy msgid "- Do all files have valid copyright and licensing information?" msgstr "" "Os seguintes arquivos non teñen información de licenza nen de copyright:" #: src/reuse/cli/lint.py:81 src/reuse/cli/lint_file.py:38 msgid "Prevent output." msgstr "" #: src/reuse/cli/lint.py:89 src/reuse/cli/supported_licenses.py:28 msgid "Format output as JSON." msgstr "" #: src/reuse/cli/lint.py:97 msgid "Format output as plain text. (default)" msgstr "" #: src/reuse/cli/lint.py:105 msgid "Format output as errors per line." msgstr "" #: src/reuse/cli/convert_dep5.py:19 msgid "" "Convert .reuse/dep5 into a REUSE.toml file. The generated file is placed in " "the project root and is semantically identical. The .reuse/dep5 file is " "subsequently deleted." msgstr "" #: src/reuse/cli/convert_dep5.py:31 #, fuzzy msgid "No '.reuse/dep5' file." msgstr "Creando .reuse/dep5" #: src/reuse/cli/lint_file.py:25 msgid "" "Lint individual files for REUSE compliance. The specified FILEs are checked " "for the presence of copyright and licensing information, and whether the " "found licenses are included in the LICENSES/ directory." msgstr "" #: src/reuse/cli/lint_file.py:46 msgid "Format output as errors per line. (default)" msgstr "" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/lint_file.py:51 msgid "FILE" msgstr "" #: src/reuse/cli/lint_file.py:65 #, python-brace-format msgid "'{file}' is not inside of '{root}'." msgstr "" #: src/reuse/cli/spdx.py:22 #, fuzzy msgid "Generate an SPDX bill of materials." msgstr "imprimir a lista de materiales do proxecto en formato SPDX" #: src/reuse/cli/spdx.py:32 msgid "File to write to." msgstr "" #: src/reuse/cli/spdx.py:38 msgid "" "Populate the LicenseConcluded field; note that reuse cannot guarantee that " "the field is accurate." msgstr "" #: src/reuse/cli/spdx.py:50 msgid "Name of the person signing off on the SPDX report." msgstr "" #: src/reuse/cli/spdx.py:54 msgid "Name of the organization signing off on the SPDX report." msgstr "" #: src/reuse/cli/spdx.py:81 msgid "" "'--creator-person' or '--creator-organization' is required when '--add-" "license-concluded' is provided." msgstr "" #: src/reuse/cli/spdx.py:96 #, 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 "" #: src/reuse/cli/main.py:36 #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/decorators.py:465 #, fuzzy, python-format msgid "%(prog)s, version %(version)s" msgstr "%(prog)s: erro: %(message)s\n" #: src/reuse/cli/main.py:39 msgid "" "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." msgstr "" #: src/reuse/cli/main.py:46 msgid "" "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." msgstr "" #: src/reuse/cli/main.py:53 msgid "" "You should have received a copy of the GNU General Public License along with " "this program. If not, see ." msgstr "" #: src/reuse/cli/main.py:61 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/cli/main.py:68 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/cli/main.py:72 msgid "Support the FSFE's work:" msgstr "Apoie o traballo da FSFE:" #: src/reuse/cli/main.py:77 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/cli/main.py:88 #, fuzzy msgid "Enable debug statements." msgstr "habilitar sentencias de depuración" #: src/reuse/cli/main.py:93 msgid "Hide deprecation warnings." msgstr "" #: src/reuse/cli/main.py:98 #, fuzzy msgid "Do not skip over Git submodules." msgstr "non salte os submódulos de Git" #: src/reuse/cli/main.py:103 #, fuzzy msgid "Do not skip over Meson subprojects." msgstr "non salte os submódulos de Git" #: src/reuse/cli/main.py:108 #, fuzzy msgid "Do not use multiprocessing." msgstr "non empregue multiprocesamento" #: src/reuse/cli/main.py:118 #, fuzzy msgid "Define root of project." msgstr "definir a raíz do proxecto" #: src/reuse/cli/common.py:51 #, python-brace-format msgid "" "'{path}' could not be parsed. We received the following error message: " "{message}" msgstr "" #: src/reuse/cli/common.py:87 #, python-brace-format msgid "'{name}' is mutually exclusive with: {opts}" msgstr "" #: src/reuse/cli/common.py:103 #, fuzzy msgid "'{}' is not a valid SPDX expression." msgstr "'{}' non é unha expresión SPDX válida, cancelando" #: src/reuse/cli/download.py:54 msgid "'{}' is not a valid SPDX License Identifier." msgstr "'{}' non é un Identificador de Licenza SPDX válido." #: src/reuse/cli/download.py:61 msgid "Did you mean:" msgstr "" #: src/reuse/cli/download.py:68 msgid "" "See for a list of valid SPDX License " "Identifiers." msgstr "" "Consulte unha lista de Identificadores de Licenza SPDX válidos en ." #: src/reuse/cli/download.py:77 #, python-brace-format msgid "Error: {spdx_identifier} already exists." msgstr "Erro: {spdx_identifier} xa existe." #: src/reuse/cli/download.py:84 #, fuzzy, python-brace-format msgid "Error: {path} does not exist." msgstr "'{path}' non remata en .spdx" #: src/reuse/cli/download.py:88 msgid "Error: Failed to download license." msgstr "Erro: Fallo descargando a licenza." #: src/reuse/cli/download.py:93 msgid "Is your internet connection working?" msgstr "Está a funcionar a súa conexión a internet?" #: src/reuse/cli/download.py:98 #, python-brace-format msgid "Successfully downloaded {spdx_identifier}." msgstr "Descargouse correctamente o {spdx_identifier}." #: src/reuse/cli/download.py:108 #, fuzzy msgid "Download a license and place it in the LICENSES/ directory." msgstr "Descargar unha licenza e gardala na carpeta LICENSES/" #: src/reuse/cli/download.py:111 msgid "" "LICENSE must be a valid SPDX License Identifier. You may specify LICENSE " "multiple times to download multiple licenses." msgstr "" #: src/reuse/cli/download.py:124 #, fuzzy msgid "Download all missing licenses detected in the project." msgstr "descargar todas as licenzas detectadas mais non atopadas no proxecto" #: src/reuse/cli/download.py:132 msgid "Path to download to." msgstr "" #: src/reuse/cli/download.py:138 msgid "" "Source from which to copy custom LicenseRef- licenses, either a directory " "that contains the file or the file itself." msgstr "" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/download.py:145 #, fuzzy msgid "LICENSE" msgstr "LICENZAS DEFECTUOSAS" #: src/reuse/cli/download.py:161 #, fuzzy msgid "The 'LICENSE' argument and '--all' option are mutually exclusive." msgstr "as opcións --exclude-year e --year non se poden usar á vez" #: src/reuse/cli/download.py:173 #, fuzzy msgid "Cannot use '--output' with more than one license." msgstr "non se pode usar --output con máis dunha licenza" #: src/reuse/cli/annotate.py:66 #, fuzzy msgid "Option '--copyright', '--license', or '--contributor' is required." msgstr "precisase a opción --copyright ou --license" #: src/reuse/cli/annotate.py:127 #, 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/cli/annotate.py:160 #, python-brace-format msgid "" "'{path}' does not support single-line comments, please do not use '--single-" "line'." msgstr "" #: src/reuse/cli/annotate.py:167 #, python-brace-format msgid "" "'{path}' does not support multi-line comments, please do not use '--multi-" "line'." msgstr "" #: src/reuse/cli/annotate.py:213 #, fuzzy, python-brace-format msgid "Template '{template}' could not be found." msgstr "no se atopa o modelo {template}" #: src/reuse/cli/annotate.py:236 #, fuzzy, python-brace-format msgid "'{year}' is not a valid year range." msgstr "'{}' non é unha expresión SPDX válida, cancelando" #: src/reuse/cli/annotate.py:245 #, python-brace-format msgid "" "Your operating system's year is set to '{year}'. This is not four digits, " "and not supported." msgstr "" #: src/reuse/cli/annotate.py:287 #, fuzzy msgid "Add copyright and licensing into the headers of files." msgstr "engadir copyright e licenza na cabeceira dos arquivos" #: src/reuse/cli/annotate.py:290 msgid "" "By using --copyright and --license, you can specify which copyright holders " "and licenses to add to the headers of the given files." msgstr "" #: src/reuse/cli/annotate.py:296 msgid "" "By using --contributor, you can specify people or entity that contributed " "but are not copyright holder of the given files." msgstr "" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:309 msgid "COPYRIGHT" msgstr "" #: src/reuse/cli/annotate.py:312 #, fuzzy msgid "Copyright holder, repeatable." msgstr "declaración de copyright, repetibel" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:319 msgid "SPDX_IDENTIFIER" msgstr "" #: src/reuse/cli/annotate.py:322 #, fuzzy msgid "SPDX License Identifier, repeatable." msgstr "Identificador SPDX, repetibel" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:328 msgid "CONTRIBUTOR" msgstr "" #: src/reuse/cli/annotate.py:331 #, fuzzy msgid "File contributor, repeatable." msgstr "Identificador SPDX, repetibel" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:338 msgid "YEAR" msgstr "" #: src/reuse/cli/annotate.py:343 msgid "" "Year of copyright notice. You may define multiple years or a range of years." msgstr "" #: src/reuse/cli/annotate.py:353 #, fuzzy msgid "Comment style to use." msgstr "estilo de comentario a usar, opcional" #: src/reuse/cli/annotate.py:363 #, fuzzy msgid "Copyright prefix to use." msgstr "estilo de comentario a usar, opcional" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:375 msgid "TEMPLATE" msgstr "" #: src/reuse/cli/annotate.py:377 #, fuzzy msgid "Name of template to use." msgstr "nome do modelo a usar, opcional" #: src/reuse/cli/annotate.py:384 #, fuzzy msgid "Do not include year in copyright notice." msgstr "non incluir ano na declaración" #: src/reuse/cli/annotate.py:390 #, fuzzy msgid "Merge copyright notices if they are identical except for their years." msgstr "ano da declaración de copyright, opcional" #: src/reuse/cli/annotate.py:398 #, fuzzy msgid "Force single-line comment style." msgstr "estilo de comentario a usar, opcional" #: src/reuse/cli/annotate.py:405 #, fuzzy msgid "Force multi-line comment style." msgstr "estilo de comentario a usar, opcional" #: src/reuse/cli/annotate.py:411 msgid "Add headers to all files under specified directories recursively." msgstr "" #: src/reuse/cli/annotate.py:416 msgid "Do not replace the first header in the file; just add a new one." msgstr "" #: src/reuse/cli/annotate.py:423 msgid "Always write a .license file instead of a header inside the file." msgstr "" #: src/reuse/cli/annotate.py:430 msgid "Write a .license file to files with unrecognised comment styles." msgstr "" #: src/reuse/cli/annotate.py:437 msgid "Skip files with unrecognised comment styles." msgstr "" #: src/reuse/cli/annotate.py:448 #, fuzzy msgid "Skip files that already contain REUSE information." msgstr "Arquivos con información de licenza: {count} / {total}" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:453 msgid "PATH" msgstr "" #: src/reuse/cli/annotate.py:510 #, 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/cli/supported_licenses.py:19 msgid "List all licenses on the SPDX License List." msgstr "" #: src/reuse/global_licensing.py:92 #, python-brace-format msgid "" "{attr_name} must be a {type_name} (got {value} that is a {value_class})." msgstr "" #: src/reuse/global_licensing.py:106 #, 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:118 #, python-brace-format msgid "{attr_name} must not be empty." msgstr "" #: src/reuse/global_licensing.py:142 #, python-brace-format msgid "{name} must be a {type} (got {value} that is a {value_type})." msgstr "" #: src/reuse/global_licensing.py:166 #, python-brace-format msgid "" "The value of 'precedence' must be one of {precedence_vals} (got {received})" msgstr "" #: src/reuse/global_licensing.py:219 #, fuzzy, python-brace-format msgid "Could not parse '{notice}'" msgstr "Non se pode analizar '{expression}'" #: src/reuse/_annotate.py:94 #, python-brace-format msgid "Skipped unrecognised file '{path}'" msgstr "" #: src/reuse/_annotate.py:100 #, python-brace-format msgid "'{path}' is not recognised; creating '{path}.license'" msgstr "" #: src/reuse/_annotate.py:116 #, fuzzy, python-brace-format msgid "Skipped file '{path}' already containing REUSE information" msgstr "Arquivos con información de licenza: {count} / {total}" #: src/reuse/_annotate.py:145 #, 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:152 #, 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:163 #, python-brace-format msgid "Successfully changed header of {path}" msgstr "A cabeceira de {path} cambiada con éxito" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:162 msgid "Repeat for confirmation" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:178 msgid "Error: The value you entered was invalid." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:180 #, python-brace-format msgid "Error: {e.message}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:191 msgid "Error: The two entered values do not match." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:247 msgid "Error: invalid input" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:866 msgid "Press any key to continue..." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:332 #, python-brace-format msgid "" "Choose from:\n" "\t{choices}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:369 msgid "{value!r} is not {choice}." msgid_plural "{value!r} is not one of {choices}." msgstr[0] "" msgstr[1] "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:460 msgid "{value!r} does not match the format {format}." msgid_plural "{value!r} does not match the formats {formats}." msgstr[0] "" msgstr[1] "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:482 msgid "{value!r} is not a valid {number_type}." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:538 #, python-brace-format msgid "{value} is not in the range {range}." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:719 msgid "{value!r} is not a valid boolean. Recognized values: {states}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:747 msgid "{value!r} is not a valid UUID." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:937 msgid "file" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:939 msgid "directory" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:941 msgid "path" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:988 #, fuzzy msgid "{name} {filename!r} does not exist." msgstr "'{path}' non remata en .spdx" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:997 msgid "{name} {filename!r} is a file." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:1005 #, fuzzy msgid "{name} {filename!r} is a directory." msgstr "'{}' non é un directorio" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:1014 msgid "{name} {filename!r} is not readable." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:1023 msgid "{name} {filename!r} is not writable." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:1032 msgid "{name} {filename!r} is not executable." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:1099 #, python-brace-format msgid "{len_type} values are required, but {len_value} was given." msgid_plural "{len_type} values are required, but {len_value} were given." msgstr[0] "" msgstr[1] "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/shell_completion.py:332 msgid "Shell completion is not supported for Bash versions older than 4.4." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/shell_completion.py:339 msgid "Couldn't detect Bash version, shell completion is not supported." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:50 #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:89 #, python-brace-format msgid "Error: {message}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:81 #, python-brace-format msgid "Try '{command} {option}' for help." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:130 #, python-brace-format msgid "Invalid value: {message}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:132 #, python-brace-format msgid "Invalid value for {param_hint}: {message}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:190 #, fuzzy msgid "Missing argument" msgstr "argumentos posicionais" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:192 #, fuzzy msgid "Missing option" msgstr "Licenzas non atopadas:" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:194 msgid "Missing parameter" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:196 #, python-brace-format msgid "Missing {param_type}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:203 #, python-brace-format msgid "Missing parameter: {param_name}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:223 #, python-brace-format msgid "No such option: {name}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:235 #, python-brace-format msgid "Did you mean {possibility}?" msgid_plural "(Possible options: {possibilities})" msgstr[0] "" msgstr[1] "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:282 msgid "unknown error" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:289 msgid "Could not open file {filename!r}: {message}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1104 #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1141 #, python-brace-format msgid "{text} {deprecated_message}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1160 msgid "Options" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1222 #, fuzzy, python-brace-format msgid "Got unexpected extra argument ({args})" msgid_plural "Got unexpected extra arguments ({args})" msgstr[0] "espérase un argumento" msgstr[1] "espérase un argumento" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1241 msgid "DeprecationWarning: The command {name!r} is deprecated.{extra_message}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1425 msgid "Aborted!" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1799 #, fuzzy msgid "Commands" msgstr "subcomandos" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1830 #, fuzzy msgid "Missing command." msgstr "Licenzas non atopadas:" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1908 msgid "No such command {name!r}." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:2332 msgid "Value must be an iterable." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:2355 #, python-brace-format msgid "Takes {nargs} values but 1 was given." msgid_plural "Takes {nargs} values but {len} were given." msgstr[0] "" msgstr[1] "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:2505 msgid "" "DeprecationWarning: The {param_type} {name!r} is deprecated.{extra_message}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:2956 #, python-brace-format msgid "env var: {var}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:2959 #, python-brace-format msgid "default: {default}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:3023 msgid "(dynamic)" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/parser.py:199 msgid "Argument {name!r} takes {nargs} values." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/parser.py:381 msgid "Option {name!r} does not take a value." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/parser.py:444 msgid "Option {name!r} requires an argument." msgid_plural "Option {name!r} requires {nargs} arguments." msgstr[0] "" msgstr[1] "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/_termui_impl.py:608 #, python-brace-format msgid "{editor}: Editing failed" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/_termui_impl.py:612 #, python-brace-format msgid "{editor}: Editing failed: {e}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/decorators.py:522 #, fuzzy msgid "Show the version and exit." msgstr "mostrar esta mensaxe de axuda e sair" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/decorators.py:548 #, fuzzy msgid "Show this message and exit." msgstr "mostrar esta mensaxe de axuda e sair" #, fuzzy, python-brace-format #~ msgid "{path}: read error\n" #~ msgstr "Licenzas obsoletas:" #, fuzzy, python-brace-format #~ msgid "{lic_path}: deprecated license\n" #~ msgstr "Licenzas obsoletas:" #, fuzzy, python-brace-format #~ msgid "{lic_path}: license without file extension\n" #~ msgstr "Licenzas sen extensión de arquivo:" #, fuzzy, python-brace-format #~ msgid "{lic_path}: unused license\n" #~ msgstr "Licenzas non usadas:" #, 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" #, python-brace-format #~ msgid "Could not parse '{expression}'" #~ msgstr "Non se pode analizar '{expression}'" #, fuzzy, python-brace-format #~ msgid "(Deprecated) {text}" #~ msgstr "Licenzas obsoletas:" #, fuzzy #~ msgid "Year of copyright statement." #~ msgstr "ano da declaración de copyright, opcional" #, python-brace-format #~ msgid "determining identifier of '{path}'" #~ msgstr "resolvendo o identificador de '{path}'" #~ msgid "can't write to '{}'" #~ msgstr "non se pode escribir en '{}'" #~ msgid "show program's version number and exit" #~ msgstr "mostrar o número de versión do programa e saír" #~ msgid "download a license and place it in the LICENSES/ directory" #~ msgstr "Descargar unha licenza e gardala na carpeta LICENSES/" #~ msgid "list all non-compliant files" #~ msgstr "listar todos os arquivos que non cumplen os criterios" #, fuzzy, 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 there any deprecated licenses in the project?\n" #~ "\n" #~ "- Are there any license files in the LICENSES/ directory without file " #~ "extension?\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" #~ "- Are there any read errors?\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?" #~ msgid "print the project's bill of materials in SPDX format" #~ msgstr "imprimir a lista de materiales do proxecto en formato SPDX" #~ msgid "'{}' is not a file" #~ msgstr "'{}' non é un arquivo" #~ msgid "can't open '{}'" #~ msgstr "non se pode abrir '{}'" #~ msgid "can't write to directory '{}'" #~ msgstr "non se pode escribir no directorio '{}'" #~ msgid "can't read or write '{}'" #~ msgstr "non se pode ler ou escribir en '{}'" #~ msgid "SPDX License Identifier of license" #~ msgstr "Identificador de Licenza SPDX da licenza" #~ msgid "the following arguments are required: license" #~ msgstr "requirense os seguintes argumentos: licenza" #~ msgid "usage: " #~ msgstr "uso: " #~ msgid ".__call__() not defined" #~ msgstr ".__call__() non definido" #, python-format #~ msgid "unknown parser %(parser_name)r (choices: %(choices)s)" #~ msgstr "analizador descoñecido %(parser_name)r (alternativas: %(choices)s)" #, python-format #~ msgid "argument \"-\" with mode %r" #~ msgstr "argumento \"-\" con modo %r" #, python-format #~ msgid "can't open '%(filename)s': %(error)s" #~ msgstr "non se pode abrir '%(filename)s': %(error)s" #, 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" #~ msgid "'required' is an invalid argument for positionals" #~ msgstr "'required' non é un argumento valido para os posicionais" #, 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" #, python-format #~ msgid "dest= is required for options like %r" #~ msgstr "requírese dest= para opcións do tipo %r" #, python-format #~ msgid "invalid conflict_resolution value: %r" #~ msgstr "valor non válido para conflict_resolution: %r" #, 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" #~ msgid "mutually exclusive arguments must be optional" #~ msgstr "os argumentos mutuamente exclusivos deben ser opcionais" #~ msgid "cannot have multiple subparser arguments" #~ msgstr "non pode haber múltiples argumentos para o subanalizador" #, python-format #~ msgid "unrecognized arguments: %s" #~ msgstr "argumentos non recoñecidos: %s" #, python-format #~ msgid "not allowed with argument %s" #~ msgstr "non se permite co argumento %s" #, python-format #~ msgid "ignored explicit argument %r" #~ msgstr "argumento explicito %r ignorado" #, python-format #~ msgid "the following arguments are required: %s" #~ msgstr "precísanse os seguintes argumentos: %s" #, python-format #~ msgid "one of the arguments %s is required" #~ msgstr "precísase un dos argumentos %s" #~ msgid "expected at most one argument" #~ msgstr "espérase un argumento como máximo" #~ msgid "expected at least one argument" #~ msgstr "espérase un argumento como mínimo" #, python-format #~ msgid "expected %s argument" #~ msgid_plural "expected %s arguments" #~ msgstr[0] "espérase %s argumento" #~ msgstr[1] "espéranse %s argumentos" #, python-format #~ msgid "ambiguous option: %(option)s could match %(matches)s" #~ msgstr "opción ambigua: %(option)s pode encaixar con %(matches)s" #, python-format #~ msgid "unexpected option string: %s" #~ msgstr "opción de cadea non esperada: %s" #, python-format #~ msgid "%r is not callable" #~ msgstr "%r non se pode chamar" #, python-format #~ msgid "invalid %(type)s value: %(value)r" #~ msgstr "valor non válido %(type)s: %(value)r" #, python-format #~ msgid "invalid choice: %(value)r (choose from %(choices)s)" #~ msgstr "alternativa non válida: %(value)r (elixir entre %(choices)s)" #~ 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 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" #~ 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-6.2.0/po/uk.po0000664000175000017500000023476115077707000013700 0ustar alexalex# 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: 2025-10-07 21:23+0000\n" "PO-Revision-Date: 2025-10-09 06:07+0000\n" "Last-Translator: Максим Горпиніч \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.14-dev\n" #: src/reuse/lint.py:40 msgid "BAD LICENSES" msgstr "ПОГАНІ ЛІЦЕНЗІЇ" #: src/reuse/lint.py:42 msgid "The following licenses are not valid SPDX licenses:" msgstr "Наступні ліцензії не є дійсними ліцензіями SPDX:" #: src/reuse/lint.py:50 msgid "DEPRECATED LICENSES" msgstr "ЗАСТАРІЛІ ЛІЦЕНЗІЇ" #: src/reuse/lint.py:52 msgid "The following licenses are deprecated by SPDX:" msgstr "У SPDX застаріли такі ліцензії:" #: src/reuse/lint.py:60 msgid "LICENSES WITHOUT FILE EXTENSION" msgstr "ЛІЦЕНЗІЇ БЕЗ РОЗШИРЕННЯ ФАЙЛУ" #: src/reuse/lint.py:62 msgid "The following licenses have no file extension:" msgstr "Ці ліцензії не мають розширення файлу:" #: src/reuse/lint.py:70 msgid "MISSING LICENSES" msgstr "ВІДСУТНІ ЛІЦЕНЗІЇ" #: src/reuse/lint.py:72 msgid "'{}' found in:" msgstr "'{}' знайдено в:" #: src/reuse/lint.py:79 msgid "UNUSED LICENSES" msgstr "НЕВИКОРИСТАНІ ЛІЦЕНЗІЇ" #: src/reuse/lint.py:80 msgid "The following licenses are not used:" msgstr "Не використовуються такі ліцензії:" #: src/reuse/lint.py:87 msgid "READ ERRORS" msgstr "ПОМИЛКИ ЧИТАННЯ" #: src/reuse/lint.py:88 msgid "Could not read:" msgstr "Не вдалося прочитати:" #: src/reuse/lint.py:94 msgid "INVALID SPDX LICENSE EXPRESSIONS" msgstr "НЕДІЙСНІ ВИРАЗИ ЛІЦЕНЗІЇ SPDX" #: src/reuse/lint.py:99 msgid "'{}' contains invalid SPDX License Expressions:" msgstr "'{}' містить недійсні вирази ліцензії SPDX:" #: src/reuse/lint.py:124 msgid "MISSING COPYRIGHT AND LICENSING INFORMATION" msgstr "ВІДСУТНІ ВІДОМОСТІ ПРО АВТОРСЬКІ ПРАВА ТА ЛІЦЕНЗУВАННЯ" #: src/reuse/lint.py:130 msgid "The following files have no copyright and licensing information:" msgstr "" "Наступні файли не мають інформації про авторські права та ліцензування:" #: src/reuse/lint.py:141 msgid "The following files have no copyright information:" msgstr "Такі файли не містять відомостей про авторські права:" #: src/reuse/lint.py:150 msgid "The following files have no licensing information:" msgstr "Такі файли не мають відомостей про ліцензування:" #: src/reuse/lint.py:157 msgid "SUMMARY" msgstr "ПІДСУМОК" #: src/reuse/lint.py:162 msgid "Bad licenses:" msgstr "Погані ліцензії:" #: src/reuse/lint.py:163 msgid "Deprecated licenses:" msgstr "Застарілі ліцензії:" #: src/reuse/lint.py:166 msgid "Licenses without file extension:" msgstr "Ліцензії без розширення файлу:" #: src/reuse/lint.py:169 msgid "Missing licenses:" msgstr "Відсутні ліцензії:" #: src/reuse/lint.py:170 msgid "Unused licenses:" msgstr "Невикористані ліцензії:" #: src/reuse/lint.py:171 msgid "Used licenses:" msgstr "Використані ліцензії:" #: src/reuse/lint.py:172 msgid "Read errors:" msgstr "Помилки читання:" #: src/reuse/lint.py:173 msgid "Invalid SPDX License Expressions:" msgstr "Недійсні вирази ліцензії SPDX:" #: src/reuse/lint.py:183 msgid "Files with copyright information:" msgstr "Файли з інформацією про авторські права:" #: src/reuse/lint.py:187 msgid "Files with license information:" msgstr "Файли з інформацією про ліцензію:" #: src/reuse/lint.py:204 msgid "" "Congratulations! Your project is compliant with version {} of the REUSE " "Specification :-)" msgstr "Вітаємо! Ваш проєкт відповідає версії {} специфікації REUSE :-)" #: src/reuse/lint.py:211 msgid "" "Unfortunately, your project is not compliant with version {} of the REUSE " "Specification :-(" msgstr "На жаль, ваш проєкт не сумісний із версією {} специфікації REUSE :-(" #: src/reuse/lint.py:218 msgid "RECOMMENDATIONS" msgstr "РЕКОМЕНДАЦІЇ" #: src/reuse/lint.py:286 #, python-brace-format msgid "missing license '{lic}'" msgstr "відсутня ліцензія '{lic}'" #: src/reuse/lint.py:291 msgid "read error" msgstr "помилка читання" #: src/reuse/lint.py:296 #, python-brace-format msgid "invalid SPDX License Expression '{expression}'" msgstr "недійсний вираз ліцензії SPDX '{expression}'" #: src/reuse/lint.py:303 msgid "no license identifier" msgstr "без ідентифікатора ліцензії" #: src/reuse/lint.py:307 msgid "no copyright notice" msgstr "без повідомлення про авторські права" #: src/reuse/lint.py:345 #, python-brace-format msgid "bad license '{lic}'" msgstr "погана ліцензія '{lic}'" #: src/reuse/lint.py:350 msgid "deprecated license" msgstr "застаріла ліцензія" #: src/reuse/lint.py:355 msgid "license without file extension" msgstr "ліцензія без розширення файлу" #: src/reuse/lint.py:360 msgid "unused license" msgstr "невикористана ліцензія" #: src/reuse/project.py:253 #, python-brace-format msgid "'{path}' covered by {global_path}" msgstr "'{path}' покрито за рахунок {global_path}" #: src/reuse/project.py:261 #, python-brace-format msgid "" "'{path}' is covered exclusively by REUSE.toml. Not reading the file contents." msgstr "'{path}' покрито виключно файлом REUSE.toml. Зміст файлу не читається." #: 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:355 #, 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:419 #, python-brace-format msgid "{path} does not have a file extension" msgstr "{path} не має розширення файлу" #: src/reuse/project.py:429 #, 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:441 #, 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:480 msgid "" "project '{}' is not a VCS repository or required VCS software is not " "installed" msgstr "" "проєкт '{}' не є репозиторієм VCS або потрібне програмне забезпечення VCS не " "встановлено" #: src/reuse/extract.py:49 #, python-brace-format msgid "" "REUSE_ENCODING_MODULE must have a value in {modules}; it has '{env_module}'. " "Aborting." msgstr "" "REUSE_ENCODING_MODULE має мати значення в {modules}; він має '{env_module}'. " "Переривання." #: src/reuse/extract.py:69 msgid "" "No supported module that can detect the encoding of files could be " "successfully imported. Re-read the installation instructions for the reuse " "package, or try the following:" msgstr "" "Не вдалося успішно імпортувати жоден підтримуваний модуль, який може " "визначити кодування файлів. Перечитайте інструкції з встановлення пакета " "повторного використання або спробуйте ось що:" #: src/reuse/extract.py:75 msgid "" "- If you are running a Linux distribution, try your equivalent of `apt " "install file` or `dnf install file`." msgstr "" "- Якщо ви використовуєте дистрибутив Linux, спробуйте ваш еквівалент `apt " "install file` або `dnf install file`." #: src/reuse/extract.py:80 msgid "" "- Run ` pipx install reuse[charset-normalizer]`. Replace 'pipx' with 'pip' " "if you are not using pipx." msgstr "" "- Виконайте команду `pipx install reuse[charset-normalizer]`. Замініть " "'pipx' на 'pip', якщо ви не використовуєте pipx." #: src/reuse/extract.py:451 #, python-brace-format msgid "" "'{path}' was detected as a binary file; not searching its contents for REUSE " "information." msgstr "" "'{path}' виявлено як двійковий файл або його розширення позначено таким, що " "не коментується; пошук інформації у його вмісті для REUSE не виконується." #: src/reuse/extract.py:462 #, python-brace-format msgid "" "extracting REUSE information from '{path}' (encoding {encoding}, encoding " "module {module}, newline {newline})" msgstr "" "вилучення інформації про ПОВТОРНЕ ВИКОРИСТАННЯ з '{path}' (кодування " "{encoding}, модуль кодування {module}, новий рядок {newline})" #: src/reuse/header.py:87 msgid "generated comment is missing copyright lines or license expressions" msgstr "" "у згенерованому коментарі відсутні рядки про авторські права або вирази " "ліцензії" #: src/reuse/report.py:160 #, python-brace-format msgid "Could not read '{path}'" msgstr "Не вдалося прочитати '{path}'" #: src/reuse/report.py:165 #, python-brace-format msgid "Unexpected error occurred while parsing '{path}'" msgstr "Під час аналізу '{path}' сталася неочікувана помилка" #: src/reuse/report.py:521 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:532 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:543 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:552 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:564 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:575 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:584 msgid "" "Fix invalid SPDX License Expressions: In one or more files there are SPDX " "License Expressions which cannot be parse. Check whether the value that " "follows 'SPDX-License-Identifier:' is correct. If the detected expression is " "not meant to be valid, put it between 'REUSE-IgnoreStart' and 'REUSE-" "IgnoreEnd' comments." msgstr "" "Виправлення недійсних виразів ліцензії SPDX: в одному або декількох файлах є " "вирази ліцензії SPDX, які не можна проаналізувати. Перевірте, чи правильне " "значення, що йде за «SPDX-License-Identifier:». Якщо виявлений вираз не є " "дійсним, помістіть його між коментарями «REUSE-IgnoreStart» і «REUSE-" "IgnoreEnd»." #: src/reuse/report.py:595 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/cli/lint.py:28 #, python-brace-format msgid "" "Lint the project directory for REUSE compliance. This version of the tool " "checks against version {reuse_version} of the REUSE Specification. You can " "find the latest version of the specification at ." msgstr "" "Виконує перевірку каталогу проекту на відповідність специфікації REUSE. Ця " "версія інструменту перевіряє версію {reuse_version} специфікації REUSE. " "Останню версію специфікації можна знайти за адресою ." #: src/reuse/cli/lint.py:34 msgid "Specifically, the following criteria are checked:" msgstr "Зокрема, перевіряються наступні критерії:" #: src/reuse/cli/lint.py:38 msgid "" "- Are there any bad (unrecognised, not compliant with SPDX) licenses in the " "project?" msgstr "- Чи є в проекті погані (невизнані, не сумісні з SPDX) ліцензії?" #: src/reuse/cli/lint.py:43 msgid "- Are there any deprecated licenses in the project?" msgstr "- Чи є якісь застарілі ліцензії в проекті?" #: src/reuse/cli/lint.py:47 msgid "" "- Are there any license files in the LICENSES/ directory without file " "extension?" msgstr "- Чи є якісь файли ліцензій в каталозі LICENSES/ без розширення?" #: src/reuse/cli/lint.py:54 msgid "" "- Are any licenses referred to inside of the project, but not included in " "the LICENSES/ directory?" msgstr "" "- Чи є якісь ліцензії, на які є посилання в проекті, але які не включено до " "каталогу LICENSES/?" #: src/reuse/cli/lint.py:61 msgid "" "- Are any licenses included in the LICENSES/ directory that are not used " "inside of the project?" msgstr "" "- Чи включено до каталогу LICENSES/ якісь ліцензії, які не використовуються " "у проекті?" #: src/reuse/cli/lint.py:66 msgid "- Are there any read errors?" msgstr "- Чи є якісь помилки читання?" #: src/reuse/cli/lint.py:69 msgid "- Do all files have valid copyright and licensing information?" msgstr "" "- Чи всі файли мають дійсну інформацію про авторські права та ліцензії?" #: src/reuse/cli/lint.py:81 src/reuse/cli/lint_file.py:38 msgid "Prevent output." msgstr "Запобігти виведенню." #: src/reuse/cli/lint.py:89 src/reuse/cli/supported_licenses.py:28 msgid "Format output as JSON." msgstr "Виводити у форматі JSON." #: src/reuse/cli/lint.py:97 msgid "Format output as plain text. (default)" msgstr "Формат виводу - звичайний текст. (за замовчуванням)" #: src/reuse/cli/lint.py:105 msgid "Format output as errors per line." msgstr "Формат виведення - помилки на рядок." #: src/reuse/cli/convert_dep5.py:19 msgid "" "Convert .reuse/dep5 into a REUSE.toml file. The generated file is placed in " "the project root and is semantically identical. The .reuse/dep5 file is " "subsequently deleted." msgstr "" "Сконвертуйте .reuse/dep5 у файл REUSE.toml. Згенерований файл розміщується в " "корені проекту і є семантично ідентичним. Згодом файл .reuse/dep5 буде " "видалено." #: src/reuse/cli/convert_dep5.py:31 msgid "No '.reuse/dep5' file." msgstr "Файл '.reuse/dep5 відсутній." #: src/reuse/cli/lint_file.py:25 msgid "" "Lint individual files for REUSE compliance. The specified FILEs are checked " "for the presence of copyright and licensing information, and whether the " "found licenses are included in the LICENSES/ directory." msgstr "" "Перебирає окремі файли на відповідність вимогам REUSE. Вказані ФАЙЛИ " "перевіряються на наявність інформації про авторські права та ліцензії, а " "також на наявність знайдених ліцензій у каталозі LICENSES/." #: src/reuse/cli/lint_file.py:46 msgid "Format output as errors per line. (default)" msgstr "Формат виводу - помилки на рядок. (за замовчуванням)" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/lint_file.py:51 msgid "FILE" msgstr "ФАЙЛ" #: src/reuse/cli/lint_file.py:65 #, python-brace-format msgid "'{file}' is not inside of '{root}'." msgstr "'{file}' не знаходиться всередині '{root}'." #: src/reuse/cli/spdx.py:22 msgid "Generate an SPDX bill of materials." msgstr "Згенерувати опис матеріалів проєкту у форматі SPDX." #: src/reuse/cli/spdx.py:32 msgid "File to write to." msgstr "Файл, куди записувати." #: src/reuse/cli/spdx.py:38 msgid "" "Populate the LicenseConcluded field; note that reuse cannot guarantee that " "the field is accurate." msgstr "" "Заповніть поле LicenseConcluded; зауважте, що повторне використання не може " "гарантувати точність поля." #: src/reuse/cli/spdx.py:50 msgid "Name of the person signing off on the SPDX report." msgstr "Ім'я особи, яка підписує звіт SPDX." #: src/reuse/cli/spdx.py:54 msgid "Name of the organization signing off on the SPDX report." msgstr "Назва організації, яка підписує звіт SPDX." #: src/reuse/cli/spdx.py:81 msgid "" "'--creator-person' or '--creator-organization' is required when '--add-" "license-concluded' is provided." msgstr "" "'--creator-person' або '--creator-organization' вимагається, якщо надається " "'--add-license-concluded'." #: src/reuse/cli/spdx.py:96 #, 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" #: src/reuse/cli/main.py:36 #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/decorators.py:465 #, python-format msgid "%(prog)s, version %(version)s" msgstr "%(prog)s, версія %(version)s" #: src/reuse/cli/main.py:39 msgid "" "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." msgstr "" "Ця програма є вільним програмним забезпеченням: ви можете розповсюджувати її " "та/або змінювати відповідно до умов Стандартної публічної ліцензії GNU, " "опублікованої Фондом вільного програмного забезпечення, або версії 3 цієї " "ліцензії, або (на ваш вибір) будь-якої пізнішої версії." #: src/reuse/cli/main.py:46 msgid "" "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." msgstr "" "Ця програма поширюється в надії, що вона буде корисною, але БЕЗ ЖОДНИХ " "ГАРАНТІЙ; без навіть неявної гарантії ТОВАРНОСТІ або ПРИДАТНОСТІ ДЛЯ ПЕВНОЇ " "ЦІЛІ. Для більш детальної інформації див. Загальну публічну ліцензію GNU." #: src/reuse/cli/main.py:53 msgid "" "You should have received a copy of the GNU General Public License along with " "this program. If not, see ." msgstr "" "Ви мали отримати копію Стандартної публічної ліцензії GNU разом із цією " "програмою. Якщо ні, зверніться до ." #: src/reuse/cli/main.py:61 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/cli/main.py:68 msgid "" "This version of reuse is compatible with version {} of the REUSE " "Specification." msgstr "Ця версія reuse сумісна з версією {} специфікації REUSE." #: src/reuse/cli/main.py:72 msgid "Support the FSFE's work:" msgstr "Підтримати роботу FSFE:" #: src/reuse/cli/main.py:77 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/cli/main.py:88 msgid "Enable debug statements." msgstr "Увімкнути інструкції налагодження." #: src/reuse/cli/main.py:93 msgid "Hide deprecation warnings." msgstr "Сховати попередження про застарілість." #: src/reuse/cli/main.py:98 msgid "Do not skip over Git submodules." msgstr "Не пропускати підмодулі Git." #: src/reuse/cli/main.py:103 msgid "Do not skip over Meson subprojects." msgstr "Не пропускати підпроєкти Meson." #: src/reuse/cli/main.py:108 msgid "Do not use multiprocessing." msgstr "Не використовувати багатопроцесорність." #: src/reuse/cli/main.py:118 msgid "Define root of project." msgstr "Визначити кореневий каталог проєкту." #: src/reuse/cli/common.py:51 #, python-brace-format msgid "" "'{path}' could not be parsed. We received the following error message: " "{message}" msgstr "" "'{path}' не вдалося розібрати. Ми отримали наступне повідомлення про " "помилку: {message}" #: src/reuse/cli/common.py:87 #, python-brace-format msgid "'{name}' is mutually exclusive with: {opts}" msgstr "'{name}' є взаємовиключним з: {opts}" #: src/reuse/cli/common.py:103 msgid "'{}' is not a valid SPDX expression." msgstr "'{}' не є допустимим SPDX-виразом." #: src/reuse/cli/download.py:54 msgid "'{}' is not a valid SPDX License Identifier." msgstr "'{}' не є дійсним ідентифікатором ліцензії SPDX." #: src/reuse/cli/download.py:61 msgid "Did you mean:" msgstr "Ви мали на увазі:" #: src/reuse/cli/download.py:68 msgid "" "See for a list of valid SPDX License " "Identifiers." msgstr "" "Список дійсних ідентифікаторів ліцензій SPDX див. на ." #: src/reuse/cli/download.py:77 #, python-brace-format msgid "Error: {spdx_identifier} already exists." msgstr "Помилка: {spdx_identifier} вже існує." #: src/reuse/cli/download.py:84 #, python-brace-format msgid "Error: {path} does not exist." msgstr "Помилка: {path} не існує." #: src/reuse/cli/download.py:88 msgid "Error: Failed to download license." msgstr "Помилка: Не вдалося завантажити ліцензію." #: src/reuse/cli/download.py:93 msgid "Is your internet connection working?" msgstr "Чи працює ваше інтернет-з'єднання?" #: src/reuse/cli/download.py:98 #, python-brace-format msgid "Successfully downloaded {spdx_identifier}." msgstr "{spdx_identifier} успішно завантажено." #: src/reuse/cli/download.py:108 msgid "Download a license and place it in the LICENSES/ directory." msgstr "Завантажте ліцензію та помістіть її в каталог LICENSES/." #: src/reuse/cli/download.py:111 msgid "" "LICENSE must be a valid SPDX License Identifier. You may specify LICENSE " "multiple times to download multiple licenses." msgstr "" "LICENSE має бути дійсним ідентифікатором ліцензії SPDX. Ви можете вказати " "LICENSE кілька разів, щоб завантажити кілька ліцензій." #: src/reuse/cli/download.py:124 msgid "Download all missing licenses detected in the project." msgstr "Завантажте всі відсутні ліцензії, виявлені в проекті." #: src/reuse/cli/download.py:132 msgid "Path to download to." msgstr "Шлях для завантаження." #: src/reuse/cli/download.py:138 msgid "" "Source from which to copy custom LicenseRef- licenses, either a directory " "that contains the file or the file itself." msgstr "" "Джерело, з якого можна скопіювати користувацькі ліцензії LicenseRef, або " "каталог, який містить файл, або сам файл." #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/download.py:145 msgid "LICENSE" msgstr "ЛІЦЕНЗІЯ" #: src/reuse/cli/download.py:161 msgid "The 'LICENSE' argument and '--all' option are mutually exclusive." msgstr "Аргумент 'LICENSE' та опція '--all' є взаємовиключними." #: src/reuse/cli/download.py:173 msgid "Cannot use '--output' with more than one license." msgstr "Не можна використовувати '--output' з більш ніж однією ліцензією." #: src/reuse/cli/annotate.py:66 msgid "Option '--copyright', '--license', or '--contributor' is required." msgstr "Обов'язковою є опція '--copyright', '--license' або '--contributor'." #: src/reuse/cli/annotate.py:127 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/cli/annotate.py:160 #, python-brace-format msgid "" "'{path}' does not support single-line comments, please do not use '--single-" "line'." msgstr "" "'{path}' не підтримує однорядкові коментарі, будь ласка, не використовуйте " "'--single-line'." #: src/reuse/cli/annotate.py:167 #, python-brace-format msgid "" "'{path}' does not support multi-line comments, please do not use '--multi-" "line'." msgstr "" "'{path}' не підтримує багаторядкові коментарі, будь ласка, не використовуйте " "'--multi-line'." #: src/reuse/cli/annotate.py:213 #, python-brace-format msgid "Template '{template}' could not be found." msgstr "Шаблон '{template}' не знайдено." #: src/reuse/cli/annotate.py:236 #, python-brace-format msgid "'{year}' is not a valid year range." msgstr "'{year}' не є дійсним діапазоном років." #: src/reuse/cli/annotate.py:245 #, python-brace-format msgid "" "Your operating system's year is set to '{year}'. This is not four digits, " "and not supported." msgstr "" "Рік вашої операційної системи встановлено на «{year}». Це не чотиризначний " "формат, і він не підтримується." #: src/reuse/cli/annotate.py:287 msgid "Add copyright and licensing into the headers of files." msgstr "" "Додайте до заголовків файлів інформацію про авторські права та ліцензування." #: src/reuse/cli/annotate.py:290 msgid "" "By using --copyright and --license, you can specify which copyright holders " "and licenses to add to the headers of the given files." msgstr "" "За допомогою --copyright і --license ви можете вказати, яких власників " "авторських прав і ліцензій додавати до заголовків цих файлів." #: src/reuse/cli/annotate.py:296 msgid "" "By using --contributor, you can specify people or entity that contributed " "but are not copyright holder of the given files." msgstr "" "За допомогою --contributor ви можете вказати людей або організації, які " "зробили внесок, але не є власниками авторських прав на дані файли." #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:309 msgid "COPYRIGHT" msgstr "АВТОРСЬКЕ ПРАВО" #: src/reuse/cli/annotate.py:312 msgid "Copyright holder, repeatable." msgstr "Власник авторських прав, повторюваний." #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:319 msgid "SPDX_IDENTIFIER" msgstr "SPDX_IDENTIFIER" #: src/reuse/cli/annotate.py:322 msgid "SPDX License Identifier, repeatable." msgstr "Ідентифікатор ліцензії SPDX, повторюваний." #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:328 msgid "CONTRIBUTOR" msgstr "КОНТРИБ'ЮТОР" #: src/reuse/cli/annotate.py:331 msgid "File contributor, repeatable." msgstr "Дописувач файлів, повторюваний." #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:338 msgid "YEAR" msgstr "РІК" #: src/reuse/cli/annotate.py:343 msgid "" "Year of copyright notice. You may define multiple years or a range of years." msgstr "" "Рік повідомлення про авторські права. Ви можете визначити кілька років або " "діапазон років." #: src/reuse/cli/annotate.py:353 msgid "Comment style to use." msgstr "Стиль коментування для використання." #: src/reuse/cli/annotate.py:363 msgid "Copyright prefix to use." msgstr "Префікс авторського права для використання." #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:375 msgid "TEMPLATE" msgstr "ШАБЛОН" #: src/reuse/cli/annotate.py:377 msgid "Name of template to use." msgstr "Назва шаблону для використання." #: src/reuse/cli/annotate.py:384 msgid "Do not include year in copyright notice." msgstr "Не вказуйте рік у повідомленні про авторські права." #: src/reuse/cli/annotate.py:390 msgid "Merge copyright notices if they are identical except for their years." msgstr "" "Об’єднайте повідомлення про авторські права, якщо вони ідентичні, окрім " "років випуску." #: src/reuse/cli/annotate.py:398 msgid "Force single-line comment style." msgstr "Примусовий однорядковий стиль коментарів." #: src/reuse/cli/annotate.py:405 msgid "Force multi-line comment style." msgstr "Примусовий багаторядковий стиль коментарів." #: src/reuse/cli/annotate.py:411 msgid "Add headers to all files under specified directories recursively." msgstr "Рекурсивно додати заголовки до всіх файлів у вказаних каталогах." #: src/reuse/cli/annotate.py:416 msgid "Do not replace the first header in the file; just add a new one." msgstr "Не замінюйте перший заголовок у файлі; просто додайте новий." #: src/reuse/cli/annotate.py:423 msgid "Always write a .license file instead of a header inside the file." msgstr "Завжди записуйте файл .license замість заголовка всередині файлу." #: src/reuse/cli/annotate.py:430 msgid "Write a .license file to files with unrecognised comment styles." msgstr "Запишіть файл .license до файлів з нерозпізнаними стилями коментарів." #: src/reuse/cli/annotate.py:437 msgid "Skip files with unrecognised comment styles." msgstr "Пропускати файли з нерозпізнаними стилями коментарів." #: src/reuse/cli/annotate.py:448 msgid "Skip files that already contain REUSE information." msgstr "Пропускати файли, які вже містять інформацію REUSE." #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:453 msgid "PATH" msgstr "ШЛЯХ" #: src/reuse/cli/annotate.py:510 #, python-brace-format msgid "'{path}' is a binary, therefore using '{new_path}' for the header" msgstr "" "'{path}' є бінарним, тому для заголовка слід використовувати '{new_path}'" #: src/reuse/cli/supported_licenses.py:19 msgid "List all licenses on the SPDX License List." msgstr "Список всіх підтримуваних ліцензій SPDX." #: src/reuse/global_licensing.py:92 #, 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:106 #, 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:118 #, python-brace-format msgid "{attr_name} must not be empty." msgstr "{attr_name} не повинне бути порожнім." #: src/reuse/global_licensing.py:142 #, 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:166 #, python-brace-format msgid "" "The value of 'precedence' must be one of {precedence_vals} (got {received})" msgstr "" "Значення 'precedence' має бути одним з {precedence_vals} (отримано " "{received})" #: src/reuse/global_licensing.py:219 #, python-brace-format msgid "Could not parse '{notice}'" msgstr "Не вдалося проаналізувати '{notice}'" #: src/reuse/_annotate.py:94 #, python-brace-format msgid "Skipped unrecognised file '{path}'" msgstr "Пропущено нерозпізнаний файл '{path}'" #: src/reuse/_annotate.py:100 #, python-brace-format msgid "'{path}' is not recognised; creating '{path}.license'" msgstr "'{path}' не розпізнано; створення '{path}.license'" #: src/reuse/_annotate.py:116 #, python-brace-format msgid "Skipped file '{path}' already containing REUSE information" msgstr "Пропущений файл '{path}' вже містить інформацію REUSE" #: src/reuse/_annotate.py:145 #, python-brace-format msgid "Error: Could not create comment for '{path}'" msgstr "Помилка: не вдалося створити коментар для '{path}'" #: src/reuse/_annotate.py:152 #, 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:163 #, python-brace-format msgid "Successfully changed header of {path}" msgstr "Успішно змінено заголовок {path}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:162 msgid "Repeat for confirmation" msgstr "Повторіть для підтвердження" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:178 msgid "Error: The value you entered was invalid." msgstr "Помилка: Введене значення є недійсним." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:180 #, python-brace-format msgid "Error: {e.message}" msgstr "Помилка: {e.message}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:191 msgid "Error: The two entered values do not match." msgstr "Помилка: Два введених значення не збігаються." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:247 msgid "Error: invalid input" msgstr "Помилка: невірне введення" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:866 msgid "Press any key to continue..." msgstr "Натисніть будь-яку клавішу, щоб продовжити..." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:332 #, python-brace-format msgid "" "Choose from:\n" "\t{choices}" msgstr "" "Оберіть з:\n" "\t{choices}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:369 msgid "{value!r} is not {choice}." msgid_plural "{value!r} is not one of {choices}." msgstr[0] "{value!r} не є {choice}." msgstr[1] "{value!r} не є одним з {choices}." msgstr[2] "{value!r} не є одним з {choices}." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:460 msgid "{value!r} does not match the format {format}." msgid_plural "{value!r} does not match the formats {formats}." msgstr[0] "{value!r} не відповідає формату {format}." msgstr[1] "{value!r} не відповідає форматам {formats}." msgstr[2] "{value!r} не відповідає форматам {formats}." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:482 msgid "{value!r} is not a valid {number_type}." msgstr "{value!r} не є допустимим {number_type}." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:538 #, python-brace-format msgid "{value} is not in the range {range}." msgstr "{value} не знаходиться в діапазоні {range}." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:719 msgid "{value!r} is not a valid boolean. Recognized values: {states}" msgstr "" "{value!r} не є коректним логічним значенням. Розпізнані значення: {states}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:747 msgid "{value!r} is not a valid UUID." msgstr "{value!r} є недійсним UUID." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:937 msgid "file" msgstr "файл" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:939 msgid "directory" msgstr "каталог" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:941 msgid "path" msgstr "шлях" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:988 msgid "{name} {filename!r} does not exist." msgstr "{name} {filename!r} не існує." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:997 msgid "{name} {filename!r} is a file." msgstr "{name} {filename!r} це файл." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:1005 msgid "{name} {filename!r} is a directory." msgstr "{name} {filename!r} є каталогом." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:1014 msgid "{name} {filename!r} is not readable." msgstr "{name} {filename!r} не читабельний." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:1023 msgid "{name} {filename!r} is not writable." msgstr "{name} {filename!r} не записуваний." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:1032 msgid "{name} {filename!r} is not executable." msgstr "{name} {filename!r} не виконуваний." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:1099 #, python-brace-format msgid "{len_type} values are required, but {len_value} was given." msgid_plural "{len_type} values are required, but {len_value} were given." msgstr[0] "Потрібні значення {len_type}, але було вказано {len_value}." msgstr[1] "Потрібні значення {len_type}, але було надано {len_value}." msgstr[2] "Потрібні значення {len_type}, але було надано {len_value}." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/shell_completion.py:332 msgid "Shell completion is not supported for Bash versions older than 4.4." msgstr "Доповнення оболонки не підтримується у версіях Bash старше 4.4." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/shell_completion.py:339 msgid "Couldn't detect Bash version, shell completion is not supported." msgstr "" "Не вдалося визначити версію Bash, завершення оболонки не підтримується." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:50 #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:89 #, python-brace-format msgid "Error: {message}" msgstr "Помилка: {message}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:81 #, python-brace-format msgid "Try '{command} {option}' for help." msgstr "" "Спробуйте скористатися командою '{command} {option}' для отримання допомоги." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:130 #, python-brace-format msgid "Invalid value: {message}" msgstr "Невірне значення: {message}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:132 #, python-brace-format msgid "Invalid value for {param_hint}: {message}" msgstr "Невірне значення для {param_hint}: {message}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:190 msgid "Missing argument" msgstr "Відсутній аргумент" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:192 msgid "Missing option" msgstr "Відсутня опція" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:194 msgid "Missing parameter" msgstr "Відсутній параметр" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:196 #, python-brace-format msgid "Missing {param_type}" msgstr "Відсутній {param_type}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:203 #, python-brace-format msgid "Missing parameter: {param_name}" msgstr "Відсутній параметр: {param_name}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:223 #, python-brace-format msgid "No such option: {name}" msgstr "Немає такої опції: {name}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:235 #, python-brace-format msgid "Did you mean {possibility}?" msgid_plural "(Possible options: {possibilities})" msgstr[0] "Ви мали на увазі {possibility}?" msgstr[1] "(Можливі опції: {possibilities})" msgstr[2] "(Можливі опції: {possibilities})" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:282 msgid "unknown error" msgstr "невідома помилка" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:289 msgid "Could not open file {filename!r}: {message}" msgstr "Не вдалося відкрити файл {filename!r}: {message}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1104 #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1141 #, python-brace-format msgid "{text} {deprecated_message}" msgstr "{text} {deprecated_message}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1160 msgid "Options" msgstr "Параметри" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1222 #, python-brace-format msgid "Got unexpected extra argument ({args})" msgid_plural "Got unexpected extra arguments ({args})" msgstr[0] "Отримано неочікуваний додатковий аргумент ({args})" msgstr[1] "Отримано неочікувані додаткові аргументи ({args})" msgstr[2] "Отримано неочікувані додаткові аргументи ({args})" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1241 msgid "DeprecationWarning: The command {name!r} is deprecated.{extra_message}" msgstr "Попередження про застаріле: Команда {name!r} застаріла.{extra_message}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1425 msgid "Aborted!" msgstr "Перервано!" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1799 msgid "Commands" msgstr "Команди" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1830 msgid "Missing command." msgstr "Пропущена команда." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1908 msgid "No such command {name!r}." msgstr "Такої команди {name!r} не існує." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:2332 msgid "Value must be an iterable." msgstr "Значення повинно бути ітерованим." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:2355 #, python-brace-format msgid "Takes {nargs} values but 1 was given." msgid_plural "Takes {nargs} values but {len} were given." msgstr[0] "Приймає значення {nargs}, але було задано 1." msgstr[1] "Приймає значень {nargs}, але було задано {len}." msgstr[2] "Приймає значень {nargs}, але було задано {len}." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:2505 msgid "" "DeprecationWarning: The {param_type} {name!r} is deprecated.{extra_message}" msgstr "" "Попередження про застаріле: {param_type} {name!r} застарів.{extra_message}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:2956 #, python-brace-format msgid "env var: {var}" msgstr "env var: {var}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:2959 #, python-brace-format msgid "default: {default}" msgstr "за замовчуванням: {default}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:3023 msgid "(dynamic)" msgstr "(динамічно)" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/parser.py:199 msgid "Argument {name!r} takes {nargs} values." msgstr "Аргумент {name!r} приймає значення {nargs}." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/parser.py:381 msgid "Option {name!r} does not take a value." msgstr "Опція {name!r} не приймає значення." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/parser.py:444 msgid "Option {name!r} requires an argument." msgid_plural "Option {name!r} requires {nargs} arguments." msgstr[0] "Опція {name!r} вимагає аргумент." msgstr[1] "Опція {name!r} вимагає аргументи {nargs}." msgstr[2] "Опція {name!r} вимагає аргументів {nargs}." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/_termui_impl.py:608 #, python-brace-format msgid "{editor}: Editing failed" msgstr "{editor}: Редагування не вдалося" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/_termui_impl.py:612 #, python-brace-format msgid "{editor}: Editing failed: {e}" msgstr "{editor}: Редагування не вдалося: {e}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/decorators.py:522 msgid "Show the version and exit." msgstr "Показати версію та вийти." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/decorators.py:548 msgid "Show this message and exit." msgstr "Показати це повідомлення та вийти." #, python-brace-format #~ msgid "{path}: read error\n" #~ msgstr "{path}: помилка читання\n" #, python-brace-format #~ msgid "{lic_path}: deprecated license\n" #~ msgstr "{lic_path}: застаріла ліцензія\n" #, python-brace-format #~ msgid "{lic_path}: license without file extension\n" #~ msgstr "{lic_path}: ліцензія без розширення файлу\n" #, python-brace-format #~ msgid "{lic_path}: unused license\n" #~ msgstr "{lic_path}: невикористана ліцензія\n" #, python-brace-format #~ msgid "" #~ "'{path}' holds an SPDX expression that cannot be parsed, skipping the file" #~ msgstr "" #~ "'{path}' містить вираз SPDX, який неможливо проаналізувати, пропуск файлу" #, python-brace-format #~ msgid "Could not parse '{expression}'" #~ msgstr "Не вдалося проаналізувати '{expression}'" #, python-brace-format #~ msgid "(Deprecated) {text}" #~ msgstr "(Застарілі) {text}" #~ msgid "required" #~ msgstr "необхідно" #~ msgid "Year of copyright statement." #~ msgstr "Рік заяви про авторське право." #, python-brace-format #~ msgid "determining identifier of '{path}'" #~ msgstr "визначення ідентифікатора '{path}'" #~ msgid "--skip-unrecognised has no effect when used together with --style" #~ msgstr "--skip-unrecognised не працює разом із --style" #~ msgid "can't write to '{}'" #~ msgstr "неможливо записати в '{}'" #~ msgid "show program's version number and exit" #~ 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." #~ msgstr "" #~ "Додайте інформацію про авторські права та ліцензування в заголовок одного " #~ "або декількох файлів.\n" #~ "\n" #~ " За допомогою --copyright і --license ви можете вказати, яких власників " #~ "авторських прав і ліцензій додавати до заголовків цих файлів.\n" #~ "\n" #~ " За допомогою --contributor ви можете вказати особу або організацію, яка " #~ "зробила внесок, але не є власником авторських прав на дані файли." #~ msgid "download a license and place it in the LICENSES/ directory" #~ msgstr "завантажити ліцензію та розмістити її в каталозі LICENSES/" #~ msgid "list all non-compliant files" #~ msgstr "список усіх несумісних файлів" #, fuzzy, 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 there any deprecated licenses in the project?\n" #~ "\n" #~ "- Are there any license files in the LICENSES/ directory without file " #~ "extension?\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" #~ "- Are there any read errors?\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" #~ "- Чи всі файли мають дійсні відомості про авторські права та ліцензії?" #~ msgid "list non-compliant files from specified list of files" #~ msgstr "список невідповідних файлів із вказаного списку файлів" #~ msgid "print the project's bill of materials in SPDX format" #~ msgstr "друкувати опис матеріалів проєкту у форматі SPDX" #~ msgid "convert .reuse/dep5 to REUSE.toml" #~ msgstr "конвертувати .reuse/dep5 у REUSE.toml" #~ msgid "'{}' is not a file" #~ msgstr "'{}' не є файлом" #~ msgid "can't open '{}'" #~ msgstr "не вдалося відкрити '{}'" #~ msgid "can't write to directory '{}'" #~ msgstr "неможливо записати в каталог '{}'" #~ msgid "can't read or write '{}'" #~ msgstr "неможливо прочитати чи записати '{}'" #~ msgid "SPDX License Identifier of license" #~ msgstr "Ідентифікатор ліцензії SPDX" #~ msgid "--output has no effect when used together with --all" #~ msgstr "--output не працює разом з --all" #~ msgid "the following arguments are required: license" #~ msgstr "необхідні такі аргументи: license" #~ msgid "usage: " #~ msgstr "використання: " #~ msgid ".__call__() not defined" #~ msgstr ".__call__() не визначено" #, python-format #~ msgid "unknown parser %(parser_name)r (choices: %(choices)s)" #~ msgstr "невідомий парсер %(parser_name)r (варто вибрати: %(choices)s)" #, python-format #~ msgid "argument \"-\" with mode %r" #~ msgstr "аргумент \"-\" з режимом %r" #, python-format #~ msgid "can't open '%(filename)s': %(error)s" #~ msgstr "не вдалося відкрити '%(filename)s': %(error)s" #, python-format #~ msgid "cannot merge actions - two groups are named %r" #~ msgstr "не вдалося об'єднати дії - дві групи називаються %r" #~ msgid "'required' is an invalid argument for positionals" #~ msgstr "'required' — неприпустимий аргумент для позиційних значень" #, python-format #~ msgid "" #~ "invalid option string %(option)r: must start with a character " #~ "%(prefix_chars)r" #~ msgstr "" #~ "недійсний рядок опцій %(option)r: має починатися з символу " #~ "%(prefix_chars)r" #, python-format #~ msgid "dest= is required for options like %r" #~ msgstr "dest= потрібен для таких опцій, як %r" #, python-format #~ msgid "invalid conflict_resolution value: %r" #~ msgstr "недійсне значення conflict_resolution: %r" #, python-format #~ msgid "conflicting option string: %s" #~ msgid_plural "conflicting option strings: %s" #~ msgstr[0] "конфліктний рядок опцій: %s" #~ msgstr[1] "конфліктні рядки опцій: %s" #~ msgstr[2] "конфліктні рядки опцій: %s" #~ msgid "mutually exclusive arguments must be optional" #~ msgstr "взаємозаперечні аргументи повинні бути необов'язковими" #~ msgid "cannot have multiple subparser arguments" #~ msgstr "не може мати кілька аргументів підпарсера" #, python-format #~ msgid "unrecognized arguments: %s" #~ msgstr "нерозпізнані аргументи: %s" #, python-format #~ msgid "not allowed with argument %s" #~ msgstr "не дозволено з аргументом %s" #, python-format #~ msgid "ignored explicit argument %r" #~ msgstr "нехтується явний аргумент %r" #, python-format #~ msgid "the following arguments are required: %s" #~ msgstr "такі аргументи обов'язкові: %s" #, python-format #~ msgid "one of the arguments %s is required" #~ msgstr "один з аргументів %s обов'язковий" #~ msgid "expected at most one argument" #~ msgstr "очікується щонайбільше один аргумент" #~ msgid "expected at least one argument" #~ msgstr "очікується хоча б один аргумент" #, python-format #~ msgid "expected %s argument" #~ msgid_plural "expected %s arguments" #~ msgstr[0] "очікується %s аргумент" #~ msgstr[1] "очікується %s аргументи" #~ msgstr[2] "очікується %s аргументів" #, python-format #~ msgid "ambiguous option: %(option)s could match %(matches)s" #~ msgstr "неоднозначний параметр: %(option)s може відповідати %(matches)s" #, python-format #~ msgid "unexpected option string: %s" #~ msgstr "неочікуваний рядок параметрів: %s" #, python-format #~ msgid "%r is not callable" #~ msgstr "%r не можна викликати" #, python-format #~ msgid "invalid %(type)s value: %(value)r" #~ msgstr "недійсне значення %(type)s: %(value)r" #, python-format #~ msgid "invalid choice: %(value)r (choose from %(choices)s)" #~ msgstr "неприпустимий вибір: %(value)r (варто обрати з %(choices)s)" #, python-brace-format #~ msgid "'{path}' could not be decoded as UTF-8." #~ msgstr "'{path}' не може бути декодовано як UTF-8." #, 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 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 "" #~ "--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-6.2.0/po/zh_Hant.po0000664000175000017500000010230115077707000014634 0ustar alexalex# 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: 2025-10-07 21:23+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" "Language: zh_Hant\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" #: src/reuse/lint.py:40 msgid "BAD LICENSES" msgstr "" #: src/reuse/lint.py:42 msgid "The following licenses are not valid SPDX licenses:" msgstr "" #: src/reuse/lint.py:50 msgid "DEPRECATED LICENSES" msgstr "" #: src/reuse/lint.py:52 msgid "The following licenses are deprecated by SPDX:" msgstr "" #: src/reuse/lint.py:60 msgid "LICENSES WITHOUT FILE EXTENSION" msgstr "" #: src/reuse/lint.py:62 msgid "The following licenses have no file extension:" msgstr "" #: src/reuse/lint.py:70 msgid "MISSING LICENSES" msgstr "" #: src/reuse/lint.py:72 msgid "'{}' found in:" msgstr "" #: src/reuse/lint.py:79 msgid "UNUSED LICENSES" msgstr "" #: src/reuse/lint.py:80 msgid "The following licenses are not used:" msgstr "" #: src/reuse/lint.py:87 msgid "READ ERRORS" msgstr "" #: src/reuse/lint.py:88 msgid "Could not read:" msgstr "" #: src/reuse/lint.py:94 msgid "INVALID SPDX LICENSE EXPRESSIONS" msgstr "" #: src/reuse/lint.py:99 msgid "'{}' contains invalid SPDX License Expressions:" msgstr "" #: src/reuse/lint.py:124 msgid "MISSING COPYRIGHT AND LICENSING INFORMATION" msgstr "" #: src/reuse/lint.py:130 msgid "The following files have no copyright and licensing information:" msgstr "" #: src/reuse/lint.py:141 msgid "The following files have no copyright information:" msgstr "" #: src/reuse/lint.py:150 msgid "The following files have no licensing information:" msgstr "" #: src/reuse/lint.py:157 msgid "SUMMARY" msgstr "" #: src/reuse/lint.py:162 msgid "Bad licenses:" msgstr "" #: src/reuse/lint.py:163 msgid "Deprecated licenses:" msgstr "" #: src/reuse/lint.py:166 msgid "Licenses without file extension:" msgstr "" #: src/reuse/lint.py:169 msgid "Missing licenses:" msgstr "" #: src/reuse/lint.py:170 msgid "Unused licenses:" msgstr "" #: src/reuse/lint.py:171 msgid "Used licenses:" msgstr "" #: src/reuse/lint.py:172 msgid "Read errors:" msgstr "" #: src/reuse/lint.py:173 msgid "Invalid SPDX License Expressions:" msgstr "" #: src/reuse/lint.py:183 msgid "Files with copyright information:" msgstr "" #: src/reuse/lint.py:187 msgid "Files with license information:" msgstr "" #: src/reuse/lint.py:204 msgid "" "Congratulations! Your project is compliant with version {} of the REUSE " "Specification :-)" msgstr "" #: src/reuse/lint.py:211 msgid "" "Unfortunately, your project is not compliant with version {} of the REUSE " "Specification :-(" msgstr "" #: src/reuse/lint.py:218 msgid "RECOMMENDATIONS" msgstr "" #: src/reuse/lint.py:286 #, python-brace-format msgid "missing license '{lic}'" msgstr "" #: src/reuse/lint.py:291 msgid "read error" msgstr "" #: src/reuse/lint.py:296 #, python-brace-format msgid "invalid SPDX License Expression '{expression}'" msgstr "" #: src/reuse/lint.py:303 msgid "no license identifier" msgstr "" #: src/reuse/lint.py:307 msgid "no copyright notice" msgstr "" #: src/reuse/lint.py:345 #, python-brace-format msgid "bad license '{lic}'" msgstr "" #: src/reuse/lint.py:350 msgid "deprecated license" msgstr "" #: src/reuse/lint.py:355 msgid "license without file extension" msgstr "" #: src/reuse/lint.py:360 msgid "unused license" msgstr "" #: src/reuse/project.py:253 #, python-brace-format msgid "'{path}' covered by {global_path}" msgstr "" #: src/reuse/project.py:261 #, python-brace-format msgid "" "'{path}' is covered exclusively by REUSE.toml. Not reading the file contents." 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:355 #, 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:419 #, python-brace-format msgid "{path} does not have a file extension" msgstr "" #: src/reuse/project.py:429 #, 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:441 #, python-brace-format msgid "" "{identifier} is the SPDX License Identifier of both {path} and {other_path}" msgstr "" #: src/reuse/project.py:480 msgid "" "project '{}' is not a VCS repository or required VCS software is not " "installed" msgstr "" #: src/reuse/extract.py:49 #, python-brace-format msgid "" "REUSE_ENCODING_MODULE must have a value in {modules}; it has '{env_module}'. " "Aborting." msgstr "" #: src/reuse/extract.py:69 msgid "" "No supported module that can detect the encoding of files could be " "successfully imported. Re-read the installation instructions for the reuse " "package, or try the following:" msgstr "" #: src/reuse/extract.py:75 msgid "" "- If you are running a Linux distribution, try your equivalent of `apt " "install file` or `dnf install file`." msgstr "" #: src/reuse/extract.py:80 msgid "" "- Run ` pipx install reuse[charset-normalizer]`. Replace 'pipx' with 'pip' " "if you are not using pipx." msgstr "" #: src/reuse/extract.py:451 #, python-brace-format msgid "" "'{path}' was detected as a binary file; not searching its contents for REUSE " "information." msgstr "" #: src/reuse/extract.py:462 #, python-brace-format msgid "" "extracting REUSE information from '{path}' (encoding {encoding}, encoding " "module {module}, newline {newline})" msgstr "" #: src/reuse/header.py:87 msgid "generated comment is missing copyright lines or license expressions" msgstr "" #: src/reuse/report.py:160 #, python-brace-format msgid "Could not read '{path}'" msgstr "" #: src/reuse/report.py:165 #, python-brace-format msgid "Unexpected error occurred while parsing '{path}'" msgstr "" #: src/reuse/report.py:521 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:532 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:543 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:552 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:564 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:575 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:584 msgid "" "Fix invalid SPDX License Expressions: In one or more files there are SPDX " "License Expressions which cannot be parse. Check whether the value that " "follows 'SPDX-License-Identifier:' is correct. If the detected expression is " "not meant to be valid, put it between 'REUSE-IgnoreStart' and 'REUSE-" "IgnoreEnd' comments." msgstr "" #: src/reuse/report.py:595 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/cli/lint.py:28 #, python-brace-format msgid "" "Lint the project directory for REUSE compliance. This version of the tool " "checks against version {reuse_version} of the REUSE Specification. You can " "find the latest version of the specification at ." msgstr "" #: src/reuse/cli/lint.py:34 msgid "Specifically, the following criteria are checked:" msgstr "" #: src/reuse/cli/lint.py:38 msgid "" "- Are there any bad (unrecognised, not compliant with SPDX) licenses in the " "project?" msgstr "" #: src/reuse/cli/lint.py:43 msgid "- Are there any deprecated licenses in the project?" msgstr "" #: src/reuse/cli/lint.py:47 msgid "" "- Are there any license files in the LICENSES/ directory without file " "extension?" msgstr "" #: src/reuse/cli/lint.py:54 msgid "" "- Are any licenses referred to inside of the project, but not included in " "the LICENSES/ directory?" msgstr "" #: src/reuse/cli/lint.py:61 msgid "" "- Are any licenses included in the LICENSES/ directory that are not used " "inside of the project?" msgstr "" #: src/reuse/cli/lint.py:66 msgid "- Are there any read errors?" msgstr "" #: src/reuse/cli/lint.py:69 msgid "- Do all files have valid copyright and licensing information?" msgstr "" #: src/reuse/cli/lint.py:81 src/reuse/cli/lint_file.py:38 msgid "Prevent output." msgstr "" #: src/reuse/cli/lint.py:89 src/reuse/cli/supported_licenses.py:28 msgid "Format output as JSON." msgstr "" #: src/reuse/cli/lint.py:97 msgid "Format output as plain text. (default)" msgstr "" #: src/reuse/cli/lint.py:105 msgid "Format output as errors per line." msgstr "" #: src/reuse/cli/convert_dep5.py:19 msgid "" "Convert .reuse/dep5 into a REUSE.toml file. The generated file is placed in " "the project root and is semantically identical. The .reuse/dep5 file is " "subsequently deleted." msgstr "" #: src/reuse/cli/convert_dep5.py:31 msgid "No '.reuse/dep5' file." msgstr "" #: src/reuse/cli/lint_file.py:25 msgid "" "Lint individual files for REUSE compliance. The specified FILEs are checked " "for the presence of copyright and licensing information, and whether the " "found licenses are included in the LICENSES/ directory." msgstr "" #: src/reuse/cli/lint_file.py:46 msgid "Format output as errors per line. (default)" msgstr "" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/lint_file.py:51 msgid "FILE" msgstr "" #: src/reuse/cli/lint_file.py:65 #, python-brace-format msgid "'{file}' is not inside of '{root}'." msgstr "" #: src/reuse/cli/spdx.py:22 msgid "Generate an SPDX bill of materials." msgstr "" #: src/reuse/cli/spdx.py:32 msgid "File to write to." msgstr "" #: src/reuse/cli/spdx.py:38 msgid "" "Populate the LicenseConcluded field; note that reuse cannot guarantee that " "the field is accurate." msgstr "" #: src/reuse/cli/spdx.py:50 msgid "Name of the person signing off on the SPDX report." msgstr "" #: src/reuse/cli/spdx.py:54 msgid "Name of the organization signing off on the SPDX report." msgstr "" #: src/reuse/cli/spdx.py:81 msgid "" "'--creator-person' or '--creator-organization' is required when '--add-" "license-concluded' is provided." msgstr "" #: src/reuse/cli/spdx.py:96 #, 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 "" #: src/reuse/cli/main.py:36 #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/decorators.py:465 #, python-format msgid "%(prog)s, version %(version)s" msgstr "" #: src/reuse/cli/main.py:39 msgid "" "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." msgstr "" #: src/reuse/cli/main.py:46 msgid "" "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." msgstr "" #: src/reuse/cli/main.py:53 msgid "" "You should have received a copy of the GNU General Public License along with " "this program. If not, see ." msgstr "" #: src/reuse/cli/main.py:61 msgid "" "reuse is a tool for compliance with the REUSE recommendations. See for more information, and " "for the online documentation." msgstr "" #: src/reuse/cli/main.py:68 msgid "" "This version of reuse is compatible with version {} of the REUSE " "Specification." msgstr "" #: src/reuse/cli/main.py:72 msgid "Support the FSFE's work:" msgstr "" #: src/reuse/cli/main.py:77 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/cli/main.py:88 msgid "Enable debug statements." msgstr "" #: src/reuse/cli/main.py:93 msgid "Hide deprecation warnings." msgstr "" #: src/reuse/cli/main.py:98 msgid "Do not skip over Git submodules." msgstr "" #: src/reuse/cli/main.py:103 msgid "Do not skip over Meson subprojects." msgstr "" #: src/reuse/cli/main.py:108 msgid "Do not use multiprocessing." msgstr "" #: src/reuse/cli/main.py:118 msgid "Define root of project." msgstr "" #: src/reuse/cli/common.py:51 #, python-brace-format msgid "" "'{path}' could not be parsed. We received the following error message: " "{message}" msgstr "" #: src/reuse/cli/common.py:87 #, python-brace-format msgid "'{name}' is mutually exclusive with: {opts}" msgstr "" #: src/reuse/cli/common.py:103 msgid "'{}' is not a valid SPDX expression." msgstr "" #: src/reuse/cli/download.py:54 msgid "'{}' is not a valid SPDX License Identifier." msgstr "" #: src/reuse/cli/download.py:61 msgid "Did you mean:" msgstr "" #: src/reuse/cli/download.py:68 msgid "" "See for a list of valid SPDX License " "Identifiers." msgstr "" #: src/reuse/cli/download.py:77 #, python-brace-format msgid "Error: {spdx_identifier} already exists." msgstr "" #: src/reuse/cli/download.py:84 #, python-brace-format msgid "Error: {path} does not exist." msgstr "" #: src/reuse/cli/download.py:88 msgid "Error: Failed to download license." msgstr "" #: src/reuse/cli/download.py:93 msgid "Is your internet connection working?" msgstr "" #: src/reuse/cli/download.py:98 #, python-brace-format msgid "Successfully downloaded {spdx_identifier}." msgstr "" #: src/reuse/cli/download.py:108 msgid "Download a license and place it in the LICENSES/ directory." msgstr "" #: src/reuse/cli/download.py:111 msgid "" "LICENSE must be a valid SPDX License Identifier. You may specify LICENSE " "multiple times to download multiple licenses." msgstr "" #: src/reuse/cli/download.py:124 msgid "Download all missing licenses detected in the project." msgstr "" #: src/reuse/cli/download.py:132 msgid "Path to download to." msgstr "" #: src/reuse/cli/download.py:138 msgid "" "Source from which to copy custom LicenseRef- licenses, either a directory " "that contains the file or the file itself." msgstr "" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/download.py:145 msgid "LICENSE" msgstr "" #: src/reuse/cli/download.py:161 msgid "The 'LICENSE' argument and '--all' option are mutually exclusive." msgstr "" #: src/reuse/cli/download.py:173 msgid "Cannot use '--output' with more than one license." msgstr "" #: src/reuse/cli/annotate.py:66 msgid "Option '--copyright', '--license', or '--contributor' is required." msgstr "" #: src/reuse/cli/annotate.py:127 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/cli/annotate.py:160 #, python-brace-format msgid "" "'{path}' does not support single-line comments, please do not use '--single-" "line'." msgstr "" #: src/reuse/cli/annotate.py:167 #, python-brace-format msgid "" "'{path}' does not support multi-line comments, please do not use '--multi-" "line'." msgstr "" #: src/reuse/cli/annotate.py:213 #, python-brace-format msgid "Template '{template}' could not be found." msgstr "" #: src/reuse/cli/annotate.py:236 #, python-brace-format msgid "'{year}' is not a valid year range." msgstr "" #: src/reuse/cli/annotate.py:245 #, python-brace-format msgid "" "Your operating system's year is set to '{year}'. This is not four digits, " "and not supported." msgstr "" #: src/reuse/cli/annotate.py:287 msgid "Add copyright and licensing into the headers of files." msgstr "" #: src/reuse/cli/annotate.py:290 msgid "" "By using --copyright and --license, you can specify which copyright holders " "and licenses to add to the headers of the given files." msgstr "" #: src/reuse/cli/annotate.py:296 msgid "" "By using --contributor, you can specify people or entity that contributed " "but are not copyright holder of the given files." msgstr "" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:309 msgid "COPYRIGHT" msgstr "" #: src/reuse/cli/annotate.py:312 msgid "Copyright holder, repeatable." msgstr "" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:319 msgid "SPDX_IDENTIFIER" msgstr "" #: src/reuse/cli/annotate.py:322 msgid "SPDX License Identifier, repeatable." msgstr "" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:328 msgid "CONTRIBUTOR" msgstr "" #: src/reuse/cli/annotate.py:331 msgid "File contributor, repeatable." msgstr "" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:338 msgid "YEAR" msgstr "" #: src/reuse/cli/annotate.py:343 msgid "" "Year of copyright notice. You may define multiple years or a range of years." msgstr "" #: src/reuse/cli/annotate.py:353 msgid "Comment style to use." msgstr "" #: src/reuse/cli/annotate.py:363 msgid "Copyright prefix to use." msgstr "" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:375 msgid "TEMPLATE" msgstr "" #: src/reuse/cli/annotate.py:377 msgid "Name of template to use." msgstr "" #: src/reuse/cli/annotate.py:384 msgid "Do not include year in copyright notice." msgstr "" #: src/reuse/cli/annotate.py:390 msgid "Merge copyright notices if they are identical except for their years." msgstr "" #: src/reuse/cli/annotate.py:398 msgid "Force single-line comment style." msgstr "" #: src/reuse/cli/annotate.py:405 msgid "Force multi-line comment style." msgstr "" #: src/reuse/cli/annotate.py:411 msgid "Add headers to all files under specified directories recursively." msgstr "" #: src/reuse/cli/annotate.py:416 msgid "Do not replace the first header in the file; just add a new one." msgstr "" #: src/reuse/cli/annotate.py:423 msgid "Always write a .license file instead of a header inside the file." msgstr "" #: src/reuse/cli/annotate.py:430 msgid "Write a .license file to files with unrecognised comment styles." msgstr "" #: src/reuse/cli/annotate.py:437 msgid "Skip files with unrecognised comment styles." msgstr "" #: src/reuse/cli/annotate.py:448 msgid "Skip files that already contain REUSE information." msgstr "" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:453 msgid "PATH" msgstr "" #: src/reuse/cli/annotate.py:510 #, python-brace-format msgid "'{path}' is a binary, therefore using '{new_path}' for the header" msgstr "" #: src/reuse/cli/supported_licenses.py:19 msgid "List all licenses on the SPDX License List." msgstr "" #: src/reuse/global_licensing.py:92 #, python-brace-format msgid "" "{attr_name} must be a {type_name} (got {value} that is a {value_class})." msgstr "" #: src/reuse/global_licensing.py:106 #, 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:118 #, python-brace-format msgid "{attr_name} must not be empty." msgstr "" #: src/reuse/global_licensing.py:142 #, python-brace-format msgid "{name} must be a {type} (got {value} that is a {value_type})." msgstr "" #: src/reuse/global_licensing.py:166 #, python-brace-format msgid "" "The value of 'precedence' must be one of {precedence_vals} (got {received})" msgstr "" #: src/reuse/global_licensing.py:219 #, python-brace-format msgid "Could not parse '{notice}'" msgstr "" #: src/reuse/_annotate.py:94 #, python-brace-format msgid "Skipped unrecognised file '{path}'" msgstr "" #: src/reuse/_annotate.py:100 #, python-brace-format msgid "'{path}' is not recognised; creating '{path}.license'" msgstr "" #: src/reuse/_annotate.py:116 #, python-brace-format msgid "Skipped file '{path}' already containing REUSE information" msgstr "" #: src/reuse/_annotate.py:145 #, python-brace-format msgid "Error: Could not create comment for '{path}'" msgstr "" #: src/reuse/_annotate.py:152 #, 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:163 #, python-brace-format msgid "Successfully changed header of {path}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:162 msgid "Repeat for confirmation" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:178 msgid "Error: The value you entered was invalid." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:180 #, python-brace-format msgid "Error: {e.message}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:191 msgid "Error: The two entered values do not match." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:247 msgid "Error: invalid input" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:866 msgid "Press any key to continue..." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:332 #, python-brace-format msgid "" "Choose from:\n" "\t{choices}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:369 msgid "{value!r} is not {choice}." msgid_plural "{value!r} is not one of {choices}." msgstr[0] "" msgstr[1] "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:460 msgid "{value!r} does not match the format {format}." msgid_plural "{value!r} does not match the formats {formats}." msgstr[0] "" msgstr[1] "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:482 msgid "{value!r} is not a valid {number_type}." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:538 #, python-brace-format msgid "{value} is not in the range {range}." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:719 msgid "{value!r} is not a valid boolean. Recognized values: {states}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:747 msgid "{value!r} is not a valid UUID." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:937 msgid "file" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:939 msgid "directory" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:941 msgid "path" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:988 msgid "{name} {filename!r} does not exist." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:997 msgid "{name} {filename!r} is a file." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:1005 msgid "{name} {filename!r} is a directory." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:1014 msgid "{name} {filename!r} is not readable." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:1023 msgid "{name} {filename!r} is not writable." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:1032 msgid "{name} {filename!r} is not executable." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:1099 #, python-brace-format msgid "{len_type} values are required, but {len_value} was given." msgid_plural "{len_type} values are required, but {len_value} were given." msgstr[0] "" msgstr[1] "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/shell_completion.py:332 msgid "Shell completion is not supported for Bash versions older than 4.4." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/shell_completion.py:339 msgid "Couldn't detect Bash version, shell completion is not supported." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:50 #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:89 #, python-brace-format msgid "Error: {message}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:81 #, python-brace-format msgid "Try '{command} {option}' for help." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:130 #, python-brace-format msgid "Invalid value: {message}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:132 #, python-brace-format msgid "Invalid value for {param_hint}: {message}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:190 msgid "Missing argument" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:192 msgid "Missing option" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:194 msgid "Missing parameter" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:196 #, python-brace-format msgid "Missing {param_type}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:203 #, python-brace-format msgid "Missing parameter: {param_name}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:223 #, python-brace-format msgid "No such option: {name}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:235 #, python-brace-format msgid "Did you mean {possibility}?" msgid_plural "(Possible options: {possibilities})" msgstr[0] "" msgstr[1] "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:282 msgid "unknown error" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:289 msgid "Could not open file {filename!r}: {message}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1104 #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1141 #, python-brace-format msgid "{text} {deprecated_message}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1160 msgid "Options" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1222 #, python-brace-format msgid "Got unexpected extra argument ({args})" msgid_plural "Got unexpected extra arguments ({args})" msgstr[0] "" msgstr[1] "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1241 msgid "DeprecationWarning: The command {name!r} is deprecated.{extra_message}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1425 msgid "Aborted!" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1799 msgid "Commands" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1830 msgid "Missing command." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1908 msgid "No such command {name!r}." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:2332 msgid "Value must be an iterable." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:2355 #, python-brace-format msgid "Takes {nargs} values but 1 was given." msgid_plural "Takes {nargs} values but {len} were given." msgstr[0] "" msgstr[1] "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:2505 msgid "" "DeprecationWarning: The {param_type} {name!r} is deprecated.{extra_message}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:2956 #, python-brace-format msgid "env var: {var}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:2959 #, python-brace-format msgid "default: {default}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:3023 msgid "(dynamic)" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/parser.py:199 msgid "Argument {name!r} takes {nargs} values." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/parser.py:381 msgid "Option {name!r} does not take a value." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/parser.py:444 msgid "Option {name!r} requires an argument." msgid_plural "Option {name!r} requires {nargs} arguments." msgstr[0] "" msgstr[1] "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/_termui_impl.py:608 #, python-brace-format msgid "{editor}: Editing failed" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/_termui_impl.py:612 #, python-brace-format msgid "{editor}: Editing failed: {e}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/decorators.py:522 msgid "Show the version and exit." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/decorators.py:548 msgid "Show this message and exit." msgstr "" reuse-tool-6.2.0/po/tr.po0000664000175000017500000017703315077707000013704 0ustar alexalex# 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: 2025-10-07 21:23+0000\n" "PO-Revision-Date: 2025-10-22 13:02+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.14-dev\n" #: src/reuse/lint.py:40 msgid "BAD LICENSES" msgstr "KÖTÜ LİSANSLAR" #: src/reuse/lint.py:42 msgid "The following licenses are not valid SPDX licenses:" msgstr "Şu lisanslar geçerli SPDX lisansları değiller:" #: src/reuse/lint.py:50 msgid "DEPRECATED LICENSES" msgstr "MODASI GEÇMİŞ LİSANSLAR" #: src/reuse/lint.py:52 msgid "The following licenses are deprecated by SPDX:" msgstr "Şu lisanslar artık SPDX tarafından kullanılmıyor:" #: src/reuse/lint.py:60 msgid "LICENSES WITHOUT FILE EXTENSION" msgstr "DOSYA UZANTISI OLMAYAN LİSANSLAR" #: src/reuse/lint.py:62 msgid "The following licenses have no file extension:" msgstr "Şu lisansların dosya uzantısı yok:" #: src/reuse/lint.py:70 msgid "MISSING LICENSES" msgstr "EKSİK LİSANSLAR" #: src/reuse/lint.py:72 msgid "'{}' found in:" msgstr "'{}' şurada mevcut:" #: src/reuse/lint.py:79 msgid "UNUSED LICENSES" msgstr "KULLANILMAYAN LİSANSLAR" #: src/reuse/lint.py:80 msgid "The following licenses are not used:" msgstr "Şu lisanslar kullanılmıyor:" #: src/reuse/lint.py:87 msgid "READ ERRORS" msgstr "OKUMA HATALARI" #: src/reuse/lint.py:88 msgid "Could not read:" msgstr "Okunamıyor:" #: src/reuse/lint.py:94 msgid "INVALID SPDX LICENSE EXPRESSIONS" msgstr "GEÇERSİZ SPDX LİSANS İFADELERİ" #: src/reuse/lint.py:99 msgid "'{}' contains invalid SPDX License Expressions:" msgstr "'{}' geçersiz SPDX Lisans İfadeleri içeriyor:" #: src/reuse/lint.py:124 msgid "MISSING COPYRIGHT AND LICENSING INFORMATION" msgstr "EKSİK TELİF HAKKI VE LİSANS BİLGİSİ" #: src/reuse/lint.py:130 msgid "The following files have no copyright and licensing information:" msgstr "Şu dosyalarda telif hakkı ve lisans bilgisi yok:" #: src/reuse/lint.py:141 msgid "The following files have no copyright information:" msgstr "Şu dosyalarda telif hakkı bilgisi yok:" #: src/reuse/lint.py:150 msgid "The following files have no licensing information:" msgstr "Şu dosyalarda lisans bilgisi yok:" #: src/reuse/lint.py:157 msgid "SUMMARY" msgstr "ÖZET" #: src/reuse/lint.py:162 msgid "Bad licenses:" msgstr "Kötü lisanslar:" #: src/reuse/lint.py:163 msgid "Deprecated licenses:" msgstr "Modası geçmiş lisanslar:" #: src/reuse/lint.py:166 msgid "Licenses without file extension:" msgstr "Dosya uzantısı olmayan lisanslar:" #: src/reuse/lint.py:169 msgid "Missing licenses:" msgstr "Eksik lisanslar:" #: src/reuse/lint.py:170 msgid "Unused licenses:" msgstr "Kullanılmayan lisanslar:" #: src/reuse/lint.py:171 msgid "Used licenses:" msgstr "Kullanılan lisanslar:" #: src/reuse/lint.py:172 msgid "Read errors:" msgstr "Okuma hataları:" #: src/reuse/lint.py:173 msgid "Invalid SPDX License Expressions:" msgstr "Geçersiz SPDX Lisans İfadeleri:" #: src/reuse/lint.py:183 msgid "Files with copyright information:" msgstr "Telif hakkı bilgisi içeren dosyalar:" #: src/reuse/lint.py:187 msgid "Files with license information:" msgstr "Lisans bilgisi içeren dosyalar:" #: src/reuse/lint.py:204 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:211 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:218 msgid "RECOMMENDATIONS" msgstr "ÖNERİLER" #: src/reuse/lint.py:286 #, python-brace-format msgid "missing license '{lic}'" msgstr "eksik lisans: '{lic}'" #: src/reuse/lint.py:291 msgid "read error" msgstr "okuma hatası" #: src/reuse/lint.py:296 #, python-brace-format msgid "invalid SPDX License Expression '{expression}'" msgstr "hatalı SPDX Lisans İfadesi: '{expression}'" #: src/reuse/lint.py:303 msgid "no license identifier" msgstr "lisans tanımlayıcı yok" #: src/reuse/lint.py:307 msgid "no copyright notice" msgstr "telif hakkı bildirimi yok" #: src/reuse/lint.py:345 #, python-brace-format msgid "bad license '{lic}'" msgstr "kötü lisans: '{lic}'" #: src/reuse/lint.py:350 msgid "deprecated license" msgstr "kullanımdan kalkmış lisans" #: src/reuse/lint.py:355 msgid "license without file extension" msgstr "dosya uzantısı olmayan lisans" #: src/reuse/lint.py:360 msgid "unused license" msgstr "kullanılmayan lisans" #: src/reuse/project.py:253 #, python-brace-format msgid "'{path}' covered by {global_path}" msgstr "'{path}', {global_path} tarafından kapsanıyor" #: src/reuse/project.py:261 #, python-brace-format msgid "" "'{path}' is covered exclusively by REUSE.toml. Not reading the file contents." msgstr "" "'{path}' yalnızca REUSE.toml tarafından kapsanmaktadır. Dosya içeriği " "okunmuyor." #: 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' kullanımdan kaldırılmıştır. Bunun yerine REUSE.toml " "kullanmanız önerilir. Dönüştürmek için `reuse convert-dep5` komutunu " "kullanın." #: src/reuse/project.py:355 #, python-brace-format msgid "" "Found both '{new_path}' and '{old_path}'. You cannot keep both files " "simultaneously; they are not intercompatible." msgstr "" "Hem ‘{new_path}’ hem de ‘{old_path}’ bulundu. Her iki dosyayı aynı anda " "tutamazsınız; bunlar birbiriyle uyumsuzdur." #: src/reuse/project.py:419 #, python-brace-format msgid "{path} does not have a file extension" msgstr "{path} bir dosya uzantısına sahip değil" #: src/reuse/project.py:429 #, 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:441 #, 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 " "Tanımlayıcısıdır" #: src/reuse/project.py:480 msgid "" "project '{}' is not a VCS repository or required VCS software is not " "installed" msgstr "" "'{}' projesi bir VCS deposu değil veya gerekli VCS yazılımı kurulu değil" #: src/reuse/extract.py:49 #, python-brace-format msgid "" "REUSE_ENCODING_MODULE must have a value in {modules}; it has '{env_module}'. " "Aborting." msgstr "" "REUSE_ENCODING_MODULE, {modules} içinde bir değere sahip olmalıdır; " "‘{env_module}’ değerine sahiptir. İptal ediliyor." #: src/reuse/extract.py:69 msgid "" "No supported module that can detect the encoding of files could be " "successfully imported. Re-read the installation instructions for the reuse " "package, or try the following:" msgstr "" "Dosyaların karakter kodlamasını algılamayan desteklenen hiçbir modül " "başarıyla içe aktarılamadı. Yeniden kullanım paketi için kurulum " "talimatlarını tekrar okuyun veya aşağıdakileri deneyin:" #: src/reuse/extract.py:75 msgid "" "- If you are running a Linux distribution, try your equivalent of `apt " "install file` or `dnf install file`." msgstr "" "- Linux dağıtımı kullanıyorsanız, `apt install file` veya `dnf install file` " "komutlarının eşdeğerini deneyin." #: src/reuse/extract.py:80 msgid "" "- Run ` pipx install reuse[charset-normalizer]`. Replace 'pipx' with 'pip' " "if you are not using pipx." msgstr "" "- ` pipx install reuse[charset-normalizer]` komutunu çalıştırın. Pipx " "kullanmıyorsanız, 'pipx' yerine 'pip' yazın." #: src/reuse/extract.py:451 #, python-brace-format msgid "" "'{path}' was detected as a binary file; not searching its contents for REUSE " "information." msgstr "" "'{path}' ikili dosya olarak algılandı; içeriğinde REUSE bilgisi aranmıyor." #: src/reuse/extract.py:462 #, python-brace-format msgid "" "extracting REUSE information from '{path}' (encoding {encoding}, encoding " "module {module}, newline {newline})" msgstr "" "'{path}' adresinden REUSE bilgilerini ayıklama " "(kodlama {encoding}, kodlama modülü {module}, satır sonu {newline})" #: src/reuse/header.py:87 msgid "generated comment is missing copyright lines or license expressions" msgstr "oluşturulan yorumda telif hakkı satırları veya lisans ifadeleri eksik" #: src/reuse/report.py:160 #, python-brace-format msgid "Could not read '{path}'" msgstr "'{path}' okunamıyor" #: src/reuse/report.py:165 #, python-brace-format msgid "Unexpected error occurred while parsing '{path}'" msgstr "'{path}' çözümlenirken beklenmedik bir hata oluştu" #: src/reuse/report.py:521 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 "" "Kötü lisansları düzeltin: LICENSES dizininde ve/veya ‘SPDX-License-" "Identifier’ etiketleri tarafından sağlanan en az bir lisans geçersizdir. " "Bunlar geçerli SPDX Lisans Tanımlayıcıları değildir veya ‘LicenseRef-’ ile " "başlamamaktadır. Özel lisanslarla ilgili SSS: https://reuse.software/faq/" "#custom-license" #: src/reuse/report.py:532 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 "" "Kullanımdan kalkmış lisansları düzeltin: LICENSES dizinindeki ve/veya ‘SPDX-" "License-Identifier’ etiketi veya ‘.reuse/dep5’ ile sağlanan lisanslardan en " "az biri SPDX tarafından kullanımdan kaldırılmıştır. Güncel liste ve ilgili " "önerilen yeni tanımlayıcılar burada bulunabilir: " #: src/reuse/report.py:543 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 "" "Dosya uzantısı olmayan lisansları düzeltin: 'LICENSES' dizininde en az bir " "lisans metin dosyasının '.txt' dosya uzantısı yoktur. Lütfen dosya(ları) " "uygun şekilde yeniden adlandırın." #: src/reuse/report.py:552 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 "" "Eksik lisansları düzeltin: 'SPDX-License-Identifier' etiketleri tarafından " "sağlanan lisans tanımlayıcılarından en az biri için, 'LICENSES' dizininde " "karşılık gelen lisans metin dosyası bulunmamaktadır. SPDX lisans " "tanımlayıcıları için, eksik olanları almak üzere 'reuse download --all' " "komutunu çalıştırmanız yeterlidir. Özel lisanslar için " "('LicenseRef-' ile başlayan), bu dosyaları kendiniz eklemeniz gerekir." #: src/reuse/report.py:564 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 "" "Kullanılmayan lisansları düzeltin: 'LICENSES' içindeki lisans metin " "dosyalarından en az biri, hiçbir dosya tarafından referans alınmamaktadır " "(örneğin, 'SPDX-License-Identifier' etiketi tarafından). Lütfen, uygun " "şekilde lisanslanmış dosyaları doğru şekilde etiketlediğinizden emin olun " "veya hiçbir dosya veya kod parçacığının bu şekilde lisanslanmadığından " "eminseniz, kullanılmayan lisans metnini silin." #: src/reuse/report.py:575 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 "" "Okuma hatalarını düzeltin: Dizinindeki dosyalardan en az biri araç " "tarafından okunamıyor. Lütfen dosya izinlerini kontrol edin. Etkilenen " "dosyalar, kaydedilen hata mesajlarının bir parçası olarak çıktının en " "üstünde bulunur." #: src/reuse/report.py:584 msgid "" "Fix invalid SPDX License Expressions: In one or more files there are SPDX " "License Expressions which cannot be parse. Check whether the value that " "follows 'SPDX-License-Identifier:' is correct. If the detected expression is " "not meant to be valid, put it between 'REUSE-IgnoreStart' and 'REUSE-" "IgnoreEnd' comments." msgstr "" "Geçersiz SPDX Lisans İfadelerini Düzeltin: Bir veya daha fazla dosyada, " "ayrıştırılamayan SPDX Lisans İfadeleri bulunmaktadır. 'SPDX-License-" "Identifier:' ifadesini takip eden değerin doğru olup olmadığını kontrol " "edin. Algılanan ifadenin geçerli olması amaçlanmıyorsa, onu 'REUSE-" "IgnoreStart' ve 'REUSE-IgnoreEnd' yorumları arasına yerleştirin." #: src/reuse/report.py:595 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 "" "Eksik telif hakkı/lisans bilgilerini düzeltin: Bir veya daha fazla dosya " "için, araç telif hakkı ve/veya lisans bilgilerini bulamıyor. Bunu genellikle " "her dosyaya 'SPDX-FileCopyrightText' ve 'SPDX-License-Identifier' etiketleri " "ekleyerek yapabilirsiniz. Öğretici, bunu yapmanın başka yollarını da " "açıklamaktadır: " #: src/reuse/cli/lint.py:28 #, python-brace-format msgid "" "Lint the project directory for REUSE compliance. This version of the tool " "checks against version {reuse_version} of the REUSE Specification. You can " "find the latest version of the specification at ." msgstr "" "Proje dizinini REUSE uyumluluğu için denetleyin. Bu araç sürümü, REUSE " "Belirtiminin {reuse_version} sürümüne göre denetler. Belirtimin en son " "sürümünü adresinde bulabilirsiniz." #: src/reuse/cli/lint.py:34 msgid "Specifically, the following criteria are checked:" msgstr "Özellikle, aşağıdaki kriterler denetlenir:" #: src/reuse/cli/lint.py:38 msgid "" "- Are there any bad (unrecognised, not compliant with SPDX) licenses in the " "project?" msgstr "- Projede kötü (tanınmayan, SPDX ile uyumlu olmayan) lisanslar var mı?" #: src/reuse/cli/lint.py:43 msgid "- Are there any deprecated licenses in the project?" msgstr "- Projede kullanımdan kaldırılmış lisanslar var mı?" #: src/reuse/cli/lint.py:47 msgid "" "- Are there any license files in the LICENSES/ directory without file " "extension?" msgstr "" "- LICENSES/ dizininde dosya uzantısı olmayan herhangi bir lisans dosyası var " "mı?" #: src/reuse/cli/lint.py:54 msgid "" "- Are any licenses referred to inside of the project, but not included in " "the LICENSES/ directory?" msgstr "" "- Proje içinde atıfta bulunulan ancak LICENSES/ dizininde bulunmayan " "herhangi bir lisans var mı?" #: src/reuse/cli/lint.py:61 msgid "" "- Are any licenses included in the LICENSES/ directory that are not used " "inside of the project?" msgstr "" "- LICENSES/ dizininde, proje içinde kullanılmayan herhangi bir lisans var mı?" #: src/reuse/cli/lint.py:66 msgid "- Are there any read errors?" msgstr "- Okuma hatası var mı?" #: src/reuse/cli/lint.py:69 msgid "- Do all files have valid copyright and licensing information?" msgstr "- Tüm dosyalar geçerli telif hakkı ve lisans bilgilerine sahip mi?" #: src/reuse/cli/lint.py:81 src/reuse/cli/lint_file.py:38 msgid "Prevent output." msgstr "Çıktıyı önle." #: src/reuse/cli/lint.py:89 src/reuse/cli/supported_licenses.py:28 msgid "Format output as JSON." msgstr "Çıktıyı JSON olarak biçimlendir." #: src/reuse/cli/lint.py:97 msgid "Format output as plain text. (default)" msgstr "Çıktıyı düz metin olarak biçimlendir. (varsayılan)" #: src/reuse/cli/lint.py:105 msgid "Format output as errors per line." msgstr "Çıktıyı satır başına hatalar olarak biçimlendir." #: src/reuse/cli/convert_dep5.py:19 msgid "" "Convert .reuse/dep5 into a REUSE.toml file. The generated file is placed in " "the project root and is semantically identical. The .reuse/dep5 file is " "subsequently deleted." msgstr "" ".reuse/dep5 dosyasını REUSE.toml dosyasına dönüştürün. Oluşturulan dosya " "proje kök dizinine yerleştirilir ve anlamsal olarak aynıdır. .reuse/dep5 " "dosyası daha sonra silinir." #: src/reuse/cli/convert_dep5.py:31 msgid "No '.reuse/dep5' file." msgstr "'.reuse/dep5' dosyası yok." #: src/reuse/cli/lint_file.py:25 msgid "" "Lint individual files for REUSE compliance. The specified FILEs are checked " "for the presence of copyright and licensing information, and whether the " "found licenses are included in the LICENSES/ directory." msgstr "" "REUSE uyumluluğu için tek tek dosyaları denetle. Belirtilen DOSYALAR, telif " "hakkı ve lisans bilgilerinin varlığı açısından denetlenir ve bulunan " "lisansların LICENSES/ dizininde yer alıp almadığına bakılır." #: src/reuse/cli/lint_file.py:46 msgid "Format output as errors per line. (default)" msgstr "Çıktıyı satır başına hata olarak biçimlendir. (varsayılan)" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/lint_file.py:51 msgid "FILE" msgstr "DOSYA" #: src/reuse/cli/lint_file.py:65 #, python-brace-format msgid "'{file}' is not inside of '{root}'." msgstr "'{file}' '{root}' içinde değil." #: src/reuse/cli/spdx.py:22 msgid "Generate an SPDX bill of materials." msgstr "SPDX ürün ağacı oluştur." #: src/reuse/cli/spdx.py:32 msgid "File to write to." msgstr "Yazılacak dosya." #: src/reuse/cli/spdx.py:38 msgid "" "Populate the LicenseConcluded field; note that reuse cannot guarantee that " "the field is accurate." msgstr "" "LicenseConcluded alanını doldur; yeniden kullanımın bu alanın doğruluğunu " "garanti etmediğini unutmayın." #: src/reuse/cli/spdx.py:50 msgid "Name of the person signing off on the SPDX report." msgstr "SPDX raporunu imzalayan kişinin adı." #: src/reuse/cli/spdx.py:54 msgid "Name of the organization signing off on the SPDX report." msgstr "SPDX raporunu imzalayan kuruluşun adı." #: src/reuse/cli/spdx.py:81 msgid "" "'--creator-person' or '--creator-organization' is required when '--add-" "license-concluded' is provided." msgstr "" "'--add-license-concluded' seçeneği belirtildiğinde '--creator-person' veya " "'--creator-organization' seçeneği zorunludur." #: src/reuse/cli/spdx.py:96 #, 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}' ortak SPDX dosya deseniyle eşleşmiyor. Önerilen adlandırma " "kurallarını burada bulabilirsiniz: https://spdx.github.io/spdx-spec/" "conformance/#44-standard-data-format-requirements" #: src/reuse/cli/main.py:36 #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/decorators.py:465 #, python-format msgid "%(prog)s, version %(version)s" msgstr "%(prog)s, sürüm %(version)s" #: src/reuse/cli/main.py:39 msgid "" "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." msgstr "" "Bu program özgür bir yazılımdır: Özgür Yazılım Vakfı tarafından yayınlanan " "GNU Genel Kamu Lisansı'nın şartları altında, Lisansın 3. sürümü veya " "(tercihinize bağlı olarak) daha sonraki herhangi bir sürümü altında yeniden " "dağıtabilir ve/veya değiştirebilirsiniz." #: src/reuse/cli/main.py:46 msgid "" "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." msgstr "" "Bu program, yararlı olacağı umuduyla dağıtılmaktadır, ancak HERHANGİ BİR " "GARANTİ VERİLMEMEKTEDİR; TİCARİ ELVERİŞLİLİK veya BELİRLİ BİR AMACA UYGUNLUK " "konusunda zımni garanti bile verilmez. Daha fazla bilgi için GNU Genel Kamu " "Lisansını inceleyin." #: src/reuse/cli/main.py:53 msgid "" "You should have received a copy of the GNU General Public License along with " "this program. If not, see ." msgstr "" "Bu programla birlikte GNU Genel Kamu Lisansı'nın bir kopyasını almış " "olmalısınız. Eğer almadıysanız, adresine " "bakın." #: src/reuse/cli/main.py:61 msgid "" "reuse is a tool for compliance with the REUSE recommendations. See for more information, and " "for the online documentation." msgstr "" "reuse, REUSE önerilerine uyum için kullanılan bir araçtır. Daha fazla bilgi " "için adresini, çevrimiçi belgeler için ise " " adresini ziyaret edin." #: src/reuse/cli/main.py:68 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/cli/main.py:72 msgid "Support the FSFE's work:" msgstr "FSFE'nin çalışmalarını destekleyin:" #: src/reuse/cli/main.py:77 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 "" "Bağışlar, gücümüz ve özerkliğimiz için çok önemlidir. Bağışlar, gerektiğinde " "Özgür Yazılım için çalışmaya devam etmemizi sağlar. Lütfen adresinden bağış yapmayı düşünün." #: src/reuse/cli/main.py:88 msgid "Enable debug statements." msgstr "Hata ayıklama ifadelerini etkinleştir." #: src/reuse/cli/main.py:93 msgid "Hide deprecation warnings." msgstr "Kullanımdan kalkma uyarılarını gizle." #: src/reuse/cli/main.py:98 msgid "Do not skip over Git submodules." msgstr "Git submodullerini atlama." #: src/reuse/cli/main.py:103 msgid "Do not skip over Meson subprojects." msgstr "Meson alt projelerini atlama." #: src/reuse/cli/main.py:108 msgid "Do not use multiprocessing." msgstr "Çoklu işlem kullanma." #: src/reuse/cli/main.py:118 msgid "Define root of project." msgstr "Projenin kök dizinini tanımla." #: src/reuse/cli/common.py:51 #, python-brace-format msgid "" "'{path}' could not be parsed. We received the following error message: " "{message}" msgstr "'{path}' çözümlenemedi. Şu hata mesajını aldık: {message}" #: src/reuse/cli/common.py:87 #, python-brace-format msgid "'{name}' is mutually exclusive with: {opts}" msgstr "'{name}' şununla birlikte kullanılamaz: {opts}" #: src/reuse/cli/common.py:103 msgid "'{}' is not a valid SPDX expression." msgstr "'{}' geçerli bir SPDX ifadesi değildir." #: src/reuse/cli/download.py:54 msgid "'{}' is not a valid SPDX License Identifier." msgstr "'{}' geçerli bir SPDX Lisans Tanımlayıcısı değildir." #: src/reuse/cli/download.py:61 msgid "Did you mean:" msgstr "Şunu mu demek istediniz:" #: src/reuse/cli/download.py:68 msgid "" "See for a list of valid SPDX License " "Identifiers." msgstr "" "Geçerli SPDX Lisans Tanımlayıcılarının listesi için adresine bakın." #: src/reuse/cli/download.py:77 #, python-brace-format msgid "Error: {spdx_identifier} already exists." msgstr "Hata: {spdx_identifier} zaten var." #: src/reuse/cli/download.py:84 #, python-brace-format msgid "Error: {path} does not exist." msgstr "Hata: {path} mevcut değil." #: src/reuse/cli/download.py:88 msgid "Error: Failed to download license." msgstr "Hata: Lisans indirilemedi." #: src/reuse/cli/download.py:93 msgid "Is your internet connection working?" msgstr "İnternet bağlantınız çalışıyor mu?" #: src/reuse/cli/download.py:98 #, python-brace-format msgid "Successfully downloaded {spdx_identifier}." msgstr "{spdx_identifier} başarıyla indirildi." #: src/reuse/cli/download.py:108 msgid "Download a license and place it in the LICENSES/ directory." msgstr "Bir lisans indir ve LICENSES/ dizinine yerleştir." #: src/reuse/cli/download.py:111 msgid "" "LICENSE must be a valid SPDX License Identifier. You may specify LICENSE " "multiple times to download multiple licenses." msgstr "" "LICENSE, geçerli bir SPDX Lisans Tanımlayıcısı olmalıdır. Birden fazla " "lisans indirmek için LICENSE ifadesini birden fazla kez belirtebilirsiniz." #: src/reuse/cli/download.py:124 msgid "Download all missing licenses detected in the project." msgstr "Projede tespit edilen tüm eksik lisansları indir." #: src/reuse/cli/download.py:132 msgid "Path to download to." msgstr "İndirme yolu." #: src/reuse/cli/download.py:138 msgid "" "Source from which to copy custom LicenseRef- licenses, either a directory " "that contains the file or the file itself." msgstr "" "Özel LicenseRef lisanslarını kopyalamak için kaynak, dosyayı içeren bir " "dizin veya dosyanın kendisi." #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/download.py:145 msgid "LICENSE" msgstr "LİSANS" #: src/reuse/cli/download.py:161 msgid "The 'LICENSE' argument and '--all' option are mutually exclusive." msgstr "'LICENSE' argümanı ve '--all' seçeneklerinden biri olmalıdır." #: src/reuse/cli/download.py:173 msgid "Cannot use '--output' with more than one license." msgstr "'--output' birden fazla lisansla birlikte kullanılamaz." #: src/reuse/cli/annotate.py:66 msgid "Option '--copyright', '--license', or '--contributor' is required." msgstr "'--copyright', '--license' veya '--contributor' seçeneği gereklidir." #: src/reuse/cli/annotate.py:127 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 dosyalar tanınmayan bir dosya uzantısına sahiptir. Lütfen '--" "style', '--force-dot-license', '--fallback-dot-license' veya '--skip-" "unrecognised' seçeneklerini kullanın:" #: src/reuse/cli/annotate.py:160 #, python-brace-format msgid "" "'{path}' does not support single-line comments, please do not use '--single-" "line'." msgstr "" "'{path}' tek satırlık yorumları desteklemez, lütfen '--single-line' " "kullanmayın." #: src/reuse/cli/annotate.py:167 #, python-brace-format msgid "" "'{path}' does not support multi-line comments, please do not use '--multi-" "line'." msgstr "" "'{path}' çok satırlı yorumları desteklemez, lütfen '--multi-line' " "kullanmayın." #: src/reuse/cli/annotate.py:213 #, python-brace-format msgid "Template '{template}' could not be found." msgstr "'{template}' şablonu bulunamadı." #: src/reuse/cli/annotate.py:236 #, python-brace-format msgid "'{year}' is not a valid year range." msgstr "'{year}' geçerli bir yıl aralığı değildir." #: src/reuse/cli/annotate.py:245 #, python-brace-format msgid "" "Your operating system's year is set to '{year}'. This is not four digits, " "and not supported." msgstr "" "İşletim sisteminizin yılı '{year}' olarak ayarlanmıştır. Bu dört basamaklı " "bir sayı değildir ve desteklenmemektedir." #: src/reuse/cli/annotate.py:287 msgid "Add copyright and licensing into the headers of files." msgstr "Dosya başlıklarına telif hakkı ve lisans bilgilerini ekle." #: src/reuse/cli/annotate.py:290 msgid "" "By using --copyright and --license, you can specify which copyright holders " "and licenses to add to the headers of the given files." msgstr "" "--copyright ve --license seçeneklerini kullanarak, belirli dosyaların " "başlıklarına hangi telif hakkı sahiplerinin ve lisansların ekleneceğini " "belirtebilirsiniz." #: src/reuse/cli/annotate.py:296 msgid "" "By using --contributor, you can specify people or entity that contributed " "but are not copyright holder of the given files." msgstr "" "--contributor seçeneğini kullanarak, belirli dosyalara katkıda bulunmuş " "ancak telif hakkı sahibi olmayan kişileri veya kuruluşları belirtebilirsiniz." #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:309 msgid "COPYRIGHT" msgstr "TELİF HAKKI" #: src/reuse/cli/annotate.py:312 msgid "Copyright holder, repeatable." msgstr "Telif hakkı sahibi, tekrarlanabilir." #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:319 msgid "SPDX_IDENTIFIER" msgstr "SPDX_TANIMLAYICI" #: src/reuse/cli/annotate.py:322 msgid "SPDX License Identifier, repeatable." msgstr "SPDX Lisans Tanımlayıcı, tekrarlanabilir." #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:328 msgid "CONTRIBUTOR" msgstr "KATKIDA BULUNANLAR" #: src/reuse/cli/annotate.py:331 msgid "File contributor, repeatable." msgstr "Dosyaya katkıda bulunan, tekrarlanabilir." #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:338 msgid "YEAR" msgstr "YIL" #: src/reuse/cli/annotate.py:343 msgid "" "Year of copyright notice. You may define multiple years or a range of years." msgstr "" "Telif hakkı bildirimi yılı. Birden fazla yıl veya bir yıl aralığı " "tanımlayabilirsiniz." #: src/reuse/cli/annotate.py:353 msgid "Comment style to use." msgstr "Kullanılacak yorum biçimi." #: src/reuse/cli/annotate.py:363 msgid "Copyright prefix to use." msgstr "Kullanılacak telif hakkı ön eki." #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:375 msgid "TEMPLATE" msgstr "ŞABLON" #: src/reuse/cli/annotate.py:377 msgid "Name of template to use." msgstr "Kullanılacak şablonun adı." #: src/reuse/cli/annotate.py:384 msgid "Do not include year in copyright notice." msgstr "Telif hakkı beyanına yıl eklenmesin." #: src/reuse/cli/annotate.py:390 msgid "Merge copyright notices if they are identical except for their years." msgstr "" "Telif hakkı beyanları yıl dışında tamamen aynıysa telif hakkı bildirimlerini " "birleştir." #: src/reuse/cli/annotate.py:398 msgid "Force single-line comment style." msgstr "Tek satırlık yorum biçimini zorla." #: src/reuse/cli/annotate.py:405 msgid "Force multi-line comment style." msgstr "Çok satırlı yorum biçimini zorla." #: src/reuse/cli/annotate.py:411 msgid "Add headers to all files under specified directories recursively." msgstr "" "Belirtilen dizinler altındaki tüm dosyalara yinelemeli olarak başlıklar ekle." #: src/reuse/cli/annotate.py:416 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 başlık ekle." #: src/reuse/cli/annotate.py:423 msgid "Always write a .license file instead of a header inside the file." msgstr "Dosyada başlık yerine her zaman bir .license dosyası yaz." #: src/reuse/cli/annotate.py:430 msgid "Write a .license file to files with unrecognised comment styles." msgstr "" "Tanınmayan yorum biçimleri içeren dosyalar için bir .license dosyası yaz." #: src/reuse/cli/annotate.py:437 msgid "Skip files with unrecognised comment styles." msgstr "Tanınmayan yorum biçimleri içeren dosyaları atla." #: src/reuse/cli/annotate.py:448 msgid "Skip files that already contain REUSE information." msgstr "REUSE bilgisi içeren dosyaları atla." #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:453 msgid "PATH" msgstr "YOL" #: src/reuse/cli/annotate.py:510 #, 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/cli/supported_licenses.py:19 msgid "List all licenses on the SPDX License List." msgstr "SPDX Lisans Listesi'ndeki tüm lisansları listele." #: src/reuse/global_licensing.py:92 #, python-brace-format msgid "" "{attr_name} must be a {type_name} (got {value} that is a {value_class})." msgstr "" "{attr_name} bir {type_name} olmalıdır " "(bir {value_class} olan {value} değerine sahiptir)." #: src/reuse/global_licensing.py:106 #, 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} koleksiyonundaki öğe {type_name} olmalıdır " "({item_class} olan {item_value} elde edildi)." #: src/reuse/global_licensing.py:118 #, python-brace-format msgid "{attr_name} must not be empty." msgstr "{attr_name} boş bırakılmamalıdır." #: src/reuse/global_licensing.py:142 #, python-brace-format msgid "{name} must be a {type} (got {value} that is a {value_type})." msgstr "" "{name} bir {type} olmalıdır ({value_type} olan {value} değerine sahiptir)." #: src/reuse/global_licensing.py:166 #, python-brace-format msgid "" "The value of 'precedence' must be one of {precedence_vals} (got {received})" msgstr "" "'öncelik' değeri {precedence_vals} değerlerinden biri olmalıdır " "(elde edilen değer {received})" #: src/reuse/global_licensing.py:219 #, python-brace-format msgid "Could not parse '{notice}'" msgstr "'{notice}' çözümlenemiyor" #: src/reuse/_annotate.py:94 #, python-brace-format msgid "Skipped unrecognised file '{path}'" msgstr "Tanımlanamayan '{path}' dosyası atlandı" #: src/reuse/_annotate.py:100 #, python-brace-format msgid "'{path}' is not recognised; creating '{path}.license'" msgstr "'{path}‘ tanımlanamadı; '{path}.license' dosyası oluşturuluyor" #: src/reuse/_annotate.py:116 #, 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:145 #, python-brace-format msgid "Error: Could not create comment for '{path}'" msgstr "Hata: '{path}' için yorum oluşturulamıyor" #: src/reuse/_annotate.py:152 #, 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:163 #, python-brace-format msgid "Successfully changed header of {path}" msgstr "{path} başlığı başarılı bir şekilde değiştirildi" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:162 msgid "Repeat for confirmation" msgstr "Onay için tekrarlayın" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:178 msgid "Error: The value you entered was invalid." msgstr "Hata: Girdiğiniz değer geçersiz." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:180 #, python-brace-format msgid "Error: {e.message}" msgstr "Hata: {e.message}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:191 msgid "Error: The two entered values do not match." msgstr "Hata: Girilen iki değer birbiriyle uyuşmuyor." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:247 msgid "Error: invalid input" msgstr "Hata: geçersiz giriş" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:866 msgid "Press any key to continue..." msgstr "Devam etmek için bir tuşa basın..." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:332 #, python-brace-format msgid "" "Choose from:\n" "\t{choices}" msgstr "" "Aşağıdakilerden seçin:\n" "\t{choices}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:369 msgid "{value!r} is not {choice}." msgid_plural "{value!r} is not one of {choices}." msgstr[0] "{value!r} {choice} değildir." msgstr[1] "{value!r} {choice}'lardan biri değildir." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:460 msgid "{value!r} does not match the format {format}." msgid_plural "{value!r} does not match the formats {formats}." msgstr[0] "{value!r} {format} biçimiyle eşleşmiyor." msgstr[1] "{value!r} {formats} biçimleriyle eşleşmiyor." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:482 msgid "{value!r} is not a valid {number_type}." msgstr "{value!r} geçerli bir {number_type} değildir." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:538 #, python-brace-format msgid "{value} is not in the range {range}." msgstr "{value} {range} aralığında değildir." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:719 msgid "{value!r} is not a valid boolean. Recognized values: {states}" msgstr "{value!r} geçerli bir boolean değildir. Tanınan değerler: {states}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:747 msgid "{value!r} is not a valid UUID." msgstr "{value!r} geçerli bir UUID değildir." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:937 msgid "file" msgstr "dosya" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:939 msgid "directory" msgstr "dizin" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:941 msgid "path" msgstr "yol" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:988 msgid "{name} {filename!r} does not exist." msgstr "{name} {filename!r} mevcut değil." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:997 msgid "{name} {filename!r} is a file." msgstr "{name} {filename!r} bir dosya." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:1005 msgid "{name} {filename!r} is a directory." msgstr "{name} {filename!r} bir dizin." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:1014 msgid "{name} {filename!r} is not readable." msgstr "{name} {filename!r} okunabilir değil." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:1023 msgid "{name} {filename!r} is not writable." msgstr "{name} {filename!r} yazılabilir değil." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:1032 msgid "{name} {filename!r} is not executable." msgstr "{name} {filename!r} çalıştırılabilir değil." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:1099 #, python-brace-format msgid "{len_type} values are required, but {len_value} was given." msgid_plural "{len_type} values are required, but {len_value} were given." msgstr[0] "{len_type} değeri gerekli, ancak {len_value} verilmiş." msgstr[1] "{len_type} değerleri gerekli, ancak {len_value} verilmiş." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/shell_completion.py:332 msgid "Shell completion is not supported for Bash versions older than 4.4." msgstr "Kabuk tamamlama, 4.4'ten eski Bash sürümlerinde desteklenmemektedir." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/shell_completion.py:339 msgid "Couldn't detect Bash version, shell completion is not supported." msgstr "Bash sürümü algılanamadı, kabuk tamamlama desteklenmiyor." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:50 #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:89 #, python-brace-format msgid "Error: {message}" msgstr "Hata: {message}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:81 #, python-brace-format msgid "Try '{command} {option}' for help." msgstr "Yardım için '{command} {option}' deneyin." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:130 #, python-brace-format msgid "Invalid value: {message}" msgstr "Geçersiz değer: {message}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:132 #, python-brace-format msgid "Invalid value for {param_hint}: {message}" msgstr "{param_hint} için geçersiz değer: {message}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:190 msgid "Missing argument" msgstr "Eksik argüman" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:192 msgid "Missing option" msgstr "Eksik seçenek" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:194 msgid "Missing parameter" msgstr "Eksik parametre" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:196 #, python-brace-format msgid "Missing {param_type}" msgstr "{param_type} eksik" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:203 #, python-brace-format msgid "Missing parameter: {param_name}" msgstr "Eksik parametre: {param_name}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:223 #, python-brace-format msgid "No such option: {name}" msgstr "Böyle bir seçenek yok: {name}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:235 #, python-brace-format msgid "Did you mean {possibility}?" msgid_plural "(Possible options: {possibilities})" msgstr[0] "{possibility} mi demek istediniz?" msgstr[1] "(Olası seçenekler: {possibilities})" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:282 msgid "unknown error" msgstr "bilinmeyen hata" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:289 msgid "Could not open file {filename!r}: {message}" msgstr "{filename!r} dosyası açılamadı: {message}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1104 #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1141 #, python-brace-format msgid "{text} {deprecated_message}" msgstr "{text} {deprecated_message}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1160 msgid "Options" msgstr "Seçenekler" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1222 #, python-brace-format msgid "Got unexpected extra argument ({args})" msgid_plural "Got unexpected extra arguments ({args})" msgstr[0] "Beklenmedik ekstra argüman ({args})" msgstr[1] "Beklenmedik ekstra argümanlar ({args})" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1241 msgid "DeprecationWarning: The command {name!r} is deprecated.{extra_message}" msgstr "" "KullanımdanKaldırıldıUyarısı: {name!r} komutu kullanımdan " "kaldırılmıştır.{extra_message}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1425 msgid "Aborted!" msgstr "İptal edildi!" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1799 msgid "Commands" msgstr "Komutlar" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1830 msgid "Missing command." msgstr "Eksik komut." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1908 msgid "No such command {name!r}." msgstr "{name!r} adlı komut yok." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:2332 msgid "Value must be an iterable." msgstr "Değer yinelenebilir olmalıdır." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:2355 #, python-brace-format msgid "Takes {nargs} values but 1 was given." msgid_plural "Takes {nargs} values but {len} were given." msgstr[0] "{nargs} değer alır, ancak 1 değer verildi." msgstr[1] "{nargs} değer alır, ancak {len} değer verildi." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:2505 msgid "" "DeprecationWarning: The {param_type} {name!r} is deprecated.{extra_message}" msgstr "" "KullanımdanKaldırıldıUyarısı: {param_type} {name!r} komutu kullanımdan " "kaldırılmıştır.{extra_message}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:2956 #, python-brace-format msgid "env var: {var}" msgstr "ortam değişkeni: {var}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:2959 #, python-brace-format msgid "default: {default}" msgstr "varsayılan: {default}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:3023 msgid "(dynamic)" msgstr "(dinamik)" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/parser.py:199 msgid "Argument {name!r} takes {nargs} values." msgstr "{name!r} argümanı {nargs} değer alır." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/parser.py:381 msgid "Option {name!r} does not take a value." msgstr "{name!r} seçeneği bir değer almıyor." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/parser.py:444 msgid "Option {name!r} requires an argument." msgid_plural "Option {name!r} requires {nargs} arguments." msgstr[0] "{name!r} seçeneği bir argüman gerektirir." msgstr[1] "{name!r} seçeneği {nargs} argüman gerektirir." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/_termui_impl.py:608 #, python-brace-format msgid "{editor}: Editing failed" msgstr "{editor}: Düzenleme başarısız oldu" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/_termui_impl.py:612 #, python-brace-format msgid "{editor}: Editing failed: {e}" msgstr "{editor}: Düzenleme başarısız oldu: {e}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/decorators.py:522 msgid "Show the version and exit." msgstr "Sürümü göster ve çık." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/decorators.py:548 msgid "Show this message and exit." msgstr "Bu mesajı göster ve çık." #, fuzzy, python-brace-format #~ msgid "{path}: read error\n" #~ msgstr "Modası geçmiş lisanslar:" #, fuzzy, python-brace-format #~ msgid "{lic_path}: deprecated license\n" #~ msgstr "Modası geçmiş lisanslar:" #, fuzzy, python-brace-format #~ msgid "{lic_path}: license without file extension\n" #~ msgstr "Dosya uzantısı olmayan lisanslar:" #, fuzzy, python-brace-format #~ msgid "{lic_path}: unused license\n" #~ msgstr "Kullanılmayan lisanslar:" #, 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" #, python-brace-format #~ msgid "Could not parse '{expression}'" #~ msgstr "'{expression}' çözümlenemiyor" #, python-brace-format #~ msgid "(Deprecated) {text}" #~ msgstr "(Kullanımdan kaldırıldı) {text}" #~ msgid "required" #~ msgstr "gerekli" #~ msgid "Year of copyright statement." #~ msgstr "Telif hakkı beyanının yılı." #, python-brace-format #~ msgid "determining identifier of '{path}'" #~ msgstr "'{path}' kimliği belirleniyor" #~ msgid "--skip-unrecognised has no effect when used together with --style" #~ msgstr "--skip-unrecognised, --style ile kullanıldığında etkisizdir" #~ msgid "can't write to '{}'" #~ msgstr "'{}' yazılamıyor" #~ msgid "show program's version number and exit" #~ msgstr "programın sürüm numarasını gösterip çıkar" #~ msgid "download a license and place it in the LICENSES/ directory" #~ msgstr "bir lisans indirir ve LICENSES/ dizinine yerleştirir" #~ msgid "list all non-compliant files" #~ msgstr "bütün uyumsuz dosyaları listeler" #, fuzzy, 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 there any deprecated licenses in the project?\n" #~ "\n" #~ "- Are there any license files in the LICENSES/ directory without file " #~ "extension?\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" #~ "- Are there any read errors?\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?" #~ msgid "print the project's bill of materials in SPDX format" #~ msgstr "projenin malzeme listesini SPDX biçiminde yazdırır" #~ msgid "'{}' is not a file" #~ msgstr "'{}' bir dosya değil" #~ msgid "can't open '{}'" #~ msgstr "'{}' açılamıyor" #~ msgid "can't write to directory '{}'" #~ msgstr "'{}' dizinine yazılamıyor" #~ msgid "can't read or write '{}'" #~ msgstr "'{}' okunamıyor veya yazılamıyor" #~ msgid "SPDX License Identifier of license" #~ msgstr "Lisansın SPDX Lisans Kimliği" #~ msgid "--output has no effect when used together with --all" #~ msgstr "--all ile birlikte kullanıldığında --output'un bir etkisi yok" #~ msgid "the following arguments are required: license" #~ msgstr "şu değişkenler gerekiyor: license" #~ msgid "usage: " #~ msgstr "kullanım: " #~ msgid ".__call__() not defined" #~ msgstr ".__call__() tanımlı değil" #, python-format #~ msgid "unknown parser %(parser_name)r (choices: %(choices)s)" #~ msgstr "bilinmeyen ayrıştıcı %(parser_name)r (choices: %(choices)s)" #, python-format #~ msgid "argument \"-\" with mode %r" #~ msgstr "%r kipine sahip \"-\" argümanı" #, python-format #~ msgid "can't open '%(filename)s': %(error)s" #~ msgstr "'%(filename)s' açılamıyor: %(error)s" #, python-format #~ msgid "cannot merge actions - two groups are named %r" #~ msgstr "eylemler birleştirilemiyor - iki grup %r olarak adlandırılmış" #~ msgid "'required' is an invalid argument for positionals" #~ msgstr "'required' konumsal parametre için hatalı bir değişkendir" #, 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ı" #, python-format #~ msgid "dest= is required for options like %r" #~ msgstr "%r gibi seçenekler için dest= gerekli" #, python-format #~ msgid "invalid conflict_resolution value: %r" #~ msgstr "hatalı conflict_resolution değeri: %r" #, 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" #~ msgid "mutually exclusive arguments must be optional" #~ msgstr "ayrık seçenekler isteğe bağlı olmalı" #~ msgid "cannot have multiple subparser arguments" #~ msgstr "birden fazla altayrıştırıcı değişkeni içeremez" #, python-format #~ msgid "unrecognized arguments: %s" #~ msgstr "tanımlanamayan değişkenler: %s" #, python-format #~ msgid "not allowed with argument %s" #~ msgstr "%s değişkeniyle izin yok" #, python-format #~ msgid "ignored explicit argument %r" #~ msgstr "açık %r değişkeni yok sayıldı" #, python-format #~ msgid "the following arguments are required: %s" #~ msgstr "şu değişkenler gereklidir: %s" #, python-format #~ msgid "one of the arguments %s is required" #~ msgstr "%s değişkenlerinden biri gereklidir" #~ msgid "expected at most one argument" #~ msgstr "en fazla bir değişken bekleniyor" #~ msgid "expected at least one argument" #~ msgstr "en azından bir değişken bekleniyor" #, 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" #, python-format #~ msgid "ambiguous option: %(option)s could match %(matches)s" #~ msgstr "belirsiz seçenek: %(option)s, %(matches)s ile eşleşebilir" #, python-format #~ msgid "unexpected option string: %s" #~ msgstr "beklenmedik seçenek karakter dizisi: %s" #, python-format #~ msgid "%r is not callable" #~ msgstr "%r çağrılabilir değil" #, python-format #~ msgid "invalid %(type)s value: %(value)r" #~ msgstr "hatalı %(type)s değeri: %(value)r" #, python-format #~ msgid "invalid choice: %(value)r (choose from %(choices)s)" #~ msgstr "hatalı tercih: %(value)r (%(choices)s seçilmelidir)" #, fuzzy, python-brace-format #~ msgid "'{path}' could not be decoded as UTF-8." #~ msgstr ".reuse/dep5 utf-8 olarak çözümlenemiyor" #, 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 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 "" #~ "--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-6.2.0/po/reuse.pot.license0000664000175000017500000000015415077707000016174 0ustar alexalexSPDX-FileCopyrightText: 2023 Carmen Bianca BAKKER SPDX-License-Identifier: CC0-1.0 reuse-tool-6.2.0/po/ja.po0000664000175000017500000013260015077707000013640 0ustar alexalex# 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: 2025-10-07 21:23+0000\n" "PO-Revision-Date: 2025-04-23 12:01+0000\n" "Last-Translator: Shun Sakai \n" "Language-Team: Japanese \n" "Language: ja\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "X-Generator: Weblate 5.11.1-dev\n" #: src/reuse/lint.py:40 #, fuzzy msgid "BAD LICENSES" msgstr "LICENSE" #: src/reuse/lint.py:42 #, fuzzy msgid "The following licenses are not valid SPDX licenses:" msgstr "- 全てのファイルに有効な著作権とライセンスの情報がありますか?" #: src/reuse/lint.py:50 msgid "DEPRECATED LICENSES" msgstr "" #: src/reuse/lint.py:52 msgid "The following licenses are deprecated by SPDX:" msgstr "" #: src/reuse/lint.py:60 msgid "LICENSES WITHOUT FILE EXTENSION" msgstr "" #: src/reuse/lint.py:62 msgid "The following licenses have no file extension:" msgstr "" #: src/reuse/lint.py:70 #, fuzzy msgid "MISSING LICENSES" msgstr "LICENSE" #: src/reuse/lint.py:72 msgid "'{}' found in:" msgstr "" #: src/reuse/lint.py:79 #, fuzzy msgid "UNUSED LICENSES" msgstr "LICENSE" #: src/reuse/lint.py:80 msgid "The following licenses are not used:" msgstr "" #: src/reuse/lint.py:87 msgid "READ ERRORS" msgstr "" #: src/reuse/lint.py:88 msgid "Could not read:" msgstr "" #: src/reuse/lint.py:94 msgid "INVALID SPDX LICENSE EXPRESSIONS" msgstr "" #: src/reuse/lint.py:99 #, fuzzy msgid "'{}' contains invalid SPDX License Expressions:" msgstr "「{}」は有効なSPDX表現ではありません。" #: src/reuse/lint.py:124 msgid "MISSING COPYRIGHT AND LICENSING INFORMATION" msgstr "" #: src/reuse/lint.py:130 #, fuzzy msgid "The following files have no copyright and licensing information:" msgstr "- 全てのファイルに有効な著作権とライセンスの情報がありますか?" #: src/reuse/lint.py:141 #, fuzzy msgid "The following files have no copyright information:" msgstr "- 全てのファイルに有効な著作権とライセンスの情報がありますか?" #: src/reuse/lint.py:150 #, fuzzy msgid "The following files have no licensing information:" msgstr "- 全てのファイルに有効な著作権とライセンスの情報がありますか?" #: src/reuse/lint.py:157 msgid "SUMMARY" msgstr "" #: src/reuse/lint.py:162 msgid "Bad licenses:" msgstr "" #: src/reuse/lint.py:163 #, fuzzy msgid "Deprecated licenses:" msgstr "(非推奨){text}" #: src/reuse/lint.py:166 msgid "Licenses without file extension:" msgstr "" #: src/reuse/lint.py:169 #, fuzzy msgid "Missing licenses:" msgstr "オプションが不足しています" #: src/reuse/lint.py:170 msgid "Unused licenses:" msgstr "" #: src/reuse/lint.py:171 msgid "Used licenses:" msgstr "" #: src/reuse/lint.py:172 msgid "Read errors:" msgstr "" #: src/reuse/lint.py:173 #, fuzzy msgid "Invalid SPDX License Expressions:" msgstr "「{}」は有効なSPDX表現ではありません。" #: src/reuse/lint.py:183 msgid "Files with copyright information:" msgstr "" #: src/reuse/lint.py:187 msgid "Files with license information:" msgstr "" #: src/reuse/lint.py:204 #, fuzzy msgid "" "Congratulations! Your project is compliant with version {} of the REUSE " "Specification :-)" msgstr "このバージョンのreuseはREUSE仕様のバージョン{}と互換性があります。" #: src/reuse/lint.py:211 #, fuzzy msgid "" "Unfortunately, your project is not compliant with version {} of the REUSE " "Specification :-(" msgstr "このバージョンのreuseはREUSE仕様のバージョン{}と互換性があります。" #: src/reuse/lint.py:218 msgid "RECOMMENDATIONS" msgstr "" #: src/reuse/lint.py:286 #, fuzzy, python-brace-format msgid "missing license '{lic}'" msgstr "「{}」は有効なSPDXライセンス識別子ではありません。" #: src/reuse/lint.py:291 msgid "read error" msgstr "" #: src/reuse/lint.py:296 #, fuzzy, python-brace-format msgid "invalid SPDX License Expression '{expression}'" msgstr "「{}」は有効なSPDX表現ではありません。" #: src/reuse/lint.py:303 #, fuzzy msgid "no license identifier" msgstr "「{}」は有効なSPDXライセンス識別子ではありません。" #: src/reuse/lint.py:307 #, fuzzy msgid "no copyright notice" msgstr "著作権宣言に年を含めません。" #: src/reuse/lint.py:345 #, fuzzy, python-brace-format msgid "bad license '{lic}'" msgstr "「{}」は有効なSPDXライセンス識別子ではありません。" #: src/reuse/lint.py:350 #, fuzzy msgid "deprecated license" msgstr "(非推奨){text}" #: src/reuse/lint.py:355 msgid "license without file extension" msgstr "" #: src/reuse/lint.py:360 msgid "unused license" msgstr "" #: src/reuse/project.py:253 #, python-brace-format msgid "'{path}' covered by {global_path}" msgstr "" #: src/reuse/project.py:261 #, python-brace-format msgid "" "'{path}' is covered exclusively by REUSE.toml. Not reading the file contents." 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:355 #, 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:419 #, python-brace-format msgid "{path} does not have a file extension" msgstr "" #: src/reuse/project.py:429 #, 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:441 #, python-brace-format msgid "" "{identifier} is the SPDX License Identifier of both {path} and {other_path}" msgstr "" #: src/reuse/project.py:480 msgid "" "project '{}' is not a VCS repository or required VCS software is not " "installed" msgstr "" #: src/reuse/extract.py:49 #, python-brace-format msgid "" "REUSE_ENCODING_MODULE must have a value in {modules}; it has '{env_module}'. " "Aborting." msgstr "" #: src/reuse/extract.py:69 msgid "" "No supported module that can detect the encoding of files could be " "successfully imported. Re-read the installation instructions for the reuse " "package, or try the following:" msgstr "" #: src/reuse/extract.py:75 msgid "" "- If you are running a Linux distribution, try your equivalent of `apt " "install file` or `dnf install file`." msgstr "" #: src/reuse/extract.py:80 msgid "" "- Run ` pipx install reuse[charset-normalizer]`. Replace 'pipx' with 'pip' " "if you are not using pipx." msgstr "" #: src/reuse/extract.py:451 #, python-brace-format msgid "" "'{path}' was detected as a binary file; not searching its contents for REUSE " "information." msgstr "" #: src/reuse/extract.py:462 #, python-brace-format msgid "" "extracting REUSE information from '{path}' (encoding {encoding}, encoding " "module {module}, newline {newline})" msgstr "" #: src/reuse/header.py:87 msgid "generated comment is missing copyright lines or license expressions" msgstr "" #: src/reuse/report.py:160 #, python-brace-format msgid "Could not read '{path}'" msgstr "" #: src/reuse/report.py:165 #, python-brace-format msgid "Unexpected error occurred while parsing '{path}'" msgstr "" #: src/reuse/report.py:521 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:532 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:543 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:552 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:564 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:575 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:584 msgid "" "Fix invalid SPDX License Expressions: In one or more files there are SPDX " "License Expressions which cannot be parse. Check whether the value that " "follows 'SPDX-License-Identifier:' is correct. If the detected expression is " "not meant to be valid, put it between 'REUSE-IgnoreStart' and 'REUSE-" "IgnoreEnd' comments." msgstr "" #: src/reuse/report.py:595 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/cli/lint.py:28 #, python-brace-format msgid "" "Lint the project directory for REUSE compliance. This version of the tool " "checks against version {reuse_version} of the REUSE Specification. You can " "find the latest version of the specification at ." msgstr "" "プロジェクトディレクトリのREUSE準拠について静的解析を行います。このバージョン" "のツールはREUSE仕様のバージョン{reuse_version}に基づいて検査します。仕様の最" "新版はで確認できます。" #: src/reuse/cli/lint.py:34 msgid "Specifically, the following criteria are checked:" msgstr "具体的には、以下の基準が検査されます。" #: src/reuse/cli/lint.py:38 msgid "" "- Are there any bad (unrecognised, not compliant with SPDX) licenses in the " "project?" msgstr "" "- プロジェクトに悪い(識別できない、SPDXに準拠していない)ライセンスはありま" "すか?" #: src/reuse/cli/lint.py:43 msgid "- Are there any deprecated licenses in the project?" msgstr "- プロジェクトに非推奨ライセンスはありますか?" #: src/reuse/cli/lint.py:47 msgid "" "- Are there any license files in the LICENSES/ directory without file " "extension?" msgstr "- LICENSES/ディレクトリに拡張子のないライセンスファイルはありますか?" #: src/reuse/cli/lint.py:54 msgid "" "- Are any licenses referred to inside of the project, but not included in " "the LICENSES/ directory?" msgstr "" "- プロジェクト内で参照されているが、LICENSES/ディレクトリに含まれていないライ" "センスはありますか?" #: src/reuse/cli/lint.py:61 msgid "" "- Are any licenses included in the LICENSES/ directory that are not used " "inside of the project?" msgstr "" "- LICENSES/ディレクトリにプロジェクト内で使用されていないライセンスは含まれて" "いますか?" #: src/reuse/cli/lint.py:66 msgid "- Are there any read errors?" msgstr "- 読み取りエラーはありますか?" #: src/reuse/cli/lint.py:69 msgid "- Do all files have valid copyright and licensing information?" msgstr "- 全てのファイルに有効な著作権とライセンスの情報がありますか?" #: src/reuse/cli/lint.py:81 src/reuse/cli/lint_file.py:38 msgid "Prevent output." msgstr "出力を抑えます。" #: src/reuse/cli/lint.py:89 src/reuse/cli/supported_licenses.py:28 msgid "Format output as JSON." msgstr "出力をJSONとして整形します。" #: src/reuse/cli/lint.py:97 msgid "Format output as plain text. (default)" msgstr "出力をプレーンテキストとして整形します。(既定)" #: src/reuse/cli/lint.py:105 msgid "Format output as errors per line." msgstr "出力を行ごとにエラーとして整形します。" #: src/reuse/cli/convert_dep5.py:19 msgid "" "Convert .reuse/dep5 into a REUSE.toml file. The generated file is placed in " "the project root and is semantically identical. The .reuse/dep5 file is " "subsequently deleted." msgstr "" ".reuse/dep5をREUSE.tomlファイルに変換します。生成されたファイルはプロジェクト" "のルートに配置され意味的に同一です。.reuse/dep5ファイルは削除されます。" #: src/reuse/cli/convert_dep5.py:31 msgid "No '.reuse/dep5' file." msgstr "「.reuse/dep5」ファイルがありません。" #: src/reuse/cli/lint_file.py:25 msgid "" "Lint individual files for REUSE compliance. The specified FILEs are checked " "for the presence of copyright and licensing information, and whether the " "found licenses are included in the LICENSES/ directory." msgstr "" "個々のファイルのREUSE準拠を静的解析します。指定されたFILEの著作権とライセンス" "の情報の存在と、見つかったライセンスがLICENSES/ディレクトリに含まれているかど" "うかを検査します。" #: src/reuse/cli/lint_file.py:46 msgid "Format output as errors per line. (default)" msgstr "出力を行ごとにエラーとして整形します。(既定)" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/lint_file.py:51 msgid "FILE" msgstr "FILE" #: src/reuse/cli/lint_file.py:65 #, python-brace-format msgid "'{file}' is not inside of '{root}'." msgstr "「{file}」は「{root}」内にありません。" #: src/reuse/cli/spdx.py:22 msgid "Generate an SPDX bill of materials." msgstr "材料のSPDX証書を生成します。" #: src/reuse/cli/spdx.py:32 msgid "File to write to." msgstr "書き込むファイル。" #: src/reuse/cli/spdx.py:38 msgid "" "Populate the LicenseConcluded field; note that reuse cannot guarantee that " "the field is accurate." msgstr "" "LicenseConcludedフィールドを追加します。reuseはフィールドが正確であることを保" "証できないことに注意してください。" #: src/reuse/cli/spdx.py:50 msgid "Name of the person signing off on the SPDX report." msgstr "SPDXレポートに署名する人の名前。" #: src/reuse/cli/spdx.py:54 msgid "Name of the organization signing off on the SPDX report." msgstr "SPDXレポートに署名する団体の名前。" #: src/reuse/cli/spdx.py:81 msgid "" "'--creator-person' or '--creator-organization' is required when '--add-" "license-concluded' is provided." msgstr "" "「--add-license-concluded」が指定されている場合は「--creator-person」または" "「--creator-organization」が必要です。" #: src/reuse/cli/spdx.py:96 #, 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" #: src/reuse/cli/main.py:36 #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/decorators.py:465 #, python-format msgid "%(prog)s, version %(version)s" msgstr "%(prog)s、バージョン%(version)s" #: src/reuse/cli/main.py:39 msgid "" "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." msgstr "" "このプログラムは自由ソフトウェアです。あなたはフリーソフトウェア財団により発" "行されたGNU一般公衆ライセンスバージョン3、または(あなたの選択として)それ以" "降のバージョンの条件の下で、再配布や改変を行うことができます。" #: src/reuse/cli/main.py:46 msgid "" "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." msgstr "" "このプログラムは有用であることを期待して配布されていますが、いかなる保証もあ" "りません。商品性または特定の目的に対する適合性の暗黙の保証さえもありません。" "詳細はGNU一般公衆ライセンスを参照してください。" #: src/reuse/cli/main.py:53 msgid "" "You should have received a copy of the GNU General Public License along with " "this program. If not, see ." msgstr "" "あなたはこのプログラムと共にGNU一般公衆ライセンスの複製を受け取っているはずで" "す。もし、受け取っていない場合はを参照してくだ" "さい。" #: src/reuse/cli/main.py:61 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/cli/main.py:68 msgid "" "This version of reuse is compatible with version {} of the REUSE " "Specification." msgstr "このバージョンのreuseはREUSE仕様のバージョン{}と互換性があります。" #: src/reuse/cli/main.py:72 msgid "Support the FSFE's work:" msgstr "FSFEの活動を支援する:" #: src/reuse/cli/main.py:77 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/cli/main.py:88 msgid "Enable debug statements." msgstr "デバッグ宣言を有効にします。" #: src/reuse/cli/main.py:93 msgid "Hide deprecation warnings." msgstr "非推奨の警告を非表示にします。" #: src/reuse/cli/main.py:98 msgid "Do not skip over Git submodules." msgstr "Gitサブモジュールをスキップしません。" #: src/reuse/cli/main.py:103 msgid "Do not skip over Meson subprojects." msgstr "Mesonサブプロジェクトをスキップしません。" #: src/reuse/cli/main.py:108 msgid "Do not use multiprocessing." msgstr "マルチプロセッシングを使用しません。" #: src/reuse/cli/main.py:118 msgid "Define root of project." msgstr "プロジェクトのルートを定義します。" #: src/reuse/cli/common.py:51 #, python-brace-format msgid "" "'{path}' could not be parsed. We received the following error message: " "{message}" msgstr "" "「{path}」を解析できませんでした。次のエラーメッセージを受信しました: " "{message}" #: src/reuse/cli/common.py:87 #, python-brace-format msgid "'{name}' is mutually exclusive with: {opts}" msgstr "「{name}」は次と相互に排他的です: {opts}" #: src/reuse/cli/common.py:103 msgid "'{}' is not a valid SPDX expression." msgstr "「{}」は有効なSPDX表現ではありません。" #: src/reuse/cli/download.py:54 msgid "'{}' is not a valid SPDX License Identifier." msgstr "「{}」は有効なSPDXライセンス識別子ではありません。" #: src/reuse/cli/download.py:61 msgid "Did you mean:" msgstr "もしかして:" #: src/reuse/cli/download.py:68 msgid "" "See for a list of valid SPDX License " "Identifiers." msgstr "" "有効なSPDXライセンス識別子の一覧についてはを参照" "してください。" #: src/reuse/cli/download.py:77 #, python-brace-format msgid "Error: {spdx_identifier} already exists." msgstr "エラー: {spdx_identifier}はすでに存在します。" #: src/reuse/cli/download.py:84 #, python-brace-format msgid "Error: {path} does not exist." msgstr "エラー: {path}は存在しません。" #: src/reuse/cli/download.py:88 msgid "Error: Failed to download license." msgstr "エラー: ライセンスをダウンロードできませんでした。" #: src/reuse/cli/download.py:93 msgid "Is your internet connection working?" msgstr "インターネット接続は機能していますか?" #: src/reuse/cli/download.py:98 #, python-brace-format msgid "Successfully downloaded {spdx_identifier}." msgstr "{spdx_identifier}を正常にダウンロードしました。" #: src/reuse/cli/download.py:108 msgid "Download a license and place it in the LICENSES/ directory." msgstr "ライセンスをダウンロードしてLICENSES/ディレクトリに配置します。" #: src/reuse/cli/download.py:111 msgid "" "LICENSE must be a valid SPDX License Identifier. You may specify LICENSE " "multiple times to download multiple licenses." msgstr "" "ライセンスは有効なSPDXライセンス識別子でなければなりません。ライセンスを複数" "回指定すると複数のライセンスをダウンロードできます。" #: src/reuse/cli/download.py:124 msgid "Download all missing licenses detected in the project." msgstr "" "プロジェクトで検出された全ての欠落しているライセンスをダウンロードします。" #: src/reuse/cli/download.py:132 msgid "Path to download to." msgstr "ダウンロード先のパス。" #: src/reuse/cli/download.py:138 msgid "" "Source from which to copy custom LicenseRef- licenses, either a directory " "that contains the file or the file itself." msgstr "" "ファイルまたはファイルを含むディレクトリからカスタムLicenseRef-ライセンスをコ" "ピーします。" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/download.py:145 msgid "LICENSE" msgstr "LICENSE" #: src/reuse/cli/download.py:161 msgid "The 'LICENSE' argument and '--all' option are mutually exclusive." msgstr "「LICENSE」引数と「--all」オプションは相互に排他的です。" #: src/reuse/cli/download.py:173 msgid "Cannot use '--output' with more than one license." msgstr "複数のライセンスで「--output」は使用できません。" #: src/reuse/cli/annotate.py:66 msgid "Option '--copyright', '--license', or '--contributor' is required." msgstr "" "「--copyright」、「--license」または「--contributor」オプションが必要です。" #: src/reuse/cli/annotate.py:127 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/cli/annotate.py:160 #, python-brace-format msgid "" "'{path}' does not support single-line comments, please do not use '--single-" "line'." msgstr "" "「{path}」は行コメントに対応していません、「--single-line」は使用しないでくだ" "さい。" #: src/reuse/cli/annotate.py:167 #, python-brace-format msgid "" "'{path}' does not support multi-line comments, please do not use '--multi-" "line'." msgstr "" "「{path}」はブロックコメントに対応していません、「--multi-line」は使用しない" "でください。" #: src/reuse/cli/annotate.py:213 #, python-brace-format msgid "Template '{template}' could not be found." msgstr "テンプレート「{template}」が見つかりませんでした。" #: src/reuse/cli/annotate.py:236 #, fuzzy, python-brace-format msgid "'{year}' is not a valid year range." msgstr "{value!r}は有効な真理値ではありません。" #: src/reuse/cli/annotate.py:245 #, python-brace-format msgid "" "Your operating system's year is set to '{year}'. This is not four digits, " "and not supported." msgstr "" #: src/reuse/cli/annotate.py:287 msgid "Add copyright and licensing into the headers of files." msgstr "ファイルのヘッダーに著作権とライセンスの情報を追加します。" #: src/reuse/cli/annotate.py:290 msgid "" "By using --copyright and --license, you can specify which copyright holders " "and licenses to add to the headers of the given files." msgstr "" "--copyrightと--licenseを使うと、指定されたファイルのヘッダーに追加する著作権" "者とライセンスを指定できます。" #: src/reuse/cli/annotate.py:296 msgid "" "By using --contributor, you can specify people or entity that contributed " "but are not copyright holder of the given files." msgstr "" "--contributorを使用すると、指定されたファイルに著作権者ではなく貢献した人や団" "体を指定できます。" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:309 msgid "COPYRIGHT" msgstr "COPYRIGHT" #: src/reuse/cli/annotate.py:312 #, fuzzy msgid "Copyright holder, repeatable." msgstr "著作権宣言、繰り返し可能。" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:319 msgid "SPDX_IDENTIFIER" msgstr "SPDX_IDENTIFIER" #: src/reuse/cli/annotate.py:322 msgid "SPDX License Identifier, repeatable." msgstr "SPDXライセンス識別子、繰り返し可能。" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:328 msgid "CONTRIBUTOR" msgstr "CONTRIBUTOR" #: src/reuse/cli/annotate.py:331 msgid "File contributor, repeatable." msgstr "ファイル貢献者、繰り返し可能。" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:338 msgid "YEAR" msgstr "YEAR" #: src/reuse/cli/annotate.py:343 msgid "" "Year of copyright notice. You may define multiple years or a range of years." msgstr "" #: src/reuse/cli/annotate.py:353 msgid "Comment style to use." msgstr "使用するコメントスタイル。" #: src/reuse/cli/annotate.py:363 msgid "Copyright prefix to use." msgstr "使用する著作権接頭辞。" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:375 msgid "TEMPLATE" msgstr "TEMPLATE" #: src/reuse/cli/annotate.py:377 msgid "Name of template to use." msgstr "使用するテンプレートの名前。" #: src/reuse/cli/annotate.py:384 #, fuzzy msgid "Do not include year in copyright notice." msgstr "著作権宣言に年を含めません。" #: src/reuse/cli/annotate.py:390 #, fuzzy msgid "Merge copyright notices if they are identical except for their years." msgstr "著作権宣言が一致する場合に著作権行を統合します。" #: src/reuse/cli/annotate.py:398 msgid "Force single-line comment style." msgstr "行コメントスタイルを強制します。" #: src/reuse/cli/annotate.py:405 msgid "Force multi-line comment style." msgstr "ブロックコメントスタイルを強制します。" #: src/reuse/cli/annotate.py:411 msgid "Add headers to all files under specified directories recursively." msgstr "" "指定されたディレクトリ以下の全てのファイルにヘッダーを再帰的に追加します。" #: src/reuse/cli/annotate.py:416 msgid "Do not replace the first header in the file; just add a new one." msgstr "" "ファイルの元からあるヘッダーを置き換えるのではなく、新しいヘッダーを追加しま" "す。" #: src/reuse/cli/annotate.py:423 msgid "Always write a .license file instead of a header inside the file." msgstr "ファイル内のヘッダーではなく常に.licenseファイルに書き込みます。" #: src/reuse/cli/annotate.py:430 msgid "Write a .license file to files with unrecognised comment styles." msgstr "" "ファイルのコメントスタイルが識別できないときは.licenseファイルに書き込みま" "す。" #: src/reuse/cli/annotate.py:437 msgid "Skip files with unrecognised comment styles." msgstr "コメントスタイルが識別できないファイルをスキップします。" #: src/reuse/cli/annotate.py:448 msgid "Skip files that already contain REUSE information." msgstr "すでにREUSE情報を含んでいるファイルをスキップします。" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:453 msgid "PATH" msgstr "PATH" #: src/reuse/cli/annotate.py:510 #, python-brace-format msgid "'{path}' is a binary, therefore using '{new_path}' for the header" msgstr "「{path}」はバイナリなので、ヘッダーには「{new_path}」を使用します" #: src/reuse/cli/supported_licenses.py:19 msgid "List all licenses on the SPDX License List." msgstr "SPDXライセンスリストの全てのライセンスを一覧表示します。" #: src/reuse/global_licensing.py:92 #, python-brace-format msgid "" "{attr_name} must be a {type_name} (got {value} that is a {value_class})." msgstr "" #: src/reuse/global_licensing.py:106 #, 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:118 #, python-brace-format msgid "{attr_name} must not be empty." msgstr "" #: src/reuse/global_licensing.py:142 #, python-brace-format msgid "{name} must be a {type} (got {value} that is a {value_type})." msgstr "" #: src/reuse/global_licensing.py:166 #, python-brace-format msgid "" "The value of 'precedence' must be one of {precedence_vals} (got {received})" msgstr "" #: src/reuse/global_licensing.py:219 #, python-brace-format msgid "Could not parse '{notice}'" msgstr "" #: src/reuse/_annotate.py:94 #, python-brace-format msgid "Skipped unrecognised file '{path}'" msgstr "" #: src/reuse/_annotate.py:100 #, python-brace-format msgid "'{path}' is not recognised; creating '{path}.license'" msgstr "" #: src/reuse/_annotate.py:116 #, fuzzy, python-brace-format msgid "Skipped file '{path}' already containing REUSE information" msgstr "すでにREUSE情報を含んでいるファイルをスキップします。" #: src/reuse/_annotate.py:145 #, python-brace-format msgid "Error: Could not create comment for '{path}'" msgstr "" #: src/reuse/_annotate.py:152 #, 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:163 #, python-brace-format msgid "Successfully changed header of {path}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:162 msgid "Repeat for confirmation" msgstr "確認のために繰り返します" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:178 msgid "Error: The value you entered was invalid." msgstr "エラー: あなたの入力した値は無効でした。" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:180 #, python-brace-format msgid "Error: {e.message}" msgstr "エラー: {e.message}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:191 msgid "Error: The two entered values do not match." msgstr "エラー: 入力された2つの値が一致しません。" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:247 msgid "Error: invalid input" msgstr "エラー: 無効な入力" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:866 msgid "Press any key to continue..." msgstr "続行するにはなにかキーを押してください..." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:332 #, python-brace-format msgid "" "Choose from:\n" "\t{choices}" msgstr "" "選択肢:\n" "\t{choices}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:369 msgid "{value!r} is not {choice}." msgid_plural "{value!r} is not one of {choices}." msgstr[0] "{value!r}は{choices}ではありません。" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:460 msgid "{value!r} does not match the format {format}." msgid_plural "{value!r} does not match the formats {formats}." msgstr[0] "{value!r}は形式{formats}と一致しません。" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:482 msgid "{value!r} is not a valid {number_type}." msgstr "{value!r}は有効な{number_type}ではありません。" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:538 #, python-brace-format msgid "{value} is not in the range {range}." msgstr "{value}は{range}の範囲内ではありません。" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:719 #, fuzzy msgid "{value!r} is not a valid boolean. Recognized values: {states}" msgstr "{value!r}は有効な真理値ではありません。" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:747 msgid "{value!r} is not a valid UUID." msgstr "{value!r}は有効なUUIDではありません。" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:937 msgid "file" msgstr "ファイル" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:939 msgid "directory" msgstr "ディレクトリ" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:941 msgid "path" msgstr "パス" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:988 msgid "{name} {filename!r} does not exist." msgstr "{name} {filename!r}は存在しません。" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:997 msgid "{name} {filename!r} is a file." msgstr "{name} {filename!r}はファイルです。" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:1005 #, fuzzy msgid "{name} {filename!r} is a directory." msgstr "{name} 「{filename}」はディレクトリです。" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:1014 msgid "{name} {filename!r} is not readable." msgstr "{name} {filename!r}は読み取り可能ではありません。" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:1023 msgid "{name} {filename!r} is not writable." msgstr "{name} {filename!r}は書き込み可能ではありません。" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:1032 msgid "{name} {filename!r} is not executable." msgstr "{name} {filename!r}は実行可能ではありません。" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:1099 #, python-brace-format msgid "{len_type} values are required, but {len_value} was given." msgid_plural "{len_type} values are required, but {len_value} were given." msgstr[0] "{len_type}個の値が必要ですが、{len_value}個が指定されました。" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/shell_completion.py:332 msgid "Shell completion is not supported for Bash versions older than 4.4." msgstr "シェル補完はバージョン4.4より古いBashでは対応していません。" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/shell_completion.py:339 msgid "Couldn't detect Bash version, shell completion is not supported." msgstr "Bashのバージョンを検出できませんでした、シェル補完は対応していません。" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:50 #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:89 #, python-brace-format msgid "Error: {message}" msgstr "エラー: {message}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:81 #, python-brace-format msgid "Try '{command} {option}' for help." msgstr "使い方については「{command} {option}」を試してください。" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:130 #, python-brace-format msgid "Invalid value: {message}" msgstr "無効な値: {message}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:132 #, python-brace-format msgid "Invalid value for {param_hint}: {message}" msgstr "{param_hint}の値が無効です: {message}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:190 msgid "Missing argument" msgstr "引数が不足しています" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:192 msgid "Missing option" msgstr "オプションが不足しています" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:194 msgid "Missing parameter" msgstr "パラメーターが不足しています" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:196 #, python-brace-format msgid "Missing {param_type}" msgstr "{param_type}が不足しています" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:203 #, python-brace-format msgid "Missing parameter: {param_name}" msgstr "不足しているパラメーター: {param_name}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:223 #, python-brace-format msgid "No such option: {name}" msgstr "そのようなオプションはありません: {name}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:235 #, python-brace-format msgid "Did you mean {possibility}?" msgid_plural "(Possible options: {possibilities})" msgstr[0] "もしかして{possibilities}ですか?" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:282 msgid "unknown error" msgstr "不明なエラー" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:289 msgid "Could not open file {filename!r}: {message}" msgstr "ファイル{filename!r}を開けませんでした: {message}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1104 #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1141 #, python-brace-format msgid "{text} {deprecated_message}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1160 msgid "Options" msgstr "オプション" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1222 #, python-brace-format msgid "Got unexpected extra argument ({args})" msgid_plural "Got unexpected extra arguments ({args})" msgstr[0] "予期しない追加の引数({args})を取得しました" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1241 #, fuzzy msgid "DeprecationWarning: The command {name!r} is deprecated.{extra_message}" msgstr "DeprecationWarning: コマンド{name!r}は非推奨です。" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1425 msgid "Aborted!" msgstr "中止しました!" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1799 msgid "Commands" msgstr "コマンド" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1830 msgid "Missing command." msgstr "コマンドがありません。" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1908 msgid "No such command {name!r}." msgstr "そのようなコマンド{name!r}はありません。" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:2332 msgid "Value must be an iterable." msgstr "値は繰り返し可能でなければなりません。" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:2355 #, python-brace-format msgid "Takes {nargs} values but 1 was given." msgid_plural "Takes {nargs} values but {len} were given." msgstr[0] "{nargs}個の値を取りますが{len}個が指定されました。" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:2505 #, fuzzy msgid "" "DeprecationWarning: The {param_type} {name!r} is deprecated.{extra_message}" msgstr "DeprecationWarning: コマンド{name!r}は非推奨です。" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:2956 #, python-brace-format msgid "env var: {var}" msgstr "環境変数: {var}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:2959 #, python-brace-format msgid "default: {default}" msgstr "既定: {default}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:3023 msgid "(dynamic)" msgstr "(動的)" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/parser.py:199 msgid "Argument {name!r} takes {nargs} values." msgstr "引数{name!r}は{nargs}個の値を取ります。" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/parser.py:381 msgid "Option {name!r} does not take a value." msgstr "オプション{name!r}は値を取りません。" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/parser.py:444 msgid "Option {name!r} requires an argument." msgid_plural "Option {name!r} requires {nargs} arguments." msgstr[0] "オプション{name!r}には{nargs}個の引数が必要です。" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/_termui_impl.py:608 #, python-brace-format msgid "{editor}: Editing failed" msgstr "{editor}: 編集できませんでした" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/_termui_impl.py:612 #, python-brace-format msgid "{editor}: Editing failed: {e}" msgstr "{editor}: 編集できませんでした: {e}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/decorators.py:522 msgid "Show the version and exit." msgstr "バージョンを表示して終了します。" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/decorators.py:548 msgid "Show this message and exit." msgstr "このメッセージを表示して終了します。" #, python-brace-format #~ msgid "(Deprecated) {text}" #~ msgstr "(非推奨){text}" #~ msgid "required" #~ msgstr "必須" #~ msgid "Year of copyright statement." #~ msgstr "著作権宣言の年。" reuse-tool-6.2.0/po/it.po0000664000175000017500000014726615077707000013700 0ustar alexalex# 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: 2025-10-07 21:23+0000\n" "PO-Revision-Date: 2025-10-09 21:52+0000\n" "Last-Translator: Marco Ciampa \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 5.14-dev\n" #: src/reuse/lint.py:40 msgid "BAD LICENSES" msgstr "LICENZE NON VALIDE" #: src/reuse/lint.py:42 msgid "The following licenses are not valid SPDX licenses:" msgstr "Le seguenti licenze non sono licenze SPDX valide:" #: src/reuse/lint.py:50 msgid "DEPRECATED LICENSES" msgstr "LICENZE DEPRECATE" #: src/reuse/lint.py:52 msgid "The following licenses are deprecated by SPDX:" msgstr "Le seguenti licenze sono deprecate per SPDX:" #: src/reuse/lint.py:60 msgid "LICENSES WITHOUT FILE EXTENSION" msgstr "LICENZE SENZA ESTENSIONE DEL FILE" #: src/reuse/lint.py:62 msgid "The following licenses have no file extension:" msgstr "Le seguenti licenze non hanno l'estensione del file:" #: src/reuse/lint.py:70 msgid "MISSING LICENSES" msgstr "LICENZE MANCANTI" #: src/reuse/lint.py:72 msgid "'{}' found in:" msgstr "'{}' trovato in:" #: src/reuse/lint.py:79 msgid "UNUSED LICENSES" msgstr "LICENZE NON UTILIZZATE" #: src/reuse/lint.py:80 msgid "The following licenses are not used:" msgstr "Le seguenti licenze non sono utilizzate:" #: src/reuse/lint.py:87 msgid "READ ERRORS" msgstr "ERRORI DI LETTURA" #: src/reuse/lint.py:88 msgid "Could not read:" msgstr "Non è possibile leggere:" #: src/reuse/lint.py:94 msgid "INVALID SPDX LICENSE EXPRESSIONS" msgstr "ESPRESSIONI DI LICENZA SPDX NON VALIDE" #: src/reuse/lint.py:99 #, fuzzy msgid "'{}' contains invalid SPDX License Expressions:" msgstr "'{}' non è una espressione valida SPDX, interruzione" #: src/reuse/lint.py:124 msgid "MISSING COPYRIGHT AND LICENSING INFORMATION" msgstr "MANCANO LE INFORMAZIONI SU COPYRIGHT E LICENZA" #: src/reuse/lint.py:130 #, fuzzy msgid "The following files have no copyright and licensing information:" msgstr "I seguenti file non hanno informazioni sul copyright:" #: src/reuse/lint.py:141 msgid "The following files have no copyright information:" msgstr "I seguenti file non hanno informazioni sul copyright:" #: src/reuse/lint.py:150 msgid "The following files have no licensing information:" msgstr "I seguenti file non hanno informazioni sulla licenza:" #: src/reuse/lint.py:157 msgid "SUMMARY" msgstr "RAPPORTO" #: src/reuse/lint.py:162 msgid "Bad licenses:" msgstr "Licenze non valide:" #: src/reuse/lint.py:163 msgid "Deprecated licenses:" msgstr "Licenze obsolete:" #: src/reuse/lint.py:166 msgid "Licenses without file extension:" msgstr "Licenze senza estensione del file:" #: src/reuse/lint.py:169 msgid "Missing licenses:" msgstr "Licenze mancanti:" #: src/reuse/lint.py:170 msgid "Unused licenses:" msgstr "Licenze non utilizzate:" #: src/reuse/lint.py:171 msgid "Used licenses:" msgstr "Licenze usate:" #: src/reuse/lint.py:172 #, fuzzy msgid "Read errors:" msgstr "Errori di lettura: {count}" #: src/reuse/lint.py:173 #, fuzzy msgid "Invalid SPDX License Expressions:" msgstr "'{}' non è una espressione valida SPDX, interruzione" #: src/reuse/lint.py:183 #, fuzzy msgid "Files with copyright information:" msgstr "File con informazioni sul copyright: {count} / {total}" #: src/reuse/lint.py:187 #, fuzzy msgid "Files with license information:" msgstr "File con informazioni sulla licenza: {count} / {total}" #: src/reuse/lint.py:204 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:211 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:218 msgid "RECOMMENDATIONS" msgstr "RACCOMANDAZIONI" #: src/reuse/lint.py:286 #, python-brace-format msgid "missing license '{lic}'" msgstr "licenza mancante '{lic}'" #: src/reuse/lint.py:291 msgid "read error" msgstr "errore di lettura" #: src/reuse/lint.py:296 #, python-brace-format msgid "invalid SPDX License Expression '{expression}'" msgstr "espressione di licenza SPDX non valida '{expression}'" #: src/reuse/lint.py:303 msgid "no license identifier" msgstr "nessun identificativo di licenza" #: src/reuse/lint.py:307 #, fuzzy msgid "no copyright notice" msgstr "'{}' non è un valido Identificativo di Licenza SPDX." #: src/reuse/lint.py:345 #, fuzzy, python-brace-format msgid "bad license '{lic}'" msgstr "Licenze non utilizzate:" #: src/reuse/lint.py:350 #, fuzzy msgid "deprecated license" msgstr "Licenze obsolete:" #: src/reuse/lint.py:355 #, fuzzy msgid "license without file extension" msgstr "Licenze senza estensione del file:" #: src/reuse/lint.py:360 #, fuzzy msgid "unused license" msgstr "Licenze non utilizzate:" #: src/reuse/project.py:253 #, fuzzy, python-brace-format msgid "'{path}' covered by {global_path}" msgstr "'{path}' verificato da .reuse/dep5" #: src/reuse/project.py:261 #, python-brace-format msgid "" "'{path}' is covered exclusively by REUSE.toml. Not reading the file contents." msgstr "" "'{path}' è coperto esclusivamente da REUSE.toml. Il contenuto del file non " "viene letto." #: 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' è obsoleto. Si consiglia di utilizzare invece REUSE.toml. Per " "la conversione, utilizzare `reuse convert-dep5`." #: src/reuse/project.py:355 #, python-brace-format msgid "" "Found both '{new_path}' and '{old_path}'. You cannot keep both files " "simultaneously; they are not intercompatible." msgstr "" "Trovati sia '{new_path}' che '{old_path}'. Non è possibile mantenere " "entrambi i file contemporaneamente; non sono intercompatibili." #: src/reuse/project.py:419 #, python-brace-format msgid "{path} does not have a file extension" msgstr "{path} non ha l'estensione del file" #: src/reuse/project.py:429 #, 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:441 #, 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:480 msgid "" "project '{}' is not a VCS repository or required VCS software is not " "installed" msgstr "" "il progetto '{}' non è un repository VCS o il software VCS richiesto non è " "installato" #: src/reuse/extract.py:49 #, python-brace-format msgid "" "REUSE_ENCODING_MODULE must have a value in {modules}; it has '{env_module}'. " "Aborting." msgstr "" #: src/reuse/extract.py:69 msgid "" "No supported module that can detect the encoding of files could be " "successfully imported. Re-read the installation instructions for the reuse " "package, or try the following:" msgstr "" #: src/reuse/extract.py:75 msgid "" "- If you are running a Linux distribution, try your equivalent of `apt " "install file` or `dnf install file`." msgstr "" #: src/reuse/extract.py:80 msgid "" "- Run ` pipx install reuse[charset-normalizer]`. Replace 'pipx' with 'pip' " "if you are not using pipx." msgstr "" #: src/reuse/extract.py:451 #, python-brace-format msgid "" "'{path}' was detected as a binary file; not searching its contents for REUSE " "information." msgstr "" #: src/reuse/extract.py:462 #, python-brace-format msgid "" "extracting REUSE information from '{path}' (encoding {encoding}, encoding " "module {module}, newline {newline})" msgstr "" #: src/reuse/header.py:87 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/report.py:160 #, python-brace-format msgid "Could not read '{path}'" msgstr "Non è possibile leggere '{path}'" #: src/reuse/report.py:165 #, python-brace-format msgid "Unexpected error occurred while parsing '{path}'" msgstr "Errore sconosciuto durante la parsificazione di '{path}'" #: src/reuse/report.py:521 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:532 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:543 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:552 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:564 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:575 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:584 msgid "" "Fix invalid SPDX License Expressions: In one or more files there are SPDX " "License Expressions which cannot be parse. Check whether the value that " "follows 'SPDX-License-Identifier:' is correct. If the detected expression is " "not meant to be valid, put it between 'REUSE-IgnoreStart' and 'REUSE-" "IgnoreEnd' comments." msgstr "" #: src/reuse/report.py:595 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/cli/lint.py:28 #, python-brace-format msgid "" "Lint the project directory for REUSE compliance. This version of the tool " "checks against version {reuse_version} of the REUSE Specification. You can " "find the latest version of the specification at ." msgstr "" #: src/reuse/cli/lint.py:34 msgid "Specifically, the following criteria are checked:" msgstr "" #: src/reuse/cli/lint.py:38 msgid "" "- Are there any bad (unrecognised, not compliant with SPDX) licenses in the " "project?" msgstr "" #: src/reuse/cli/lint.py:43 #, fuzzy msgid "- Are there any deprecated licenses in the project?" msgstr "Qual è l'indirizzo Internet del progetto?" #: src/reuse/cli/lint.py:47 msgid "" "- Are there any license files in the LICENSES/ directory without file " "extension?" msgstr "" #: src/reuse/cli/lint.py:54 msgid "" "- Are any licenses referred to inside of the project, but not included in " "the LICENSES/ directory?" msgstr "" #: src/reuse/cli/lint.py:61 msgid "" "- Are any licenses included in the LICENSES/ directory that are not used " "inside of the project?" msgstr "" #: src/reuse/cli/lint.py:66 msgid "- Are there any read errors?" msgstr "" #: src/reuse/cli/lint.py:69 #, fuzzy msgid "- Do all files have valid copyright and licensing information?" msgstr "I seguenti file non hanno informazioni sul copyright e sulla licenza:" #: src/reuse/cli/lint.py:81 src/reuse/cli/lint_file.py:38 msgid "Prevent output." msgstr "" #: src/reuse/cli/lint.py:89 src/reuse/cli/supported_licenses.py:28 msgid "Format output as JSON." msgstr "" #: src/reuse/cli/lint.py:97 msgid "Format output as plain text. (default)" msgstr "" #: src/reuse/cli/lint.py:105 msgid "Format output as errors per line." msgstr "" #: src/reuse/cli/convert_dep5.py:19 msgid "" "Convert .reuse/dep5 into a REUSE.toml file. The generated file is placed in " "the project root and is semantically identical. The .reuse/dep5 file is " "subsequently deleted." msgstr "" #: src/reuse/cli/convert_dep5.py:31 #, fuzzy msgid "No '.reuse/dep5' file." msgstr "Creazione di .reuse/dep5" #: src/reuse/cli/lint_file.py:25 msgid "" "Lint individual files for REUSE compliance. The specified FILEs are checked " "for the presence of copyright and licensing information, and whether the " "found licenses are included in the LICENSES/ directory." msgstr "" #: src/reuse/cli/lint_file.py:46 msgid "Format output as errors per line. (default)" msgstr "" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/lint_file.py:51 msgid "FILE" msgstr "" #: src/reuse/cli/lint_file.py:65 #, python-brace-format msgid "'{file}' is not inside of '{root}'." msgstr "" #: src/reuse/cli/spdx.py:22 #, fuzzy msgid "Generate an SPDX bill of materials." msgstr "stampa l'elenco dei componenti del progetto in formato SPDX" #: src/reuse/cli/spdx.py:32 msgid "File to write to." msgstr "" #: src/reuse/cli/spdx.py:38 msgid "" "Populate the LicenseConcluded field; note that reuse cannot guarantee that " "the field is accurate." msgstr "" #: src/reuse/cli/spdx.py:50 msgid "Name of the person signing off on the SPDX report." msgstr "" #: src/reuse/cli/spdx.py:54 msgid "Name of the organization signing off on the SPDX report." msgstr "" #: src/reuse/cli/spdx.py:81 msgid "" "'--creator-person' or '--creator-organization' is required when '--add-" "license-concluded' is provided." msgstr "" #: src/reuse/cli/spdx.py:96 #, 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 "" #: src/reuse/cli/main.py:36 #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/decorators.py:465 #, fuzzy, python-format msgid "%(prog)s, version %(version)s" msgstr "%(prog)s: errore: %(message)s\n" #: src/reuse/cli/main.py:39 msgid "" "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." msgstr "" #: src/reuse/cli/main.py:46 msgid "" "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." msgstr "" #: src/reuse/cli/main.py:53 msgid "" "You should have received a copy of the GNU General Public License along with " "this program. If not, see ." msgstr "" #: src/reuse/cli/main.py:61 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/cli/main.py:68 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/cli/main.py:72 msgid "Support the FSFE's work:" msgstr "Sostieni il lavoro della FSFE:" #: src/reuse/cli/main.py:77 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/cli/main.py:88 #, fuzzy msgid "Enable debug statements." msgstr "abilita le istruzioni di debug" #: src/reuse/cli/main.py:93 msgid "Hide deprecation warnings." msgstr "" #: src/reuse/cli/main.py:98 #, fuzzy msgid "Do not skip over Git submodules." msgstr "non omettere i sottomoduli Git" #: src/reuse/cli/main.py:103 #, fuzzy msgid "Do not skip over Meson subprojects." msgstr "non omettere i sottomoduli Git" #: src/reuse/cli/main.py:108 #, fuzzy msgid "Do not use multiprocessing." msgstr "non utilizzare il multiprocessing" #: src/reuse/cli/main.py:118 #, fuzzy msgid "Define root of project." msgstr "impostare la directory principale del progetto" #: src/reuse/cli/common.py:51 #, python-brace-format msgid "" "'{path}' could not be parsed. We received the following error message: " "{message}" msgstr "" #: src/reuse/cli/common.py:87 #, python-brace-format msgid "'{name}' is mutually exclusive with: {opts}" msgstr "" #: src/reuse/cli/common.py:103 #, fuzzy msgid "'{}' is not a valid SPDX expression." msgstr "'{}' non è una espressione valida SPDX, interruzione" #: src/reuse/cli/download.py:54 msgid "'{}' is not a valid SPDX License Identifier." msgstr "'{}' non è un valido Identificativo di Licenza SPDX." #: src/reuse/cli/download.py:61 msgid "Did you mean:" msgstr "" #: src/reuse/cli/download.py:68 msgid "" "See for a list of valid SPDX License " "Identifiers." msgstr "" "Consulta per la lista degli Identificativi di " "Licenza SPDX validi." #: src/reuse/cli/download.py:77 #, python-brace-format msgid "Error: {spdx_identifier} already exists." msgstr "Errore: {spdx_identifier} esiste già." #: src/reuse/cli/download.py:84 #, fuzzy, python-brace-format msgid "Error: {path} does not exist." msgstr "'{path}' non ha estensione .spdx" #: src/reuse/cli/download.py:88 msgid "Error: Failed to download license." msgstr "Errore: Fallito lo scaricamento della licenza." #: src/reuse/cli/download.py:93 msgid "Is your internet connection working?" msgstr "La tua connessione Internet funziona?" #: src/reuse/cli/download.py:98 #, python-brace-format msgid "Successfully downloaded {spdx_identifier}." msgstr "Scaricamento completato di {spdx_identifier}." #: src/reuse/cli/download.py:108 #, fuzzy msgid "Download a license and place it in the LICENSES/ directory." msgstr "scarica una licenza e salvala nella directory LICENSES/" #: src/reuse/cli/download.py:111 msgid "" "LICENSE must be a valid SPDX License Identifier. You may specify LICENSE " "multiple times to download multiple licenses." msgstr "" #: src/reuse/cli/download.py:124 #, fuzzy msgid "Download all missing licenses detected in the project." msgstr "scarica tutte le licenze mancanti ma usate nel progetto" #: src/reuse/cli/download.py:132 msgid "Path to download to." msgstr "" #: src/reuse/cli/download.py:138 msgid "" "Source from which to copy custom LicenseRef- licenses, either a directory " "that contains the file or the file itself." msgstr "" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/download.py:145 #, fuzzy msgid "LICENSE" msgstr "LICENZE NON VALIDA" #: src/reuse/cli/download.py:161 #, fuzzy msgid "The 'LICENSE' argument and '--all' option are mutually exclusive." msgstr "i parametri --exclude-year e --year sono multualmente esclusivi" #: src/reuse/cli/download.py:173 #, fuzzy msgid "Cannot use '--output' with more than one license." msgstr "non puoi usare --output con più di una licenza" #: src/reuse/cli/annotate.py:66 #, fuzzy msgid "Option '--copyright', '--license', or '--contributor' is required." msgstr "è necessario specificare il parametro --copyright o --license" #: src/reuse/cli/annotate.py:127 #, 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/cli/annotate.py:160 #, python-brace-format msgid "" "'{path}' does not support single-line comments, please do not use '--single-" "line'." msgstr "" #: src/reuse/cli/annotate.py:167 #, python-brace-format msgid "" "'{path}' does not support multi-line comments, please do not use '--multi-" "line'." msgstr "" #: src/reuse/cli/annotate.py:213 #, fuzzy, python-brace-format msgid "Template '{template}' could not be found." msgstr "il modello {template} non è stato trovato" #: src/reuse/cli/annotate.py:236 #, fuzzy, python-brace-format msgid "'{year}' is not a valid year range." msgstr "'{}' non è una espressione valida SPDX, interruzione" #: src/reuse/cli/annotate.py:245 #, python-brace-format msgid "" "Your operating system's year is set to '{year}'. This is not four digits, " "and not supported." msgstr "" #: src/reuse/cli/annotate.py:287 #, fuzzy msgid "Add copyright and licensing into the headers of files." msgstr "" "aggiunge le informazioni sul copyright e sulla licenza nell'intestazione dei " "file" #: src/reuse/cli/annotate.py:290 msgid "" "By using --copyright and --license, you can specify which copyright holders " "and licenses to add to the headers of the given files." msgstr "" #: src/reuse/cli/annotate.py:296 msgid "" "By using --contributor, you can specify people or entity that contributed " "but are not copyright holder of the given files." msgstr "" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:309 msgid "COPYRIGHT" msgstr "" #: src/reuse/cli/annotate.py:312 #, fuzzy msgid "Copyright holder, repeatable." msgstr "dichiarazione del copyright, ripetibile" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:319 msgid "SPDX_IDENTIFIER" msgstr "" #: src/reuse/cli/annotate.py:322 #, fuzzy msgid "SPDX License Identifier, repeatable." msgstr "Identificativo SPDX, ripetibile" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:328 msgid "CONTRIBUTOR" msgstr "" #: src/reuse/cli/annotate.py:331 #, fuzzy msgid "File contributor, repeatable." msgstr "Identificativo SPDX, ripetibile" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:338 msgid "YEAR" msgstr "" #: src/reuse/cli/annotate.py:343 msgid "" "Year of copyright notice. You may define multiple years or a range of years." msgstr "" #: src/reuse/cli/annotate.py:353 #, fuzzy msgid "Comment style to use." msgstr "stile dei commenti da usare, opzionale" #: src/reuse/cli/annotate.py:363 #, fuzzy msgid "Copyright prefix to use." msgstr "stile dei commenti da usare, opzionale" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:375 msgid "TEMPLATE" msgstr "" #: src/reuse/cli/annotate.py:377 #, fuzzy msgid "Name of template to use." msgstr "nome del template da usare, opzionale" #: src/reuse/cli/annotate.py:384 #, fuzzy msgid "Do not include year in copyright notice." msgstr "non include l'anno nella dichiarazione" #: src/reuse/cli/annotate.py:390 #, fuzzy msgid "Merge copyright notices if they are identical except for their years." msgstr "anno della dichiaraione del copyright, opzionale" #: src/reuse/cli/annotate.py:398 #, fuzzy msgid "Force single-line comment style." msgstr "stile dei commenti da usare, opzionale" #: src/reuse/cli/annotate.py:405 #, fuzzy msgid "Force multi-line comment style." msgstr "stile dei commenti da usare, opzionale" #: src/reuse/cli/annotate.py:411 msgid "Add headers to all files under specified directories recursively." msgstr "" #: src/reuse/cli/annotate.py:416 msgid "Do not replace the first header in the file; just add a new one." msgstr "" #: src/reuse/cli/annotate.py:423 msgid "Always write a .license file instead of a header inside the file." msgstr "" #: src/reuse/cli/annotate.py:430 msgid "Write a .license file to files with unrecognised comment styles." msgstr "" #: src/reuse/cli/annotate.py:437 msgid "Skip files with unrecognised comment styles." msgstr "" #: src/reuse/cli/annotate.py:448 #, fuzzy msgid "Skip files that already contain REUSE information." msgstr "File con informazioni sulla licenza: {count} / {total}" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:453 msgid "PATH" msgstr "" #: src/reuse/cli/annotate.py:510 #, 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/cli/supported_licenses.py:19 msgid "List all licenses on the SPDX License List." msgstr "" #: src/reuse/global_licensing.py:92 #, python-brace-format msgid "" "{attr_name} must be a {type_name} (got {value} that is a {value_class})." msgstr "" #: src/reuse/global_licensing.py:106 #, 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:118 #, python-brace-format msgid "{attr_name} must not be empty." msgstr "" #: src/reuse/global_licensing.py:142 #, python-brace-format msgid "{name} must be a {type} (got {value} that is a {value_type})." msgstr "" #: src/reuse/global_licensing.py:166 #, python-brace-format msgid "" "The value of 'precedence' must be one of {precedence_vals} (got {received})" msgstr "" #: src/reuse/global_licensing.py:219 #, fuzzy, python-brace-format msgid "Could not parse '{notice}'" msgstr "Non è possibile parsificare '{expression}'" #: src/reuse/_annotate.py:94 #, python-brace-format msgid "Skipped unrecognised file '{path}'" msgstr "" #: src/reuse/_annotate.py:100 #, python-brace-format msgid "'{path}' is not recognised; creating '{path}.license'" msgstr "" #: src/reuse/_annotate.py:116 #, fuzzy, python-brace-format msgid "Skipped file '{path}' already containing REUSE information" msgstr "File con informazioni sulla licenza: {count} / {total}" #: src/reuse/_annotate.py:145 #, python-brace-format msgid "Error: Could not create comment for '{path}'" msgstr "Errore: Non è possibile creare il commento per '{path}'" #: src/reuse/_annotate.py:152 #, 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:163 #, python-brace-format msgid "Successfully changed header of {path}" msgstr "Instestazione di {path} aggiornata" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:162 msgid "Repeat for confirmation" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:178 msgid "Error: The value you entered was invalid." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:180 #, python-brace-format msgid "Error: {e.message}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:191 msgid "Error: The two entered values do not match." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:247 msgid "Error: invalid input" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:866 msgid "Press any key to continue..." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:332 #, python-brace-format msgid "" "Choose from:\n" "\t{choices}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:369 msgid "{value!r} is not {choice}." msgid_plural "{value!r} is not one of {choices}." msgstr[0] "" msgstr[1] "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:460 msgid "{value!r} does not match the format {format}." msgid_plural "{value!r} does not match the formats {formats}." msgstr[0] "" msgstr[1] "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:482 msgid "{value!r} is not a valid {number_type}." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:538 #, python-brace-format msgid "{value} is not in the range {range}." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:719 msgid "{value!r} is not a valid boolean. Recognized values: {states}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:747 msgid "{value!r} is not a valid UUID." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:937 msgid "file" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:939 msgid "directory" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:941 msgid "path" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:988 #, fuzzy msgid "{name} {filename!r} does not exist." msgstr "'{path}' non ha estensione .spdx" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:997 msgid "{name} {filename!r} is a file." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:1005 #, fuzzy msgid "{name} {filename!r} is a directory." msgstr "'{}' non è una directory" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:1014 msgid "{name} {filename!r} is not readable." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:1023 msgid "{name} {filename!r} is not writable." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:1032 msgid "{name} {filename!r} is not executable." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:1099 #, python-brace-format msgid "{len_type} values are required, but {len_value} was given." msgid_plural "{len_type} values are required, but {len_value} were given." msgstr[0] "" msgstr[1] "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/shell_completion.py:332 msgid "Shell completion is not supported for Bash versions older than 4.4." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/shell_completion.py:339 msgid "Couldn't detect Bash version, shell completion is not supported." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:50 #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:89 #, python-brace-format msgid "Error: {message}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:81 #, python-brace-format msgid "Try '{command} {option}' for help." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:130 #, python-brace-format msgid "Invalid value: {message}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:132 #, python-brace-format msgid "Invalid value for {param_hint}: {message}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:190 #, fuzzy msgid "Missing argument" msgstr "parametri posizionali" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:192 #, fuzzy msgid "Missing option" msgstr "Licenze mancanti:" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:194 msgid "Missing parameter" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:196 #, python-brace-format msgid "Missing {param_type}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:203 #, python-brace-format msgid "Missing parameter: {param_name}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:223 #, python-brace-format msgid "No such option: {name}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:235 #, python-brace-format msgid "Did you mean {possibility}?" msgid_plural "(Possible options: {possibilities})" msgstr[0] "" msgstr[1] "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:282 msgid "unknown error" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:289 msgid "Could not open file {filename!r}: {message}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1104 #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1141 #, python-brace-format msgid "{text} {deprecated_message}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1160 msgid "Options" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1222 #, fuzzy, python-brace-format msgid "Got unexpected extra argument ({args})" msgid_plural "Got unexpected extra arguments ({args})" msgstr[0] "richiesto un parametro" msgstr[1] "richiesto un parametro" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1241 msgid "DeprecationWarning: The command {name!r} is deprecated.{extra_message}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1425 msgid "Aborted!" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1799 #, fuzzy msgid "Commands" msgstr "sottocomandi" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1830 #, fuzzy msgid "Missing command." msgstr "Licenze mancanti:" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1908 msgid "No such command {name!r}." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:2332 msgid "Value must be an iterable." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:2355 #, python-brace-format msgid "Takes {nargs} values but 1 was given." msgid_plural "Takes {nargs} values but {len} were given." msgstr[0] "" msgstr[1] "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:2505 msgid "" "DeprecationWarning: The {param_type} {name!r} is deprecated.{extra_message}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:2956 #, python-brace-format msgid "env var: {var}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:2959 #, python-brace-format msgid "default: {default}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:3023 msgid "(dynamic)" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/parser.py:199 msgid "Argument {name!r} takes {nargs} values." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/parser.py:381 msgid "Option {name!r} does not take a value." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/parser.py:444 msgid "Option {name!r} requires an argument." msgid_plural "Option {name!r} requires {nargs} arguments." msgstr[0] "" msgstr[1] "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/_termui_impl.py:608 #, python-brace-format msgid "{editor}: Editing failed" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/_termui_impl.py:612 #, python-brace-format msgid "{editor}: Editing failed: {e}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/decorators.py:522 #, fuzzy msgid "Show the version and exit." msgstr "mostra questo messaggio ed esci" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/decorators.py:548 #, fuzzy msgid "Show this message and exit." msgstr "mostra questo messaggio ed esci" #, fuzzy, python-brace-format #~ msgid "{path}: read error\n" #~ msgstr "Licenze obsolete:" #, fuzzy, python-brace-format #~ msgid "{lic_path}: deprecated license\n" #~ msgstr "Licenze obsolete:" #, fuzzy, python-brace-format #~ msgid "{lic_path}: license without file extension\n" #~ msgstr "Licenze senza estensione del file:" #, fuzzy, python-brace-format #~ msgid "{lic_path}: unused license\n" #~ msgstr "Licenze non utilizzate:" #, 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" #, python-brace-format #~ msgid "Could not parse '{expression}'" #~ msgstr "Non è possibile parsificare '{expression}'" #, fuzzy, python-brace-format #~ msgid "(Deprecated) {text}" #~ msgstr "Licenze obsolete:" #, fuzzy #~ msgid "Year of copyright statement." #~ msgstr "anno della dichiaraione del copyright, opzionale" #, python-brace-format #~ msgid "determining identifier of '{path}'" #~ msgstr "determinazione dell'identificativo di '{path}'" #~ msgid "can't write to '{}'" #~ msgstr "non è possibile scrivere su '{}'" #~ msgid "show program's version number and exit" #~ msgstr "mostra la versione del programma ed esce" #~ msgid "download a license and place it in the LICENSES/ directory" #~ msgstr "scarica una licenza e salvala nella directory LICENSES/" #~ msgid "list all non-compliant files" #~ msgstr "lista dei file non conformi" #, fuzzy, 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 there any deprecated licenses in the project?\n" #~ "\n" #~ "- Are there any license files in the LICENSES/ directory without file " #~ "extension?\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" #~ "- Are there any read errors?\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?" #~ msgid "print the project's bill of materials in SPDX format" #~ msgstr "stampa l'elenco dei componenti del progetto in formato SPDX" #~ msgid "'{}' is not a file" #~ msgstr "'{}' non è un file" #~ msgid "can't open '{}'" #~ msgstr "non è possibile aprire '{}'" #~ msgid "can't write to directory '{}'" #~ msgstr "non è possibile scrivere nella directory '{}'" #~ msgid "can't read or write '{}'" #~ msgstr "non è possibile leggere o scrivere '{}'" #~ msgid "SPDX License Identifier of license" #~ msgstr "Identificativo di Licenza SPDX" #~ msgid "the following arguments are required: license" #~ msgstr "sono richiesti i seguenti parametri: license" #~ msgid "usage: " #~ msgstr "uso: " #~ msgid ".__call__() not defined" #~ msgstr ".__call__() non definita" #, python-format #~ msgid "unknown parser %(parser_name)r (choices: %(choices)s)" #~ msgstr "" #~ "parsificatore sconosciuto: %(parser_name)r (alternative: %(choices)s)" #, python-format #~ msgid "argument \"-\" with mode %r" #~ msgstr "parametro \"-\" con modo %r" #, python-format #~ msgid "can't open '%(filename)s': %(error)s" #~ msgstr "non è possibile aprire '%(filename)s': %(error)s" #, python-format #~ msgid "cannot merge actions - two groups are named %r" #~ msgstr "" #~ "non è possibile unire le azioni - due gruppi hanno lo stesso nome %r" #~ msgid "'required' is an invalid argument for positionals" #~ msgstr "'required' non è un parametro posizionale valido" #, 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" #, python-format #~ msgid "dest= is required for options like %r" #~ msgstr "dest= è richiesto per opzioni come %r" #, python-format #~ msgid "invalid conflict_resolution value: %r" #~ msgstr "valore per conflict_resolution non valido: %r" #, 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" #~ msgid "mutually exclusive arguments must be optional" #~ msgstr "i parametri mutualmente esclusivi devono essere opzionali" #~ msgid "cannot have multiple subparser arguments" #~ msgstr "non è possibile avere più di un parametro con sotto-parsificatore" #, python-format #~ msgid "unrecognized arguments: %s" #~ msgstr "parametro sconosciuto: %s" #, python-format #~ msgid "not allowed with argument %s" #~ msgstr "non permesso con parametro %s" #, python-format #~ msgid "ignored explicit argument %r" #~ msgstr "parametro esplicito ignorato %r" #, python-format #~ msgid "the following arguments are required: %s" #~ msgstr "i seguenti parametri sono obbligatori: %s" #, python-format #~ msgid "one of the arguments %s is required" #~ msgstr "uno dei parametri %s è richiesto" #~ msgid "expected at most one argument" #~ msgstr "al massimo un parametro aspettato" #~ msgid "expected at least one argument" #~ msgstr "richiesto almeno un parametro" #, python-format #~ msgid "expected %s argument" #~ msgid_plural "expected %s arguments" #~ msgstr[0] "richiesto il parametro %s" #~ msgstr[1] "richiesti i parametri %s" #, python-format #~ msgid "ambiguous option: %(option)s could match %(matches)s" #~ msgstr "opzione ambigua: %(option)s può essere %(matches)s" #, python-format #~ msgid "unexpected option string: %s" #~ msgstr "nome opzione inaspettato: %s" #, python-format #~ msgid "%r is not callable" #~ msgstr "%r non è richiamabile" #, python-format #~ msgid "invalid %(type)s value: %(value)r" #~ msgstr "valore %(type)s non valido: %(value)r" #, python-format #~ msgid "invalid choice: %(value)r (choose from %(choices)s)" #~ msgstr "scelta non valida: %(value)r (opzioni valide: %(choices)s)" #~ 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 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" #~ 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-6.2.0/po/eo.po0000664000175000017500000015705315077707000013662 0ustar alexalex# 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: 2025-10-07 21:23+0000\n" "PO-Revision-Date: 2025-10-09 21:52+0000\n" "Last-Translator: Marco Ciampa \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.14-dev\n" #: src/reuse/lint.py:40 #, fuzzy msgid "BAD LICENSES" msgstr "NEUZATAJ PERMESILOJ" #: src/reuse/lint.py:42 #, fuzzy msgid "The following licenses are not valid SPDX licenses:" msgstr "La sekvajn permesilojn oni ne uzas:" #: src/reuse/lint.py:50 msgid "DEPRECATED LICENSES" msgstr "ARĤAIKIGITAJ PERMESILOJ" #: src/reuse/lint.py:52 msgid "The following licenses are deprecated by SPDX:" msgstr "La sekvajn permesilojn arĥaikigis SPDX:" #: src/reuse/lint.py:60 msgid "LICENSES WITHOUT FILE EXTENSION" msgstr "PERMESILOJ SEN DOSIERSUFIKSO" #: src/reuse/lint.py:62 msgid "The following licenses have no file extension:" msgstr "La sekvaj permesiloj ne havas dosiersufikson:" #: src/reuse/lint.py:70 msgid "MISSING LICENSES" msgstr "MANKANTAJ PERMESILOJ" #: src/reuse/lint.py:72 msgid "'{}' found in:" msgstr "'{}' trovita en:" #: src/reuse/lint.py:79 msgid "UNUSED LICENSES" msgstr "NEUZATAJ PERMESILOJ" #: src/reuse/lint.py:80 msgid "The following licenses are not used:" msgstr "La sekvajn permesilojn oni ne uzas:" #: src/reuse/lint.py:87 msgid "READ ERRORS" msgstr "LEG-ERAROJ" #: src/reuse/lint.py:88 msgid "Could not read:" msgstr "Ne povis legi:" #: src/reuse/lint.py:94 msgid "INVALID SPDX LICENSE EXPRESSIONS" msgstr "" #: src/reuse/lint.py:99 #, fuzzy msgid "'{}' contains invalid SPDX License Expressions:" msgstr "'{}' ne estas valida SPDX-esprimo. Ĉesigante" #: src/reuse/lint.py:124 msgid "MISSING COPYRIGHT AND LICENSING INFORMATION" msgstr "MANKANTAJ KOPIRAJTAJ KAJ PERMESILAJ INFORMOJ" #: src/reuse/lint.py:130 #, fuzzy msgid "The following files have no copyright and licensing information:" msgstr "La sekvaj dosieroj ne havas kopirajtajn informojn:" #: src/reuse/lint.py:141 msgid "The following files have no copyright information:" msgstr "La sekvaj dosieroj ne havas kopirajtajn informojn:" #: src/reuse/lint.py:150 msgid "The following files have no licensing information:" msgstr "La sekvaj dosieroj ne havas permesilajn informojn:" #: src/reuse/lint.py:157 msgid "SUMMARY" msgstr "RESUMO" #: src/reuse/lint.py:162 msgid "Bad licenses:" msgstr "Malbonaj permesiloj:" #: src/reuse/lint.py:163 msgid "Deprecated licenses:" msgstr "Arĥaikigitaj permesiloj:" #: src/reuse/lint.py:166 msgid "Licenses without file extension:" msgstr "Permesiloj sen dosiersufikso:" #: src/reuse/lint.py:169 msgid "Missing licenses:" msgstr "Mankantaj permesiloj:" #: src/reuse/lint.py:170 msgid "Unused licenses:" msgstr "Neuzataj permesiloj:" #: src/reuse/lint.py:171 msgid "Used licenses:" msgstr "Uzataj permesiloj:" #: src/reuse/lint.py:172 #, fuzzy msgid "Read errors:" msgstr "Leg-eraroj: {count}" #: src/reuse/lint.py:173 #, fuzzy msgid "Invalid SPDX License Expressions:" msgstr "'{}' ne estas valida SPDX-esprimo. Ĉesigante" #: src/reuse/lint.py:183 #, fuzzy msgid "Files with copyright information:" msgstr "Dosieroj sen kopirajtinformo: {count} / {total}" #: src/reuse/lint.py:187 #, fuzzy msgid "Files with license information:" msgstr "Dosieroj sen permesilinformo: {count} / {total}" #: src/reuse/lint.py:204 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:211 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:218 msgid "RECOMMENDATIONS" msgstr "REKOMENDOJ" #: src/reuse/lint.py:286 #, fuzzy, python-brace-format msgid "missing license '{lic}'" msgstr "'{}' ne estas valida SPDX Permesila Identigilo." #: src/reuse/lint.py:291 #, fuzzy msgid "read error" msgstr "Leg-eraroj: {count}" #: src/reuse/lint.py:296 #, fuzzy, python-brace-format msgid "invalid SPDX License Expression '{expression}'" msgstr "'{}' ne estas valida SPDX-esprimo. Ĉesigante" #: src/reuse/lint.py:303 #, fuzzy msgid "no license identifier" msgstr "'{}' ne estas valida SPDX Permesila Identigilo." #: src/reuse/lint.py:307 #, fuzzy msgid "no copyright notice" msgstr "'{}' ne estas valida SPDX Permesila Identigilo." #: src/reuse/lint.py:345 #, fuzzy, python-brace-format msgid "bad license '{lic}'" msgstr "Neuzataj permesiloj:" #: src/reuse/lint.py:350 #, fuzzy msgid "deprecated license" msgstr "Arĥaikigitaj permesiloj:" #: src/reuse/lint.py:355 #, fuzzy msgid "license without file extension" msgstr "Permesiloj sen dosiersufikso:" #: src/reuse/lint.py:360 #, fuzzy msgid "unused license" msgstr "Neuzataj permesiloj:" #: src/reuse/project.py:253 #, fuzzy, python-brace-format msgid "'{path}' covered by {global_path}" msgstr "'{path}' sub .reuse/dep5" #: src/reuse/project.py:261 #, python-brace-format msgid "" "'{path}' is covered exclusively by REUSE.toml. Not reading the file contents." 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:355 #, python-brace-format msgid "" "Found both '{new_path}' and '{old_path}'. You cannot keep both files " "simultaneously; they are not intercompatible." msgstr "" "Trovis ambaŭ '{new_path}' kaj '{old_path}'. Oni ne povas konservi ambaŭ " "dosierojn samtempe; ili ne estas interkongruaj." #: src/reuse/project.py:419 #, python-brace-format msgid "{path} does not have a file extension" msgstr "{path} ne havas dosiersufikson" #: src/reuse/project.py:429 #, 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:441 #, 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:480 msgid "" "project '{}' is not a VCS repository or required VCS software is not " "installed" msgstr "" "projekto '{}' ne estas VCS-deponejo aŭ la bezonata VCS-programaro ne estas " "instalita" #: src/reuse/extract.py:49 #, python-brace-format msgid "" "REUSE_ENCODING_MODULE must have a value in {modules}; it has '{env_module}'. " "Aborting." msgstr "" #: src/reuse/extract.py:69 msgid "" "No supported module that can detect the encoding of files could be " "successfully imported. Re-read the installation instructions for the reuse " "package, or try the following:" msgstr "" #: src/reuse/extract.py:75 msgid "" "- If you are running a Linux distribution, try your equivalent of `apt " "install file` or `dnf install file`." msgstr "" #: src/reuse/extract.py:80 msgid "" "- Run ` pipx install reuse[charset-normalizer]`. Replace 'pipx' with 'pip' " "if you are not using pipx." msgstr "" #: src/reuse/extract.py:451 #, python-brace-format msgid "" "'{path}' was detected as a binary file; not searching its contents for REUSE " "information." msgstr "" #: src/reuse/extract.py:462 #, python-brace-format msgid "" "extracting REUSE information from '{path}' (encoding {encoding}, encoding " "module {module}, newline {newline})" msgstr "" #: src/reuse/header.py:87 msgid "generated comment is missing copyright lines or license expressions" msgstr "al generita komento mankas kopirajtlinioj aŭ permesilesprimoj" #: src/reuse/report.py:160 #, python-brace-format msgid "Could not read '{path}'" msgstr "Ne povis legi '{path}'" #: src/reuse/report.py:165 #, python-brace-format msgid "Unexpected error occurred while parsing '{path}'" msgstr "Okazis neanticipita eraro dum analizado de '{path}'" #: src/reuse/report.py:521 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:532 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:543 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:552 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:564 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:575 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:584 msgid "" "Fix invalid SPDX License Expressions: In one or more files there are SPDX " "License Expressions which cannot be parse. Check whether the value that " "follows 'SPDX-License-Identifier:' is correct. If the detected expression is " "not meant to be valid, put it between 'REUSE-IgnoreStart' and 'REUSE-" "IgnoreEnd' comments." msgstr "" #: src/reuse/report.py:595 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/cli/lint.py:28 #, python-brace-format msgid "" "Lint the project directory for REUSE compliance. This version of the tool " "checks against version {reuse_version} of the REUSE Specification. You can " "find the latest version of the specification at ." msgstr "" #: src/reuse/cli/lint.py:34 msgid "Specifically, the following criteria are checked:" msgstr "" #: src/reuse/cli/lint.py:38 msgid "" "- Are there any bad (unrecognised, not compliant with SPDX) licenses in the " "project?" msgstr "" #: src/reuse/cli/lint.py:43 #, fuzzy msgid "- Are there any deprecated licenses in the project?" msgstr "Kiu estas la reta adreso de la projekto?" #: src/reuse/cli/lint.py:47 msgid "" "- Are there any license files in the LICENSES/ directory without file " "extension?" msgstr "" #: src/reuse/cli/lint.py:54 msgid "" "- Are any licenses referred to inside of the project, but not included in " "the LICENSES/ directory?" msgstr "" #: src/reuse/cli/lint.py:61 msgid "" "- Are any licenses included in the LICENSES/ directory that are not used " "inside of the project?" msgstr "" #: src/reuse/cli/lint.py:66 msgid "- Are there any read errors?" msgstr "" #: src/reuse/cli/lint.py:69 #, fuzzy msgid "- Do all files have valid copyright and licensing information?" msgstr "La sekvaj dosieroj ne havas kopirajtajn kaj permesilajn informojn:" #: src/reuse/cli/lint.py:81 src/reuse/cli/lint_file.py:38 msgid "Prevent output." msgstr "" #: src/reuse/cli/lint.py:89 src/reuse/cli/supported_licenses.py:28 msgid "Format output as JSON." msgstr "" #: src/reuse/cli/lint.py:97 msgid "Format output as plain text. (default)" msgstr "" #: src/reuse/cli/lint.py:105 msgid "Format output as errors per line." msgstr "" #: src/reuse/cli/convert_dep5.py:19 msgid "" "Convert .reuse/dep5 into a REUSE.toml file. The generated file is placed in " "the project root and is semantically identical. The .reuse/dep5 file is " "subsequently deleted." msgstr "" #: src/reuse/cli/convert_dep5.py:31 #, fuzzy msgid "No '.reuse/dep5' file." msgstr "Krante .reuse/dep5" #: src/reuse/cli/lint_file.py:25 msgid "" "Lint individual files for REUSE compliance. The specified FILEs are checked " "for the presence of copyright and licensing information, and whether the " "found licenses are included in the LICENSES/ directory." msgstr "" #: src/reuse/cli/lint_file.py:46 msgid "Format output as errors per line. (default)" msgstr "" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/lint_file.py:51 msgid "FILE" msgstr "" #: src/reuse/cli/lint_file.py:65 #, python-brace-format msgid "'{file}' is not inside of '{root}'." msgstr "" #: src/reuse/cli/spdx.py:22 #, fuzzy msgid "Generate an SPDX bill of materials." msgstr "presi la pecoliston de la projekto en SPDX-formo" #: src/reuse/cli/spdx.py:32 msgid "File to write to." msgstr "" #: src/reuse/cli/spdx.py:38 msgid "" "Populate the LicenseConcluded field; note that reuse cannot guarantee that " "the field is accurate." msgstr "" #: src/reuse/cli/spdx.py:50 msgid "Name of the person signing off on the SPDX report." msgstr "" #: src/reuse/cli/spdx.py:54 msgid "Name of the organization signing off on the SPDX report." msgstr "" #: src/reuse/cli/spdx.py:81 msgid "" "'--creator-person' or '--creator-organization' is required when '--add-" "license-concluded' is provided." msgstr "" #: src/reuse/cli/spdx.py:96 #, 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 "" #: src/reuse/cli/main.py:36 #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/decorators.py:465 #, fuzzy, python-format msgid "%(prog)s, version %(version)s" msgstr "%(prog)s: eraro: %(message)s\n" #: src/reuse/cli/main.py:39 msgid "" "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." msgstr "" #: src/reuse/cli/main.py:46 msgid "" "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." msgstr "" #: src/reuse/cli/main.py:53 msgid "" "You should have received a copy of the GNU General Public License along with " "this program. If not, see ." msgstr "" #: src/reuse/cli/main.py:61 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/cli/main.py:68 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/cli/main.py:72 msgid "Support the FSFE's work:" msgstr "Subtenu la laboradon de FSFE:" #: src/reuse/cli/main.py:77 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/cli/main.py:88 #, fuzzy msgid "Enable debug statements." msgstr "ŝalti sencimigajn ordonojn" #: src/reuse/cli/main.py:93 #, fuzzy msgid "Hide deprecation warnings." msgstr "kaŝi avertojn de evitindaĵoj" #: src/reuse/cli/main.py:98 #, fuzzy msgid "Do not skip over Git submodules." msgstr "ne preterpasi Git-submodulojn" #: src/reuse/cli/main.py:103 #, fuzzy msgid "Do not skip over Meson subprojects." msgstr "ne preterpasi Meson-subprojektojn" #: src/reuse/cli/main.py:108 #, fuzzy msgid "Do not use multiprocessing." msgstr "ne uzi plurprocesoradon" #: src/reuse/cli/main.py:118 #, fuzzy msgid "Define root of project." msgstr "difini radikon de la projekto" #: src/reuse/cli/common.py:51 #, python-brace-format msgid "" "'{path}' could not be parsed. We received the following error message: " "{message}" msgstr "" #: src/reuse/cli/common.py:87 #, python-brace-format msgid "'{name}' is mutually exclusive with: {opts}" msgstr "" #: src/reuse/cli/common.py:103 #, fuzzy msgid "'{}' is not a valid SPDX expression." msgstr "'{}' ne estas valida SPDX-esprimo. Ĉesigante" #: src/reuse/cli/download.py:54 msgid "'{}' is not a valid SPDX License Identifier." msgstr "'{}' ne estas valida SPDX Permesila Identigilo." #: src/reuse/cli/download.py:61 #, fuzzy msgid "Did you mean:" msgstr "Ĉu vi intencis:" #: src/reuse/cli/download.py:68 msgid "" "See for a list of valid SPDX License " "Identifiers." msgstr "" "Vidu por listo de validaj SPDX Permesilaj " "Identigiloj." #: src/reuse/cli/download.py:77 #, python-brace-format msgid "Error: {spdx_identifier} already exists." msgstr "Eraro: {spdx_identifier} jam ekzistas." #: src/reuse/cli/download.py:84 #, fuzzy, python-brace-format msgid "Error: {path} does not exist." msgstr "'{path}' ne finiĝas per .spdx" #: src/reuse/cli/download.py:88 msgid "Error: Failed to download license." msgstr "Eraro: Malsukcesis elŝuti permesilon." #: src/reuse/cli/download.py:93 msgid "Is your internet connection working?" msgstr "Ĉu via retkonekto funkcias?" #: src/reuse/cli/download.py:98 #, python-brace-format msgid "Successfully downloaded {spdx_identifier}." msgstr "Sukceses elŝutis {spdx_identifier}." #: src/reuse/cli/download.py:108 #, 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/cli/download.py:111 msgid "" "LICENSE must be a valid SPDX License Identifier. You may specify LICENSE " "multiple times to download multiple licenses." msgstr "" #: src/reuse/cli/download.py:124 #, fuzzy msgid "Download all missing licenses detected in the project." msgstr "elŝuti ĉiujn mankantajn permesilojn kiujn oni eltrovis en la projekto" #: src/reuse/cli/download.py:132 msgid "Path to download to." msgstr "" #: src/reuse/cli/download.py:138 msgid "" "Source from which to copy custom LicenseRef- licenses, either a directory " "that contains the file or the file itself." msgstr "" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/download.py:145 #, fuzzy msgid "LICENSE" msgstr "MALBONAJ PERMESILOJ" #: src/reuse/cli/download.py:161 #, fuzzy msgid "The 'LICENSE' argument and '--all' option are mutually exclusive." msgstr "opcio --exclude-year kaj --year ekskluzivas unu la alian" #: src/reuse/cli/download.py:173 #, fuzzy msgid "Cannot use '--output' with more than one license." msgstr "ne povas uzi --output kun pli ol unu permesilo" #: src/reuse/cli/annotate.py:66 #, fuzzy msgid "Option '--copyright', '--license', or '--contributor' is required." msgstr "opcio --copyright aŭ --license necesas" #: src/reuse/cli/annotate.py:127 #, 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/cli/annotate.py:160 #, fuzzy, 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/cli/annotate.py:167 #, fuzzy, 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/cli/annotate.py:213 #, fuzzy, python-brace-format msgid "Template '{template}' could not be found." msgstr "ŝablono {template} netroveblas" #: src/reuse/cli/annotate.py:236 #, fuzzy, python-brace-format msgid "'{year}' is not a valid year range." msgstr "'{}' ne estas valida SPDX-esprimo. Ĉesigante" #: src/reuse/cli/annotate.py:245 #, python-brace-format msgid "" "Your operating system's year is set to '{year}'. This is not four digits, " "and not supported." msgstr "" #: src/reuse/cli/annotate.py:287 #, fuzzy msgid "Add copyright and licensing into the headers of files." msgstr "aldoni kopirajtajn kaj permesilajn informojn en la kapojn de dosieroj" #: src/reuse/cli/annotate.py:290 msgid "" "By using --copyright and --license, you can specify which copyright holders " "and licenses to add to the headers of the given files." msgstr "" #: src/reuse/cli/annotate.py:296 msgid "" "By using --contributor, you can specify people or entity that contributed " "but are not copyright holder of the given files." msgstr "" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:309 msgid "COPYRIGHT" msgstr "" #: src/reuse/cli/annotate.py:312 #, fuzzy msgid "Copyright holder, repeatable." msgstr "kopirajtlinio, ripetabla" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:319 msgid "SPDX_IDENTIFIER" msgstr "" #: src/reuse/cli/annotate.py:322 #, fuzzy msgid "SPDX License Identifier, repeatable." msgstr "SPDX Identigilo, ripetabla" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:328 msgid "CONTRIBUTOR" msgstr "" #: src/reuse/cli/annotate.py:331 #, fuzzy msgid "File contributor, repeatable." msgstr "SPDX Identigilo, ripetabla" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:338 msgid "YEAR" msgstr "" #: src/reuse/cli/annotate.py:343 msgid "" "Year of copyright notice. You may define multiple years or a range of years." msgstr "" #: src/reuse/cli/annotate.py:353 #, fuzzy msgid "Comment style to use." msgstr "uzenda komentstilo, malnepra" #: src/reuse/cli/annotate.py:363 #, fuzzy msgid "Copyright prefix to use." msgstr "uzenda komentstilo, malnepra" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:375 msgid "TEMPLATE" msgstr "" #: src/reuse/cli/annotate.py:377 #, fuzzy msgid "Name of template to use." msgstr "nomo de uzenda ŝablono, malnepra" #: src/reuse/cli/annotate.py:384 #, fuzzy msgid "Do not include year in copyright notice." msgstr "ne inkluzivi jaron en kopirajtlinio" #: src/reuse/cli/annotate.py:390 #, fuzzy msgid "Merge copyright notices if they are identical except for their years." msgstr "jaro de kopirajtlinio, malnepra" #: src/reuse/cli/annotate.py:398 #, fuzzy msgid "Force single-line comment style." msgstr "uzenda komentstilo, malnepra" #: src/reuse/cli/annotate.py:405 #, fuzzy msgid "Force multi-line comment style." msgstr "uzenda komentstilo, malnepra" #: src/reuse/cli/annotate.py:411 msgid "Add headers to all files under specified directories recursively." msgstr "" #: src/reuse/cli/annotate.py:416 msgid "Do not replace the first header in the file; just add a new one." msgstr "" #: src/reuse/cli/annotate.py:423 msgid "Always write a .license file instead of a header inside the file." msgstr "" #: src/reuse/cli/annotate.py:430 msgid "Write a .license file to files with unrecognised comment styles." msgstr "" #: src/reuse/cli/annotate.py:437 msgid "Skip files with unrecognised comment styles." msgstr "" #: src/reuse/cli/annotate.py:448 #, fuzzy msgid "Skip files that already contain REUSE information." msgstr "Preterpasis dosieron '{path}' kiu jam enhavas REUSE-informojn" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:453 msgid "PATH" msgstr "" #: src/reuse/cli/annotate.py:510 #, 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/cli/supported_licenses.py:19 #, fuzzy msgid "List all licenses on the SPDX License List." msgstr "listigi ĉiujn subtenitajn SPDX-permesilojn" #: src/reuse/global_licensing.py:92 #, python-brace-format msgid "" "{attr_name} must be a {type_name} (got {value} that is a {value_class})." msgstr "" #: src/reuse/global_licensing.py:106 #, 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:118 #, python-brace-format msgid "{attr_name} must not be empty." msgstr "" #: src/reuse/global_licensing.py:142 #, python-brace-format msgid "{name} must be a {type} (got {value} that is a {value_type})." msgstr "" #: src/reuse/global_licensing.py:166 #, python-brace-format msgid "" "The value of 'precedence' must be one of {precedence_vals} (got {received})" msgstr "" #: src/reuse/global_licensing.py:219 #, fuzzy, python-brace-format msgid "Could not parse '{notice}'" msgstr "Ne povis analizi '{expression}'" #: src/reuse/_annotate.py:94 #, fuzzy, python-brace-format msgid "Skipped unrecognised file '{path}'" msgstr "Preterpasis nekonatan dosieron {path}" #: src/reuse/_annotate.py:100 #, python-brace-format msgid "'{path}' is not recognised; creating '{path}.license'" msgstr "" #: src/reuse/_annotate.py:116 #, python-brace-format msgid "Skipped file '{path}' already containing REUSE information" msgstr "Preterpasis dosieron '{path}' kiu jam enhavas REUSE-informojn" #: src/reuse/_annotate.py:145 #, python-brace-format msgid "Error: Could not create comment for '{path}'" msgstr "Eraro: Ne povis krei komenton por '{path}'" #: src/reuse/_annotate.py:152 #, 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:163 #, python-brace-format msgid "Successfully changed header of {path}" msgstr "Sukcese ŝanĝis kapon de {path}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:162 msgid "Repeat for confirmation" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:178 msgid "Error: The value you entered was invalid." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:180 #, python-brace-format msgid "Error: {e.message}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:191 msgid "Error: The two entered values do not match." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:247 msgid "Error: invalid input" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:866 msgid "Press any key to continue..." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:332 #, python-brace-format msgid "" "Choose from:\n" "\t{choices}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:369 msgid "{value!r} is not {choice}." msgid_plural "{value!r} is not one of {choices}." msgstr[0] "" msgstr[1] "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:460 msgid "{value!r} does not match the format {format}." msgid_plural "{value!r} does not match the formats {formats}." msgstr[0] "" msgstr[1] "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:482 msgid "{value!r} is not a valid {number_type}." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:538 #, python-brace-format msgid "{value} is not in the range {range}." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:719 msgid "{value!r} is not a valid boolean. Recognized values: {states}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:747 msgid "{value!r} is not a valid UUID." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:937 msgid "file" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:939 msgid "directory" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:941 msgid "path" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:988 #, fuzzy msgid "{name} {filename!r} does not exist." msgstr "'{path}' ne finiĝas per .spdx" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:997 msgid "{name} {filename!r} is a file." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:1005 #, fuzzy msgid "{name} {filename!r} is a directory." msgstr "'{}' ne estas dosierujo" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:1014 msgid "{name} {filename!r} is not readable." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:1023 msgid "{name} {filename!r} is not writable." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:1032 msgid "{name} {filename!r} is not executable." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:1099 #, python-brace-format msgid "{len_type} values are required, but {len_value} was given." msgid_plural "{len_type} values are required, but {len_value} were given." msgstr[0] "" msgstr[1] "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/shell_completion.py:332 msgid "Shell completion is not supported for Bash versions older than 4.4." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/shell_completion.py:339 msgid "Couldn't detect Bash version, shell completion is not supported." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:50 #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:89 #, python-brace-format msgid "Error: {message}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:81 #, python-brace-format msgid "Try '{command} {option}' for help." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:130 #, python-brace-format msgid "Invalid value: {message}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:132 #, python-brace-format msgid "Invalid value for {param_hint}: {message}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:190 #, fuzzy msgid "Missing argument" msgstr "poziciaj argumentoj" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:192 #, fuzzy msgid "Missing option" msgstr "Mankantaj permesiloj:" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:194 msgid "Missing parameter" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:196 #, python-brace-format msgid "Missing {param_type}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:203 #, python-brace-format msgid "Missing parameter: {param_name}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:223 #, python-brace-format msgid "No such option: {name}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:235 #, fuzzy, python-brace-format msgid "Did you mean {possibility}?" msgid_plural "(Possible options: {possibilities})" msgstr[0] "Ĉu vi intencis:" msgstr[1] "Ĉu vi intencis:" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:282 msgid "unknown error" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:289 msgid "Could not open file {filename!r}: {message}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1104 #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1141 #, python-brace-format msgid "{text} {deprecated_message}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1160 msgid "Options" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1222 #, fuzzy, python-brace-format msgid "Got unexpected extra argument ({args})" msgid_plural "Got unexpected extra arguments ({args})" msgstr[0] "anticipis unu argumenton" msgstr[1] "anticipis unu argumenton" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1241 msgid "DeprecationWarning: The command {name!r} is deprecated.{extra_message}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1425 msgid "Aborted!" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1799 #, fuzzy msgid "Commands" msgstr "subkomandoj" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1830 #, fuzzy msgid "Missing command." msgstr "Mankantaj permesiloj:" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1908 msgid "No such command {name!r}." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:2332 msgid "Value must be an iterable." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:2355 #, python-brace-format msgid "Takes {nargs} values but 1 was given." msgid_plural "Takes {nargs} values but {len} were given." msgstr[0] "" msgstr[1] "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:2505 msgid "" "DeprecationWarning: The {param_type} {name!r} is deprecated.{extra_message}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:2956 #, python-brace-format msgid "env var: {var}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:2959 #, python-brace-format msgid "default: {default}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:3023 msgid "(dynamic)" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/parser.py:199 msgid "Argument {name!r} takes {nargs} values." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/parser.py:381 msgid "Option {name!r} does not take a value." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/parser.py:444 msgid "Option {name!r} requires an argument." msgid_plural "Option {name!r} requires {nargs} arguments." msgstr[0] "" msgstr[1] "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/_termui_impl.py:608 #, python-brace-format msgid "{editor}: Editing failed" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/_termui_impl.py:612 #, python-brace-format msgid "{editor}: Editing failed: {e}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/decorators.py:522 #, fuzzy msgid "Show the version and exit." msgstr "montri ĉi tiun helpmesaĝon kaj eliri" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/decorators.py:548 #, fuzzy msgid "Show this message and exit." msgstr "montri ĉi tiun helpmesaĝon kaj eliri" #, fuzzy, python-brace-format #~ msgid "{path}: read error\n" #~ msgstr "Arĥaikigitaj permesiloj:" #, fuzzy, python-brace-format #~ msgid "{lic_path}: deprecated license\n" #~ msgstr "Arĥaikigitaj permesiloj:" #, fuzzy, python-brace-format #~ msgid "{lic_path}: license without file extension\n" #~ msgstr "Permesiloj sen dosiersufikso:" #, fuzzy, python-brace-format #~ msgid "{lic_path}: unused license\n" #~ msgstr "Neuzataj permesiloj:" #, 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" #, python-brace-format #~ msgid "Could not parse '{expression}'" #~ msgstr "Ne povis analizi '{expression}'" #, fuzzy, python-brace-format #~ msgid "(Deprecated) {text}" #~ msgstr "Arĥaikigitaj permesiloj:" #, fuzzy #~ msgid "Year of copyright statement." #~ msgstr "jaro de kopirajtlinio, malnepra" #, python-brace-format #~ msgid "determining identifier of '{path}'" #~ msgstr "precizigante identigilon de '{path}'" #, fuzzy #~ msgid "--skip-unrecognised has no effect when used together with --style" #~ msgstr "--output faras nenion kiam --all ankaŭ uziĝas" #~ msgid "can't write to '{}'" #~ msgstr "ne povas skribi al '{}'" #~ msgid "show program's version number and exit" #~ msgstr "montri versionumeron de programo kaj eliri" #~ msgid "download a license and place it in the LICENSES/ directory" #~ msgstr "elŝuti permesilon kaj meti ĝin en la LICENSES/-dosierujon" #~ msgid "list all non-compliant files" #~ msgstr "listigi ĉiujn nekonformajn dosierojn" #, fuzzy, 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 there any deprecated licenses in the project?\n" #~ "\n" #~ "- Are there any license files in the LICENSES/ directory without file " #~ "extension?\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" #~ "- Are there any read errors?\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?" #~ msgid "print the project's bill of materials in SPDX format" #~ msgstr "presi la pecoliston de la projekto en SPDX-formo" #~ msgid "'{}' is not a file" #~ msgstr "'{}' ne estas dosiero" #~ msgid "can't open '{}'" #~ msgstr "ne povas malfermi '{}'" #~ msgid "can't write to directory '{}'" #~ msgstr "ne povas skribi al dosierujo '{}'" #~ msgid "can't read or write '{}'" #~ msgstr "ne povas legi aŭ skribi '{}'" #~ msgid "SPDX License Identifier of license" #~ msgstr "SPDX Permesila Identigilo de permesilo" #~ msgid "--output has no effect when used together with --all" #~ msgstr "--output faras nenion kiam --all ankaŭ uziĝas" #~ msgid "the following arguments are required: license" #~ msgstr "la sekvaj argumentoj nepras: license" #~ msgid "usage: " #~ msgstr "uzo: " #~ msgid ".__call__() not defined" #~ msgstr ".__call__() ne difiniĝas" #, python-format #~ msgid "unknown parser %(parser_name)r (choices: %(choices)s)" #~ msgstr "nekonata analizilo %(parser_name)r (elektoj: %(choices)s)" #, python-format #~ msgid "argument \"-\" with mode %r" #~ msgstr "argumento \"-\" kun moduso %r" #, python-format #~ msgid "can't open '%(filename)s': %(error)s" #~ msgstr "ne povas malfermi '%(filename)s': %(error)s" #, python-format #~ msgid "cannot merge actions - two groups are named %r" #~ msgstr "ne povas kunigi agojn - du grupoj nomiĝas %r" #~ msgid "'required' is an invalid argument for positionals" #~ msgstr "'required' estas nevalida argumento por poziciaj" #, 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" #, python-format #~ msgid "dest= is required for options like %r" #~ msgstr "dest= nepras por elektebloj kiel %r" #, python-format #~ msgid "invalid conflict_resolution value: %r" #~ msgstr "nevalida valoro de conflict_resolution: %r" #, 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" #~ msgid "mutually exclusive arguments must be optional" #~ msgstr "reciproke ekskluzivaj argumentoj devas esti malnepraj" #~ msgid "cannot have multiple subparser arguments" #~ msgstr "ne povas havi plurajn subanalizilajn argumentojn" #, python-format #~ msgid "unrecognized arguments: %s" #~ msgstr "nekonataj argumentoj: %s" #, python-format #~ msgid "not allowed with argument %s" #~ msgstr "ne permesita kun argumento: %s" #, python-format #~ msgid "ignored explicit argument %r" #~ msgstr "malatentis malimplicitan argumenton %r" #, python-format #~ msgid "the following arguments are required: %s" #~ msgstr "la sekvaj argumentoj nepras: %s" #, python-format #~ msgid "one of the arguments %s is required" #~ msgstr "unu el la argumentoj %s nepras" #~ msgid "expected at most one argument" #~ msgstr "anticipis maksimume unu argumenton" #~ msgid "expected at least one argument" #~ msgstr "anticipis minimume unu argumenton" #, python-format #~ msgid "expected %s argument" #~ msgid_plural "expected %s arguments" #~ msgstr[0] "anticipis %s argumenton" #~ msgstr[1] "anticipis %s argumentojn" #, python-format #~ msgid "ambiguous option: %(option)s could match %(matches)s" #~ msgstr "dubsenca elekteblo: %(option)s povus egali al %(matches)s" #, python-format #~ msgid "unexpected option string: %s" #~ msgstr "neanticipita elektebla ĉeno: %s" #, python-format #~ msgid "%r is not callable" #~ msgstr "%r ne alvokeblas" #, python-format #~ msgid "invalid %(type)s value: %(value)r" #~ msgstr "nevalida %(type)s-valoro: %(value)r" #, python-format #~ msgid "invalid choice: %(value)r (choose from %(choices)s)" #~ msgstr "nevalida elekto: %(value)r (elektu el %(choices)s)" #, fuzzy, python-brace-format #~ msgid "'{path}' could not be decoded as UTF-8." #~ msgstr "ne povis malkodi '{dep5}' kiel UTF-8." #~ 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 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" #~ 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-6.2.0/po/cs.po0000664000175000017500000017547715077707000013676 0ustar alexalex# 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: 2025-10-07 21:23+0000\n" "PO-Revision-Date: 2025-09-23 22:01+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 5.14-dev\n" #: src/reuse/lint.py:40 msgid "BAD LICENSES" msgstr "CHYBNÉ LICENCE" #: src/reuse/lint.py:42 #, fuzzy msgid "The following licenses are not valid SPDX licenses:" msgstr "Následující licence nejsou používány:" #: src/reuse/lint.py:50 msgid "DEPRECATED LICENSES" msgstr "ZASTARALÉ LICENCE" #: src/reuse/lint.py:52 msgid "The following licenses are deprecated by SPDX:" msgstr "Následující licence jsou v SPDX zrušeny:" #: src/reuse/lint.py:60 msgid "LICENSES WITHOUT FILE EXTENSION" msgstr "LICENCE BEZ KONCOVKY SOUBORU" #: src/reuse/lint.py:62 msgid "The following licenses have no file extension:" msgstr "Následující licence nemají příponu souboru:" #: src/reuse/lint.py:70 msgid "MISSING LICENSES" msgstr "CHYBĚJÍCÍ LICENCE" #: src/reuse/lint.py:72 msgid "'{}' found in:" msgstr "'{}' nalezeno v:" #: src/reuse/lint.py:79 msgid "UNUSED LICENSES" msgstr "NEPOUŽITÉ LICENCE" #: src/reuse/lint.py:80 msgid "The following licenses are not used:" msgstr "Následující licence nejsou používány:" #: src/reuse/lint.py:87 msgid "READ ERRORS" msgstr "CHYBY ČTENÍ" #: src/reuse/lint.py:88 msgid "Could not read:" msgstr "Nelze načíst:" #: src/reuse/lint.py:94 msgid "INVALID SPDX LICENSE EXPRESSIONS" msgstr "" #: src/reuse/lint.py:99 #, fuzzy msgid "'{}' contains invalid SPDX License Expressions:" msgstr "'{}' není platný výraz SPDX." #: src/reuse/lint.py:124 msgid "MISSING COPYRIGHT AND LICENSING INFORMATION" msgstr "CHYBĚJÍCÍ INFORMACE O AUTORSKÝCH PRÁVECH A LICENCÍCH" #: src/reuse/lint.py:130 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:141 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:150 msgid "The following files have no licensing information:" msgstr "Následující soubory neobsahují žádné licenční informace:" #: src/reuse/lint.py:157 msgid "SUMMARY" msgstr "SHRNUTÍ" #: src/reuse/lint.py:162 msgid "Bad licenses:" msgstr "Neplatné licence:" #: src/reuse/lint.py:163 msgid "Deprecated licenses:" msgstr "Zastaralé licence:" #: src/reuse/lint.py:166 msgid "Licenses without file extension:" msgstr "Licence bez přípony souboru:" #: src/reuse/lint.py:169 msgid "Missing licenses:" msgstr "Chybějící licence:" #: src/reuse/lint.py:170 msgid "Unused licenses:" msgstr "Nepoužité licence:" #: src/reuse/lint.py:171 msgid "Used licenses:" msgstr "Použité licence:" #: src/reuse/lint.py:172 msgid "Read errors:" msgstr "Chyby čtení:" #: src/reuse/lint.py:173 #, fuzzy msgid "Invalid SPDX License Expressions:" msgstr "'{}' není platný výraz SPDX." #: src/reuse/lint.py:183 msgid "Files with copyright information:" msgstr "Soubory s informacemi o autorských právech:" #: src/reuse/lint.py:187 msgid "Files with license information:" msgstr "Soubory s licenčními informacemi:" #: src/reuse/lint.py:204 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:211 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:218 msgid "RECOMMENDATIONS" msgstr "DOPORUČENÍ" #: src/reuse/lint.py:286 #, fuzzy, python-brace-format msgid "missing license '{lic}'" msgstr "{path}: chybí licence {lic}\n" #: src/reuse/lint.py:291 #, fuzzy msgid "read error" msgstr "Chyby čtení:" #: src/reuse/lint.py:296 #, fuzzy, python-brace-format msgid "invalid SPDX License Expression '{expression}'" msgstr "'{}' není platný výraz SPDX." #: src/reuse/lint.py:303 #, fuzzy msgid "no license identifier" msgstr "{path}: žádný identifikátor licence\n" #: src/reuse/lint.py:307 #, fuzzy msgid "no copyright notice" msgstr "{path}: žádné upozornění na autorská práva\n" #: src/reuse/lint.py:345 #, fuzzy, python-brace-format msgid "bad license '{lic}'" msgstr "{path}: špatná licence {lic}\n" #: src/reuse/lint.py:350 #, fuzzy msgid "deprecated license" msgstr "Zastaralé licence:" #: src/reuse/lint.py:355 #, fuzzy msgid "license without file extension" msgstr "Licence bez přípony souboru:" #: src/reuse/lint.py:360 #, fuzzy msgid "unused license" msgstr "Nepoužité licence:" #: src/reuse/project.py:253 #, python-brace-format msgid "'{path}' covered by {global_path}" msgstr "'{path}' zahrnuto v {global_path}" #: src/reuse/project.py:261 #, python-brace-format msgid "" "'{path}' is covered exclusively by REUSE.toml. Not reading the file contents." msgstr "'{path}' je zahrnuta výhradně v REUSE.toml. Nečte obsah souboru." #: 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' je zastaralý. Místo toho doporučujeme používat soubor REUSE." "toml. Pro konverzi použijte `reuse convert-dep5`." #: src/reuse/project.py:355 #, python-brace-format msgid "" "Found both '{new_path}' and '{old_path}'. You cannot keep both files " "simultaneously; they are not intercompatible." msgstr "" "Nalezeno '{new_path}' i '{old_path}'. Oba soubory nelze uchovávat současně, " "nejsou vzájemně kompatibilní." #: src/reuse/project.py:419 #, python-brace-format msgid "{path} does not have a file extension" msgstr "{path} nemá příponu souboru" #: src/reuse/project.py:429 #, 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:441 #, 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:480 msgid "" "project '{}' is not a VCS repository or required VCS software is not " "installed" msgstr "" "projekt '{}' není úložištěm VCS nebo není nainstalován požadovaný software " "VCS" #: src/reuse/extract.py:49 #, python-brace-format msgid "" "REUSE_ENCODING_MODULE must have a value in {modules}; it has '{env_module}'. " "Aborting." msgstr "" #: src/reuse/extract.py:69 msgid "" "No supported module that can detect the encoding of files could be " "successfully imported. Re-read the installation instructions for the reuse " "package, or try the following:" msgstr "" #: src/reuse/extract.py:75 msgid "" "- If you are running a Linux distribution, try your equivalent of `apt " "install file` or `dnf install file`." msgstr "" #: src/reuse/extract.py:80 msgid "" "- Run ` pipx install reuse[charset-normalizer]`. Replace 'pipx' with 'pip' " "if you are not using pipx." msgstr "" #: src/reuse/extract.py:451 #, python-brace-format msgid "" "'{path}' was detected as a binary file; not searching its contents for REUSE " "information." msgstr "" "'{path}' byl rozpoznán jako binární soubor; v jeho obsahu nebyly hledány " "informace o REUSE." #: src/reuse/extract.py:462 #, python-brace-format msgid "" "extracting REUSE information from '{path}' (encoding {encoding}, encoding " "module {module}, newline {newline})" msgstr "" #: src/reuse/header.py:87 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/report.py:160 #, python-brace-format msgid "Could not read '{path}'" msgstr "Nepodařilo se načíst '{path}'" #: src/reuse/report.py:165 #, 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:521 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 "" "Oprava špatných licencí: Alespoň jedna licence v adresáři LICENSES a/nebo " "poskytnutá pomocí značek 'SPDX-License-Identifier' je neplatná. Nejsou to " "platné identifikátory licencí SPDX nebo nezačínají znakem 'LicenseRef-'. " "Často kladené otázky o vlastních licencích: https://reuse.software/faq/" "#custom-license" #: src/reuse/report.py:532 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 "" "Oprava zastaralých licencí: Alespoň jedna z licencí v adresáři LICENSES a/" "nebo poskytnutých pomocí tagu 'SPDX-License-Identifier' nebo v souboru '." "reuse/dep5' byla v SPDX zastaralá. Aktuální seznam a příslušné doporučené " "nové identifikátory naleznete zde: " #: src/reuse/report.py:543 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 "" "Oprava licencí bez přípony souboru: Nejméně jeden textový soubor licence v " "adresáři 'LICENSES' nemá příponu '.txt'. Soubor(y) odpovídajícím způsobem " "přejmenujte." #: src/reuse/report.py:552 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 "" "Oprava chybějících licencí: V adresáři 'LICENSES' není k dispozici " "odpovídající textový soubor s licencí pro alespoň jeden z identifikátorů " "licencí poskytovaných pomocí značek 'SPDX-License-Identifier'. Pro " "identifikátory licencí SPDX můžete jednoduše spustit příkaz 'reuse download " "--all' a získat všechny chybějící. Pro vlastní licence (začínající na " "'LicenseRef-') musíte tyto soubory přidat sami." #: src/reuse/report.py:564 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 "" "Oprava nepoužívaných licencí: Alespoň jeden z textových souborů licencí v " "'LICENSES' není odkazován žádným souborem, např. značkou 'SPDX-License-" "Identifier'. Ujistěte se, že jste odpovídajícím způsobem licencované soubory " "buď správně označili, nebo nepoužitý licenční text odstranili, pokud jste si " "jisti, že žádný soubor nebo kousek kódu není takto licencován." #: src/reuse/report.py:575 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 "" "Oprava chyb čtení: Nástroj nemůže přečíst alespoň jeden ze souborů v " "adresáři. Zkontrolujte oprávnění souboru. Postižené soubory najdete v horní " "části výstupu jako součást zaznamenaných chybových hlášení." #: src/reuse/report.py:584 msgid "" "Fix invalid SPDX License Expressions: In one or more files there are SPDX " "License Expressions which cannot be parse. Check whether the value that " "follows 'SPDX-License-Identifier:' is correct. If the detected expression is " "not meant to be valid, put it between 'REUSE-IgnoreStart' and 'REUSE-" "IgnoreEnd' comments." msgstr "" #: src/reuse/report.py:595 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 "" "Oprava chybějících informací o autorských právech/licencích: U jednoho nebo " "více souborů nemůže nástroj najít informace o autorských právech a/nebo " "licenční informace. To obvykle provedete přidáním značek 'SPDX-" "FileCopyrightText' a 'SPDX-License-Identifier' ke každému souboru. V návodu " "jsou vysvětleny další způsoby, jak to provést: " #: src/reuse/cli/lint.py:28 #, python-brace-format msgid "" "Lint the project directory for REUSE compliance. This version of the tool " "checks against version {reuse_version} of the REUSE Specification. You can " "find the latest version of the specification at ." msgstr "" "Proveďte lintování adresáře projektu, aby byl v souladu s pravidly REUSE. " "Tato verze nástroje kontroluje verzi {reuse_version} specifikace REUSE. " "Nejnovější verzi specifikace najdete na adrese ." #: src/reuse/cli/lint.py:34 msgid "Specifically, the following criteria are checked:" msgstr "Kontrolují se zejména tato kritéria:" #: src/reuse/cli/lint.py:38 msgid "" "- Are there any bad (unrecognised, not compliant with SPDX) licenses in the " "project?" msgstr "" "- Jsou v projektu nějaké špatné (nerozpoznané, nekompatibilní s SPDX) " "licence?" #: src/reuse/cli/lint.py:43 msgid "- Are there any deprecated licenses in the project?" msgstr "- Jsou v projektu nějaké zastaralé licence?" #: src/reuse/cli/lint.py:47 msgid "" "- Are there any license files in the LICENSES/ directory without file " "extension?" msgstr "- Jsou v adresáři LICENSES/ nějaké licenční soubory bez přípony?" #: src/reuse/cli/lint.py:54 msgid "" "- Are any licenses referred to inside of the project, but not included in " "the LICENSES/ directory?" msgstr "" "- Odkazuje se na nějaké licence uvnitř projektu, ale nejsou obsaženy v " "adresáři LICENSES/?" #: src/reuse/cli/lint.py:61 msgid "" "- Are any licenses included in the LICENSES/ directory that are not used " "inside of the project?" msgstr "" "- Jsou v adresáři LICENSES/ obsaženy nějaké licence, které se v projektu " "nepoužívají?" #: src/reuse/cli/lint.py:66 msgid "- Are there any read errors?" msgstr "- Dochází k chybám při čtení?" #: src/reuse/cli/lint.py:69 msgid "- Do all files have valid copyright and licensing information?" msgstr "" "- Mají všechny soubory platné informace o autorských právech a licencích?" #: src/reuse/cli/lint.py:81 src/reuse/cli/lint_file.py:38 msgid "Prevent output." msgstr "Brání výstupu." #: src/reuse/cli/lint.py:89 src/reuse/cli/supported_licenses.py:28 msgid "Format output as JSON." msgstr "Formátuje výstup jako JSON." #: src/reuse/cli/lint.py:97 msgid "Format output as plain text. (default)" msgstr "Formátování výstupu jako prostého textu. (výchozí)" #: src/reuse/cli/lint.py:105 msgid "Format output as errors per line." msgstr "Formátuje výstup jako chyby na řádek." #: src/reuse/cli/convert_dep5.py:19 msgid "" "Convert .reuse/dep5 into a REUSE.toml file. The generated file is placed in " "the project root and is semantically identical. The .reuse/dep5 file is " "subsequently deleted." msgstr "" "Převod souboru .reuse/dep5 do souboru REUSE.toml. Vygenerovaný soubor je " "umístěn v kořenovém adresáři projektu a je sémanticky identický. Soubor ." "reuse/dep5 je následně odstraněn." #: src/reuse/cli/convert_dep5.py:31 msgid "No '.reuse/dep5' file." msgstr "Žádný soubor '.reuse/dep5'." #: src/reuse/cli/lint_file.py:25 msgid "" "Lint individual files for REUSE compliance. The specified FILEs are checked " "for the presence of copyright and licensing information, and whether the " "found licenses are included in the LICENSES/ directory." msgstr "" "Lintování jednotlivých souborů pro splnění požadavků REUSE. U zadaných " "souborů se kontroluje přítomnost informací o autorských právech a licencích " "a zda jsou nalezené licence obsaženy v adresáři LICENSES/." #: src/reuse/cli/lint_file.py:46 msgid "Format output as errors per line. (default)" msgstr "Formátování výstupu jako chyby na řádek. (výchozí)" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/lint_file.py:51 msgid "FILE" msgstr "SOUBOR" #: src/reuse/cli/lint_file.py:65 #, python-brace-format msgid "'{file}' is not inside of '{root}'." msgstr "'{file}' není uvnitř '{root}'." #: src/reuse/cli/spdx.py:22 msgid "Generate an SPDX bill of materials." msgstr "Vytisknout výkaz položek v SPDX." #: src/reuse/cli/spdx.py:32 msgid "File to write to." msgstr "Soubor, do kterého se zapisuje." #: src/reuse/cli/spdx.py:38 msgid "" "Populate the LicenseConcluded field; note that reuse cannot guarantee that " "the field is accurate." msgstr "" "Vyplňte pole LicenseConcluded; upozorňujeme, že reuse nemůže zaručit, že " "pole je přesné." #: src/reuse/cli/spdx.py:50 msgid "Name of the person signing off on the SPDX report." msgstr "Jméno osoby podepisující zprávu SPDX." #: src/reuse/cli/spdx.py:54 msgid "Name of the organization signing off on the SPDX report." msgstr "Název organizace, která podepisuje zprávu SPDX." #: src/reuse/cli/spdx.py:81 msgid "" "'--creator-person' or '--creator-organization' is required when '--add-" "license-concluded' is provided." msgstr "" "Pokud je zadán parametr '--add-license-concluded', je vyžadován parametr '--" "creator-person' nebo '--creator-organization'." #: src/reuse/cli/spdx.py:96 #, 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" #: src/reuse/cli/main.py:36 #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/decorators.py:465 #, python-format msgid "%(prog)s, version %(version)s" msgstr "%(prog)s, verze %(version)s" #: src/reuse/cli/main.py:39 msgid "" "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." msgstr "" "Tento program je svobodný software: můžete jej šířit a/nebo upravovat za " "podmínek GNU General Public License, jak ji vydala Free Software Foundation, " "a to buď ve verzi 3, nebo (podle vaší volby) v jakékoli pozdější verzi." #: src/reuse/cli/main.py:46 msgid "" "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." msgstr "" "Tento program je šířen v naději, že bude užitečný, ale BEZ JAKÉKOLIV ZÁRUKY; " "dokonce ani bez předpokládané záruky PRODEJNOSTI nebo VHODNOSTI PRO " "KONKRÉTNÍ ÚČEL. Další podrobnosti naleznete v Obecné veřejné licenci GNU." #: src/reuse/cli/main.py:53 msgid "" "You should have received a copy of the GNU General Public License along with " "this program. If not, see ." msgstr "" "Spolu s tímto programem jste měli obdržet kopii Obecné veřejné licence GNU. " "Pokud ne, podívejte se na ." #: src/reuse/cli/main.py:61 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/cli/main.py:68 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/cli/main.py:72 msgid "Support the FSFE's work:" msgstr "Podpořte činnost FSFE:" #: src/reuse/cli/main.py:77 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/cli/main.py:88 msgid "Enable debug statements." msgstr "Povolit příkazy pro ladění." #: src/reuse/cli/main.py:93 msgid "Hide deprecation warnings." msgstr "Skrýt varování o zastarání." #: src/reuse/cli/main.py:98 msgid "Do not skip over Git submodules." msgstr "Nepřeskakovat submoduly v Git." #: src/reuse/cli/main.py:103 msgid "Do not skip over Meson subprojects." msgstr "Nepřeskakovat podprojekty Meson." #: src/reuse/cli/main.py:108 msgid "Do not use multiprocessing." msgstr "Nepoužívat multiprocessing." #: src/reuse/cli/main.py:118 msgid "Define root of project." msgstr "Definovat kořen projektu." #: src/reuse/cli/common.py:51 #, python-brace-format msgid "" "'{path}' could not be parsed. We received the following error message: " "{message}" msgstr "" "'{path}' se nepodařilo zpracovat. Obdrželi jsme následující chybové hlášení: " "{message}" #: src/reuse/cli/common.py:87 #, python-brace-format msgid "'{name}' is mutually exclusive with: {opts}" msgstr "'{name}' se vzájemně vylučuje s: {opts}" #: src/reuse/cli/common.py:103 msgid "'{}' is not a valid SPDX expression." msgstr "'{}' není platný výraz SPDX." #: src/reuse/cli/download.py:54 msgid "'{}' is not a valid SPDX License Identifier." msgstr "'{}' není platný identifikátor licence SPDX." #: src/reuse/cli/download.py:61 msgid "Did you mean:" msgstr "Chtěl jste říct:" #: src/reuse/cli/download.py:68 msgid "" "See for a list of valid SPDX License " "Identifiers." msgstr "" "Seznam platných identifikátorů licence SPDX naleznete na ." #: src/reuse/cli/download.py:77 #, python-brace-format msgid "Error: {spdx_identifier} already exists." msgstr "Chyba: {spdx_identifier} již existuje." #: src/reuse/cli/download.py:84 #, python-brace-format msgid "Error: {path} does not exist." msgstr "Chyba: {path} neexistuje." #: src/reuse/cli/download.py:88 msgid "Error: Failed to download license." msgstr "Chyba: Nepodařilo se stáhnout licenci." #: src/reuse/cli/download.py:93 msgid "Is your internet connection working?" msgstr "Funguje vaše internetové připojení?" #: src/reuse/cli/download.py:98 #, python-brace-format msgid "Successfully downloaded {spdx_identifier}." msgstr "Úspěšně stažen {spdx_identifier}." #: src/reuse/cli/download.py:108 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/cli/download.py:111 msgid "" "LICENSE must be a valid SPDX License Identifier. You may specify LICENSE " "multiple times to download multiple licenses." msgstr "" "LICENSE musí být platný identifikátor licence SPDX. Pro stažení více licencí " "můžete zadat LICENSE vícekrát." #: src/reuse/cli/download.py:124 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/cli/download.py:132 msgid "Path to download to." msgstr "Cesta ke stažení." #: src/reuse/cli/download.py:138 msgid "" "Source from which to copy custom LicenseRef- licenses, either a directory " "that contains the file or the file itself." msgstr "" "Zdroj, ze kterého se kopírují vlastní licence LicenseRef- nebo adresář, " "který soubor obsahuje, nebo samotný soubor." #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/download.py:145 msgid "LICENSE" msgstr "LICENCE" #: src/reuse/cli/download.py:161 msgid "The 'LICENSE' argument and '--all' option are mutually exclusive." msgstr "Argument 'LICENSE' a možnost '--all' se vzájemně vylučují." #: src/reuse/cli/download.py:173 msgid "Cannot use '--output' with more than one license." msgstr "Nelze použít --output s více než jednou licencí." #: src/reuse/cli/annotate.py:66 msgid "Option '--copyright', '--license', or '--contributor' is required." msgstr "Je vyžadována možnost „--copyright“, „--licence“ nebo „--contributor“." #: src/reuse/cli/annotate.py:127 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 souboru. Použijte prosím „--" "style“, „--force-dot-license“, „--fallback-dot-license“ nebo „--skip-" "unrecognised“:" #: src/reuse/cli/annotate.py:160 #, 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/cli/annotate.py:167 #, 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 prosím --multi-line." #: src/reuse/cli/annotate.py:213 #, python-brace-format msgid "Template '{template}' could not be found." msgstr "Šablonu {template} se nepodařilo najít." #: src/reuse/cli/annotate.py:236 #, fuzzy, python-brace-format msgid "'{year}' is not a valid year range." msgstr "{value!r} není platný boolean." #: src/reuse/cli/annotate.py:245 #, python-brace-format msgid "" "Your operating system's year is set to '{year}'. This is not four digits, " "and not supported." msgstr "" #: src/reuse/cli/annotate.py:287 msgid "Add copyright and licensing into the headers of files." msgstr "Přidání autorských práv a licencí do záhlaví souborů." #: src/reuse/cli/annotate.py:290 msgid "" "By using --copyright and --license, you can specify which copyright holders " "and licenses to add to the headers of the given files." msgstr "" "Pomocí --copyright a --license můžete určit, které držitele autorských práv " "a licence přidat do záhlaví daných souborů." #: src/reuse/cli/annotate.py:296 msgid "" "By using --contributor, you can specify people or entity that contributed " "but are not copyright holder of the given files." msgstr "" "Pomocí --contributor můžete určit osoby nebo subjekty, které přispěly, ale " "nejsou držiteli autorských práv k daným souborům." #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:309 msgid "COPYRIGHT" msgstr "COPYRIGHT" #: src/reuse/cli/annotate.py:312 #, fuzzy msgid "Copyright holder, repeatable." msgstr "Prohlášení o autorských právech, opakovatelné." #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:319 msgid "SPDX_IDENTIFIER" msgstr "SPDX_IDENTIFIER" #: src/reuse/cli/annotate.py:322 msgid "SPDX License Identifier, repeatable." msgstr "Identifikátor licence SPDX, opakovatelný." #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:328 msgid "CONTRIBUTOR" msgstr "PŘISPĚVATEL" #: src/reuse/cli/annotate.py:331 msgid "File contributor, repeatable." msgstr "Přispěvatel souboru, opakovatelný." #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:338 msgid "YEAR" msgstr "ROK" #: src/reuse/cli/annotate.py:343 msgid "" "Year of copyright notice. You may define multiple years or a range of years." msgstr "" #: src/reuse/cli/annotate.py:353 msgid "Comment style to use." msgstr "Styl komentáře k použití." #: src/reuse/cli/annotate.py:363 msgid "Copyright prefix to use." msgstr "Předpona autorských práv k užití." #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:375 msgid "TEMPLATE" msgstr "ŠABLONA" #: src/reuse/cli/annotate.py:377 msgid "Name of template to use." msgstr "Název šablony, která se má použít." #: src/reuse/cli/annotate.py:384 #, fuzzy msgid "Do not include year in copyright notice." msgstr "V prohlášení o autorských právech neuvádějte rok." #: src/reuse/cli/annotate.py:390 #, fuzzy msgid "Merge copyright notices if they are identical except for their years." msgstr "" "Slučte řádky s autorskými právy, pokud jsou prohlášení o autorských právech " "totožná." #: src/reuse/cli/annotate.py:398 msgid "Force single-line comment style." msgstr "Vyžadujte jednořádkový styl komentáře." #: src/reuse/cli/annotate.py:405 msgid "Force multi-line comment style." msgstr "Vyžadujte víceřádkový styl komentáře." #: src/reuse/cli/annotate.py:411 msgid "Add headers to all files under specified directories recursively." msgstr "Rekurzivně přidejte hlavičky ke všem souborům v zadaných adresářích." #: src/reuse/cli/annotate.py:416 msgid "Do not replace the first header in the file; just add a new one." msgstr "První záhlaví v souboru nenahrazujte, pouze přidejte nové." #: src/reuse/cli/annotate.py:423 msgid "Always write a .license file instead of a header inside the file." msgstr "Místo hlavičky uvnitř souboru vždy napište soubor .license." #: src/reuse/cli/annotate.py:430 msgid "Write a .license file to files with unrecognised comment styles." msgstr "Zapište soubor .license do souborů s nerozpoznanými styly komentářů." #: src/reuse/cli/annotate.py:437 msgid "Skip files with unrecognised comment styles." msgstr "Přeskočte soubory s nerozpoznanými styly komentářů." #: src/reuse/cli/annotate.py:448 msgid "Skip files that already contain REUSE information." msgstr "Přeskočte soubory, které již obsahují informace REUSE." #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:453 msgid "PATH" msgstr "CESTA" #: src/reuse/cli/annotate.py:510 #, 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/cli/supported_licenses.py:19 msgid "List all licenses on the SPDX License List." msgstr "Seznam všech licencí v seznamu licencí SPDX." #: src/reuse/global_licensing.py:92 #, python-brace-format msgid "" "{attr_name} must be a {type_name} (got {value} that is a {value_class})." msgstr "" "{attr_name} musí být {type_name} (mít {value}, který je {value_class})." #: src/reuse/global_licensing.py:106 #, python-brace-format msgid "" "Item in {attr_name} collection must be a {type_name} (got {item_value} that " "is a {item_class})." msgstr "" "Položka v kolekci {attr_name} musí být {type_name} (mít {item_value}, která " "je {item_class})." #: src/reuse/global_licensing.py:118 #, python-brace-format msgid "{attr_name} must not be empty." msgstr "{attr_name} nesmí být prázdný." #: src/reuse/global_licensing.py:142 #, python-brace-format msgid "{name} must be a {type} (got {value} that is a {value_type})." msgstr "{name} musí být {type} (má {value}, která je {value_type})." #: src/reuse/global_licensing.py:166 #, python-brace-format msgid "" "The value of 'precedence' must be one of {precedence_vals} (got {received})" msgstr "" "Hodnota 'precedence' musí být jedna z {precedence_vals} (got {received})" #: src/reuse/global_licensing.py:219 #, fuzzy, python-brace-format msgid "Could not parse '{notice}'" msgstr "Nepodařilo se analyzovat '{expression}'" #: src/reuse/_annotate.py:94 #, python-brace-format msgid "Skipped unrecognised file '{path}'" msgstr "Přeskočen nerozpoznaný soubor '{path}'" #: src/reuse/_annotate.py:100 #, python-brace-format msgid "'{path}' is not recognised; creating '{path}.license'" msgstr "'{path}' není rozpoznán; vytváří se '{path}.license'" #: src/reuse/_annotate.py:116 #, python-brace-format msgid "Skipped file '{path}' already containing REUSE information" msgstr "Přeskočený soubor '{path}' již obsahuje informace REUSE" #: src/reuse/_annotate.py:145 #, 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:152 #, 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:163 #, python-brace-format msgid "Successfully changed header of {path}" msgstr "Úspěšně změněna hlavička {path}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:162 msgid "Repeat for confirmation" msgstr "Opakovat pro potvrzení" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:178 msgid "Error: The value you entered was invalid." msgstr "Chyba: Zadaná hodnota je neplatná." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:180 #, python-brace-format msgid "Error: {e.message}" msgstr "Chyba: {e.message}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:191 msgid "Error: The two entered values do not match." msgstr "Chyba: Dvě zadané hodnoty se neshodují." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:247 msgid "Error: invalid input" msgstr "Chyba: neplatné zadání" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:866 msgid "Press any key to continue..." msgstr "Pro pokračování stiskněte libovolnou klávesu..." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:332 #, python-brace-format msgid "" "Choose from:\n" "\t{choices}" msgstr "" "Vyberte si z:\n" "\t{choices}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:369 msgid "{value!r} is not {choice}." msgid_plural "{value!r} is not one of {choices}." msgstr[0] "{value!r} není {choice}." msgstr[1] "{value!r} není jednou z {choices}." msgstr[2] "{value!r} není jednou z {choices}." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:460 msgid "{value!r} does not match the format {format}." msgid_plural "{value!r} does not match the formats {formats}." msgstr[0] "{value!r} neodpovídá formátu {format}." msgstr[1] "{value!r} neodpovídá formátům {formats}." msgstr[2] "{value!r} neodpovídá formátům {formats}." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:482 msgid "{value!r} is not a valid {number_type}." msgstr "{value!r} není platný {number_type}." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:538 #, python-brace-format msgid "{value} is not in the range {range}." msgstr "{value} není v rozsahu {range}." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:719 #, fuzzy msgid "{value!r} is not a valid boolean. Recognized values: {states}" msgstr "{value!r} není platný boolean." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:747 msgid "{value!r} is not a valid UUID." msgstr "{value!r} není platný UUID." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:937 msgid "file" msgstr "soubor" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:939 msgid "directory" msgstr "adresář" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:941 msgid "path" msgstr "cesta" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:988 msgid "{name} {filename!r} does not exist." msgstr "{name} {filename!r} neexistuje." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:997 msgid "{name} {filename!r} is a file." msgstr "{name} {filename!r} je soubor." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:1005 msgid "{name} {filename!r} is a directory." msgstr "{name} {filename!r} je adresář." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:1014 msgid "{name} {filename!r} is not readable." msgstr "{name} {filename!r} není čitelný." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:1023 msgid "{name} {filename!r} is not writable." msgstr "{name} {filename!r} není zapisovatelný." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:1032 msgid "{name} {filename!r} is not executable." msgstr "{name} {filename!r} není spustitelný." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:1099 #, python-brace-format msgid "{len_type} values are required, but {len_value} was given." msgid_plural "{len_type} values are required, but {len_value} were given." msgstr[0] "" "Hodnoty {len_type} jsou povinné, ale byla zadána {len_value} hodnota." msgstr[1] "" "Hodnoty {len_type} jsou povinné, ale byly zadány {len_value} hodnoty." msgstr[2] "" "Hodnoty {len_type} jsou povinné, ale bylo zadáno {len_value} hodnot." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/shell_completion.py:332 msgid "Shell completion is not supported for Bash versions older than 4.4." msgstr "" "Doplňování shellu není podporováno ve verzích jazyka Bash starších než 4.4." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/shell_completion.py:339 msgid "Couldn't detect Bash version, shell completion is not supported." msgstr "Nepodařilo se zjistit verzi Bash, doplňování shellu není podporováno." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:50 #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:89 #, python-brace-format msgid "Error: {message}" msgstr "Chyba: {message}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:81 #, python-brace-format msgid "Try '{command} {option}' for help." msgstr "Pro nápovědu zkuste '{command} {option}'." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:130 #, python-brace-format msgid "Invalid value: {message}" msgstr "Neplatná hodnota: {message}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:132 #, python-brace-format msgid "Invalid value for {param_hint}: {message}" msgstr "Neplatná hodnota pro {param_hint}: {message}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:190 msgid "Missing argument" msgstr "Chybějící argument" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:192 msgid "Missing option" msgstr "Chybějící možnost" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:194 msgid "Missing parameter" msgstr "Chybějící parametr" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:196 #, python-brace-format msgid "Missing {param_type}" msgstr "Chybějící {param_type}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:203 #, python-brace-format msgid "Missing parameter: {param_name}" msgstr "Chybějící parametr: {param_name}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:223 #, python-brace-format msgid "No such option: {name}" msgstr "Žádná taková možnost neexistuje: {name}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:235 #, python-brace-format msgid "Did you mean {possibility}?" msgid_plural "(Possible options: {possibilities})" msgstr[0] "Měl jste na mysli {possibility}?" msgstr[1] "Měl jste na mysli {possibilities})" msgstr[2] "Měl jste na mysli {possibilities})" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:282 msgid "unknown error" msgstr "neznámá chyba" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:289 msgid "Could not open file {filename!r}: {message}" msgstr "Nelze otevřít soubor {filename!r}: {message}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1104 #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1141 #, python-brace-format msgid "{text} {deprecated_message}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1160 msgid "Options" msgstr "Možnosti" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1222 #, python-brace-format msgid "Got unexpected extra argument ({args})" msgid_plural "Got unexpected extra arguments ({args})" msgstr[0] "Má ({args}) neočekávaný argument" msgstr[1] "Má ({args}) neočekávané argumenty navíc" msgstr[2] "Má ({args}) neočekávaných argumentů navíc" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1241 #, fuzzy msgid "DeprecationWarning: The command {name!r} is deprecated.{extra_message}" msgstr "Upozornění na zastarání: Příkaz {name!r} je zastaralý." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1425 msgid "Aborted!" msgstr "Přerušeno!" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1799 msgid "Commands" msgstr "Příkazy" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1830 msgid "Missing command." msgstr "Chybějící příkaz." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1908 msgid "No such command {name!r}." msgstr "Žádný takový příkaz {name!r}." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:2332 msgid "Value must be an iterable." msgstr "Hodnota musí být iterovatelná." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:2355 #, python-brace-format msgid "Takes {nargs} values but 1 was given." msgid_plural "Takes {nargs} values but {len} were given." msgstr[0] "Přijímá hodnoty {nargs}, ale byla zadána 1." msgstr[1] "Přijímá hodnoty {nargs}, ale byly zadány hodnoty {len}." msgstr[2] "Přijímá hodnoty {nargs}, ale byly zadány hodnoty {len}." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:2505 #, fuzzy msgid "" "DeprecationWarning: The {param_type} {name!r} is deprecated.{extra_message}" msgstr "Upozornění na zastarání: Příkaz {name!r} je zastaralý." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:2956 #, python-brace-format msgid "env var: {var}" msgstr "env var: {var}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:2959 #, python-brace-format msgid "default: {default}" msgstr "výchozí: {default}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:3023 msgid "(dynamic)" msgstr "(dynamický)" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/parser.py:199 msgid "Argument {name!r} takes {nargs} values." msgstr "Argument {name!r} nabývá hodnot {nargs}." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/parser.py:381 msgid "Option {name!r} does not take a value." msgstr "Možnost {name!r} nepřebírá hodnotu." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/parser.py:444 msgid "Option {name!r} requires an argument." msgid_plural "Option {name!r} requires {nargs} arguments." msgstr[0] "Možnost {name!r} vyžaduje argument." msgstr[1] "Možnost {name!r} vyžaduje argumenty {nargs}." msgstr[2] "Možnost {name!r} vyžaduje argumenty {nargs}." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/_termui_impl.py:608 #, python-brace-format msgid "{editor}: Editing failed" msgstr "{editor}: Editace se nezdařila" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/_termui_impl.py:612 #, python-brace-format msgid "{editor}: Editing failed: {e}" msgstr "{editor}: Úpravy se nezdařily: {e}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/decorators.py:522 msgid "Show the version and exit." msgstr "Zobrazit verzi a ukončit." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/decorators.py:548 msgid "Show this message and exit." msgstr "Zobrazit tuto zprávu a ukončit." #, python-brace-format #~ msgid "{path}: read error\n" #~ msgstr "{path}: chyba čtení\n" #, python-brace-format #~ msgid "{lic_path}: deprecated license\n" #~ msgstr "{lic_path}: zastaralá licence\n" #, python-brace-format #~ msgid "{lic_path}: license without file extension\n" #~ msgstr "{lic_path}: licence bez přípony souboru\n" #, python-brace-format #~ msgid "{lic_path}: unused license\n" #~ msgstr "{lic_path}: nepoužitá licence\n" #, 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čí" #, python-brace-format #~ msgid "Could not parse '{expression}'" #~ msgstr "Nepodařilo se analyzovat '{expression}'" #, python-brace-format #~ msgid "(Deprecated) {text}" #~ msgstr "(Zastaralé) {text}" #~ msgid "required" #~ msgstr "vyžadováno" #~ msgid "Year of copyright statement." #~ msgstr "Rok prohlášení o autorských právech." #, python-brace-format #~ msgid "determining identifier of '{path}'" #~ msgstr "určující identifikátor '{path}'" #~ 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" #~ msgid "can't write to '{}'" #~ msgstr "nelze zapisovat do '{}'" #~ msgid "show program's version number and exit" #~ msgstr "zobrazit číslo verze programu a ukončit jej" #~ 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 "" #~ "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" #~ "Pomocí parametru --contributor můžete určit osoby nebo subjekty, které " #~ "přispěly, ale nejsou držiteli autorských práv daných souborů." #~ 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/" #~ msgid "list all non-compliant files" #~ msgstr "seznam všech nevyhovujících souborů" #, fuzzy, 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 there any deprecated licenses in the project?\n" #~ "\n" #~ "- Are there any license files in the LICENSES/ directory without file " #~ "extension?\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" #~ "- Are there any read errors?\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?" #~ msgid "list non-compliant files from specified list of files" #~ msgstr "seznam nevyhovujících souborů ze zadaného seznamu souborů" #~ msgid "print the project's bill of materials in SPDX format" #~ msgstr "vytisknout výkaz materiálu projektu ve formátu SPDX" #~ msgid "convert .reuse/dep5 to REUSE.toml" #~ msgstr "Převeďte .reuse/dep5 do REUSE.toml" #~ msgid "'{}' is not a file" #~ msgstr "'{}' není soubor" #~ msgid "can't open '{}'" #~ msgstr "nelze otevřít '{}'" #~ msgid "can't write to directory '{}'" #~ msgstr "nelze zapisovat do adresáře '{}'" #~ msgid "can't read or write '{}'" #~ msgstr "nelze číst ani zapisovat '{}'" #~ msgid "SPDX License Identifier of license" #~ msgstr "Licence SPDX Identifikátor licence" #~ msgid "--output has no effect when used together with --all" #~ msgstr "--output nemá žádný účinek, pokud se použije společně s --all" #~ msgid "the following arguments are required: license" #~ msgstr "jsou vyžadovány tyto argumenty: licence" #~ msgid "usage: " #~ msgstr "použití: " #~ msgid ".__call__() not defined" #~ msgstr ".__call__() není definováno" #, python-format #~ msgid "unknown parser %(parser_name)r (choices: %(choices)s)" #~ msgstr "neznámý parser %(parser_name)r (volby: %(choices)s)" #, python-format #~ msgid "argument \"-\" with mode %r" #~ msgstr "argument \"-\" s režimem %r" #, python-format #~ msgid "can't open '%(filename)s': %(error)s" #~ msgstr "nelze otevřít '%(filename)s': %(error)s" #, python-format #~ msgid "cannot merge actions - two groups are named %r" #~ msgstr "nelze sloučit akce - dvě skupiny se jmenují %r" #~ msgid "'required' is an invalid argument for positionals" #~ msgstr "'required' je neplatný argument pro pozicionály" #, 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" #, python-format #~ msgid "dest= is required for options like %r" #~ msgstr "dest= je vyžadováno pro možnosti jako %r" #, python-format #~ msgid "invalid conflict_resolution value: %r" #~ msgstr "neplatná hodnota conflict_resolution: %r" #, 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" #~ msgid "mutually exclusive arguments must be optional" #~ msgstr "vzájemně se vylučující argumenty musí být nepovinné" #~ msgid "cannot have multiple subparser arguments" #~ msgstr "nemůže mít více argumentů dílčího parseru" #, python-format #~ msgid "unrecognized arguments: %s" #~ msgstr "neuznané argumenty: %s" #, python-format #~ msgid "not allowed with argument %s" #~ msgstr "není povoleno s argumentem %s" #, python-format #~ msgid "ignored explicit argument %r" #~ msgstr "ignoroval explicitní argument %r" #, python-format #~ msgid "the following arguments are required: %s" #~ msgstr "jsou vyžadovány následující argumenty: %s" #, python-format #~ msgid "one of the arguments %s is required" #~ msgstr "jeden z argumentů %s je povinný" #~ msgid "expected at most one argument" #~ msgstr "očekává se nejvýše jeden argument" #~ msgid "expected at least one argument" #~ msgstr "očekává se alespoň jeden argument" #, 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ů" #, python-format #~ msgid "ambiguous option: %(option)s could match %(matches)s" #~ msgstr "nejednoznačná možnost: %(option)s by mohlo odpovídat %(matches)s" #, python-format #~ msgid "unexpected option string: %s" #~ msgstr "neočekávaný volitelný řetězec: %s" #, python-format #~ msgid "%r is not callable" #~ msgstr "%r nelze volat" #, python-format #~ msgid "invalid %(type)s value: %(value)r" #~ msgstr "neplatná hodnota %(type)s: %(value)r" #, python-format #~ msgid "invalid choice: %(value)r (choose from %(choices)s)" #~ msgstr "neplatná volba: %(value)r (vyberte z %(choices)s)" #, python-brace-format #~ msgid "'{path}' could not be decoded as UTF-8." #~ msgstr "'{path}' se nepodařilo dekódovat jako UTF-8." #~ 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 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 "" #~ "--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-6.2.0/po/es.po0000664000175000017500000021555115077707000013664 0ustar alexalex# 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: 2025-10-07 21:23+0000\n" "PO-Revision-Date: 2025-10-25 12:02+0000\n" "Last-Translator: eulalio \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.14.1-dev\n" #: src/reuse/lint.py:40 msgid "BAD LICENSES" msgstr "LICENCIAS NO VÁLIDAS" #: src/reuse/lint.py:42 msgid "The following licenses are not valid SPDX licenses:" msgstr "Las siguientes licencias no son licencias SPDX válidas:" #: src/reuse/lint.py:50 msgid "DEPRECATED LICENSES" msgstr "LICENCIAS OBSOLETAS" #: src/reuse/lint.py:52 msgid "The following licenses are deprecated by SPDX:" msgstr "Las siguientes licencias han quedado obsoletas según SPDX:" #: src/reuse/lint.py:60 msgid "LICENSES WITHOUT FILE EXTENSION" msgstr "LICENCIAS SIN EXTENSIÓN DE FICHERO" #: src/reuse/lint.py:62 msgid "The following licenses have no file extension:" msgstr "Las siguientes licencias no tienen extensión de fichero:" #: src/reuse/lint.py:70 msgid "MISSING LICENSES" msgstr "LICENCIAS NO ENCONTRADAS" #: src/reuse/lint.py:72 msgid "'{}' found in:" msgstr "'{}' encontrado en:" #: src/reuse/lint.py:79 msgid "UNUSED LICENSES" msgstr "LICENCIAS NO UTILIZADAS" #: src/reuse/lint.py:80 msgid "The following licenses are not used:" msgstr "Las siguientes licencias no son utilizadas:" #: src/reuse/lint.py:87 msgid "READ ERRORS" msgstr "ERRORES DE LECTURA" #: src/reuse/lint.py:88 msgid "Could not read:" msgstr "No se pudo leer:" #: src/reuse/lint.py:94 msgid "INVALID SPDX LICENSE EXPRESSIONS" msgstr "EXPRESIONES DE LICENCIA SPDX NO VÁLIDAS" #: src/reuse/lint.py:99 msgid "'{}' contains invalid SPDX License Expressions:" msgstr "'{}' contiene expresiones de licencia SPDX no válidas:" #: src/reuse/lint.py:124 msgid "MISSING COPYRIGHT AND LICENSING INFORMATION" msgstr "FALTA INFORMACIÓN SOBRE COPYRIGHT Y LICENCIA" #: src/reuse/lint.py:130 msgid "The following files have no copyright and licensing information:" msgstr "" "Los siguientes ficheros no tiene información sobre derechos de autor y " "licencias:" #: src/reuse/lint.py:141 msgid "The following files have no copyright information:" msgstr "Los siguientes ficheros carecen de información de copyright:" #: src/reuse/lint.py:150 msgid "The following files have no licensing information:" msgstr "Los siguientes ficheros carecen de información de licencia:" #: src/reuse/lint.py:157 msgid "SUMMARY" msgstr "RESUMEN" #: src/reuse/lint.py:162 msgid "Bad licenses:" msgstr "Licencias malas:" #: src/reuse/lint.py:163 msgid "Deprecated licenses:" msgstr "Licencias obsoletas:" #: src/reuse/lint.py:166 msgid "Licenses without file extension:" msgstr "Licencias sin extensión de fichero:" #: src/reuse/lint.py:169 msgid "Missing licenses:" msgstr "Licencias no encontradas:" #: src/reuse/lint.py:170 msgid "Unused licenses:" msgstr "Licencias no utilizadas:" #: src/reuse/lint.py:171 msgid "Used licenses:" msgstr "Licencias utilizadas:" #: src/reuse/lint.py:172 msgid "Read errors:" msgstr "Errores de lectura:" #: src/reuse/lint.py:173 msgid "Invalid SPDX License Expressions:" msgstr "Expresiones de Licencia SPDX no válidas:" #: src/reuse/lint.py:183 msgid "Files with copyright information:" msgstr "archivos con información sobre derechos de autor:" #: src/reuse/lint.py:187 msgid "Files with license information:" msgstr "Archivos con información sobre las licencias:" #: src/reuse/lint.py:204 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:211 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:218 msgid "RECOMMENDATIONS" msgstr "RECOMENDACIONES" #: src/reuse/lint.py:286 #, python-brace-format msgid "missing license '{lic}'" msgstr "licencia que falta '{lic}'" #: src/reuse/lint.py:291 #, fuzzy msgid "read error" msgstr "Errores de lectura:" #: src/reuse/lint.py:296 #, python-brace-format msgid "invalid SPDX License Expression '{expression}'" msgstr "es una expresión SPDX no válida '{expression}'" #: src/reuse/lint.py:303 msgid "no license identifier" msgstr "ningún Identificador de licencia" #: src/reuse/lint.py:307 msgid "no copyright notice" msgstr "sin aviso de derechos de autor" #: src/reuse/lint.py:345 #, python-brace-format msgid "bad license '{lic}'" msgstr "licencia incorrecta'{lic}'" #: src/reuse/lint.py:350 msgid "deprecated license" msgstr "Licencias obsoletas" #: src/reuse/lint.py:355 #, fuzzy msgid "license without file extension" msgstr "Licencias sin extensión de fichero:" #: src/reuse/lint.py:360 #, fuzzy msgid "unused license" msgstr "Licencias no utilizadas:" #: src/reuse/project.py:253 #, python-brace-format msgid "'{path}' covered by {global_path}" msgstr "'{path}' cubierto por {global_path}" #: src/reuse/project.py:261 #, python-brace-format msgid "" "'{path}' is covered exclusively by REUSE.toml. Not reading the file contents." msgstr "" "'{path}' está cubierto exclusivamente por REUSE.toml. No leer el contenido " "del archivo." #: 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' está en desuso. Se recomienda utilizar REUSE.toml en su lugar. " "Usar `reuse convert-dep5` para convertir." #: src/reuse/project.py:355 #, python-brace-format msgid "" "Found both '{new_path}' and '{old_path}'. You cannot keep both files " "simultaneously; they are not intercompatible." msgstr "" "Se encontraron tanto '{new_path}' como '{old_path}'. No puede conservar " "ambos archivos simultáneamente; son incompatibles." #: src/reuse/project.py:419 #, python-brace-format msgid "{path} does not have a file extension" msgstr "{path} no tiene extensión de fichero" #: src/reuse/project.py:429 #, 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:441 #, 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:480 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/extract.py:49 #, python-brace-format msgid "" "REUSE_ENCODING_MODULE must have a value in {modules}; it has '{env_module}'. " "Aborting." msgstr "" "REUSE_ENCODING_MODULE ha de tener un valor en {modules}; si tiene " "'{env_module}'. Anular." #: src/reuse/extract.py:69 msgid "" "No supported module that can detect the encoding of files could be " "successfully imported. Re-read the installation instructions for the reuse " "package, or try the following:" msgstr "" "No se pudo importar correctamente ningún módulo compatible que pueda " "detectar la codificación de archivos. Vuelva a leer las instrucciones de " "instalación del paquete de reutilización o intente lo siguiente:" #: src/reuse/extract.py:75 msgid "" "- If you are running a Linux distribution, try your equivalent of `apt " "install file` or `dnf install file`." msgstr "" "-Si está ejecutando una distribución de Linux, pruebe su equivalente de `apt " "install file` o `dnf install file`." #: src/reuse/extract.py:80 msgid "" "- Run ` pipx install reuse[charset-normalizer]`. Replace 'pipx' with 'pip' " "if you are not using pipx." msgstr "" "- Ejecutar ` pipx install reuse[charset-normalizer]`. Sustituir 'pipx' con " "'pip' si no estás usando pipx." #: src/reuse/extract.py:451 #, 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/extract.py:462 #, python-brace-format msgid "" "extracting REUSE information from '{path}' (encoding {encoding}, encoding " "module {module}, newline {newline})" msgstr "" "extraer información de REUSE de '{path}' (codificación {encoding}, módulo de " "codificación {module}, nueva línea {newline})" #: src/reuse/header.py:87 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/report.py:160 #, python-brace-format msgid "Could not read '{path}'" msgstr "No se pudo leer '{path}'" #: src/reuse/report.py:165 #, python-brace-format msgid "Unexpected error occurred while parsing '{path}'" msgstr "Se produjo un error inesperado al procesar '{path}'" #: src/reuse/report.py:521 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:532 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:543 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:552 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:564 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:575 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:584 msgid "" "Fix invalid SPDX License Expressions: In one or more files there are SPDX " "License Expressions which cannot be parse. Check whether the value that " "follows 'SPDX-License-Identifier:' is correct. If the detected expression is " "not meant to be valid, put it between 'REUSE-IgnoreStart' and 'REUSE-" "IgnoreEnd' comments." msgstr "" "Corregir expresiones de licencia SPDX no válidas: En uno o más archivos hay " "expresiones de licencia SPDX que no se pueden analizar. Comprobar si el " "valor que sigue a 'SPDX-License-Identifier:' es correcto. Si la expresión " "detectada no pretende ser válida, colocarla entre los comentarios 'REUSE-" "IgnoreStart' y 'REUSE-IgnoreEnd'." #: src/reuse/report.py:595 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/cli/lint.py:28 #, python-brace-format msgid "" "Lint the project directory for REUSE compliance. This version of the tool " "checks against version {reuse_version} of the REUSE Specification. You can " "find the latest version of the specification at ." msgstr "" "Elimine el directorio del proyecto para cumplir con REUSE. Esta versión de " "la herramienta se compara con la versión {reuse_version} de la " "especificación de REUSE. Puede encontrar la última versión de la " "especificación en ." #: src/reuse/cli/lint.py:34 msgid "Specifically, the following criteria are checked:" msgstr "Específicamente, se verifican los siguientes criterios:" #: src/reuse/cli/lint.py:38 msgid "" "- Are there any bad (unrecognised, not compliant with SPDX) licenses in the " "project?" msgstr "" "- ¿ Hay alguna licencia incorrecta (no reconocida, que no cumpla con SPDX) " "en el proyecto?" #: src/reuse/cli/lint.py:43 msgid "- Are there any deprecated licenses in the project?" msgstr "- ¿Hay licencias obsoletas en el proyecto?" #: src/reuse/cli/lint.py:47 msgid "" "- Are there any license files in the LICENSES/ directory without file " "extension?" msgstr "" "- ¿Hay algún archivo de licencia en el directorio LICENSES/ sin extensión de " "archivo?" #: src/reuse/cli/lint.py:54 msgid "" "- Are any licenses referred to inside of the project, but not included in " "the LICENSES/ directory?" msgstr "" "- ¿Se hace referencia a alguna licencia dentro del proyecto, pero no se " "incluye en el directorio LICENSES/?" #: src/reuse/cli/lint.py:61 msgid "" "- Are any licenses included in the LICENSES/ directory that are not used " "inside of the project?" msgstr "" "- ¿ Hay licencias incluidas en el directorio LICENSES/ que no se utilicen " "dentro del proyecto?" #: src/reuse/cli/lint.py:66 msgid "- Are there any read errors?" msgstr "- ¿Hay algún error de lectura?" #: src/reuse/cli/lint.py:69 msgid "- Do all files have valid copyright and licensing information?" msgstr "" "- ¿Todos los archivos tienen información válida sobre derechos de autor y " "licencias?" #: src/reuse/cli/lint.py:81 src/reuse/cli/lint_file.py:38 msgid "Prevent output." msgstr "Evita la producción" #: src/reuse/cli/lint.py:89 src/reuse/cli/supported_licenses.py:28 msgid "Format output as JSON." msgstr "Formato de salida JSON." #: src/reuse/cli/lint.py:97 msgid "Format output as plain text. (default)" msgstr "Formato de salida como texto plano (por defecto)" #: src/reuse/cli/lint.py:105 msgid "Format output as errors per line." msgstr "Formato de salida como errores por línea." #: src/reuse/cli/convert_dep5.py:19 msgid "" "Convert .reuse/dep5 into a REUSE.toml file. The generated file is placed in " "the project root and is semantically identical. The .reuse/dep5 file is " "subsequently deleted." msgstr "" "Convertir .reuse/dep5 en un archivo REUSE.toml. El archivo generado se " "coloca en la raíz del proyecto y es semánticamente idéntico. El archivo ." "reuse/dep5 se elimina posteriormente." #: src/reuse/cli/convert_dep5.py:31 msgid "No '.reuse/dep5' file." msgstr "Sin archivo '.reuse/dep5'" #: src/reuse/cli/lint_file.py:25 msgid "" "Lint individual files for REUSE compliance. The specified FILEs are checked " "for the presence of copyright and licensing information, and whether the " "found licenses are included in the LICENSES/ directory." msgstr "" "Eliminar archivos individuales para el cumplimiento de REUSE. Se comprueba " "en los ARCHIVOs especificados la presencia de información sobre derechos de " "autor y licencias, y si las licencias encontradas están incluidas en el " "directorio LICENSES/." #: src/reuse/cli/lint_file.py:46 msgid "Format output as errors per line. (default)" msgstr "Formatea la salida como errores por línea. (por defecto)" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/lint_file.py:51 msgid "FILE" msgstr "ARCHIVO" #: src/reuse/cli/lint_file.py:65 #, python-brace-format msgid "'{file}' is not inside of '{root}'." msgstr "'{file}' no está dentro de '{root}'." #: src/reuse/cli/spdx.py:22 msgid "Generate an SPDX bill of materials." msgstr "Generar una lista de materiales SPDX." #: src/reuse/cli/spdx.py:32 msgid "File to write to." msgstr "Archivo para escribir." #: src/reuse/cli/spdx.py:38 msgid "" "Populate the LicenseConcluded field; note that reuse cannot guarantee that " "the field is accurate." msgstr "" "Rellenar el campo LicenseConcluded; ten en cuenta que reuse no puede " "garantizar que el campo sea exacto" #: src/reuse/cli/spdx.py:50 msgid "Name of the person signing off on the SPDX report." msgstr "Nombre de la persona que firma el informe SPDX." #: src/reuse/cli/spdx.py:54 msgid "Name of the organization signing off on the SPDX report." msgstr "Nombre de la organización que firma el informe SPDX." #: src/reuse/cli/spdx.py:81 msgid "" "'--creator-person' or '--creator-organization' is required when '--add-" "license-concluded' is provided." msgstr "" "Se requiere '--creator-person' o '--creator-organization' cuando se " "proporciona '--add-license-concluded'." #: src/reuse/cli/spdx.py:96 #, 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" #: src/reuse/cli/main.py:36 #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/decorators.py:465 #, python-format msgid "%(prog)s, version %(version)s" msgstr "%(prog)s, versión %(version)s" #: src/reuse/cli/main.py:39 msgid "" "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." msgstr "" "Este programa es software libre: puede redistribuirlo y/o modificarlo bajo " "los términos de la Licencia Pública General GNU publicada por la Free " "Software Foundation, ya sea la versión 3 de la Licencia, o (a su elección) " "cualquier versión posterior." #: src/reuse/cli/main.py:46 msgid "" "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." msgstr "" "Este programa se distribuye con la esperanza de que sea útil, pero SIN " "NINGUNA GARANTÍA; ni siquiera la garantía implícita de COMERCIABILIDAD o " "IDONEIDAD PARA UN PROPÓSITO PARTICULAR. Consulte la Licencia Pública General " "GNU para más detalles." #: src/reuse/cli/main.py:53 msgid "" "You should have received a copy of the GNU General Public License along with " "this program. If not, see ." msgstr "" "Debería haber recibido una copia de la Licencia Pública General GNU junto " "con este programa. Si no es así, consulte ." #: src/reuse/cli/main.py:61 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/cli/main.py:68 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/cli/main.py:72 msgid "Support the FSFE's work:" msgstr "Apoya el trabajo de la FSFE:" #: src/reuse/cli/main.py:77 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/cli/main.py:88 msgid "Enable debug statements." msgstr "Habilita instrucciones de depuración." #: src/reuse/cli/main.py:93 msgid "Hide deprecation warnings." msgstr "Ocultar las advertencias de que está obsoleto" #: src/reuse/cli/main.py:98 msgid "Do not skip over Git submodules." msgstr "No omitir los submódulos de Git" #: src/reuse/cli/main.py:103 msgid "Do not skip over Meson subprojects." msgstr "No saltarse los subproyectos de Meson" #: src/reuse/cli/main.py:108 msgid "Do not use multiprocessing." msgstr "No utilizar multiproceso" #: src/reuse/cli/main.py:118 msgid "Define root of project." msgstr "Definir el origen del proyecto" #: src/reuse/cli/common.py:51 #, python-brace-format msgid "" "'{path}' could not be parsed. We received the following error message: " "{message}" msgstr "" "'{path}' no se pudo analizar. Con el siguiente mensaje de error: {message}" #: src/reuse/cli/common.py:87 #, python-brace-format msgid "'{name}' is mutually exclusive with: {opts}" msgstr "'{name}' se excluye mutuamente con: {opts}" #: src/reuse/cli/common.py:103 msgid "'{}' is not a valid SPDX expression." msgstr "'{}' no es una expresión SPDX válida," #: src/reuse/cli/download.py:54 msgid "'{}' is not a valid SPDX License Identifier." msgstr "'{}' no es un Identificador SPDX de Licencia válido." #: src/reuse/cli/download.py:61 #, fuzzy msgid "Did you mean:" msgstr "Querías decir:" #: src/reuse/cli/download.py:68 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/cli/download.py:77 #, python-brace-format msgid "Error: {spdx_identifier} already exists." msgstr "Error: {spdx_identifier} ya existe." #: src/reuse/cli/download.py:84 #, fuzzy, python-brace-format msgid "Error: {path} does not exist." msgstr "Error: {path} no existe." #: src/reuse/cli/download.py:88 msgid "Error: Failed to download license." msgstr "Error: Fallo al descargar la licencia." #: src/reuse/cli/download.py:93 msgid "Is your internet connection working?" msgstr "¿Está funcionando tu conexión a Internet?" #: src/reuse/cli/download.py:98 #, python-brace-format msgid "Successfully downloaded {spdx_identifier}." msgstr "{spdx_identifier} descargado con éxito." #: src/reuse/cli/download.py:108 msgid "Download a license and place it in the LICENSES/ directory." msgstr "Descargar una licencia y colocarla en el directorio LICENSES/ ." #: src/reuse/cli/download.py:111 msgid "" "LICENSE must be a valid SPDX License Identifier. You may specify LICENSE " "multiple times to download multiple licenses." msgstr "" "LICENSE debe ser un identificador de licencia SPDX válido. Puede especificar " "LICENSE varias veces para descargar varias licencias." #: src/reuse/cli/download.py:124 msgid "Download all missing licenses detected in the project." msgstr "" "Descargar todas las licencias no disponibles detectadas en el proyecto." #: src/reuse/cli/download.py:132 msgid "Path to download to." msgstr "Ruta a la que descargar." #: src/reuse/cli/download.py:138 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" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/download.py:145 msgid "LICENSE" msgstr "LICENCIA" #: src/reuse/cli/download.py:161 msgid "The 'LICENSE' argument and '--all' option are mutually exclusive." msgstr "El argumento 'LICENSE' y la opción '--all' se excluyen mutuamente" #: src/reuse/cli/download.py:173 msgid "Cannot use '--output' with more than one license." msgstr "No se puede utilizar '--output' con más de una licencia" #: src/reuse/cli/annotate.py:66 msgid "Option '--copyright', '--license', or '--contributor' is required." msgstr "se requiere la opción '--copyright', '--license', o '--contributor'" #: src/reuse/cli/annotate.py:127 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 de archivo reconocida. Por " "favor use '--style', '--force-dot-license', '--fallback-dot-license', o '--" "skip-unrecognised':" #: src/reuse/cli/annotate.py:160 #, 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/cli/annotate.py:167 #, 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/cli/annotate.py:213 #, python-brace-format msgid "Template '{template}' could not be found." msgstr "no pudo encontrarse la plantilla '{template}'" #: src/reuse/cli/annotate.py:236 #, python-brace-format msgid "'{year}' is not a valid year range." msgstr "'{year}' no es un rango de año válido." #: src/reuse/cli/annotate.py:245 #, python-brace-format msgid "" "Your operating system's year is set to '{year}'. This is not four digits, " "and not supported." msgstr "" "El año de su sistema operativo está configurado en '{year}'. Esto no es de " "cuatro dígitos, y no es compatible." #: src/reuse/cli/annotate.py:287 msgid "Add copyright and licensing into the headers of files." msgstr "Añadir derechos de autor y licencias en las cabeceras de los archivos." #: src/reuse/cli/annotate.py:290 msgid "" "By using --copyright and --license, you can specify which copyright holders " "and licenses to add to the headers of the given files." msgstr "" "Al usar -- copyright y -- license, puede especificar qué titulares de " "derechos de autor y licencias agregar a los encabezados de los archivos " "dados." #: src/reuse/cli/annotate.py:296 msgid "" "By using --contributor, you can specify people or entity that contributed " "but are not copyright holder of the given files." msgstr "" "Al usar -- contributor, puede especificar personas o entidades que " "contribuyeron pero que no son titulares de los derechos de autor de los " "archivos dados." #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:309 msgid "COPYRIGHT" msgstr "DERECHOS DE AUTOR" #: src/reuse/cli/annotate.py:312 #, fuzzy msgid "Copyright holder, repeatable." msgstr "Declaración de derechos de autor, repetible." #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:319 msgid "SPDX_IDENTIFIER" msgstr "SPDX_IDENTIFIER" #: src/reuse/cli/annotate.py:322 msgid "SPDX License Identifier, repeatable." msgstr "Identificador de licencia SPDX, repetible." #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:328 msgid "CONTRIBUTOR" msgstr "COLABORADOR" #: src/reuse/cli/annotate.py:331 msgid "File contributor, repeatable." msgstr "Claborador de archivos, repetible." #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:338 msgid "YEAR" msgstr "AÑO" #: src/reuse/cli/annotate.py:343 msgid "" "Year of copyright notice. You may define multiple years or a range of years." msgstr "" "Año de aviso de derechos de autor. Puede definir varios años o un rango de " "años." #: src/reuse/cli/annotate.py:353 msgid "Comment style to use." msgstr "Estilo de comentario a utilizar." #: src/reuse/cli/annotate.py:363 msgid "Copyright prefix to use." msgstr "Prefijo de derechos de autor a utilizar." #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:375 msgid "TEMPLATE" msgstr "PLANTILLA" #: src/reuse/cli/annotate.py:377 msgid "Name of template to use." msgstr "nombre de la plantilla a utilizar." #: src/reuse/cli/annotate.py:384 #, fuzzy msgid "Do not include year in copyright notice." msgstr "No incluir el año en la declaración de derechos de autor." #: src/reuse/cli/annotate.py:390 msgid "Merge copyright notices if they are identical except for their years." msgstr "" "Fusione los avisos de derechos de autor si son idénticos, excepto por sus " "años." #: src/reuse/cli/annotate.py:398 msgid "Force single-line comment style." msgstr "forzar el estilo del comentario de una sola línea." #: src/reuse/cli/annotate.py:405 msgid "Force multi-line comment style." msgstr "Forzar estilo de comentario multilínea." #: src/reuse/cli/annotate.py:411 msgid "Add headers to all files under specified directories recursively." msgstr "" "Añadir cabeceras a todos los archivos de los directorios especificados de " "forma recursiva" #: src/reuse/cli/annotate.py:416 msgid "Do not replace the first header in the file; just add a new one." msgstr "No sustituir la primera cabecera del archivo; añadir una nueva" #: src/reuse/cli/annotate.py:423 msgid "Always write a .license file instead of a header inside the file." msgstr "" "Escribir siempre un archivo .license en lugar de una cabecera dentro del " "archivo" #: src/reuse/cli/annotate.py:430 msgid "Write a .license file to files with unrecognised comment styles." msgstr "" "Escribir un archivo .license en archivos con estilos de comentario no " "reconocidos" #: src/reuse/cli/annotate.py:437 msgid "Skip files with unrecognised comment styles." msgstr "Omitir los archivos con estilos de comentario no reconocidos" #: src/reuse/cli/annotate.py:448 msgid "Skip files that already contain REUSE information." msgstr "Omitir los archivos que ya contienen la información REUSE" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:453 msgid "PATH" msgstr "PATH" #: src/reuse/cli/annotate.py:510 #, 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/cli/supported_licenses.py:19 msgid "List all licenses on the SPDX License List." msgstr "Enumere todas las licencias en la lista de licencias SPDX." #: src/reuse/global_licensing.py:92 #, python-brace-format msgid "" "{attr_name} must be a {type_name} (got {value} that is a {value_class})." msgstr "" "{attr_name} debe ser un {type_name} (got {value}, que es una {value_class})." #: src/reuse/global_licensing.py:106 #, python-brace-format msgid "" "Item in {attr_name} collection must be a {type_name} (got {item_value} that " "is a {item_class})." msgstr "" "El elemento en la colección {attr_name} debe ser un {type_name} (obtiene " "{item_value}, que es un {item_class})." #: src/reuse/global_licensing.py:118 #, python-brace-format msgid "{attr_name} must not be empty." msgstr "{attr_name} no debe estar vacío." #: src/reuse/global_licensing.py:142 #, python-brace-format msgid "{name} must be a {type} (got {value} that is a {value_type})." msgstr "{name} debe ser un {type} (obtiene {value}, que es un {value_type})." #: src/reuse/global_licensing.py:166 #, python-brace-format msgid "" "The value of 'precedence' must be one of {precedence_vals} (got {received})" msgstr "" "El valor de 'precedence' debe ser uno de {precedence_vals} (obtiene " "{received})" #: src/reuse/global_licensing.py:219 #, python-brace-format msgid "Could not parse '{notice}'" msgstr "No se pudo analizar '{notice}'" #: src/reuse/_annotate.py:94 #, python-brace-format msgid "Skipped unrecognised file '{path}'" msgstr "Se ha omitido el archivo no reconocido de '{path}'" #: src/reuse/_annotate.py:100 #, python-brace-format msgid "'{path}' is not recognised; creating '{path}.license'" msgstr "'{path}' no se reconoce; creando '{path}.license'" #: src/reuse/_annotate.py:116 #, 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:145 #, 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:152 #, 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:163 #, python-brace-format msgid "Successfully changed header of {path}" msgstr "Cabecera de {path} correctamente cambiada" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:162 msgid "Repeat for confirmation" msgstr "Repita para confirmar" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:178 msgid "Error: The value you entered was invalid." msgstr "Error: El valor que ingresó no era válido." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:180 #, fuzzy, python-brace-format msgid "Error: {e.message}" msgstr "Error: {e.message}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:191 msgid "Error: The two entered values do not match." msgstr "Error: No coinciden los dos valores introducidos." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:247 msgid "Error: invalid input" msgstr "Error: entrada inválida" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:866 msgid "Press any key to continue..." msgstr "Pulsar cualquier tecla para continuar..." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:332 #, python-brace-format msgid "" "Choose from:\n" "\t{choices}" msgstr "" "Elige entre:\n" "\t{choices}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:369 msgid "{value!r} is not {choice}." msgid_plural "{value!r} is not one of {choices}." msgstr[0] "{value!r} no es {choice}." msgstr[1] "{value!r} no es uno de los {choices}." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:460 msgid "{value!r} does not match the format {format}." msgid_plural "{value!r} does not match the formats {formats}." msgstr[0] "{¡valor!r} no coincide con el formato {format}." msgstr[1] "{¡valor!r} no coinciden con los formatos {formats}." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:482 msgid "{value!r} is not a valid {number_type}." msgstr "{¡valor!r} no es un {number_type} válido." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:538 #, python-brace-format msgid "{value} is not in the range {range}." msgstr "{value} no está en el rango {range}." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:719 msgid "{value!r} is not a valid boolean. Recognized values: {states}" msgstr "{value!r} no es un valor booleano válido. Valores reconocidos: {states}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:747 msgid "{value!r} is not a valid UUID." msgstr "{¡valor!r} no es un UUID válido." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:937 msgid "file" msgstr "archivo" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:939 msgid "directory" msgstr "directorio" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:941 msgid "path" msgstr "trayectoria" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:988 msgid "{name} {filename!r} does not exist." msgstr "{name} {filename!r} no existe." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:997 msgid "{name} {filename!r} is a file." msgstr "{name} {filename!r} es un archivo." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:1005 #, fuzzy msgid "{name} {filename!r} is a directory." msgstr "{name} '{filename}' es un directorio." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:1014 msgid "{name} {filename!r} is not readable." msgstr "{name} {filename!r} no es legible." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:1023 msgid "{name} {filename!r} is not writable." msgstr "{name} {filename!r} no se puede escribir." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:1032 msgid "{name} {filename!r} is not executable." msgstr "{name} {filename!r} no es ejecutable." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:1099 #, python-brace-format msgid "{len_type} values are required, but {len_value} was given." msgid_plural "{len_type} values are required, but {len_value} were given." msgstr[0] "{len_type} se requieren valores, pero se proporcionó {len_value}." msgstr[1] "" "{len_type} se requieren valores, pero se proporcionaron {len_value}." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/shell_completion.py:332 msgid "Shell completion is not supported for Bash versions older than 4.4." msgstr "" "El término del shell no es compatible con versiones de Bash anteriores a la " "4.4." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/shell_completion.py:339 msgid "Couldn't detect Bash version, shell completion is not supported." msgstr "" "No se pudo detectar la versión de Bash, no se admite la finalización del " "shell." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:50 #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:89 #, fuzzy, python-brace-format msgid "Error: {message}" msgstr "Error: {message}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:81 #, python-brace-format msgid "Try '{command} {option}' for help." msgstr "Probar '{command} {option}' para obtener ayuda." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:130 #, python-brace-format msgid "Invalid value: {message}" msgstr "Valor no válido: {message}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:132 #, python-brace-format msgid "Invalid value for {param_hint}: {message}" msgstr "Valor no válido para {param_hint}: {message}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:190 msgid "Missing argument" msgstr "Argumento que falta" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:192 msgid "Missing option" msgstr "Opción que falta" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:194 msgid "Missing parameter" msgstr "Parámetro que falta" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:196 #, python-brace-format msgid "Missing {param_type}" msgstr "Que falta {param_type}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:203 #, python-brace-format msgid "Missing parameter: {param_name}" msgstr "Parámetro que falta: {param_name}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:223 #, python-brace-format msgid "No such option: {name}" msgstr "No existe tal opción: {name}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:235 #, python-brace-format msgid "Did you mean {possibility}?" msgid_plural "(Possible options: {possibilities})" msgstr[0] "¿Querías decir {possibility}?" msgstr[1] "(Opciones posibles: {possibilities})" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:282 msgid "unknown error" msgstr "error desconocido" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:289 msgid "Could not open file {filename!r}: {message}" msgstr "No se pudo abrir el archivo {filename!r}: {message}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1104 #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1141 #, fuzzy, python-brace-format msgid "{text} {deprecated_message}" msgstr "{text} {deprecated_message}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1160 msgid "Options" msgstr "Opciones" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1222 #, python-brace-format msgid "Got unexpected extra argument ({args})" msgid_plural "Got unexpected extra arguments ({args})" msgstr[0] "Tiene un argumento extra inesperado ({args})" msgstr[1] "Tiene unos argumentos extras inesperados ({args})" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1241 msgid "DeprecationWarning: The command {name!r} is deprecated.{extra_message}" msgstr "" "DeprecationWarning: : El comando {name!r} está en desuso.{extra_message}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1425 msgid "Aborted!" msgstr "¡Abortado!" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1799 msgid "Commands" msgstr "Comandos" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1830 msgid "Missing command." msgstr "Comando que falta." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1908 msgid "No such command {name!r}." msgstr "No hay tal comando {name!r}." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:2332 msgid "Value must be an iterable." msgstr "El valor debe ser capaz de repetirse." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:2355 #, python-brace-format msgid "Takes {nargs} values but 1 was given." msgid_plural "Takes {nargs} values but {len} were given." msgstr[0] "Toma valores {nargs} pero se dio 1." msgstr[1] "Toma valores {nargs} pero se dieron {len}." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:2505 msgid "" "DeprecationWarning: The {param_type} {name!r} is deprecated.{extra_message}" msgstr "" "DeprecationWarning: : El {param_type} {name!r} está en desuso.{extra_message}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:2956 #, fuzzy, python-brace-format msgid "env var: {var}" msgstr "env var: {var}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:2959 #, python-brace-format msgid "default: {default}" msgstr "predeterminado: {default}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:3023 msgid "(dynamic)" msgstr "(dinámico)" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/parser.py:199 msgid "Argument {name!r} takes {nargs} values." msgstr "Argumento {name!r} toma valores {nargs}." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/parser.py:381 msgid "Option {name!r} does not take a value." msgstr "Opción {name!r} no toma un valor." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/parser.py:444 msgid "Option {name!r} requires an argument." msgid_plural "Option {name!r} requires {nargs} arguments." msgstr[0] "Opción {name!r} requiere argumentos {nargs}." msgstr[1] "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/_termui_impl.py:608 #, python-brace-format msgid "{editor}: Editing failed" msgstr "{editor}: Error de edición" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/_termui_impl.py:612 #, python-brace-format msgid "{editor}: Editing failed: {e}" msgstr "{editor}: Error de edición: {e}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/decorators.py:522 msgid "Show the version and exit." msgstr "Mostrar la versión y salir." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/decorators.py:548 msgid "Show this message and exit." msgstr "Mostrar este mensaje y salir." #, fuzzy, python-brace-format #~ msgid "{path}: read error\n" #~ msgstr "Licencias obsoletas:" #, fuzzy, python-brace-format #~ msgid "{lic_path}: deprecated license\n" #~ msgstr "Licencias obsoletas:" #, fuzzy, python-brace-format #~ msgid "{lic_path}: license without file extension\n" #~ msgstr "Licencias sin extensión de fichero:" #, fuzzy, python-brace-format #~ msgid "{lic_path}: unused license\n" #~ msgstr "Licencias no utilizadas:" #, 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" #, python-brace-format #~ msgid "Could not parse '{expression}'" #~ msgstr "No se pudo procesar '{expression}'" #, fuzzy, python-brace-format #~ msgid "(Deprecated) {text}" #~ msgstr "(Deprecated) {text}" #~ msgid "required" #~ msgstr "requerido" #~ msgid "Year of copyright statement." #~ msgstr "Año de la declaración de derechos de autor." #, python-brace-format #~ msgid "determining identifier of '{path}'" #~ msgstr "determinando el identificador de '{path}'" #~ msgid "--skip-unrecognised has no effect when used together with --style" #~ msgstr "" #~ "--skip-unrecognised no tiene efecto cuando se utiliza junto con --style" #~ msgid "can't write to '{}'" #~ msgstr "no se puede escribir en '{}'" #~ msgid "show program's version number and exit" #~ msgstr "muestra la versión del programa y sale" #~ 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 "" #~ "Añadir copyright y licencias en la cabecera de uno o más archivos.\n" #~ "\n" #~ "Usando --copyright y --license, puede especificar qué titulares de " #~ "derechos de autor y licencias añadir a las cabeceras de los archivos " #~ "dados.\n" #~ "\n" #~ "Usando --contributor, puede especificar las personas o entidades que han " #~ "contribuido pero no son titulares de los derechos de autor de los " #~ "archivos dados." #~ msgid "download a license and place it in the LICENSES/ directory" #~ msgstr "descarga una licencia y guárdala en el directorio \"LICENSES/\"" #~ msgid "list all non-compliant files" #~ msgstr "lista todos los ficheros no compatibles" #, 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 there any deprecated licenses in the project?\n" #~ "\n" #~ "- Are there any license files in the LICENSES/ directory without file " #~ "extension?\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" #~ "- Are there any read errors?\n" #~ "\n" #~ "- Do all files have valid copyright and licensing information?" #~ msgstr "" #~ "Comprueba que el directorio del proyecto cumple con la versión " #~ "{reuse_version} de la especificación REUSE. Puede encontrar la última " #~ "versión de la especificación en .\n" #~ "\n" #~ "En concreto, se comprueban los siguientes criterios\n" #~ "\n" #~ "- ¿Existen licencias defectuosas (no reconocidas, no conformes con SPDX) " #~ "en el proyecto?\n" #~ "\n" #~ "- ¿Hay licencias obsoletas en el proyecto?\n" #~ "\n" #~ "- ¿Hay algún archivo de licencia en el directorio LICENSES/ sin extensión " #~ "de archivo?\n" #~ "\n" #~ "- ¿Hay licencias a las que se haga referencia dentro del proyecto, pero " #~ "que no estén incluidas en el directorio LICENSES/?\n" #~ "\n" #~ "- ¿Hay licencias incluidas en el directorio LICENSES/ que no se utilicen " #~ "en el proyecto?\n" #~ "\n" #~ "- ¿Hay errores de lectura?\n" #~ "\n" #~ "- ¿Tienen todos los archivos información válida sobre derechos de autor y " #~ "licencias?" #~ msgid "list non-compliant files from specified list of files" #~ msgstr "" #~ "enumerar los archivos no compatibles de la lista de archivos especificada" #~ msgid "print the project's bill of materials in SPDX format" #~ msgstr "imprime la lista de materiales del proyecto en formato SPDX" #~ msgid "List all non-deprecated SPDX licenses from the official list." #~ msgstr "Enumere todas las licencias SPDX no obsoletas de la lista oficial." #~ msgid "convert .reuse/dep5 to REUSE.toml" #~ msgstr "convertir . reuse/dep5 a REUSE.toml" #~ msgid "'{}' is not a file" #~ msgstr "'{}' no es un fichero" #~ msgid "can't open '{}'" #~ msgstr "no se puede abrir '{}'" #~ msgid "can't write to directory '{}'" #~ msgstr "no se pude escribir en el directorio '{}'" #~ msgid "can't read or write '{}'" #~ msgstr "no se puede leer o escribir '{}'" #~ msgid "SPDX License Identifier of license" #~ msgstr "Identificador SPDX de la licencia" #~ msgid "--output has no effect when used together with --all" #~ msgstr "--output no tiene efecto cuando se utiliza junto con --all" #~ msgid "the following arguments are required: license" #~ msgstr "se requieren los siguientes parámetros: license" #~ msgid "usage: " #~ msgstr "uso: " #~ msgid ".__call__() not defined" #~ msgstr ".__call__() no definido" #, python-format #~ msgid "unknown parser %(parser_name)r (choices: %(choices)s)" #~ msgstr "" #~ "analizador sintáctico desconocido: %(parser_name)r (alternativas: " #~ "%(choices)s)" #, python-format #~ msgid "argument \"-\" with mode %r" #~ msgstr "parámetro \"-\" con modo %r" #, python-format #~ msgid "can't open '%(filename)s': %(error)s" #~ msgstr "no se puede abrir '%(filename)s': %(error)s" #, python-format #~ msgid "cannot merge actions - two groups are named %r" #~ msgstr "no se pueden fusionar las acciones: dos grupos se llaman %r" #~ msgid "'required' is an invalid argument for positionals" #~ msgstr "'required' es un argumento posicional inválido" #, 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" #, python-format #~ msgid "dest= is required for options like %r" #~ msgstr "se requiere dest= para opciones como %r" #, python-format #~ msgid "invalid conflict_resolution value: %r" #~ msgstr "valor no válido de conflict_resolution: %r" #, 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" #~ msgid "mutually exclusive arguments must be optional" #~ msgstr "los parámetros mutuamente excluyentes deben ser opcionales" #~ msgid "cannot have multiple subparser arguments" #~ msgstr "no puede contener múltiples parámetros del subanalizador sintáctico" #, python-format #~ msgid "unrecognized arguments: %s" #~ msgstr "parámetros no reconocidos: %s" #, python-format #~ msgid "not allowed with argument %s" #~ msgstr "no permitido con el parámetro %s" #, python-format #~ msgid "ignored explicit argument %r" #~ msgstr "parámetro explícito ignorado: %r" #, python-format #~ msgid "the following arguments are required: %s" #~ msgstr "los siguientes parámetros son obligatorios: %s" #, python-format #~ msgid "one of the arguments %s is required" #~ msgstr "se requiere uno de los parámetros %s" #~ msgid "expected at most one argument" #~ msgstr "se espera un parámetro, como máximo" #~ msgid "expected at least one argument" #~ msgstr "se espera un parámetro, como mínimo" #, 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" #, python-format #~ msgid "ambiguous option: %(option)s could match %(matches)s" #~ msgstr "opción ambigua: %(option)s podría coincidir con %(matches)s" #, python-format #~ msgid "unexpected option string: %s" #~ msgstr "cadena de opción inesperada: %s" #, python-format #~ msgid "%r is not callable" #~ msgstr "%r no se puede invocar" #, python-format #~ msgid "invalid %(type)s value: %(value)r" #~ msgstr "valor no válido de %(type)s: %(value)r" #, python-format #~ msgid "invalid choice: %(value)r (choose from %(choices)s)" #~ msgstr "opción inválida: %(value)r (opciones: %(choices)s)" #, fuzzy, python-brace-format #~ msgid "'{path}' could not be decoded as UTF-8." #~ msgstr "'{dep5}' no pudo ser decodificado como UTF-8." #, 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 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 "" #~ "--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-6.2.0/po/sv.po0000664000175000017500000012034515077707000013701 0ustar alexalex# 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: 2025-10-07 21:23+0000\n" "PO-Revision-Date: 2025-05-08 19:01+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.12-dev\n" #: src/reuse/lint.py:40 #, fuzzy msgid "BAD LICENSES" msgstr "LICENS" #: src/reuse/lint.py:42 #, fuzzy msgid "The following licenses are not valid SPDX licenses:" msgstr "följande argument behövs: licens" #: src/reuse/lint.py:50 msgid "DEPRECATED LICENSES" msgstr "" #: src/reuse/lint.py:52 msgid "The following licenses are deprecated by SPDX:" msgstr "" #: src/reuse/lint.py:60 msgid "LICENSES WITHOUT FILE EXTENSION" msgstr "" #: src/reuse/lint.py:62 msgid "The following licenses have no file extension:" msgstr "" #: src/reuse/lint.py:70 #, fuzzy msgid "MISSING LICENSES" msgstr "LICENS" #: src/reuse/lint.py:72 msgid "'{}' found in:" msgstr "" #: src/reuse/lint.py:79 #, fuzzy msgid "UNUSED LICENSES" msgstr "LICENS" #: src/reuse/lint.py:80 #, fuzzy msgid "The following licenses are not used:" msgstr "följande argument behövs: licens" #: src/reuse/lint.py:87 msgid "READ ERRORS" msgstr "" #: src/reuse/lint.py:88 msgid "Could not read:" msgstr "" #: src/reuse/lint.py:94 msgid "INVALID SPDX LICENSE EXPRESSIONS" msgstr "" #: src/reuse/lint.py:99 #, fuzzy msgid "'{}' contains invalid SPDX License Expressions:" msgstr "'{}' är inte ett giltigt SPDX-uttryck, avbryter" #: src/reuse/lint.py:124 msgid "MISSING COPYRIGHT AND LICENSING INFORMATION" msgstr "" #: src/reuse/lint.py:130 #, fuzzy msgid "The following files have no copyright and licensing information:" msgstr "" "- Har alla filer ett giltigt kopieringsskydd och licensieringsinformation?" #: src/reuse/lint.py:141 #, fuzzy msgid "The following files have no copyright information:" msgstr "" "- Har alla filer ett giltigt kopieringsskydd och licensieringsinformation?" #: src/reuse/lint.py:150 #, fuzzy msgid "The following files have no licensing information:" msgstr "" "- Har alla filer ett giltigt kopieringsskydd och licensieringsinformation?" #: src/reuse/lint.py:157 msgid "SUMMARY" msgstr "" #: src/reuse/lint.py:162 msgid "Bad licenses:" msgstr "" #: src/reuse/lint.py:163 #, fuzzy msgid "Deprecated licenses:" msgstr "(Föråldrad) {text}" #: src/reuse/lint.py:166 msgid "Licenses without file extension:" msgstr "" #: src/reuse/lint.py:169 #, fuzzy msgid "Missing licenses:" msgstr "Alternativ saknas" #: src/reuse/lint.py:170 msgid "Unused licenses:" msgstr "" #: src/reuse/lint.py:171 msgid "Used licenses:" msgstr "" #: src/reuse/lint.py:172 msgid "Read errors:" msgstr "" #: src/reuse/lint.py:173 #, fuzzy msgid "Invalid SPDX License Expressions:" msgstr "'{}' är inte ett giltigt SPDX-uttryck, avbryter" #: src/reuse/lint.py:183 msgid "Files with copyright information:" msgstr "" #: src/reuse/lint.py:187 msgid "Files with license information:" msgstr "" #: src/reuse/lint.py:204 #, fuzzy msgid "" "Congratulations! Your project is compliant with version {} of the REUSE " "Specification :-)" msgstr "" "Den här versionen av reuse är kompatibel med version {} av REUSE-" "specifikationen." #: src/reuse/lint.py:211 #, fuzzy msgid "" "Unfortunately, your project is not compliant with version {} of the REUSE " "Specification :-(" msgstr "" "Den här versionen av reuse är kompatibel med version {} av REUSE-" "specifikationen." #: src/reuse/lint.py:218 msgid "RECOMMENDATIONS" msgstr "" #: src/reuse/lint.py:286 #, fuzzy, python-brace-format msgid "missing license '{lic}'" msgstr "'{}' är inte ett giltigt SPDX-uttryck, avbryter" #: src/reuse/lint.py:291 msgid "read error" msgstr "" #: src/reuse/lint.py:296 #, fuzzy, python-brace-format msgid "invalid SPDX License Expression '{expression}'" msgstr "'{}' är inte ett giltigt SPDX-uttryck, avbryter" #: src/reuse/lint.py:303 #, fuzzy msgid "no license identifier" msgstr "'{}' är inte ett giltigt SPDX-uttryck, avbryter" #: src/reuse/lint.py:307 msgid "no copyright notice" msgstr "" #: src/reuse/lint.py:345 #, fuzzy, python-brace-format msgid "bad license '{lic}'" msgstr "'{}' är inte ett giltigt SPDX-uttryck, avbryter" #: src/reuse/lint.py:350 #, fuzzy msgid "deprecated license" msgstr "(Föråldrad) {text}" #: src/reuse/lint.py:355 msgid "license without file extension" msgstr "" #: src/reuse/lint.py:360 msgid "unused license" msgstr "" #: src/reuse/project.py:253 #, python-brace-format msgid "'{path}' covered by {global_path}" msgstr "" #: src/reuse/project.py:261 #, python-brace-format msgid "" "'{path}' is covered exclusively by REUSE.toml. Not reading the file contents." 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:355 #, 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:419 #, python-brace-format msgid "{path} does not have a file extension" msgstr "" #: src/reuse/project.py:429 #, 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:441 #, python-brace-format msgid "" "{identifier} is the SPDX License Identifier of both {path} and {other_path}" msgstr "" #: src/reuse/project.py:480 msgid "" "project '{}' is not a VCS repository or required VCS software is not " "installed" msgstr "" #: src/reuse/extract.py:49 #, python-brace-format msgid "" "REUSE_ENCODING_MODULE must have a value in {modules}; it has '{env_module}'. " "Aborting." msgstr "" #: src/reuse/extract.py:69 msgid "" "No supported module that can detect the encoding of files could be " "successfully imported. Re-read the installation instructions for the reuse " "package, or try the following:" msgstr "" #: src/reuse/extract.py:75 msgid "" "- If you are running a Linux distribution, try your equivalent of `apt " "install file` or `dnf install file`." msgstr "" #: src/reuse/extract.py:80 msgid "" "- Run ` pipx install reuse[charset-normalizer]`. Replace 'pipx' with 'pip' " "if you are not using pipx." msgstr "" #: src/reuse/extract.py:451 #, python-brace-format msgid "" "'{path}' was detected as a binary file; not searching its contents for REUSE " "information." msgstr "" #: src/reuse/extract.py:462 #, python-brace-format msgid "" "extracting REUSE information from '{path}' (encoding {encoding}, encoding " "module {module}, newline {newline})" msgstr "" #: src/reuse/header.py:87 msgid "generated comment is missing copyright lines or license expressions" msgstr "" #: src/reuse/report.py:160 #, fuzzy, python-brace-format msgid "Could not read '{path}'" msgstr "Kunde inte tolka '{expression}'" #: src/reuse/report.py:165 #, python-brace-format msgid "Unexpected error occurred while parsing '{path}'" msgstr "" #: src/reuse/report.py:521 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:532 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:543 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:552 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:564 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:575 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:584 msgid "" "Fix invalid SPDX License Expressions: In one or more files there are SPDX " "License Expressions which cannot be parse. Check whether the value that " "follows 'SPDX-License-Identifier:' is correct. If the detected expression is " "not meant to be valid, put it between 'REUSE-IgnoreStart' and 'REUSE-" "IgnoreEnd' comments." msgstr "" #: src/reuse/report.py:595 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/cli/lint.py:28 #, python-brace-format msgid "" "Lint the project directory for REUSE compliance. This version of the tool " "checks against version {reuse_version} of the REUSE Specification. You can " "find the latest version of the specification at ." msgstr "" #: src/reuse/cli/lint.py:34 msgid "Specifically, the following criteria are checked:" msgstr "Följande kriteriet är kontrollerat specifikt:" #: src/reuse/cli/lint.py:38 msgid "" "- Are there any bad (unrecognised, not compliant with SPDX) licenses in the " "project?" msgstr "" #: src/reuse/cli/lint.py:43 msgid "- Are there any deprecated licenses in the project?" msgstr "- Finns det några föråldrade licenser i projektet?" #: src/reuse/cli/lint.py:47 msgid "" "- Are there any license files in the LICENSES/ directory without file " "extension?" msgstr "" #: src/reuse/cli/lint.py:54 msgid "" "- Are any licenses referred to inside of the project, but not included in " "the LICENSES/ directory?" msgstr "" #: src/reuse/cli/lint.py:61 msgid "" "- Are any licenses included in the LICENSES/ directory that are not used " "inside of the project?" msgstr "" #: src/reuse/cli/lint.py:66 msgid "- Are there any read errors?" msgstr "- Finns det några läs-fel?" #: src/reuse/cli/lint.py:69 msgid "- Do all files have valid copyright and licensing information?" msgstr "" "- Har alla filer ett giltigt kopieringsskydd och licensieringsinformation?" #: src/reuse/cli/lint.py:81 src/reuse/cli/lint_file.py:38 msgid "Prevent output." msgstr "Förhindra utmatning." #: src/reuse/cli/lint.py:89 src/reuse/cli/supported_licenses.py:28 msgid "Format output as JSON." msgstr "Formatera utmatning som JSON." #: src/reuse/cli/lint.py:97 msgid "Format output as plain text. (default)" msgstr "Formatera utmatningen som ren text. (standard)" #: src/reuse/cli/lint.py:105 msgid "Format output as errors per line." msgstr "Formatera utmatningen som fel per rad." #: src/reuse/cli/convert_dep5.py:19 msgid "" "Convert .reuse/dep5 into a REUSE.toml file. The generated file is placed in " "the project root and is semantically identical. The .reuse/dep5 file is " "subsequently deleted." msgstr "" #: src/reuse/cli/convert_dep5.py:31 msgid "No '.reuse/dep5' file." msgstr "Ingen '.reuse/dep5'-file." #: src/reuse/cli/lint_file.py:25 msgid "" "Lint individual files for REUSE compliance. The specified FILEs are checked " "for the presence of copyright and licensing information, and whether the " "found licenses are included in the LICENSES/ directory." msgstr "" #: src/reuse/cli/lint_file.py:46 msgid "Format output as errors per line. (default)" msgstr "Formatera utmatningen som fel per rad. (standard)" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/lint_file.py:51 msgid "FILE" msgstr "FIL" #: src/reuse/cli/lint_file.py:65 #, python-brace-format msgid "'{file}' is not inside of '{root}'." msgstr "{file} är inte inuti '{root}'." #: src/reuse/cli/spdx.py:22 msgid "Generate an SPDX bill of materials." msgstr "" #: src/reuse/cli/spdx.py:32 msgid "File to write to." msgstr "Fil att skriva till." #: src/reuse/cli/spdx.py:38 msgid "" "Populate the LicenseConcluded field; note that reuse cannot guarantee that " "the field is accurate." msgstr "" #: src/reuse/cli/spdx.py:50 msgid "Name of the person signing off on the SPDX report." msgstr "" #: src/reuse/cli/spdx.py:54 msgid "Name of the organization signing off on the SPDX report." msgstr "" #: src/reuse/cli/spdx.py:81 msgid "" "'--creator-person' or '--creator-organization' is required when '--add-" "license-concluded' is provided." msgstr "" "'--creator-person' eller '--creator-organization' krävs när '--add-license-" "concluded' tillhandahålls." #: src/reuse/cli/spdx.py:96 #, 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 "" #: src/reuse/cli/main.py:36 #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/decorators.py:465 #, python-format msgid "%(prog)s, version %(version)s" msgstr "%(prog)s, version %(version)s" #: src/reuse/cli/main.py:39 msgid "" "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." msgstr "" #: src/reuse/cli/main.py:46 msgid "" "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." msgstr "" #: src/reuse/cli/main.py:53 msgid "" "You should have received a copy of the GNU General Public License along with " "this program. If not, see ." msgstr "" #: src/reuse/cli/main.py:61 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/cli/main.py:68 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/cli/main.py:72 msgid "Support the FSFE's work:" msgstr "Stötta FSFE's arbete:" #: src/reuse/cli/main.py:77 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/cli/main.py:88 msgid "Enable debug statements." msgstr "" #: src/reuse/cli/main.py:93 msgid "Hide deprecation warnings." msgstr "" #: src/reuse/cli/main.py:98 #, fuzzy msgid "Do not skip over Git submodules." msgstr "hoppa inte över undermoduler för Git" #: src/reuse/cli/main.py:103 #, fuzzy msgid "Do not skip over Meson subprojects." msgstr "hoppa inte över underprojekt för Meson" #: src/reuse/cli/main.py:108 msgid "Do not use multiprocessing." msgstr "Använd inte multibehandling." #: src/reuse/cli/main.py:118 #, fuzzy msgid "Define root of project." msgstr "definiera roten av projektet" #: src/reuse/cli/common.py:51 #, 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/cli/common.py:87 #, python-brace-format msgid "'{name}' is mutually exclusive with: {opts}" msgstr "'{name}' är ömsesidigt exklusivt med: {opts}" #: src/reuse/cli/common.py:103 #, fuzzy msgid "'{}' is not a valid SPDX expression." msgstr "'{}' är inte ett giltigt SPDX-uttryck, avbryter" #: src/reuse/cli/download.py:54 #, fuzzy msgid "'{}' is not a valid SPDX License Identifier." msgstr "'{}' är inte ett giltigt SPDX-uttryck, avbryter" #: src/reuse/cli/download.py:61 #, fuzzy msgid "Did you mean:" msgstr "Menade du:" #: src/reuse/cli/download.py:68 msgid "" "See for a list of valid SPDX License " "Identifiers." msgstr "" "Se för en lista över giltiga SPDX-" "licensidentifierare." #: src/reuse/cli/download.py:77 #, python-brace-format msgid "Error: {spdx_identifier} already exists." msgstr "Fel: {spdx_identifier} existerar redan." #: src/reuse/cli/download.py:84 #, fuzzy, python-brace-format msgid "Error: {path} does not exist." msgstr "Fel: {path} existerar inte." #: src/reuse/cli/download.py:88 msgid "Error: Failed to download license." msgstr "Fel: Hämtningen av licensen misslyckades." #: src/reuse/cli/download.py:93 msgid "Is your internet connection working?" msgstr "Fungerar din internet-anslutning?" #: src/reuse/cli/download.py:98 #, python-brace-format msgid "Successfully downloaded {spdx_identifier}." msgstr "Hämtningen av {spdx_identifier} lyckades." #: src/reuse/cli/download.py:108 #, 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/cli/download.py:111 msgid "" "LICENSE must be a valid SPDX License Identifier. You may specify LICENSE " "multiple times to download multiple licenses." msgstr "" #: src/reuse/cli/download.py:124 #, fuzzy msgid "Download all missing licenses detected in the project." msgstr "ladda ner alla saknade licenser som upptäckts i projektet" #: src/reuse/cli/download.py:132 msgid "Path to download to." msgstr "Genväg att hämta till." #: src/reuse/cli/download.py:138 msgid "" "Source from which to copy custom LicenseRef- licenses, either a directory " "that contains the file or the file itself." msgstr "" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/download.py:145 msgid "LICENSE" msgstr "LICENS" #: src/reuse/cli/download.py:161 msgid "The 'LICENSE' argument and '--all' option are mutually exclusive." msgstr "Argumentet 'LICENS' och alternativet '--all' är ömsesidigt exklusivt." #: src/reuse/cli/download.py:173 #, fuzzy msgid "Cannot use '--output' with more than one license." msgstr "kan inte använda --output med mer än en licens" #: src/reuse/cli/annotate.py:66 msgid "Option '--copyright', '--license', or '--contributor' is required." msgstr "Alternativet '--copyright', '--license', eller '--contributor' krävs." #: src/reuse/cli/annotate.py:127 msgid "" "The following files do not have a recognised file extension. Please use '--" "style', '--force-dot-license', '--fallback-dot-license', or '--skip-" "unrecognised':" msgstr "" "De följande filerna har inte en filändelse som känns igen. Vänligen använd " "'--style','force-dot-license','--fallback-dot-license', eller '--skip-" "unrecognised':" #: src/reuse/cli/annotate.py:160 #, python-brace-format msgid "" "'{path}' does not support single-line comments, please do not use '--single-" "line'." msgstr "" "'{path}' har inte stöd för kommentarer på en rad, vänligen använd inte '--" "single-line'." #: src/reuse/cli/annotate.py:167 #, fuzzy, python-brace-format msgid "" "'{path}' does not support multi-line comments, please do not use '--multi-" "line'." msgstr "" "'{path}' stöjder inte kommentarer på flera rader, använd inte --multi-line" #: src/reuse/cli/annotate.py:213 #, fuzzy, python-brace-format msgid "Template '{template}' could not be found." msgstr "'{dep5}' kunde inte avkodas som UTF-8." #: src/reuse/cli/annotate.py:236 #, fuzzy, python-brace-format msgid "'{year}' is not a valid year range." msgstr "{value!r} är inte en giltig boolean." #: src/reuse/cli/annotate.py:245 #, python-brace-format msgid "" "Your operating system's year is set to '{year}'. This is not four digits, " "and not supported." msgstr "" #: src/reuse/cli/annotate.py:287 msgid "Add copyright and licensing into the headers of files." msgstr "" #: src/reuse/cli/annotate.py:290 msgid "" "By using --copyright and --license, you can specify which copyright holders " "and licenses to add to the headers of the given files." msgstr "" #: src/reuse/cli/annotate.py:296 msgid "" "By using --contributor, you can specify people or entity that contributed " "but are not copyright holder of the given files." msgstr "" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:309 msgid "COPYRIGHT" msgstr "KOPIERINGSSKYDD" #: src/reuse/cli/annotate.py:312 msgid "Copyright holder, repeatable." msgstr "" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:319 msgid "SPDX_IDENTIFIER" msgstr "SPDX_IDENTIFIERARE" #: src/reuse/cli/annotate.py:322 msgid "SPDX License Identifier, repeatable." msgstr "" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:328 msgid "CONTRIBUTOR" msgstr "" #: src/reuse/cli/annotate.py:331 msgid "File contributor, repeatable." msgstr "" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:338 msgid "YEAR" msgstr "ÅR" #: src/reuse/cli/annotate.py:343 msgid "" "Year of copyright notice. You may define multiple years or a range of years." msgstr "" #: src/reuse/cli/annotate.py:353 msgid "Comment style to use." msgstr "Kommentarstilen att använda." #: src/reuse/cli/annotate.py:363 msgid "Copyright prefix to use." msgstr "" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:375 msgid "TEMPLATE" msgstr "MALL" #: src/reuse/cli/annotate.py:377 msgid "Name of template to use." msgstr "Namnet på mallen som ska användas." #: src/reuse/cli/annotate.py:384 msgid "Do not include year in copyright notice." msgstr "" #: src/reuse/cli/annotate.py:390 msgid "Merge copyright notices if they are identical except for their years." msgstr "" #: src/reuse/cli/annotate.py:398 msgid "Force single-line comment style." msgstr "" #: src/reuse/cli/annotate.py:405 msgid "Force multi-line comment style." msgstr "" #: src/reuse/cli/annotate.py:411 msgid "Add headers to all files under specified directories recursively." msgstr "Lägg till huvuden i alla filer under angivna kataloger rekursivt." #: src/reuse/cli/annotate.py:416 msgid "Do not replace the first header in the file; just add a new one." msgstr "" #: src/reuse/cli/annotate.py:423 msgid "Always write a .license file instead of a header inside the file." msgstr "" #: src/reuse/cli/annotate.py:430 msgid "Write a .license file to files with unrecognised comment styles." msgstr "Skriv en .licens-fil med icke igenkända kommentarstilar." #: src/reuse/cli/annotate.py:437 msgid "Skip files with unrecognised comment styles." msgstr "Hoppa över filer med icke igenkända kommentarstilar." #: src/reuse/cli/annotate.py:448 #, fuzzy msgid "Skip files that already contain REUSE information." msgstr "Hoppade över fil '{path}' innehåller redan REUSE information" #. TRANSLATORS: You may translate this. Please preserve capital letters. #: src/reuse/cli/annotate.py:453 msgid "PATH" msgstr "GENVÄG" #: src/reuse/cli/annotate.py:510 #, python-brace-format msgid "'{path}' is a binary, therefore using '{new_path}' for the header" msgstr "'{path}' är en binär, använder därför '{new_path}' för huvudet" #: src/reuse/cli/supported_licenses.py:19 #, fuzzy msgid "List all licenses on the SPDX License List." msgstr "lista alla SPDX-licenser som stöds" #: src/reuse/global_licensing.py:92 #, python-brace-format msgid "" "{attr_name} must be a {type_name} (got {value} that is a {value_class})." msgstr "" #: src/reuse/global_licensing.py:106 #, 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:118 #, python-brace-format msgid "{attr_name} must not be empty." msgstr "" #: src/reuse/global_licensing.py:142 #, python-brace-format msgid "{name} must be a {type} (got {value} that is a {value_type})." msgstr "" #: src/reuse/global_licensing.py:166 #, python-brace-format msgid "" "The value of 'precedence' must be one of {precedence_vals} (got {received})" msgstr "" #: src/reuse/global_licensing.py:219 #, fuzzy, python-brace-format msgid "Could not parse '{notice}'" msgstr "Kunde inte tolka '{expression}'" #: src/reuse/_annotate.py:94 #, python-brace-format msgid "Skipped unrecognised file '{path}'" msgstr "Hoppar över fil som inte känns igen '{path}'" #: src/reuse/_annotate.py:100 #, python-brace-format msgid "'{path}' is not recognised; creating '{path}.license'" msgstr "'{path}' känns inte igen; skapar '{path}.license'" #: src/reuse/_annotate.py:116 #, fuzzy, python-brace-format msgid "Skipped file '{path}' already containing REUSE information" msgstr "Hoppade över fil '{path}' innehåller redan REUSE information" #: src/reuse/_annotate.py:145 #, python-brace-format msgid "Error: Could not create comment for '{path}'" msgstr "Fel: Kunde inte skapa kommentar för '{path}'" #: src/reuse/_annotate.py:152 #, 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:163 #, python-brace-format msgid "Successfully changed header of {path}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:162 msgid "Repeat for confirmation" msgstr "Upprepa för bekräftelse" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:178 msgid "Error: The value you entered was invalid." msgstr "Fel: Värdet som du fyllde i var ogiltigt." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:180 #, python-brace-format msgid "Error: {e.message}" msgstr "Fel: {e.message}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:191 msgid "Error: The two entered values do not match." msgstr "Fel: De två värderna som ifylldes matchar inte." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:247 msgid "Error: invalid input" msgstr "Fel: ogiltig inmatning" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/termui.py:866 msgid "Press any key to continue..." msgstr "Tryck på en tangent för att fortsätta..." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:332 #, python-brace-format msgid "" "Choose from:\n" "\t{choices}" msgstr "" "Välj:\n" " {choices}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:369 msgid "{value!r} is not {choice}." msgid_plural "{value!r} is not one of {choices}." msgstr[0] "{value!r} är inte {choice}." msgstr[1] "{value!r} är inte en utav {choice}." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:460 msgid "{value!r} does not match the format {format}." msgid_plural "{value!r} does not match the formats {formats}." msgstr[0] "" msgstr[1] "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:482 msgid "{value!r} is not a valid {number_type}." msgstr "{value!r} är inte ett giltigt {number_type}." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:538 #, python-brace-format msgid "{value} is not in the range {range}." msgstr "{value} är inte inom intervallet {range}." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:719 #, fuzzy msgid "{value!r} is not a valid boolean. Recognized values: {states}" msgstr "{value!r} är inte en giltig boolean." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:747 msgid "{value!r} is not a valid UUID." msgstr "{value!r} är inte ett giltigt UUID." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:937 msgid "file" msgstr "fil" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:939 msgid "directory" msgstr "katalog" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:941 msgid "path" msgstr "genväg" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:988 #, fuzzy msgid "{name} {filename!r} does not exist." msgstr "Fel: {path} existerar inte." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:997 msgid "{name} {filename!r} is a file." msgstr "{name} {filename!r} är en fil." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:1005 #, fuzzy msgid "{name} {filename!r} is a directory." msgstr "'{}' är inte en katalog" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:1014 msgid "{name} {filename!r} is not readable." msgstr "{name} {filename!r} är inte läsbart." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:1023 msgid "{name} {filename!r} is not writable." msgstr "{name} {filename!r} är inte skrivbart." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:1032 msgid "{name} {filename!r} is not executable." msgstr "{name} {filename!r} är inte kör-bart." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/types.py:1099 #, python-brace-format msgid "{len_type} values are required, but {len_value} was given." msgid_plural "{len_type} values are required, but {len_value} were given." msgstr[0] "" msgstr[1] "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/shell_completion.py:332 msgid "Shell completion is not supported for Bash versions older than 4.4." msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/shell_completion.py:339 msgid "Couldn't detect Bash version, shell completion is not supported." msgstr "Kunde inte upptäcka Bash-versionen, skalkomplettering stöds inte." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:50 #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:89 #, python-brace-format msgid "Error: {message}" msgstr "Fel: {message}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:81 #, python-brace-format msgid "Try '{command} {option}' for help." msgstr "Prova '{command} {option}' för hjälp." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:130 #, python-brace-format msgid "Invalid value: {message}" msgstr "Ogiltigt värde: {message}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:132 #, python-brace-format msgid "Invalid value for {param_hint}: {message}" msgstr "Ogiltigt värde för {param_hint}: {message}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:190 msgid "Missing argument" msgstr "Argument saknas" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:192 msgid "Missing option" msgstr "Alternativ saknas" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:194 msgid "Missing parameter" msgstr "Parameter saknas" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:196 #, python-brace-format msgid "Missing {param_type}" msgstr "Saknas {param_type}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:203 #, python-brace-format msgid "Missing parameter: {param_name}" msgstr "Parameter saknas: {param_name}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:223 #, python-brace-format msgid "No such option: {name}" msgstr "Inget sådant alternativ: {name}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:235 #, fuzzy, python-brace-format msgid "Did you mean {possibility}?" msgid_plural "(Possible options: {possibilities})" msgstr[0] "Menade du:" msgstr[1] "Menade du:" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:282 msgid "unknown error" msgstr "okänt fel" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/exceptions.py:289 msgid "Could not open file {filename!r}: {message}" msgstr "Kunde inte öppna filen {filename!r}: {message}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1104 #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1141 #, python-brace-format msgid "{text} {deprecated_message}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1160 msgid "Options" msgstr "Alternativ" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1222 #, python-brace-format msgid "Got unexpected extra argument ({args})" msgid_plural "Got unexpected extra arguments ({args})" msgstr[0] "Fick ett oväntat extra argument ({args})" msgstr[1] "Fick oväntade extra argument ({args})" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1241 msgid "DeprecationWarning: The command {name!r} is deprecated.{extra_message}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1425 msgid "Aborted!" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1799 msgid "Commands" msgstr "Kommandon" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1830 msgid "Missing command." msgstr "Kommando saknas." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:1908 msgid "No such command {name!r}." msgstr "Inget sådant kommando {name!r}." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:2332 msgid "Value must be an iterable." msgstr "Värdet måste vara upprepningsbart." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:2355 #, python-brace-format msgid "Takes {nargs} values but 1 was given." msgid_plural "Takes {nargs} values but {len} were given." msgstr[0] "" msgstr[1] "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:2505 msgid "" "DeprecationWarning: The {param_type} {name!r} is deprecated.{extra_message}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:2956 #, python-brace-format msgid "env var: {var}" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:2959 #, python-brace-format msgid "default: {default}" msgstr "standard: {default}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/core.py:3023 msgid "(dynamic)" msgstr "" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/parser.py:199 msgid "Argument {name!r} takes {nargs} values." msgstr "Argumentet {name!r} tar {nargs}-värden." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/parser.py:381 msgid "Option {name!r} does not take a value." msgstr "Alternativet {name!r} tar inte emot något värde." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/parser.py:444 msgid "Option {name!r} requires an argument." msgid_plural "Option {name!r} requires {nargs} arguments." msgstr[0] "Alternativet {name!r} kräver ett argument." msgstr[1] "Alternativen {name!r} kräver {nargs} argument." #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/_termui_impl.py:608 #, python-brace-format msgid "{editor}: Editing failed" msgstr "{editor}: Redigeringen misslyckades" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/_termui_impl.py:612 #, python-brace-format msgid "{editor}: Editing failed: {e}" msgstr "{editor}: Redigeringen misslyckades: {e}" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/decorators.py:522 #, fuzzy msgid "Show the version and exit." msgstr "visa programmets versionsnummer och avsluta" #: /home/runner/.cache/pypoetry/virtualenvs/reuse-MK6tuBk_-py3.12/lib/python3.12/site-packages/click/decorators.py:548 msgid "Show this message and exit." msgstr "Visa det här meddelandet och avsluta." #, python-brace-format #~ msgid "Could not parse '{expression}'" #~ msgstr "Kunde inte tolka '{expression}'" #, python-brace-format #~ msgid "(Deprecated) {text}" #~ msgstr "(Föråldrad) {text}" #~ msgid "required" #~ msgstr "krävs" #~ msgid "can't write to '{}'" #~ msgstr "kan inte skriva till '{}'" #~ msgid "download a license and place it in the LICENSES/ directory" #~ msgstr "hämta en licens och placera den i mappen LICENSES/" #~ msgid "list all non-compliant files" #~ msgstr "lista alla filer som inte uppfyller kraven" #~ msgid "'{}' is not a file" #~ msgstr "'{}' är inte en fil" #~ msgid "can't open '{}'" #~ msgstr "kan inte öppna '{}'" #~ msgid "can't write to directory '{}'" #~ msgstr "kan inte skriva till katalogen '{}'" #~ msgid "can't read or write '{}'" #~ msgstr "kan inte läsa eller skriva '{}'" #~ 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-6.2.0/poetry.lock0000664000175000017500000043571515077707000014501 0ustar alexalex# This file is automatically @generated by Poetry 2.2.1 and should not be changed by hand. [[package]] name = "accessible-pygments" version = "0.0.5" description = "A collection of accessible pygments styles" optional = false python-versions = ">=3.9" groups = ["docs"] files = [ {file = "accessible_pygments-0.0.5-py3-none-any.whl", hash = "sha256:88ae3211e68a1d0b011504b2ffc1691feafce124b845bd072ab6f9f66f34d4b7"}, {file = "accessible_pygments-0.0.5.tar.gz", hash = "sha256:40918d3e6a2b619ad424cb91e556bd3bd8865443d9f22f1dcdf79e33c8046872"}, ] [package.dependencies] pygments = ">=1.5" [package.extras] dev = ["pillow", "pkginfo (>=1.10)", "playwright", "pre-commit", "setuptools", "twine (>=5.0)"] tests = ["hypothesis", "pytest"] [[package]] name = "alabaster" version = "1.0.0" description = "A light, configurable Sphinx theme" optional = false python-versions = ">=3.10" groups = ["docs"] files = [ {file = "alabaster-1.0.0-py3-none-any.whl", hash = "sha256:fc6786402dc3fcb2de3cabd5fe455a2db534b371124f1f21de8731783dec828b"}, {file = "alabaster-1.0.0.tar.gz", hash = "sha256:c00dca57bca26fa62a6d7d0a9fcce65f3e026e9bfe33e9c538fd3fbb2144fd9e"}, ] [[package]] name = "astroid" version = "4.0.1" description = "An abstract syntax tree for Python with inference support." optional = false python-versions = ">=3.10.0" groups = ["dev"] files = [ {file = "astroid-4.0.1-py3-none-any.whl", hash = "sha256:37ab2f107d14dc173412327febf6c78d39590fdafcb44868f03b6c03452e3db0"}, {file = "astroid-4.0.1.tar.gz", hash = "sha256:0d778ec0def05b935e198412e62f9bcca8b3b5c39fdbe50b0ba074005e477aab"}, ] [package.dependencies] typing-extensions = {version = ">=4", markers = "python_version < \"3.11\""} [[package]] name = "attrs" version = "25.4.0" description = "Classes Without Boilerplate" optional = false python-versions = ">=3.9" groups = ["main", "dev"] files = [ {file = "attrs-25.4.0-py3-none-any.whl", hash = "sha256:adcf7e2a1fb3b36ac48d97835bb6d8ade15b8dcce26aba8bf1d14847b57a3373"}, {file = "attrs-25.4.0.tar.gz", hash = "sha256:16d5969b87f0859ef33a48b35d55ac1be6e42ae49d5e853b597db70c35c57e11"}, ] markers = {dev = "python_version >= \"3.11\""} [[package]] name = "babel" version = "2.17.0" description = "Internationalization utilities" optional = false python-versions = ">=3.8" groups = ["docs"] files = [ {file = "babel-2.17.0-py3-none-any.whl", hash = "sha256:4d0b53093fdfb4b21c92b5213dba5a1b23885afa8383709427046b21c366e5f2"}, {file = "babel-2.17.0.tar.gz", hash = "sha256:0c54cffb19f690cdcc52a3b50bcbf71e07a808d1c80d549f2459b9d2cf0afb9d"}, ] [package.extras] dev = ["backports.zoneinfo ; python_version < \"3.9\"", "freezegun (>=1.0,<2.0)", "jinja2 (>=3.0)", "pytest (>=6.0)", "pytest-cov", "pytz", "setuptools", "tzdata ; sys_platform == \"win32\""] [[package]] name = "beautifulsoup4" version = "4.14.2" description = "Screen-scraping library" optional = false python-versions = ">=3.7.0" groups = ["docs"] files = [ {file = "beautifulsoup4-4.14.2-py3-none-any.whl", hash = "sha256:5ef6fa3a8cbece8488d66985560f97ed091e22bbc4e9c2338508a9d5de6d4515"}, {file = "beautifulsoup4-4.14.2.tar.gz", hash = "sha256:2a98ab9f944a11acee9cc848508ec28d9228abfd522ef0fad6a02a72e0ded69e"}, ] [package.dependencies] soupsieve = ">1.2" typing-extensions = ">=4.0.0" [package.extras] cchardet = ["cchardet"] chardet = ["chardet"] charset-normalizer = ["charset-normalizer"] html5lib = ["html5lib"] lxml = ["lxml"] [[package]] name = "black" version = "25.9.0" description = "The uncompromising code formatter." optional = false python-versions = ">=3.9" groups = ["dev", "lsp"] files = [ {file = "black-25.9.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ce41ed2614b706fd55fd0b4a6909d06b5bab344ffbfadc6ef34ae50adba3d4f7"}, {file = "black-25.9.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2ab0ce111ef026790e9b13bd216fa7bc48edd934ffc4cbf78808b235793cbc92"}, {file = "black-25.9.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f96b6726d690c96c60ba682955199f8c39abc1ae0c3a494a9c62c0184049a713"}, {file = "black-25.9.0-cp310-cp310-win_amd64.whl", hash = "sha256:d119957b37cc641596063cd7db2656c5be3752ac17877017b2ffcdb9dfc4d2b1"}, {file = "black-25.9.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:456386fe87bad41b806d53c062e2974615825c7a52159cde7ccaeb0695fa28fa"}, {file = "black-25.9.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a16b14a44c1af60a210d8da28e108e13e75a284bf21a9afa6b4571f96ab8bb9d"}, {file = "black-25.9.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:aaf319612536d502fdd0e88ce52d8f1352b2c0a955cc2798f79eeca9d3af0608"}, {file = "black-25.9.0-cp311-cp311-win_amd64.whl", hash = "sha256:c0372a93e16b3954208417bfe448e09b0de5cc721d521866cd9e0acac3c04a1f"}, {file = "black-25.9.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:1b9dc70c21ef8b43248f1d86aedd2aaf75ae110b958a7909ad8463c4aa0880b0"}, {file = "black-25.9.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8e46eecf65a095fa62e53245ae2795c90bdecabd53b50c448d0a8bcd0d2e74c4"}, {file = "black-25.9.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9101ee58ddc2442199a25cb648d46ba22cd580b00ca4b44234a324e3ec7a0f7e"}, {file = "black-25.9.0-cp312-cp312-win_amd64.whl", hash = "sha256:77e7060a00c5ec4b3367c55f39cf9b06e68965a4f2e61cecacd6d0d9b7ec945a"}, {file = "black-25.9.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0172a012f725b792c358d57fe7b6b6e8e67375dd157f64fa7a3097b3ed3e2175"}, {file = "black-25.9.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:3bec74ee60f8dfef564b573a96b8930f7b6a538e846123d5ad77ba14a8d7a64f"}, {file = "black-25.9.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b756fc75871cb1bcac5499552d771822fd9db5a2bb8db2a7247936ca48f39831"}, {file = "black-25.9.0-cp313-cp313-win_amd64.whl", hash = "sha256:846d58e3ce7879ec1ffe816bb9df6d006cd9590515ed5d17db14e17666b2b357"}, {file = "black-25.9.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:ef69351df3c84485a8beb6f7b8f9721e2009e20ef80a8d619e2d1788b7816d47"}, {file = "black-25.9.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e3c1f4cd5e93842774d9ee4ef6cd8d17790e65f44f7cdbaab5f2cf8ccf22a823"}, {file = "black-25.9.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:154b06d618233fe468236ba1f0e40823d4eb08b26f5e9261526fde34916b9140"}, {file = "black-25.9.0-cp39-cp39-win_amd64.whl", hash = "sha256:e593466de7b998374ea2585a471ba90553283fb9beefcfa430d84a2651ed5933"}, {file = "black-25.9.0-py3-none-any.whl", hash = "sha256:474b34c1342cdc157d307b56c4c65bce916480c4a8f6551fdc6bf9b486a7c4ae"}, {file = "black-25.9.0.tar.gz", hash = "sha256:0474bca9a0dd1b51791fcc507a4e02078a1c63f6d4e4ae5544b9848c7adfb619"}, ] [package.dependencies] click = ">=8.0.0" mypy-extensions = ">=0.4.3" packaging = ">=22.0" pathspec = ">=0.9.0" platformdirs = ">=2" pytokens = ">=0.1.10" 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.10)"] jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"] uvloop = ["uvloop (>=0.15.2)"] [[package]] name = "boolean-py" version = "5.0" description = "Define boolean algebras, create and parse boolean expressions and create custom boolean DSL." optional = false python-versions = "*" groups = ["main"] files = [ {file = "boolean_py-5.0-py3-none-any.whl", hash = "sha256:ef28a70bd43115208441b53a045d1549e2f0ec6e3d08a9d142cbc41c1938e8d9"}, {file = "boolean_py-5.0.tar.gz", hash = "sha256:60cbc4bad079753721d32649545505362c754e121570ada4658b852a3a318d95"}, ] [package.extras] dev = ["build", "twine"] docs = ["Sphinx (>=3.3.1)", "doc8 (>=0.8.1)", "sphinx-rtd-theme (>=0.5.0)", "sphinxcontrib-apidoc (>=0.3.0)"] linting = ["black", "isort", "pycodestyle"] testing = ["pytest (>=6,!=7.0.0)", "pytest-xdist (>=2)"] [[package]] name = "bumpver" version = "2025.1131" description = "Bump version numbers in project files." optional = false python-versions = ">=2.7" groups = ["dev"] files = [ {file = "bumpver-2025.1131-py2.py3-none-any.whl", hash = "sha256:c02527f6ed7887afbc06c07630047b24a9f9d02d544a65639e99bf8b92aaa674"}, {file = "bumpver-2025.1131.tar.gz", hash = "sha256:a35fd2d43a5f65f014035c094866bd3bd6c739606f29fd41246d6ec6e839d3f9"}, ] [package.dependencies] click = {version = "*", markers = "python_version >= \"3.6\""} colorama = ">=0.4" lexid = "*" toml = "*" [[package]] name = "certifi" version = "2025.10.5" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.7" groups = ["docs"] files = [ {file = "certifi-2025.10.5-py3-none-any.whl", hash = "sha256:0f212c2744a9bb6de0c56639a6f68afe01ecd92d91f14ae897c4fe7bbeeef0de"}, {file = "certifi-2025.10.5.tar.gz", hash = "sha256:47c09d31ccf2acf0be3f701ea53595ee7e0b8fa08801c6624be771df09ae7b43"}, ] [[package]] name = "cfgv" version = "3.4.0" description = "Validate configuration and produce human readable error messages." optional = false python-versions = ">=3.8" groups = ["dev"] 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" optional = true python-versions = ">=3.7" groups = ["main"] markers = "extra == \"chardet\"" 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.4.4" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false python-versions = ">=3.7" groups = ["main", "docs"] files = [ {file = "charset_normalizer-3.4.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e824f1492727fa856dd6eda4f7cee25f8518a12f3c4a56a74e8095695089cf6d"}, {file = "charset_normalizer-3.4.4-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4bd5d4137d500351a30687c2d3971758aac9a19208fc110ccb9d7188fbe709e8"}, {file = "charset_normalizer-3.4.4-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:027f6de494925c0ab2a55eab46ae5129951638a49a34d87f4c3eda90f696b4ad"}, {file = "charset_normalizer-3.4.4-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f820802628d2694cb7e56db99213f930856014862f3fd943d290ea8438d07ca8"}, {file = "charset_normalizer-3.4.4-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:798d75d81754988d2565bff1b97ba5a44411867c0cf32b77a7e8f8d84796b10d"}, {file = "charset_normalizer-3.4.4-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9d1bb833febdff5c8927f922386db610b49db6e0d4f4ee29601d71e7c2694313"}, {file = "charset_normalizer-3.4.4-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:9cd98cdc06614a2f768d2b7286d66805f94c48cde050acdbbb7db2600ab3197e"}, {file = "charset_normalizer-3.4.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:077fbb858e903c73f6c9db43374fd213b0b6a778106bc7032446a8e8b5b38b93"}, {file = "charset_normalizer-3.4.4-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:244bfb999c71b35de57821b8ea746b24e863398194a4014e4c76adc2bbdfeff0"}, {file = "charset_normalizer-3.4.4-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:64b55f9dce520635f018f907ff1b0df1fdc31f2795a922fb49dd14fbcdf48c84"}, {file = "charset_normalizer-3.4.4-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:faa3a41b2b66b6e50f84ae4a68c64fcd0c44355741c6374813a800cd6695db9e"}, {file = "charset_normalizer-3.4.4-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:6515f3182dbe4ea06ced2d9e8666d97b46ef4c75e326b79bb624110f122551db"}, {file = "charset_normalizer-3.4.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:cc00f04ed596e9dc0da42ed17ac5e596c6ccba999ba6bd92b0e0aef2f170f2d6"}, {file = "charset_normalizer-3.4.4-cp310-cp310-win32.whl", hash = "sha256:f34be2938726fc13801220747472850852fe6b1ea75869a048d6f896838c896f"}, {file = "charset_normalizer-3.4.4-cp310-cp310-win_amd64.whl", hash = "sha256:a61900df84c667873b292c3de315a786dd8dac506704dea57bc957bd31e22c7d"}, {file = "charset_normalizer-3.4.4-cp310-cp310-win_arm64.whl", hash = "sha256:cead0978fc57397645f12578bfd2d5ea9138ea0fac82b2f63f7f7c6877986a69"}, {file = "charset_normalizer-3.4.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:6e1fcf0720908f200cd21aa4e6750a48ff6ce4afe7ff5a79a90d5ed8a08296f8"}, {file = "charset_normalizer-3.4.4-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5f819d5fe9234f9f82d75bdfa9aef3a3d72c4d24a6e57aeaebba32a704553aa0"}, {file = "charset_normalizer-3.4.4-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:a59cb51917aa591b1c4e6a43c132f0cdc3c76dbad6155df4e28ee626cc77a0a3"}, {file = "charset_normalizer-3.4.4-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:8ef3c867360f88ac904fd3f5e1f902f13307af9052646963ee08ff4f131adafc"}, {file = "charset_normalizer-3.4.4-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d9e45d7faa48ee908174d8fe84854479ef838fc6a705c9315372eacbc2f02897"}, {file = "charset_normalizer-3.4.4-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:840c25fb618a231545cbab0564a799f101b63b9901f2569faecd6b222ac72381"}, {file = "charset_normalizer-3.4.4-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:ca5862d5b3928c4940729dacc329aa9102900382fea192fc5e52eb69d6093815"}, {file = "charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d9c7f57c3d666a53421049053eaacdd14bbd0a528e2186fcb2e672effd053bb0"}, {file = "charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:277e970e750505ed74c832b4bf75dac7476262ee2a013f5574dd49075879e161"}, {file = "charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:31fd66405eaf47bb62e8cd575dc621c56c668f27d46a61d975a249930dd5e2a4"}, {file = "charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:0d3d8f15c07f86e9ff82319b3d9ef6f4bf907608f53fe9d92b28ea9ae3d1fd89"}, {file = "charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:9f7fcd74d410a36883701fafa2482a6af2ff5ba96b9a620e9e0721e28ead5569"}, {file = "charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ebf3e58c7ec8a8bed6d66a75d7fb37b55e5015b03ceae72a8e7c74495551e224"}, {file = "charset_normalizer-3.4.4-cp311-cp311-win32.whl", hash = "sha256:eecbc200c7fd5ddb9a7f16c7decb07b566c29fa2161a16cf67b8d068bd21690a"}, {file = "charset_normalizer-3.4.4-cp311-cp311-win_amd64.whl", hash = "sha256:5ae497466c7901d54b639cf42d5b8c1b6a4fead55215500d2f486d34db48d016"}, {file = "charset_normalizer-3.4.4-cp311-cp311-win_arm64.whl", hash = "sha256:65e2befcd84bc6f37095f5961e68a6f077bf44946771354a28ad434c2cce0ae1"}, {file = "charset_normalizer-3.4.4-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0a98e6759f854bd25a58a73fa88833fba3b7c491169f86ce1180c948ab3fd394"}, {file = "charset_normalizer-3.4.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b5b290ccc2a263e8d185130284f8501e3e36c5e02750fc6b6bdeb2e9e96f1e25"}, {file = "charset_normalizer-3.4.4-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:74bb723680f9f7a6234dcf67aea57e708ec1fbdf5699fb91dfd6f511b0a320ef"}, {file = "charset_normalizer-3.4.4-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f1e34719c6ed0b92f418c7c780480b26b5d9c50349e9a9af7d76bf757530350d"}, {file = "charset_normalizer-3.4.4-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:2437418e20515acec67d86e12bf70056a33abdacb5cb1655042f6538d6b085a8"}, {file = "charset_normalizer-3.4.4-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:11d694519d7f29d6cd09f6ac70028dba10f92f6cdd059096db198c283794ac86"}, {file = "charset_normalizer-3.4.4-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:ac1c4a689edcc530fc9d9aa11f5774b9e2f33f9a0c6a57864e90908f5208d30a"}, {file = "charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:21d142cc6c0ec30d2efee5068ca36c128a30b0f2c53c1c07bd78cb6bc1d3be5f"}, {file = "charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:5dbe56a36425d26d6cfb40ce79c314a2e4dd6211d51d6d2191c00bed34f354cc"}, {file = "charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:5bfbb1b9acf3334612667b61bd3002196fe2a1eb4dd74d247e0f2a4d50ec9bbf"}, {file = "charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:d055ec1e26e441f6187acf818b73564e6e6282709e9bcb5b63f5b23068356a15"}, {file = "charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:af2d8c67d8e573d6de5bc30cdb27e9b95e49115cd9baad5ddbd1a6207aaa82a9"}, {file = "charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:780236ac706e66881f3b7f2f32dfe90507a09e67d1d454c762cf642e6e1586e0"}, {file = "charset_normalizer-3.4.4-cp312-cp312-win32.whl", hash = "sha256:5833d2c39d8896e4e19b689ffc198f08ea58116bee26dea51e362ecc7cd3ed26"}, {file = "charset_normalizer-3.4.4-cp312-cp312-win_amd64.whl", hash = "sha256:a79cfe37875f822425b89a82333404539ae63dbdddf97f84dcbc3d339aae9525"}, {file = "charset_normalizer-3.4.4-cp312-cp312-win_arm64.whl", hash = "sha256:376bec83a63b8021bb5c8ea75e21c4ccb86e7e45ca4eb81146091b56599b80c3"}, {file = "charset_normalizer-3.4.4-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:e1f185f86a6f3403aa2420e815904c67b2f9ebc443f045edd0de921108345794"}, {file = "charset_normalizer-3.4.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6b39f987ae8ccdf0d2642338faf2abb1862340facc796048b604ef14919e55ed"}, {file = "charset_normalizer-3.4.4-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3162d5d8ce1bb98dd51af660f2121c55d0fa541b46dff7bb9b9f86ea1d87de72"}, {file = "charset_normalizer-3.4.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:81d5eb2a312700f4ecaa977a8235b634ce853200e828fbadf3a9c50bab278328"}, {file = "charset_normalizer-3.4.4-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5bd2293095d766545ec1a8f612559f6b40abc0eb18bb2f5d1171872d34036ede"}, {file = "charset_normalizer-3.4.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a8a8b89589086a25749f471e6a900d3f662d1d3b6e2e59dcecf787b1cc3a1894"}, {file = "charset_normalizer-3.4.4-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:bc7637e2f80d8530ee4a78e878bce464f70087ce73cf7c1caf142416923b98f1"}, {file = "charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f8bf04158c6b607d747e93949aa60618b61312fe647a6369f88ce2ff16043490"}, {file = "charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:554af85e960429cf30784dd47447d5125aaa3b99a6f0683589dbd27e2f45da44"}, {file = "charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:74018750915ee7ad843a774364e13a3db91682f26142baddf775342c3f5b1133"}, {file = "charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:c0463276121fdee9c49b98908b3a89c39be45d86d1dbaa22957e38f6321d4ce3"}, {file = "charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:362d61fd13843997c1c446760ef36f240cf81d3ebf74ac62652aebaf7838561e"}, {file = "charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9a26f18905b8dd5d685d6d07b0cdf98a79f3c7a918906af7cc143ea2e164c8bc"}, {file = "charset_normalizer-3.4.4-cp313-cp313-win32.whl", hash = "sha256:9b35f4c90079ff2e2edc5b26c0c77925e5d2d255c42c74fdb70fb49b172726ac"}, {file = "charset_normalizer-3.4.4-cp313-cp313-win_amd64.whl", hash = "sha256:b435cba5f4f750aa6c0a0d92c541fb79f69a387c91e61f1795227e4ed9cece14"}, {file = "charset_normalizer-3.4.4-cp313-cp313-win_arm64.whl", hash = "sha256:542d2cee80be6f80247095cc36c418f7bddd14f4a6de45af91dfad36d817bba2"}, {file = "charset_normalizer-3.4.4-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:da3326d9e65ef63a817ecbcc0df6e94463713b754fe293eaa03da99befb9a5bd"}, {file = "charset_normalizer-3.4.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8af65f14dc14a79b924524b1e7fffe304517b2bff5a58bf64f30b98bbc5079eb"}, {file = "charset_normalizer-3.4.4-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:74664978bb272435107de04e36db5a9735e78232b85b77d45cfb38f758efd33e"}, {file = "charset_normalizer-3.4.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:752944c7ffbfdd10c074dc58ec2d5a8a4cd9493b314d367c14d24c17684ddd14"}, {file = "charset_normalizer-3.4.4-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d1f13550535ad8cff21b8d757a3257963e951d96e20ec82ab44bc64aeb62a191"}, {file = "charset_normalizer-3.4.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ecaae4149d99b1c9e7b88bb03e3221956f68fd6d50be2ef061b2381b61d20838"}, {file = "charset_normalizer-3.4.4-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:cb6254dc36b47a990e59e1068afacdcd02958bdcce30bb50cc1700a8b9d624a6"}, {file = "charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:c8ae8a0f02f57a6e61203a31428fa1d677cbe50c93622b4149d5c0f319c1d19e"}, {file = "charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:47cc91b2f4dd2833fddaedd2893006b0106129d4b94fdb6af1f4ce5a9965577c"}, {file = "charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:82004af6c302b5d3ab2cfc4cc5f29db16123b1a8417f2e25f9066f91d4411090"}, {file = "charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:2b7d8f6c26245217bd2ad053761201e9f9680f8ce52f0fcd8d0755aeae5b2152"}, {file = "charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:799a7a5e4fb2d5898c60b640fd4981d6a25f1c11790935a44ce38c54e985f828"}, {file = "charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:99ae2cffebb06e6c22bdc25801d7b30f503cc87dbd283479e7b606f70aff57ec"}, {file = "charset_normalizer-3.4.4-cp314-cp314-win32.whl", hash = "sha256:f9d332f8c2a2fcbffe1378594431458ddbef721c1769d78e2cbc06280d8155f9"}, {file = "charset_normalizer-3.4.4-cp314-cp314-win_amd64.whl", hash = "sha256:8a6562c3700cce886c5be75ade4a5db4214fda19fede41d9792d100288d8f94c"}, {file = "charset_normalizer-3.4.4-cp314-cp314-win_arm64.whl", hash = "sha256:de00632ca48df9daf77a2c65a484531649261ec9f25489917f09e455cb09ddb2"}, {file = "charset_normalizer-3.4.4-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ce8a0633f41a967713a59c4139d29110c07e826d131a316b50ce11b1d79b4f84"}, {file = "charset_normalizer-3.4.4-cp38-cp38-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:eaabd426fe94daf8fd157c32e571c85cb12e66692f15516a83a03264b08d06c3"}, {file = "charset_normalizer-3.4.4-cp38-cp38-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:c4ef880e27901b6cc782f1b95f82da9313c0eb95c3af699103088fa0ac3ce9ac"}, {file = "charset_normalizer-3.4.4-cp38-cp38-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2aaba3b0819274cc41757a1da876f810a3e4d7b6eb25699253a4effef9e8e4af"}, {file = "charset_normalizer-3.4.4-cp38-cp38-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:778d2e08eda00f4256d7f672ca9fef386071c9202f5e4607920b86d7803387f2"}, {file = "charset_normalizer-3.4.4-cp38-cp38-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f155a433c2ec037d4e8df17d18922c3a0d9b3232a396690f17175d2946f0218d"}, {file = "charset_normalizer-3.4.4-cp38-cp38-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:a8bf8d0f749c5757af2142fe7903a9df1d2e8aa3841559b2bad34b08d0e2bcf3"}, {file = "charset_normalizer-3.4.4-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:194f08cbb32dc406d6e1aea671a68be0823673db2832b38405deba2fb0d88f63"}, {file = "charset_normalizer-3.4.4-cp38-cp38-musllinux_1_2_armv7l.whl", hash = "sha256:6aee717dcfead04c6eb1ce3bd29ac1e22663cdea57f943c87d1eab9a025438d7"}, {file = "charset_normalizer-3.4.4-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:cd4b7ca9984e5e7985c12bc60a6f173f3c958eae74f3ef6624bb6b26e2abbae4"}, {file = "charset_normalizer-3.4.4-cp38-cp38-musllinux_1_2_riscv64.whl", hash = "sha256:b7cf1017d601aa35e6bb650b6ad28652c9cd78ee6caff19f3c28d03e1c80acbf"}, {file = "charset_normalizer-3.4.4-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:e912091979546adf63357d7e2ccff9b44f026c075aeaf25a52d0e95ad2281074"}, {file = "charset_normalizer-3.4.4-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:5cb4d72eea50c8868f5288b7f7f33ed276118325c1dfd3957089f6b519e1382a"}, {file = "charset_normalizer-3.4.4-cp38-cp38-win32.whl", hash = "sha256:837c2ce8c5a65a2035be9b3569c684358dfbf109fd3b6969630a87535495ceaa"}, {file = "charset_normalizer-3.4.4-cp38-cp38-win_amd64.whl", hash = "sha256:44c2a8734b333e0578090c4cd6b16f275e07aa6614ca8715e6c038e865e70576"}, {file = "charset_normalizer-3.4.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:a9768c477b9d7bd54bc0c86dbaebdec6f03306675526c9927c0e8a04e8f94af9"}, {file = "charset_normalizer-3.4.4-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1bee1e43c28aa63cb16e5c14e582580546b08e535299b8b6158a7c9c768a1f3d"}, {file = "charset_normalizer-3.4.4-cp39-cp39-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:fd44c878ea55ba351104cb93cc85e74916eb8fa440ca7903e57575e97394f608"}, {file = "charset_normalizer-3.4.4-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:0f04b14ffe5fdc8c4933862d8306109a2c51e0704acfa35d51598eb45a1e89fc"}, {file = "charset_normalizer-3.4.4-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:cd09d08005f958f370f539f186d10aec3377d55b9eeb0d796025d4886119d76e"}, {file = "charset_normalizer-3.4.4-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4fe7859a4e3e8457458e2ff592f15ccb02f3da787fcd31e0183879c3ad4692a1"}, {file = "charset_normalizer-3.4.4-cp39-cp39-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:fa09f53c465e532f4d3db095e0c55b615f010ad81803d383195b6b5ca6cbf5f3"}, {file = "charset_normalizer-3.4.4-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:7fa17817dc5625de8a027cb8b26d9fefa3ea28c8253929b8d6649e705d2835b6"}, {file = "charset_normalizer-3.4.4-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:5947809c8a2417be3267efc979c47d76a079758166f7d43ef5ae8e9f92751f88"}, {file = "charset_normalizer-3.4.4-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:4902828217069c3c5c71094537a8e623f5d097858ac6ca8252f7b4d10b7560f1"}, {file = "charset_normalizer-3.4.4-cp39-cp39-musllinux_1_2_riscv64.whl", hash = "sha256:7c308f7e26e4363d79df40ca5b2be1c6ba9f02bdbccfed5abddb7859a6ce72cf"}, {file = "charset_normalizer-3.4.4-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:2c9d3c380143a1fedbff95a312aa798578371eb29da42106a29019368a475318"}, {file = "charset_normalizer-3.4.4-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:cb01158d8b88ee68f15949894ccc6712278243d95f344770fa7593fa2d94410c"}, {file = "charset_normalizer-3.4.4-cp39-cp39-win32.whl", hash = "sha256:2677acec1a2f8ef614c6888b5b4ae4060cc184174a938ed4e8ef690e15d3e505"}, {file = "charset_normalizer-3.4.4-cp39-cp39-win_amd64.whl", hash = "sha256:f8e160feb2aed042cd657a72acc0b481212ed28b1b9a95c0cee1621b524e1966"}, {file = "charset_normalizer-3.4.4-cp39-cp39-win_arm64.whl", hash = "sha256:b5d84d37db046c5ca74ee7bb47dd6cbc13f80665fdde3e8040bdd3fb015ecb50"}, {file = "charset_normalizer-3.4.4-py3-none-any.whl", hash = "sha256:7a32c560861a02ff789ad905a2fe94e3f840803362c84fecf1851cb4cf3dc37f"}, {file = "charset_normalizer-3.4.4.tar.gz", hash = "sha256:94537985111c35f28720e43603b8e7b43a6ecfb2ce1d3058bbe955b73404e21a"}, ] [[package]] name = "click" version = "8.3.0" description = "Composable command line interface toolkit" optional = false python-versions = ">=3.10" groups = ["main", "dev", "lsp"] files = [ {file = "click-8.3.0-py3-none-any.whl", hash = "sha256:9b9f285302c6e3064f4330c05f05b81945b2a39544279343e6e7c5f27a9baddc"}, {file = "click-8.3.0.tar.gz", hash = "sha256:e7b8232224eba16f4ebe410c25ced9f7875cb5f3263ffc93cc3e8da705e229c4"}, ] [package.dependencies] colorama = {version = "*", markers = "platform_system == \"Windows\""} [[package]] name = "colorama" version = "0.4.6" description = "Cross-platform colored terminal text." optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" groups = ["main", "dev", "docs", "lsp", "test"] files = [ {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, ] markers = {main = "platform_system == \"Windows\"", docs = "sys_platform == \"win32\"", lsp = "platform_system == \"Windows\"", test = "sys_platform == \"win32\""} [[package]] name = "coverage" version = "7.11.0" description = "Code coverage measurement for Python" optional = false python-versions = ">=3.10" groups = ["test"] files = [ {file = "coverage-7.11.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:eb53f1e8adeeb2e78962bade0c08bfdc461853c7969706ed901821e009b35e31"}, {file = "coverage-7.11.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d9a03ec6cb9f40a5c360f138b88266fd8f58408d71e89f536b4f91d85721d075"}, {file = "coverage-7.11.0-cp310-cp310-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:0d7f0616c557cbc3d1c2090334eddcbb70e1ae3a40b07222d62b3aa47f608fab"}, {file = "coverage-7.11.0-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:e44a86a47bbdf83b0a3ea4d7df5410d6b1a0de984fbd805fa5101f3624b9abe0"}, {file = "coverage-7.11.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:596763d2f9a0ee7eec6e643e29660def2eef297e1de0d334c78c08706f1cb785"}, {file = "coverage-7.11.0-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:ef55537ff511b5e0a43edb4c50a7bf7ba1c3eea20b4f49b1490f1e8e0e42c591"}, {file = "coverage-7.11.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:9cbabd8f4d0d3dc571d77ae5bdbfa6afe5061e679a9d74b6797c48d143307088"}, {file = "coverage-7.11.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e24045453384e0ae2a587d562df2a04d852672eb63051d16096d3f08aa4c7c2f"}, {file = "coverage-7.11.0-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:7161edd3426c8d19bdccde7d49e6f27f748f3c31cc350c5de7c633fea445d866"}, {file = "coverage-7.11.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:3d4ed4de17e692ba6415b0587bc7f12bc80915031fc9db46a23ce70fc88c9841"}, {file = "coverage-7.11.0-cp310-cp310-win32.whl", hash = "sha256:765c0bc8fe46f48e341ef737c91c715bd2a53a12792592296a095f0c237e09cf"}, {file = "coverage-7.11.0-cp310-cp310-win_amd64.whl", hash = "sha256:24d6f3128f1b2d20d84b24f4074475457faedc3d4613a7e66b5e769939c7d969"}, {file = "coverage-7.11.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3d58ecaa865c5b9fa56e35efc51d1014d4c0d22838815b9fce57a27dd9576847"}, {file = "coverage-7.11.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b679e171f1c104a5668550ada700e3c4937110dbdd153b7ef9055c4f1a1ee3cc"}, {file = "coverage-7.11.0-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:ca61691ba8c5b6797deb221a0d09d7470364733ea9c69425a640f1f01b7c5bf0"}, {file = "coverage-7.11.0-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:aef1747ede4bd8ca9cfc04cc3011516500c6891f1b33a94add3253f6f876b7b7"}, {file = "coverage-7.11.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a1839d08406e4cba2953dcc0ffb312252f14d7c4c96919f70167611f4dee2623"}, {file = "coverage-7.11.0-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e0eb0a2dcc62478eb5b4cbb80b97bdee852d7e280b90e81f11b407d0b81c4287"}, {file = "coverage-7.11.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:bc1fbea96343b53f65d5351d8fd3b34fd415a2670d7c300b06d3e14a5af4f552"}, {file = "coverage-7.11.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:214b622259dd0cf435f10241f1333d32caa64dbc27f8790ab693428a141723de"}, {file = "coverage-7.11.0-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:258d9967520cca899695d4eb7ea38be03f06951d6ca2f21fb48b1235f791e601"}, {file = "coverage-7.11.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:cf9e6ff4ca908ca15c157c409d608da77a56a09877b97c889b98fb2c32b6465e"}, {file = "coverage-7.11.0-cp311-cp311-win32.whl", hash = "sha256:fcc15fc462707b0680cff6242c48625da7f9a16a28a41bb8fd7a4280920e676c"}, {file = "coverage-7.11.0-cp311-cp311-win_amd64.whl", hash = "sha256:865965bf955d92790f1facd64fe7ff73551bd2c1e7e6b26443934e9701ba30b9"}, {file = "coverage-7.11.0-cp311-cp311-win_arm64.whl", hash = "sha256:5693e57a065760dcbeb292d60cc4d0231a6d4b6b6f6a3191561e1d5e8820b745"}, {file = "coverage-7.11.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:9c49e77811cf9d024b95faf86c3f059b11c0c9be0b0d61bc598f453703bd6fd1"}, {file = "coverage-7.11.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a61e37a403a778e2cda2a6a39abcc895f1d984071942a41074b5c7ee31642007"}, {file = "coverage-7.11.0-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:c79cae102bb3b1801e2ef1511fb50e91ec83a1ce466b2c7c25010d884336de46"}, {file = "coverage-7.11.0-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:16ce17ceb5d211f320b62df002fa7016b7442ea0fd260c11cec8ce7730954893"}, {file = "coverage-7.11.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:80027673e9d0bd6aef86134b0771845e2da85755cf686e7c7c59566cf5a89115"}, {file = "coverage-7.11.0-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:4d3ffa07a08657306cd2215b0da53761c4d73cb54d9143b9303a6481ec0cd415"}, {file = "coverage-7.11.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:a3b6a5f8b2524fd6c1066bc85bfd97e78709bb5e37b5b94911a6506b65f47186"}, {file = "coverage-7.11.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:fcc0a4aa589de34bc56e1a80a740ee0f8c47611bdfb28cd1849de60660f3799d"}, {file = "coverage-7.11.0-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:dba82204769d78c3fd31b35c3d5f46e06511936c5019c39f98320e05b08f794d"}, {file = "coverage-7.11.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:81b335f03ba67309a95210caf3eb43bd6fe75a4e22ba653ef97b4696c56c7ec2"}, {file = "coverage-7.11.0-cp312-cp312-win32.whl", hash = "sha256:037b2d064c2f8cc8716fe4d39cb705779af3fbf1ba318dc96a1af858888c7bb5"}, {file = "coverage-7.11.0-cp312-cp312-win_amd64.whl", hash = "sha256:d66c0104aec3b75e5fd897e7940188ea1892ca1d0235316bf89286d6a22568c0"}, {file = "coverage-7.11.0-cp312-cp312-win_arm64.whl", hash = "sha256:d91ebeac603812a09cf6a886ba6e464f3bbb367411904ae3790dfe28311b15ad"}, {file = "coverage-7.11.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:cc3f49e65ea6e0d5d9bd60368684fe52a704d46f9e7fc413918f18d046ec40e1"}, {file = "coverage-7.11.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f39ae2f63f37472c17b4990f794035c9890418b1b8cca75c01193f3c8d3e01be"}, {file = "coverage-7.11.0-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:7db53b5cdd2917b6eaadd0b1251cf4e7d96f4a8d24e174bdbdf2f65b5ea7994d"}, {file = "coverage-7.11.0-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:10ad04ac3a122048688387828b4537bc9cf60c0bf4869c1e9989c46e45690b82"}, {file = "coverage-7.11.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4036cc9c7983a2b1f2556d574d2eb2154ac6ed55114761685657e38782b23f52"}, {file = "coverage-7.11.0-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:7ab934dd13b1c5e94b692b1e01bd87e4488cb746e3a50f798cb9464fd128374b"}, {file = "coverage-7.11.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:59a6e5a265f7cfc05f76e3bb53eca2e0dfe90f05e07e849930fecd6abb8f40b4"}, {file = "coverage-7.11.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:df01d6c4c81e15a7c88337b795bb7595a8596e92310266b5072c7e301168efbd"}, {file = "coverage-7.11.0-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:8c934bd088eed6174210942761e38ee81d28c46de0132ebb1801dbe36a390dcc"}, {file = "coverage-7.11.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5a03eaf7ec24078ad64a07f02e30060aaf22b91dedf31a6b24d0d98d2bba7f48"}, {file = "coverage-7.11.0-cp313-cp313-win32.whl", hash = "sha256:695340f698a5f56f795b2836abe6fb576e7c53d48cd155ad2f80fd24bc63a040"}, {file = "coverage-7.11.0-cp313-cp313-win_amd64.whl", hash = "sha256:2727d47fce3ee2bac648528e41455d1b0c46395a087a229deac75e9f88ba5a05"}, {file = "coverage-7.11.0-cp313-cp313-win_arm64.whl", hash = "sha256:0efa742f431529699712b92ecdf22de8ff198df41e43aeaaadf69973eb93f17a"}, {file = "coverage-7.11.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:587c38849b853b157706407e9ebdca8fd12f45869edb56defbef2daa5fb0812b"}, {file = "coverage-7.11.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:b971bdefdd75096163dd4261c74be813c4508477e39ff7b92191dea19f24cd37"}, {file = "coverage-7.11.0-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:269bfe913b7d5be12ab13a95f3a76da23cf147be7fa043933320ba5625f0a8de"}, {file = "coverage-7.11.0-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:dadbcce51a10c07b7c72b0ce4a25e4b6dcb0c0372846afb8e5b6307a121eb99f"}, {file = "coverage-7.11.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9ed43fa22c6436f7957df036331f8fe4efa7af132054e1844918866cd228af6c"}, {file = "coverage-7.11.0-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:9516add7256b6713ec08359b7b05aeff8850c98d357784c7205b2e60aa2513fa"}, {file = "coverage-7.11.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:eb92e47c92fcbcdc692f428da67db33337fa213756f7adb6a011f7b5a7a20740"}, {file = "coverage-7.11.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:d06f4fc7acf3cabd6d74941d53329e06bab00a8fe10e4df2714f0b134bfc64ef"}, {file = "coverage-7.11.0-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:6fbcee1a8f056af07ecd344482f711f563a9eb1c2cad192e87df00338ec3cdb0"}, {file = "coverage-7.11.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:dbbf012be5f32533a490709ad597ad8a8ff80c582a95adc8d62af664e532f9ca"}, {file = "coverage-7.11.0-cp313-cp313t-win32.whl", hash = "sha256:cee6291bb4fed184f1c2b663606a115c743df98a537c969c3c64b49989da96c2"}, {file = "coverage-7.11.0-cp313-cp313t-win_amd64.whl", hash = "sha256:a386c1061bf98e7ea4758e4313c0ab5ecf57af341ef0f43a0bf26c2477b5c268"}, {file = "coverage-7.11.0-cp313-cp313t-win_arm64.whl", hash = "sha256:f9ea02ef40bb83823b2b04964459d281688fe173e20643870bb5d2edf68bc836"}, {file = "coverage-7.11.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:c770885b28fb399aaf2a65bbd1c12bf6f307ffd112d6a76c5231a94276f0c497"}, {file = "coverage-7.11.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:a3d0e2087dba64c86a6b254f43e12d264b636a39e88c5cc0a01a7c71bcfdab7e"}, {file = "coverage-7.11.0-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:73feb83bb41c32811973b8565f3705caf01d928d972b72042b44e97c71fd70d1"}, {file = "coverage-7.11.0-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:c6f31f281012235ad08f9a560976cc2fc9c95c17604ff3ab20120fe480169bca"}, {file = "coverage-7.11.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e9570ad567f880ef675673992222746a124b9595506826b210fbe0ce3f0499cd"}, {file = "coverage-7.11.0-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:8badf70446042553a773547a61fecaa734b55dc738cacf20c56ab04b77425e43"}, {file = "coverage-7.11.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:a09c1211959903a479e389685b7feb8a17f59ec5a4ef9afde7650bd5eabc2777"}, {file = "coverage-7.11.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:5ef83b107f50db3f9ae40f69e34b3bd9337456c5a7fe3461c7abf8b75dd666a2"}, {file = "coverage-7.11.0-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:f91f927a3215b8907e214af77200250bb6aae36eca3f760f89780d13e495388d"}, {file = "coverage-7.11.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:cdbcd376716d6b7fbfeedd687a6c4be019c5a5671b35f804ba76a4c0a778cba4"}, {file = "coverage-7.11.0-cp314-cp314-win32.whl", hash = "sha256:bab7ec4bb501743edc63609320aaec8cd9188b396354f482f4de4d40a9d10721"}, {file = "coverage-7.11.0-cp314-cp314-win_amd64.whl", hash = "sha256:3d4ba9a449e9364a936a27322b20d32d8b166553bfe63059bd21527e681e2fad"}, {file = "coverage-7.11.0-cp314-cp314-win_arm64.whl", hash = "sha256:ce37f215223af94ef0f75ac68ea096f9f8e8c8ec7d6e8c346ee45c0d363f0479"}, {file = "coverage-7.11.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:f413ce6e07e0d0dc9c433228727b619871532674b45165abafe201f200cc215f"}, {file = "coverage-7.11.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:05791e528a18f7072bf5998ba772fe29db4da1234c45c2087866b5ba4dea710e"}, {file = "coverage-7.11.0-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:cacb29f420cfeb9283b803263c3b9a068924474ff19ca126ba9103e1278dfa44"}, {file = "coverage-7.11.0-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:314c24e700d7027ae3ab0d95fbf8d53544fca1f20345fd30cd219b737c6e58d3"}, {file = "coverage-7.11.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:630d0bd7a293ad2fc8b4b94e5758c8b2536fdf36c05f1681270203e463cbfa9b"}, {file = "coverage-7.11.0-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e89641f5175d65e2dbb44db15fe4ea48fade5d5bbb9868fdc2b4fce22f4a469d"}, {file = "coverage-7.11.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:c9f08ea03114a637dab06cedb2e914da9dc67fa52c6015c018ff43fdde25b9c2"}, {file = "coverage-7.11.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:ce9f3bde4e9b031eaf1eb61df95c1401427029ea1bfddb8621c1161dcb0fa02e"}, {file = "coverage-7.11.0-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:e4dc07e95495923d6fd4d6c27bf70769425b71c89053083843fd78f378558996"}, {file = "coverage-7.11.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:424538266794db2861db4922b05d729ade0940ee69dcf0591ce8f69784db0e11"}, {file = "coverage-7.11.0-cp314-cp314t-win32.whl", hash = "sha256:4c1eeb3fb8eb9e0190bebafd0462936f75717687117339f708f395fe455acc73"}, {file = "coverage-7.11.0-cp314-cp314t-win_amd64.whl", hash = "sha256:b56efee146c98dbf2cf5cffc61b9829d1e94442df4d7398b26892a53992d3547"}, {file = "coverage-7.11.0-cp314-cp314t-win_arm64.whl", hash = "sha256:b5c2705afa83f49bd91962a4094b6b082f94aef7626365ab3f8f4bd159c5acf3"}, {file = "coverage-7.11.0-py3-none-any.whl", hash = "sha256:4b7589765348d78fb4e5fb6ea35d07564e387da2fc5efff62e0222971f155f68"}, {file = "coverage-7.11.0.tar.gz", hash = "sha256:167bd504ac1ca2af7ff3b81d245dfea0292c5032ebef9d66cc08a7d28c1b8050"}, ] [package.dependencies] tomli = {version = "*", optional = true, markers = "python_full_version <= \"3.11.0a6\" and extra == \"toml\""} [package.extras] toml = ["tomli ; python_full_version <= \"3.11.0a6\""] [[package]] name = "dill" version = "0.4.0" description = "serialize all of Python" optional = false python-versions = ">=3.8" groups = ["dev"] files = [ {file = "dill-0.4.0-py3-none-any.whl", hash = "sha256:44f54bf6412c2c8464c14e8243eb163690a9800dbe2c367330883b19c7561049"}, {file = "dill-0.4.0.tar.gz", hash = "sha256:0633f1d2df477324f53a895b02c901fb961bdbf65a17122586ea7019292cbcf0"}, ] [package.extras] graph = ["objgraph (>=1.7.2)"] profile = ["gprof2dot (>=2022.7.29)"] [[package]] name = "distlib" version = "0.4.0" description = "Distribution utilities" optional = false python-versions = "*" groups = ["dev"] files = [ {file = "distlib-0.4.0-py2.py3-none-any.whl", hash = "sha256:9659f7d87e46584a30b5780e43ac7a2143098441670ff0a49d5f9034c54a6c16"}, {file = "distlib-0.4.0.tar.gz", hash = "sha256:feec40075be03a04501a973d81f633735b4b69f98b05450592310c0f401a4e0d"}, ] [[package]] name = "docstring-to-markdown" version = "0.17" description = "On the fly conversion of Python docstrings to markdown" optional = false python-versions = ">=3.7" groups = ["lsp"] files = [ {file = "docstring_to_markdown-0.17-py3-none-any.whl", hash = "sha256:fd7d5094aa83943bf5f9e1a13701866b7c452eac19765380dead666e36d3711c"}, {file = "docstring_to_markdown-0.17.tar.gz", hash = "sha256:df72a112294c7492487c9da2451cae0faeee06e86008245c188c5761c9590ca3"}, ] [package.dependencies] importlib-metadata = ">=3.6" typing_extensions = ">=4.6" [[package]] name = "docutils" version = "0.21.2" description = "Docutils -- Python Documentation Utilities" optional = false python-versions = ">=3.9" groups = ["docs"] files = [ {file = "docutils-0.21.2-py3-none-any.whl", hash = "sha256:dafca5b9e384f0e419294eb4d2ff9fa826435bf15f15b7bd45723e8ad76811b2"}, {file = "docutils-0.21.2.tar.gz", hash = "sha256:3a6b18732edf182daa3cd12775bbb338cf5691468f91eeeb109deff6ebfa986f"}, ] [[package]] name = "exceptiongroup" version = "1.3.0" description = "Backport of PEP 654 (exception groups)" optional = false python-versions = ">=3.7" groups = ["test"] markers = "python_version == \"3.10\"" files = [ {file = "exceptiongroup-1.3.0-py3-none-any.whl", hash = "sha256:4d111e6e0c13d0644cad6ddaa7ed0261a0b36971f6d23e7ec9b4b9097da78a10"}, {file = "exceptiongroup-1.3.0.tar.gz", hash = "sha256:b241f5885f560bc56a59ee63ca4c6a8bfa46ae4ad651af316d4e81817bb9fd88"}, ] [package.dependencies] typing-extensions = {version = ">=4.6.0", markers = "python_version < \"3.13\""} [package.extras] test = ["pytest (>=6)"] [[package]] name = "file-magic" version = "0.4.1" description = "Python front end for libmagic(3)" optional = true python-versions = ">=2.7" groups = ["main"] markers = "extra == \"file-magic\"" files = [ {file = "file-magic-0.4.1.tar.gz", hash = "sha256:a91d1483117f7ed48cd0238ad9be36b04824d57e9c38ea7523113989e81b9c53"}, {file = "file_magic-0.4.1-py3-none-any.whl", hash = "sha256:cb9496a1656baf75cadd771479f63b53081095e968d0be72b9b7a7ed538e4fb8"}, ] [[package]] name = "filelock" version = "3.20.0" description = "A platform independent file lock." optional = false python-versions = ">=3.10" groups = ["dev"] files = [ {file = "filelock-3.20.0-py3-none-any.whl", hash = "sha256:339b4732ffda5cd79b13f4e2711a31b0365ce445d95d243bb996273d072546a2"}, {file = "filelock-3.20.0.tar.gz", hash = "sha256:711e943b4ec6be42e1d4e6690b48dc175c822967466bb31c0c293f34334c13f4"}, ] [[package]] name = "freezegun" version = "1.5.5" description = "Let your Python tests travel through time" optional = false python-versions = ">=3.8" groups = ["test"] files = [ {file = "freezegun-1.5.5-py3-none-any.whl", hash = "sha256:cd557f4a75cf074e84bc374249b9dd491eaeacd61376b9eb3c423282211619d2"}, {file = "freezegun-1.5.5.tar.gz", hash = "sha256:ac7742a6cc6c25a2c35e9292dfd554b897b517d2dec26891a2e8debf205cb94a"}, ] [package.dependencies] python-dateutil = ">=2.7" [[package]] name = "furo" version = "2025.9.25" description = "A clean customisable Sphinx documentation theme." optional = false python-versions = ">=3.8" groups = ["docs"] files = [ {file = "furo-2025.9.25-py3-none-any.whl", hash = "sha256:2937f68e823b8e37b410c972c371bc2b1d88026709534927158e0cb3fac95afe"}, {file = "furo-2025.9.25.tar.gz", hash = "sha256:3eac05582768fdbbc2bdfa1cdbcdd5d33cfc8b4bd2051729ff4e026a1d7e0a98"}, ] [package.dependencies] accessible-pygments = ">=0.0.5" beautifulsoup4 = "*" pygments = ">=2.7" sphinx = ">=6.0,<9.0" sphinx-basic-ng = ">=1.0.0.beta2" [[package]] name = "gitdb" version = "4.0.12" description = "Git Object Database" optional = false python-versions = ">=3.7" groups = ["dev"] files = [ {file = "gitdb-4.0.12-py3-none-any.whl", hash = "sha256:67073e15955400952c6565cc3e707c554a4eea2e428946f7a4c162fab9bd9bcf"}, {file = "gitdb-4.0.12.tar.gz", hash = "sha256:5ef71f855d191a3326fcfbc0d5da835f26b13fbcba60c32c21091c349ffdb571"}, ] [package.dependencies] smmap = ">=3.0.1,<6" [[package]] name = "gitpython" version = "3.1.45" description = "GitPython is a Python library used to interact with Git repositories" optional = false python-versions = ">=3.7" groups = ["dev"] files = [ {file = "gitpython-3.1.45-py3-none-any.whl", hash = "sha256:8908cb2e02fb3b93b7eb0f2827125cb699869470432cc885f019b8fd0fccff77"}, {file = "gitpython-3.1.45.tar.gz", hash = "sha256:85b0ee964ceddf211c41b9f27a49086010a190fd8132a24e21f362a4b36a791c"}, ] [package.dependencies] gitdb = ">=4.0.1,<5" [package.extras] doc = ["sphinx (>=7.1.2,<7.2)", "sphinx-autodoc-typehints", "sphinx_rtd_theme"] test = ["coverage[toml]", "ddt (>=1.1.1,!=1.4.3)", "mock ; python_version < \"3.8\"", "mypy", "pre-commit", "pytest (>=7.3.1)", "pytest-cov", "pytest-instafail", "pytest-mock", "pytest-sugar", "typing-extensions ; python_version < \"3.11\""] [[package]] name = "identify" version = "2.6.15" description = "File identification library for Python" optional = false python-versions = ">=3.9" groups = ["dev"] files = [ {file = "identify-2.6.15-py2.py3-none-any.whl", hash = "sha256:1181ef7608e00704db228516541eb83a88a9f94433a8c80bb9b5bd54b1d81757"}, {file = "identify-2.6.15.tar.gz", hash = "sha256:e4f4864b96c6557ef2a1e1c951771838f4edc9df3a72ec7118b338801b11c7bf"}, ] [package.extras] license = ["ukkonen"] [[package]] name = "idna" version = "3.11" description = "Internationalized Domain Names in Applications (IDNA)" optional = false python-versions = ">=3.8" groups = ["docs"] files = [ {file = "idna-3.11-py3-none-any.whl", hash = "sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea"}, {file = "idna-3.11.tar.gz", hash = "sha256:795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902"}, ] [package.extras] all = ["flake8 (>=7.1.1)", "mypy (>=1.11.2)", "pytest (>=8.3.2)", "ruff (>=0.6.2)"] [[package]] name = "imagesize" version = "1.4.1" description = "Getting image size from png/jpeg/jpeg2000/gif file" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" groups = ["docs"] 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.7.0" description = "Read metadata from Python packages" optional = false python-versions = ">=3.9" groups = ["lsp"] files = [ {file = "importlib_metadata-8.7.0-py3-none-any.whl", hash = "sha256:e5dd1551894c77868a30651cef00984d50e1002d06942a7101d34870c5f02afd"}, {file = "importlib_metadata-8.7.0.tar.gz", hash = "sha256:d13b81ad223b890aa16c5471f2ac3056cf76c5f10f82d6f9292f0b415f389000"}, ] [package.dependencies] zipp = ">=3.20" [package.extras] check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1) ; sys_platform != \"cygwin\""] cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] enabler = ["pytest-enabler (>=2.2)"] perf = ["ipython"] test = ["flufl.flake8", "importlib_resources (>=1.3) ; python_version < \"3.9\"", "jaraco.test (>=5.4)", "packaging", "pyfakefs", "pytest (>=6,!=8.1.*)", "pytest-perf (>=0.9.2)"] type = ["pytest-mypy"] [[package]] name = "iniconfig" version = "2.3.0" description = "brain-dead simple config-ini parsing" optional = false python-versions = ">=3.10" groups = ["test"] files = [ {file = "iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12"}, {file = "iniconfig-2.3.0.tar.gz", hash = "sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730"}, ] [[package]] name = "isort" version = "7.0.0" description = "A Python utility / library to sort Python imports." optional = false python-versions = ">=3.10.0" groups = ["dev", "lsp"] files = [ {file = "isort-7.0.0-py3-none-any.whl", hash = "sha256:1bcabac8bc3c36c7fb7b98a76c8abb18e0f841a3ba81decac7691008592499c1"}, {file = "isort-7.0.0.tar.gz", hash = "sha256:5513527951aadb3ac4292a41a16cbc50dd1642432f5e8c20057d414bdafb4187"}, ] [package.extras] colors = ["colorama"] plugins = ["setuptools"] [[package]] name = "jedi" version = "0.19.2" description = "An autocompletion tool for Python that can be used for text editors." optional = false python-versions = ">=3.6" groups = ["lsp"] files = [ {file = "jedi-0.19.2-py2.py3-none-any.whl", hash = "sha256:a8ef22bde8490f57fe5c7681a3c83cb58874daf72b4784de3cce5b6ef6edb5b9"}, {file = "jedi-0.19.2.tar.gz", hash = "sha256:4770dc3de41bde3966b02eb84fbcf557fb33cce26ad23da12c742fb50ecb11f0"}, ] [package.dependencies] parso = ">=0.8.4,<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 (<9.0.0)"] [[package]] name = "jinja2" version = "3.1.6" description = "A very fast and expressive template engine." optional = false python-versions = ">=3.7" groups = ["main", "docs"] files = [ {file = "jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67"}, {file = "jinja2-3.1.6.tar.gz", hash = "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d"}, ] [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." optional = false python-versions = ">=2.7" groups = ["dev"] 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.4.4" description = "license-expression is a comprehensive utility library to parse, compare, simplify and normalize license expressions (such as SPDX license expressions) using boolean logic." optional = false python-versions = ">=3.9" groups = ["main"] files = [ {file = "license_expression-30.4.4-py3-none-any.whl", hash = "sha256:421788fdcadb41f049d2dc934ce666626265aeccefddd25e162a26f23bcbf8a4"}, {file = "license_expression-30.4.4.tar.gz", hash = "sha256:73448f0aacd8d0808895bdc4b2c8e01a8d67646e4188f887375398c761f340fd"}, ] [package.dependencies] "boolean.py" = ">=4.0" [package.extras] dev = ["Sphinx (>=5.0.2)", "doc8 (>=0.11.2)", "pytest (>=7.0.1)", "pytest-xdist (>=2)", "ruff", "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)", "twine"] [[package]] name = "markdown-it-py" version = "3.0.0" description = "Python port of markdown-it. Markdown parsing, done right!" optional = false python-versions = ">=3.8" groups = ["docs"] 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 = "3.0.3" description = "Safely add untrusted strings to HTML/XML markup." optional = false python-versions = ">=3.9" groups = ["main", "docs"] files = [ {file = "markupsafe-3.0.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2f981d352f04553a7171b8e44369f2af4055f888dfb147d55e42d29e29e74559"}, {file = "markupsafe-3.0.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e1c1493fb6e50ab01d20a22826e57520f1284df32f2d8601fdd90b6304601419"}, {file = "markupsafe-3.0.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1ba88449deb3de88bd40044603fafffb7bc2b055d626a330323a9ed736661695"}, {file = "markupsafe-3.0.3-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f42d0984e947b8adf7dd6dde396e720934d12c506ce84eea8476409563607591"}, {file = "markupsafe-3.0.3-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:c0c0b3ade1c0b13b936d7970b1d37a57acde9199dc2aecc4c336773e1d86049c"}, {file = "markupsafe-3.0.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:0303439a41979d9e74d18ff5e2dd8c43ed6c6001fd40e5bf2e43f7bd9bbc523f"}, {file = "markupsafe-3.0.3-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:d2ee202e79d8ed691ceebae8e0486bd9a2cd4794cec4824e1c99b6f5009502f6"}, {file = "markupsafe-3.0.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:177b5253b2834fe3678cb4a5f0059808258584c559193998be2601324fdeafb1"}, {file = "markupsafe-3.0.3-cp310-cp310-win32.whl", hash = "sha256:2a15a08b17dd94c53a1da0438822d70ebcd13f8c3a95abe3a9ef9f11a94830aa"}, {file = "markupsafe-3.0.3-cp310-cp310-win_amd64.whl", hash = "sha256:c4ffb7ebf07cfe8931028e3e4c85f0357459a3f9f9490886198848f4fa002ec8"}, {file = "markupsafe-3.0.3-cp310-cp310-win_arm64.whl", hash = "sha256:e2103a929dfa2fcaf9bb4e7c091983a49c9ac3b19c9061b6d5427dd7d14d81a1"}, {file = "markupsafe-3.0.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1cc7ea17a6824959616c525620e387f6dd30fec8cb44f649e31712db02123dad"}, {file = "markupsafe-3.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4bd4cd07944443f5a265608cc6aab442e4f74dff8088b0dfc8238647b8f6ae9a"}, {file = "markupsafe-3.0.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6b5420a1d9450023228968e7e6a9ce57f65d148ab56d2313fcd589eee96a7a50"}, {file = "markupsafe-3.0.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0bf2a864d67e76e5c9a34dc26ec616a66b9888e25e7b9460e1c76d3293bd9dbf"}, {file = "markupsafe-3.0.3-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:bc51efed119bc9cfdf792cdeaa4d67e8f6fcccab66ed4bfdd6bde3e59bfcbb2f"}, {file = "markupsafe-3.0.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:068f375c472b3e7acbe2d5318dea141359e6900156b5b2ba06a30b169086b91a"}, {file = "markupsafe-3.0.3-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:7be7b61bb172e1ed687f1754f8e7484f1c8019780f6f6b0786e76bb01c2ae115"}, {file = "markupsafe-3.0.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f9e130248f4462aaa8e2552d547f36ddadbeaa573879158d721bbd33dfe4743a"}, {file = "markupsafe-3.0.3-cp311-cp311-win32.whl", hash = "sha256:0db14f5dafddbb6d9208827849fad01f1a2609380add406671a26386cdf15a19"}, {file = "markupsafe-3.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:de8a88e63464af587c950061a5e6a67d3632e36df62b986892331d4620a35c01"}, {file = "markupsafe-3.0.3-cp311-cp311-win_arm64.whl", hash = "sha256:3b562dd9e9ea93f13d53989d23a7e775fdfd1066c33494ff43f5418bc8c58a5c"}, {file = "markupsafe-3.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d53197da72cc091b024dd97249dfc7794d6a56530370992a5e1a08983ad9230e"}, {file = "markupsafe-3.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1872df69a4de6aead3491198eaf13810b565bdbeec3ae2dc8780f14458ec73ce"}, {file = "markupsafe-3.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3a7e8ae81ae39e62a41ec302f972ba6ae23a5c5396c8e60113e9066ef893da0d"}, {file = "markupsafe-3.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d6dd0be5b5b189d31db7cda48b91d7e0a9795f31430b7f271219ab30f1d3ac9d"}, {file = "markupsafe-3.0.3-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:94c6f0bb423f739146aec64595853541634bde58b2135f27f61c1ffd1cd4d16a"}, {file = "markupsafe-3.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:be8813b57049a7dc738189df53d69395eba14fb99345e0a5994914a3864c8a4b"}, {file = "markupsafe-3.0.3-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:83891d0e9fb81a825d9a6d61e3f07550ca70a076484292a70fde82c4b807286f"}, {file = "markupsafe-3.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:77f0643abe7495da77fb436f50f8dab76dbc6e5fd25d39589a0f1fe6548bfa2b"}, {file = "markupsafe-3.0.3-cp312-cp312-win32.whl", hash = "sha256:d88b440e37a16e651bda4c7c2b930eb586fd15ca7406cb39e211fcff3bf3017d"}, {file = "markupsafe-3.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:26a5784ded40c9e318cfc2bdb30fe164bdb8665ded9cd64d500a34fb42067b1c"}, {file = "markupsafe-3.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:35add3b638a5d900e807944a078b51922212fb3dedb01633a8defc4b01a3c85f"}, {file = "markupsafe-3.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e1cf1972137e83c5d4c136c43ced9ac51d0e124706ee1c8aa8532c1287fa8795"}, {file = "markupsafe-3.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:116bb52f642a37c115f517494ea5feb03889e04df47eeff5b130b1808ce7c219"}, {file = "markupsafe-3.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:133a43e73a802c5562be9bbcd03d090aa5a1fe899db609c29e8c8d815c5f6de6"}, {file = "markupsafe-3.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ccfcd093f13f0f0b7fdd0f198b90053bf7b2f02a3927a30e63f3ccc9df56b676"}, {file = "markupsafe-3.0.3-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:509fa21c6deb7a7a273d629cf5ec029bc209d1a51178615ddf718f5918992ab9"}, {file = "markupsafe-3.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a4afe79fb3de0b7097d81da19090f4df4f8d3a2b3adaa8764138aac2e44f3af1"}, {file = "markupsafe-3.0.3-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:795e7751525cae078558e679d646ae45574b47ed6e7771863fcc079a6171a0fc"}, {file = "markupsafe-3.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8485f406a96febb5140bfeca44a73e3ce5116b2501ac54fe953e488fb1d03b12"}, {file = "markupsafe-3.0.3-cp313-cp313-win32.whl", hash = "sha256:bdd37121970bfd8be76c5fb069c7751683bdf373db1ed6c010162b2a130248ed"}, {file = "markupsafe-3.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:9a1abfdc021a164803f4d485104931fb8f8c1efd55bc6b748d2f5774e78b62c5"}, {file = "markupsafe-3.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:7e68f88e5b8799aa49c85cd116c932a1ac15caaa3f5db09087854d218359e485"}, {file = "markupsafe-3.0.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:218551f6df4868a8d527e3062d0fb968682fe92054e89978594c28e642c43a73"}, {file = "markupsafe-3.0.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:3524b778fe5cfb3452a09d31e7b5adefeea8c5be1d43c4f810ba09f2ceb29d37"}, {file = "markupsafe-3.0.3-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4e885a3d1efa2eadc93c894a21770e4bc67899e3543680313b09f139e149ab19"}, {file = "markupsafe-3.0.3-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8709b08f4a89aa7586de0aadc8da56180242ee0ada3999749b183aa23df95025"}, {file = "markupsafe-3.0.3-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:b8512a91625c9b3da6f127803b166b629725e68af71f8184ae7e7d54686a56d6"}, {file = "markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9b79b7a16f7fedff2495d684f2b59b0457c3b493778c9eed31111be64d58279f"}, {file = "markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:12c63dfb4a98206f045aa9563db46507995f7ef6d83b2f68eda65c307c6829eb"}, {file = "markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:8f71bc33915be5186016f675cd83a1e08523649b0e33efdb898db577ef5bb009"}, {file = "markupsafe-3.0.3-cp313-cp313t-win32.whl", hash = "sha256:69c0b73548bc525c8cb9a251cddf1931d1db4d2258e9599c28c07ef3580ef354"}, {file = "markupsafe-3.0.3-cp313-cp313t-win_amd64.whl", hash = "sha256:1b4b79e8ebf6b55351f0d91fe80f893b4743f104bff22e90697db1590e47a218"}, {file = "markupsafe-3.0.3-cp313-cp313t-win_arm64.whl", hash = "sha256:ad2cf8aa28b8c020ab2fc8287b0f823d0a7d8630784c31e9ee5edea20f406287"}, {file = "markupsafe-3.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:eaa9599de571d72e2daf60164784109f19978b327a3910d3e9de8c97b5b70cfe"}, {file = "markupsafe-3.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c47a551199eb8eb2121d4f0f15ae0f923d31350ab9280078d1e5f12b249e0026"}, {file = "markupsafe-3.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f34c41761022dd093b4b6896d4810782ffbabe30f2d443ff5f083e0cbbb8c737"}, {file = "markupsafe-3.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:457a69a9577064c05a97c41f4e65148652db078a3a509039e64d3467b9e7ef97"}, {file = "markupsafe-3.0.3-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e8afc3f2ccfa24215f8cb28dcf43f0113ac3c37c2f0f0806d8c70e4228c5cf4d"}, {file = "markupsafe-3.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ec15a59cf5af7be74194f7ab02d0f59a62bdcf1a537677ce67a2537c9b87fcda"}, {file = "markupsafe-3.0.3-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:0eb9ff8191e8498cca014656ae6b8d61f39da5f95b488805da4bb029cccbfbaf"}, {file = "markupsafe-3.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:2713baf880df847f2bece4230d4d094280f4e67b1e813eec43b4c0e144a34ffe"}, {file = "markupsafe-3.0.3-cp314-cp314-win32.whl", hash = "sha256:729586769a26dbceff69f7a7dbbf59ab6572b99d94576a5592625d5b411576b9"}, {file = "markupsafe-3.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:bdc919ead48f234740ad807933cdf545180bfbe9342c2bb451556db2ed958581"}, {file = "markupsafe-3.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:5a7d5dc5140555cf21a6fefbdbf8723f06fcd2f63ef108f2854de715e4422cb4"}, {file = "markupsafe-3.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:1353ef0c1b138e1907ae78e2f6c63ff67501122006b0f9abad68fda5f4ffc6ab"}, {file = "markupsafe-3.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:1085e7fbddd3be5f89cc898938f42c0b3c711fdcb37d75221de2666af647c175"}, {file = "markupsafe-3.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1b52b4fb9df4eb9ae465f8d0c228a00624de2334f216f178a995ccdcf82c4634"}, {file = "markupsafe-3.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fed51ac40f757d41b7c48425901843666a6677e3e8eb0abcff09e4ba6e664f50"}, {file = "markupsafe-3.0.3-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f190daf01f13c72eac4efd5c430a8de82489d9cff23c364c3ea822545032993e"}, {file = "markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e56b7d45a839a697b5eb268c82a71bd8c7f6c94d6fd50c3d577fa39a9f1409f5"}, {file = "markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:f3e98bb3798ead92273dc0e5fd0f31ade220f59a266ffd8a4f6065e0a3ce0523"}, {file = "markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:5678211cb9333a6468fb8d8be0305520aa073f50d17f089b5b4b477ea6e67fdc"}, {file = "markupsafe-3.0.3-cp314-cp314t-win32.whl", hash = "sha256:915c04ba3851909ce68ccc2b8e2cd691618c4dc4c4232fb7982bca3f41fd8c3d"}, {file = "markupsafe-3.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4faffd047e07c38848ce017e8725090413cd80cbc23d86e55c587bf979e579c9"}, {file = "markupsafe-3.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:32001d6a8fc98c8cb5c947787c5d08b0a50663d139f1305bac5885d98d9b40fa"}, {file = "markupsafe-3.0.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:15d939a21d546304880945ca1ecb8a039db6b4dc49b2c5a400387cdae6a62e26"}, {file = "markupsafe-3.0.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f71a396b3bf33ecaa1626c255855702aca4d3d9fea5e051b41ac59a9c1c41edc"}, {file = "markupsafe-3.0.3-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0f4b68347f8c5eab4a13419215bdfd7f8c9b19f2b25520968adfad23eb0ce60c"}, {file = "markupsafe-3.0.3-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e8fc20152abba6b83724d7ff268c249fa196d8259ff481f3b1476383f8f24e42"}, {file = "markupsafe-3.0.3-cp39-cp39-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:949b8d66bc381ee8b007cd945914c721d9aba8e27f71959d750a46f7c282b20b"}, {file = "markupsafe-3.0.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:3537e01efc9d4dccdf77221fb1cb3b8e1a38d5428920e0657ce299b20324d758"}, {file = "markupsafe-3.0.3-cp39-cp39-musllinux_1_2_riscv64.whl", hash = "sha256:591ae9f2a647529ca990bc681daebdd52c8791ff06c2bfa05b65163e28102ef2"}, {file = "markupsafe-3.0.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:a320721ab5a1aba0a233739394eb907f8c8da5c98c9181d1161e77a0c8e36f2d"}, {file = "markupsafe-3.0.3-cp39-cp39-win32.whl", hash = "sha256:df2449253ef108a379b8b5d6b43f4b1a8e81a061d6537becd5582fba5f9196d7"}, {file = "markupsafe-3.0.3-cp39-cp39-win_amd64.whl", hash = "sha256:7c3fb7d25180895632e5d3148dbdc29ea38ccb7fd210aa27acbd1201a1902c6e"}, {file = "markupsafe-3.0.3-cp39-cp39-win_arm64.whl", hash = "sha256:38664109c14ffc9e7437e86b4dceb442b0096dfe3541d7864d9cbe1da4cf36c8"}, {file = "markupsafe-3.0.3.tar.gz", hash = "sha256:722695808f4b6457b320fdc131280796bdceb04ab50fe1795cd540799ebe1698"}, ] [[package]] name = "mccabe" version = "0.7.0" description = "McCabe checker, plugin for flake8" optional = false python-versions = ">=3.6" groups = ["dev"] 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.5.0" description = "Collection of plugins for markdown-it-py" optional = false python-versions = ">=3.10" groups = ["docs"] files = [ {file = "mdit_py_plugins-0.5.0-py3-none-any.whl", hash = "sha256:07a08422fc1936a5d26d146759e9155ea466e842f5ab2f7d2266dd084c8dab1f"}, {file = "mdit_py_plugins-0.5.0.tar.gz", hash = "sha256:f4918cb50119f50446560513a8e311d574ff6aaed72606ddae6d35716fe809c6"}, ] [package.dependencies] markdown-it-py = ">=2.0.0,<5.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" optional = false python-versions = ">=3.7" groups = ["docs"] 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.18.2" description = "Optional static typing for Python" optional = false python-versions = ">=3.9" groups = ["dev", "lsp"] files = [ {file = "mypy-1.18.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c1eab0cf6294dafe397c261a75f96dc2c31bffe3b944faa24db5def4e2b0f77c"}, {file = "mypy-1.18.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:7a780ca61fc239e4865968ebc5240bb3bf610ef59ac398de9a7421b54e4a207e"}, {file = "mypy-1.18.2-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:448acd386266989ef11662ce3c8011fd2a7b632e0ec7d61a98edd8e27472225b"}, {file = "mypy-1.18.2-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f9e171c465ad3901dc652643ee4bffa8e9fef4d7d0eece23b428908c77a76a66"}, {file = "mypy-1.18.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:592ec214750bc00741af1f80cbf96b5013d81486b7bb24cb052382c19e40b428"}, {file = "mypy-1.18.2-cp310-cp310-win_amd64.whl", hash = "sha256:7fb95f97199ea11769ebe3638c29b550b5221e997c63b14ef93d2e971606ebed"}, {file = "mypy-1.18.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:807d9315ab9d464125aa9fcf6d84fde6e1dc67da0b6f80e7405506b8ac72bc7f"}, {file = "mypy-1.18.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:776bb00de1778caf4db739c6e83919c1d85a448f71979b6a0edd774ea8399341"}, {file = "mypy-1.18.2-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1379451880512ffce14505493bd9fe469e0697543717298242574882cf8cdb8d"}, {file = "mypy-1.18.2-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1331eb7fd110d60c24999893320967594ff84c38ac6d19e0a76c5fd809a84c86"}, {file = "mypy-1.18.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:3ca30b50a51e7ba93b00422e486cbb124f1c56a535e20eff7b2d6ab72b3b2e37"}, {file = "mypy-1.18.2-cp311-cp311-win_amd64.whl", hash = "sha256:664dc726e67fa54e14536f6e1224bcfce1d9e5ac02426d2326e2bb4e081d1ce8"}, {file = "mypy-1.18.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:33eca32dd124b29400c31d7cf784e795b050ace0e1f91b8dc035672725617e34"}, {file = "mypy-1.18.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a3c47adf30d65e89b2dcd2fa32f3aeb5e94ca970d2c15fcb25e297871c8e4764"}, {file = "mypy-1.18.2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5d6c838e831a062f5f29d11c9057c6009f60cb294fea33a98422688181fe2893"}, {file = "mypy-1.18.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:01199871b6110a2ce984bde85acd481232d17413868c9807e95c1b0739a58914"}, {file = "mypy-1.18.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a2afc0fa0b0e91b4599ddfe0f91e2c26c2b5a5ab263737e998d6817874c5f7c8"}, {file = "mypy-1.18.2-cp312-cp312-win_amd64.whl", hash = "sha256:d8068d0afe682c7c4897c0f7ce84ea77f6de953262b12d07038f4d296d547074"}, {file = "mypy-1.18.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:07b8b0f580ca6d289e69209ec9d3911b4a26e5abfde32228a288eb79df129fcc"}, {file = "mypy-1.18.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:ed4482847168439651d3feee5833ccedbf6657e964572706a2adb1f7fa4dfe2e"}, {file = "mypy-1.18.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c3ad2afadd1e9fea5cf99a45a822346971ede8685cc581ed9cd4d42eaf940986"}, {file = "mypy-1.18.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a431a6f1ef14cf8c144c6b14793a23ec4eae3db28277c358136e79d7d062f62d"}, {file = "mypy-1.18.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:7ab28cc197f1dd77a67e1c6f35cd1f8e8b73ed2217e4fc005f9e6a504e46e7ba"}, {file = "mypy-1.18.2-cp313-cp313-win_amd64.whl", hash = "sha256:0e2785a84b34a72ba55fb5daf079a1003a34c05b22238da94fcae2bbe46f3544"}, {file = "mypy-1.18.2-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:62f0e1e988ad41c2a110edde6c398383a889d95b36b3e60bcf155f5164c4fdce"}, {file = "mypy-1.18.2-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:8795a039bab805ff0c1dfdb8cd3344642c2b99b8e439d057aba30850b8d3423d"}, {file = "mypy-1.18.2-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6ca1e64b24a700ab5ce10133f7ccd956a04715463d30498e64ea8715236f9c9c"}, {file = "mypy-1.18.2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d924eef3795cc89fecf6bedc6ed32b33ac13e8321344f6ddbf8ee89f706c05cb"}, {file = "mypy-1.18.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:20c02215a080e3a2be3aa50506c67242df1c151eaba0dcbc1e4e557922a26075"}, {file = "mypy-1.18.2-cp314-cp314-win_amd64.whl", hash = "sha256:749b5f83198f1ca64345603118a6f01a4e99ad4bf9d103ddc5a3200cc4614adf"}, {file = "mypy-1.18.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:25a9c8fb67b00599f839cf472713f54249a62efd53a54b565eb61956a7e3296b"}, {file = "mypy-1.18.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c2b9c7e284ee20e7598d6f42e13ca40b4928e6957ed6813d1ab6348aa3f47133"}, {file = "mypy-1.18.2-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d6985ed057513e344e43a26cc1cd815c7a94602fb6a3130a34798625bc2f07b6"}, {file = "mypy-1.18.2-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:22f27105f1525ec024b5c630c0b9f36d5c1cc4d447d61fe51ff4bd60633f47ac"}, {file = "mypy-1.18.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:030c52d0ea8144e721e49b1f68391e39553d7451f0c3f8a7565b59e19fcb608b"}, {file = "mypy-1.18.2-cp39-cp39-win_amd64.whl", hash = "sha256:aa5e07ac1a60a253445797e42b8b2963c9675563a94f11291ab40718b016a7a0"}, {file = "mypy-1.18.2-py3-none-any.whl", hash = "sha256:22a1748707dd62b58d2ae53562ffc4d7f8bcc727e8ac7cbc69c053ddc874d47e"}, {file = "mypy-1.18.2.tar.gz", hash = "sha256:06a398102a5f203d7477b2923dda3634c36727fa5c237d8f859ef90c42a9924b"}, ] [package.dependencies] mypy_extensions = ">=1.0.0" pathspec = ">=0.9.0" tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} typing_extensions = ">=4.6.0" [package.extras] dmypy = ["psutil (>=4.0)"] faster-cache = ["orjson"] install-types = ["pip"] mypyc = ["setuptools (>=50)"] reports = ["lxml"] [[package]] name = "mypy-extensions" version = "1.1.0" description = "Type system extensions for programs checked with the mypy type checker." optional = false python-versions = ">=3.8" groups = ["dev", "lsp"] files = [ {file = "mypy_extensions-1.1.0-py3-none-any.whl", hash = "sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505"}, {file = "mypy_extensions-1.1.0.tar.gz", hash = "sha256:52e68efc3284861e772bbcd66823fde5ae21fd2fdb51c62a211403730b916558"}, ] [[package]] name = "myst-parser" version = "4.0.1" description = "An extended [CommonMark](https://spec.commonmark.org/) compliant parser," optional = false python-versions = ">=3.10" groups = ["docs"] files = [ {file = "myst_parser-4.0.1-py3-none-any.whl", hash = "sha256:9134e88959ec3b5780aedf8a99680ea242869d012e8821db3126d427edc9c95d"}, {file = "myst_parser-4.0.1.tar.gz", hash = "sha256:5cfea715e4f3574138aecbf7d54132296bfd72bb614d31168f48c477a830a7c4"}, ] [package.dependencies] docutils = ">=0.19,<0.22" jinja2 = "*" markdown-it-py = ">=3.0,<4.0" mdit-py-plugins = ">=0.4.1,<1.0" pyyaml = "*" sphinx = ">=7,<9" [package.extras] code-style = ["pre-commit (>=4.0,<5.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", "pygments (<2.19)", "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" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" groups = ["dev"] 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 = "25.0" description = "Core utilities for Python packages" optional = false python-versions = ">=3.8" groups = ["dev", "docs", "lsp", "test"] files = [ {file = "packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484"}, {file = "packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f"}, ] [[package]] name = "parso" version = "0.8.5" description = "A Python Parser" optional = false python-versions = ">=3.6" groups = ["lsp"] files = [ {file = "parso-0.8.5-py2.py3-none-any.whl", hash = "sha256:646204b5ee239c396d040b90f9e272e9a8017c630092bf59980beb62fd033887"}, {file = "parso-0.8.5.tar.gz", hash = "sha256:034d7354a9a018bdce352f48b2a8a450f05e9d6ee85db84764e9b6bd96dafe5a"}, ] [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." optional = false python-versions = ">=3.8" groups = ["dev", "lsp"] 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 = "7.0.1" description = "Python Build Reasonableness" optional = false python-versions = ">=2.6" groups = ["docs"] files = [ {file = "pbr-7.0.1-py2.py3-none-any.whl", hash = "sha256:32df5156fbeccb6f8a858d1ebc4e465dcf47d6cc7a4895d5df9aa951c712fc35"}, {file = "pbr-7.0.1.tar.gz", hash = "sha256:3ecbcb11d2b8551588ec816b3756b1eb4394186c3b689b17e04850dfc20f7e57"}, ] [package.dependencies] setuptools = "*" [[package]] name = "platformdirs" version = "4.5.0" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." optional = false python-versions = ">=3.10" groups = ["dev", "lsp"] files = [ {file = "platformdirs-4.5.0-py3-none-any.whl", hash = "sha256:e578a81bb873cbb89a41fcc904c7ef523cc18284b7e3b3ccf06aca1403b7ebd3"}, {file = "platformdirs-4.5.0.tar.gz", hash = "sha256:70ddccdd7c99fc5942e9fc25636a8b34d04c24b335100223152c2803e4063312"}, ] [package.extras] docs = ["furo (>=2025.9.25)", "proselint (>=0.14)", "sphinx (>=8.2.3)", "sphinx-autodoc-typehints (>=3.2)"] test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=8.4.2)", "pytest-cov (>=7)", "pytest-mock (>=3.15.1)"] type = ["mypy (>=1.18.2)"] [[package]] name = "pluggy" version = "1.6.0" description = "plugin and hook calling mechanisms for python" optional = false python-versions = ">=3.9" groups = ["lsp", "test"] files = [ {file = "pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746"}, {file = "pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3"}, ] [package.extras] dev = ["pre-commit", "tox"] testing = ["coverage", "pytest", "pytest-benchmark"] [[package]] name = "pre-commit" version = "4.3.0" description = "A framework for managing and maintaining multi-language pre-commit hooks." optional = false python-versions = ">=3.9" groups = ["dev"] files = [ {file = "pre_commit-4.3.0-py2.py3-none-any.whl", hash = "sha256:2b0747ad7e6e967169136edffee14c16e148a778a54e4f967921aa1ebf2308d8"}, {file = "pre_commit-4.3.0.tar.gz", hash = "sha256:499fe450cc9d42e9d58e606262795ecb64dd05438943c62b66f6a8673da30b16"}, ] [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 = "3.0.2" description = "Protokolo is a change log generator." optional = false python-versions = ">=3.11" groups = ["dev"] markers = "python_version >= \"3.11\"" files = [ {file = "protokolo-3.0.2-cp313-cp313-manylinux_2_41_x86_64.whl", hash = "sha256:fd5227a77758efc0d8ac5a62451985a8fc3b5dd65ad36bcea47f52fe07f55f16"}, {file = "protokolo-3.0.2.tar.gz", hash = "sha256:d6c98080cfb56cab4f2512cabcffd36434d3ab32272ac610197af08197da213c"}, ] [package.dependencies] attrs = ">=22.1.0" click = ">=8.0" [[package]] name = "pygments" version = "2.19.2" description = "Pygments is a syntax highlighting package written in Python." optional = false python-versions = ">=3.8" groups = ["docs", "test"] files = [ {file = "pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b"}, {file = "pygments-2.19.2.tar.gz", hash = "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887"}, ] [package.extras] windows-terminal = ["colorama (>=0.4.6)"] [[package]] name = "pylint" version = "4.0.2" description = "python code static checker" optional = false python-versions = ">=3.10.0" groups = ["dev"] files = [ {file = "pylint-4.0.2-py3-none-any.whl", hash = "sha256:9627ccd129893fb8ee8e8010261cb13485daca83e61a6f854a85528ee579502d"}, {file = "pylint-4.0.2.tar.gz", hash = "sha256:9c22dfa52781d3b79ce86ab2463940f874921a3e5707bcfc98dd0c019945014e"}, ] [package.dependencies] astroid = ">=4.0.1,<=4.1.dev0" colorama = {version = ">=0.4.5", markers = "sys_platform == \"win32\""} dill = [ {version = ">=0.2", markers = "python_version < \"3.11\""}, {version = ">=0.3.7", markers = "python_version >= \"3.12\""}, {version = ">=0.3.6", markers = "python_version == \"3.11\""}, ] isort = ">=5,<5.13 || >5.13,<8" mccabe = ">=0.6,<0.8" platformdirs = ">=2.2" tomli = {version = ">=1.1", markers = "python_version < \"3.11\""} tomlkit = ">=0.10.1" [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" optional = false python-versions = "*" groups = ["lsp"] files = [ {file = "pyls-isort-0.2.2.tar.gz", hash = "sha256:2192bd2203db00459f85eb329521feba58af63075d2dd10a051a4eccd000bba0"}, ] [package.dependencies] isort = "*" python-lsp-server = "*" [[package]] name = "pylsp-mypy" version = "0.7.0" description = "Mypy linter for the Python LSP Server" optional = false python-versions = ">=3.9" groups = ["lsp"] files = [ {file = "pylsp_mypy-0.7.0-py3-none-any.whl", hash = "sha256:756377d05d251d2e31d1963397654149b9c1ea5b0ba1aedd74adef76decd32e9"}, {file = "pylsp_mypy-0.7.0.tar.gz", hash = "sha256:e94f531d4ce523222c2af7471abe396cfeb4cc3c4b181d54462fb6d553e1e0b3"}, ] [package.dependencies] mypy = ">=0.981" python-lsp-server = ">=1.7.0" tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} [package.extras] test = ["coverage", "pytest", "pytest-cov", "tox"] [[package]] name = "pytest" version = "8.4.2" description = "pytest: simple powerful testing with Python" optional = false python-versions = ">=3.9" groups = ["test"] files = [ {file = "pytest-8.4.2-py3-none-any.whl", hash = "sha256:872f880de3fc3a5bdc88a11b39c9710c3497a547cfa9320bc3c5e62fbf272e79"}, {file = "pytest-8.4.2.tar.gz", hash = "sha256:86c0d0b93306b961d58d62a4db4879f27fe25513d4b969df351abdddb3c30e01"}, ] [package.dependencies] colorama = {version = ">=0.4", markers = "sys_platform == \"win32\""} exceptiongroup = {version = ">=1", markers = "python_version < \"3.11\""} iniconfig = ">=1" packaging = ">=20" pluggy = ">=1.5,<2" pygments = ">=2.7.2" tomli = {version = ">=1", markers = "python_version < \"3.11\""} [package.extras] dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "requests", "setuptools", "xmlschema"] [[package]] name = "pytest-cov" version = "7.0.0" description = "Pytest plugin for measuring coverage." optional = false python-versions = ">=3.9" groups = ["test"] files = [ {file = "pytest_cov-7.0.0-py3-none-any.whl", hash = "sha256:3b8e9558b16cc1479da72058bdecf8073661c7f57f7d3c5f22a1c23507f2d861"}, {file = "pytest_cov-7.0.0.tar.gz", hash = "sha256:33c97eda2e049a0c5298e91f519302a1334c26ac65c1a483d6206fd458361af1"}, ] [package.dependencies] coverage = {version = ">=7.10.6", extras = ["toml"]} pluggy = ">=1.2" pytest = ">=7" [package.extras] testing = ["process-tests", "pytest-xdist", "virtualenv"] [[package]] name = "python-dateutil" version = "2.9.0.post0" description = "Extensions to the standard Python datetime module" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" groups = ["test"] 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 = "1.0.1" description = "Modules to read and manipulate many file formats related to Debian packages and repositories" optional = false python-versions = ">=3.7" groups = ["main"] files = [ {file = "python-debian-1.0.1.tar.gz", hash = "sha256:3ada9b83a3d671b58081782c0969cffa0102f6ce433fbbc7cf21275b8b5cc771"}, {file = "python_debian-1.0.1-py3-none-any.whl", hash = "sha256:8f137c230c1d9279c2ac892b35915068b2aca090c9fd3da5671ff87af32af12c"}, ] [package.dependencies] charset-normalizer = "*" [package.extras] test = ["pytest", "pytest-cov"] [[package]] name = "python-lsp-black" version = "2.0.0" description = "Black plugin for the Python LSP Server" optional = false python-versions = ">=3.8" groups = ["lsp"] 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" optional = false python-versions = ">=3.8" groups = ["lsp"] 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.13.1" description = "Python Language Server for the Language Server Protocol" optional = false python-versions = ">=3.9" groups = ["lsp"] files = [ {file = "python_lsp_server-1.13.1-py3-none-any.whl", hash = "sha256:fadf45275d12a9d9a13e36717a8383cee8e7cffe8a30698d38bfb3fe71b5cdcd"}, {file = "python_lsp_server-1.13.1.tar.gz", hash = "sha256:bfa3d6bbca3fc3e6d0137b27cd1eabee65783a8d4314c36e1e230c603419afa3"}, ] [package.dependencies] black = "*" docstring-to-markdown = "*" 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.1,<8)", "mccabe (>=0.7.0,<0.8.0)", "pycodestyle (>=2.12.0,<2.13.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.1,<8)"] mccabe = ["mccabe (>=0.7.0,<0.8.0)"] pycodestyle = ["pycodestyle (>=2.12.0,<2.13.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)", "pyqt6", "pytest", "pytest-cov", "websockets (>=10.3)"] websockets = ["websockets (>=10.3)"] yapf = ["whatthepatch (>=1.0.2,<2.0.0)", "yapf (>=0.33.0)"] [[package]] name = "python-magic" version = "0.4.27" description = "File type identification using libmagic" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" groups = ["main"] files = [ {file = "python-magic-0.4.27.tar.gz", hash = "sha256:c1ba14b08e4a5f5c31a302b7721239695b2f0f058d125bd5ce1ee36b9d9d3c3b"}, {file = "python_magic-0.4.27-py2.py3-none-any.whl", hash = "sha256:c212960ad306f700aa0d01e5d7a325d20548ff97eb9920dcd29513174f0294d3"}, ] [[package]] name = "pytokens" version = "0.2.0" description = "A Fast, spec compliant Python 3.13+ tokenizer that runs on older Pythons." optional = false python-versions = ">=3.8" groups = ["dev", "lsp"] files = [ {file = "pytokens-0.2.0-py3-none-any.whl", hash = "sha256:74d4b318c67f4295c13782ddd9abcb7e297ec5630ad060eb90abf7ebbefe59f8"}, {file = "pytokens-0.2.0.tar.gz", hash = "sha256:532d6421364e5869ea57a9523bf385f02586d4662acbcc0342afd69511b4dd43"}, ] [package.extras] dev = ["black", "build", "mypy", "pytest", "pytest-cov", "setuptools", "tox", "twine", "wheel"] [[package]] name = "pyyaml" version = "6.0.3" description = "YAML parser and emitter for Python" optional = false python-versions = ">=3.8" groups = ["dev", "docs"] files = [ {file = "PyYAML-6.0.3-cp38-cp38-macosx_10_13_x86_64.whl", hash = "sha256:c2514fceb77bc5e7a2f7adfaa1feb2fb311607c9cb518dbc378688ec73d8292f"}, {file = "PyYAML-6.0.3-cp38-cp38-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9c57bb8c96f6d1808c030b1687b9b5fb476abaa47f0db9c0101f5e9f394e97f4"}, {file = "PyYAML-6.0.3-cp38-cp38-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:efd7b85f94a6f21e4932043973a7ba2613b059c4a000551892ac9f1d11f5baf3"}, {file = "PyYAML-6.0.3-cp38-cp38-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:22ba7cfcad58ef3ecddc7ed1db3409af68d023b7f940da23c6c2a1890976eda6"}, {file = "PyYAML-6.0.3-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:6344df0d5755a2c9a276d4473ae6b90647e216ab4757f8426893b5dd2ac3f369"}, {file = "PyYAML-6.0.3-cp38-cp38-win32.whl", hash = "sha256:3ff07ec89bae51176c0549bc4c63aa6202991da2d9a6129d7aef7f1407d3f295"}, {file = "PyYAML-6.0.3-cp38-cp38-win_amd64.whl", hash = "sha256:5cf4e27da7e3fbed4d6c3d8e797387aaad68102272f8f9752883bc32d61cb87b"}, {file = "pyyaml-6.0.3-cp310-cp310-macosx_10_13_x86_64.whl", hash = "sha256:214ed4befebe12df36bcc8bc2b64b396ca31be9304b8f59e25c11cf94a4c033b"}, {file = "pyyaml-6.0.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:02ea2dfa234451bbb8772601d7b8e426c2bfa197136796224e50e35a78777956"}, {file = "pyyaml-6.0.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b30236e45cf30d2b8e7b3e85881719e98507abed1011bf463a8fa23e9c3e98a8"}, {file = "pyyaml-6.0.3-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:66291b10affd76d76f54fad28e22e51719ef9ba22b29e1d7d03d6777a9174198"}, {file = "pyyaml-6.0.3-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9c7708761fccb9397fe64bbc0395abcae8c4bf7b0eac081e12b809bf47700d0b"}, {file = "pyyaml-6.0.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:418cf3f2111bc80e0933b2cd8cd04f286338bb88bdc7bc8e6dd775ebde60b5e0"}, {file = "pyyaml-6.0.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:5e0b74767e5f8c593e8c9b5912019159ed0533c70051e9cce3e8b6aa699fcd69"}, {file = "pyyaml-6.0.3-cp310-cp310-win32.whl", hash = "sha256:28c8d926f98f432f88adc23edf2e6d4921ac26fb084b028c733d01868d19007e"}, {file = "pyyaml-6.0.3-cp310-cp310-win_amd64.whl", hash = "sha256:bdb2c67c6c1390b63c6ff89f210c8fd09d9a1217a465701eac7316313c915e4c"}, {file = "pyyaml-6.0.3-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:44edc647873928551a01e7a563d7452ccdebee747728c1080d881d68af7b997e"}, {file = "pyyaml-6.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:652cb6edd41e718550aad172851962662ff2681490a8a711af6a4d288dd96824"}, {file = "pyyaml-6.0.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:10892704fc220243f5305762e276552a0395f7beb4dbf9b14ec8fd43b57f126c"}, {file = "pyyaml-6.0.3-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:850774a7879607d3a6f50d36d04f00ee69e7fc816450e5f7e58d7f17f1ae5c00"}, {file = "pyyaml-6.0.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b8bb0864c5a28024fac8a632c443c87c5aa6f215c0b126c449ae1a150412f31d"}, {file = "pyyaml-6.0.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1d37d57ad971609cf3c53ba6a7e365e40660e3be0e5175fa9f2365a379d6095a"}, {file = "pyyaml-6.0.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:37503bfbfc9d2c40b344d06b2199cf0e96e97957ab1c1b546fd4f87e53e5d3e4"}, {file = "pyyaml-6.0.3-cp311-cp311-win32.whl", hash = "sha256:8098f252adfa6c80ab48096053f512f2321f0b998f98150cea9bd23d83e1467b"}, {file = "pyyaml-6.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:9f3bfb4965eb874431221a3ff3fdcddc7e74e3b07799e0e84ca4a0f867d449bf"}, {file = "pyyaml-6.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7f047e29dcae44602496db43be01ad42fc6f1cc0d8cd6c83d342306c32270196"}, {file = "pyyaml-6.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:fc09d0aa354569bc501d4e787133afc08552722d3ab34836a80547331bb5d4a0"}, {file = "pyyaml-6.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9149cad251584d5fb4981be1ecde53a1ca46c891a79788c0df828d2f166bda28"}, {file = "pyyaml-6.0.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5fdec68f91a0c6739b380c83b951e2c72ac0197ace422360e6d5a959d8d97b2c"}, {file = "pyyaml-6.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ba1cc08a7ccde2d2ec775841541641e4548226580ab850948cbfda66a1befcdc"}, {file = "pyyaml-6.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8dc52c23056b9ddd46818a57b78404882310fb473d63f17b07d5c40421e47f8e"}, {file = "pyyaml-6.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:41715c910c881bc081f1e8872880d3c650acf13dfa8214bad49ed4cede7c34ea"}, {file = "pyyaml-6.0.3-cp312-cp312-win32.whl", hash = "sha256:96b533f0e99f6579b3d4d4995707cf36df9100d67e0c8303a0c55b27b5f99bc5"}, {file = "pyyaml-6.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:5fcd34e47f6e0b794d17de1b4ff496c00986e1c83f7ab2fb8fcfe9616ff7477b"}, {file = "pyyaml-6.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:64386e5e707d03a7e172c0701abfb7e10f0fb753ee1d773128192742712a98fd"}, {file = "pyyaml-6.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8da9669d359f02c0b91ccc01cac4a67f16afec0dac22c2ad09f46bee0697eba8"}, {file = "pyyaml-6.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2283a07e2c21a2aa78d9c4442724ec1eb15f5e42a723b99cb3d822d48f5f7ad1"}, {file = "pyyaml-6.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee2922902c45ae8ccada2c5b501ab86c36525b883eff4255313a253a3160861c"}, {file = "pyyaml-6.0.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a33284e20b78bd4a18c8c2282d549d10bc8408a2a7ff57653c0cf0b9be0afce5"}, {file = "pyyaml-6.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0f29edc409a6392443abf94b9cf89ce99889a1dd5376d94316ae5145dfedd5d6"}, {file = "pyyaml-6.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f7057c9a337546edc7973c0d3ba84ddcdf0daa14533c2065749c9075001090e6"}, {file = "pyyaml-6.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:eda16858a3cab07b80edaf74336ece1f986ba330fdb8ee0d6c0d68fe82bc96be"}, {file = "pyyaml-6.0.3-cp313-cp313-win32.whl", hash = "sha256:d0eae10f8159e8fdad514efdc92d74fd8d682c933a6dd088030f3834bc8e6b26"}, {file = "pyyaml-6.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:79005a0d97d5ddabfeeea4cf676af11e647e41d81c9a7722a193022accdb6b7c"}, {file = "pyyaml-6.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:5498cd1645aa724a7c71c8f378eb29ebe23da2fc0d7a08071d89469bf1d2defb"}, {file = "pyyaml-6.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:8d1fab6bb153a416f9aeb4b8763bc0f22a5586065f86f7664fc23339fc1c1fac"}, {file = "pyyaml-6.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:34d5fcd24b8445fadc33f9cf348c1047101756fd760b4dacb5c3e99755703310"}, {file = "pyyaml-6.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:501a031947e3a9025ed4405a168e6ef5ae3126c59f90ce0cd6f2bfc477be31b7"}, {file = "pyyaml-6.0.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b3bc83488de33889877a0f2543ade9f70c67d66d9ebb4ac959502e12de895788"}, {file = "pyyaml-6.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c458b6d084f9b935061bc36216e8a69a7e293a2f1e68bf956dcd9e6cbcd143f5"}, {file = "pyyaml-6.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7c6610def4f163542a622a73fb39f534f8c101d690126992300bf3207eab9764"}, {file = "pyyaml-6.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5190d403f121660ce8d1d2c1bb2ef1bd05b5f68533fc5c2ea899bd15f4399b35"}, {file = "pyyaml-6.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:4a2e8cebe2ff6ab7d1050ecd59c25d4c8bd7e6f400f5f82b96557ac0abafd0ac"}, {file = "pyyaml-6.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:93dda82c9c22deb0a405ea4dc5f2d0cda384168e466364dec6255b293923b2f3"}, {file = "pyyaml-6.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:02893d100e99e03eda1c8fd5c441d8c60103fd175728e23e431db1b589cf5ab3"}, {file = "pyyaml-6.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c1ff362665ae507275af2853520967820d9124984e0f7466736aea23d8611fba"}, {file = "pyyaml-6.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6adc77889b628398debc7b65c073bcb99c4a0237b248cacaf3fe8a557563ef6c"}, {file = "pyyaml-6.0.3-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a80cb027f6b349846a3bf6d73b5e95e782175e52f22108cfa17876aaeff93702"}, {file = "pyyaml-6.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:00c4bdeba853cc34e7dd471f16b4114f4162dc03e6b7afcc2128711f0eca823c"}, {file = "pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:66e1674c3ef6f541c35191caae2d429b967b99e02040f5ba928632d9a7f0f065"}, {file = "pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:16249ee61e95f858e83976573de0f5b2893b3677ba71c9dd36b9cf8be9ac6d65"}, {file = "pyyaml-6.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4ad1906908f2f5ae4e5a8ddfce73c320c2a1429ec52eafd27138b7f1cbe341c9"}, {file = "pyyaml-6.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b"}, {file = "pyyaml-6.0.3-cp39-cp39-macosx_10_13_x86_64.whl", hash = "sha256:b865addae83924361678b652338317d1bd7e79b1f4596f96b96c77a5a34b34da"}, {file = "pyyaml-6.0.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c3355370a2c156cffb25e876646f149d5d68f5e0a3ce86a5084dd0b64a994917"}, {file = "pyyaml-6.0.3-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3c5677e12444c15717b902a5798264fa7909e41153cdf9ef7ad571b704a63dd9"}, {file = "pyyaml-6.0.3-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5ed875a24292240029e4483f9d4a4b8a1ae08843b9c54f43fcc11e404532a8a5"}, {file = "pyyaml-6.0.3-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0150219816b6a1fa26fb4699fb7daa9caf09eb1999f3b70fb6e786805e80375a"}, {file = "pyyaml-6.0.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:fa160448684b4e94d80416c0fa4aac48967a969efe22931448d853ada8baf926"}, {file = "pyyaml-6.0.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:27c0abcb4a5dac13684a37f76e701e054692a9b2d3064b70f5e4eb54810553d7"}, {file = "pyyaml-6.0.3-cp39-cp39-win32.whl", hash = "sha256:1ebe39cb5fc479422b83de611d14e2c0d3bb2a18bbcb01f229ab3cfbd8fee7a0"}, {file = "pyyaml-6.0.3-cp39-cp39-win_amd64.whl", hash = "sha256:2e71d11abed7344e42a8849600193d15b6def118602c4c176f748e4583246007"}, {file = "pyyaml-6.0.3.tar.gz", hash = "sha256:d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f"}, ] [[package]] name = "requests" version = "2.32.5" description = "Python HTTP for Humans." optional = false python-versions = ">=3.9" groups = ["docs"] files = [ {file = "requests-2.32.5-py3-none-any.whl", hash = "sha256:2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6"}, {file = "requests-2.32.5.tar.gz", hash = "sha256:dbba0bac56e100853db0ea71b82b4dfd5fe2bf6d3754a8893c3af500cec7d7cf"}, ] [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 = "roman-numerals-py" version = "3.1.0" description = "Manipulate well-formed Roman numerals" optional = false python-versions = ">=3.9" groups = ["docs"] markers = "python_version >= \"3.11\"" files = [ {file = "roman_numerals_py-3.1.0-py3-none-any.whl", hash = "sha256:9da2ad2fb670bcf24e81070ceb3be72f6c11c440d73bd579fbeca1e9f330954c"}, {file = "roman_numerals_py-3.1.0.tar.gz", hash = "sha256:be4bf804f083a4ce001b5eb7e3c0862479d10f94c936f6c4e5f250aa5ff5bd2d"}, ] [package.extras] lint = ["mypy (==1.15.0)", "pyright (==1.1.394)", "ruff (==0.9.7)"] test = ["pytest (>=8)"] [[package]] name = "setuptools" version = "80.9.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false python-versions = ">=3.9" groups = ["docs"] files = [ {file = "setuptools-80.9.0-py3-none-any.whl", hash = "sha256:062d34222ad13e0cc312a4c02d73f059e86a4acbfbdea8f8f76b28c99f306922"}, {file = "setuptools-80.9.0.tar.gz", hash = "sha256:f36b47402ecde768dbfafc46e8e4207b4360c654f1f3bb84475f0a28628fb19c"}, ] [package.extras] check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1) ; sys_platform != \"cygwin\"", "ruff (>=0.8.0) ; sys_platform != \"cygwin\""] core = ["importlib_metadata (>=6) ; python_version < \"3.10\"", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more_itertools", "more_itertools (>=8.8)", "packaging (>=24.2)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1) ; python_version < \"3.11\"", "wheel (>=0.43.0)"] cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] enabler = ["pytest-enabler (>=2.2)"] test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21) ; python_version >= \"3.9\" and sys_platform != \"cygwin\"", "jaraco.envs (>=2.2)", "jaraco.path (>=3.7.2)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf ; sys_platform != \"cygwin\"", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] type = ["importlib_metadata (>=7.0.2) ; python_version < \"3.10\"", "jaraco.develop (>=7.21) ; sys_platform != \"cygwin\"", "mypy (==1.14.*)", "pytest-mypy"] [[package]] name = "six" version = "1.17.0" description = "Python 2 and 3 compatibility utilities" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" groups = ["test"] files = [ {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, ] [[package]] name = "smmap" version = "5.0.2" description = "A pure Python implementation of a sliding window memory map manager" optional = false python-versions = ">=3.7" groups = ["dev"] files = [ {file = "smmap-5.0.2-py3-none-any.whl", hash = "sha256:b30115f0def7d7531d22a0fb6502488d879e75b260a9db4d0819cfb25403af5e"}, {file = "smmap-5.0.2.tar.gz", hash = "sha256:26ea65a03958fa0c8a1c7e8c7a58fdc77221b8910f6be2131affade476898ad5"}, ] [[package]] name = "snowballstemmer" version = "3.0.1" description = "This package provides 32 stemmers for 30 languages generated from Snowball algorithms." optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*" groups = ["docs"] files = [ {file = "snowballstemmer-3.0.1-py3-none-any.whl", hash = "sha256:6cd7b3897da8d6c9ffb968a6781fa6532dce9c3618a4b127d920dab764a19064"}, {file = "snowballstemmer-3.0.1.tar.gz", hash = "sha256:6d5eeeec8e9f84d4d56b847692bacf79bc2c8e90c7f80ca4444ff8b6f2e52895"}, ] [[package]] name = "soupsieve" version = "2.8" description = "A modern CSS selector implementation for Beautiful Soup." optional = false python-versions = ">=3.9" groups = ["docs"] files = [ {file = "soupsieve-2.8-py3-none-any.whl", hash = "sha256:0cc76456a30e20f5d7f2e14a98a4ae2ee4e5abdc7c5ea0aafe795f344bc7984c"}, {file = "soupsieve-2.8.tar.gz", hash = "sha256:e2dd4a40a628cb5f28f6d4b0db8800b8f581b65bb380b97de22ba5ca8d72572f"}, ] [[package]] name = "sphinx" version = "8.1.3" description = "Python documentation generator" optional = false python-versions = ">=3.10" groups = ["docs"] markers = "python_version == \"3.10\"" files = [ {file = "sphinx-8.1.3-py3-none-any.whl", hash = "sha256:09719015511837b76bf6e03e42eb7595ac8c2e41eeb9c29c5b755c6b677992a2"}, {file = "sphinx-8.1.3.tar.gz", hash = "sha256:43c1911eecb0d3e161ad78611bc905d1ad0e523e4ddc202a58a821773dc4c927"}, ] [package.dependencies] alabaster = ">=0.7.14" babel = ">=2.13" colorama = {version = ">=0.4.6", markers = "sys_platform == \"win32\""} docutils = ">=0.20,<0.22" imagesize = ">=1.3" Jinja2 = ">=3.1" packaging = ">=23.0" Pygments = ">=2.17" requests = ">=2.30.0" snowballstemmer = ">=2.2" sphinxcontrib-applehelp = ">=1.0.7" sphinxcontrib-devhelp = ">=1.0.6" sphinxcontrib-htmlhelp = ">=2.0.6" sphinxcontrib-jsmath = ">=1.0.1" sphinxcontrib-qthelp = ">=1.0.6" sphinxcontrib-serializinghtml = ">=1.1.9" tomli = {version = ">=2", markers = "python_version < \"3.11\""} [package.extras] docs = ["sphinxcontrib-websupport"] lint = ["flake8 (>=6.0)", "mypy (==1.11.1)", "pyright (==1.1.384)", "pytest (>=6.0)", "ruff (==0.6.9)", "sphinx-lint (>=0.9)", "tomli (>=2)", "types-Pillow (==10.2.0.20240822)", "types-Pygments (==2.18.0.20240506)", "types-colorama (==0.4.15.20240311)", "types-defusedxml (==0.7.0.20240218)", "types-docutils (==0.21.0.20241005)", "types-requests (==2.32.0.20240914)", "types-urllib3 (==1.26.25.14)"] test = ["cython (>=3.0)", "defusedxml (>=0.7.1)", "pytest (>=8.0)", "setuptools (>=70.0)", "typing_extensions (>=4.9)"] [[package]] name = "sphinx" version = "8.2.3" description = "Python documentation generator" optional = false python-versions = ">=3.11" groups = ["docs"] markers = "python_version >= \"3.11\"" files = [ {file = "sphinx-8.2.3-py3-none-any.whl", hash = "sha256:4405915165f13521d875a8c29c8970800a0141c14cc5416a38feca4ea5d9b9c3"}, {file = "sphinx-8.2.3.tar.gz", hash = "sha256:398ad29dee7f63a75888314e9424d40f52ce5a6a87ae88e7071e80af296ec348"}, ] [package.dependencies] alabaster = ">=0.7.14" babel = ">=2.13" colorama = {version = ">=0.4.6", markers = "sys_platform == \"win32\""} docutils = ">=0.20,<0.22" imagesize = ">=1.3" Jinja2 = ">=3.1" packaging = ">=23.0" Pygments = ">=2.17" requests = ">=2.30.0" roman-numerals-py = ">=1.0.0" snowballstemmer = ">=2.2" sphinxcontrib-applehelp = ">=1.0.7" sphinxcontrib-devhelp = ">=1.0.6" sphinxcontrib-htmlhelp = ">=2.0.6" sphinxcontrib-jsmath = ">=1.0.1" sphinxcontrib-qthelp = ">=1.0.6" sphinxcontrib-serializinghtml = ">=1.1.9" [package.extras] docs = ["sphinxcontrib-websupport"] lint = ["betterproto (==2.0.0b6)", "mypy (==1.15.0)", "pypi-attestations (==0.0.21)", "pyright (==1.1.395)", "pytest (>=8.0)", "ruff (==0.9.9)", "sphinx-lint (>=0.9)", "types-Pillow (==10.2.0.20240822)", "types-Pygments (==2.19.0.20250219)", "types-colorama (==0.4.15.20240311)", "types-defusedxml (==0.7.0.20240218)", "types-docutils (==0.21.0.20241128)", "types-requests (==2.32.0.20241016)", "types-urllib3 (==1.26.25.14)"] test = ["cython (>=3.0)", "defusedxml (>=0.7.1)", "pytest (>=8.0)", "pytest-xdist[psutil] (>=3.4)", "setuptools (>=70.0)", "typing_extensions (>=4.9)"] [[package]] name = "sphinx-basic-ng" version = "1.0.0b2" description = "A modern skeleton for Sphinx themes." optional = false python-versions = ">=3.7" groups = ["docs"] 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.6.0" description = "A Sphinx extension for running 'sphinx-apidoc' on each build" optional = false python-versions = ">=3.9" groups = ["docs"] files = [ {file = "sphinxcontrib_apidoc-0.6.0-py3-none-any.whl", hash = "sha256:668592f933eee858f3bc0d0810d56d50dfa0a70f650a2faaaad501b9a3504633"}, {file = "sphinxcontrib_apidoc-0.6.0.tar.gz", hash = "sha256:329b9810d66988f48e127a6bd18cc8efbbd1cd20b8deb4691a35738af49ad88d"}, ] [package.dependencies] pbr = "*" Sphinx = ">=5.0.0" [[package]] name = "sphinxcontrib-applehelp" version = "2.0.0" description = "sphinxcontrib-applehelp is a Sphinx extension which outputs Apple help books" optional = false python-versions = ">=3.9" groups = ["docs"] files = [ {file = "sphinxcontrib_applehelp-2.0.0-py3-none-any.whl", hash = "sha256:4cd3f0ec4ac5dd9c17ec65e9ab272c9b867ea77425228e68ecf08d6b28ddbdb5"}, {file = "sphinxcontrib_applehelp-2.0.0.tar.gz", hash = "sha256:2f29ef331735ce958efa4734873f084941970894c6090408b079c61b2e1c06d1"}, ] [package.extras] lint = ["mypy", "ruff (==0.5.5)", "types-docutils"] standalone = ["Sphinx (>=5)"] test = ["pytest"] [[package]] name = "sphinxcontrib-devhelp" version = "2.0.0" description = "sphinxcontrib-devhelp is a sphinx extension which outputs Devhelp documents" optional = false python-versions = ">=3.9" groups = ["docs"] files = [ {file = "sphinxcontrib_devhelp-2.0.0-py3-none-any.whl", hash = "sha256:aefb8b83854e4b0998877524d1029fd3e6879210422ee3780459e28a1f03a8a2"}, {file = "sphinxcontrib_devhelp-2.0.0.tar.gz", hash = "sha256:411f5d96d445d1d73bb5d52133377b4248ec79db5c793ce7dbe59e074b4dd1ad"}, ] [package.extras] lint = ["mypy", "ruff (==0.5.5)", "types-docutils"] standalone = ["Sphinx (>=5)"] test = ["pytest"] [[package]] name = "sphinxcontrib-htmlhelp" version = "2.1.0" description = "sphinxcontrib-htmlhelp is a sphinx extension which renders HTML help files" optional = false python-versions = ">=3.9" groups = ["docs"] files = [ {file = "sphinxcontrib_htmlhelp-2.1.0-py3-none-any.whl", hash = "sha256:166759820b47002d22914d64a075ce08f4c46818e17cfc9470a9786b759b19f8"}, {file = "sphinxcontrib_htmlhelp-2.1.0.tar.gz", hash = "sha256:c9e2916ace8aad64cc13a0d233ee22317f2b9025b9cf3295249fa985cc7082e9"}, ] [package.extras] lint = ["mypy", "ruff (==0.5.5)", "types-docutils"] standalone = ["Sphinx (>=5)"] test = ["html5lib", "pytest"] [[package]] name = "sphinxcontrib-jsmath" version = "1.0.1" description = "A sphinx extension which renders display math in HTML via JavaScript" optional = false python-versions = ">=3.5" groups = ["docs"] 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 = "2.0.0" description = "sphinxcontrib-qthelp is a sphinx extension which outputs QtHelp documents" optional = false python-versions = ">=3.9" groups = ["docs"] files = [ {file = "sphinxcontrib_qthelp-2.0.0-py3-none-any.whl", hash = "sha256:b18a828cdba941ccd6ee8445dbe72ffa3ef8cbe7505d8cd1fa0d42d3f2d5f3eb"}, {file = "sphinxcontrib_qthelp-2.0.0.tar.gz", hash = "sha256:4fe7d0ac8fc171045be623aba3e2a8f613f8682731f9153bb2e40ece16b9bbab"}, ] [package.extras] lint = ["mypy", "ruff (==0.5.5)", "types-docutils"] standalone = ["Sphinx (>=5)"] test = ["defusedxml (>=0.7.1)", "pytest"] [[package]] name = "sphinxcontrib-serializinghtml" version = "2.0.0" description = "sphinxcontrib-serializinghtml is a sphinx extension which outputs \"serialized\" HTML files (json and pickle)" optional = false python-versions = ">=3.9" groups = ["docs"] files = [ {file = "sphinxcontrib_serializinghtml-2.0.0-py3-none-any.whl", hash = "sha256:6e2cb0eef194e10c27ec0023bfeb25badbbb5868244cf5bc5bdc04e4464bf331"}, {file = "sphinxcontrib_serializinghtml-2.0.0.tar.gz", hash = "sha256:e9d912827f872c029017a53f0ef2180b327c3f7fd23c87229f7a8e8b70031d4d"}, ] [package.extras] lint = ["mypy", "ruff (==0.5.5)", "types-docutils"] standalone = ["Sphinx (>=5)"] test = ["pytest"] [[package]] name = "toml" version = "0.10.2" description = "Python Library for Tom's Obvious, Minimal Language" optional = false python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" groups = ["dev"] 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.3.0" description = "A lil' TOML parser" optional = false python-versions = ">=3.8" groups = ["dev", "docs", "lsp", "test"] markers = "python_version == \"3.10\"" files = [ {file = "tomli-2.3.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:88bd15eb972f3664f5ed4b57c1634a97153b4bac4479dcb6a495f41921eb7f45"}, {file = "tomli-2.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:883b1c0d6398a6a9d29b508c331fa56adbcdff647f6ace4dfca0f50e90dfd0ba"}, {file = "tomli-2.3.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d1381caf13ab9f300e30dd8feadb3de072aeb86f1d34a8569453ff32a7dea4bf"}, {file = "tomli-2.3.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a0e285d2649b78c0d9027570d4da3425bdb49830a6156121360b3f8511ea3441"}, {file = "tomli-2.3.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0a154a9ae14bfcf5d8917a59b51ffd5a3ac1fd149b71b47a3a104ca4edcfa845"}, {file = "tomli-2.3.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:74bf8464ff93e413514fefd2be591c3b0b23231a77f901db1eb30d6f712fc42c"}, {file = "tomli-2.3.0-cp311-cp311-win32.whl", hash = "sha256:00b5f5d95bbfc7d12f91ad8c593a1659b6387b43f054104cda404be6bda62456"}, {file = "tomli-2.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:4dc4ce8483a5d429ab602f111a93a6ab1ed425eae3122032db7e9acf449451be"}, {file = "tomli-2.3.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d7d86942e56ded512a594786a5ba0a5e521d02529b3826e7761a05138341a2ac"}, {file = "tomli-2.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:73ee0b47d4dad1c5e996e3cd33b8a76a50167ae5f96a2607cbe8cc773506ab22"}, {file = "tomli-2.3.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:792262b94d5d0a466afb5bc63c7daa9d75520110971ee269152083270998316f"}, {file = "tomli-2.3.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4f195fe57ecceac95a66a75ac24d9d5fbc98ef0962e09b2eddec5d39375aae52"}, {file = "tomli-2.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e31d432427dcbf4d86958c184b9bfd1e96b5b71f8eb17e6d02531f434fd335b8"}, {file = "tomli-2.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:7b0882799624980785240ab732537fcfc372601015c00f7fc367c55308c186f6"}, {file = "tomli-2.3.0-cp312-cp312-win32.whl", hash = "sha256:ff72b71b5d10d22ecb084d345fc26f42b5143c5533db5e2eaba7d2d335358876"}, {file = "tomli-2.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:1cb4ed918939151a03f33d4242ccd0aa5f11b3547d0cf30f7c74a408a5b99878"}, {file = "tomli-2.3.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:5192f562738228945d7b13d4930baffda67b69425a7f0da96d360b0a3888136b"}, {file = "tomli-2.3.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:be71c93a63d738597996be9528f4abe628d1adf5e6eb11607bc8fe1a510b5dae"}, {file = "tomli-2.3.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c4665508bcbac83a31ff8ab08f424b665200c0e1e645d2bd9ab3d3e557b6185b"}, {file = "tomli-2.3.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4021923f97266babc6ccab9f5068642a0095faa0a51a246a6a02fccbb3514eaf"}, {file = "tomli-2.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a4ea38c40145a357d513bffad0ed869f13c1773716cf71ccaa83b0fa0cc4e42f"}, {file = "tomli-2.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ad805ea85eda330dbad64c7ea7a4556259665bdf9d2672f5dccc740eb9d3ca05"}, {file = "tomli-2.3.0-cp313-cp313-win32.whl", hash = "sha256:97d5eec30149fd3294270e889b4234023f2c69747e555a27bd708828353ab606"}, {file = "tomli-2.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:0c95ca56fbe89e065c6ead5b593ee64b84a26fca063b5d71a1122bf26e533999"}, {file = "tomli-2.3.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:cebc6fe843e0733ee827a282aca4999b596241195f43b4cc371d64fc6639da9e"}, {file = "tomli-2.3.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:4c2ef0244c75aba9355561272009d934953817c49f47d768070c3c94355c2aa3"}, {file = "tomli-2.3.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c22a8bf253bacc0cf11f35ad9808b6cb75ada2631c2d97c971122583b129afbc"}, {file = "tomli-2.3.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0eea8cc5c5e9f89c9b90c4896a8deefc74f518db5927d0e0e8d4a80953d774d0"}, {file = "tomli-2.3.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:b74a0e59ec5d15127acdabd75ea17726ac4c5178ae51b85bfe39c4f8a278e879"}, {file = "tomli-2.3.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:b5870b50c9db823c595983571d1296a6ff3e1b88f734a4c8f6fc6188397de005"}, {file = "tomli-2.3.0-cp314-cp314-win32.whl", hash = "sha256:feb0dacc61170ed7ab602d3d972a58f14ee3ee60494292d384649a3dc38ef463"}, {file = "tomli-2.3.0-cp314-cp314-win_amd64.whl", hash = "sha256:b273fcbd7fc64dc3600c098e39136522650c49bca95df2d11cf3b626422392c8"}, {file = "tomli-2.3.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:940d56ee0410fa17ee1f12b817b37a4d4e4dc4d27340863cc67236c74f582e77"}, {file = "tomli-2.3.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:f85209946d1fe94416debbb88d00eb92ce9cd5266775424ff81bc959e001acaf"}, {file = "tomli-2.3.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a56212bdcce682e56b0aaf79e869ba5d15a6163f88d5451cbde388d48b13f530"}, {file = "tomli-2.3.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c5f3ffd1e098dfc032d4d3af5c0ac64f6d286d98bc148698356847b80fa4de1b"}, {file = "tomli-2.3.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:5e01decd096b1530d97d5d85cb4dff4af2d8347bd35686654a004f8dea20fc67"}, {file = "tomli-2.3.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:8a35dd0e643bb2610f156cca8db95d213a90015c11fee76c946aa62b7ae7e02f"}, {file = "tomli-2.3.0-cp314-cp314t-win32.whl", hash = "sha256:a1f7f282fe248311650081faafa5f4732bdbfef5d45fe3f2e702fbc6f2d496e0"}, {file = "tomli-2.3.0-cp314-cp314t-win_amd64.whl", hash = "sha256:70a251f8d4ba2d9ac2542eecf008b3c8a9fc5c3f9f02c56a9d7952612be2fdba"}, {file = "tomli-2.3.0-py3-none-any.whl", hash = "sha256:e95b1af3c5b07d9e643909b5abbec77cd9f1217e6d0bca72b0234736b9fb1f1b"}, {file = "tomli-2.3.0.tar.gz", hash = "sha256:64be704a875d2a59753d80ee8a533c3fe183e3f06807ff7dc2232938ccb01549"}, ] [[package]] name = "tomlkit" version = "0.13.3" description = "Style preserving TOML library" optional = false python-versions = ">=3.8" groups = ["main", "dev"] files = [ {file = "tomlkit-0.13.3-py3-none-any.whl", hash = "sha256:c89c649d79ee40629a9fda55f8ace8c6a1b42deb912b2a8fd8d942ddadb606b0"}, {file = "tomlkit-0.13.3.tar.gz", hash = "sha256:430cf247ee57df2b94ee3fbe588e71d362a941ebb545dec29b53961d61add2a1"}, ] [[package]] name = "typing-extensions" version = "4.15.0" description = "Backported and Experimental Type Hints for Python 3.9+" optional = false python-versions = ">=3.9" groups = ["dev", "docs", "lsp", "test"] files = [ {file = "typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548"}, {file = "typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466"}, ] markers = {test = "python_version == \"3.10\""} [[package]] name = "ujson" version = "5.11.0" description = "Ultra fast JSON encoder and decoder for Python" optional = false python-versions = ">=3.9" groups = ["lsp"] files = [ {file = "ujson-5.11.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:446e8c11c06048611c9d29ef1237065de0af07cabdd97e6b5b527b957692ec25"}, {file = "ujson-5.11.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:16ccb973b7ada0455201808ff11d48fe9c3f034a6ab5bd93b944443c88299f89"}, {file = "ujson-5.11.0-cp310-cp310-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3134b783ab314d2298d58cda7e47e7a0f7f71fc6ade6ac86d5dbeaf4b9770fa6"}, {file = "ujson-5.11.0-cp310-cp310-manylinux_2_24_i686.manylinux_2_28_i686.whl", hash = "sha256:185f93ebccffebc8baf8302c869fac70dd5dd78694f3b875d03a31b03b062cdb"}, {file = "ujson-5.11.0-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d06e87eded62ff0e5f5178c916337d2262fdbc03b31688142a3433eabb6511db"}, {file = "ujson-5.11.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:181fb5b15703a8b9370b25345d2a1fd1359f0f18776b3643d24e13ed9c036d4c"}, {file = "ujson-5.11.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:a4df61a6df0a4a8eb5b9b1ffd673429811f50b235539dac586bb7e9e91994138"}, {file = "ujson-5.11.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:6eff24e1abd79e0ec6d7eae651dd675ddbc41f9e43e29ef81e16b421da896915"}, {file = "ujson-5.11.0-cp310-cp310-win32.whl", hash = "sha256:30f607c70091483550fbd669a0b37471e5165b317d6c16e75dba2aa967608723"}, {file = "ujson-5.11.0-cp310-cp310-win_amd64.whl", hash = "sha256:3d2720e9785f84312b8e2cb0c2b87f1a0b1c53aaab3b2af3ab817d54409012e0"}, {file = "ujson-5.11.0-cp310-cp310-win_arm64.whl", hash = "sha256:85e6796631165f719084a9af00c79195d3ebf108151452fefdcb1c8bb50f0105"}, {file = "ujson-5.11.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d7c46cb0fe5e7056b9acb748a4c35aa1b428025853032540bb7e41f46767321f"}, {file = "ujson-5.11.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d8951bb7a505ab2a700e26f691bdfacf395bc7e3111e3416d325b513eea03a58"}, {file = "ujson-5.11.0-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:952c0be400229940248c0f5356514123d428cba1946af6fa2bbd7503395fef26"}, {file = "ujson-5.11.0-cp311-cp311-manylinux_2_24_i686.manylinux_2_28_i686.whl", hash = "sha256:94fcae844f1e302f6f8095c5d1c45a2f0bfb928cccf9f1b99e3ace634b980a2a"}, {file = "ujson-5.11.0-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7e0ec1646db172beb8d3df4c32a9d78015e671d2000af548252769e33079d9a6"}, {file = "ujson-5.11.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:da473b23e3a54448b008d33f742bcd6d5fb2a897e42d1fc6e7bf306ea5d18b1b"}, {file = "ujson-5.11.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:aa6b3d4f1c0d3f82930f4cbd7fe46d905a4a9205a7c13279789c1263faf06dba"}, {file = "ujson-5.11.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:4843f3ab4fe1cc596bb7e02228ef4c25d35b4bb0809d6a260852a4bfcab37ba3"}, {file = "ujson-5.11.0-cp311-cp311-win32.whl", hash = "sha256:e979fbc469a7f77f04ec2f4e853ba00c441bf2b06720aa259f0f720561335e34"}, {file = "ujson-5.11.0-cp311-cp311-win_amd64.whl", hash = "sha256:683f57f0dd3acdd7d9aff1de0528d603aafcb0e6d126e3dc7ce8b020a28f5d01"}, {file = "ujson-5.11.0-cp311-cp311-win_arm64.whl", hash = "sha256:7855ccea3f8dad5e66d8445d754fc1cf80265a4272b5f8059ebc7ec29b8d0835"}, {file = "ujson-5.11.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7895f0d2d53bd6aea11743bd56e3cb82d729980636cd0ed9b89418bf66591702"}, {file = "ujson-5.11.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:12b5e7e22a1fe01058000d1b317d3b65cc3daf61bd2ea7a2b76721fe160fa74d"}, {file = "ujson-5.11.0-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0180a480a7d099082501cad1fe85252e4d4bf926b40960fb3d9e87a3a6fbbc80"}, {file = "ujson-5.11.0-cp312-cp312-manylinux_2_24_i686.manylinux_2_28_i686.whl", hash = "sha256:fa79fdb47701942c2132a9dd2297a1a85941d966d8c87bfd9e29b0cf423f26cc"}, {file = "ujson-5.11.0-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8254e858437c00f17cb72e7a644fc42dad0ebb21ea981b71df6e84b1072aaa7c"}, {file = "ujson-5.11.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1aa8a2ab482f09f6c10fba37112af5f957689a79ea598399c85009f2f29898b5"}, {file = "ujson-5.11.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:a638425d3c6eed0318df663df44480f4a40dc87cc7c6da44d221418312f6413b"}, {file = "ujson-5.11.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:7e3cff632c1d78023b15f7e3a81c3745cd3f94c044d1e8fa8efbd6b161997bbc"}, {file = "ujson-5.11.0-cp312-cp312-win32.whl", hash = "sha256:be6b0eaf92cae8cdee4d4c9e074bde43ef1c590ed5ba037ea26c9632fb479c88"}, {file = "ujson-5.11.0-cp312-cp312-win_amd64.whl", hash = "sha256:b7b136cc6abc7619124fd897ef75f8e63105298b5ca9bdf43ebd0e1fa0ee105f"}, {file = "ujson-5.11.0-cp312-cp312-win_arm64.whl", hash = "sha256:6cd2df62f24c506a0ba322d5e4fe4466d47a9467b57e881ee15a31f7ecf68ff6"}, {file = "ujson-5.11.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:109f59885041b14ee9569bf0bb3f98579c3fa0652317b355669939e5fc5ede53"}, {file = "ujson-5.11.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a31c6b8004438e8c20fc55ac1c0e07dad42941db24176fe9acf2815971f8e752"}, {file = "ujson-5.11.0-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:78c684fb21255b9b90320ba7e199780f653e03f6c2528663768965f4126a5b50"}, {file = "ujson-5.11.0-cp313-cp313-manylinux_2_24_i686.manylinux_2_28_i686.whl", hash = "sha256:4c9f5d6a27d035dd90a146f7761c2272cf7103de5127c9ab9c4cd39ea61e878a"}, {file = "ujson-5.11.0-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:837da4d27fed5fdc1b630bd18f519744b23a0b5ada1bbde1a36ba463f2900c03"}, {file = "ujson-5.11.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:787aff4a84da301b7f3bac09bc696e2e5670df829c6f8ecf39916b4e7e24e701"}, {file = "ujson-5.11.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:6dd703c3e86dc6f7044c5ac0b3ae079ed96bf297974598116aa5fb7f655c3a60"}, {file = "ujson-5.11.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:3772e4fe6b0c1e025ba3c50841a0ca4786825a4894c8411bf8d3afe3a8061328"}, {file = "ujson-5.11.0-cp313-cp313-win32.whl", hash = "sha256:8fa2af7c1459204b7a42e98263b069bd535ea0cd978b4d6982f35af5a04a4241"}, {file = "ujson-5.11.0-cp313-cp313-win_amd64.whl", hash = "sha256:34032aeca4510a7c7102bd5933f59a37f63891f30a0706fb46487ab6f0edf8f0"}, {file = "ujson-5.11.0-cp313-cp313-win_arm64.whl", hash = "sha256:ce076f2df2e1aa62b685086fbad67f2b1d3048369664b4cdccc50707325401f9"}, {file = "ujson-5.11.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:65724738c73645db88f70ba1f2e6fb678f913281804d5da2fd02c8c5839af302"}, {file = "ujson-5.11.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:29113c003ca33ab71b1b480bde952fbab2a0b6b03a4ee4c3d71687cdcbd1a29d"}, {file = "ujson-5.11.0-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c44c703842024d796b4c78542a6fcd5c3cb948b9fc2a73ee65b9c86a22ee3638"}, {file = "ujson-5.11.0-cp314-cp314-manylinux_2_24_i686.manylinux_2_28_i686.whl", hash = "sha256:e750c436fb90edf85585f5c62a35b35082502383840962c6983403d1bd96a02c"}, {file = "ujson-5.11.0-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f278b31a7c52eb0947b2db55a5133fbc46b6f0ef49972cd1a80843b72e135aba"}, {file = "ujson-5.11.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ab2cb8351d976e788669c8281465d44d4e94413718af497b4e7342d7b2f78018"}, {file = "ujson-5.11.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:090b4d11b380ae25453100b722d0609d5051ffe98f80ec52853ccf8249dfd840"}, {file = "ujson-5.11.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:80017e870d882d5517d28995b62e4e518a894f932f1e242cbc802a2fd64d365c"}, {file = "ujson-5.11.0-cp314-cp314-win32.whl", hash = "sha256:1d663b96eb34c93392e9caae19c099ec4133ba21654b081956613327f0e973ac"}, {file = "ujson-5.11.0-cp314-cp314-win_amd64.whl", hash = "sha256:849e65b696f0d242833f1df4182096cedc50d414215d1371fca85c541fbff629"}, {file = "ujson-5.11.0-cp314-cp314-win_arm64.whl", hash = "sha256:e73df8648c9470af2b6a6bf5250d4744ad2cf3d774dcf8c6e31f018bdd04d764"}, {file = "ujson-5.11.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:de6e88f62796372fba1de973c11138f197d3e0e1d80bcb2b8aae1e826096d433"}, {file = "ujson-5.11.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:49e56ef8066f11b80d620985ae36869a3ff7e4b74c3b6129182ec5d1df0255f3"}, {file = "ujson-5.11.0-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1a325fd2c3a056cf6c8e023f74a0c478dd282a93141356ae7f16d5309f5ff823"}, {file = "ujson-5.11.0-cp314-cp314t-manylinux_2_24_i686.manylinux_2_28_i686.whl", hash = "sha256:a0af6574fc1d9d53f4ff371f58c96673e6d988ed2b5bf666a6143c782fa007e9"}, {file = "ujson-5.11.0-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:10f29e71ecf4ecd93a6610bd8efa8e7b6467454a363c3d6416db65de883eb076"}, {file = "ujson-5.11.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:1a0a9b76a89827a592656fe12e000cf4f12da9692f51a841a4a07aa4c7ecc41c"}, {file = "ujson-5.11.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:b16930f6a0753cdc7d637b33b4e8f10d5e351e1fb83872ba6375f1e87be39746"}, {file = "ujson-5.11.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:04c41afc195fd477a59db3a84d5b83a871bd648ef371cf8c6f43072d89144eef"}, {file = "ujson-5.11.0-cp314-cp314t-win32.whl", hash = "sha256:aa6d7a5e09217ff93234e050e3e380da62b084e26b9f2e277d2606406a2fc2e5"}, {file = "ujson-5.11.0-cp314-cp314t-win_amd64.whl", hash = "sha256:48055e1061c1bb1f79e75b4ac39e821f3f35a9b82de17fce92c3140149009bec"}, {file = "ujson-5.11.0-cp314-cp314t-win_arm64.whl", hash = "sha256:1194b943e951092db611011cb8dbdb6cf94a3b816ed07906e14d3bc6ce0e90ab"}, {file = "ujson-5.11.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:65f3c279f4ed4bf9131b11972040200c66ae040368abdbb21596bf1564899694"}, {file = "ujson-5.11.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:99c49400572cd77050894e16864a335225191fd72a818ea6423ae1a06467beac"}, {file = "ujson-5.11.0-cp39-cp39-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0654a2691fc252c3c525e3d034bb27b8a7546c9d3eb33cd29ce6c9feda361a6a"}, {file = "ujson-5.11.0-cp39-cp39-manylinux_2_24_i686.manylinux_2_28_i686.whl", hash = "sha256:6b6ec7e7321d7fc19abdda3ad809baef935f49673951a8bab486aea975007e02"}, {file = "ujson-5.11.0-cp39-cp39-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f62b9976fabbcde3ab6e413f4ec2ff017749819a0786d84d7510171109f2d53c"}, {file = "ujson-5.11.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:7f1a27ab91083b4770e160d17f61b407f587548f2c2b5fbf19f94794c495594a"}, {file = "ujson-5.11.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:ecd6ff8a3b5a90c292c2396c2d63c687fd0ecdf17de390d852524393cd9ed052"}, {file = "ujson-5.11.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:9aacbeb23fdbc4b256a7d12e0beb9063a1ba5d9e0dbb2cfe16357c98b4334596"}, {file = "ujson-5.11.0-cp39-cp39-win32.whl", hash = "sha256:674f306e3e6089f92b126eb2fe41bcb65e42a15432c143365c729fdb50518547"}, {file = "ujson-5.11.0-cp39-cp39-win_amd64.whl", hash = "sha256:c6618f480f7c9ded05e78a1938873fde68baf96cdd74e6d23c7e0a8441175c4b"}, {file = "ujson-5.11.0-cp39-cp39-win_arm64.whl", hash = "sha256:5600202a731af24a25e2d7b6eb3f648e4ecd4bb67c4d5cf12f8fab31677469c9"}, {file = "ujson-5.11.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:abae0fb58cc820092a0e9e8ba0051ac4583958495bfa5262a12f628249e3b362"}, {file = "ujson-5.11.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:fac6c0649d6b7c3682a0a6e18d3de6857977378dce8d419f57a0b20e3d775b39"}, {file = "ujson-5.11.0-pp311-pypy311_pp73-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4b42c115c7c6012506e8168315150d1e3f76e7ba0f4f95616f4ee599a1372bbc"}, {file = "ujson-5.11.0-pp311-pypy311_pp73-manylinux_2_24_i686.manylinux_2_28_i686.whl", hash = "sha256:86baf341d90b566d61a394869ce77188cc8668f76d7bb2c311d77a00f4bdf844"}, {file = "ujson-5.11.0-pp311-pypy311_pp73-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4598bf3965fc1a936bd84034312bcbe00ba87880ef1ee33e33c1e88f2c398b49"}, {file = "ujson-5.11.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:416389ec19ef5f2013592f791486bef712ebce0cd59299bf9df1ba40bb2f6e04"}, {file = "ujson-5.11.0.tar.gz", hash = "sha256:e204ae6f909f099ba6b6b942131cee359ddda2b6e4ea39c12eb8b991fe2010e0"}, ] [[package]] name = "urllib3" version = "2.5.0" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false python-versions = ">=3.9" groups = ["docs"] files = [ {file = "urllib3-2.5.0-py3-none-any.whl", hash = "sha256:e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc"}, {file = "urllib3-2.5.0.tar.gz", hash = "sha256:3fc47733c7e419d4bc3f6b3dc2b4f890bb743906a30d56ba4a5bfa4bbff92760"}, ] [package.extras] brotli = ["brotli (>=1.0.9) ; platform_python_implementation == \"CPython\"", "brotlicffi (>=0.8.0) ; platform_python_implementation != \"CPython\""] h2 = ["h2 (>=4,<5)"] socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] zstd = ["zstandard (>=0.18.0)"] [[package]] name = "virtualenv" version = "20.35.3" description = "Virtual Python Environment builder" optional = false python-versions = ">=3.8" groups = ["dev"] files = [ {file = "virtualenv-20.35.3-py3-none-any.whl", hash = "sha256:63d106565078d8c8d0b206d48080f938a8b25361e19432d2c9db40d2899c810a"}, {file = "virtualenv-20.35.3.tar.gz", hash = "sha256:4f1a845d131133bdff10590489610c98c168ff99dc75d6c96853801f7f67af44"}, ] [package.dependencies] distlib = ">=0.3.7,<1" filelock = ">=3.12.2,<4" platformdirs = ">=3.9.1,<5" typing-extensions = {version = ">=4.13.2", markers = "python_version < \"3.11\""} [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) ; platform_python_implementation == \"PyPy\" or platform_python_implementation == \"GraalVM\" or platform_python_implementation == \"CPython\" and sys_platform == \"win32\" and python_version >= \"3.13\"", "pytest-mock (>=3.11.1)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)", "setuptools (>=68)", "time-machine (>=2.10) ; platform_python_implementation == \"CPython\""] [[package]] name = "zipp" version = "3.23.0" description = "Backport of pathlib-compatible object wrapper for zip files" optional = false python-versions = ">=3.9" groups = ["lsp"] files = [ {file = "zipp-3.23.0-py3-none-any.whl", hash = "sha256:071652d6115ed432f5ce1d34c336c0adfd6a884660d1e9712a256d3d3bd4b14e"}, {file = "zipp-3.23.0.tar.gz", hash = "sha256:a07157588a12518c9d4034df3fbbee09c814741a33ff63c05fa29d26a2404166"}, ] [package.extras] check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1) ; sys_platform != \"cygwin\""] cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] enabler = ["pytest-enabler (>=2.2)"] test = ["big-O", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more_itertools", "pytest (>=6,!=8.1.*)", "pytest-ignore-flaky"] type = ["pytest-mypy"] [extras] chardet = ["chardet"] charset-normalizer = ["charset-normalizer"] file-magic = ["file-magic"] [metadata] lock-version = "2.1" python-versions = ">=3.10" content-hash = "f6baf943e3dba01a6cf2823643e1270691f72ac3c229c18016ae4407de40a6ae" reuse-tool-6.2.0/CHANGELOG.md0000664000175000017500000015072515077707000014111 0ustar alexalex # 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. ## v6.2.0 - 2025-10-27 ### Added - Added new file extensions and files: - `.arcconfig`, `.arclint`, `.arcunit` (#1123) - `.nvmrc` (#1211) - `.smk`, `Snakefile`, `matplotlibrc` (#1206) - `.yamllint` (#1124) - `uv.lock` (#1156) - `dune`, `dune-project`, `dune-workspace` (#1208) - `file-magic` is now supported as an additional module for detecting the encoding of files. (#1264) - Support deprecated licences for `reuse download`. (#606) - Markdown files which have frontmatter (i.e. yaml or toml between a `---` block at the start of the file) now get Python-like comments inside of the frontmatter when annotating. (#1170) ### Fixed - When `file-magic` is installed simultaneously with `python-magic`, the tool used to misbehave (read: crash), because either one of them could be imported on `import magic`. This misbehaviour no longer happens. (#1264) - Invalid SPDX license expressions are no longer recognized as used or missing licenses. (#1254) - `click` translations are now correctly loaded. (#1267) ## v6.1.2 - 2025-10-08 ### Fixed - Fixed a bug where a newline would sometimes be missing from `reuse lint --lines`. (#1251) - The output of `reuse lint --lines` is now sorted by path name. (#1251) - Fixed a performance regression introduced in v6.1.1 that would cause some copyright notices to take incredibly long to parse. (#1252) ## v6.1.1 - 2025-10-07 ### Changed - In the Docker images, Alpine is bumped to `alpine:3.22` and Debian to `debian:13-slim`. (#1247) ### Fixed - ASCII frames around comments were broken in v6.0.0. They now work again. The sole condition is that the 'suffix' of a comment is identical to its 'prefix'. For example: ``` /*******************************************\ |* SPDX-License-Identifier: CC-BY-SA-4.0 *| \*******************************************/ ``` (#1249) ## v6.1.0 - 2025-10-07 This release adds a simple feature as a workaround for a bug that will be resolved in a later version. The bug is described in , and can be summarised as: When `charset-normalizer` is used to detect the encoding of a file, it will erroneously detect a UTF-8 file as having no encoding (i.e. a binary file) when the 2048th byte is a non-final byte of a multi-byte glyph. You can run reuse as `REUSE_ENCODING_MODULE=chardet reuse` to circumvent this bug. If you use pre-commit, you can use this snippet: ```yaml repos: - repo: https://github.com/fsfe/reuse-tool rev: v6.1.0 hooks: - id: reuse entry: env REUSE_ENCODING_MODULE=chardet reuse ``` You will not encounter this bug if your environment has libmagic available. ### Added - You can now specify the module that will be used for detecting the encoding of files with the `REUSE_ENCODING_MODULE` environment variable. (#1245) - The Docker images and the pre-commit hooks now come bundled with all encoding modules. (#1245) - The `--debug` flag now tells you the detected encoding and detected newlines of each file, as well as which encoding module is used. (#1246) ## v6.0.0 - 2025-10-06 This release contains a lot of refactoring regarding the parsing of files. The most impactful details are that `reuse lint` now searches every file in its entirety for REUSE information, tries to detect each file's encoding, and no longer breaks when invalid SPDX License Expressions are detected. Because files are now read in their entireties instead of just the first 4 KiB, you may need to add `REUSE-IgnoreStart` and `REUSE-IgnoreEnd` tags to get rid of false positives that were previously too deep into files for `reuse` to detect. **For package maintainers:** This release removes, adds, and changes dependencies. It merits running `git diff v5.1.1..v6.0.0 pyproject.toml` and reading the 'Changed' section of this change log to see what changed. ### Added - Added new file extensions: - `py.typed` (#1239) - `.blade.php` (#573) - A new criterion 'Invalid SPDX License Expressions' has been added to `reuse lint`. Invalid expressions are SPDX License Expressions which are not valid according to the grammar of the SPDX specification. (#1240) ### Changed - Python 3.9 support dropped. (#1219) - The Python requirement for `reuse` now no longer requires a lower major version than 4. The requirement is now `>=3.10` instead of `>=3.10,<4`. (#1219) - Dependency changes: - Removed explicit dependency `boolean.boolean`. It is now an implicit dependency via `license-expression`. (#1240) - The dependency `python-magic` has been added, alongside the optional dependencies `charset-normalizer` and `chardet`. So long as at least one of these is installed, the program will work. (#1235) - The dependency `binaryornot` has been removed. (#1235) - The minimum requirements of several dependencies have been updated. (#1235, #1241) - `reuse lint` now always searches the entire file for REUSE information. Previously, it only searched the first 4 KiB under most circumstances. (#1229) - The encodings of files are now detected before they are read or altered. (#1235, #1218) - The 'Bad licenses' criterion in `reuse lint` previously searched for bad licenses in every single file. Now, only bad licenses in `LICENSES/` are detected, which is more in line with the documentation. (#1240) - The behaviour of the `--year` option to `reuse annotate`is now different. Previously, you could define `--year ` multiple times. Now you can only do so once, but the value may be a string containing multiple years or a range of years. (#1145) - `reuse annotate --merge-copyrights` works more efficiently now, capable of better heuristics to detect years and year ranges. (#1145) - `reuse annotate --merge-copyrights` no longer adds spacing around the merged year ranges. i.e. `2017-2025`, not `2017 - 2025`. (#1145) ### Fixed - Unparseable SPDX expressions in a file now no longer cause the collection of REUSE information from that file to entirely fail. (#1240) - Files with carriage return (`\r`) line endings are now correctly linted. (#1235, #1226) - There used to be a specific scenario where `reuse lint` would read the contents of an entire file into memory. This no longer happens. `reuse annotate` will still read the entire file into memory. (#1229) - Fixed formatting in `lint` subcommand help message. (#1212, #1236) - Fixed a case where, if a recognised file extension (such as `.blade.php`) has two or more components, it would not be correctly recognised. (#573) - Fixed a bug where, if `REUSE-IgnoreStart` is the very first thing that appears in a file, the subsequent text is not actually ignored. (#1229) - If using `reuse annotate` to write to a file, the BOM is preserved if the encoding is UTF-8, UTF-16, or UTF-32. (#1235, #384) - The summaries of `reuse lint` are now sorted better. (#1241) - Several performance improvements. Local testing on a 12-core laptop suggests speedup of up to 50%, but it may depend on your repository. (#1222, #1223, #1230, #1241) ## v5.1.1 - 2025-09-05 ### Fixed - Fixed repository file detection using jujutsu versions 0.19.0 or later. (#1191) - Fixed a bug that caused not all strings to be marked translatable. This bug was introduced in v5.0.0. Strings that were already translated _before_ the release of v5.0.0 are now translated again. (#1216) ## v5.1.0 - 2025-09-04 ### Added - Added new file extensions: - `.dtd` (#1141) - `.gperf` (#1131) - Erlang `.erl` and `.hrl`, leex and yecc Erlang parser generators `.xrl` and `.yrl` (#1117) - Elixir (`.ex` and `.exs`) (#1117) - Gleam (`.gleam`) (#1117) - Lean (`.lean`, `.olean`, and `.ilean`) (#1188) - Added `--json` flag to the `supported-licenses` subcommand. (#1187) ### Changed - Revert `Cargo.lock` to uncommentable. (#1169) - `reuse annotate` previously would insert a newline after a header, which is not always a desirable behavior. Instead of inserting a newline, `reuse annotate` will now respect the existing whitespace of the file where the header is being placed. When the license header is being added to a file for the first time, a space will be added after the license, but subsequent updates to the header will leave the whitespace alone. (#1136) - Updated `spdx-license-list-data` to v3.27.0. ## v5.0.2 - 2024-11-14 ### Fixed - The release date for the v5.0.0 entry in the change log was wrong. ## v5.0.1 - 2024-11-14 ### Fixed - Fix readthedocs build. ## v5.0.0 - 2024-11-14 This is a big release for a small change set. With this release, the tool becomes compatible with [REUSE Specification 3.3](https://reuse.software/spec-3.3), which is a very subtly improved release of the much bigger version 3.2. ### Added - More file types are recognised: - Cabal (`.cabal`, `cabal.project`) (#1089, #1090) - `.envrc` (#1061) - `.flake.lock` (#1061) - Ansible Jinja2 (`.j2`) (#1036) - Poetry lock file (`poetry.lock`) (#1037) - Added `lint-file` subcommand to enable running lint on specific files. (#1055) - Added shell completion via `click`. (#1084) - Added Jujutsu VCS support. (#1051) - Added new copyright prefixes `spdx-string`, `spdx-string-c`, and `spdx-string-symbol`. (#979) - Support for Python 3.13. (#1092) ### Changed - Bumped REUSE Specification version to [version 3.3](https://reuse.software/spec-3.3). (#1069) - Switched from `argparse` to `click` for handling the CLI. The CLI should still handle the same, with identical options and arguments, but some stuff changed under the hood. (#1084) Find here a small list of differences: - `-h` is no longer shorthand for `--help`. - `--version` now outputs "reuse, version X.Y.Z", followed by a licensing blurb on different paragraphs. - Some options are made explicitly mutually exclusive, such as `annotate`'s `--skip-unrecognised` and `--style`, and `download`'s `--output` and `--all`. - Subcommands which take a list of things (files, license) as arguments, such as `annotate`, `lint-file`, or `download`, now also allow zero arguments. This will do nothing, but can be useful in scripting. - `annotate` and `lint-file` now also take directories as arguments. This will do nothing, but can be useful in scripting. - Changes to comment styles: - Allow Python-style comments in Cargo.lock files. (#1060) - `.s` files (GNU as) now use the C comment style. (#1034) - `.ld` files (GNU ld) now use the C comment style. (#1034) - `REUSE.toml` no longer needs a licensing header. (#1042) - `.gitkeep` is no longer ignored, because this is not defined in the specification. However, if `.gitkeep` is a 0-size file, it will remain ignored (because 0-size files are ignored). (#1043) - If `REUSE.toml` is ignored by VCS, the linter no longer parses this file. (#1047) - SPDX license and exception list updated to v3.25.0. - More `LICENSE` and `COPYING`-like files are ignored. Now, such files suffixed by `-anything` are also ignored, typically something like `LICENSE-MIT`. Files with the UK spelling `LICENCE` are also ignored. (#1041) ### Removed - Python 3.8 support removed. (#1080) ### Fixed - In `REUSE.toml`, fixed the globbing of a single asterisk succeeded by a slash (e.g. `directory-*/foo.py`). The glob previously did nothing. (#1078) - Increased the minimum requirement of `attrs` to `>=21.3`. Older versions do not import correctly. (#1044) - Performance greatly improved for projects with large directories ignored by VCS. (#1047) - Performance slightly improved for large projects. (#1047) - The plain output of `lint` has been slightly improved, getting rid of an errant newline. (#1091) - `reuse annotate --merge-copyrights` now works more reliably with copyright prefixes. This still needs some work, though. (#979) - In some scenarios, where a user has multiple `REUSE.toml` files and one of those files could not be parsed, the wrong `REUSE.toml` was signalled as being unparseable. This is now fixed. (#1047) - Fixed a bug where `REUSE.toml` did not correctly apply its annotations to files which have an accompanying `.license` file. (#1058) - When running `reuse download SPDX-IDENTIFIER+`, download `SPDX-IDENTIFIER` instead. This also works for `reuse download --all`. (#1098) ## v4.0.3 - 2024-07-08 ### Fixed - Increased the minimum requirement of `attrs` to `>=21.3`. Older versions do not import correctly. (#1044) ## v4.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) ## v4.0.1 - 2024-07-03 ### Fixed - Make sure that Read the Docs can compile the documentation. This necesitated updating `poetry.lock`. (#1028) ## v4.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) ## v3.0.2 - 2024-04-08 ### Fixed - `annotate`'s '`--style` now works again when used for a file with an unrecognised extension. (#909) ## v3.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) ## v3.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) ## v2.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 ## v2.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. ## v1.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) ## v1.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) ## v1.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`. ## v0.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. ## v0.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. ## v0.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. ## v0.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 ';'. ## v0.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. ## v0.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. ## v0.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 . ## v0.3.3 - 2018-07-15 ### Fixed - Any files with the suffix `.spdx` are no longer considered licenses. ## v0.3.2 - 2018-07-15 ### Fixed - The documentation now builds under Python 3.7. ## v0.3.1 - 2018-07-14 ### Fixed - When using reuse from a child directory using pygit2, correctly find the root. ## v0.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. ## v0.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. ## v0.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. ## v0.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. ## v0.0.4 - 2017-11-06 ### Fixed - Removed dependency on `os.PathLike` so that Python 3.5 is actually supported ## v0.0.3 - 2017-11-06 ### Fixed - Fixed the link to PyPI in the README. ## v0.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-6.2.0/Makefile0000664000175000017500000000605715077707000013736 0ustar alexalex# 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 .mypy_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 $(shell find src/reuse -name '*.py') xgettext --add-comments --output=po/click.pot $(shell find "${VIRTUAL_ENV}"/lib/python*/*-packages/click -name '*.py') msgcat --output=po/reuse.pot po/reuse.pot po/click.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-6.2.0/CONTRIBUTING.md0000664000175000017500000001363315077707000014525 0ustar alexalex # 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. **Pull requests need not be perfect.** Not all the tests need to pass. A pull request with 80% of the work done is a lot better than no pull request at all. We can work together on making the pull request merge-ready, or the maintainers can finalise the pull request for you. Making a pull request generally necessitates the following steps: ### Set up 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` ### Make changes This is the tricky bit for which no development guide exists. You make changes somewhere in the code. If you can, do the following things: - Write docstrings. - Add type hinting. - Write tests. - Update documentation. - Add self as author to every touched file. - Add self to `AUTHORS.rst`. ### Commit and submit a pull request As part of committing, `pre-commit` should run some checks. If you can easily fix them, fix them. If you get stuck here, **do not worry**. Just skip the pre-commit step with `git commit -n`, and make a pull request. The maintainers will be happy to fix those annoying things. ### Make a change log entry 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. ## 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 - Create branch release-x.y.z - `bumpver update --set-version vx.y.z` - `make update-resources` - `protokolo compile -f version vx.y.z` - Alter changelog - `poetry lock` (otherwise documentation won't generate; ). Update versions in `.pre-commit-config.yaml` as necessary. - Bump Alpine and Debian in Dockerfile. - Do some final tweaks/bugfixes (and alter changelog) - `make test-release` - `pip install -i https://test.pypi.org/simple reuse` and test the package. - Make a pull request of `release-x.y.z` against `main`. - Once everything is good, `git tag -s vx.y.z`. Minimal tag message. - `git push origin vx.y.z` - `make release` - Accept the PR. - 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-6.2.0/docs/0000775000175000017500000000000015077707000013216 5ustar alexalexreuse-tool-6.2.0/docs/scripts.rst0000664000175000017500000001433115077707000015441 0ustar alexalex.. SPDX-FileCopyrightText: 2022 Nico Rikken SPDX-FileCopyrightText: 2025 Matthias Schoettle SPDX-FileCopyrightText: 2025 Simon Barth 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 Year of first commit while following renames ============================================ If you want to follow file renames in the Git history, you can use the `--follow` argument. This requires you to pass the file to `git log`. .. SPDX-SnippetBegin .. SPDX-Snippet-License-Identifier: CC0-1.0 .. code-block:: console $ git log --follow --date="format:%Y" --format="format:%cd" -- docs/scripts.rst | tail -n 1 2022 .. 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-6.2.0/docs/conf.py0000664000175000017500000001151315077707000014516 0ustar alexalex# 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 = "6.2.0" # 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 = ["cli"] 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)} # Auto-generate header anchors up to 3 headings deep. myst_heading_anchors = 3 # -- 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-lint-file", "reuse-lint-file", "Verify whether the specified files are 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, ), ] manpages_url = ( "https://reuse.readthedocs.io/en/v{version}/man/{page}.html".format( version=version, page="{page}" ) ) # -- 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-6.2.0/docs/reuse-r-only.svg0000664000175000017500000001275015077707000016305 0ustar alexalex image/svg+xml reuse-tool-6.2.0/docs/man/0000775000175000017500000000000015077707000013771 5ustar alexalexreuse-tool-6.2.0/docs/man/reuse-convert-dep5.rst0000664000175000017500000000300615077707000020156 0ustar alexalex.. 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:: --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-6.2.0/docs/man/reuse-supported-licenses.rst0000664000175000017500000000152215077707000021474 0ustar alexalex.. SPDX-FileCopyrightText: 2024 Free Software Foundation Europe e.V. SPDX-FileCopyrightText: 2025 Shun Sakai 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:: -j, --json Output the list as JSON. .. option:: --help Display help and exit. reuse-tool-6.2.0/docs/man/reuse-download.rst0000664000175000017500000000213315077707000017452 0ustar alexalex.. 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 PATH 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:: --help Display help and exit. reuse-tool-6.2.0/docs/man/reuse-lint.rst0000664000175000017500000000522215077707000016613 0ustar alexalex.. 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. Invalid SPDX License Expressions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ SPDX License Expressions that follow ``SPDX-License-Identifier`` tags which are not parseable as valid SPDX. 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 a ``REUSE.toml`` file, which must be in an ancestor directory relative to the 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. This option is the default. .. option:: -l, --lines Output one line per error, prefixed by the file path. .. option:: --help Display help and exit. reuse-tool-6.2.0/docs/man/reuse-lint-file.rst0000664000175000017500000000215015077707000017525 0ustar alexalex.. SPDX-FileCopyrightText: 2019 Free Software Foundation Europe e.V. SPDX-FileCopyrightText: © 2020 Liferay, Inc. SPDX-License-Identifier: CC-BY-SA-4.0 reuse-lint-file =============== Synopsis -------- **reuse lint-file** [*options*] [*file* ...] Description ----------- :program:`reuse-lint-file` verifies whether the specified files are compliant with the REUSE Specification located at ``_. It runs the linter from :manpage:`reuse-lint(1)` against a subset of files, using a subset of criteria. Files that are ignored by :program:`reuse-lint` are also ignored by :program:`reuse-lint-file`, even if specified. Criteria -------- The criteria are the same as used in :manpage:`reuse-lint(1)`, but using only a subset: - Missing licenses. - Read errors. - Files without copyright and license information. Options ------- .. option:: -q, --quiet Do not print anything to STDOUT. .. option:: -l, --lines Output one line per error, prefixed by the file path. This option is the default. .. option:: --help Display help and exit. reuse-tool-6.2.0/docs/man/reuse-annotate.rst0000664000175000017500000001716415077707000017466 0ustar alexalex.. 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). You can repeat these options. .. 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. .. option:: -l, --license LICENSE An SPDX license identifier. .. option:: --contributor CONTRIBUTOR A name of a contributor. The contributor will be added via the ``SPDX-FileContributor:`` tag. Other options ------------- .. option:: -y, --year YEAR Define the year of the copyright notice(s). If not defined, the year defaults to the current year. The value may be a (complex) range, such as '2017-2019', or '2017, 2019-2022, 2024-Present'. .. 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 notice. 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: © spdx-string: SPDX-FileCopyrightText: Copyright spdx-string-c: SPDX-FileCopyrightText: Copyright (C) spdx-string-symbol: SPDX-FileCopyrightText: Copyright © 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:: --help Display help and exit. Templates --------- When the tool adds a header to a file, it normally first lists all copyright notices 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-6.2.0/docs/man/index.rst0000664000175000017500000000072715077707000015640 0ustar alexalex.. 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-lint-file reuse-spdx reuse-supported-licenses reuse-tool-6.2.0/docs/man/reuse-spdx.rst0000664000175000017500000000167315077707000016631 0ustar alexalex.. 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:: --help Display help and exit. reuse-tool-6.2.0/docs/man/reuse.rst0000664000175000017500000000666515077707000015663 0ustar alexalex.. SPDX-FileCopyrightText: 2019 Free Software Foundation Europe e.V. SPDX-FileCopyrightText: © 2020 Liferay, Inc. SPDX-FileCopyrightText: 2024 Emil Velikov 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 entire 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. 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. 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:: --help Display help and exit. If no command is provided, this option is implied. .. option:: --version Display the version and exit. Environment ----------- :program:`reuse` respects the following environment variables. .. describe:: REUSE_ENCODING_MODULE Instead of automatically picking the best module to detect the encodings of files, :program:`reuse` will use the module defined here. Its value must be ``python-magic``, ``file-magic``, ``charset_normalizer``, or ``chardet``. 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-lint-file(1)` Verify whether individual files are 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-6.2.0/docs/reuse-r-only.svg.license0000664000175000017500000000015115077707000017716 0ustar alexalexSPDX-FileCopyrightText: 2023 Free Software Foundation Europe e.V. SPDX-License-Identifier: CC-BY-SA-4.0 reuse-tool-6.2.0/docs/authors.rst0000664000175000017500000000024415077707000015435 0ustar alexalex.. SPDX-FileCopyrightText: 2017 Free Software Foundation Europe e.V. SPDX-License-Identifier: CC-BY-SA-4.0 .. include:: ../AUTHORS.rst reuse-tool-6.2.0/docs/_static/0000775000175000017500000000000015077707000014644 5ustar alexalexreuse-tool-6.2.0/docs/_static/.gitkeep0000664000175000017500000000000015077707000016263 0ustar alexalexreuse-tool-6.2.0/docs/index.rst0000664000175000017500000000204115077707000015054 0ustar alexalex.. 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-6.2.0/docs/Makefile0000664000175000017500000000140615077707000014657 0ustar alexalex# SPDX-FileCopyrightText: 2017 Free Software Foundation Europe e.V. # SPDX-FileCopyrightText: 2025 Simon Barth # # SPDX-License-Identifier: GPL-3.0-or-later # You can set these variables from the command line. SPHINXOPTS ?= --fail-on-warning 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-6.2.0/docs/usage.rst.license0000664000175000017500000000030015077707000016466 0ustar alexalexSPDX-FileCopyrightText: 2019 Free Software Foundation Europe e.V. SPDX-FileCopyrightText: © 2020 Liferay, Inc. SPDX-License-Identifier: CC-BY-SA-4.0 reuse-tool-6.2.0/.readthedocs.yaml0000664000175000017500000000075215077707000015521 0ustar alexalex# 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.10" 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-6.2.0/.pylintrc0000664000175000017500000000443715077707000014143 0ustar alexalex# 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, inconsistent-quotes, too-many-positional-arguments 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-6.2.0/.pre-commit-config.yaml0000664000175000017500000000235415077707000016553 0ustar alexalex# 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: 25.9.0 hooks: - id: black - repo: https://github.com/pycqa/isort rev: 7.0.0 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.18.2 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==25.4.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 ]