proto_node/depman/
execute.rs1use crate::depman::NodeDependencyManager;
2use clean_path::Clean;
3use proto_core::{async_trait, Describable, Executable, Installable, ProtoError};
4use starbase_utils::json::{self, JsonValue};
5use std::path::{Path, PathBuf};
6
7pub fn extract_bin_from_package_json(
8 package_path: PathBuf,
9 bin_name: &str,
10) -> Result<Option<String>, ProtoError> {
11 let mut bin_path = None;
12 let json: JsonValue = json::read_file(package_path)?;
13
14 if let Some(bin_field) = json.get("bin") {
15 match bin_field {
16 JsonValue::String(bin) => {
17 bin_path = Some(bin.to_owned());
18 }
19 JsonValue::Object(bins) => {
20 if let Some(bin) = bins.get(bin_name) {
21 bin_path = Some(bin.as_str().unwrap_or_default().to_string());
22 }
23 }
24 _ => {}
25 };
26 }
27
28 if bin_path.is_none() {
29 if let Some(main_field) = json.get("main") {
30 bin_path = Some(main_field.as_str().unwrap_or_default().to_string());
31 }
32 }
33
34 Ok(bin_path)
35}
36
37#[async_trait]
38impl Executable<'_> for NodeDependencyManager {
39 async fn find_bin_path(&mut self) -> Result<(), ProtoError> {
40 let install_dir = self.get_install_dir()?;
41 let bin_name = &self.package_name;
42 let package_json = install_dir.join("package.json");
43
44 if package_json.exists() {
45 if let Some(bin_path) = extract_bin_from_package_json(package_json, bin_name)? {
46 self.bin_path = Some(install_dir.join(bin_path).clean());
47
48 return Ok(());
49 }
50 }
51
52 return Err(ProtoError::ExecuteMissingBin(
53 self.get_name(),
54 install_dir.join(format!("bin/{bin_name}.js")),
55 ));
56 }
57
58 fn get_bin_path(&self) -> Result<&Path, ProtoError> {
59 match self.bin_path.as_ref() {
60 Some(bin) => Ok(bin),
61 None => Err(ProtoError::MissingTool(self.get_name())),
62 }
63 }
64
65 fn get_globals_bin_dir(&self) -> Result<Option<PathBuf>, ProtoError> {
66 Ok(Some(
67 self.base_dir
68 .parent()
69 .unwrap()
70 .join("node")
71 .join("globals")
72 .join("bin"),
73 ))
74 }
75}