microvms_edges/control/
project.rs1use std::path::Path;
8
9use microvms_app::control::artifact::ProjectFiles;
10use microvms_app::control::project::project_ecosystem;
11use microvms_app::error::{Error, ErrorKind};
12
13pub fn read_project_files(dir: impl AsRef<Path>) -> Result<ProjectFiles, Error> {
16 let dir = dir.as_ref();
17 let ecosystem = project_ecosystem(&dir.display().to_string(), |name| dir.join(name).is_file())?;
18 let read = |name: &str| {
19 let path = dir.join(name);
20 std::fs::read(&path).map_err(|error| {
21 Error::new(
22 ErrorKind::Precondition,
23 format!("could not read {}: {error}", path.display()),
24 )
25 .with_source(error)
26 })
27 };
28 Ok(ProjectFiles {
29 ecosystem,
30 manifest: read(ecosystem.manifest_name())?,
31 lockfile: read(ecosystem.lockfile_name())?,
32 })
33}
34
35#[cfg(test)]
36mod tests {
37 use microvms_app::control::artifact::Ecosystem;
38
39 use super::*;
40
41 #[test]
44 fn a_project_dir_with_one_pair_reads_both_files() {
45 let dir = tempfile::tempdir().expect("a temp dir");
46 std::fs::write(dir.path().join("pyproject.toml"), b"[project]").expect("writes");
47 std::fs::write(dir.path().join("uv.lock"), b"version = 1").expect("writes");
48 std::fs::write(dir.path().join(".env"), b"SECRET=1").expect("writes");
49
50 let files = read_project_files(dir.path()).expect("one pair, one ecosystem");
51 assert_eq!(files.ecosystem, Ecosystem::Uv);
52 assert_eq!(files.manifest, b"[project]");
53 assert_eq!(files.lockfile, b"version = 1");
54 }
55
56 #[test]
58 fn a_project_dir_without_a_pair_is_refused_naming_it() {
59 let dir = tempfile::tempdir().expect("a temp dir");
60 std::fs::write(dir.path().join("pyproject.toml"), b"[project]").expect("writes");
61 let error = read_project_files(dir.path()).expect_err("no lockfile to key on");
62 assert_eq!(error.kind(), ErrorKind::Precondition);
63 let message = error.to_string();
64 assert!(message.contains("uv lock"), "{message}");
65 assert!(
66 message.contains(&dir.path().display().to_string()),
67 "{message}"
68 );
69 }
70}