Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion PythonScripts/audit_translations/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ The tool analyzes rule files to detect the following issues:
* **Rule Differences:** Structural changes (match expressions, conditions, variables, or test/replace layout) between the source and target translation.
* **Definition Coverage:** Compares literal `definitions.yaml` entries by name and collection kind (`vector`, `set`, or `map`).

Add `# audit-ignore` to a rule block to suppress auditing that rule.
After a blank line, add `# audit-ignore` immediately before a rule to suppress
auditing that rule. Existing markers inside a rule block are also supported.

---

Expand Down
34 changes: 31 additions & 3 deletions PythonScripts/audit_translations/parsers.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,11 +149,39 @@ def format_tag(tag_value: Any) -> str | None:


def build_raw_blocks(lines: list[str], starts: list[int]) -> list[str]:
blocks = []
if not starts:
return blocks
return []

block_starts = starts.copy()
for idx, start in enumerate(starts):
end = starts[idx + 1] if idx + 1 < len(starts) else len(lines)
if idx == 0:
while start > 0 and (not lines[start - 1].strip() or lines[start - 1].lstrip().startswith("#")):
start -= 1
block_starts[idx] = start
continue

lower_bound = starts[idx - 1] + 1
dash_line = re.fullmatch(r"\s*-\s*(?:#.*)?", lines[start - 1]) if start > lower_bound else None
if dash_line:
start -= 1
block_starts[idx] = start
continue

comment_start = start
while comment_start > lower_bound and lines[comment_start - 1].lstrip().startswith("#"):
comment_start -= 1

# A separating blank makes the comment run introductory text for this
# item. Without one, leave the run with the preceding rule.
if comment_start > lower_bound and not lines[comment_start - 1].strip():
start = comment_start - 1
while start > lower_bound and not lines[start - 1].strip():
start -= 1
block_starts[idx] = start

blocks = []
for idx, start in enumerate(block_starts):
end = block_starts[idx + 1] if idx + 1 < len(block_starts) else len(lines)
blocks.append("\n".join(lines[start:end]))
return blocks

Expand Down
85 changes: 85 additions & 0 deletions PythonScripts/audit_translations/tests/test_parsers.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,91 @@ def test_detects_audit_ignore(self):
rules = parse_rules_file(content, data)
assert rules[0].audit_ignore

def test_assigns_leading_audit_ignore_to_following_rule(self):
"""A marker directly above a rule suppresses that rule, not its neighbour."""
content = """
- name: first
tag: mo
match: "."

# audit-ignore: the following placeholder intentionally differs
# from the source-language rule.
- name: second
tag: mi
match: "false()"
"""
yaml = YAML()
data = yaml.load(content)
rules = parse_rules_file(content, data)
assert not rules[0].audit_ignore
assert rules[1].audit_ignore

def test_keeps_audit_ignore_inside_rule(self):
"""Existing markers within a rule block remain supported."""
content = """
- name: first
tag: mo
# audit-ignore
match: "."

- name: second
tag: mi
match: "x"
"""
yaml = YAML()
data = yaml.load(content)
rules = parse_rules_file(content, data)
assert rules[0].audit_ignore
assert not rules[1].audit_ignore

def test_keeps_touching_comment_with_preceding_rule(self):
"""A comment without a separating blank remains part of the preceding rule."""
content = """
- name: first
tag: mo
match: "."
# audit-ignore: this comment documents the first rule
- name: second
tag: mi
match: "x"
"""
yaml = YAML()
data = yaml.load(content)
rules = parse_rules_file(content, data)
assert rules[0].audit_ignore
assert not rules[1].audit_ignore

def test_includes_comment_on_item_dash_line(self):
"""A comment attached to an item's dash belongs to that item."""
content = """
- name: first
tag: mo
match: "."

- # second rule introduction
name: second
tag: mi
match: "x"
"""
yaml = YAML()
data = yaml.load(content)
rules = parse_rules_file(content, data)
assert "second rule introduction" not in rules[0].raw_content
assert "second rule introduction" in rules[1].raw_content

def test_assigns_file_header_to_first_rule(self):
"""A leading marker before the first item is included in its raw block."""
content = """
# audit-ignore
- name: first
tag: mo
match: "."
"""
yaml = YAML()
data = yaml.load(content)
rules = parse_rules_file(content, data)
assert rules[0].audit_ignore

def test_handles_array_tag(self):
"""Ensure handles array tag."""
content = """- name: multi-tag
Expand Down
Loading