Skip to content

CLI

CLI interface.

cli()

CLI entrypoint.

Source code in src/dbt_score/cli.py
@click.version_option(message="%(version)s")
@click.group(
    help=f"\b{BANNER}",
    invoke_without_command=False,
    context_settings={"help_option_names": ["-h", "--help"]},
)
def cli() -> None:
    """CLI entrypoint."""

lint(ctx, format, select, namespace, disabled_rule, manifest, run_dbt_parse, fail_project_under, fail_any_item_under)

Lint dbt metadata.

Source code in src/dbt_score/cli.py
@cli.command()
@click.option(
    "--format",
    "-f",
    help="Output format. Plain is suitable for terminals, manifest for rich "
    "documentation, json for machine-readable output.",
    type=click.Choice(["plain", "manifest", "ascii", "json"]),
    default="plain",
)
@click.option(
    "--select",
    "-s",
    help="Specify the nodes to include.",
    multiple=True,
)
@click.option(
    "--namespace",
    "-n",
    help="Namespace to look for rules.",
    default=None,
    multiple=True,
)
@click.option(
    "--disabled-rule",
    help="Rule to disable.",
    default=None,
    multiple=True,
)
@click.option(
    "--manifest",
    "-m",
    help="Manifest filepath.",
    type=click.Path(path_type=Path),
    default=get_default_manifest_path(),
)
@click.option(
    "--run-dbt-parse",
    "-p",
    help="Run dbt parse.",
    is_flag=True,
    default=False,
)
@click.option(
    "--fail-project-under",
    help="Fail if the project score is under this value.",
    type=float,
    is_flag=False,
    default=None,
)
@click.option(
    "--fail-any-item-under",
    help="Fail if any evaluable item is under this value.",
    type=float,
    is_flag=False,
    default=None,
)
@click.pass_context
def lint(
    ctx: click.Context,
    format: Literal["plain", "manifest", "ascii"],
    select: tuple[str],
    namespace: list[str],
    disabled_rule: list[str],
    manifest: Path,
    run_dbt_parse: bool,
    fail_project_under: float,
    fail_any_item_under: float,
) -> None:
    """Lint dbt metadata."""
    manifest_provided = (
        click.get_current_context().get_parameter_source("manifest")
        != ParameterSource.DEFAULT
    )
    if manifest_provided and run_dbt_parse:
        raise click.UsageError("--run-dbt-parse cannot be used with --manifest.")

    config = Config()
    config.load()
    if namespace:
        config.overload({"rule_namespaces": namespace})
    if disabled_rule:
        config.overload({"disabled_rules": disabled_rule})
    if fail_project_under:
        config.overload({"fail_project_under": fail_project_under})
    if fail_any_item_under:
        config.overload({"fail_any_item_under": fail_any_item_under})

    try:
        if run_dbt_parse:
            dbt_parse()
        evaluation = lint_dbt_project(
            manifest_path=manifest, config=config, format=format, select=select
        )

    except FileNotFoundError:
        logger.error(
            "dbt's manifest.json could not be found. If you're in a dbt project, be "
            "sure to run 'dbt parse' first, or use the option '--run-dbt-parse'."
        )
        ctx.exit(2)

    except DbtParseException:
        logger.error("dbt failed to parse project. Run `dbt parse` to investigate.")
        ctx.exit(2)

    except Exception:
        logger.error(traceback.format_exc())
        ctx.exit(2)

    if (
        any(x.value < config.fail_any_item_under for x in evaluation.scores.values())
        or evaluation.project_score.value < config.fail_project_under
    ):
        ctx.exit(1)

list_command(namespace, disabled_rule, title, format)

Display rules list.

Source code in src/dbt_score/cli.py
@cli.command(name="list")
@click.option(
    "--namespace",
    "-n",
    help="Namespace.",
    default=None,
    multiple=True,
)
@click.option(
    "--disabled-rule",
    help="Rule to disable.",
    default=None,
    multiple=True,
)
@click.option(
    "--title",
    help="Page title (Markdown only).",
    default=None,
)
@click.option(
    "--format",
    "-f",
    help="Output format.",
    type=click.Choice(["terminal", "markdown"]),
    default="terminal",
)
def list_command(
    namespace: list[str], disabled_rule: list[str], title: str, format: str
) -> None:
    """Display rules list."""
    config = Config()
    config.load()
    if namespace:
        config.overload({"rule_namespaces": namespace})
    if disabled_rule:
        config.overload({"disabled_rules": disabled_rule})

    display_catalog(config, title, format)