use crate::commands;
use crate::config::Config;
use crate::engine::Stack;
use crate::git::GitRepo;
use anyhow::Result;
use colored::Colorize;
use std::process::Command;
pub fn run(no_pr: bool, no_submit: bool, auto_stash_pop: bool) -> Result<()> {
let repo = GitRepo::open()?;
let original = repo.current_branch()?;
let workdir = repo.workdir()?.to_path_buf();
let stack = Stack::load(&repo)?;
println!("{}", "Cascading stack...".bold());
warn_if_trunk_stale(&repo, &stack);
commands::navigate::bottom_with_loaded_stack(&stack, &workdir, &original)?;
commands::restack::run(
false,
false,
false,
false,
true,
true,
auto_stash_pop,
commands::restack::SubmitAfterRestack::No,
)?;
if repo.rebase_in_progress()? {
return Ok(());
}
if no_submit {
println!("{}", "Skipping push and PRs (--no-submit)".dimmed());
} else {
commands::submit::run(
commands::submit::SubmitScope::Stack,
commands::submit::SubmitOptions {
no_pr,
yes: true,
no_prompt: true,
..Default::default()
},
)?;
}
if !repo.rebase_in_progress()? && repo.current_branch()? != original {
repo.checkout(&original)?;
}
Ok(())
}
fn warn_if_trunk_stale(repo: &GitRepo, stack: &Stack) {
let Ok(config) = Config::load() else { return };
let Ok(workdir) = repo.workdir() else { return };
let remote_ref = format!("{}/{}", config.remote_name(), stack.trunk);
let output = Command::new("git")
.args([
"rev-list",
"--count",
&format!("{}..{}", stack.trunk, remote_ref),
])
.current_dir(workdir)
.output();
if let Ok(out) = output
&& out.status.success()
{
let count_str = String::from_utf8_lossy(&out.stdout);
let count: u64 = count_str.trim().parse().unwrap_or(0);
if count > 0 {
println!(
" {} {} is {} commit{} behind {} — run {} to sync first",
"warning:".yellow().bold(),
stack.trunk.cyan(),
count.to_string().yellow(),
if count == 1 { "" } else { "s" },
remote_ref.cyan(),
"stax rs".bold(),
);
}
}
}