mithril_build_script/
lib.rs

1use std::fs;
2use std::path::{Path, PathBuf};
3
4pub mod fake_aggregator;
5pub mod open_api;
6
7pub fn get_package_path(package_name: &str) -> PathBuf {
8    let cargo_pkgid_output = std::process::Command::new(env!("CARGO"))
9        .args(["pkgid", "--quiet", "-p", package_name])
10        .output()
11        .unwrap();
12
13    match cargo_pkgid_output.status.success() {
14        true => {
15            let output_string = std::str::from_utf8(&cargo_pkgid_output.stdout)
16                .unwrap()
17                .trim();
18            let package_path = extract_package_path(output_string);
19
20            PathBuf::from(package_path)
21        }
22        false => {
23            panic!(
24                "cargo pkgid failed: stderr: {}",
25                std::str::from_utf8(&cargo_pkgid_output.stderr)
26                    .unwrap()
27                    .trim()
28            )
29        }
30    }
31}
32
33const PKGID_OUTPUT_PREFIX: &str = "file://";
34
35fn extract_package_path<'a>(pkgid_output: &'a str) -> &'a str {
36    let output_without_prefix = pkgid_output
37        .split(PKGID_OUTPUT_PREFIX)
38        .collect::<Vec<&'a str>>();
39
40    output_without_prefix
41        .last()
42        .unwrap_or_else(|| {
43            panic!("Could not remove '{PKGID_OUTPUT_PREFIX}' prefix from `cargo pkgid` output: {pkgid_output}")
44        })
45        .split('#')
46        .collect::<Vec<_>>()
47        .first()
48        .unwrap_or_else(|| panic!("Could not remove '#x.y.z' suffix from `cargo pkgid` output: {pkgid_output}"))
49}
50
51pub(crate) fn list_files_in_folder(folder: &Path) -> impl Iterator<Item = fs::DirEntry> + '_ {
52    fs::read_dir(folder)
53        .unwrap_or_else(|_| panic!("Could not read `{}` dir", folder.display()))
54        .filter_map(move |e| {
55            let entry = e.unwrap_or_else(|_| {
56                panic!("Failed to read a file in the `{}` dir", folder.display())
57            });
58            match entry.file_type() {
59                Ok(file_type) if file_type.is_file() => Some(entry),
60                _ => None,
61            }
62        })
63}
64
65#[cfg(test)]
66// Note: adding `mithril-common` as a dev-dependency would lead to a circular dependency, so
67// we can't use its `TempDir` api.
68pub(crate) fn get_temp_dir(dir_name: &str) -> PathBuf {
69    let dir = std::env::temp_dir()
70        .join("mithril_test")
71        .join("build_script")
72        .join(dir_name);
73
74    if dir.exists() {
75        fs::remove_dir_all(&dir).unwrap();
76    }
77    fs::create_dir_all(&dir).unwrap();
78
79    dir
80}
81
82#[cfg(test)]
83mod tests {
84    use super::*;
85
86    #[test]
87    fn get_package_path_should_return_path_of_existing_package() {
88        let expected = PathBuf::from("./../../mithril-aggregator/")
89            .canonicalize()
90            .unwrap();
91
92        let package_path = get_package_path("mithril-aggregator");
93
94        assert_eq!(package_path, expected);
95    }
96
97    #[test]
98    #[should_panic]
99    fn get_package_path_panic_if_valid_name_of_not_existing_package() {
100        get_package_path("it-does-not-exist");
101    }
102
103    #[test]
104    #[should_panic]
105    fn get_package_path_panic_if_invalid_package_name() {
106        get_package_path("Invalid Package Name ~~~");
107    }
108
109    #[test]
110    fn extract_package_path_from_multiple_pkid_formats() {
111        let expected = "/dev/package_path/crate";
112
113        assert_eq!(
114            extract_package_path(&format!("{PKGID_OUTPUT_PREFIX}{expected}#version")),
115            expected
116        );
117        assert_eq!(
118            extract_package_path(&format!("path+{PKGID_OUTPUT_PREFIX}{expected}#version")),
119            expected
120        );
121    }
122}