From 0717165724ebfcdc301325f77c9e06904134940c Mon Sep 17 00:00:00 2001 From: Jaixii Date: Mon, 29 Jun 2026 04:44:25 -0400 Subject: [PATCH] feat: add --require-license strict mode flag Closes #29 --- src/api_contract_guardian/cli.py | 36 +++++++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/src/api_contract_guardian/cli.py b/src/api_contract_guardian/cli.py index 029b3d4..4f6167a 100644 --- a/src/api_contract_guardian/cli.py +++ b/src/api_contract_guardian/cli.py @@ -2,6 +2,7 @@ from __future__ import annotations +import os from pathlib import Path from typing import Any @@ -26,10 +27,11 @@ def require_license(product: str) -> None: # type: ignore[misc] pass +_require_license_strict: bool = False + + def _require_license(tool_name: str) -> None: """Lazily check revenueholdings license only when a command runs.""" - import os - if os.environ.get("REVENUEHOLDINGS_LICENSE_BYPASS"): return try: @@ -37,7 +39,16 @@ def _require_license(tool_name: str) -> None: require_license(tool_name) except ImportError: - pass + if _require_license_strict: + _get_console().print( + "[bold red]Error:[/bold red] revenueholdings-license is not installed. " + "Install it with: pip install revenueholdings-license", + err=True, + ) + raise typer.Exit(code=1) from None + except Exception: + if _require_license_strict: + raise def _validate_output_format( @@ -70,6 +81,25 @@ def _get_console() -> Any: return _console +@app.callback() +def _app_callback( + require_license_flag: bool = typer.Option( + False, + "--require-license", + help=( + "Exit with an error if revenueholdings-license is not installed " + "or if the license check fails. " + "Also enabled via REVENUEHOLDINGS_REQUIRE_LICENSE=1." + ), + ), +) -> None: + """Detect breaking changes in OpenAPI specs and gate CI pipelines.""" + global _require_license_strict + _require_license_strict = require_license_flag or bool( + os.environ.get("REVENUEHOLDINGS_REQUIRE_LICENSE") + ) + + def _load_and_validate(path: str) -> dict: """Load a spec from file path and validate it's a supported OpenAPI version.""" from .loader import SpecLoadError, load_spec, validate_openapi_version