diff --git a/CHANGELOG.md b/CHANGELOG.md index 9f9079a..6d34b5c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## 0.10.2 + +#### 🚀 Updates + +- Added a `dist-url` config setting, allowing the download host to be customized. + ## 0.10.1 #### 🚀 Updates diff --git a/Cargo.lock b/Cargo.lock index ef0c423..cfde139 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1815,7 +1815,7 @@ dependencies = [ [[package]] name = "node_depman_plugin" -version = "0.10.1" +version = "0.10.2" dependencies = [ "extism-pdk", "node_common", @@ -1832,7 +1832,7 @@ dependencies = [ [[package]] name = "node_plugin" -version = "0.10.1" +version = "0.10.2" dependencies = [ "extism-pdk", "node_common", diff --git a/README.md b/README.md index 310aefa..0ae8b82 100644 --- a/README.md +++ b/README.md @@ -24,10 +24,12 @@ All plugins can be configured with a `.prototools` file. ### Node.js - `bundled-npm` (bool) - When `node` is installed, also install `npm` with the version of npm that came bundled with Node.js. Defaults to `false`. +- `dist-url` (string) - The distribution URL to download Node.js archives from. Supports `{version}` and `{file}` tokens. ```toml [tools.node] bundled-npm = true +dist-url = "https://..." ``` ### Package managers diff --git a/crates/common/src/config.rs b/crates/common/src/config.rs index 8b0c74f..0f379c5 100644 --- a/crates/common/src/config.rs +++ b/crates/common/src/config.rs @@ -1,6 +1,21 @@ -#[derive(Debug, Default, serde::Deserialize, serde::Serialize)] +#[derive(Debug, serde::Deserialize, serde::Serialize)] #[serde(default, deny_unknown_fields, rename_all = "kebab-case")] -pub struct PluginConfig { +pub struct NodePluginConfig { pub bundled_npm: bool, + pub dist_url: String, +} + +impl Default for NodePluginConfig { + fn default() -> Self { + Self { + bundled_npm: false, + dist_url: "https://nodejs.org/download/release/v{version}/{file}".into(), + } + } +} + +#[derive(Debug, Default, serde::Deserialize, serde::Serialize)] +#[serde(default, deny_unknown_fields, rename_all = "kebab-case")] +pub struct NodeDepmanPluginConfig { pub shared_globals_dir: bool, } diff --git a/crates/node-depman/Cargo.toml b/crates/node-depman/Cargo.toml index f7c0541..1f92932 100644 --- a/crates/node-depman/Cargo.toml +++ b/crates/node-depman/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "node_depman_plugin" -version = "0.10.1" +version = "0.10.2" edition = "2021" license = "MIT" publish = false diff --git a/crates/node-depman/src/proto.rs b/crates/node-depman/src/proto.rs index 3b5cd5c..9d0efaf 100644 --- a/crates/node-depman/src/proto.rs +++ b/crates/node-depman/src/proto.rs @@ -1,7 +1,7 @@ use crate::npm_registry::parse_registry_response; use crate::package_manager::PackageManager; use extism_pdk::*; -use node_common::{NodeDistVersion, PluginConfig, VoltaField}; +use node_common::{NodeDepmanPluginConfig, NodeDistVersion, VoltaField}; use nodejs_package_json::PackageJson; use proto_pdk::*; use std::collections::HashMap; @@ -354,7 +354,7 @@ pub fn locate_executables( } }; - let config = get_tool_config::()?; + let config = get_tool_config::()?; if config.shared_globals_dir { globals_lookup_dirs.clear(); @@ -378,7 +378,7 @@ pub fn pre_run(Json(input): Json) -> FnResult> { }; let args = &input.passthrough_args; - let config = get_tool_config::()?; + let config = get_tool_config::()?; if args.len() < 3 || !config.shared_globals_dir { return Ok(Json(result)); diff --git a/crates/node-depman/tests/hooks_test.rs b/crates/node-depman/tests/hooks_test.rs index 0f67059..bfcbe8b 100644 --- a/crates/node-depman/tests/hooks_test.rs +++ b/crates/node-depman/tests/hooks_test.rs @@ -1,4 +1,4 @@ -use node_common::PluginConfig; +use node_common::NodeDepmanPluginConfig; use proto_pdk_api::RunHook; use proto_pdk_test_utils::*; use std::collections::HashMap; @@ -33,9 +33,8 @@ mod pre_run { fn does_nothing_if_disabled() { let sandbox = create_empty_proto_sandbox(); let plugin = sandbox.create_plugin_with_config("npm-test", |config| { - config.tool_config(PluginConfig { + config.tool_config(NodeDepmanPluginConfig { shared_globals_dir: false, - ..Default::default() }); }); @@ -49,9 +48,8 @@ mod pre_run { fn does_nothing_if_enabled_but_no_args() { let sandbox = create_empty_proto_sandbox(); let plugin = sandbox.create_plugin_with_config("npm-test", |config| { - config.tool_config(PluginConfig { + config.tool_config(NodeDepmanPluginConfig { shared_globals_dir: true, - ..Default::default() }); }); @@ -68,9 +66,8 @@ mod pre_run { fn does_nothing_if_a_prefix_was_provided() { let sandbox = create_empty_proto_sandbox(); let plugin = sandbox.create_plugin_with_config("npm-test", |config| { - config.tool_config(PluginConfig { + config.tool_config(NodeDepmanPluginConfig { shared_globals_dir: true, - ..Default::default() }); }); @@ -94,9 +91,8 @@ mod pre_run { fn adds_env_var() { let sandbox = create_empty_proto_sandbox(); let plugin = sandbox.create_plugin_with_config("npm-test", |config| { - config.tool_config(PluginConfig { + config.tool_config(NodeDepmanPluginConfig { shared_globals_dir: true, - ..Default::default() }); }); @@ -124,9 +120,8 @@ mod pre_run { fn adds_env_var_with_aliases() { let sandbox = create_empty_proto_sandbox(); let plugin = sandbox.create_plugin_with_config("npm-test", |config| { - config.tool_config(PluginConfig { + config.tool_config(NodeDepmanPluginConfig { shared_globals_dir: true, - ..Default::default() }); }); @@ -158,9 +153,8 @@ mod pre_run { fn does_nothing_if_disabled() { let sandbox = create_empty_proto_sandbox(); let plugin = sandbox.create_plugin_with_config("pnpm-test", |config| { - config.tool_config(PluginConfig { + config.tool_config(NodeDepmanPluginConfig { shared_globals_dir: false, - ..Default::default() }); }); @@ -174,9 +168,8 @@ mod pre_run { fn does_nothing_if_enabled_but_no_args() { let sandbox = create_empty_proto_sandbox(); let plugin = sandbox.create_plugin_with_config("pnpm-test", |config| { - config.tool_config(PluginConfig { + config.tool_config(NodeDepmanPluginConfig { shared_globals_dir: true, - ..Default::default() }); }); @@ -193,9 +186,8 @@ mod pre_run { fn does_nothing_if_a_dir_was_provided() { let sandbox = create_empty_proto_sandbox(); let plugin = sandbox.create_plugin_with_config("pnpm-test", |config| { - config.tool_config(PluginConfig { + config.tool_config(NodeDepmanPluginConfig { shared_globals_dir: true, - ..Default::default() }); }); @@ -219,9 +211,8 @@ mod pre_run { fn adds_args() { let sandbox = create_empty_proto_sandbox(); let plugin = sandbox.create_plugin_with_config("pnpm-test", |config| { - config.tool_config(PluginConfig { + config.tool_config(NodeDepmanPluginConfig { shared_globals_dir: true, - ..Default::default() }); }); @@ -247,9 +238,8 @@ mod pre_run { fn adds_args_with_aliases() { let sandbox = create_empty_proto_sandbox(); let plugin = sandbox.create_plugin_with_config("pnpm-test", |config| { - config.tool_config(PluginConfig { + config.tool_config(NodeDepmanPluginConfig { shared_globals_dir: true, - ..Default::default() }); }); @@ -281,9 +271,8 @@ mod pre_run { fn does_nothing_if_disabled() { let sandbox = create_empty_proto_sandbox(); let plugin = sandbox.create_plugin_with_config("yarn-test", |config| { - config.tool_config(PluginConfig { + config.tool_config(NodeDepmanPluginConfig { shared_globals_dir: false, - ..Default::default() }); }); @@ -297,9 +286,8 @@ mod pre_run { fn does_nothing_if_enabled_but_no_args() { let sandbox = create_empty_proto_sandbox(); let plugin = sandbox.create_plugin_with_config("yarn-test", |config| { - config.tool_config(PluginConfig { + config.tool_config(NodeDepmanPluginConfig { shared_globals_dir: true, - ..Default::default() }); }); @@ -316,9 +304,8 @@ mod pre_run { fn does_nothing_if_a_prefix_was_provided() { let sandbox = create_empty_proto_sandbox(); let plugin = sandbox.create_plugin_with_config("yarn-test", |config| { - config.tool_config(PluginConfig { + config.tool_config(NodeDepmanPluginConfig { shared_globals_dir: true, - ..Default::default() }); }); @@ -342,9 +329,8 @@ mod pre_run { fn adds_env_var() { let sandbox = create_empty_proto_sandbox(); let plugin = sandbox.create_plugin_with_config("yarn-test", |config| { - config.tool_config(PluginConfig { + config.tool_config(NodeDepmanPluginConfig { shared_globals_dir: true, - ..Default::default() }); }); diff --git a/crates/node/Cargo.toml b/crates/node/Cargo.toml index 3691f90..98e5f41 100644 --- a/crates/node/Cargo.toml +++ b/crates/node/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "node_plugin" -version = "0.10.1" +version = "0.10.2" edition = "2021" license = "MIT" publish = false diff --git a/crates/node/src/proto.rs b/crates/node/src/proto.rs index e37e51b..dc24bd1 100644 --- a/crates/node/src/proto.rs +++ b/crates/node/src/proto.rs @@ -1,5 +1,5 @@ use extism_pdk::*; -use node_common::{NodeDistLTS, NodeDistVersion, PluginConfig, VoltaField}; +use node_common::{NodeDistLTS, NodeDistVersion, NodePluginConfig, VoltaField}; use nodejs_package_json::PackageJson; use proto_pdk::*; @@ -163,14 +163,14 @@ pub fn download_prebuilt( let arch = map_arch(env.os, env.arch)?; let mut version = input.context.version; - let mut host = "https://nodejs.org/download/release".to_owned(); + let mut host = get_tool_config::()?.dist_url; // When canary, extract the latest version from the index if version.is_canary() { let response: Vec = fetch_url("https://nodejs.org/download/nightly/index.json")?; - host = "https://nodejs.org/download/nightly".into(); + host = host.replace("/release/", "/nightly/"); version = VersionSpec::parse(&response[0].version)?; } @@ -202,9 +202,14 @@ pub fn download_prebuilt( Ok(Json(DownloadPrebuiltOutput { archive_prefix: Some(prefix), - download_url: format!("{host}/v{version}/{filename}"), + download_url: host + .replace("{version}", &version.to_string()) + .replace("{file}", &filename), download_name: Some(filename), - checksum_url: Some(format!("{host}/v{version}/SHASUMS256.txt")), + checksum_url: Some( + host.replace("{version}", &version.to_string()) + .replace("{file}", "SHASUMS256.txt"), + ), ..DownloadPrebuiltOutput::default() })) } @@ -228,7 +233,7 @@ pub fn locate_executables( #[plugin_fn] pub fn post_install(Json(input): Json) -> FnResult<()> { - let config = get_tool_config::()?; + let config = get_tool_config::()?; if !config.bundled_npm || input diff --git a/crates/node/tests/hooks_test.rs b/crates/node/tests/hooks_test.rs index 03a4596..3097f18 100644 --- a/crates/node/tests/hooks_test.rs +++ b/crates/node/tests/hooks_test.rs @@ -1,7 +1,7 @@ // Importing proto_pdk crashes Windows because it contains WASM code #[cfg(not(windows))] mod node_hooks { - use node_common::PluginConfig; + use node_common::NodePluginConfig; use proto_pdk::InstallHook; use proto_pdk_test_utils::*; use serial_test::serial; @@ -24,7 +24,7 @@ mod node_hooks { fn installs_bundled_npm() { let sandbox = create_empty_proto_sandbox(); let plugin = sandbox.create_plugin_with_config("node-test", |config| { - config.tool_config(PluginConfig { + config.tool_config(NodePluginConfig { bundled_npm: true, ..Default::default() }); @@ -61,7 +61,7 @@ mod node_hooks { fn can_pin_bundled_npm() { let sandbox = create_empty_proto_sandbox(); let plugin = sandbox.create_plugin_with_config("node-test", |config| { - config.tool_config(PluginConfig { + config.tool_config(NodePluginConfig { bundled_npm: true, ..Default::default() }); @@ -89,7 +89,7 @@ mod node_hooks { fn can_skip_bundled_npm() { let sandbox = create_empty_proto_sandbox(); let plugin = sandbox.create_plugin_with_config("node-test", |config| { - config.tool_config(PluginConfig { + config.tool_config(NodePluginConfig { bundled_npm: true, ..Default::default() }); diff --git a/crates/node/tests/versions_test.rs b/crates/node/tests/versions_test.rs index c9c8d8a..92b6aab 100644 --- a/crates/node/tests/versions_test.rs +++ b/crates/node/tests/versions_test.rs @@ -5,8 +5,8 @@ generate_resolve_versions_tests!("node-test", { "10.1" => "10.1.0", "lts-gallium" => "16.20.2", "lts/fermium" => "14.21.3", - "stable" => "20.11.1", - "node" => "21.7.1", + "stable" => "20.12.1", + "node" => "21.7.2", }); #[test]