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    // Comparing absolute paths on Windows is tricky because it may add `\\?\` prefix:
87    //   left:  "/C:/a/mithril/mithril/mithril-aggregator"
88    //   right: "\\\\?\\C:\\a\\mithril\\mithril\\mithril-aggregator"
89    #[cfg(not(target_os = "windows"))]
90    #[test]
91    fn get_package_path_should_return_path_of_existing_package() {
92        let expected = PathBuf::from("./../../mithril-aggregator/")
93            .canonicalize()
94            .unwrap();
95
96        let package_path = get_package_path("mithril-aggregator");
97
98        assert_eq!(package_path, expected);
99    }
100
101    #[test]
102    #[should_panic]
103    fn get_package_path_panic_if_valid_name_of_not_existing_package() {
104        get_package_path("it-does-not-exist");
105    }
106
107    #[test]
108    #[should_panic]
109    fn get_package_path_panic_if_invalid_package_name() {
110        get_package_path("Invalid Package Name ~~~");
111    }
112
113    #[test]
114    fn extract_package_path_from_multiple_pkid_formats() {
115        let expected = "/dev/package_path/crate";
116
117        assert_eq!(
118            extract_package_path(&format!("{PKGID_OUTPUT_PREFIX}{expected}#version")),
119            expected
120        );
121        assert_eq!(
122            extract_package_path(&format!("path+{PKGID_OUTPUT_PREFIX}{expected}#version")),
123            expected
124        );
125    }
126}