Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 33 additions & 3 deletions src/api_contract_guardian/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from __future__ import annotations

import os
from pathlib import Path
from typing import Any

Expand All @@ -26,18 +27,28 @@ 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:
from revenueholdings_license import require_license

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(
Expand Down Expand Up @@ -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
Expand Down
Loading