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