Skip to content

Commit eb25be6

Browse files
fix: verify daemon readable push previews
1 parent 245a320 commit eb25be6

6 files changed

Lines changed: 65 additions & 16 deletions

File tree

crates/loc-cli/src/commands.rs

Lines changed: 36 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4106,6 +4106,7 @@ fn verify_daemon_push_plan_matches_cli_preview(
41064106
fn push_preview_plan_matches(cli_preview: &PushReport, daemon_preview: &PushReport) -> bool {
41074107
cli_preview.validation == daemon_preview.validation
41084108
&& cli_preview.plan == daemon_preview.plan
4109+
&& cli_preview.readable_diff == daemon_preview.readable_diff
41094110
&& cli_preview.guardrail == daemon_preview.guardrail
41104111
}
41114112

@@ -4235,7 +4236,7 @@ fn diff(args: &[String], json: bool) -> i32 {
42354236
exit_code
42364237
}
42374238
Ok(report) => {
4238-
let exit_code = diff_plain_report_exit_code(&report);
4239+
let exit_code = diff_report_exit_code(&report);
42394240
print_diff_report(&report);
42404241
exit_code
42414242
}
@@ -6637,13 +6638,6 @@ fn diff_report_exit_code(report: &crate::diff::DiffReport) -> i32 {
66376638
}
66386639
}
66396640

6640-
fn diff_plain_report_exit_code(report: &crate::diff::DiffReport) -> i32 {
6641-
match report.action.as_str() {
6642-
"confirm_plan" | "confirm_dangerous_plan" => 4,
6643-
_ => diff_report_exit_code(report),
6644-
}
6645-
}
6646-
66476641
fn pull_report_exit_code(report: &PullReport) -> i32 {
66486642
if report.ok {
66496643
EXIT_SUCCESS
@@ -7192,9 +7186,9 @@ mod tests {
71927186
print_push_confirmation_preview, projection_mode_for_target,
71937187
projection_usage_options_for_target, prompt_for_push_confirmation,
71947188
pull_direct_fallback_error, push_confirmation_preview_matches_displayed,
7195-
should_prompt_for_push_confirmation, should_refresh_notion_url_search,
7196-
spinner_config_for_command, spinner_enabled, status as run_status_command,
7197-
validate_virtual_projection_registration, write_log_report,
7189+
push_preview_plan_matches, should_prompt_for_push_confirmation,
7190+
should_refresh_notion_url_search, spinner_config_for_command, spinner_enabled,
7191+
status as run_status_command, validate_virtual_projection_registration, write_log_report,
71987192
};
71997193

72007194
#[test]
@@ -7798,6 +7792,18 @@ mod tests {
77987792
assert_eq!(diff_report_exit_code(&report(false)), EXIT_VALIDATION);
77997793
}
78007794

7795+
#[test]
7796+
fn confirm_plan_diff_report_exits_successfully_when_clean() {
7797+
let mut report = report(true);
7798+
report.action = "confirm_plan".to_string();
7799+
report.readable_diff = Some(locality_core::readable_diff::ReadableDiffOutput {
7800+
files: Vec::new(),
7801+
text: "diff --locality a/Roadmap.md b/Roadmap.md\n".to_string(),
7802+
});
7803+
7804+
assert_eq!(diff_report_exit_code(&report), EXIT_SUCCESS);
7805+
}
7806+
78017807
#[test]
78027808
fn push_report_exit_codes_track_gate_states() {
78037809
assert_eq!(
@@ -7929,6 +7935,25 @@ mod tests {
79297935
));
79307936
}
79317937

7938+
#[test]
7939+
fn daemon_push_preview_match_includes_readable_diff() {
7940+
let mut cli_preview = push_report("confirm_plan");
7941+
cli_preview.readable_diff = Some(locality_core::readable_diff::ReadableDiffOutput {
7942+
files: Vec::new(),
7943+
text: "diff --locality a/Roadmap.md b/Roadmap.md\n-Old\n+New\n".to_string(),
7944+
});
7945+
let mut daemon_preview = cli_preview.clone();
7946+
7947+
assert!(push_preview_plan_matches(&cli_preview, &daemon_preview));
7948+
7949+
daemon_preview.readable_diff = Some(locality_core::readable_diff::ReadableDiffOutput {
7950+
files: Vec::new(),
7951+
text: "diff --locality a/Roadmap.md b/Roadmap.md\n-Old\n+Different\n".to_string(),
7952+
});
7953+
7954+
assert!(!push_preview_plan_matches(&cli_preview, &daemon_preview));
7955+
}
7956+
79327957
#[test]
79337958
fn spinner_is_only_enabled_for_human_terminal_output() {
79347959
assert!(spinner_enabled(false, true));

crates/loc-cli/src/push.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,7 @@ impl PushReport {
223223
mount_id,
224224
entity_id,
225225
pipeline,
226+
readable_diff,
226227
action,
227228
execution,
228229
push_id,
@@ -252,7 +253,7 @@ impl PushReport {
252253
.map(ValidationIssueOutput::from)
253254
.collect(),
254255
plan: pipeline.plan.map(PushPlanOutput::from),
255-
readable_diff: None,
256+
readable_diff,
256257
guardrail: GuardrailOutput::from(pipeline.guardrail),
257258
action: daemon_action_name(&action, &pipeline_action, error.as_ref()).to_string(),
258259
pipeline_action,

crates/loc-cli/tests/diff.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -640,7 +640,7 @@ fn diff_plain_text_summary_includes_entity_creates() {
640640
.expect("run loc diff");
641641

642642
assert!(
643-
output.status.code() == Some(4),
643+
output.status.success(),
644644
"stdout:\n{}\nstderr:\n{}",
645645
String::from_utf8_lossy(&output.stdout),
646646
String::from_utf8_lossy(&output.stderr)
@@ -686,7 +686,7 @@ fn diff_plain_text_output_includes_readable_patch() {
686686
.expect("run loc diff");
687687

688688
assert!(
689-
output.status.code() == Some(4),
689+
output.status.success(),
690690
"stdout:\n{}\nstderr:\n{}",
691691
String::from_utf8_lossy(&output.stdout),
692692
String::from_utf8_lossy(&output.stderr)

crates/loc-cli/tests/push.rs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use std::thread;
1010
use std::time::{Duration, Instant, SystemTime, UNIX_EPOCH};
1111

1212
use loc_cli::push::{
13-
PushOptions, push_report_exit_code, run_push, run_push_with_daemon,
13+
PushOptions, PushReport, push_report_exit_code, run_push, run_push_with_daemon,
1414
run_push_with_daemon_at_state_root, select_push_targets,
1515
};
1616
use locality_connector::{
@@ -28,6 +28,7 @@ use locality_core::model::{
2828
};
2929
use locality_core::planner::{GuardrailDecision, PushOperation, PushPlan};
3030
use locality_core::push::{PushPipelineAction, PushPipelineResult, PushStage};
31+
use locality_core::readable_diff::ReadableDiffOutput;
3132
use locality_core::shadow::ShadowDocument;
3233
use locality_core::validation::ValidationReport;
3334
use locality_core::{LocalityError, LocalityResult};
@@ -710,6 +711,22 @@ fn push_json_preview_uses_cli_diff_plan_when_running_daemon_has_stale_planner()
710711
);
711712
}
712713

714+
#[test]
715+
fn daemon_push_report_preserves_readable_diff_for_cli_preview() {
716+
let fixture = PushFixture::new();
717+
let mut daemon_report =
718+
stale_daemon_push_report(&fixture.root.join("Roadmap.md"), &fixture.mount_id);
719+
let readable_diff = ReadableDiffOutput {
720+
files: Vec::new(),
721+
text: "diff --locality a/Roadmap.md b/Roadmap.md\n-Old\n+New\n".to_string(),
722+
};
723+
daemon_report.readable_diff = Some(readable_diff.clone());
724+
725+
let report = PushReport::from_daemon(daemon_report);
726+
727+
assert_eq!(report.readable_diff, Some(readable_diff));
728+
}
729+
713730
#[test]
714731
fn approved_push_refuses_stale_daemon_plan_before_apply() {
715732
let fixture = PushFixture::new();
@@ -1065,6 +1082,7 @@ fn stale_daemon_push_report(path: &Path, mount_id: &MountId) -> PushJobReport {
10651082
PushStage::PlanAndConfirm,
10661083
],
10671084
},
1085+
readable_diff: None,
10681086
action: PushJobAction::NotReady,
10691087
execution: None,
10701088
push_id: None,

crates/localityd/src/execution.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use locality_core::hydration::HydrationRequest;
1313
use locality_core::journal::{JournalStatus, PushId};
1414
use locality_core::model::{MountId, RemoteId};
1515
use locality_core::push::{PushExecutionResult, PushPipelineResult};
16+
use locality_core::readable_diff::ReadableDiffOutput;
1617
use serde::{Deserialize, Serialize};
1718

1819
use crate::hydration::{HydrationDrainReport, HydrationOutcome, HydrationSource};
@@ -70,6 +71,7 @@ pub struct PushJobReport {
7071
pub mount_id: MountId,
7172
pub entity_id: RemoteId,
7273
pub pipeline: PushPipelineResult,
74+
pub readable_diff: Option<ReadableDiffOutput>,
7375
pub action: PushJobAction,
7476
pub execution: Option<PushExecutionResult>,
7577
pub push_id: Option<PushId>,

crates/localityd/src/push.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,7 @@ where
171171
mount_id: prepared.mount.mount_id,
172172
entity_id: prepared.entity.remote_id,
173173
pipeline: prepared.pipeline,
174+
readable_diff: prepared.readable_diff,
174175
action: PushJobAction::NotReady,
175176
execution: None,
176177
push_id: None,
@@ -334,7 +335,7 @@ where
334335
previous_push_id,
335336
created_at_unix_ms,
336337
))
337-
.with_readable_diff(readable_diff);
338+
.with_readable_diff(readable_diff.clone());
338339

339340
if !prepared.shadows.is_empty() {
340341
execution_request = execution_request.with_preimages(
@@ -372,6 +373,7 @@ where
372373
mount_id: prepared.mount.mount_id,
373374
entity_id: prepared.entity.remote_id,
374375
pipeline: prepared.pipeline,
376+
readable_diff: readable_diff.clone(),
375377
action: PushJobAction::from_execution(&result),
376378
push_id: Some(result.push_id.clone()),
377379
journal_status: result.journal_status.clone(),
@@ -383,6 +385,7 @@ where
383385
mount_id: prepared.mount.mount_id,
384386
entity_id: prepared.entity.remote_id,
385387
pipeline: prepared.pipeline,
388+
readable_diff,
386389
action: PushJobAction::Failed,
387390
execution: None,
388391
push_id: Some(push_id.clone()),

0 commit comments

Comments
 (0)