mod control;
mod ensure;
mod exec;
mod goal;
mod identity;
mod lineage;
mod pins;
mod plan;
mod prompt;
mod prompt_ops;
mod run;
use crate::opslog::{self, OpEntry};
use crate::projects::join::JoinState;
use crate::start::{BallSpec, Payload, StartInputs};
use crate::test_support::authoring_new_arm;
use litany::mint::SplitMix64;
use std::path::{Path, PathBuf};
use tempfile::{TempDir, tempdir};
pub(super) fn write_exec(dir: &Path, name: &str, body: &str) -> PathBuf {
let path = dir.join(name);
crate::test_support::write_exec(&path, body);
path
}
pub(super) fn fake_bl(dir: &Path, id: &str, worktree: &Path) -> PathBuf {
let body = format!(
"#!/bin/sh\ncase \"$1\" in\ncreate) printf '%s\\n' '{id}';;\nclaim) printf '%s\\n' '{wt}';;\nesac\nexit 0\n",
wt = worktree.display(),
);
write_exec(dir, "bl", &body)
}
pub(super) fn fake_litany(dir: &Path) -> PathBuf {
write_exec(
dir,
"litany",
&format!(
"#!/bin/sh\ncase \"$1\" in\nprime) [ -n \"$LITANY_HOME\" ] && mkdir -p \"$LITANY_HOME\" \
&& : > \"$LITANY_HOME/models.yaml\";;\n{}esac\nexit 0\n",
authoring_new_arm()
),
)
}
pub(super) fn fake_fail(dir: &Path, name: &str, msg: &str) -> PathBuf {
write_exec(
dir,
name,
&format!("#!/bin/sh\nprintf '%s\\n' '{msg}' 1>&2\nexit 3\n"),
)
}
pub(super) struct World {
pub(super) bin: TempDir,
pub(super) state: TempDir,
pub(super) balls: TempDir,
pub(super) yog: TempDir,
pub(super) home: TempDir,
pub(super) project: TempDir,
}
impl World {
pub(super) fn new() -> Self {
Self {
bin: tempdir().unwrap(),
state: tempdir().unwrap(),
balls: tempdir().unwrap(),
yog: tempdir().unwrap(),
home: tempdir().unwrap(),
project: tempdir().unwrap(),
}
}
pub(super) fn ops(&self) -> Vec<OpEntry> {
opslog::tail(self.state.path(), 16)
}
pub(super) fn verbs(&self) -> Vec<String> {
self.ops()
.into_iter()
.filter_map(|e| e.argv.get(1).cloned())
.collect()
}
pub(super) fn litany(&self) -> crate::cli_outbound::Cli {
let home = crate::world::layout_under(self.yog.path()).litany;
crate::cli_outbound::Cli::new(fake_litany(self.bin.path())).with_env(vec![(
"LITANY_HOME".to_owned(),
home.to_string_lossy().into_owned(),
)])
}
pub(super) fn inputs(&self, name: &str, payload: Payload) -> StartInputs {
StartInputs {
workspace: crate::binding::workspace_path(self.yog.path(), name),
repo: payload.project().map(|_| self.project.path().to_path_buf()),
payload,
home: self.home.path().to_path_buf(),
yog_data_root: self.yog.path().to_path_buf(),
balls_state_root: self.balls.path().to_path_buf(),
conversation_names: Vec::new(),
}
}
}
pub(super) fn rng() -> SplitMix64 {
SplitMix64::from_seed(0x5eed)
}
pub(super) fn ball(project: &Path, id: &str, join: JoinState) -> Payload {
Payload::Ball {
project: crate::naming::leaf(project),
ball: BallSpec::Existing {
id: id.to_owned(),
title: "T".to_owned(),
body: "B".to_owned(),
join,
tags: Vec::new(),
},
}
}