diff --git a/README.md b/README.md index 269d4aca5..a2fff828f 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ Experimental package manager for node.js written in rust. - [ ] `why` - [ ] `licenses` - [ ] `run` -- [ ] `test` +- [x] `test` - [ ] `exec` ## Debugging diff --git a/crates/cli/src/commands.rs b/crates/cli/src/commands.rs index efce23cf4..3bdffdf04 100644 --- a/crates/cli/src/commands.rs +++ b/crates/cli/src/commands.rs @@ -18,6 +18,8 @@ pub enum Subcommands { Init, /// Add a package Add(AddArgs), + /// Runs a package's "test" script, if one was provided. + Test, } #[derive(Parser, Debug)] diff --git a/crates/cli/src/lib.rs b/crates/cli/src/lib.rs index 752f5d627..f55c4da01 100644 --- a/crates/cli/src/lib.rs +++ b/crates/cli/src/lib.rs @@ -32,6 +32,9 @@ pub async fn run_commands() -> Result<()> { // the existing entry. registry_manager.add_dependency(&args.package, args.get_dependency_group()).await?; } + Subcommands::Test => { + PackageJson::from_path(&package_json_path)?.execute_command("test")?; + } } Ok(()) diff --git a/crates/package_json/src/error.rs b/crates/package_json/src/error.rs index 14518eec1..d107ae7f6 100644 --- a/crates/package_json/src/error.rs +++ b/crates/package_json/src/error.rs @@ -10,4 +10,8 @@ pub enum PackageJsonError { AlreadyExist, #[error("invalid attribute: {0}")] InvalidAttribute(String), + #[error("No package.json was found in {0}")] + NoImporterManifestFound(String), + #[error("Missing script: \"{0}\"")] + NoScript(String), } diff --git a/crates/package_json/src/lib.rs b/crates/package_json/src/lib.rs index 457670ca1..1803d0673 100644 --- a/crates/package_json/src/lib.rs +++ b/crates/package_json/src/lib.rs @@ -6,6 +6,7 @@ use std::{ fs, io::{Read, Write}, path::PathBuf, + process::{Command, Stdio}, }; use serde_json::{json, Map, Value}; @@ -77,6 +78,14 @@ impl PackageJson { Ok(()) } + pub fn from_path(path: &PathBuf) -> Result { + if !path.exists() { + return Err(PackageJsonError::NoImporterManifestFound(path.display().to_string())); + } + + Ok(PackageJson { path: path.to_path_buf(), value: PackageJson::read_from_file(path)? }) + } + pub fn create_if_needed(path: &PathBuf) -> Result { let value = if path.exists() { PackageJson::read_from_file(path)? @@ -116,4 +125,29 @@ impl PackageJson { } Ok(()) } + + pub fn execute_command(&self, command: &str) -> Result<(), PackageJsonError> { + match self + .value + .get("scripts") + .unwrap_or(&Value::default()) + .get(command) + .unwrap_or(&Value::default()) + .as_str() + { + Some(command) => { + let mut cmd = Command::new(command) + .stdout(Stdio::inherit()) + .stderr(Stdio::inherit()) + .stdin(Stdio::inherit()) + .spawn() + .unwrap(); + + cmd.wait().unwrap(); + + Ok(()) + } + None => Err(PackageJsonError::NoScript(command.to_string())), + } + } }