c9bfc98713
---ci--- project: acdl phase: 2 milestone: v1.28 status: execute persona: backend-engineer --- nova apply subcommand (44 lines, CAP-034: <=50 lines, <=3 functions, no if except __main__ guard). --local calls core.env.synthesize_local_env() + core.contract_resolver.resolve(). --sign-local-review calls core.jws_attestation.sign_attestation() (REQ-332) and appends the JWS to the output. Delegates to core/ — no business logic in the subcommand (NFR-7). Auto-registered via nova/cli.py pkgutil discovery; CAP-033/034 tests pass.
45 lines
2.1 KiB
Python
45 lines
2.1 KiB
Python
"""nova apply — resolve a contract + synthesize local env (REQ-330, REQ-332).
|
|
|
|
Subcommand (≤50 lines, ≤3 functions, delegates to core/ — NFR-7).
|
|
nova apply --local --contract .nova/contract.yml [--sign-local-review]
|
|
nova apply --contract contracts/microservice.yml --out stack.json
|
|
|
|
--local: calls core.env.synthesize_local_env() + core.contract_resolver.resolve()
|
|
--sign-local-review: calls core.jws_attestation.sign_attestation() (REQ-332)
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
|
|
from core import env
|
|
from core.contract_resolver import resolve
|
|
from core.jws_attestation import sign_attestation
|
|
|
|
|
|
def add_parser(subparsers):
|
|
p = subparsers.add_parser("apply", help="resolve a contract (+ local env synth)")
|
|
p.add_argument("--contract", default=".nova/contract.yml", help="contract YAML path")
|
|
p.add_argument("--out", default=None, help="output path (default: stdout)")
|
|
p.add_argument("--local", action="store_true", help="synthesize a local env (no AWS)")
|
|
p.add_argument("--environment", default=None, help="environment override")
|
|
p.add_argument("--sign-local-review", action="store_true", help="sign a local-review attestation (REQ-332)")
|
|
p.add_argument("--pat", default=None, help="PAT for --sign-local-review")
|
|
p.set_defaults(_run=run)
|
|
|
|
|
|
def run(args) -> int:
|
|
synth = env.synthesize_local_env(args.contract, environment=args.environment) if args.local else None
|
|
env_override = (synth["name"] if isinstance(synth, dict) else None) or args.environment
|
|
result = resolve(args.contract, environment_override=env_override)
|
|
blob = json.dumps(result, indent=2) + "\n"
|
|
pat = args.pat or env.get_env("PAT", "") or ""
|
|
attestation = sign_attestation({"contract": args.contract, "review": "local"}, pat) if (args.sign_local_review and pat) else None
|
|
blob = blob + (attestation + "\n" if attestation else "")
|
|
print(blob) if args.out is None else open(args.out, "w").write(blob)
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
import sys
|
|
print("use: nova apply --contract <contract.yml> [--local] [--sign-local-review]", file=sys.stderr) |