Skip to content

Commit 930dd5d

Browse files
authored
Fix: remove extraneous spacing between CLI annotation and runtime (#4231)
1 parent 666419d commit 930dd5d

2 files changed

Lines changed: 100 additions & 48 deletions

File tree

sqlmesh/core/console.py

Lines changed: 40 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -891,7 +891,7 @@ def update_snapshot_evaluation_progress(
891891
self.evaluation_column_widths["duration"]
892892
)
893893

894-
msg = f"{batch} {display_name} {annotation} {duration}".replace(
894+
msg = f"{batch} {display_name} {annotation} {duration}".replace(
895895
CHECK_MARK, GREEN_CHECK_MARK
896896
)
897897

@@ -3359,54 +3359,56 @@ def _create_evaluation_model_annotation(snapshot: Snapshot, interval_info: t.Opt
33593359
return interval_info if interval_info else ""
33603360

33613361

3362-
def _calculate_interval_str_len(batched_intervals: t.Dict[Snapshot, t.List[Interval]]) -> int:
3362+
def _calculate_interval_str_len(snapshot: Snapshot, intervals: t.List[Interval]) -> int:
33633363
interval_str_len = 0
3364-
for snapshot, intervals in batched_intervals.items():
3365-
for interval in intervals:
3366-
interval_str_len = max(
3367-
interval_str_len,
3368-
len(
3369-
_create_evaluation_model_annotation(
3370-
snapshot, _format_evaluation_model_interval(snapshot, interval)
3371-
)
3372-
),
3373-
)
3364+
for interval in intervals:
3365+
interval_str_len = max(
3366+
interval_str_len,
3367+
len(
3368+
_create_evaluation_model_annotation(
3369+
snapshot, _format_evaluation_model_interval(snapshot, interval)
3370+
)
3371+
),
3372+
)
33743373
return interval_str_len
33753374

33763375

3377-
def _calculate_audit_str_len(batched_intervals: t.Dict[Snapshot, t.List[Interval]]) -> int:
3376+
def _calculate_audit_str_len(snapshot: Snapshot) -> int:
33783377
# The annotation includes audit results. We cannot build the audits result string
33793378
# until after evaluation occurs, but we must determine the annotation column width here.
33803379
# Therefore, we add enough padding for the longest possible audits result string.
33813380
audit_str_len = 0
33823381
audit_base_str_len = len(f", audits ") + 1 # +1 for check/X
3383-
for snapshot in batched_intervals:
3384-
if snapshot.is_audit:
3382+
if snapshot.is_audit:
3383+
# +1 for "1" audit count, +1 for red X
3384+
audit_str_len = max(
3385+
audit_str_len, audit_base_str_len + (2 if not snapshot.audit.blocking else 1)
3386+
)
3387+
if snapshot.is_model and snapshot.model.audits:
3388+
num_audits = len(snapshot.model.audits_with_args)
3389+
num_nonblocking_audits = sum(
3390+
1
3391+
for audit in snapshot.model.audits_with_args
3392+
if not audit[0].blocking
3393+
or ("blocking" in audit[1] and audit[1]["blocking"] == exp.false())
3394+
)
3395+
if num_audits == 1:
33853396
# +1 for "1" audit count, +1 for red X
3386-
audit_str_len = max(
3387-
audit_str_len, audit_base_str_len + (2 if not snapshot.audit.blocking else 1)
3388-
)
3389-
if snapshot.is_model and snapshot.model.audits:
3390-
num_audits = len(snapshot.model.audits_with_args)
3391-
num_nonblocking_audits = sum(
3392-
1
3393-
for audit in snapshot.model.audits_with_args
3394-
if not audit[0].blocking
3395-
or ("blocking" in audit[1] and audit[1]["blocking"] == exp.false())
3396-
)
3397-
if num_audits == 1:
3398-
# +1 for "1" audit count, +1 for red X
3399-
audit_len = audit_base_str_len + (2 if num_nonblocking_audits else 1)
3400-
else:
3401-
audit_len = audit_base_str_len + len(str(num_audits))
3402-
if num_nonblocking_audits:
3403-
# +1 for space, +1 for red X
3404-
audit_len += len(str(num_nonblocking_audits)) + 2
3405-
audit_str_len = max(audit_str_len, audit_len)
3397+
audit_len = audit_base_str_len + (2 if num_nonblocking_audits else 1)
3398+
else:
3399+
audit_len = audit_base_str_len + len(str(num_audits))
3400+
if num_nonblocking_audits:
3401+
# +1 for space, +1 for red X
3402+
audit_len += len(str(num_nonblocking_audits)) + 2
3403+
audit_str_len = max(audit_str_len, audit_len)
34063404
return audit_str_len
34073405

34083406

34093407
def _calculate_annotation_str_len(batched_intervals: t.Dict[Snapshot, t.List[Interval]]) -> int:
3410-
return _calculate_interval_str_len(batched_intervals) + _calculate_audit_str_len(
3411-
batched_intervals
3412-
)
3408+
annotation_str_len = 0
3409+
for snapshot, intervals in batched_intervals.items():
3410+
annotation_str_len = max(
3411+
annotation_str_len,
3412+
_calculate_interval_str_len(snapshot, intervals) + _calculate_audit_str_len(snapshot),
3413+
)
3414+
return annotation_str_len

tests/cli/test_cli.py

Lines changed: 60 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ def test_plan(runner, tmp_path):
182182
assert_plan_success(result)
183183
# 'Models needing backfill' section and eval progress bar should display the same inclusive intervals
184184
assert "sqlmesh_example.incremental_model: [2020-01-01 - 2022-12-31]" in result.output
185-
assert "sqlmesh_example.incremental_model [insert 2020-01-01 - 2022-12-31]" in result.output
185+
assert "sqlmesh_example.incremental_model [insert 2020-01-01 - 2022-12-31]" in result.output
186186

187187

188188
def test_plan_skip_tests(runner, tmp_path):
@@ -243,7 +243,7 @@ def test_plan_restate_model(runner, tmp_path):
243243
assert result.exit_code == 0
244244
assert_duckdb_test(result)
245245
assert "No changes to plan: project files match the `prod` environment" in result.output
246-
assert "sqlmesh_example.full_model [full refresh" in result.output
246+
assert "sqlmesh_example.full_model [full refresh" in result.output
247247
assert_model_batches_executed(result)
248248
assert_virtual_layer_updated(result)
249249

@@ -553,6 +553,56 @@ def test_plan_dev_no_changes(runner, tmp_path):
553553
assert_virtual_layer_updated(result)
554554

555555

556+
def test_plan_dev_longnames(runner, tmp_path):
557+
create_example_project(tmp_path)
558+
559+
long_model_names = {
560+
"full": f"full_{'a' * 80}",
561+
"incremental": f"incremental_{'b' * 80}",
562+
"seed": f"seed_{'c' * 80}",
563+
}
564+
for model_name in long_model_names:
565+
with open(tmp_path / "models" / f"{model_name}_model.sql", "r") as f:
566+
model_text = f.read()
567+
for more_model_names in long_model_names:
568+
model_text = model_text.replace(
569+
f"sqlmesh_example.{more_model_names}_model",
570+
f"sqlmesh_example.{long_model_names[more_model_names]}_model",
571+
)
572+
with open(tmp_path / "models" / f"{model_name}_model.sql", "w") as f:
573+
f.write(model_text)
574+
575+
# Input: `y` to apply and backfill
576+
result = runner.invoke(
577+
cli,
578+
[
579+
"--log-file-dir",
580+
tmp_path,
581+
"--paths",
582+
tmp_path,
583+
"plan",
584+
"dev_butamuchlongerenvironmentname",
585+
"--skip-tests",
586+
"--no-prompts",
587+
"--auto-apply",
588+
],
589+
)
590+
assert result.exit_code == 0
591+
assert (
592+
"sqlmesh_example__dev_butamuchlongerenvironmentname.seed_cccccccccccccccccccccccc\ncccccccccccccccccccccccccccccccccccccccccccccccccccccccc_model [insert \nseed file]"
593+
in result.output
594+
)
595+
assert (
596+
"sqlmesh_example__dev_butamuchlongerenvironmentname.incremental_bbbbbbbbbbbbbbbbb\nbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_model [insert "
597+
in result.output
598+
)
599+
assert (
600+
"sqlmesh_example__dev_butamuchlongerenvironmentname.full_aaaaaaaaaaaaaaaaaaaaaaaa\naaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_model [full \nrefresh"
601+
in result.output
602+
)
603+
assert_backfill_success(result)
604+
605+
556606
def test_plan_nonbreaking(runner, tmp_path):
557607
create_example_project(tmp_path)
558608
init_prod_and_backfill(runner, tmp_path)
@@ -568,8 +618,8 @@ def test_plan_nonbreaking(runner, tmp_path):
568618
assert "+ 'a' AS new_col" in result.output
569619
assert "Directly Modified: sqlmesh_example.incremental_model (Non-breaking)" in result.output
570620
assert "sqlmesh_example.full_model (Indirect Non-breaking)" in result.output
571-
assert "sqlmesh_example.incremental_model [insert" in result.output
572-
assert "sqlmesh_example.full_model [full refresh" not in result.output
621+
assert "sqlmesh_example.incremental_model [insert" in result.output
622+
assert "sqlmesh_example.full_model [full refresh" not in result.output
573623
assert_backfill_success(result)
574624

575625

@@ -626,8 +676,8 @@ def test_plan_breaking(runner, tmp_path):
626676
assert result.exit_code == 0
627677
assert "+ item_id + 1 AS item_id," in result.output
628678
assert "Directly Modified: sqlmesh_example.full_model (Breaking)" in result.output
629-
assert "sqlmesh_example.full_model [full refresh" in result.output
630-
assert "sqlmesh_example.incremental_model [insert" not in result.output
679+
assert "sqlmesh_example.full_model [full refresh" in result.output
680+
assert "sqlmesh_example.incremental_model [insert" not in result.output
631681
assert_backfill_success(result)
632682

633683

@@ -665,8 +715,8 @@ def test_plan_dev_select(runner, tmp_path):
665715
assert "+ item_id + 1 AS item_id," not in result.output
666716
assert "Directly Modified: sqlmesh_example__dev.full_model (Breaking)" not in result.output
667717
# only incremental_model backfilled
668-
assert "sqlmesh_example__dev.incremental_model [insert" in result.output
669-
assert "sqlmesh_example__dev.full_model [full refresh" not in result.output
718+
assert "sqlmesh_example__dev.incremental_model [insert" in result.output
719+
assert "sqlmesh_example__dev.full_model [full refresh" not in result.output
670720
assert_backfill_success(result)
671721

672722

@@ -704,8 +754,8 @@ def test_plan_dev_backfill(runner, tmp_path):
704754
"Directly Modified: sqlmesh_example__dev.incremental_model (Non-breaking)" in result.output
705755
)
706756
# only incremental_model backfilled
707-
assert "sqlmesh_example__dev.incremental_model [insert" in result.output
708-
assert "sqlmesh_example__dev.full_model [full refresh" not in result.output
757+
assert "sqlmesh_example__dev.incremental_model [insert" in result.output
758+
assert "sqlmesh_example__dev.full_model [full refresh" not in result.output
709759
assert_backfill_success(result)
710760

711761

0 commit comments

Comments
 (0)