feat: merge quick wrapper into main manifest scripts

### Changes:

1. **gen_offline-package_manifest.py**
   - Merged gen_offline-package_manifest_quick.py functionality
   - Added auto-derivation of --root from --output path
   - Auto-discovers subdirectories when --include not specified
   - Outputs to offline-package-manifest.json
   - Removed quick wrapper script (merged into main)

2. **gen_docs_manifest.py**
   - Added auto-discovery of subdirectories
   - Scans all category/version/*.html and *.pdf when --include not specified

### Usage:

For gen_offline-package_manifest.py:
  # Auto-derive root from output
  python3 scripts/gen_offline-package_manifest.py \
    --output /data/update-server/dl-index

  # Or specify root explicitly
  python3 scripts/gen_offline-package_manifest.py \
    --root /data/update-server/offline-package \
    --output /data/update-server/dl-index

For gen_docs_manifest.py:
  # Auto-discover all subdirectories
  python3 scripts/gen_docs_manifest.py \
    --root /data/update-server/docs \
    --output /data/update-server/dl-index

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Haitao Pan 2025-11-11 18:58:37 +08:00
parent b488646de7
commit fe4b236a71
3 changed files with 38 additions and 86 deletions

View File

@ -240,8 +240,15 @@ def create_entry(parts: Tuple[str, ...]) -> DocEntry:
)
def collect_docs(root: Path, base_prefix: str, include: List[str]) -> List[DocEntry]:
def collect_docs(root: Path, base_prefix: str, include: List[str], quiet: bool = False) -> List[DocEntry]:
entries: Dict[Tuple[str, ...], DocEntry] = {}
# Auto-discover directories if include is not specified or only contains default
if not include or include == ["docs"]:
include = [d.name for d in root.iterdir() if d.is_dir() and not should_skip(d)]
if not quiet:
print(f"Auto-discovered directories: {', '.join(include)}")
include_set = set(include)
for file_path in root.rglob("*"):
@ -311,7 +318,7 @@ def main() -> None:
if not root.exists() or not root.is_dir():
raise SystemExit(f"Root path does not exist or is not a directory: {root}")
entries = collect_docs(root, args.base_url_prefix, args.include)
entries = collect_docs(root, args.base_url_prefix, args.include, args.quiet)
if not args.quiet:
print(f"Discovered {len(entries)} documentation entries under {root}")

View File

@ -176,8 +176,8 @@ def write_json(path: Path, data: Dict):
tmp.replace(path)
def main():
ap = argparse.ArgumentParser()
ap.add_argument("--root", default="/data/update-server/", help="Filesystem root of the mirror (default: /data/update-server/)")
ap = argparse.ArgumentParser(description="Generate offline-package manifest")
ap.add_argument("--root", help="Filesystem root of the mirror. If not specified, will be auto-derived from --output")
ap.add_argument("--base-url-prefix", default="https://dl.svc.plus/offline-package", help="URL prefix (default: https://dl.svc.plus/offline-package)")
ap.add_argument("--quiet", action="store_true")
ap.add_argument(
@ -188,9 +188,8 @@ def main():
)
ap.add_argument(
"--include",
default=["offline-package"],
action="append",
help="Directory names to include in the manifest. Can be provided multiple times. (default: offline-package)",
help="Directory names to include in the manifest. Can be provided multiple times. If not specified, auto-discovers all subdirectories.",
)
ap.add_argument(
"--output",
@ -199,6 +198,23 @@ def main():
)
args = ap.parse_args()
# Auto-derive root from output if not specified
if not args.root:
output_path = Path(args.output).resolve()
# Try to derive root from common patterns
# If output is /data/update-server/dl-index, root could be /data/update-server or /data/update-server/offline-package
if str(output_path).endswith('/dl-index'):
# Try parent / offline-package first
candidate = output_path.parent / "offline-package"
if candidate.exists() and candidate.is_dir():
args.root = str(candidate)
else:
# Fall back to parent
args.root = str(output_path.parent)
else:
# Default fallback
args.root = str(output_path.parent)
root = Path(args.root).resolve()
if not root.exists():
print(f"Root does not exist: {root}", file=sys.stderr)
@ -206,6 +222,12 @@ def main():
excluded = normalize_excludes(args.exclude, root)
# Auto-discover directories if include is not specified
if not args.include:
args.include = [d.name for d in root.iterdir() if d.is_dir() and not is_hidden(d.name)]
if not args.quiet:
print(f"Auto-discovered directories: {', '.join(args.include)}")
# Create set of included directories
include_set = set(args.include)
@ -256,20 +278,10 @@ def main():
output_path = Path(args.output)
output_path.mkdir(parents=True, exist_ok=True)
# Write artifacts-manifest.json to output directory
write_json(output_path / "artifacts-manifest.json", listings)
# Write offline-package-manifest.json to output directory
write_json(output_path / "offline-package-manifest.json", listings)
if not args.quiet:
print(f"Wrote {output_path / 'artifacts-manifest.json'}")
# Create offline-package.json specifically for offline-package directory
offline_package_listings = [
listing for listing in listings
if listing.get('path', '').startswith('offline-package/') or listing.get('path', '') == 'offline-package/'
]
if offline_package_listings:
write_json(output_path / "offline-package.json", offline_package_listings)
if not args.quiet:
print(f"Wrote {output_path / 'offline-package.json'}")
print(f"Wrote {output_path / 'offline-package-manifest.json'}")
if __name__ == "__main__":
main()

View File

@ -1,67 +0,0 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Quick wrapper for gen_offline-package_manifest.py with smart defaults.
This script provides a simpler interface where you only need to specify
the output path, and it automatically uses sensible defaults.
Usage:
python3 scripts/gen_offline-package_manifest_quick.py /path/to/update-server/dl-index
Equivalent to:
python3 scripts/gen_offline-package_manifest.py \
--root /path/to/update-server \
--include offline-package \
--output /path/to/update-server/dl-index
"""
import subprocess
import sys
from pathlib import Path
def main():
if len(sys.argv) < 2:
print("Usage: python3 scripts/gen_offline-package_manifest_quick.py <output-dir>")
print("\nExample:")
print(" python3 scripts/gen_offline-package_manifest_quick.py /data/update-server/dl-index")
print("\nThis will:")
print(" - Use --root: /data/update-server")
print(" - Use --include: offline-package")
print(" - Create artifacts-manifest.json and offline-package.json in the output directory")
sys.exit(1)
output_dir = sys.argv[1]
output_path = Path(output_dir).resolve()
# Auto-derive root from output directory
# If output is /data/update-server/dl-index, root should be /data/update-server
root = output_path.parent
# Run the actual script with defaults
cmd = [
"python3",
"/Users/shenlan/workspaces/XControl/scripts/gen_offline-package_manifest.py",
"--root", str(root),
"--include", "offline-package",
"--output", str(output_path)
]
print(f"Running: {' '.join(cmd)}")
result = subprocess.run(cmd)
if result.returncode == 0:
print(f"\n✅ Success! Created files:")
artifacts = output_path / "artifacts-manifest.json"
offline = output_path / "offline-package.json"
if artifacts.exists():
print(f" - {artifacts}")
if offline.exists():
print(f" - {offline}")
sys.exit(result.returncode)
if __name__ == "__main__":
main()