use super::{ConfigSource, VERSION_FILE, control_origin, read_control};
use crate::config::Workflow;
use crate::config::version::Version;
use crate::prompt::{Deps, Error, WORKFLOW_FILE};
use crate::template::GitRunner;
use crate::workspace::workflow_mark;
use std::path::Path;
pub(super) fn resolve_workflow(
workspace: &Path,
source: &ConfigSource<'_>,
governing: &str,
deps: &Deps<'_>,
) -> Result<Workflow, Error> {
let marked = match source {
ConfigSource::Fork(_) => None,
ConfigSource::Agent(agent_id) => nearest_mark(workspace, agent_id, deps.git),
};
match marked {
None => read_workflow(workspace, governing, deps),
Some(commit) => {
let version_raw = read_control(workspace, &commit, VERSION_FILE, deps)?;
Version::parse(&version_raw, &control_origin(&commit, VERSION_FILE))?;
read_workflow(workspace, &commit, deps)
}
}
}
fn read_workflow(workspace: &Path, commit: &str, deps: &Deps<'_>) -> Result<Workflow, Error> {
let raw = read_control(workspace, commit, WORKFLOW_FILE, deps)?;
Ok(Workflow::parse(
&raw,
&control_origin(commit, WORKFLOW_FILE),
)?)
}
pub(in crate::prompt) fn nearest_mark(
workspace: &Path,
agent_id: &str,
git: &dyn GitRunner,
) -> Option<String> {
let mut id = agent_id.to_string();
loop {
if let Some(commit) = workflow_mark::read(workspace, &id, git) {
return Some(commit);
}
id = crate::prompt::inbox::parent_of(&id)?;
}
}