summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/lint-doc.yml11
-rw-r--r--scripts/doc-linter.py22
2 files changed, 27 insertions, 6 deletions
diff --git a/.github/workflows/lint-doc.yml b/.github/workflows/lint-doc.yml
index d7f25f38..eb7386d0 100644
--- a/.github/workflows/lint-doc.yml
+++ b/.github/workflows/lint-doc.yml
@@ -30,5 +30,14 @@ jobs:
- name: run doc linter
env:
+ # Pass modified + added + renamed file lists. `files_modified`
+ # alone misses newly-added pages — a PR adding a new doc with
+ # long lines or real public IPs would otherwise slip through.
FILES_MODIFIED: ${{ steps.file_changes.outputs.files_modified }}
- run: python scripts/doc-linter.py "$FILES_MODIFIED"
+ FILES_ADDED: ${{ steps.file_changes.outputs.files_added }}
+ FILES_RENAMED: ${{ steps.file_changes.outputs.files_renamed }}
+ run: |
+ python scripts/doc-linter.py \
+ "$FILES_MODIFIED" \
+ "$FILES_ADDED" \
+ "$FILES_RENAMED"
diff --git a/scripts/doc-linter.py b/scripts/doc-linter.py
index e352615c..509b1400 100644
--- a/scripts/doc-linter.py
+++ b/scripts/doc-linter.py
@@ -2,7 +2,7 @@ import os
import re
import ipaddress
import sys
-import ast
+import json
IPV4SEG = r'(?:25[0-5]|(?:2[0-4]|1{0,1}[0-9]){0,1}[0-9])'
IPV4ADDR = r'\b(?:(?:' + IPV4SEG + r'\.){3,3}' + IPV4SEG + r')\b'
@@ -302,11 +302,23 @@ def main():
# Only the argv-parsing step is wrapped in try/except. Errors raised by
# handle_file_action() must propagate so CI failures stay visible instead
# of silently triggering a full docs/ walk.
- try:
- files = ast.literal_eval(sys.argv[1])
- except (IndexError, SyntaxError, ValueError):
- # No argv or malformed list -> fall back to walking DOCS_ROOT.
+ #
+ # Accepts one or more positional argv entries, each a JSON array of
+ # paths (e.g., `'["foo.md", "bar.rst"]'`). Arrays are merged and
+ # deduplicated before linting. CI passes `files_modified`,
+ # `files_added`, etc. as separate args — see lint-doc.yml.
+ if len(sys.argv) <= 1:
files = None
+ else:
+ try:
+ files = []
+ for arg in sys.argv[1:]:
+ if arg.strip():
+ files.extend(json.loads(arg))
+ files = sorted(set(files))
+ except (json.JSONDecodeError, TypeError):
+ # Malformed input -> fall back to walking DOCS_ROOT.
+ files = None
if files is not None:
for file in files: