1use std::fs::File;
2use std::io::{BufRead, BufReader};
3use std::path::Path;
4use std::process::Command;
5
6use crate::ci::CiEnv;
7
8#[macro_export]
12macro_rules! exit {
13 ($code:expr) => {
14 $crate::util::detail_exit($code, cfg!(test));
15 };
16}
17
18pub fn detail_exit(code: i32, is_test: bool) -> ! {
21 if is_test {
23 panic!("status code: {code}");
24 } else {
25 if CiEnv::is_ci() {
28 let bootstrap_args =
30 std::env::args().skip(1).map(|a| a.to_string()).collect::<Vec<_>>().join(" ");
31 eprintln!("Bootstrap failed while executing `{bootstrap_args}`");
32 }
33
34 std::process::exit(code);
36 }
37}
38
39pub fn fail(s: &str) -> ! {
40 eprintln!("\n\n{s}\n\n");
41 detail_exit(1, cfg!(test));
42}
43
44pub fn try_run(cmd: &mut Command, print_cmd_on_fail: bool) -> Result<(), ()> {
45 let status = match cmd.status() {
46 Ok(status) => status,
47 Err(e) => fail(&format!("failed to execute command: {cmd:?}\nerror: {e}")),
48 };
49 if !status.success() {
50 if print_cmd_on_fail {
51 println!(
52 "\n\ncommand did not execute successfully: {cmd:?}\n\
53 expected success, got: {status}\n\n"
54 );
55 }
56 Err(())
57 } else {
58 Ok(())
59 }
60}
61
62pub fn parse_gitmodules(target_dir: &Path) -> Vec<String> {
64 let gitmodules = target_dir.join(".gitmodules");
65 assert!(gitmodules.exists(), "'{}' file is missing.", gitmodules.display());
66
67 let file = File::open(gitmodules).unwrap();
68
69 let mut submodules_paths = vec![];
70 for line in BufReader::new(file).lines().map_while(Result::ok) {
71 let line = line.trim();
72 if line.starts_with("path") {
73 let actual_path = line.split(' ').next_back().expect("Couldn't get value of path");
74 submodules_paths.push(actual_path.to_owned());
75 }
76 }
77
78 submodules_paths
79}