From 81be90131a09c3acc20108c26862dceae8e11961 Mon Sep 17 00:00:00 2001 From: garnizeH Date: Sat, 18 Apr 2026 21:49:09 -0300 Subject: [PATCH 1/2] ci: standardize workflows and fix CARGO_REGISTRY_TOKEN secret name --- .github/workflows/ci.yml | 26 +++++++++++++------------- .github/workflows/minimal-features.yml | 17 +++++++++++++++++ .github/workflows/publish.yml | 16 ++++++++++++++++ .gitignore | 1 - clippy.toml | 2 +- justfile | 21 ++++++++++++++++++++- scripts/check_docs_tiers.py | 13 +++++++++++-- scripts/check_links.py | 4 ++-- scripts/doc_lint.py | 4 +++- 9 files changed, 83 insertions(+), 21 deletions(-) create mode 100644 .github/workflows/minimal-features.yml create mode 100644 .github/workflows/publish.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 41f85e6..8192abb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -20,8 +20,8 @@ jobs: name: Format Check runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - - uses: dtolnay/rust-toolchain@1.94.1 + - uses: actions/checkout@v6 + - uses: dtolnay/rust-toolchain@stable with: toolchain: 1.94.1 - run: cargo fmt --all --check @@ -30,8 +30,8 @@ jobs: name: Security Audit runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - - uses: dtolnay/rust-toolchain@1.94.1 + - uses: actions/checkout@v6 + - uses: dtolnay/rust-toolchain@stable with: toolchain: 1.94.1 - uses: taiki-e/install-action@cargo-deny @@ -45,8 +45,8 @@ jobs: name: Clippy Lint runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - - uses: dtolnay/rust-toolchain@1.94.1 + - uses: actions/checkout@v6 + - uses: dtolnay/rust-toolchain@stable with: toolchain: 1.94.1 - uses: Swatinem/rust-cache@v2 @@ -58,7 +58,7 @@ jobs: name: Documentation Audit runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Install codespell run: sudo apt-get update && sudo apt-get install -y codespell - name: Run Frontmatter Lint @@ -74,8 +74,8 @@ jobs: needs: [fmt, security, clippy] runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - - uses: dtolnay/rust-toolchain@1.94.1 + - uses: actions/checkout@v6 + - uses: dtolnay/rust-toolchain@stable with: toolchain: 1.94.1 - uses: Swatinem/rust-cache@v2 @@ -91,8 +91,8 @@ jobs: env: RUSTDOCFLAGS: "-D warnings" steps: - - uses: actions/checkout@v4 - - uses: dtolnay/rust-toolchain@1.94.1 + - uses: actions/checkout@v6 + - uses: dtolnay/rust-toolchain@stable with: toolchain: 1.94.1 - uses: Swatinem/rust-cache@v2 @@ -106,8 +106,8 @@ jobs: needs: [fmt, security, clippy] runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - - uses: dtolnay/rust-toolchain@nightly-2025-07-01 + - uses: actions/checkout@v6 + - uses: dtolnay/rust-toolchain@stable with: toolchain: nightly-2025-07-01 - uses: Swatinem/rust-cache@v2 diff --git a/.github/workflows/minimal-features.yml b/.github/workflows/minimal-features.yml new file mode 100644 index 0000000..2fc18f5 --- /dev/null +++ b/.github/workflows/minimal-features.yml @@ -0,0 +1,17 @@ +name: Minimal Features Check + +on: + push: + branches: [ main ] + pull_request: + branches: [ main ] + +jobs: + check-minimal: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + - name: Rust Toolchain + uses: dtolnay/rust-toolchain@stable + - name: Check Minimal Features + run: cargo check -p void-rush --no-default-features diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 0000000..bec2528 --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,16 @@ +name: Publish +on: + push: + tags: + - 'v*' +jobs: + publish: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + - name: Rust Toolchain + uses: dtolnay/rust-toolchain@stable + - name: Publish to crates.io + env: + CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} + run: cargo publish -p void-rush diff --git a/.gitignore b/.gitignore index c48acc4..2ab9040 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,5 @@ # --- Rust / Cargo --- target/ -Cargo.lock # --- OS Specific --- .DS_Store diff --git a/clippy.toml b/clippy.toml index 9308f73..15a3cea 100644 --- a/clippy.toml +++ b/clippy.toml @@ -1,2 +1,2 @@ -# Enforce that all functions returning Result are handled +# Enforce that all wildcard imports are warned warn-on-all-wildcard-imports = true diff --git a/justfile b/justfile index 052695f..e9adb1c 100644 --- a/justfile +++ b/justfile @@ -1,6 +1,10 @@ # Run fast quality gate checks (fmt, clippy, test, security, docs-check) [group('check')] -check: fmt clippy security docs-check +check: fmt clippy test security docs-check + +# Run ALL CI-equivalent checks (fast + docs-strict, udeps) +[group('check')] +check-all: check docs-strict udeps # Check formatting [group('lint')] @@ -12,6 +16,11 @@ fmt: clippy: cargo clippy --workspace --all-targets -- -D warnings +# Run all unit and integration tests +[group('test')] +test: + cargo nextest run --workspace + # Run security audits (licenses, advisories, vulnerabilities) [group('security')] security: @@ -29,3 +38,13 @@ docs-check: python3 scripts/doc_lint.py python3 scripts/check_links.py uvx codespell + +# Build documentation (mirrors the CI job — warnings are errors) +[group('doc')] +docs-strict: + RUSTDOCFLAGS="-D warnings" cargo doc --workspace --no-deps + +# Check for unused dependencies (requires nightly; runs on main in CI) +[group('lint')] +udeps: + cargo +nightly-2025-07-01 udeps --workspace --all-targets diff --git a/scripts/check_docs_tiers.py b/scripts/check_docs_tiers.py index 92cdb61..f092636 100755 --- a/scripts/check_docs_tiers.py +++ b/scripts/check_docs_tiers.py @@ -1,8 +1,9 @@ +#!/usr/bin/env python3 import os import sys import re -DESIGN_DOCS_DIR = "docs/design/" +DESIGN_DOCS_DIR = "docs/" def check_file(path): if not os.path.isfile(path): @@ -11,8 +12,16 @@ def check_file(path): with open(path, 'r') as f: content = f.read() + # Extract YAML frontmatter + fm_match = re.search(r"^---\s*\n(.*?)\n---", content, re.DOTALL | re.MULTILINE) + if not fm_match: + print(f"Error: {path} is missing frontmatter.") + return False + + frontmatter = fm_match.group(1) + # Check if Tier is in frontmatter - match = re.search(r"^Tier: (.*)$", content, re.MULTILINE) + match = re.search(r"^Tier:\s*(.*)$", frontmatter, re.MULTILINE) if not match: print(f"Error: {path} is missing 'Tier' frontmatter.") return False diff --git a/scripts/check_links.py b/scripts/check_links.py index 82f3f16..cb67ab2 100755 --- a/scripts/check_links.py +++ b/scripts/check_links.py @@ -37,8 +37,8 @@ def main(): all_files = [] for root, dirs, files in os.walk(docs_root): - if '.git' in root or 'target' in root or 'jemalloc' in root or 'node_modules' in root or 'pkg' in root: - continue + # Prune excluded directories in-place to avoid descending into them + dirs[:] = [d for d in dirs if d not in {'.git', 'target', 'jemalloc', 'node_modules', 'pkg'}] for f in files: all_files.append(os.path.normpath(os.path.join(root, f))) diff --git a/scripts/doc_lint.py b/scripts/doc_lint.py index 35fe419..15fa915 100755 --- a/scripts/doc_lint.py +++ b/scripts/doc_lint.py @@ -35,7 +35,9 @@ def main(): failed = False files_to_check = [] - for root, dirs, files in os.walk(docs_root): + for root, _dirs, files in os.walk(docs_root): + # Prune excluded directories in-place to avoid descending into them + _dirs[:] = [d for d in _dirs if d not in {'.git', 'target', 'jemalloc', 'node_modules', 'pkg'}] for f in files: if f.endswith(".md") and f != "README.md": files_to_check.append(os.path.join(root, f)) From 546e397806be82a69c81d5c1dde3981cbf559920 Mon Sep 17 00:00:00 2001 From: garnizeH Date: Sun, 19 Apr 2026 02:09:32 -0300 Subject: [PATCH 2/2] chore: remove project CI workflows, linting scripts, and configuration files --- .github/workflows/ci.yml | 118 ------------------------- .github/workflows/minimal-features.yml | 17 ---- .github/workflows/publish.yml | 16 ---- LICENSE | 6 -- README.md | 6 +- clippy.toml | 2 - deny.toml | 45 ---------- justfile | 50 ----------- rustfmt.toml | 4 - scripts/check_docs_tiers.py | 54 ----------- scripts/check_links.py | 64 -------------- scripts/doc_lint.py | 59 ------------- 12 files changed, 3 insertions(+), 438 deletions(-) delete mode 100644 .github/workflows/ci.yml delete mode 100644 .github/workflows/minimal-features.yml delete mode 100644 .github/workflows/publish.yml delete mode 100644 LICENSE delete mode 100644 clippy.toml delete mode 100644 deny.toml delete mode 100644 justfile delete mode 100644 rustfmt.toml delete mode 100755 scripts/check_docs_tiers.py delete mode 100755 scripts/check_links.py delete mode 100755 scripts/doc_lint.py diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml deleted file mode 100644 index 8192abb..0000000 --- a/.github/workflows/ci.yml +++ /dev/null @@ -1,118 +0,0 @@ -name: CI - -on: - push: - branches: [ main ] - pull_request: - branches: [ main ] - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -env: - CARGO_TERM_COLOR: always - RUSTFLAGS: "-D warnings" - -jobs: - # --- STAGE 1: FAST CHECKS & LINTS --- - fmt: - name: Format Check - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v6 - - uses: dtolnay/rust-toolchain@stable - with: - toolchain: 1.94.1 - - run: cargo fmt --all --check - - security: - name: Security Audit - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v6 - - uses: dtolnay/rust-toolchain@stable - with: - toolchain: 1.94.1 - - uses: taiki-e/install-action@cargo-deny - - uses: taiki-e/install-action@cargo-audit - - name: License & Advisory Check - run: cargo deny check - - name: Vulnerability Scan - run: cargo audit - - clippy: - name: Clippy Lint - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v6 - - uses: dtolnay/rust-toolchain@stable - with: - toolchain: 1.94.1 - - uses: Swatinem/rust-cache@v2 - - name: Install protoc - run: sudo apt-get update -y && sudo apt-get install -y protobuf-compiler - - run: cargo clippy --workspace --all-targets -- -D warnings - - docs-audit: - name: Documentation Audit - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v6 - - name: Install codespell - run: sudo apt-get update && sudo apt-get install -y codespell - - name: Run Frontmatter Lint - run: python3 scripts/doc_lint.py - - name: Run Link Check - run: python3 scripts/check_links.py - - name: Run Spelling Check - run: codespell - - # --- STAGE 2: HEAVY LIFTING (Depends on Stage 1) --- - test: - name: Test Suite - needs: [fmt, security, clippy] - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v6 - - uses: dtolnay/rust-toolchain@stable - with: - toolchain: 1.94.1 - - uses: Swatinem/rust-cache@v2 - - name: Install protoc - run: sudo apt-get update -y && sudo apt-get install -y protobuf-compiler - - uses: taiki-e/install-action@nextest - - run: cargo nextest run --workspace - - docs: - name: Documentation Build - needs: [fmt, security, clippy, docs-audit] - runs-on: ubuntu-latest - env: - RUSTDOCFLAGS: "-D warnings" - steps: - - uses: actions/checkout@v6 - - uses: dtolnay/rust-toolchain@stable - with: - toolchain: 1.94.1 - - uses: Swatinem/rust-cache@v2 - - name: Install protoc - run: sudo apt-get update -y && sudo apt-get install -y protobuf-compiler - - run: cargo doc --workspace --no-deps - - # --- STAGE 3: SUPPLEMENTAL CHECKS --- - udeps: - name: Unused Dependencies - needs: [fmt, security, clippy] - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v6 - - uses: dtolnay/rust-toolchain@stable - with: - toolchain: nightly-2025-07-01 - - uses: Swatinem/rust-cache@v2 - - name: Install protoc - run: sudo apt-get update -y && sudo apt-get install -y protobuf-compiler - - uses: taiki-e/install-action@cargo-udeps - - name: Check for unused dependencies - run: cargo +nightly-2025-07-01 udeps --workspace --all-targets diff --git a/.github/workflows/minimal-features.yml b/.github/workflows/minimal-features.yml deleted file mode 100644 index 2fc18f5..0000000 --- a/.github/workflows/minimal-features.yml +++ /dev/null @@ -1,17 +0,0 @@ -name: Minimal Features Check - -on: - push: - branches: [ main ] - pull_request: - branches: [ main ] - -jobs: - check-minimal: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v6 - - name: Rust Toolchain - uses: dtolnay/rust-toolchain@stable - - name: Check Minimal Features - run: cargo check -p void-rush --no-default-features diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml deleted file mode 100644 index bec2528..0000000 --- a/.github/workflows/publish.yml +++ /dev/null @@ -1,16 +0,0 @@ -name: Publish -on: - push: - tags: - - 'v*' -jobs: - publish: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v6 - - name: Rust Toolchain - uses: dtolnay/rust-toolchain@stable - - name: Publish to crates.io - env: - CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} - run: cargo publish -p void-rush diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 97f79f9..0000000 --- a/LICENSE +++ /dev/null @@ -1,6 +0,0 @@ -Creative Commons Attribution 4.0 International Public License - -By exercising the Licensed Rights (defined below), You accept and agree to be bound by the terms and conditions of this Creative Commons Attribution 4.0 International Public License ("Public License"). To the extent this Public License may be interpreted as a contract, You are granted the Licensed Rights in consideration of Your acceptance of these terms and conditions, and the Licensor grants You such rights in consideration of benefits the Licensor receives from making the Licensed Material available under these terms and conditions. - -[...] -(See full text at https://creativecommons.org/licenses/by/4.0/legalcode) diff --git a/README.md b/README.md index 94115bd..917ad68 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ A top-down 3D space MMO built on the Aetheris engine — Newtonian physics, cont **Void Rush** is the flagship demonstration of the Aetheris engine's capabilities. It pushes the boundaries of browser-native multiplayer by simulating a persistent universe where thousands of players interact in real-time. Every ship's thruster follows Newtonian laws, every asteroid is a destructible entity, and every trade route is contested in a living, player-driven economy. -> **[Read the Game Design Document](VOID_RUSH_GDD.md)** — ship classes, weapons, economy loops, and world architecture. +> **[Read the Game Design Document](docs/VOID_RUSH_GDD.md)** — ship classes, weapons, economy loops, and world architecture. > > 🚀 **Latest Milestone:** **Wireframe Debug Renderer (M1011) functional!** Replaced placeholder overlays with a high-performance in-canvas debug pass. @@ -37,8 +37,8 @@ For a full list of commands, run `just --list`. ## Documentation Entry Points -- **[VOID_RUSH_GDD.md](VOID_RUSH_GDD.md):** Master game design document. -- **[THEME_WORLD_DESIGN.md](THEME_WORLD_DESIGN.md):** Visual identity and environmental rules. +- **[VOID_RUSH_GDD.md](docs/VOID_RUSH_GDD.md):** Master game design document. +- **[THEME_WORLD_DESIGN.md](docs/THEME_WORLD_DESIGN.md):** Visual identity and environmental rules. - **[ECS_DESIGN.md](docs/ECS_DESIGN.md):** Entity-Component-System layout for world entities. ## Design Philosophy diff --git a/clippy.toml b/clippy.toml deleted file mode 100644 index 15a3cea..0000000 --- a/clippy.toml +++ /dev/null @@ -1,2 +0,0 @@ -# Enforce that all wildcard imports are warned -warn-on-all-wildcard-imports = true diff --git a/deny.toml b/deny.toml deleted file mode 100644 index 1f10a8f..0000000 --- a/deny.toml +++ /dev/null @@ -1,45 +0,0 @@ -# denylist configuration -# Synchronized with .cargo/audit.toml; keep both ignore lists in sync. - -[licenses] -allow = [ - "MIT", - "Apache-2.0", - "ISC", # Required by 'untrusted' (ring dep) - "CDLA-Permissive-2.0", # Required by 'webpki-root-certs' (rustls-platform-verifier dep) - "BSD-2-Clause", # Required by 'zerocopy' and other system crates - "BSD-3-Clause", # Required by various ecosystem crates - "Zlib", # Required by 'miniz_oxide' and similar compression crates - "Unicode-3.0", # Required by 'unicode-ident' - "CC0-1.0", # Required by 'hexf-parse' (wgpu dependency) - "MPL-2.0", # Required by 'webpki-roots' (openidconnect dep) - "0BSD", # Required by 'quoted_printable' (lettre dep) -] - -[advisories] -# Report unmaintained crates across all dependency types (direct + transitive). -unmaintained = "all" -# Deny yanked crates — a yanked crate may have been pulled for a security reason. -yanked = "deny" -ignore = [ - # rustls-pemfile: 1.x is unmaintained (transitive dep via tonic). - # Tracking: #1234 Revisit: 2026-06-01 - "RUSTSEC-2025-0134", - # paste: unmaintained (transitive dep via tikv-jemalloc-ctl). - # Tracking: #1235 Revisit: 2026-06-01 - "RUSTSEC-2024-0436", - # rsa: PKCS#1 v1.5 padding timing attack (transitive dep via tokio-rustls). - # Tracking: #1236 Revisit: 2026-06-01 - "RUSTSEC-2023-0071", -] - -[bans] -# Warn on duplicates; promote to deny once P1 deps are stabilised. -multiple-versions = "warn" - -[sources] -# Only allow crates from crates.io. Disallow git sources and local paths -# in production (workspace path deps are exempt by default). -unknown-registry = "deny" -unknown-git = "deny" -allow-registry = ["https://github.com/rust-lang/crates.io-index"] diff --git a/justfile b/justfile deleted file mode 100644 index e9adb1c..0000000 --- a/justfile +++ /dev/null @@ -1,50 +0,0 @@ -# Run fast quality gate checks (fmt, clippy, test, security, docs-check) -[group('check')] -check: fmt clippy test security docs-check - -# Run ALL CI-equivalent checks (fast + docs-strict, udeps) -[group('check')] -check-all: check docs-strict udeps - -# Check formatting -[group('lint')] -fmt: - cargo fmt --all --check - -# Run clippy lints -[group('lint')] -clippy: - cargo clippy --workspace --all-targets -- -D warnings - -# Run all unit and integration tests -[group('test')] -test: - cargo nextest run --workspace - -# Run security audits (licenses, advisories, vulnerabilities) -[group('security')] -security: - cargo deny check - cargo audit - -# Build documentation -[group('doc')] -docs: - cargo doc --workspace --no-deps - -# Check documentation quality (linting, frontmatter, spelling, links) -[group('doc')] -docs-check: - python3 scripts/doc_lint.py - python3 scripts/check_links.py - uvx codespell - -# Build documentation (mirrors the CI job — warnings are errors) -[group('doc')] -docs-strict: - RUSTDOCFLAGS="-D warnings" cargo doc --workspace --no-deps - -# Check for unused dependencies (requires nightly; runs on main in CI) -[group('lint')] -udeps: - cargo +nightly-2025-07-01 udeps --workspace --all-targets diff --git a/rustfmt.toml b/rustfmt.toml deleted file mode 100644 index 1009ee5..0000000 --- a/rustfmt.toml +++ /dev/null @@ -1,4 +0,0 @@ -edition = "2024" -max_width = 100 -use_small_heuristics = "Default" -newline_style = "Unix" diff --git a/scripts/check_docs_tiers.py b/scripts/check_docs_tiers.py deleted file mode 100755 index f092636..0000000 --- a/scripts/check_docs_tiers.py +++ /dev/null @@ -1,54 +0,0 @@ -#!/usr/bin/env python3 -import os -import sys -import re - -DESIGN_DOCS_DIR = "docs/" - -def check_file(path): - if not os.path.isfile(path): - return True - - with open(path, 'r') as f: - content = f.read() - - # Extract YAML frontmatter - fm_match = re.search(r"^---\s*\n(.*?)\n---", content, re.DOTALL | re.MULTILINE) - if not fm_match: - print(f"Error: {path} is missing frontmatter.") - return False - - frontmatter = fm_match.group(1) - - # Check if Tier is in frontmatter - match = re.search(r"^Tier:\s*(.*)$", frontmatter, re.MULTILINE) - if not match: - print(f"Error: {path} is missing 'Tier' frontmatter.") - return False - - tier = match.group(1).strip() - valid_tiers = ["1", "2", "3", "4", "5", "shared", "internal"] - if tier not in valid_tiers: - print(f"Error: {path} has invalid Tier '{tier}'.") - return False - - return True - -def main(): - all_passed = True - if not os.path.exists(DESIGN_DOCS_DIR): - print(f"Dir {DESIGN_DOCS_DIR} not found.") - sys.exit(1) - - for filename in os.listdir(DESIGN_DOCS_DIR): - if filename.endswith(".md"): - if not check_file(os.path.join(DESIGN_DOCS_DIR, filename)): - all_passed = False - - if not all_passed: - sys.exit(1) - - print("All design documents have valid Tier frontmatter.") - -if __name__ == "__main__": - main() diff --git a/scripts/check_links.py b/scripts/check_links.py deleted file mode 100755 index cb67ab2..0000000 --- a/scripts/check_links.py +++ /dev/null @@ -1,64 +0,0 @@ -#!/usr/bin/env python3 -import os -import re -import sys - -def check_links_in_file(filepath, all_files): - errors = [] - with open(filepath, 'r', encoding='utf-8') as f: - content = f.read() - - # Find [text](link) or [text]: link - links = re.findall(r'\[.*?\]\((.*?)\)', content) - links += re.findall(r'^\[.*?\]:\s*(.*?)$', content, re.MULTILINE) - - for link in links: - link = link.strip().split(" ")[0].strip(" <>") - if link.startswith('http') or link.startswith('#') or link.startswith('mailto:'): - continue - - # Remove anchor - link_path = link.split('#')[0] - if not link_path: - continue - - # Resolve relative to current file - current_dir = os.path.dirname(filepath) - target_path = os.path.normpath(os.path.join(current_dir, link_path)) - - if not os.path.exists(target_path): - errors.append(f"Broken link: {link} (Target: {target_path})") - - return errors - -def main(): - docs_root = "." # Check from root - failed = False - - all_files = [] - for root, dirs, files in os.walk(docs_root): - # Prune excluded directories in-place to avoid descending into them - dirs[:] = [d for d in dirs if d not in {'.git', 'target', 'jemalloc', 'node_modules', 'pkg'}] - for f in files: - all_files.append(os.path.normpath(os.path.join(root, f))) - - md_files = [f for f in all_files if f.endswith('.md')] - - for md_file in md_files: - errors = check_links_in_file(md_file, all_files) - if errors: - print(f"❌ {md_file}:") - for err in errors: - print(f" - {err}") - failed = True - else: - # print(f"✅ {md_file}: OK") - pass - - if failed: - sys.exit(1) - else: - print("✅ All internal links are valid.") - -if __name__ == "__main__": - main() diff --git a/scripts/doc_lint.py b/scripts/doc_lint.py deleted file mode 100755 index 15fa915..0000000 --- a/scripts/doc_lint.py +++ /dev/null @@ -1,59 +0,0 @@ -#!/usr/bin/env python3 -import os -import sys -import re - -REQUIRED_FIELDS = ["Version", "Status", "Phase", "Last Updated", "Authors"] -REQUIRED_SECTIONS = ["## Executive Summary", "## Appendix A — Glossary", "## Appendix B — Decision Log"] - -def lint_file(filepath): - errors = [] - with open(filepath, 'r', encoding='utf-8') as f: - content = f.read() - - # Check for frontmatter - frontmatter_match = re.search(r'^---\n(.*?)\n---', content, re.DOTALL) - if not frontmatter_match: - errors.append("Missing frontmatter (YAML block starting and ending with ---)") - else: - fm_content = frontmatter_match.group(1) - for field in REQUIRED_FIELDS: - if f"{field}:" not in fm_content: - errors.append(f"Missing required frontmatter field: {field}") - - # Check for required sections (only for design files) - if "design" in filepath.split(os.sep): - for section in REQUIRED_SECTIONS: - if section not in content: - errors.append(f"Missing required section: {section}") - - return errors - -def main(): - docs_root = "docs" - design_dir = os.path.join(docs_root, "design") - failed = False - - files_to_check = [] - for root, _dirs, files in os.walk(docs_root): - # Prune excluded directories in-place to avoid descending into them - _dirs[:] = [d for d in _dirs if d not in {'.git', 'target', 'jemalloc', 'node_modules', 'pkg'}] - for f in files: - if f.endswith(".md") and f != "README.md": - files_to_check.append(os.path.join(root, f)) - - for filepath in files_to_check: - errors = lint_file(filepath) - if errors: - print(f"❌ {filepath}:") - for err in errors: - print(f" - {err}") - failed = True - else: - print(f"✅ {filepath}: OK") - - if failed: - sys.exit(1) - -if __name__ == "__main__": - main()