From 510fd6e3a32a1c70dff7bf703ccbf554683fabbd Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Tue, 14 May 2024 18:23:19 +0200 Subject: Merging upstream version 0.1.33. Signed-off-by: Daniel Baumann --- tests/lint_tests/lint_tutil.py | 10 +- tests/lint_tests/test_lint_dcpy.py | 64 +++++++ tests/lint_tests/test_lint_dctrl.py | 265 +++++++++++++++++++++++++- tests/lint_tests/test_lint_dpatches_series.py | 152 +++++++++++++++ 4 files changed, 478 insertions(+), 13 deletions(-) create mode 100644 tests/lint_tests/test_lint_dcpy.py create mode 100644 tests/lint_tests/test_lint_dpatches_series.py (limited to 'tests/lint_tests') diff --git a/tests/lint_tests/lint_tutil.py b/tests/lint_tests/lint_tutil.py index 26df505..65fe0ad 100644 --- a/tests/lint_tests/lint_tutil.py +++ b/tests/lint_tests/lint_tutil.py @@ -3,8 +3,8 @@ from typing import List, Optional, Mapping, Any, Callable import pytest +from debputy.filesystem_scan import VirtualPathBase from debputy.linting.lint_util import ( - LinterImpl, LinterPositionCodec, LintStateImpl, LintState, @@ -44,6 +44,7 @@ class LintWrapper: self.dctrl_lines: Optional[List[str]] = None self.path = path self._dctrl_parser = dctrl_parser + self.source_root: Optional[VirtualPathBase] = None self.lint_style_preference_table = StylePreferenceTable({}, {}) self.effective_preference: Optional[EffectivePreference] = None @@ -57,11 +58,13 @@ class LintWrapper: dctrl_lines, ignore_errors=True ) ) + source_root = self.source_root + debian_dir = source_root.get("debian") if source_root is not None else None state = LintStateImpl( self._debputy_plugin_feature_set, self.lint_style_preference_table, - None, - None, + source_root, + debian_dir, self.path, "".join(dctrl_lines) if dctrl_lines is not None else "", lines, @@ -84,6 +87,7 @@ def check_diagnostics( if diagnostics: for diagnostic in diagnostics: assert diagnostic.severity is not None + assert diagnostic.source is not None return diagnostics diff --git a/tests/lint_tests/test_lint_dcpy.py b/tests/lint_tests/test_lint_dcpy.py new file mode 100644 index 0000000..f827d3e --- /dev/null +++ b/tests/lint_tests/test_lint_dcpy.py @@ -0,0 +1,64 @@ +import textwrap + +import pytest + +from debputy.lsp.lsp_debian_copyright import _lint_debian_copyright +from debputy.packages import DctrlParser +from debputy.plugin.api.feature_set import PluginProvidedFeatureSet +from lint_tests.lint_tutil import ( + group_diagnostics_by_severity, + LintWrapper, +) + +try: + from lsprotocol.types import Diagnostic, DiagnosticSeverity +except ImportError: + pass + + +@pytest.fixture +def line_linter( + debputy_plugin_feature_set: PluginProvidedFeatureSet, + lint_dctrl_parser: DctrlParser, +) -> LintWrapper: + return LintWrapper( + "/nowhere/debian/copyright", + _lint_debian_copyright, + debputy_plugin_feature_set, + lint_dctrl_parser, + ) + + +def test_dcpy_files_lint(line_linter: LintWrapper) -> None: + lines = textwrap.dedent( + """\ + Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ + + Files: foo .//unnecessary///many/slashes + Copyright: Noone + License: something + yada yada yada + """ + ).splitlines(keepends=True) + + diagnostics = line_linter(lines) + by_severity = group_diagnostics_by_severity(diagnostics) + assert DiagnosticSeverity.Warning in by_severity + + assert DiagnosticSeverity.Error not in by_severity + assert DiagnosticSeverity.Hint not in by_severity + assert DiagnosticSeverity.Information not in by_severity + + warnings = by_severity[DiagnosticSeverity.Warning] + print(warnings) + assert len(warnings) == 2 + + first_warn, second_warn = warnings + + msg = 'Unnecessary prefix ".//"' + assert first_warn.message == msg + assert f"{first_warn.range}" == "2:11-2:14" + + msg = 'Simplify to a single "/"' + assert second_warn.message == msg + assert f"{second_warn.range}" == "2:25-2:28" diff --git a/tests/lint_tests/test_lint_dctrl.py b/tests/lint_tests/test_lint_dctrl.py index bcb1613..7e9477e 100644 --- a/tests/lint_tests/test_lint_dctrl.py +++ b/tests/lint_tests/test_lint_dctrl.py @@ -4,6 +4,7 @@ from typing import List, Optional import pytest from debputy.lsp.lsp_debian_control import _lint_debian_control +from debputy.lsp.lsp_debian_control_reference_data import CURRENT_STANDARDS_VERSION from debputy.packages import DctrlParser from debputy.plugin.api.feature_set import PluginProvidedFeatureSet from lint_tests.lint_tutil import ( @@ -18,9 +19,6 @@ except ImportError: pass -STANDARDS_VERSION = "4.7.0" - - class DctrlLintWrapper(LintWrapper): def __call__(self, lines: List[str]) -> Optional[List["Diagnostic"]]: @@ -104,7 +102,7 @@ def test_dctrl_lint_typos(line_linter: LintWrapper) -> None: lines = textwrap.dedent( f"""\ Source: foo - Standards-Version: {STANDARDS_VERSION} + Standards-Version: {CURRENT_STANDARDS_VERSION} Priority: optional Section: devel Maintainer: Jane Developer @@ -137,7 +135,7 @@ def test_dctrl_lint_mx_value_with_typo(line_linter: LintWrapper) -> None: lines = textwrap.dedent( f"""\ Source: foo - Standards-Version: {STANDARDS_VERSION} + Standards-Version: {CURRENT_STANDARDS_VERSION} Priority: optional Section: devel Maintainer: Jane Developer @@ -176,7 +174,7 @@ def test_dctrl_lint_mx_value(line_linter: LintWrapper) -> None: lines = textwrap.dedent( f"""\ Source: foo - Standards-Version: {STANDARDS_VERSION} + Standards-Version: {CURRENT_STANDARDS_VERSION} Priority: optional Section: devel Maintainer: Jane Developer @@ -205,7 +203,7 @@ def test_dctrl_lint_mx_value(line_linter: LintWrapper) -> None: lines = textwrap.dedent( f"""\ Source: foo - Standards-Version: {STANDARDS_VERSION} + Standards-Version: {CURRENT_STANDARDS_VERSION} Priority: optional Section: devel Maintainer: Jane Developer @@ -238,14 +236,14 @@ def test_dctrl_lint_dup_sep(line_linter: LintWrapper) -> None: Source: foo Section: devel Priority: optional - Standards-Version: {STANDARDS_VERSION} + Standards-Version: {CURRENT_STANDARDS_VERSION} Maintainer: Jane Developer Build-Depends: debhelper-compat (= 13) Package: foo Architecture: all - Depends: foo, - , bar + Depends: bar, + , baz Description: Some very interesting synopsis A very interesting description that spans multiple lines @@ -263,3 +261,250 @@ def test_dctrl_lint_dup_sep(line_linter: LintWrapper) -> None: assert error.message == msg assert f"{error.range}" == "10:1-10:2" assert error.severity == DiagnosticSeverity.Error + + +def test_dctrl_lint_ma(line_linter: LintWrapper) -> None: + lines = textwrap.dedent( + f"""\ + Source: foo + Section: devel + Priority: optional + Standards-Version: {CURRENT_STANDARDS_VERSION} + Maintainer: Jane Developer + Build-Depends: debhelper-compat (= 13) + + Package: foo + Architecture: all + Multi-Arch: same + Depends: bar, baz + Description: Some very interesting synopsis + A very interesting description + that spans multiple lines + . + Just so be clear, this is for a test. + """ + ).splitlines(keepends=True) + + diagnostics = line_linter(lines) + print(diagnostics) + assert diagnostics and len(diagnostics) == 1 + error = diagnostics[0] + + msg = "Multi-Arch: same is not valid for Architecture: all packages. Maybe you want foreign?" + assert error.message == msg + assert f"{error.range}" == "9:12-9:16" + assert error.severity == DiagnosticSeverity.Error + + +def test_dctrl_lint_udeb(line_linter: LintWrapper) -> None: + lines = textwrap.dedent( + f"""\ + Source: foo + Section: devel + Priority: optional + Standards-Version: {CURRENT_STANDARDS_VERSION} + Maintainer: Jane Developer + Build-Depends: debhelper-compat (= 13) + + Package: foo + Architecture: all + XB-Installer-Menu-Item: 1234 + Depends: bar, baz + Description: Some very interesting synopsis + A very interesting description + that spans multiple lines + . + Just so be clear, this is for a test. + + Package: bar-udeb + Architecture: all + Section: debian-installer + Package-Type: udeb + XB-Installer-Menu-Item: golf + Description: Some very interesting synopsis + A very interesting description + that spans multiple lines + . + Just so be clear, this is for a test. + """ + ).splitlines(keepends=True) + + diagnostics = line_linter(lines) + print(diagnostics) + assert diagnostics and len(diagnostics) == 2 + first, second = diagnostics + + msg = "The XB-Installer-Menu-Item field is only applicable to udeb packages (`Package-Type: udeb`)" + assert first.message == msg + assert f"{first.range}" == "9:0-9:22" + assert first.severity == DiagnosticSeverity.Warning + + msg = r'The value "golf" does not match the regex ^[1-9]\d{3,4}$.' + assert second.message == msg + assert f"{second.range}" == "21:24-21:28" + assert second.severity == DiagnosticSeverity.Error + + +def test_dctrl_lint_arch_only_fields(line_linter: LintWrapper) -> None: + lines = textwrap.dedent( + f"""\ + Source: foo + Section: devel + Priority: optional + Standards-Version: {CURRENT_STANDARDS_VERSION} + Maintainer: Jane Developer + Build-Depends: debhelper-compat (= 13) + + Package: foo + Architecture: all + X-DH-Build-For-Type: target + Depends: bar, baz + Description: Some very interesting synopsis + A very interesting description + that spans multiple lines + . + Just so be clear, this is for a test. + """ + ).splitlines(keepends=True) + + diagnostics = line_linter(lines) + print(diagnostics) + assert diagnostics and len(diagnostics) == 1 + issue = diagnostics[0] + + msg = "The X-DH-Build-For-Type field is not applicable to arch:all packages (`Architecture: all`)" + assert issue.message == msg + assert f"{issue.range}" == "9:0-9:19" + assert issue.severity == DiagnosticSeverity.Warning + + +def test_dctrl_lint_sv(line_linter: LintWrapper) -> None: + lines = textwrap.dedent( + f"""\ + Source: foo + Section: devel + Priority: optional + Standards-Version: 4.6.2 + Maintainer: Jane Developer + Build-Depends: debhelper-compat (= 13) + + Package: foo + Architecture: all + Depends: bar, baz + Description: Some very interesting synopsis + A very interesting description + that spans multiple lines + . + Just so be clear, this is for a test. + """ + ).splitlines(keepends=True) + + diagnostics = line_linter(lines) + print(diagnostics) + assert diagnostics and len(diagnostics) == 1 + issue = diagnostics[0] + + msg = f"Latest Standards-Version is {CURRENT_STANDARDS_VERSION}" + assert issue.message == msg + assert f"{issue.range}" == "3:19-3:24" + assert issue.severity == DiagnosticSeverity.Information + + lines = textwrap.dedent( + f"""\ + Source: foo + Section: devel + Priority: optional + Standards-Version: Golf + Maintainer: Jane Developer + Build-Depends: debhelper-compat (= 13) + + Package: foo + Architecture: all + Depends: bar, baz + Description: Some very interesting synopsis + A very interesting description + that spans multiple lines + . + Just so be clear, this is for a test. + """ + ).splitlines(keepends=True) + + diagnostics = line_linter(lines) + print(diagnostics) + assert diagnostics and len(diagnostics) == 1 + issue = diagnostics[0] + + msg = f'Not a valid version. Current version is "{CURRENT_STANDARDS_VERSION}"' + assert issue.message == msg + assert f"{issue.range}" == "3:19-3:23" + assert issue.severity == DiagnosticSeverity.Warning + + lines = textwrap.dedent( + f"""\ + Source: foo + Section: devel + Priority: optional + Standards-Version: {CURRENT_STANDARDS_VERSION}.0 + Maintainer: Jane Developer + Build-Depends: debhelper-compat (= 13) + + Package: foo + Architecture: all + Depends: bar, baz + Description: Some very interesting synopsis + A very interesting description + that spans multiple lines + . + Just so be clear, this is for a test. + """ + ).splitlines(keepends=True) + + diagnostics = line_linter(lines) + print(diagnostics) + assert diagnostics and len(diagnostics) == 1 + issue = diagnostics[0] + + msg = "Unnecessary version segment. This part of the version is only used for editorial changes" + assert issue.message == msg + assert f"{issue.range}" == "3:24-3:26" + assert issue.severity == DiagnosticSeverity.Information + + +def test_dctrl_lint_multiple_vcs(line_linter: LintWrapper) -> None: + lines = textwrap.dedent( + f"""\ + Source: foo + Section: devel + Priority: optional + Standards-Version: {CURRENT_STANDARDS_VERSION} + Maintainer: Jane Developer + Build-Depends: debhelper-compat (= 13) + Vcs-Git: https://salsa.debian.org/debian/foo + Vcs-Svn: https://svn.debian.org/debian/foo + Vcs-Browser: https://salsa.debian.org/debian/foo + + Package: foo + Architecture: all + Depends: bar, baz + Description: Some very interesting synopsis + A very interesting description + that spans multiple lines + . + Just so be clear, this is for a test. + """ + ).splitlines(keepends=True) + + diagnostics = line_linter(lines) + print(diagnostics) + assert diagnostics and len(diagnostics) == 2 + first_issue, second_issue = diagnostics + + msg = f'Multiple Version Control fields defined ("Vcs-Git")' + assert first_issue.message == msg + assert f"{first_issue.range}" == "6:0-7:0" + assert first_issue.severity == DiagnosticSeverity.Warning + + msg = f'Multiple Version Control fields defined ("Vcs-Svn")' + assert second_issue.message == msg + assert f"{second_issue.range}" == "7:0-8:0" + assert second_issue.severity == DiagnosticSeverity.Warning diff --git a/tests/lint_tests/test_lint_dpatches_series.py b/tests/lint_tests/test_lint_dpatches_series.py new file mode 100644 index 0000000..ed2a802 --- /dev/null +++ b/tests/lint_tests/test_lint_dpatches_series.py @@ -0,0 +1,152 @@ +import textwrap + +import pytest + +from debputy.lsp.lsp_debian_patches_series import _lint_debian_patches_series +from debputy.packages import DctrlParser +from debputy.plugin.api.feature_set import PluginProvidedFeatureSet +from debputy.plugin.api.test_api import build_virtual_file_system +from lint_tests.lint_tutil import ( + LintWrapper, +) + +try: + from lsprotocol.types import Diagnostic, DiagnosticSeverity +except ImportError: + pass + + +@pytest.fixture +def line_linter( + debputy_plugin_feature_set: PluginProvidedFeatureSet, + lint_dctrl_parser: DctrlParser, +) -> LintWrapper: + return LintWrapper( + "/nowhere/debian/patches/series", + _lint_debian_patches_series, + debputy_plugin_feature_set, + lint_dctrl_parser, + ) + + +def test_dpatches_series_files_lint(line_linter: LintWrapper) -> None: + lines = textwrap.dedent( + """\ + # Some leading comment + + ../some.patch + + .//.//./subdir/another-delta.diff # foo + + subdir/no-issues.patch # bar + """ + ).splitlines(keepends=True) + + fs = build_virtual_file_system( + [ + "./debian/patches/series", + "./debian/some.patch", + "./debian/patches/subdir/another-delta.diff", + "./debian/patches/subdir/no-issues.patch", + ] + ) + + line_linter.source_root = fs + + diagnostics = line_linter(lines) + print(diagnostics) + assert len(diagnostics) == 2 + + first_issue, second_issue = diagnostics + + msg = 'Disallowed prefix "../"' + assert first_issue.message == msg + assert f"{first_issue.range}" == "2:0-2:3" + assert first_issue.severity == DiagnosticSeverity.Error + + msg = 'Unnecessary prefix ".//.//./"' + assert second_issue.message == msg + assert f"{second_issue.range}" == "4:0-4:8" + assert second_issue.severity == DiagnosticSeverity.Warning + + +def test_dpatches_series_files_file_mismatch_lint(line_linter: LintWrapper) -> None: + lines = textwrap.dedent( + """\ + # Some leading comment + + some/used-twice.patch + + some/missing-file.patch + + some/used-twice.patch + """ + ).splitlines(keepends=True) + + fs = build_virtual_file_system( + [ + "./debian/patches/series", + "./debian/ignored.patch", + "./debian/patches/some/unused-file.diff", + "./debian/patches/some/used-twice.patch", + ] + ) + + line_linter.source_root = fs + + diagnostics = line_linter(lines) + print(diagnostics) + assert len(diagnostics) == 3 + + first_issue, second_issue, third_issue = diagnostics + + msg = 'Non-existing patch "some/missing-file.patch"' + assert first_issue.message == msg + assert f"{first_issue.range}" == "4:0-4:23" + assert first_issue.severity == DiagnosticSeverity.Error + + msg = 'Duplicate patch: "some/used-twice.patch"' + assert second_issue.message == msg + assert f"{second_issue.range}" == "6:0-6:21" + assert second_issue.severity == DiagnosticSeverity.Error + + msg = 'Unused patch: "some/unused-file.diff"' + assert third_issue.message == msg + assert f"{third_issue.range}" == "0:0-7:22" + assert third_issue.severity == DiagnosticSeverity.Warning + + +def test_dpatches_series_files_ext_lint(line_linter: LintWrapper) -> None: + lines = textwrap.dedent( + """\ + # Some leading comment + + some/ok.diff + + some/ok.patch + + some/no-extension + """ + ).splitlines(keepends=True) + + fs = build_virtual_file_system( + [ + "./debian/patches/series", + "./debian/patches/some/ok.diff", + "./debian/patches/some/ok.patch", + "./debian/patches/some/no-extension", + ] + ) + + line_linter.source_root = fs + + diagnostics = line_linter(lines) + print(diagnostics) + assert len(diagnostics) == 1 + + issue = diagnostics[0] + + msg = 'Patch not using ".patch" or ".diff" as extension: "some/no-extension"' + assert issue.message == msg + assert f"{issue.range}" == "6:0-6:17" + assert issue.severity == DiagnosticSeverity.Hint -- cgit v1.2.3