mod activity;
mod command_log;
mod effects;
mod recording;
use std::fmt::Display;
use std::path::{Path, PathBuf};
use std::sync::{LazyLock, Mutex, MutexGuard, PoisonError};
use crate::config::UserConfig;
use crate::harness::Choice;
use crate::issue::{IssueUrl, Repo};
use activity::Kind;
use effects::OnMachine;
use recording::Record;
pub enum Begin<'a> {
Run(&'a IssueUrl),
ChildRun(&'a str),
ArchitectRun,
PickupRun,
}
#[derive(Clone, Copy)]
pub enum Work<'a> {
Run(&'a IssueUrl),
SpecRun(&'a IssueUrl),
PickupRun(&'a IssueUrl),
ArchitectRun(&'a Repo),
}
#[derive(Clone, Copy)]
pub enum Pass {
ArchitectRun,
PickupRun,
}
static RECORD: LazyLock<Mutex<Record<OnMachine>>> =
LazyLock::new(|| Mutex::new(Record::new(OnMachine)));
pub fn begin(begin: Begin) {
record().begin(begin);
}
pub fn configured(config: &UserConfig) {
record().configured(config);
}
pub fn started(work: Work, harness: &Choice) {
record().started(work, harness);
}
pub fn skipped(pass: Pass, repo: &Repo, reason: impl Display) {
record().skipped(pass, repo, reason);
}
pub fn ended(outcome: impl Display) {
record().ended(outcome);
}
pub fn show_held() {
record().show_held();
}
pub fn root(repo: &Repo) -> PathBuf {
record().root(repo)
}
pub fn stamp() -> String {
record().stamp()
}
pub fn command_log_path() -> Option<PathBuf> {
record().command_log_path()
}
pub fn eprint(line: &str) {
record().eprint(line);
}
pub fn print(line: &str) {
record().print(line);
}
fn root_under(logs_dir: &Path, repo: &Repo) -> PathBuf {
logs_dir.join(&repo.owner).join(&repo.name)
}
impl Work<'_> {
fn repo(self) -> Repo {
match self {
Work::Run(issue) | Work::SpecRun(issue) | Work::PickupRun(issue) => issue.repo(),
Work::ArchitectRun(repo) => repo.clone(),
}
}
fn kind(self) -> Kind {
match self {
Work::Run(_) => Kind::Run,
Work::SpecRun(_) => Kind::SpecRun,
Work::PickupRun(_) => Kind::PickupRun,
Work::ArchitectRun(_) => Kind::ArchitectRun,
}
}
fn issue(self) -> Option<u64> {
match self {
Work::Run(issue) | Work::SpecRun(issue) | Work::PickupRun(issue) => Some(issue.number),
Work::ArchitectRun(_) => None,
}
}
fn command_log(self, root: &Path, stamp: &str) -> PathBuf {
let (folder, prefix) = match self {
Work::Run(issue) | Work::SpecRun(issue) => ("issue", format!("{}-", issue.number)),
Work::PickupRun(issue) => ("pickup", format!("{}-", issue.number)),
Work::ArchitectRun(_) => ("architect", String::new()),
};
root.join("commands")
.join(folder)
.join(format!("{prefix}{stamp}.log"))
}
}
fn record() -> MutexGuard<'static, Record<OnMachine>> {
RECORD.lock().unwrap_or_else(PoisonError::into_inner)
}