All checks were successful
Build and Publish Container Image / build-and-push (push) Successful in 38s
Assistant: codex Assistant-Model: gpt-5.6-sol Assistant-Session: 01a02b22-9638-76d2-bbff-b7ea1770b118
73 lines
2.2 KiB
Python
73 lines
2.2 KiB
Python
"""Operator CLI for SBOM Nexus."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import argparse
|
|
import json
|
|
import os
|
|
from pathlib import Path
|
|
|
|
from sbom_nexus.scanner import scan_repository
|
|
|
|
|
|
def _serve(args: argparse.Namespace) -> None:
|
|
if args.database_url:
|
|
os.environ["SBOM_NEXUS_DATABASE_URL"] = args.database_url
|
|
elif args.database:
|
|
os.environ["SBOM_NEXUS_DATABASE_PATH"] = str(Path(args.database).resolve())
|
|
import uvicorn
|
|
|
|
uvicorn.run(
|
|
"sbom_nexus.api:create_app",
|
|
host=args.host,
|
|
port=args.port,
|
|
reload=args.reload,
|
|
factory=True,
|
|
)
|
|
|
|
|
|
def _scan(args: argparse.Namespace) -> None:
|
|
result = scan_repository(
|
|
Path(args.path), slug=args.slug, source_revision=args.source_revision
|
|
)
|
|
rendered = json.dumps(result, indent=2, sort_keys=True)
|
|
if args.output:
|
|
output = Path(args.output)
|
|
if output.exists() and not args.force:
|
|
raise SystemExit(f"Refusing to overwrite {output}; pass --force")
|
|
output.write_text(rendered + "\n", encoding="utf-8")
|
|
else:
|
|
print(rendered)
|
|
if not result["ok"]:
|
|
raise SystemExit(1)
|
|
|
|
|
|
def build_parser() -> argparse.ArgumentParser:
|
|
parser = argparse.ArgumentParser(prog="sbom-nexus")
|
|
subparsers = parser.add_subparsers(dest="command", required=True)
|
|
|
|
serve = subparsers.add_parser("serve", help="Run the SBOM Nexus HTTP API")
|
|
serve.add_argument("--host", default="127.0.0.1")
|
|
serve.add_argument("--port", type=int, default=8010)
|
|
serve.add_argument("--database", help="SQLite database path")
|
|
serve.add_argument("--database-url", help="SQLAlchemy database URL (PostgreSQL in production)")
|
|
serve.add_argument("--reload", action="store_true")
|
|
serve.set_defaults(handler=_serve)
|
|
|
|
scan = subparsers.add_parser("scan", help="Derive a snapshot from repository sources")
|
|
scan.add_argument("path", nargs="?", default=".")
|
|
scan.add_argument("--slug")
|
|
scan.add_argument("--source-revision")
|
|
scan.add_argument("--output")
|
|
scan.add_argument("--force", action="store_true")
|
|
scan.set_defaults(handler=_scan)
|
|
return parser
|
|
|
|
|
|
def main() -> None:
|
|
args = build_parser().parse_args()
|
|
args.handler(args)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|