diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index ce868aa..417703a 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -2,7 +2,7 @@ exclude: tests/data repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.4.0 + rev: v4.5.0 hooks: - id: trailing-whitespace - id: end-of-file-fixer @@ -10,22 +10,24 @@ repos: - id: check-added-large-files - repo: https://github.com/PyCQA/pylint - rev: v2.17.3 + rev: v3.0.1 hooks: - id: pylint + additional_dependencies: + - setuptools - repo: https://github.com/psf/black - rev: 23.3.0 + rev: 23.10.1 hooks: - id: black - repo: https://github.com/asottile/pyupgrade - rev: v3.3.2 + rev: v3.15.0 hooks: - id: pyupgrade args: ["--py37-plus"] - repo: https://github.com/igorshubovych/markdownlint-cli - rev: v0.33.0 + rev: v0.37.0 hooks: - id: markdownlint-fix diff --git a/CHANGES b/CHANGES index 4fb769b..421e6db 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,9 @@ +1.2.5 | 2023-11-03 12:19:41 +0100 + + * GH-62: Preserve newlines before comments (Benjamin Bannier, Corelight) + + * Bump pre-commit hooks (Benjamin Bannier, Corelight) + 1.2.4-7 | 2023-09-22 08:41:33 +0200 * Fix race in project Makefile (Benjamin Bannier, Corelight) diff --git a/VERSION b/VERSION index 0527a8e..c813fe1 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.2.4-7 +1.2.5 diff --git a/tests/test_formatting.py b/tests/test_formatting.py index 9fe6475..7513a27 100755 --- a/tests/test_formatting.py +++ b/tests/test_formatting.py @@ -5,6 +5,7 @@ import pathlib import sys import unittest +import textwrap # Sets up sys.path and provides helpers import testutils as tu @@ -62,6 +63,34 @@ def test_index_slice(self): self.assertEqual(self._format(b"data[1 :1-1];").rstrip(), b"data[1 : 1 - 1];") self.assertEqual(self._format(b"data[f(): ];").rstrip(), b"data[f() :];") + def test_format_comment_separator(self): + """Validates that we preserve the separator before a comment. This is a + regression test for #62.""" + + self.assertEqual( + self._format(b"global x = 42; # Inline.\n"), b"global x = 42; # Inline.\n" + ) + + code = textwrap.dedent( + """\ + event zeek_init() {} + # Comment on next line. + """ + ) + + expected = textwrap.dedent( + """\ + event zeek_init() + \t{ } + # Comment on next line. + """ + ) + + # We split out lines here to work around different line endings on Windows. + self.assertEqual( + self._format(code.encode()).decode().splitlines(), expected.splitlines() + ) + class TestFormattingErrors(unittest.TestCase): def _format(self, content): diff --git a/zeekscript/__init__.py b/zeekscript/__init__.py index 302f0cb..03ad113 100644 --- a/zeekscript/__init__.py +++ b/zeekscript/__init__.py @@ -1,5 +1,5 @@ """Wrapper around more low-level tests.""" -__version__ = "1.2.4-7" +__version__ = "1.2.5" __all__ = ["cli", "error", "formatter", "node", "output", "parser", "script"] from .cli import * diff --git a/zeekscript/formatter.py b/zeekscript/formatter.py index f6d3b50..33718e1 100644 --- a/zeekscript/formatter.py +++ b/zeekscript/formatter.py @@ -1336,10 +1336,15 @@ def __init__(self, script, node, ostream, indent=0, hints=None): class MinorCommentFormatter(CommentFormatter): def format(self): node = self.node - # There's something before us and it's not a newline, then - # separate this comment from it with a space: - if node.prev_cst_sibling and not node.prev_cst_sibling.is_nl(): - self._write_sp() + + # Preserve separator to previous node if any. + if node.prev_cst_sibling: + if node.prev_cst_sibling.is_nl(): + # Keep newlines verbatim. + self._write_nl() + else: + # If we are on the same line, normalize to exactly one space. + self._write_sp() self._format_token() # Write comment itself