chore: import upstream snapshot with attribution
CI: cua-driver distro-compat matrix / debian:12 (glibc 2.36) (push) Has been cancelled
CI: SPDX Headers / Check SPDX headers (warn-only) (push) Has been cancelled
CD: Docs MCP Server / build (linux/amd64) (push) Has been cancelled
CD: Docs MCP Server / build (linux/arm64) (push) Has been cancelled
CD: Docs MCP Server / merge (push) Has been cancelled
CI: cua-driver distro-compat matrix / Resolve release version (push) Has been cancelled
CI: cua-driver distro-compat matrix / fedora:41 (glibc 2.40) (push) Has been cancelled
CI: cua-driver distro-compat matrix / rockylinux:9 (glibc 2.34) (push) Has been cancelled
CI: cua-driver distro-compat matrix / ubuntu:22.04 (glibc 2.35) (push) Has been cancelled
CI: cua-driver distro-compat matrix / ubuntu:24.04 (glibc 2.39) (push) Has been cancelled
CI: cua-driver distro-compat matrix / Distro compat summary (push) Has been cancelled
CI: Rust Linux unit / Rust Linux unit and compile (push) Has been cancelled
CI: Rust Windows unit / Rust Windows unit and compile (push) Has been cancelled
CI: Nix Linux Rust source / Nix / compositor build (push) Has been cancelled
CI: Nix Linux Rust source / Nix / driver package (push) Has been cancelled
CI: Nix Linux Rust source / Nix / Rust unit tests (push) Has been cancelled
CI: cua-driver distro-compat matrix / debian:12 (glibc 2.36) (push) Has been cancelled
CI: SPDX Headers / Check SPDX headers (warn-only) (push) Has been cancelled
CD: Docs MCP Server / build (linux/amd64) (push) Has been cancelled
CD: Docs MCP Server / build (linux/arm64) (push) Has been cancelled
CD: Docs MCP Server / merge (push) Has been cancelled
CI: cua-driver distro-compat matrix / Resolve release version (push) Has been cancelled
CI: cua-driver distro-compat matrix / fedora:41 (glibc 2.40) (push) Has been cancelled
CI: cua-driver distro-compat matrix / rockylinux:9 (glibc 2.34) (push) Has been cancelled
CI: cua-driver distro-compat matrix / ubuntu:22.04 (glibc 2.35) (push) Has been cancelled
CI: cua-driver distro-compat matrix / ubuntu:24.04 (glibc 2.39) (push) Has been cancelled
CI: cua-driver distro-compat matrix / Distro compat summary (push) Has been cancelled
CI: Rust Linux unit / Rust Linux unit and compile (push) Has been cancelled
CI: Rust Windows unit / Rust Windows unit and compile (push) Has been cancelled
CI: Nix Linux Rust source / Nix / compositor build (push) Has been cancelled
CI: Nix Linux Rust source / Nix / driver package (push) Has been cancelled
CI: Nix Linux Rust source / Nix / Rust unit tests (push) Has been cancelled
This commit is contained in:
Executable
+124
@@ -0,0 +1,124 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Add or verify SPDX + copyright headers on cua-driver source files.
|
||||
|
||||
Two modes:
|
||||
--apply (default): insert the header on files that lack it
|
||||
--check: exit 1 if any tracked file is missing the header (use in CI)
|
||||
|
||||
Header format (matches Linux-kernel / Rust ecosystem convention):
|
||||
|
||||
// SPDX-License-Identifier: MIT
|
||||
// Copyright (c) 2026 Cua AI, Inc.
|
||||
//
|
||||
// <blank line>
|
||||
// <original file content>
|
||||
|
||||
The script is idempotent: it skips any file that already contains an
|
||||
SPDX-License-Identifier marker in its first 2 KiB.
|
||||
|
||||
Typical use:
|
||||
scripts/spdx-headers.py # apply to libs/cua-driver
|
||||
scripts/spdx-headers.py libs/cua-driver-rs # apply to a different tree
|
||||
scripts/spdx-headers.py --check # CI gate
|
||||
scripts/spdx-headers.py --dry-run # preview only
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import pathlib
|
||||
import sys
|
||||
from typing import Iterable
|
||||
|
||||
LICENSE_ID = "MIT"
|
||||
COPYRIGHT_HOLDER = "Cua AI, Inc."
|
||||
COPYRIGHT_YEAR = "2026"
|
||||
|
||||
HEADER_LINES = [
|
||||
f"// SPDX-License-Identifier: {LICENSE_ID}",
|
||||
f"// Copyright (c) {COPYRIGHT_YEAR} {COPYRIGHT_HOLDER}",
|
||||
"",
|
||||
]
|
||||
MARKER = "SPDX-License-Identifier"
|
||||
EXTENSIONS = {".swift", ".rs"}
|
||||
SKIP_DIR_NAMES = {"target", ".build", "build", "node_modules", "DerivedData", ".git"}
|
||||
DEFAULT_ROOT = "libs/cua-driver"
|
||||
|
||||
|
||||
def file_has_header(path: pathlib.Path) -> bool:
|
||||
try:
|
||||
head = path.read_bytes()[:2048].decode("utf-8", errors="replace")
|
||||
except OSError:
|
||||
return True # don't try to rewrite unreadable files
|
||||
return MARKER in head
|
||||
|
||||
|
||||
def insert_header(path: pathlib.Path) -> None:
|
||||
body = path.read_text(encoding="utf-8")
|
||||
path.write_text("\n".join(HEADER_LINES) + "\n" + body, encoding="utf-8")
|
||||
|
||||
|
||||
def iter_source_files(root: pathlib.Path) -> Iterable[pathlib.Path]:
|
||||
for path in root.rglob("*"):
|
||||
if not path.is_file():
|
||||
continue
|
||||
if path.suffix not in EXTENSIONS:
|
||||
continue
|
||||
if any(part in SKIP_DIR_NAMES for part in path.parts):
|
||||
continue
|
||||
yield path
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter)
|
||||
parser.add_argument("root", nargs="?", default=DEFAULT_ROOT, help=f"directory to scan (default: {DEFAULT_ROOT})")
|
||||
mode = parser.add_mutually_exclusive_group()
|
||||
mode.add_argument("--apply", action="store_true", help="insert headers on files that lack them (default)")
|
||||
mode.add_argument("--check", action="store_true", help="exit 1 if any file is missing a header")
|
||||
mode.add_argument("--dry-run", action="store_true", help="report what would change without writing")
|
||||
args = parser.parse_args()
|
||||
|
||||
root = pathlib.Path(args.root).resolve()
|
||||
if not root.exists():
|
||||
print(f"error: {root} does not exist", file=sys.stderr)
|
||||
return 2
|
||||
|
||||
apply_mode = args.apply or not (args.check or args.dry_run)
|
||||
missing: list[pathlib.Path] = []
|
||||
touched = 0
|
||||
skipped = 0
|
||||
|
||||
for path in iter_source_files(root):
|
||||
if file_has_header(path):
|
||||
skipped += 1
|
||||
continue
|
||||
missing.append(path)
|
||||
rel = path.relative_to(root)
|
||||
if apply_mode:
|
||||
insert_header(path)
|
||||
touched += 1
|
||||
print(f"+ {rel}")
|
||||
elif args.dry_run:
|
||||
print(f"would add header: {rel}")
|
||||
else: # --check
|
||||
print(f"missing header: {rel}")
|
||||
|
||||
print()
|
||||
if args.check:
|
||||
if missing:
|
||||
print(f"error: {len(missing)} file(s) missing SPDX header under {root}", file=sys.stderr)
|
||||
return 1
|
||||
print(f"ok: all {skipped} source files under {root} carry SPDX headers")
|
||||
return 0
|
||||
|
||||
if args.dry_run:
|
||||
print(f"would add headers to {len(missing)} file(s); {skipped} already have one")
|
||||
return 0
|
||||
|
||||
print(f"added headers to {touched} file(s); {skipped} already had one")
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
Reference in New Issue
Block a user