use std::path::PathBuf;
use argonauts_core::events::RunEventKind;
use argonauts_core::log::{Note, NoteLevel};
use argonauts_core::required::RequiredStep as KeptStep;
use argonauts_runner::{Library, Required, RequiredStep};
use crate::engine::host::Host;
pub fn for_run(host: &Host, request: &str) -> Required {
let (required, problems) = read(&super::library(host), &kept(host), request);
for problem in problems {
let note = Note {
level: NoteLevel::Warn,
text: problem,
};
let _ = host.record(None, None, RunEventKind::Note(note));
}
required
}
pub fn for_request(library: &Library, kept: &[KeptStep], request: &str) -> Required {
read(library, kept, request).0
}
pub fn names(host: &Host) -> Vec<String> {
let request = host
.read(crate::understand::round::request)
.unwrap_or_default();
read(&super::library(host), &kept(host), &request)
.0
.steps
.into_iter()
.map(|step| step.name)
.collect()
}
pub fn shared(required: &Required) -> argonauts_core::required::Required {
let steps = required
.steps
.iter()
.map(|step| KeptStep {
name: step.name.clone(),
role: step.role,
does: step.does.clone(),
when: step.when.clone(),
})
.collect();
argonauts_core::required::Required {
steps,
tasks: required.tasks.clone(),
}
}
fn kept(host: &Host) -> Vec<KeptStep> {
host.read(|state| {
state
.run
.started
.as_ref()
.map(|started| started.required_steps.clone())
.unwrap_or_default()
})
}
fn read(library: &Library, kept: &[KeptStep], request: &str) -> (Required, Vec<String>) {
let folders: Vec<&PathBuf> = [&library.yours, &library.project]
.into_iter()
.flatten()
.filter(|folder| {
!library
.waiting
.contains(&folder.join(argonauts_core::required::FILE))
})
.collect();
let folders: Vec<&std::path::Path> = folders.iter().map(|folder| folder.as_path()).collect();
let read = argonauts_core::required::read_with(&folders, kept, request);
let steps = read
.required
.steps
.into_iter()
.map(|step| RequiredStep {
name: step.name,
role: step.role,
does: step.does,
when: step.when,
})
.collect();
let required = Required {
steps,
tasks: read.required.tasks,
};
(required, read.problems)
}
#[cfg(test)]
mod tests {
use argonauts_core::settings::crew::CrewRole;
use super::*;
#[test]
fn always_toml_and_the_requests_words_are_what_a_run_must_contain() {
let dir = tempfile::tempdir().unwrap();
let yours = dir.path().join("yours");
let project = dir.path().join("project");
std::fs::create_dir_all(&yours).unwrap();
std::fs::create_dir_all(&project).unwrap();
std::fs::write(
project.join(argonauts_core::required::FILE),
"[[step]]\nname = \"benchmark\"\nrole = \"worker\"\ndoes = \"Run the benchmark.\"\n",
)
.unwrap();
let mut library = Library {
project: Some(project.clone()),
yours: Some(yours),
waiting: Vec::new(),
};
let required = for_request(&library, &[], "add due dates");
assert_eq!(required.steps.len(), 1, "{required:?}");
assert_eq!(required.steps[0].name, "benchmark");
assert_eq!(required.steps[0].role, CrewRole::Worker);
assert!(required.tasks.is_empty());
library.waiting = vec![project.join(argonauts_core::required::FILE)];
assert!(for_request(&library, &[], "add due dates").is_empty());
let none = Library::default();
assert!(for_request(&none, &[], "add due dates").is_empty());
}
#[test]
fn a_step_a_setup_kept_is_required_in_place_of_the_files_step_of_its_name() {
let dir = tempfile::tempdir().unwrap();
let project = dir.path().join("project");
std::fs::create_dir_all(&project).unwrap();
std::fs::write(
project.join(argonauts_core::required::FILE),
"[[step]]\nname = \"benchmark\"\nrole = \"worker\"\ndoes = \"Run the benchmark.\"\n",
)
.unwrap();
let library = Library {
project: Some(project),
yours: None,
waiting: Vec::new(),
};
let kept = [
KeptStep {
name: "Benchmark".into(),
role: CrewRole::Reviewer,
does: Some("Time the hot path.".into()),
when: Some("last".into()),
},
KeptStep {
name: "security review".into(),
role: CrewRole::Reviewer,
does: None,
when: None,
},
];
let (required, problems) = read(&library, &kept, "add due dates");
assert!(problems.is_empty(), "{problems:?}");
let names: Vec<&str> = required
.steps
.iter()
.map(|step| step.name.as_str())
.collect();
assert_eq!(names, ["Benchmark", "security review"]);
assert_eq!(required.steps[0].role, CrewRole::Reviewer);
assert_eq!(
required.steps[0].does.as_deref(),
Some("Time the hot path.")
);
assert_eq!(for_request(&library, &kept, "add due dates"), required);
}
}