Coverage for src/check_datapackage/cli.py: 96%
23 statements
« prev ^ index » next coverage.py v7.14.1, created at 2026-06-09 08:15 +0000
« prev ^ index » next coverage.py v7.14.1, created at 2026-06-09 08:15 +0000
1"""Functions for the exposed CLI."""
3from typing import Annotated, Any, Optional
5from cyclopts import Parameter
6from seedcase_soil import (
7 Address,
8 parse_source,
9 pretty_print,
10 read_properties,
11 run_without_tracebacks,
12 setup_cli,
13)
15from check_datapackage.check import check
16from check_datapackage.config import Config
17from check_datapackage.exclusion import Exclusion
18from check_datapackage.extensions import Extensions, RequiredCheck
20CUSTOM_CHECKS_CONFIG_ERROR = (
21 "Custom checks cannot be configured in TOML because `check` must be "
22 "a Python callable. Define CustomCheck extensions in Python instead."
23)
26class ExtensionsCli:
27 """Extensions that can be represented in a TOML config file."""
29 def __init__(
30 self,
31 required_checks: Optional[list[RequiredCheck]] = None,
32 custom_checks: Any = None,
33 ) -> None:
34 """Create CLI extensions from config-file-supported fields."""
35 if custom_checks is not None:
36 raise ValueError(CUSTOM_CHECKS_CONFIG_ERROR)
37 self.required_checks = required_checks or []
40app = setup_cli(
41 name="check-datapackage",
42 help=(
43 "check-datapackage checks if metadata is compliant with the Data Package"
44 "standard"
45 ),
46 config_name=".cdp.toml",
47)
50@app.command(name="check")
51def check_cmd(
52 source: str = "datapackage.json",
53 /, # End of positional-only args
54 *, # Start of keyword-only params
55 strict: bool = False,
56 exclusions: Annotated[list[Exclusion], Parameter(show=False)] = [],
57 extensions: Annotated[ExtensionsCli, Parameter(show=False)] = ExtensionsCli(),
58) -> None:
59 """Check a Data Package's metadata against the Data Package standard.
61 Outputs a human-readable explanation of any issues found.
63 Args:
64 source: The location of a `datapackage.json`, defaults to a file or folder
65 path. Can also be an `https:` source to a remote `datapackage.json` or a
66 `github:` / `gh:` pointing to a repo with a `datapackage.json`
67 in the repo root (in the format `gh:org/repo`, which can also include
68 reference to a tag or branch, such as `gh:org/repo@main` or
69 `gh:org/repo@1.0.1`).
70 strict: If True, check "SHOULD" properties in addition to "MUST"
71 properties from the Data Package standard.
72 exclusions: A hidden CLI/config parameter for excluding issues by JSONPath
73 and/or issue type.
74 extensions: A hidden CLI/config parameter for adding extra checks.
75 """
76 address: Address = parse_source(source)
77 properties: dict[str, Any] = read_properties(address)
78 config = Config(
79 strict=strict,
80 exclusions=exclusions,
81 extensions=Extensions(required_checks=extensions.required_checks),
82 )
83 check(properties, config=config, error=True)
84 pretty_print("[green]All checks passed![/green]")
87def main() -> None:
88 """Create an entry point to run the cli without tracebacks."""
89 run_without_tracebacks(app)