diff --git a/sqlmesh/cli/main.py b/sqlmesh/cli/main.py index f5a3c62cf9..608b6eefb2 100644 --- a/sqlmesh/cli/main.py +++ b/sqlmesh/cli/main.py @@ -553,6 +553,7 @@ def diff(ctx: click.Context, environment: t.Optional[str] = None) -> None: ) @click.option( "--min-intervals", + type=int, default=None, help="For every model, ensure at least this many intervals are covered by a missing intervals check regardless of the plan start date", ) diff --git a/tests/cli/test_cli.py b/tests/cli/test_cli.py index 092def8e0c..c625cb084d 100644 --- a/tests/cli/test_cli.py +++ b/tests/cli/test_cli.py @@ -263,6 +263,44 @@ def test_plan_skip_backfill(runner, tmp_path, flag): assert "Model batches executed" not in result.output +def test_plan_min_intervals(runner, tmp_path): + create_example_project(tmp_path) + + # build prod so the dev plan below has a baseline to diff against + runner.invoke( + cli, + ["--log-file-dir", tmp_path, "--paths", tmp_path, "plan", "--no-prompts", "--auto-apply"], + ) + update_incremental_model(tmp_path) + + # --min-intervals must be coerced to int; otherwise the string reaches + # range() in _calculate_start_override_per_model and raises TypeError + result = runner.invoke( + cli, + [ + "--log-file-dir", + tmp_path, + "--paths", + tmp_path, + "plan", + "dev", + "--no-prompts", + "--auto-apply", + "--min-intervals", + "1", + ], + ) + assert result.exit_code == 0, result.output + + # a non-integer value is rejected by click, not surfaced as a traceback + result = runner.invoke( + cli, + ["--log-file-dir", tmp_path, "--paths", tmp_path, "plan", "dev", "--min-intervals", "abc"], + ) + assert result.exit_code == 2 + assert "is not a valid integer" in result.output + + def test_plan_auto_apply(runner, tmp_path): create_example_project(tmp_path)