1use std::path::PathBuf;
2use std::process::Command;
3
4use crate::bridge::{find_addon, find_node, write_temp_config};
5use crate::compile::{compile_config, load_config};
6use crate::error::DocusaurusError;
7
8pub struct RunnerOptions {
9 pub site_dir: PathBuf,
10 pub cli_options: serde_json::Value,
11}
12
13pub fn run_command(command: &str, opts: RunnerOptions) -> Result<(), DocusaurusError> {
18 let dylib = compile_config(&opts.site_dir)?;
19 let config = load_config(&dylib)?;
20 let config_json = serde_json::to_string(&config)?;
21
22 let (_temp_file, config_path) = write_temp_config(&config_json)?;
24
25 let node = find_node()?;
26 let addon = find_addon(&opts.site_dir)?;
27
28 let site_dir_str = opts.site_dir.display().to_string();
29 let config_path_str = config_path.display().to_string();
30 let addon_path_str = addon.display().to_string();
31 let cli_options_json = opts.cli_options.to_string();
34 let escaped_opts = cli_options_json
35 .replace('\\', r"\\")
36 .replace('\'', r"\'");
37
38 let script = format!(
41 "require('{addon_path_str}').{command}('{site_dir_str}', '{config_path_str}', '{escaped_opts}');"
42 );
43
44 let status = Command::new(node).args(["-e", &script]).status()?;
45
46 if !status.success() {
47 return Err(DocusaurusError::CommandFailed(status.code().unwrap_or(-1)));
48 }
49
50 Ok(())
51}