1pub mod cargo_utils;
2pub mod prepost_utils;
3
4use cargo_metadata::MetadataCommand;
5use std::env;
6use std::path::{Path, PathBuf};
7
8pub fn get_target_dir(path: Option<PathBuf>) -> PathBuf {
9 let path = path.unwrap_or(env::current_dir().expect("Failed to get current dir"));
10 let cargo = search_original_cargo();
11 let target_dir = match MetadataCommand::new()
12 .current_dir(&path)
13 .cargo_path(&cargo)
14 .exec()
15 {
16 Ok(v) => v.target_directory.into_std_path_buf(),
17 Err(e) => {
18 log::warn!("Failed to get cargo metadata: {e}; use default values");
19 std::fs::canonicalize("./target").unwrap_or(PathBuf::from("./target"))
21 }
22 };
23 let target_dir = target_dir.join("prepost");
24 if let Err(e) = std::fs::create_dir_all(&target_dir) {
25 log::error!("Failed to create target directory: {e}");
26 std::process::exit(1);
27 }
28 target_dir
29}
30
31pub fn prepost_home_path() -> PathBuf {
32 match env::home_dir() {
33 Some(v) => v.join(".cargo-prepost"),
34 None => {
35 log::error!("Failed to get home directory");
36 std::process::exit(1);
37 }
38 }
39}
40
41pub fn create_alias(path: impl AsRef<Path>) {
42 let current_exe = match env::current_exe() {
43 Ok(v) => v,
44 Err(e) => {
45 log::error!("Failed to get current executable path: {e}");
46 std::process::exit(1);
47 }
48 };
49
50 let dir = path.as_ref().parent().unwrap();
51 if let Err(e) = std::fs::create_dir_all(dir) {
52 log::error!("Failed to create directory: {e}");
53 std::process::exit(1);
54 }
55 if let Err(e) = std::os::unix::fs::symlink(current_exe, &path) {
56 log::error!("Failed to create cargo symlink: {e}");
57 std::process::exit(1);
58 }
59}
60
61pub fn search_original_cargo() -> PathBuf {
62 let path = match env::var("PATH") {
63 Ok(v) => v,
64 _ => {
65 log::error!("Failed to get PATH");
66 std::process::exit(1);
67 }
68 };
69 let paths = env::split_paths(&path);
70 let mut cargo = None;
71 for path in paths {
72 let path = path.join("cargo");
73 if path.is_file()
74 && env::current_exe().expect("Failed to fetch current executable path") != path
75 {
76 log::info!("Find default cargo: {}", path.display());
77 cargo = Some(path);
78 break;
79 }
80 }
81 match cargo {
82 Some(v) => v,
83 None => {
84 log::error!("Failed to find default cargo");
85 std::process::exit(1);
86 }
87 }
88}
89
90#[cfg(test)]
91mod test {
92 use super::*;
93
94 #[test]
95 fn test_search_original_cargo() {
96 assert!(search_original_cargo().is_file());
97 }
98
99 #[test]
100 fn test_target_dir() {
101 let target = get_target_dir(None);
102 let current = env::current_dir().unwrap();
103 assert_eq!(target, current.join("target").join("prepost"));
104 }
105}