mirror of
https://github.com/fabro-sh/fabro.git
synced 2026-10-06 02:48:25 +00:00
74 lines
2.5 KiB
Rust
74 lines
2.5 KiB
Rust
use anyhow::Context;
|
|
use anyhow::Result;
|
|
use fabro_checkpoint::git::Store;
|
|
use fabro_util::terminal::Styles;
|
|
use fabro_workflow::operations::{ForkRunInput, RewindTarget, build_timeline_or_rebuild, fork};
|
|
use git2::Repository;
|
|
|
|
use crate::args::{ForkArgs, GlobalArgs};
|
|
use crate::commands::store::rebuild::rebuild_run_store;
|
|
use crate::server_runs::ServerSummaryLookup;
|
|
use crate::shared::print_json_pretty;
|
|
use crate::shared::repo::ensure_matching_repo_origin;
|
|
|
|
pub(crate) async fn run(args: &ForkArgs, styles: &Styles, globals: &GlobalArgs) -> Result<()> {
|
|
let repo = Repository::discover(".").context("not in a git repository")?;
|
|
let lookup = ServerSummaryLookup::connect(&args.server).await?;
|
|
let run = lookup.resolve(&args.run_id)?;
|
|
let run_id = run.run_id();
|
|
let state = lookup.client().get_run_state(&run_id).await?;
|
|
let record = state.run.context("Failed to load run record from store")?;
|
|
ensure_matching_repo_origin(record.repo_origin_url.as_deref(), "fork")?;
|
|
let store = Store::new(repo);
|
|
let events = lookup.client().list_run_events(&run_id, None, None).await?;
|
|
let run_store = rebuild_run_store(&run_id, &events).await?;
|
|
|
|
let timeline = build_timeline_or_rebuild(&store, Some(&run_store), &run_id).await?;
|
|
|
|
if args.list {
|
|
if globals.json {
|
|
print_json_pretty(&super::rewind::timeline_entries_json(&timeline))?;
|
|
return Ok(());
|
|
}
|
|
super::rewind::print_timeline(&timeline, styles);
|
|
return Ok(());
|
|
}
|
|
|
|
let target = args
|
|
.target
|
|
.as_deref()
|
|
.map(str::parse::<RewindTarget>)
|
|
.transpose()?;
|
|
let new_run_id = fork(
|
|
&store,
|
|
&ForkRunInput {
|
|
source_run_id: run_id,
|
|
target,
|
|
push: !args.no_push,
|
|
},
|
|
)?;
|
|
|
|
let run_id_string = run_id.to_string();
|
|
let new_run_id_string = new_run_id.to_string();
|
|
|
|
if globals.json {
|
|
let target = args.target.clone().unwrap_or_else(|| "latest".to_string());
|
|
print_json_pretty(&serde_json::json!({
|
|
"source_run_id": run_id_string,
|
|
"new_run_id": new_run_id_string,
|
|
"target": target,
|
|
}))?;
|
|
} else {
|
|
eprintln!(
|
|
"\nForked run {} -> {}",
|
|
&run_id_string[..8.min(run_id_string.len())],
|
|
&new_run_id_string[..8.min(new_run_id_string.len())]
|
|
);
|
|
eprintln!(
|
|
"To resume: fabro resume {}",
|
|
&new_run_id_string[..8.min(new_run_id_string.len())]
|
|
);
|
|
}
|
|
|
|
Ok(())
|
|
}
|