Merge pull request #5638 from sysown/fix/lint-groups-json-format

fix: reformat groups.json and add --fix to linter
feat/cla-assistant-setup
René Cannaò 1 month ago committed by GitHub
commit aecac96c84
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

File diff suppressed because it is too large Load Diff

@ -9,25 +9,58 @@ Enforces the conventions documented in test/tap/groups/README.md:
- Keys sorted alphabetically
- File starts with '{' and ends with '}'
Usage:
python3 lint_groups_json.py [--fix] [path/to/groups.json]
--fix Auto-fix formatting issues (reformat in-place).
Exit codes:
0 - Format is correct
1 - Format violations found
0 - Format is correct (or --fix applied successfully)
1 - Format violations found (and no --fix, or --fix failed)
"""
import argparse
import json
import os
import re
import sys
def main():
groups_path = os.path.join(os.path.dirname(__file__), "groups.json")
if len(sys.argv) > 1:
groups_path = sys.argv[1]
def reformat_groups(groups_path):
"""Read groups.json and rewrite it in the canonical one-line-per-entry format."""
with open(groups_path, "r") as f:
data = json.load(f)
if not isinstance(data, dict):
print(f"ERROR: Top-level value must be a JSON object", file=sys.stderr)
return False
sorted_keys = sorted(data.keys())
lines = ["{"]
for i, key in enumerate(sorted_keys):
groups = data[key]
# Sort groups for determinism, but keep special strings like @proxysql_min_version at end
regular = sorted(g for g in groups if not g.startswith("@"))
special = sorted(g for g in groups if g.startswith("@"))
sorted_groups = regular + special
groups_str = ",".join(f'"{g}"' for g in sorted_groups)
comma = "," if i < len(sorted_keys) - 1 else ""
lines.append(f' "{key}" : [ {groups_str} ]{comma}')
lines.append("}")
lines.append("") # trailing newline
with open(groups_path, "w") as f:
f.write("\n".join(lines))
print(f"Fixed: {groups_path} ({len(sorted_keys)} entries, sorted, compact)")
return True
def lint_groups(groups_path):
"""Lint groups.json and return (exit_code, error_count)."""
if not os.path.isfile(groups_path):
print(f"ERROR: {groups_path} not found", file=sys.stderr)
return 1
return 1, 0
with open(groups_path, "r") as f:
raw = f.read()
@ -40,22 +73,20 @@ def main():
data = json.loads(raw)
except json.JSONDecodeError as e:
errors.append(f"Invalid JSON: {e}")
# Can't do further checks
for e in errors:
print(f"ERROR: {e}", file=sys.stderr)
return 1
return 1, len(errors)
if not isinstance(data, dict):
errors.append("Top-level value must be a JSON object")
for e in errors:
print(f"ERROR: {e}", file=sys.stderr)
return 1
return 1, len(errors)
# Check 2: first and last lines
if not lines or lines[0].strip() != "{":
errors.append("Line 1: must be '{'")
if lines[-1].strip() == "":
# Allow trailing newline — check second-to-last
if len(lines) < 2 or lines[-2].strip() != "}":
errors.append(f"Last non-empty line: must be '}}'")
elif lines[-1].strip() != "}":
@ -66,7 +97,7 @@ def main():
r'^ "([^"]+)" : \[ .+ \](,?)$'
)
keys_in_order = []
entry_lines = lines[1:] # skip opening brace
entry_lines = lines[1:]
for i, line in enumerate(entry_lines, start=2):
stripped = line.strip()
if stripped == "}" or stripped == "":
@ -83,7 +114,6 @@ def main():
# Check 4: keys are sorted
if keys_in_order != sorted(keys_in_order):
# Find first out-of-order key
for j in range(len(keys_in_order) - 1):
if keys_in_order[j] > keys_in_order[j + 1]:
errors.append(
@ -109,10 +139,29 @@ def main():
print(f"groups.json format lint: {len(errors)} error(s) found:", file=sys.stderr)
for e in errors:
print(f" {e}", file=sys.stderr)
return 1
print(f"\n Hint: run 'python3 {os.path.abspath(__file__)} --fix' to auto-fix", file=sys.stderr)
return 1, len(errors)
print(f"groups.json format lint: OK ({len(data)} entries, sorted, compact)")
return 0
return 0, 0
def main():
parser = argparse.ArgumentParser(description="Lint groups.json for format compliance.")
parser.add_argument("path", nargs="?", default=None, help="Path to groups.json")
parser.add_argument("--fix", action="store_true", help="Auto-fix formatting issues in-place")
args = parser.parse_args()
groups_path = args.path or os.path.join(os.path.dirname(__file__), "groups.json")
if args.fix:
ok = reformat_groups(groups_path)
if not ok:
return 1
# Re-lint after fixing to confirm
return lint_groups(groups_path)[0]
return lint_groups(groups_path)[0]
if __name__ == "__main__":

Loading…
Cancel
Save