use std::io;
use std::path::Path;
use super::{Space, config_file, lawful};
use crate::opslog::{self, OpEntry};
pub fn apply(space: &Space, state_root: &Path, ts: &str, branch: &str) -> io::Result<String> {
let path = config_file(&space.config);
let outcome = if lawful(branch) {
write_branch(&path, branch)
} else {
Err(io::Error::other(REFUSAL))
};
log_op(state_root, ts, &path, branch, &outcome)?;
outcome?;
Ok(space.branch())
}
pub const REFUSAL: &str =
"name a store branch: one word, no quotes, and not balls' own landing branch (balls/config)";
fn write_branch(path: &Path, branch: &str) -> io::Result<()> {
if let Some(parent) = path.parent() {
std::fs::create_dir_all(parent)?;
}
std::fs::write(path, body(branch))
}
pub fn body(branch: &str) -> String {
format!("tasks_branch = \"{branch}\"\n")
}
fn log_op(
state_root: &Path,
ts: &str,
path: &Path,
branch: &str,
outcome: &io::Result<()>,
) -> io::Result<()> {
let (exit, stderr) = match outcome {
Ok(()) => (0, String::new()),
Err(e) => (-3, e.to_string()),
};
opslog::append(
state_root,
&OpEntry {
ts: ts.to_owned(),
argv: vec!["yog-step".to_owned(), "marks".to_owned(), branch.to_owned()],
cwd: path.display().to_string(),
exit,
stdout: String::new(),
stderr,
origin: crate::opslog::Origin::World,
},
)
}