use super::super::GitRunner;
use super::super::checkout::Checkout;
use super::Error;
use crate::workspace::{config_ref, proposal::proposal_ref};
use std::path::Path;
pub enum Origin<'a> {
Advance,
Fork { source: &'a str },
Orphan,
Proposal {
parent: &'a str,
message: &'a str,
},
}
pub(super) fn target_ref(name: &str, origin: &Origin<'_>) -> String {
match origin {
Origin::Proposal { .. } => proposal_ref(name),
_ => config_ref(name),
}
}
pub(super) fn materialize<'a>(
git: &'a dyn GitRunner,
repo: &'a Path,
target: &str,
author: &Path,
origin: &Origin,
) -> Result<Checkout<'a>, Error> {
let src = match origin {
Origin::Fork { source } => config_ref(source),
Origin::Proposal { parent, .. } => (*parent).to_string(),
_ => String::new(),
};
let author_str = author.to_string_lossy().to_string();
let (args, created): (Vec<&str>, _) = match origin {
Origin::Advance => (vec!["worktree", "add", &author_str, target], None),
Origin::Fork { .. } => (
vec!["worktree", "add", "-b", target, &author_str, &src],
Some(target.to_string()),
),
Origin::Orphan => (
vec!["worktree", "add", "--orphan", "-b", target, &author_str],
Some(target.to_string()),
),
Origin::Proposal { .. } => (
vec!["worktree", "add", "-b", target, &author_str, &src],
Some(target.to_string()),
),
};
Checkout::add(git, repo, author, &args, created).map_err(Error::Git)
}
pub(super) fn commit_message(name: &str, origin: &Origin) -> String {
let target = target_ref(name, origin);
match origin {
Origin::Advance => format!("config: advance [{target}]"),
Origin::Fork { source } => format!("config: fork {} [{target}]", config_ref(source)),
Origin::Orphan => format!("config: init [{target}]"),
Origin::Proposal { message, .. } => (*message).to_string(),
}
}