From efb6d60b1f45d34b5cac2d8b7728add4bcf05cd1 Mon Sep 17 00:00:00 2001 From: Miles Johnson Date: Wed, 16 Aug 2023 14:53:48 -0700 Subject: [PATCH 01/16] Update deps. --- CHANGELOG.md | 6 ++++++ Cargo.toml | 6 +++--- crates/node-depman/Cargo.toml | 2 +- crates/node/Cargo.toml | 2 +- 4 files changed, 11 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5e1a260..ad022b5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## 0.1.1 + +#### 🚀 Updates + +- Added support for `install_global` and `uninstall_global`. + ## 0.1.0 #### 💥 Breaking diff --git a/Cargo.toml b/Cargo.toml index 321c807..5cbb803 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,8 +6,8 @@ members = ["crates/*"] extism-pdk = "0.3.3" # proto_pdk = { version = "0.4.1", path = "../proto/crates/pdk" } # proto_pdk_test_utils = { version = "0.3.3", path = "../proto/crates/pdk-test-utils" } -proto_pdk = "0.4.2" -proto_pdk_test_utils = "0.3.4" +proto_pdk = "0.4.6" +proto_pdk_test_utils = "0.3.11" serde = "1.0.183" starbase_sandbox = "0.1.8" -tokio = "1.29.1" +tokio = "1.31.0" diff --git a/crates/node-depman/Cargo.toml b/crates/node-depman/Cargo.toml index 79cd772..daf4109 100644 --- a/crates/node-depman/Cargo.toml +++ b/crates/node-depman/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "node_depman_plugin" -version = "0.1.0" +version = "0.1.1" edition = "2021" license = "MIT" publish = false diff --git a/crates/node/Cargo.toml b/crates/node/Cargo.toml index 288a69f..fc4a691 100644 --- a/crates/node/Cargo.toml +++ b/crates/node/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "node_plugin" -version = "0.1.0" +version = "0.1.1" edition = "2021" license = "MIT" publish = false From 56c05ddbc767eecea14d93800e3cc10e00571b74 Mon Sep 17 00:00:00 2001 From: Miles Johnson Date: Wed, 16 Aug 2023 15:00:45 -0700 Subject: [PATCH 02/16] Add versions. --- crates/node-depman/src/proto.rs | 5 +++++ crates/node-depman/tests/metadata_test.rs | 3 +++ crates/node/src/proto.rs | 1 + crates/node/tests/metadata_test.rs | 1 + 4 files changed, 10 insertions(+) diff --git a/crates/node-depman/src/proto.rs b/crates/node-depman/src/proto.rs index 9f40401..1e31ea5 100644 --- a/crates/node-depman/src/proto.rs +++ b/crates/node-depman/src/proto.rs @@ -73,6 +73,7 @@ pub fn register_tool(Json(input): Json) -> FnResult) -> FnResult) -> FnResult Date: Wed, 16 Aug 2023 15:18:35 -0700 Subject: [PATCH 03/16] Add globals. --- CHANGELOG.md | 5 +++ crates/common/Cargo.toml | 1 + crates/common/src/commands.rs | 40 +++++++++++++++++ crates/common/src/lib.rs | 1 + crates/node-depman/src/proto.rs | 76 +++++++++++++++++++++------------ crates/node/src/proto.rs | 31 +++++++++++++- 6 files changed, 126 insertions(+), 28 deletions(-) create mode 100644 crates/common/src/commands.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index ad022b5..f70f785 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,11 @@ - Added support for `install_global` and `uninstall_global`. +#### 🐞 Fixes + +- **npm** + - Will no longer crash when parsing an invalid `package.json`. + ## 0.1.0 #### 💥 Breaking diff --git a/crates/common/Cargo.toml b/crates/common/Cargo.toml index 18edb16..35ea4cd 100644 --- a/crates/common/Cargo.toml +++ b/crates/common/Cargo.toml @@ -6,4 +6,5 @@ license = "MIT" publish = false [dependencies] +proto_pdk = { workspace = true } serde = { workspace = true } diff --git a/crates/common/src/commands.rs b/crates/common/src/commands.rs new file mode 100644 index 0000000..aadaad0 --- /dev/null +++ b/crates/common/src/commands.rs @@ -0,0 +1,40 @@ +use proto_pdk::ExecCommandInput; +use std::path::Path; + +pub fn install_global(dependency: &str, globals_dir: &Path) -> ExecCommandInput { + let mut cmd = ExecCommandInput::pipe( + "npm", + [ + "install", + "--global", + "--loglevel", + "warn", + "--no-audit", + "--no-update-notifier", + dependency, + ], + ); + + // Remove the /bin component + cmd.env_vars.insert( + "PREFIX".into(), + globals_dir.parent().unwrap().to_string_lossy().to_string(), + ); + + cmd +} + +pub fn uninstall_global(dependency: &str, globals_dir: &Path) -> ExecCommandInput { + let mut cmd = ExecCommandInput::pipe( + "npm", + ["uninstall", "--global", "--loglevel", "warn", dependency], + ); + + // Remove the /bin component + cmd.env_vars.insert( + "PREFIX".into(), + globals_dir.parent().unwrap().to_string_lossy().to_string(), + ); + + cmd +} diff --git a/crates/common/src/lib.rs b/crates/common/src/lib.rs index b77eb75..2391104 100644 --- a/crates/common/src/lib.rs +++ b/crates/common/src/lib.rs @@ -1,3 +1,4 @@ +pub mod commands; mod node_dist; mod package_json; diff --git a/crates/node-depman/src/proto.rs b/crates/node-depman/src/proto.rs index 1e31ea5..9a93091 100644 --- a/crates/node-depman/src/proto.rs +++ b/crates/node-depman/src/proto.rs @@ -1,5 +1,5 @@ use extism_pdk::*; -use node_common::{BinField, NodeDistVersion, PackageJson}; +use node_common::{commands, BinField, NodeDistVersion, PackageJson}; use proto_pdk::*; use serde::Deserialize; use std::collections::HashMap; @@ -9,8 +9,8 @@ use std::path::PathBuf; #[host_fn] extern "ExtismHost" { - fn host_log(input: Json); fn exec_command(input: Json) -> Json; + fn host_log(input: Json); } #[derive(PartialEq)] @@ -117,24 +117,24 @@ pub fn locate_bins(Json(input): Json) -> FnResult { - bin_path = Some(bin); - } - BinField::Object(map) => { - if let Some(bin) = map.get(&manager_name) { - bin_path = Some(bin.to_owned()); + if let Ok(package_json) = json::from_slice::(&fs::read(package_path)?) { + if let Some(bin_field) = package_json.bin { + match bin_field { + BinField::String(bin) => { + bin_path = Some(bin); } - } - }; - } + BinField::Object(map) => { + if let Some(bin) = map.get(&manager_name) { + bin_path = Some(bin.to_owned()); + } + } + }; + } - if bin_path.is_none() { - if let Some(main_field) = package_json.main { - bin_path = Some(main_field); + if bin_path.is_none() { + if let Some(main_field) = package_json.main { + bin_path = Some(main_field); + } } } } @@ -350,21 +350,43 @@ pub fn parse_version_file( Json(input): Json, ) -> FnResult> { let mut version = None; - let manager = PackageManager::from(&input.env); if input.file == "package.json" { - let package_json: PackageJson = json::from_str(&input.content)?; - let manager_name = manager.to_string(); - - if let Some(manager) = package_json.package_manager { - let mut parts = manager.split('@'); - let name = parts.next().unwrap_or_default(); + if let Ok(package_json) = json::from_str::(&input.content) { + if let Some(pm) = package_json.package_manager { + let mut parts = pm.split('@'); + let name = parts.next().unwrap_or_default(); - if name == manager_name { - version = Some(parts.next().unwrap_or("latest").to_owned()); + if name == PackageManager::from(&input.env).to_string() { + version = Some(parts.next().unwrap_or("latest").to_owned()); + } } } } Ok(Json(ParseVersionFileOutput { version })) } + +#[plugin_fn] +pub fn install_global( + Json(input): Json, +) -> FnResult> { + let result = exec_command!(commands::install_global( + &input.dependency, + &input.globals_dir + )); + + Ok(Json(InstallGlobalOutput::from_exec_command(result))) +} + +#[plugin_fn] +pub fn uninstall_global( + Json(input): Json, +) -> FnResult> { + let result = exec_command!(commands::uninstall_global( + &input.dependency, + &input.globals_dir + )); + + Ok(Json(UninstallGlobalOutput::from_exec_command(result))) +} diff --git a/crates/node/src/proto.rs b/crates/node/src/proto.rs index a5093b3..8e5e382 100644 --- a/crates/node/src/proto.rs +++ b/crates/node/src/proto.rs @@ -1,8 +1,13 @@ use extism_pdk::*; -use node_common::{NodeDistLTS, NodeDistVersion}; +use node_common::{commands, NodeDistLTS, NodeDistVersion}; use proto_pdk::*; use std::collections::HashMap; +#[host_fn] +extern "ExtismHost" { + fn exec_command(input: Json) -> Json; +} + static NAME: &str = "Node.js"; static BIN: &str = "node"; @@ -184,3 +189,27 @@ pub fn detect_version_files(_: ()) -> FnResult> { files: vec![".nvmrc".into(), ".node-version".into()], })) } + +#[plugin_fn] +pub fn install_global( + Json(input): Json, +) -> FnResult> { + let result = exec_command!(commands::install_global( + &input.dependency, + &input.globals_dir + )); + + Ok(Json(InstallGlobalOutput::from_exec_command(result))) +} + +#[plugin_fn] +pub fn uninstall_global( + Json(input): Json, +) -> FnResult> { + let result = exec_command!(commands::uninstall_global( + &input.dependency, + &input.globals_dir + )); + + Ok(Json(UninstallGlobalOutput::from_exec_command(result))) +} From cf44ffd7e0a8871b0d6b107727d9c74244be3a31 Mon Sep 17 00:00:00 2001 From: Miles Johnson Date: Thu, 17 Aug 2023 12:20:58 -0700 Subject: [PATCH 04/16] Use new APIs. --- Cargo.toml | 9 +- crates/common/Cargo.toml | 2 +- crates/common/src/commands.rs | 2 +- crates/node-depman/src/proto.rs | 39 +++++---- crates/node-depman/tests/hooks_test.rs | 110 +++++++++++++++++++++++++ crates/node/src/proto.rs | 29 ++++--- crates/node/tests/hooks_test.rs | 50 +++++++++++ 7 files changed, 206 insertions(+), 35 deletions(-) create mode 100644 crates/node-depman/tests/hooks_test.rs create mode 100644 crates/node/tests/hooks_test.rs diff --git a/Cargo.toml b/Cargo.toml index 5cbb803..c891719 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,10 +4,11 @@ members = ["crates/*"] [workspace.dependencies] extism-pdk = "0.3.3" -# proto_pdk = { version = "0.4.1", path = "../proto/crates/pdk" } -# proto_pdk_test_utils = { version = "0.3.3", path = "../proto/crates/pdk-test-utils" } -proto_pdk = "0.4.6" -proto_pdk_test_utils = "0.3.11" +proto_pdk = { version = "0.4.6", path = "../../proto/crates/pdk" } +proto_pdk_api = { version = "0.4.8", path = "../../proto/crates/pdk-api" } +proto_pdk_test_utils = { version = "0.3.11", path = "../../proto/crates/pdk-test-utils" } +# proto_pdk = "0.4.6" +# proto_pdk_test_utils = "0.3.11" serde = "1.0.183" starbase_sandbox = "0.1.8" tokio = "1.31.0" diff --git a/crates/common/Cargo.toml b/crates/common/Cargo.toml index 35ea4cd..b2e6e7d 100644 --- a/crates/common/Cargo.toml +++ b/crates/common/Cargo.toml @@ -6,5 +6,5 @@ license = "MIT" publish = false [dependencies] -proto_pdk = { workspace = true } +proto_pdk_api = { workspace = true } serde = { workspace = true } diff --git a/crates/common/src/commands.rs b/crates/common/src/commands.rs index aadaad0..c49cbf2 100644 --- a/crates/common/src/commands.rs +++ b/crates/common/src/commands.rs @@ -1,4 +1,4 @@ -use proto_pdk::ExecCommandInput; +use proto_pdk_api::ExecCommandInput; use std::path::Path; pub fn install_global(dependency: &str, globals_dir: &Path) -> ExecCommandInput { diff --git a/crates/node-depman/src/proto.rs b/crates/node-depman/src/proto.rs index 9a93091..ee97916 100644 --- a/crates/node-depman/src/proto.rs +++ b/crates/node-depman/src/proto.rs @@ -21,10 +21,12 @@ enum PackageManager { } impl PackageManager { - pub fn from(env: &Environment) -> PackageManager { - if env.id.to_lowercase().contains("yarn") { + pub fn detect() -> PackageManager { + let id = get_tool_id(); + + if id.to_lowercase().contains("yarn") { PackageManager::Yarn - } else if env.id.to_lowercase().contains("pnpm") { + } else if id.to_lowercase().contains("pnpm") { PackageManager::Pnpm } else { PackageManager::Npm @@ -62,7 +64,9 @@ impl fmt::Display for PackageManager { #[plugin_fn] pub fn register_tool(Json(input): Json) -> FnResult> { - let manager = PackageManager::from(&input.env); + set_tool_id(input.id)?; + + let manager = PackageManager::detect(); Ok(Json(ToolMetadataOutput { name: manager.to_string(), @@ -82,8 +86,8 @@ pub fn register_tool(Json(input): Json) -> FnResult, ) -> FnResult> { - let version = &input.env.version; - let manager = PackageManager::from(&input.env); + let version = &input.state.version; + let manager = PackageManager::detect(); let package_name = manager.get_package_name(version); // Derive values based on package manager @@ -111,8 +115,8 @@ pub fn download_prebuilt( #[plugin_fn] pub fn locate_bins(Json(input): Json) -> FnResult> { let mut bin_path = None; - let package_path = input.tool_dir.join("package.json"); - let manager = PackageManager::from(&input.env); + let package_path = input.state.tool_dir.join("package.json"); + let manager = PackageManager::detect(); let manager_name = manager.to_string(); // Extract the binary from the `package.json` @@ -173,7 +177,7 @@ struct RegistryResponse { #[plugin_fn] pub fn load_versions(Json(input): Json) -> FnResult> { let mut output = LoadVersionsOutput::default(); - let manager = PackageManager::from(&input.env); + let manager = PackageManager::detect(); let package_name = manager.get_package_name(&input.initial); let mut map_output = |res: RegistryResponse| -> Result<(), Error> { @@ -220,7 +224,7 @@ pub fn load_versions(Json(input): Json) -> FnResult, ) -> FnResult> { - let manager = PackageManager::from(&input.env); + let manager = PackageManager::detect(); let mut output = ResolveVersionOutput::default(); match manager { @@ -233,7 +237,7 @@ pub fn resolve_version( let mut found_version = false; // Infer from proto's environment variable - if let Some(node_version) = input.env.vars.get("PROTO_NODE_VERSION") { + if let Some(node_version) = input.state.env_vars.get("PROTO_NODE_VERSION") { for node_release in &response { // Theirs starts with v, ours does not if &node_release.version[1..] == node_version { @@ -285,8 +289,9 @@ pub fn resolve_version( } #[plugin_fn] -pub fn create_shims(Json(input): Json) -> FnResult> { - let manager = PackageManager::from(&input.env); +pub fn create_shims(Json(_): Json) -> FnResult> { + let env = get_proto_environment()?; + let manager = PackageManager::detect(); let mut global_shims = HashMap::::new(); let mut local_shims = HashMap::::new(); @@ -300,7 +305,7 @@ pub fn create_shims(Json(input): Json) -> FnResult FnResult> { let result = exec_command!(commands::install_global( &input.dependency, - &input.globals_dir + &input.globals_dir.real_path(), )); Ok(Json(InstallGlobalOutput::from_exec_command(result))) @@ -385,7 +390,7 @@ pub fn uninstall_global( ) -> FnResult> { let result = exec_command!(commands::uninstall_global( &input.dependency, - &input.globals_dir + &input.globals_dir.real_path(), )); Ok(Json(UninstallGlobalOutput::from_exec_command(result))) diff --git a/crates/node-depman/tests/hooks_test.rs b/crates/node-depman/tests/hooks_test.rs new file mode 100644 index 0000000..49ed650 --- /dev/null +++ b/crates/node-depman/tests/hooks_test.rs @@ -0,0 +1,110 @@ +// mod utils; + +// use starbase_sandbox::predicates::prelude::*; +// use std::env; +// use utils::*; + +mod npm { + use super::*; + + // #[test] + // fn errors_if_installing_global() { + // let temp = create_empty_sandbox(); + + // let mut cmd = create_proto_command(temp.path()); + // cmd.arg("install") + // .arg("npm") + // .arg("latest") + // .assert() + // .success(); + + // let mut cmd = create_proto_command(temp.path()); + // let assert = cmd + // .arg("run") + // .arg("npm") + // .arg("latest") + // .args(["--", "install", "-g", "typescript"]) + // .assert(); + + // assert.stderr(predicate::str::contains( + // "Global binaries must be installed with proto install-global npm", + // )); + // } + + // #[test] + // fn can_bypass_global_check() { + // let temp = create_empty_sandbox(); + + // let mut cmd = create_proto_command(temp.path()); + // cmd.arg("install") + // .arg("npm") + // .arg("latest") + // .assert() + // .success(); + + // env::set_var("PROTO_NODE_INTERCEPT_GLOBALS", "0"); + + // let mut cmd = create_proto_command(temp.path()); + // let assert = cmd + // .arg("run") + // .arg("npm") + // .arg("latest") + // .args(["--", "install", "-g", "typescript"]) + // .assert(); + + // env::remove_var("PROTO_NODE_INTERCEPT_GLOBALS"); + + // assert.stderr( + // predicate::str::contains( + // "Global binaries must be installed with proto install-global npm", + // ) + // .not(), + // ); + // } +} + +mod pnpm { + // use super::*; + + // #[test] + // fn errors_if_installing_global() { + // let temp = create_empty_sandbox(); + + // let mut cmd = create_proto_command(temp.path()); + // cmd.arg("install").arg("pnpm").assert().success(); + + // let mut cmd = create_proto_command(temp.path()); + // let assert = cmd + // .arg("run") + // .arg("pnpm") + // .args(["--", "add", "-g", "typescript"]) + // .assert(); + + // assert.stderr(predicate::str::contains( + // "Global binaries must be installed with proto install-global pnpm", + // )); + // } +} + +mod yarn { + // use super::*; + + // #[test] + // fn errors_if_installing_global() { + // let temp = create_empty_sandbox(); + + // let mut cmd = create_proto_command(temp.path()); + // cmd.arg("install").arg("yarn").assert().success(); + + // let mut cmd = create_proto_command(temp.path()); + // let assert = cmd + // .arg("run") + // .arg("yarn") + // .args(["--", "global", "add", "typescript"]) + // .assert(); + + // assert.stderr(predicate::str::contains( + // "Global binaries must be installed with proto install-global yarn", + // )); + // } +} diff --git a/crates/node/src/proto.rs b/crates/node/src/proto.rs index 8e5e382..2746ce4 100644 --- a/crates/node/src/proto.rs +++ b/crates/node/src/proto.rs @@ -46,9 +46,11 @@ fn map_arch(os: HostOS, arch: HostArch) -> Result { pub fn download_prebuilt( Json(input): Json, ) -> FnResult> { + let env = get_proto_environment()?; + check_supported_os_and_arch( NAME, - &input.env, + &env, permutations! [ HostOS::Linux => [HostArch::X64, HostArch::Arm64, HostArch::Arm, HostArch::Powerpc64, HostArch::S390x], HostOS::MacOS => [HostArch::X64, HostArch::Arm64], @@ -56,10 +58,10 @@ pub fn download_prebuilt( ], )?; - let version = input.env.version; - let arch = map_arch(input.env.os, input.env.arch)?; + let version = input.state.version; + let arch = map_arch(env.os, env.arch)?; - let prefix = match input.env.os { + let prefix = match env.os { HostOS::Linux => format!("node-v{version}-linux-{arch}"), HostOS::MacOS => { let parsed_version = if version == "latest" { @@ -70,7 +72,7 @@ pub fn download_prebuilt( // Arm64 support was added after v16, but M1/M2 machines can // run x64 binaries via Rosetta. This is a compat hack! - if input.env.arch == HostArch::Arm64 && parsed_version.major < 16 { + if env.arch == HostArch::Arm64 && parsed_version.major < 16 { format!("node-v{version}-darwin-x64") } else { format!("node-v{version}-darwin-{arch}") @@ -80,7 +82,7 @@ pub fn download_prebuilt( _ => unreachable!(), }; - let filename = if input.env.os == HostOS::Windows { + let filename = if env.os == HostOS::Windows { format!("{prefix}.zip") } else { format!("{prefix}.tar.xz") @@ -96,9 +98,11 @@ pub fn download_prebuilt( } #[plugin_fn] -pub fn locate_bins(Json(input): Json) -> FnResult> { +pub fn locate_bins(Json(_): Json) -> FnResult> { + let env = get_proto_environment()?; + Ok(Json(LocateBinsOutput { - bin_path: Some(if input.env.os == HostOS::Windows { + bin_path: Some(if env.os == HostOS::Windows { format!("{}.exe", BIN).into() } else { format!("bin/{}", BIN).into() @@ -165,12 +169,13 @@ pub fn resolve_version( } #[plugin_fn] -pub fn create_shims(Json(input): Json) -> FnResult> { +pub fn create_shims(Json(_): Json) -> FnResult> { + let env = get_proto_environment()?; let mut global_shims = HashMap::new(); global_shims.insert( "npx".into(), - ShimConfig::global_with_alt_bin(if input.env.os == HostOS::Windows { + ShimConfig::global_with_alt_bin(if env.os == HostOS::Windows { "npx.cmd" } else { "bin/npx" @@ -196,7 +201,7 @@ pub fn install_global( ) -> FnResult> { let result = exec_command!(commands::install_global( &input.dependency, - &input.globals_dir + &input.globals_dir.real_path(), )); Ok(Json(InstallGlobalOutput::from_exec_command(result))) @@ -208,7 +213,7 @@ pub fn uninstall_global( ) -> FnResult> { let result = exec_command!(commands::uninstall_global( &input.dependency, - &input.globals_dir + &input.globals_dir.real_path(), )); Ok(Json(UninstallGlobalOutput::from_exec_command(result))) diff --git a/crates/node/tests/hooks_test.rs b/crates/node/tests/hooks_test.rs new file mode 100644 index 0000000..698703d --- /dev/null +++ b/crates/node/tests/hooks_test.rs @@ -0,0 +1,50 @@ +// TODO: Enable once 0.15 lands + +// #[test] +// fn installs_bundled_npm() { +// let temp = create_empty_sandbox(); + +// let mut cmd = create_proto_command(temp.path()); +// let assert = cmd.arg("install").arg("node").arg("19.0.0").assert(); + +// let output = output_to_string(&assert.get_output().stderr.to_vec()); + +// assert!(predicate::str::contains("Node.js has been installed").eval(&output)); +// assert!(predicate::str::contains("npm has been installed").eval(&output)); + +// assert!(temp.path().join("tools/node/19.0.0").exists()); +// assert!(temp.path().join("tools/npm/8.19.2").exists()); + +// let manifest = ToolManifest::load(temp.path().join("tools/npm/manifest.json")).unwrap(); + +// assert_eq!( +// manifest.default_version, +// Some(AliasOrVersion::parse("bundled").unwrap()) +// ); +// assert_eq!( +// manifest.installed_versions, +// HashSet::from_iter([Version::parse("8.19.2").unwrap()]) +// ); +// } + +// #[test] +// fn skips_bundled_npm() { +// let temp = create_empty_sandbox(); + +// let mut cmd = create_proto_command(temp.path()); +// let assert = cmd +// .arg("install") +// .arg("node") +// .arg("19.0.0") +// .arg("--") +// .arg("--no-bundled-npm") +// .assert(); + +// let output = output_to_string(&assert.get_output().stderr.to_vec()); + +// assert!(predicate::str::contains("Node.js has been installed").eval(&output)); +// assert!(!predicate::str::contains("npm has been installed").eval(&output)); + +// assert!(temp.path().join("tools/node/19.0.0").exists()); +// assert!(!temp.path().join("tools/npm/8.19.2").exists()); +// } From b98fdb664affd3e5e92b0b680abd5f7e2ef93fb9 Mon Sep 17 00:00:00 2001 From: Miles Johnson Date: Mon, 21 Aug 2023 11:08:33 -0700 Subject: [PATCH 05/16] Fix tests. --- CHANGELOG.md | 5 +- crates/node-depman/src/proto.rs | 10 +- crates/node-depman/tests/download_test.rs | 156 ++++++++++++---------- crates/node-depman/tests/hooks_test.rs | 2 +- crates/node-depman/tests/metadata_test.rs | 10 +- crates/node-depman/tests/versions_test.rs | 40 +----- crates/node/src/proto.rs | 2 +- crates/node/tests/download_test.rs | 149 +++++++++++++-------- 8 files changed, 195 insertions(+), 179 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f70f785..ac9569f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,10 +1,11 @@ # Changelog -## 0.1.1 +## 0.2.0 #### 🚀 Updates - Added support for `install_global` and `uninstall_global`. +- Updated to support proto v0.15 release. #### 🐞 Fixes @@ -15,7 +16,7 @@ #### 💥 Breaking -- Will now longer check `engines` in `package.json` when detecting a version. +- Will no longer check `engines` in `package.json` when detecting a version. #### 🚀 Updates diff --git a/crates/node-depman/src/proto.rs b/crates/node-depman/src/proto.rs index ee97916..e74911d 100644 --- a/crates/node-depman/src/proto.rs +++ b/crates/node-depman/src/proto.rs @@ -63,9 +63,7 @@ impl fmt::Display for PackageManager { } #[plugin_fn] -pub fn register_tool(Json(input): Json) -> FnResult> { - set_tool_id(input.id)?; - +pub fn register_tool(Json(_): Json) -> FnResult> { let manager = PackageManager::detect(); Ok(Json(ToolMetadataOutput { @@ -86,7 +84,7 @@ pub fn register_tool(Json(input): Json) -> FnResult, ) -> FnResult> { - let version = &input.state.version; + let version = &input.context.version; let manager = PackageManager::detect(); let package_name = manager.get_package_name(version); @@ -115,7 +113,7 @@ pub fn download_prebuilt( #[plugin_fn] pub fn locate_bins(Json(input): Json) -> FnResult> { let mut bin_path = None; - let package_path = input.state.tool_dir.join("package.json"); + let package_path = input.context.tool_dir.join("package.json"); let manager = PackageManager::detect(); let manager_name = manager.to_string(); @@ -237,7 +235,7 @@ pub fn resolve_version( let mut found_version = false; // Infer from proto's environment variable - if let Some(node_version) = input.state.env_vars.get("PROTO_NODE_VERSION") { + if let Some(node_version) = input.context.env_vars.get("PROTO_NODE_VERSION") { for node_release in &response { // Theirs starts with v, ours does not if &node_release.version[1..] == node_version { diff --git a/crates/node-depman/tests/download_test.rs b/crates/node-depman/tests/download_test.rs index 31fc080..9f11a55 100644 --- a/crates/node-depman/tests/download_test.rs +++ b/crates/node-depman/tests/download_test.rs @@ -1,6 +1,5 @@ use proto_pdk_test_utils::*; use starbase_sandbox::create_empty_sandbox; -use std::path::PathBuf; mod npm { use super::*; @@ -10,14 +9,17 @@ mod npm { #[test] fn supports_prebuilt() { let sandbox = create_empty_sandbox(); - let plugin = create_plugin("npm-test", sandbox.path()); + let mut plugin = create_plugin("npm-test", sandbox.path()); + + plugin.set_environment(HostEnvironment { + arch: HostArch::Arm64, + os: HostOS::Linux, + ..Default::default() + }); assert_eq!( plugin.download_prebuilt(DownloadPrebuiltInput { - env: Environment { - arch: HostArch::Arm64, - id: "npm".into(), - os: HostOS::Linux, + context: ToolContext { version: "9.0.0".into(), ..Default::default() } @@ -35,20 +37,21 @@ mod npm { #[test] fn locates_default_bin() { let sandbox = create_empty_sandbox(); - let plugin = create_plugin("npm-test", sandbox.path()); + let mut plugin = create_plugin("npm-test", sandbox.path()); + + plugin.set_environment(HostEnvironment { + arch: HostArch::Arm64, + os: HostOS::Linux, + ..Default::default() + }); assert_eq!( plugin .locate_bins(LocateBinsInput { - env: Environment { - arch: HostArch::Arm64, - id: "npm".into(), - os: HostOS::Linux, + context: ToolContext { version: "9.0.0".into(), ..Default::default() }, - home_dir: PathBuf::new(), - tool_dir: PathBuf::new(), }) .bin_path, Some("bin/npm".into()) @@ -64,14 +67,17 @@ mod pnpm { #[test] fn supports_prebuilt() { let sandbox = create_empty_sandbox(); - let plugin = create_plugin("pnpm-test", sandbox.path()); + let mut plugin = create_plugin("pnpm-test", sandbox.path()); + + plugin.set_environment(HostEnvironment { + arch: HostArch::X64, + os: HostOS::Windows, + ..Default::default() + }); assert_eq!( plugin.download_prebuilt(DownloadPrebuiltInput { - env: Environment { - arch: HostArch::X64, - id: "pnpm".into(), - os: HostOS::Windows, + context: ToolContext { version: "8.0.0".into(), ..Default::default() } @@ -89,20 +95,21 @@ mod pnpm { #[test] fn locates_default_bin() { let sandbox = create_empty_sandbox(); - let plugin = create_plugin("pnpm-test", sandbox.path()); + let mut plugin = create_plugin("pnpm-test", sandbox.path()); + + plugin.set_environment(HostEnvironment { + arch: HostArch::X64, + os: HostOS::Windows, + ..Default::default() + }); assert_eq!( plugin .locate_bins(LocateBinsInput { - env: Environment { - arch: HostArch::X64, - id: "pnpm".into(), - os: HostOS::Windows, + context: ToolContext { version: "8.0.0".into(), ..Default::default() }, - home_dir: PathBuf::new(), - tool_dir: PathBuf::new(), }) .bin_path, Some("bin/pnpm.cjs".into()) @@ -118,14 +125,17 @@ mod yarn { #[test] fn supports_prebuilt() { let sandbox = create_empty_sandbox(); - let plugin = create_plugin("yarn-test", sandbox.path()); + let mut plugin = create_plugin("yarn-test", sandbox.path()); + + plugin.set_environment(HostEnvironment { + arch: HostArch::X64, + os: HostOS::MacOS, + ..Default::default() + }); assert_eq!( plugin.download_prebuilt(DownloadPrebuiltInput { - env: Environment { - arch: HostArch::X64, - id: "yarn".into(), - os: HostOS::MacOS, + context: ToolContext { version: "1.22.0".into(), ..Default::default() } @@ -143,20 +153,21 @@ mod yarn { #[test] fn locates_default_bin() { let sandbox = create_empty_sandbox(); - let plugin = create_plugin("yarn-test", sandbox.path()); + let mut plugin = create_plugin("yarn-test", sandbox.path()); + + plugin.set_environment(HostEnvironment { + arch: HostArch::X64, + os: HostOS::MacOS, + ..Default::default() + }); assert_eq!( plugin .locate_bins(LocateBinsInput { - env: Environment { - arch: HostArch::X64, - id: "yarn".into(), - os: HostOS::MacOS, + context: ToolContext { version: "1.22.0".into(), ..Default::default() }, - home_dir: PathBuf::new(), - tool_dir: PathBuf::new(), }) .bin_path, Some("bin/yarn".into()) @@ -172,14 +183,17 @@ mod yarn_berry { #[test] fn supports_prebuilt() { let sandbox = create_empty_sandbox(); - let plugin = create_plugin("yarn-test", sandbox.path()); + let mut plugin = create_plugin("yarn-test", sandbox.path()); + + plugin.set_environment(HostEnvironment { + arch: HostArch::X64, + os: HostOS::MacOS, + ..Default::default() + }); assert_eq!( plugin.download_prebuilt(DownloadPrebuiltInput { - env: Environment { - arch: HostArch::X64, - id: "yarn".into(), - os: HostOS::MacOS, + context: ToolContext { version: "3.6.1".into(), ..Default::default() } @@ -198,20 +212,21 @@ mod yarn_berry { #[test] fn locates_default_bin() { let sandbox = create_empty_sandbox(); - let plugin = create_plugin("yarn-test", sandbox.path()); + let mut plugin = create_plugin("yarn-test", sandbox.path()); + + plugin.set_environment(HostEnvironment { + arch: HostArch::X64, + os: HostOS::MacOS, + ..Default::default() + }); assert_eq!( plugin .locate_bins(LocateBinsInput { - env: Environment { - arch: HostArch::X64, - id: "yarn".into(), - os: HostOS::MacOS, + context: ToolContext { version: "3.6.1".into(), ..Default::default() }, - home_dir: PathBuf::new(), - tool_dir: PathBuf::new(), }) .bin_path, Some("bin/yarn".into()) @@ -231,25 +246,32 @@ fn locates_bin_from_package_json_bin() { }"#, ); - let plugin = create_plugin("npm-test", sandbox.path()); + let mut plugin = create_plugin("npm-test", sandbox.path()); + + plugin.set_environment(HostEnvironment { + arch: HostArch::X64, + os: HostOS::Windows, + ..Default::default() + }); assert_eq!( plugin .locate_bins(LocateBinsInput { - env: Environment { - arch: HostArch::X64, - id: "npm".into(), - os: HostOS::Windows, + context: ToolContext { version: "20.0.0".into(), ..Default::default() }, - home_dir: PathBuf::new(), - tool_dir: plugin.to_virtual_path(&plugin.tool.get_tool_dir()), }) .bin_path, Some("./file.js".into()) ); + plugin.set_environment(HostEnvironment { + arch: HostArch::Arm64, + os: HostOS::Linux, + ..Default::default() + }); + sandbox.create_file( ".proto/tools/npm-test/latest/package.json", r#"{ @@ -265,15 +287,10 @@ fn locates_bin_from_package_json_bin() { assert_eq!( plugin .locate_bins(LocateBinsInput { - env: Environment { - arch: HostArch::Arm64, - id: "npm".into(), - os: HostOS::Linux, + context: ToolContext { version: "9.0.0".into(), ..Default::default() }, - home_dir: PathBuf::new(), - tool_dir: plugin.to_virtual_path(&plugin.tool.get_tool_dir()), }) .bin_path, Some("./npm.js".into()) @@ -291,20 +308,21 @@ fn locates_bin_from_package_json_main() { }"#, ); - let plugin = create_plugin("npm-test", sandbox.path()); + let mut plugin = create_plugin("npm-test", sandbox.path()); + + plugin.set_environment(HostEnvironment { + arch: HostArch::X64, + os: HostOS::MacOS, + ..Default::default() + }); assert_eq!( plugin .locate_bins(LocateBinsInput { - env: Environment { - arch: HostArch::X64, - id: "npm".into(), - os: HostOS::MacOS, + context: ToolContext { version: "8.0.0".into(), ..Default::default() }, - home_dir: PathBuf::new(), - tool_dir: plugin.to_virtual_path(&plugin.tool.get_tool_dir()), }) .bin_path, Some("./index.js".into()) diff --git a/crates/node-depman/tests/hooks_test.rs b/crates/node-depman/tests/hooks_test.rs index 49ed650..e3cb7d6 100644 --- a/crates/node-depman/tests/hooks_test.rs +++ b/crates/node-depman/tests/hooks_test.rs @@ -5,7 +5,7 @@ // use utils::*; mod npm { - use super::*; + // use super::*; // #[test] // fn errors_if_installing_global() { diff --git a/crates/node-depman/tests/metadata_test.rs b/crates/node-depman/tests/metadata_test.rs index c3dc7a8..f76facb 100644 --- a/crates/node-depman/tests/metadata_test.rs +++ b/crates/node-depman/tests/metadata_test.rs @@ -1,16 +1,8 @@ use proto_pdk_test_utils::*; use starbase_sandbox::create_empty_sandbox; -use std::path::PathBuf; fn create_metadata(id: &str) -> ToolMetadataInput { - ToolMetadataInput { - id: id.into(), - env: Environment { - id: id.into(), - ..Environment::default() - }, - home_dir: PathBuf::new(), - } + ToolMetadataInput { id: id.into() } } mod npm { diff --git a/crates/node-depman/tests/versions_test.rs b/crates/node-depman/tests/versions_test.rs index ccf34cd..30ec0ed 100644 --- a/crates/node-depman/tests/versions_test.rs +++ b/crates/node-depman/tests/versions_test.rs @@ -19,10 +19,6 @@ mod npm { plugin.parse_version_file(ParseVersionFileInput { content: r#"{ "packageManager": "yarn@1.2.3" }"#.into(), file: "package.json".into(), - env: Environment { - id: "npm-test".into(), - ..Environment::default() - }, }), ParseVersionFileOutput { version: None } ); @@ -37,10 +33,6 @@ mod npm { plugin.parse_version_file(ParseVersionFileInput { content: r#"{ "packageManager": "npm@1.2.3" }"#.into(), file: "package.json".into(), - env: Environment { - id: "npm-test".into(), - ..Environment::default() - }, }), ParseVersionFileOutput { version: Some("1.2.3".into()), @@ -57,10 +49,6 @@ mod npm { plugin.parse_version_file(ParseVersionFileInput { content: r#"{ "packageManager": "npm" }"#.into(), file: "package.json".into(), - env: Environment { - id: "npm-test".into(), - ..Environment::default() - }, }), ParseVersionFileOutput { version: Some("latest".into()), @@ -87,10 +75,6 @@ mod pnpm { plugin.parse_version_file(ParseVersionFileInput { content: r#"{ "packageManager": "yarn@1.2.3" }"#.into(), file: "package.json".into(), - env: Environment { - id: "pnpm-test".into(), - ..Environment::default() - }, }), ParseVersionFileOutput { version: None } ); @@ -105,10 +89,6 @@ mod pnpm { plugin.parse_version_file(ParseVersionFileInput { content: r#"{ "packageManager": "pnpm@1.2.3" }"#.into(), file: "package.json".into(), - env: Environment { - id: "pnpm-test".into(), - ..Environment::default() - }, }), ParseVersionFileOutput { version: Some("1.2.3".into()), @@ -125,10 +105,6 @@ mod pnpm { plugin.parse_version_file(ParseVersionFileInput { content: r#"{ "packageManager": "pnpm" }"#.into(), file: "package.json".into(), - env: Environment { - id: "pnpm-test".into(), - ..Environment::default() - }, }), ParseVersionFileOutput { version: Some("latest".into()), @@ -143,8 +119,8 @@ mod yarn { generate_resolve_versions_tests!("yarn-test", { "1" => "1.22.19", "2" => "2.4.3", - "3" => "3.6.1", - "berry" => "3.6.1", + "3" => "3.6.2", + "berry" => "3.6.2", }); #[test] @@ -156,10 +132,6 @@ mod yarn { plugin.parse_version_file(ParseVersionFileInput { content: r#"{ "packageManager": "pnpm@1.2.3" }"#.into(), file: "package.json".into(), - env: Environment { - id: "yarn-test".into(), - ..Environment::default() - }, }), ParseVersionFileOutput { version: None } ); @@ -174,10 +146,6 @@ mod yarn { plugin.parse_version_file(ParseVersionFileInput { content: r#"{ "packageManager": "yarn@1.2.3" }"#.into(), file: "package.json".into(), - env: Environment { - id: "yarn-test".into(), - ..Environment::default() - }, }), ParseVersionFileOutput { version: Some("1.2.3".into()), @@ -194,10 +162,6 @@ mod yarn { plugin.parse_version_file(ParseVersionFileInput { content: r#"{ "packageManager": "yarn" }"#.into(), file: "package.json".into(), - env: Environment { - id: "yarn-test".into(), - ..Environment::default() - }, }), ParseVersionFileOutput { version: Some("latest".into()), diff --git a/crates/node/src/proto.rs b/crates/node/src/proto.rs index 2746ce4..20f0517 100644 --- a/crates/node/src/proto.rs +++ b/crates/node/src/proto.rs @@ -58,7 +58,7 @@ pub fn download_prebuilt( ], )?; - let version = input.state.version; + let version = input.context.version; let arch = map_arch(env.os, env.arch)?; let prefix = match env.os { diff --git a/crates/node/tests/download_test.rs b/crates/node/tests/download_test.rs index b9e5c71..a602fab 100644 --- a/crates/node/tests/download_test.rs +++ b/crates/node/tests/download_test.rs @@ -1,19 +1,22 @@ use proto_pdk_test_utils::*; use starbase_sandbox::create_empty_sandbox; -use std::path::PathBuf; generate_download_install_tests!("node-test", "18.0.0"); #[test] fn supports_linux_arm64() { let sandbox = create_empty_sandbox(); - let plugin = create_plugin("node-test", sandbox.path()); + let mut plugin = create_plugin("node-test", sandbox.path()); + + plugin.set_environment(HostEnvironment { + arch: HostArch::Arm64, + os: HostOS::Linux, + ..Default::default() + }); assert_eq!( plugin.download_prebuilt(DownloadPrebuiltInput { - env: Environment { - arch: HostArch::Arm64, - os: HostOS::Linux, + context: ToolContext { version: "20.0.0".into(), ..Default::default() } @@ -31,13 +34,17 @@ fn supports_linux_arm64() { #[test] fn supports_linux_arm() { let sandbox = create_empty_sandbox(); - let plugin = create_plugin("node-test", sandbox.path()); + let mut plugin = create_plugin("node-test", sandbox.path()); + + plugin.set_environment(HostEnvironment { + arch: HostArch::Arm, + os: HostOS::Linux, + ..Default::default() + }); assert_eq!( plugin.download_prebuilt(DownloadPrebuiltInput { - env: Environment { - arch: HostArch::Arm, - os: HostOS::Linux, + context: ToolContext { version: "20.0.0".into(), ..Default::default() } @@ -55,13 +62,17 @@ fn supports_linux_arm() { #[test] fn supports_linux_x64() { let sandbox = create_empty_sandbox(); - let plugin = create_plugin("node-test", sandbox.path()); + let mut plugin = create_plugin("node-test", sandbox.path()); + + plugin.set_environment(HostEnvironment { + arch: HostArch::X64, + os: HostOS::Linux, + ..Default::default() + }); assert_eq!( plugin.download_prebuilt(DownloadPrebuiltInput { - env: Environment { - arch: HostArch::X64, - os: HostOS::Linux, + context: ToolContext { version: "20.0.0".into(), ..Default::default() } @@ -79,13 +90,17 @@ fn supports_linux_x64() { #[test] fn supports_linux_s390x() { let sandbox = create_empty_sandbox(); - let plugin = create_plugin("node-test", sandbox.path()); + let mut plugin = create_plugin("node-test", sandbox.path()); + + plugin.set_environment(HostEnvironment { + arch: HostArch::S390x, + os: HostOS::Linux, + ..Default::default() + }); assert_eq!( plugin.download_prebuilt(DownloadPrebuiltInput { - env: Environment { - arch: HostArch::S390x, - os: HostOS::Linux, + context: ToolContext { version: "20.0.0".into(), ..Default::default() } @@ -103,13 +118,17 @@ fn supports_linux_s390x() { #[test] fn supports_linux_ppc64() { let sandbox = create_empty_sandbox(); - let plugin = create_plugin("node-test", sandbox.path()); + let mut plugin = create_plugin("node-test", sandbox.path()); + + plugin.set_environment(HostEnvironment { + arch: HostArch::Powerpc64, + os: HostOS::Linux, + ..Default::default() + }); assert_eq!( plugin.download_prebuilt(DownloadPrebuiltInput { - env: Environment { - arch: HostArch::Powerpc64, - os: HostOS::Linux, + context: ToolContext { version: "20.0.0".into(), ..Default::default() } @@ -128,13 +147,17 @@ fn supports_linux_ppc64() { #[test] fn supports_macos_arm64() { let sandbox = create_empty_sandbox(); - let plugin = create_plugin("node-test", sandbox.path()); + let mut plugin = create_plugin("node-test", sandbox.path()); + + plugin.set_environment(HostEnvironment { + arch: HostArch::Arm64, + os: HostOS::MacOS, + ..Default::default() + }); assert_eq!( plugin.download_prebuilt(DownloadPrebuiltInput { - env: Environment { - arch: HostArch::Arm64, - os: HostOS::MacOS, + context: ToolContext { version: "20.0.0".into(), ..Default::default() } @@ -152,13 +175,17 @@ fn supports_macos_arm64() { #[test] fn supports_macos_x64() { let sandbox = create_empty_sandbox(); - let plugin = create_plugin("node-test", sandbox.path()); + let mut plugin = create_plugin("node-test", sandbox.path()); + + plugin.set_environment(HostEnvironment { + arch: HostArch::X64, + os: HostOS::MacOS, + ..Default::default() + }); assert_eq!( plugin.download_prebuilt(DownloadPrebuiltInput { - env: Environment { - arch: HostArch::X64, - os: HostOS::MacOS, + context: ToolContext { version: "20.0.0".into(), ..Default::default() } @@ -176,13 +203,17 @@ fn supports_macos_x64() { #[test] fn supports_windows_arm64() { let sandbox = create_empty_sandbox(); - let plugin = create_plugin("node-test", sandbox.path()); + let mut plugin = create_plugin("node-test", sandbox.path()); + + plugin.set_environment(HostEnvironment { + arch: HostArch::Arm64, + os: HostOS::Windows, + ..Default::default() + }); assert_eq!( plugin.download_prebuilt(DownloadPrebuiltInput { - env: Environment { - arch: HostArch::Arm64, - os: HostOS::Windows, + context: ToolContext { version: "20.0.0".into(), ..Default::default() } @@ -200,13 +231,17 @@ fn supports_windows_arm64() { #[test] fn supports_windows_x64() { let sandbox = create_empty_sandbox(); - let plugin = create_plugin("node-test", sandbox.path()); + let mut plugin = create_plugin("node-test", sandbox.path()); + + plugin.set_environment(HostEnvironment { + arch: HostArch::X64, + os: HostOS::Windows, + ..Default::default() + }); assert_eq!( plugin.download_prebuilt(DownloadPrebuiltInput { - env: Environment { - arch: HostArch::X64, - os: HostOS::Windows, + context: ToolContext { version: "20.0.0".into(), ..Default::default() } @@ -224,13 +259,17 @@ fn supports_windows_x64() { #[test] fn supports_windows_x86() { let sandbox = create_empty_sandbox(); - let plugin = create_plugin("node-test", sandbox.path()); + let mut plugin = create_plugin("node-test", sandbox.path()); + + plugin.set_environment(HostEnvironment { + arch: HostArch::X86, + os: HostOS::Windows, + ..Default::default() + }); assert_eq!( plugin.download_prebuilt(DownloadPrebuiltInput { - env: Environment { - arch: HostArch::X86, - os: HostOS::Windows, + context: ToolContext { version: "20.0.0".into(), ..Default::default() } @@ -248,19 +287,21 @@ fn supports_windows_x86() { #[test] fn locates_unix_bin() { let sandbox = create_empty_sandbox(); - let plugin = create_plugin("bun-test", sandbox.path()); + let mut plugin = create_plugin("bun-test", sandbox.path()); + + plugin.set_environment(HostEnvironment { + arch: HostArch::Arm64, + os: HostOS::Linux, + ..Default::default() + }); assert_eq!( plugin .locate_bins(LocateBinsInput { - env: Environment { - arch: HostArch::Arm64, - os: HostOS::Linux, + context: ToolContext { version: "20.0.0".into(), ..Default::default() }, - home_dir: PathBuf::new(), - tool_dir: PathBuf::new(), }) .bin_path, Some("bin/node".into()) @@ -270,19 +311,21 @@ fn locates_unix_bin() { #[test] fn locates_windows_bin() { let sandbox = create_empty_sandbox(); - let plugin = create_plugin("bun-test", sandbox.path()); + let mut plugin = create_plugin("bun-test", sandbox.path()); + + plugin.set_environment(HostEnvironment { + arch: HostArch::X64, + os: HostOS::Windows, + ..Default::default() + }); assert_eq!( plugin .locate_bins(LocateBinsInput { - env: Environment { - arch: HostArch::X64, - os: HostOS::Windows, + context: ToolContext { version: "20.0.0".into(), ..Default::default() }, - home_dir: PathBuf::new(), - tool_dir: PathBuf::new(), }) .bin_path, Some("node.exe".into()) From 5901395d5fff996959d8cd4d2d0243bc8a8e5e60 Mon Sep 17 00:00:00 2001 From: Miles Johnson Date: Mon, 21 Aug 2023 11:48:40 -0700 Subject: [PATCH 06/16] Add hooks. --- CHANGELOG.md | 1 + crates/node-depman/Cargo.toml | 2 +- crates/node-depman/src/proto.rs | 49 ++++++++++++++++++++++++++++++++- crates/node/Cargo.toml | 2 +- crates/node/src/proto.rs | 35 +++++++++++++++++++++++ 5 files changed, 86 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ac9569f..14ac118 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ #### 🚀 Updates - Added support for `install_global` and `uninstall_global`. +- Added `post_install` hook for installing the bundled npm. - Updated to support proto v0.15 release. #### 🐞 Fixes diff --git a/crates/node-depman/Cargo.toml b/crates/node-depman/Cargo.toml index daf4109..a89a81b 100644 --- a/crates/node-depman/Cargo.toml +++ b/crates/node-depman/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "node_depman_plugin" -version = "0.1.1" +version = "0.2.0" edition = "2021" license = "MIT" publish = false diff --git a/crates/node-depman/src/proto.rs b/crates/node-depman/src/proto.rs index e74911d..5ba9373 100644 --- a/crates/node-depman/src/proto.rs +++ b/crates/node-depman/src/proto.rs @@ -69,7 +69,7 @@ pub fn register_tool(Json(_): Json) -> FnResult) -> FnResult<()> { + let args = &input.passthrough_args; + let user_config = get_proto_user_config()?; + + if args.len() < 3 + || input.context.env_vars.get("PROTO_INSTALL_GLOBAL").is_some() + || !user_config.node_intercept_globals + { + return Ok(()); + } + + let manager = PackageManager::detect(); + let mut is_install_command = false; + let mut is_global = false; + + // npm install -g + // pnpm add -g + if manager == PackageManager::Npm || manager == PackageManager::Yarn { + is_install_command = args[0] == "install" || args[0] == "i" || args[0] == "add"; + + for arg in args { + if arg == "--global" || arg == "-g" || arg == "--location=global" { + is_global = true; + break; + } + } + } + + // yarn global add + if manager == PackageManager::Yarn { + is_global = args[0] == "global"; + is_install_command = args[1] == "add"; + } + + if is_install_command && is_global { + return err!(format!( + "Global binaries must be installed with `proto install-global {}`!\nLearn more: {}\n\nOpt-out of this functionality with `{}`.", + manager.to_string(), + "https://moonrepo.dev/docs/proto/faq#how-can-i-install-a-global-binary-for-a-language", + "node-intercept-globals = false", + )); + } + + Ok(()) +} diff --git a/crates/node/Cargo.toml b/crates/node/Cargo.toml index fc4a691..6c7bab2 100644 --- a/crates/node/Cargo.toml +++ b/crates/node/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "node_plugin" -version = "0.1.1" +version = "0.2.0" edition = "2021" license = "MIT" publish = false diff --git a/crates/node/src/proto.rs b/crates/node/src/proto.rs index 20f0517..fd16a2c 100644 --- a/crates/node/src/proto.rs +++ b/crates/node/src/proto.rs @@ -6,6 +6,7 @@ use std::collections::HashMap; #[host_fn] extern "ExtismHost" { fn exec_command(input: Json) -> Json; + fn host_log(input: Json); } static NAME: &str = "Node.js"; @@ -218,3 +219,37 @@ pub fn uninstall_global( Ok(Json(UninstallGlobalOutput::from_exec_command(result))) } + +#[plugin_fn] +pub fn post_install(Json(input): Json) -> FnResult<()> { + if input + .passthrough_args + .iter() + .any(|arg| arg == "--no-bundled-npm") + { + return Ok(()); + } + + host_log!("Installing npm that comes bundled with Node.js"); + + let mut args = vec!["install", "npm", "bundled"]; + + if input.pinned { + args.push("--pin"); + } + + if !input.passthrough_args.is_empty() { + args.push("--"); + args.extend( + input + .passthrough_args + .iter() + .map(|a| a.as_str()) + .collect::>(), + ); + } + + exec_command!(ExecCommandInput::inherit("proto", args)); + + Ok(()) +} From 7cff9d6ec7b4fb1e10297930d21a72487b5ab421 Mon Sep 17 00:00:00 2001 From: Miles Johnson Date: Mon, 21 Aug 2023 15:53:00 -0700 Subject: [PATCH 07/16] Use new crates. --- Cargo.toml | 8 +++----- crates/common/src/commands.rs | 4 ++-- crates/node-depman/tests/metadata_test.rs | 6 +++--- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index c891719..ba96783 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,11 +4,9 @@ members = ["crates/*"] [workspace.dependencies] extism-pdk = "0.3.3" -proto_pdk = { version = "0.4.6", path = "../../proto/crates/pdk" } -proto_pdk_api = { version = "0.4.8", path = "../../proto/crates/pdk-api" } -proto_pdk_test_utils = { version = "0.3.11", path = "../../proto/crates/pdk-test-utils" } -# proto_pdk = "0.4.6" -# proto_pdk_test_utils = "0.3.11" +proto_pdk = { version = "0.6.2" } # , path = "../../proto/crates/pdk" } +proto_pdk_api = { version = "0.6.0" } # , path = "../../proto/crates/pdk-api" } +proto_pdk_test_utils = { version = "0.5.0" } # , path = "../../proto/crates/pdk-test-utils" } serde = "1.0.183" starbase_sandbox = "0.1.8" tokio = "1.31.0" diff --git a/crates/common/src/commands.rs b/crates/common/src/commands.rs index c49cbf2..9e6ec2d 100644 --- a/crates/common/src/commands.rs +++ b/crates/common/src/commands.rs @@ -2,7 +2,7 @@ use proto_pdk_api::ExecCommandInput; use std::path::Path; pub fn install_global(dependency: &str, globals_dir: &Path) -> ExecCommandInput { - let mut cmd = ExecCommandInput::pipe( + let mut cmd = ExecCommandInput::inherit( "npm", [ "install", @@ -25,7 +25,7 @@ pub fn install_global(dependency: &str, globals_dir: &Path) -> ExecCommandInput } pub fn uninstall_global(dependency: &str, globals_dir: &Path) -> ExecCommandInput { - let mut cmd = ExecCommandInput::pipe( + let mut cmd = ExecCommandInput::inherit( "npm", ["uninstall", "--global", "--loglevel", "warn", dependency], ); diff --git a/crates/node-depman/tests/metadata_test.rs b/crates/node-depman/tests/metadata_test.rs index f76facb..a87cac8 100644 --- a/crates/node-depman/tests/metadata_test.rs +++ b/crates/node-depman/tests/metadata_test.rs @@ -18,7 +18,7 @@ mod npm { ToolMetadataOutput { name: "npm".into(), type_of: PluginType::DependencyManager, - env_vars: vec!["PROTO_NODE_VERSION".into()], + env_vars: vec!["PROTO_NODE_VERSION".into(), "PROTO_INSTALL_GLOBAL".into()], default_version: Some("bundled".into()), plugin_version: Some(env!("CARGO_PKG_VERSION").into()), ..ToolMetadataOutput::default() @@ -40,7 +40,7 @@ mod pnpm { ToolMetadataOutput { name: "pnpm".into(), type_of: PluginType::DependencyManager, - env_vars: vec!["PROTO_NODE_VERSION".into()], + env_vars: vec!["PROTO_NODE_VERSION".into(), "PROTO_INSTALL_GLOBAL".into()], plugin_version: Some(env!("CARGO_PKG_VERSION").into()), ..ToolMetadataOutput::default() } @@ -61,7 +61,7 @@ mod yarn { ToolMetadataOutput { name: "yarn".into(), type_of: PluginType::DependencyManager, - env_vars: vec!["PROTO_NODE_VERSION".into()], + env_vars: vec!["PROTO_NODE_VERSION".into(), "PROTO_INSTALL_GLOBAL".into()], plugin_version: Some(env!("CARGO_PKG_VERSION").into()), ..ToolMetadataOutput::default() } From 596b804c8c81f91cdd0a52c005070b32062abcbe Mon Sep 17 00:00:00 2001 From: Miles Johnson Date: Tue, 22 Aug 2023 10:33:35 -0700 Subject: [PATCH 08/16] Test node hooks. --- Cargo.toml | 2 +- crates/node/src/proto.rs | 2 +- crates/node/tests/hooks_test.rs | 116 +++++++++++++++++++++----------- 3 files changed, 80 insertions(+), 40 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index ba96783..e419e07 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,7 +6,7 @@ members = ["crates/*"] extism-pdk = "0.3.3" proto_pdk = { version = "0.6.2" } # , path = "../../proto/crates/pdk" } proto_pdk_api = { version = "0.6.0" } # , path = "../../proto/crates/pdk-api" } -proto_pdk_test_utils = { version = "0.5.0" } # , path = "../../proto/crates/pdk-test-utils" } +proto_pdk_test_utils = { version = "0.5.4" } # , path = "../../proto/crates/pdk-test-utils" } serde = "1.0.183" starbase_sandbox = "0.1.8" tokio = "1.31.0" diff --git a/crates/node/src/proto.rs b/crates/node/src/proto.rs index fd16a2c..d04956b 100644 --- a/crates/node/src/proto.rs +++ b/crates/node/src/proto.rs @@ -249,7 +249,7 @@ pub fn post_install(Json(input): Json) -> FnResult<()> { ); } - exec_command!(ExecCommandInput::inherit("proto", args)); + exec_command!(inherit, "proto", args); Ok(()) } diff --git a/crates/node/tests/hooks_test.rs b/crates/node/tests/hooks_test.rs index 698703d..5c974d3 100644 --- a/crates/node/tests/hooks_test.rs +++ b/crates/node/tests/hooks_test.rs @@ -1,50 +1,90 @@ -// TODO: Enable once 0.15 lands +use proto_pdk::InstallHook; +use proto_pdk_test_utils::{core::AliasOrVersion, create_plugin, ToolManifest, Version}; +use starbase_sandbox::create_empty_sandbox; +use std::collections::HashSet; +use std::env; +use std::path::PathBuf; -// #[test] -// fn installs_bundled_npm() { -// let temp = create_empty_sandbox(); +fn set_vars(path: PathBuf) { + env::set_var("PROTO_ROOT", path.to_string_lossy().to_string()); + env::set_var("PROTO_NODE_VERSION", "18.0.0"); +} -// let mut cmd = create_proto_command(temp.path()); -// let assert = cmd.arg("install").arg("node").arg("19.0.0").assert(); +fn reset_vars() { + env::remove_var("PROTO_ROOT"); + env::remove_var("PROTO_NODE_VERSION"); +} -// let output = output_to_string(&assert.get_output().stderr.to_vec()); +mod node_hooks { + use super::*; -// assert!(predicate::str::contains("Node.js has been installed").eval(&output)); -// assert!(predicate::str::contains("npm has been installed").eval(&output)); + #[test] + fn installs_bundled_npm() { + let sandbox = create_empty_sandbox(); + let plugin = create_plugin("node-test", sandbox.path()); -// assert!(temp.path().join("tools/node/19.0.0").exists()); -// assert!(temp.path().join("tools/npm/8.19.2").exists()); + assert!(!sandbox.path().join(".proto/tools/npm/8.6.0").exists()); -// let manifest = ToolManifest::load(temp.path().join("tools/npm/manifest.json")).unwrap(); + set_vars(sandbox.path().join(".proto")); -// assert_eq!( -// manifest.default_version, -// Some(AliasOrVersion::parse("bundled").unwrap()) -// ); -// assert_eq!( -// manifest.installed_versions, -// HashSet::from_iter([Version::parse("8.19.2").unwrap()]) -// ); -// } + plugin.post_install(InstallHook::default()); -// #[test] -// fn skips_bundled_npm() { -// let temp = create_empty_sandbox(); + reset_vars(); -// let mut cmd = create_proto_command(temp.path()); -// let assert = cmd -// .arg("install") -// .arg("node") -// .arg("19.0.0") -// .arg("--") -// .arg("--no-bundled-npm") -// .assert(); + assert!(sandbox.path().join(".proto/tools/npm/8.6.0").exists()); -// let output = output_to_string(&assert.get_output().stderr.to_vec()); + let manifest = + ToolManifest::load(sandbox.path().join(".proto/tools/npm/manifest.json")).unwrap(); -// assert!(predicate::str::contains("Node.js has been installed").eval(&output)); -// assert!(!predicate::str::contains("npm has been installed").eval(&output)); + assert_eq!( + manifest.default_version, + Some(AliasOrVersion::parse("bundled").unwrap()) + ); + assert_eq!( + manifest.installed_versions, + HashSet::from_iter([Version::parse("8.6.0").unwrap()]) + ); + } -// assert!(temp.path().join("tools/node/19.0.0").exists()); -// assert!(!temp.path().join("tools/npm/8.19.2").exists()); -// } + #[test] + fn can_pin_bundled_npm() { + let sandbox = create_empty_sandbox(); + let plugin = create_plugin("node-test", sandbox.path()); + + set_vars(sandbox.path().join(".proto")); + + plugin.post_install(InstallHook { + pinned: true, + ..InstallHook::default() + }); + + reset_vars(); + + let manifest = + ToolManifest::load(sandbox.path().join(".proto/tools/npm/manifest.json")).unwrap(); + + assert_eq!( + manifest.default_version, + Some(AliasOrVersion::parse("8.6.0").unwrap()) + ); + } + + #[test] + fn can_skip_bundled_npm() { + let sandbox = create_empty_sandbox(); + let plugin = create_plugin("node-test", sandbox.path()); + + assert!(!sandbox.path().join(".proto/tools/npm/8.6.0").exists()); + + set_vars(sandbox.path().join(".proto")); + + plugin.post_install(InstallHook { + passthrough_args: vec!["--no-bundled-npm".into()], + ..InstallHook::default() + }); + + reset_vars(); + + assert!(!sandbox.path().join(".proto/tools/npm/8.6.0").exists()); + } +} From f32128f599fdb0b15b229e90374c035ebc1fbd27 Mon Sep 17 00:00:00 2001 From: Miles Johnson Date: Tue, 22 Aug 2023 11:40:47 -0700 Subject: [PATCH 09/16] Test npm hooks. --- Cargo.toml | 1 + crates/node-depman/Cargo.toml | 1 + crates/node-depman/src/proto.rs | 2 +- crates/node-depman/tests/hooks_test.rs | 229 +++++++++++++------------ 4 files changed, 127 insertions(+), 106 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index e419e07..3358c77 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,5 +8,6 @@ proto_pdk = { version = "0.6.2" } # , path = "../../proto/crates/pdk" proto_pdk_api = { version = "0.6.0" } # , path = "../../proto/crates/pdk-api" } proto_pdk_test_utils = { version = "0.5.4" } # , path = "../../proto/crates/pdk-test-utils" } serde = "1.0.183" +serde_json = "1.0.105" starbase_sandbox = "0.1.8" tokio = "1.31.0" diff --git a/crates/node-depman/Cargo.toml b/crates/node-depman/Cargo.toml index a89a81b..5aa50ab 100644 --- a/crates/node-depman/Cargo.toml +++ b/crates/node-depman/Cargo.toml @@ -16,5 +16,6 @@ serde = { workspace = true } [dev-dependencies] proto_pdk_test_utils = { workspace = true } +serde_json = { workspace = true } starbase_sandbox = { workspace = true } tokio = { workspace = true } diff --git a/crates/node-depman/src/proto.rs b/crates/node-depman/src/proto.rs index 5ba9373..3b9b958 100644 --- a/crates/node-depman/src/proto.rs +++ b/crates/node-depman/src/proto.rs @@ -412,7 +412,7 @@ pub fn pre_run(Json(input): Json) -> FnResult<()> { // npm install -g // pnpm add -g - if manager == PackageManager::Npm || manager == PackageManager::Yarn { + if manager == PackageManager::Npm || manager == PackageManager::Pnpm { is_install_command = args[0] == "install" || args[0] == "i" || args[0] == "add"; for arg in args { diff --git a/crates/node-depman/tests/hooks_test.rs b/crates/node-depman/tests/hooks_test.rs index e3cb7d6..35280cd 100644 --- a/crates/node-depman/tests/hooks_test.rs +++ b/crates/node-depman/tests/hooks_test.rs @@ -1,110 +1,129 @@ -// mod utils; - -// use starbase_sandbox::predicates::prelude::*; -// use std::env; -// use utils::*; - -mod npm { - // use super::*; - - // #[test] - // fn errors_if_installing_global() { - // let temp = create_empty_sandbox(); - - // let mut cmd = create_proto_command(temp.path()); - // cmd.arg("install") - // .arg("npm") - // .arg("latest") - // .assert() - // .success(); - - // let mut cmd = create_proto_command(temp.path()); - // let assert = cmd - // .arg("run") - // .arg("npm") - // .arg("latest") - // .args(["--", "install", "-g", "typescript"]) - // .assert(); - - // assert.stderr(predicate::str::contains( - // "Global binaries must be installed with proto install-global npm", - // )); - // } - - // #[test] - // fn can_bypass_global_check() { - // let temp = create_empty_sandbox(); - - // let mut cmd = create_proto_command(temp.path()); - // cmd.arg("install") - // .arg("npm") - // .arg("latest") - // .assert() - // .success(); - - // env::set_var("PROTO_NODE_INTERCEPT_GLOBALS", "0"); - - // let mut cmd = create_proto_command(temp.path()); - // let assert = cmd - // .arg("run") - // .arg("npm") - // .arg("latest") - // .args(["--", "install", "-g", "typescript"]) - // .assert(); - - // env::remove_var("PROTO_NODE_INTERCEPT_GLOBALS"); - - // assert.stderr( - // predicate::str::contains( - // "Global binaries must be installed with proto install-global npm", - // ) - // .not(), - // ); - // } +use proto_pdk::{RunHook, ToolContext, UserConfigSettings}; +use proto_pdk_test_utils::create_plugin; +use starbase_sandbox::create_empty_sandbox; +use std::collections::HashMap; + +mod npm_hooks { + use super::*; + + #[test] + fn does_nothing_if_no_args() { + let sandbox = create_empty_sandbox(); + let plugin = create_plugin("npm-test", sandbox.path()); + + plugin.pre_run(RunHook::default()); + } + + #[test] + fn skips_when_env_var_set() { + let sandbox = create_empty_sandbox(); + let plugin = create_plugin("npm-test", sandbox.path()); + + plugin.pre_run(RunHook { + passthrough_args: vec!["install".into(), "-g".into(), "typescript".into()], + context: ToolContext { + env_vars: HashMap::from_iter([("PROTO_INSTALL_GLOBAL".into(), "1".into())]), + ..ToolContext::default() + }, + }); + } + + #[test] + fn can_bypass_with_user_config() { + let sandbox = create_empty_sandbox(); + let mut plugin = create_plugin("npm-test", sandbox.path()); + + plugin.tool.plugin.manifest.config.insert( + "proto_user_config".into(), + serde_json::to_string(&UserConfigSettings { + node_intercept_globals: false, + ..UserConfigSettings::default() + }) + .unwrap(), + ); + + plugin.tool.plugin.reload_config().unwrap(); + + plugin.pre_run(RunHook { + passthrough_args: vec!["install".into(), "-g".into(), "typescript".into()], + ..RunHook::default() + }); + } + + #[test] + #[should_panic(expected = "Global binaries must be installed")] + fn errors_if_installing_global() { + let sandbox = create_empty_sandbox(); + let plugin = create_plugin("npm-test", sandbox.path()); + + plugin.pre_run(RunHook { + passthrough_args: vec!["install".into(), "-g".into(), "typescript".into()], + ..RunHook::default() + }); + } + + #[test] + fn doesnt_error_for_other_commands() { + let sandbox = create_empty_sandbox(); + let plugin = create_plugin("npm-test", sandbox.path()); + + plugin.pre_run(RunHook { + passthrough_args: vec!["info".into(), "--json".into(), "typescript".into()], + ..RunHook::default() + }); + } } -mod pnpm { - // use super::*; - - // #[test] - // fn errors_if_installing_global() { - // let temp = create_empty_sandbox(); - - // let mut cmd = create_proto_command(temp.path()); - // cmd.arg("install").arg("pnpm").assert().success(); - - // let mut cmd = create_proto_command(temp.path()); - // let assert = cmd - // .arg("run") - // .arg("pnpm") - // .args(["--", "add", "-g", "typescript"]) - // .assert(); - - // assert.stderr(predicate::str::contains( - // "Global binaries must be installed with proto install-global pnpm", - // )); - // } +mod pnpm_hooks { + use super::*; + + #[test] + #[should_panic(expected = "Global binaries must be installed")] + fn errors_if_installing_global() { + let sandbox = create_empty_sandbox(); + let plugin = create_plugin("pnpm-test", sandbox.path()); + + plugin.pre_run(RunHook { + passthrough_args: vec!["add".into(), "--global".into(), "typescript".into()], + ..RunHook::default() + }); + } + + #[test] + fn doesnt_error_for_other_commands() { + let sandbox = create_empty_sandbox(); + let plugin = create_plugin("pnpm-test", sandbox.path()); + + plugin.pre_run(RunHook { + passthrough_args: vec!["info".into(), "--json".into(), "typescript".into()], + ..RunHook::default() + }); + } } -mod yarn { - // use super::*; - - // #[test] - // fn errors_if_installing_global() { - // let temp = create_empty_sandbox(); - - // let mut cmd = create_proto_command(temp.path()); - // cmd.arg("install").arg("yarn").assert().success(); - - // let mut cmd = create_proto_command(temp.path()); - // let assert = cmd - // .arg("run") - // .arg("yarn") - // .args(["--", "global", "add", "typescript"]) - // .assert(); - - // assert.stderr(predicate::str::contains( - // "Global binaries must be installed with proto install-global yarn", - // )); - // } +mod yarn_hooks { + use super::*; + + #[test] + #[should_panic(expected = "Global binaries must be installed")] + fn errors_if_installing_global() { + let sandbox = create_empty_sandbox(); + let plugin = create_plugin("yarn-test", sandbox.path()); + + plugin.pre_run(RunHook { + passthrough_args: vec!["global".into(), "add".into(), "typescript".into()], + ..RunHook::default() + }); + } + + #[test] + fn doesnt_error_for_other_commands() { + let sandbox = create_empty_sandbox(); + let plugin = create_plugin("yarn-test", sandbox.path()); + + plugin.pre_run(RunHook { + passthrough_args: vec!["info".into(), "--json".into(), "typescript".into()], + ..RunHook::default() + }); + } } From c2b8eee4145f6a80089e4c436bf1605484bdf9ca Mon Sep 17 00:00:00 2001 From: Miles Johnson Date: Tue, 22 Aug 2023 12:16:40 -0700 Subject: [PATCH 10/16] Add serial test. --- crates/node/Cargo.toml | 1 + crates/node/tests/hooks_test.rs | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/crates/node/Cargo.toml b/crates/node/Cargo.toml index 6c7bab2..7e5104c 100644 --- a/crates/node/Cargo.toml +++ b/crates/node/Cargo.toml @@ -16,5 +16,6 @@ serde = { workspace = true } [dev-dependencies] proto_pdk_test_utils = { workspace = true } +serial_test = "2.0.0" starbase_sandbox = { workspace = true } tokio = { workspace = true } diff --git a/crates/node/tests/hooks_test.rs b/crates/node/tests/hooks_test.rs index 5c974d3..6a64b6b 100644 --- a/crates/node/tests/hooks_test.rs +++ b/crates/node/tests/hooks_test.rs @@ -4,6 +4,7 @@ use starbase_sandbox::create_empty_sandbox; use std::collections::HashSet; use std::env; use std::path::PathBuf; +use serial_test::serial; fn set_vars(path: PathBuf) { env::set_var("PROTO_ROOT", path.to_string_lossy().to_string()); @@ -19,6 +20,7 @@ mod node_hooks { use super::*; #[test] + #[serial] fn installs_bundled_npm() { let sandbox = create_empty_sandbox(); let plugin = create_plugin("node-test", sandbox.path()); @@ -47,6 +49,7 @@ mod node_hooks { } #[test] + #[serial] fn can_pin_bundled_npm() { let sandbox = create_empty_sandbox(); let plugin = create_plugin("node-test", sandbox.path()); @@ -70,6 +73,7 @@ mod node_hooks { } #[test] + #[serial] fn can_skip_bundled_npm() { let sandbox = create_empty_sandbox(); let plugin = create_plugin("node-test", sandbox.path()); From ea172a618504ccb768b7564025ec8aac8fa5f3dd Mon Sep 17 00:00:00 2001 From: Miles Johnson Date: Tue, 22 Aug 2023 12:56:58 -0700 Subject: [PATCH 11/16] Install proto. --- .github/workflows/ci.yml | 1 + crates/node/tests/hooks_test.rs | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 250bcee..6c8cf84 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -45,6 +45,7 @@ jobs: - uses: moonrepo/setup-rust@v1 with: bins: cargo-wasi, cargo-nextest + - uses: moonrepo/setup-proto@v1 - run: cargo wasi build -p node_plugin - run: cargo wasi build -p node_depman_plugin - run: cargo nextest run --workspace diff --git a/crates/node/tests/hooks_test.rs b/crates/node/tests/hooks_test.rs index 6a64b6b..c989ac5 100644 --- a/crates/node/tests/hooks_test.rs +++ b/crates/node/tests/hooks_test.rs @@ -1,10 +1,10 @@ use proto_pdk::InstallHook; use proto_pdk_test_utils::{core::AliasOrVersion, create_plugin, ToolManifest, Version}; +use serial_test::serial; use starbase_sandbox::create_empty_sandbox; use std::collections::HashSet; use std::env; use std::path::PathBuf; -use serial_test::serial; fn set_vars(path: PathBuf) { env::set_var("PROTO_ROOT", path.to_string_lossy().to_string()); From f2572145172ac5b315b5c46da45564d30b2ccd8f Mon Sep 17 00:00:00 2001 From: Miles Johnson Date: Tue, 22 Aug 2023 13:10:12 -0700 Subject: [PATCH 12/16] Test globals. --- crates/common/src/commands.rs | 6 ++++++ crates/node-depman/tests/globals_test.rs | 20 ++++++++++++++++++++ crates/node/tests/globals_test.rs | 4 ++++ 3 files changed, 30 insertions(+) create mode 100644 crates/node-depman/tests/globals_test.rs create mode 100644 crates/node/tests/globals_test.rs diff --git a/crates/common/src/commands.rs b/crates/common/src/commands.rs index 9e6ec2d..a21e673 100644 --- a/crates/common/src/commands.rs +++ b/crates/common/src/commands.rs @@ -15,6 +15,9 @@ pub fn install_global(dependency: &str, globals_dir: &Path) -> ExecCommandInput ], ); + cmd.env_vars + .insert("PROTO_INSTALL_GLOBAL".into(), "true".into()); + // Remove the /bin component cmd.env_vars.insert( "PREFIX".into(), @@ -30,6 +33,9 @@ pub fn uninstall_global(dependency: &str, globals_dir: &Path) -> ExecCommandInpu ["uninstall", "--global", "--loglevel", "warn", dependency], ); + cmd.env_vars + .insert("PROTO_INSTALL_GLOBAL".into(), "true".into()); + // Remove the /bin component cmd.env_vars.insert( "PREFIX".into(), diff --git a/crates/node-depman/tests/globals_test.rs b/crates/node-depman/tests/globals_test.rs new file mode 100644 index 0000000..8d67520 --- /dev/null +++ b/crates/node-depman/tests/globals_test.rs @@ -0,0 +1,20 @@ +use proto_pdk_test_utils::*; +use starbase_sandbox::create_empty_sandbox; + +mod npm { + use super::*; + + generate_globals_test!("npm-test", "prettier"); +} + +mod pnpm { + use super::*; + + generate_globals_test!("pnpm-test", "prettier"); +} + +mod yarn { + use super::*; + + generate_globals_test!("yarn-test", "prettier"); +} diff --git a/crates/node/tests/globals_test.rs b/crates/node/tests/globals_test.rs new file mode 100644 index 0000000..9b6b9a1 --- /dev/null +++ b/crates/node/tests/globals_test.rs @@ -0,0 +1,4 @@ +use proto_pdk_test_utils::*; +use starbase_sandbox::create_empty_sandbox; + +generate_globals_test!("node-test", "prettier"); From 20e853910c23c9d63059f443f45d9477a5233987 Mon Sep 17 00:00:00 2001 From: Miles Johnson Date: Tue, 22 Aug 2023 13:34:12 -0700 Subject: [PATCH 13/16] Bump dep. --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 3358c77..1d5ff3f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,7 +6,7 @@ members = ["crates/*"] extism-pdk = "0.3.3" proto_pdk = { version = "0.6.2" } # , path = "../../proto/crates/pdk" } proto_pdk_api = { version = "0.6.0" } # , path = "../../proto/crates/pdk-api" } -proto_pdk_test_utils = { version = "0.5.4" } # , path = "../../proto/crates/pdk-test-utils" } +proto_pdk_test_utils = { version = "0.5.5" } # , path = "../../proto/crates/pdk-test-utils" } serde = "1.0.183" serde_json = "1.0.105" starbase_sandbox = "0.1.8" From 80d43e0c580ba92b01d3c00a06df3b325a49c627 Mon Sep 17 00:00:00 2001 From: Miles Johnson Date: Tue, 22 Aug 2023 14:05:32 -0700 Subject: [PATCH 14/16] Comment out test. --- crates/node-depman/tests/hooks_test.rs | 64 +++++++++++++------------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/crates/node-depman/tests/hooks_test.rs b/crates/node-depman/tests/hooks_test.rs index 35280cd..b92d960 100644 --- a/crates/node-depman/tests/hooks_test.rs +++ b/crates/node-depman/tests/hooks_test.rs @@ -50,17 +50,17 @@ mod npm_hooks { }); } - #[test] - #[should_panic(expected = "Global binaries must be installed")] - fn errors_if_installing_global() { - let sandbox = create_empty_sandbox(); - let plugin = create_plugin("npm-test", sandbox.path()); - - plugin.pre_run(RunHook { - passthrough_args: vec!["install".into(), "-g".into(), "typescript".into()], - ..RunHook::default() - }); - } + // #[test] + // #[should_panic(expected = "Global binaries must be installed")] + // fn errors_if_installing_global() { + // let sandbox = create_empty_sandbox(); + // let plugin = create_plugin("npm-test", sandbox.path()); + + // plugin.pre_run(RunHook { + // passthrough_args: vec!["install".into(), "-g".into(), "typescript".into()], + // ..RunHook::default() + // }); + // } #[test] fn doesnt_error_for_other_commands() { @@ -77,17 +77,17 @@ mod npm_hooks { mod pnpm_hooks { use super::*; - #[test] - #[should_panic(expected = "Global binaries must be installed")] - fn errors_if_installing_global() { - let sandbox = create_empty_sandbox(); - let plugin = create_plugin("pnpm-test", sandbox.path()); + // #[test] + // #[should_panic(expected = "Global binaries must be installed")] + // fn errors_if_installing_global() { + // let sandbox = create_empty_sandbox(); + // let plugin = create_plugin("pnpm-test", sandbox.path()); - plugin.pre_run(RunHook { - passthrough_args: vec!["add".into(), "--global".into(), "typescript".into()], - ..RunHook::default() - }); - } + // plugin.pre_run(RunHook { + // passthrough_args: vec!["add".into(), "--global".into(), "typescript".into()], + // ..RunHook::default() + // }); + // } #[test] fn doesnt_error_for_other_commands() { @@ -104,17 +104,17 @@ mod pnpm_hooks { mod yarn_hooks { use super::*; - #[test] - #[should_panic(expected = "Global binaries must be installed")] - fn errors_if_installing_global() { - let sandbox = create_empty_sandbox(); - let plugin = create_plugin("yarn-test", sandbox.path()); - - plugin.pre_run(RunHook { - passthrough_args: vec!["global".into(), "add".into(), "typescript".into()], - ..RunHook::default() - }); - } + // #[test] + // #[should_panic(expected = "Global binaries must be installed")] + // fn errors_if_installing_global() { + // let sandbox = create_empty_sandbox(); + // let plugin = create_plugin("yarn-test", sandbox.path()); + + // plugin.pre_run(RunHook { + // passthrough_args: vec!["global".into(), "add".into(), "typescript".into()], + // ..RunHook::default() + // }); + // } #[test] fn doesnt_error_for_other_commands() { From ff213c4b4b561efeb7979bd7fae096d402abd9d6 Mon Sep 17 00:00:00 2001 From: Miles Johnson Date: Tue, 22 Aug 2023 14:34:54 -0700 Subject: [PATCH 15/16] Wrong tests. --- crates/node-depman/tests/globals_test.rs | 28 +++++------ crates/node-depman/tests/hooks_test.rs | 64 ++++++++++++------------ 2 files changed, 46 insertions(+), 46 deletions(-) diff --git a/crates/node-depman/tests/globals_test.rs b/crates/node-depman/tests/globals_test.rs index 8d67520..fa6f8eb 100644 --- a/crates/node-depman/tests/globals_test.rs +++ b/crates/node-depman/tests/globals_test.rs @@ -1,20 +1,20 @@ -use proto_pdk_test_utils::*; -use starbase_sandbox::create_empty_sandbox; +// use proto_pdk_test_utils::*; +// use starbase_sandbox::create_empty_sandbox; -mod npm { - use super::*; +// mod npm { +// use super::*; - generate_globals_test!("npm-test", "prettier"); -} +// generate_globals_test!("npm-test", "prettier"); +// } -mod pnpm { - use super::*; +// mod pnpm { +// use super::*; - generate_globals_test!("pnpm-test", "prettier"); -} +// generate_globals_test!("pnpm-test", "prettier"); +// } -mod yarn { - use super::*; +// mod yarn { +// use super::*; - generate_globals_test!("yarn-test", "prettier"); -} +// generate_globals_test!("yarn-test", "prettier"); +// } diff --git a/crates/node-depman/tests/hooks_test.rs b/crates/node-depman/tests/hooks_test.rs index b92d960..35280cd 100644 --- a/crates/node-depman/tests/hooks_test.rs +++ b/crates/node-depman/tests/hooks_test.rs @@ -50,17 +50,17 @@ mod npm_hooks { }); } - // #[test] - // #[should_panic(expected = "Global binaries must be installed")] - // fn errors_if_installing_global() { - // let sandbox = create_empty_sandbox(); - // let plugin = create_plugin("npm-test", sandbox.path()); - - // plugin.pre_run(RunHook { - // passthrough_args: vec!["install".into(), "-g".into(), "typescript".into()], - // ..RunHook::default() - // }); - // } + #[test] + #[should_panic(expected = "Global binaries must be installed")] + fn errors_if_installing_global() { + let sandbox = create_empty_sandbox(); + let plugin = create_plugin("npm-test", sandbox.path()); + + plugin.pre_run(RunHook { + passthrough_args: vec!["install".into(), "-g".into(), "typescript".into()], + ..RunHook::default() + }); + } #[test] fn doesnt_error_for_other_commands() { @@ -77,17 +77,17 @@ mod npm_hooks { mod pnpm_hooks { use super::*; - // #[test] - // #[should_panic(expected = "Global binaries must be installed")] - // fn errors_if_installing_global() { - // let sandbox = create_empty_sandbox(); - // let plugin = create_plugin("pnpm-test", sandbox.path()); + #[test] + #[should_panic(expected = "Global binaries must be installed")] + fn errors_if_installing_global() { + let sandbox = create_empty_sandbox(); + let plugin = create_plugin("pnpm-test", sandbox.path()); - // plugin.pre_run(RunHook { - // passthrough_args: vec!["add".into(), "--global".into(), "typescript".into()], - // ..RunHook::default() - // }); - // } + plugin.pre_run(RunHook { + passthrough_args: vec!["add".into(), "--global".into(), "typescript".into()], + ..RunHook::default() + }); + } #[test] fn doesnt_error_for_other_commands() { @@ -104,17 +104,17 @@ mod pnpm_hooks { mod yarn_hooks { use super::*; - // #[test] - // #[should_panic(expected = "Global binaries must be installed")] - // fn errors_if_installing_global() { - // let sandbox = create_empty_sandbox(); - // let plugin = create_plugin("yarn-test", sandbox.path()); - - // plugin.pre_run(RunHook { - // passthrough_args: vec!["global".into(), "add".into(), "typescript".into()], - // ..RunHook::default() - // }); - // } + #[test] + #[should_panic(expected = "Global binaries must be installed")] + fn errors_if_installing_global() { + let sandbox = create_empty_sandbox(); + let plugin = create_plugin("yarn-test", sandbox.path()); + + plugin.pre_run(RunHook { + passthrough_args: vec!["global".into(), "add".into(), "typescript".into()], + ..RunHook::default() + }); + } #[test] fn doesnt_error_for_other_commands() { From 87d9d538b736e31fd9990b8df05f6ede8a12fe94 Mon Sep 17 00:00:00 2001 From: Miles Johnson Date: Tue, 22 Aug 2023 15:04:34 -0700 Subject: [PATCH 16/16] Comment out test. --- crates/node/tests/globals_test.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/node/tests/globals_test.rs b/crates/node/tests/globals_test.rs index 9b6b9a1..436c278 100644 --- a/crates/node/tests/globals_test.rs +++ b/crates/node/tests/globals_test.rs @@ -1,4 +1,4 @@ -use proto_pdk_test_utils::*; -use starbase_sandbox::create_empty_sandbox; +// use proto_pdk_test_utils::*; +// use starbase_sandbox::create_empty_sandbox; -generate_globals_test!("node-test", "prettier"); +// generate_globals_test!("node-test", "prettier");