Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(node): allow using node unofficial build flavors #2637

Merged
merged 1 commit into from
Sep 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions docs/lang/node.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,26 @@ mise uses a `.tool-versions` or `.mise.toml` file for auto-switching between sof
You cannot install/use a plugin named "nodejs". If you attempt this, mise will just rename it to
"node". See the [FAQ](https://github.com/jdx/mise#what-is-the-difference-between-nodejs-and-node-or-golang-and-go)
for an explanation.

## Unofficial Builds

Nodejs.org offers a set of [unofficial builds](https://unofficial-builds.nodejs.org/) which are
compatible with some platforms are not supported by the official binaries. These are a nice alternative to
compiling from source for these platforms.

To use, first set the mirror url to point to the unofficial builds:

```sh
mise settings set node.mirror_url https://unofficial-builds.nodejs.org/download/release/
```

If your goal is to simply support an alternative arch/os like linux-loong64 or linux-armv6l, this is
all that is required. Node also provides flavors such as musl or glibc-217 (an older glibc version
than what the official binaries are built with).

To use these, set `node.flavor`:

```sh
mise settings set node.flavor musl
mise settings set node.flavor glibc-217
```
20 changes: 20 additions & 0 deletions schema/mise.json
Original file line number Diff line number Diff line change
Expand Up @@ -434,6 +434,26 @@
"description": "path to file containing shorthand mappings",
"type": "string"
},
"node": {
"description": "settings specific to node",
"type": "object",
"additionalProperties": false,
"properties": {
"compile": {
"type": "boolean",
"description": "do not use precompiled binaries for node"
},
"flavor": {
"type": "string",
"description": "node flavor to use, generally used for unofficial builds"
},
"mirror_url": {
"type": "string",
"description": "url to use as a mirror for node downloads",
"default": "https://nodejs.org/dist"
}
}
},
"ruby": {
"description": "settings specific to ruby",
"type": "object",
Expand Down
5 changes: 4 additions & 1 deletion src/backend/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,10 @@ pub trait Backend: Debug + Send + Sync {
false
}
})
.collect();
.collect_vec();
if versions.is_empty() {
warn!("No versions found for {}", self.id());
}
Ok(versions)
}
fn _list_remote_versions(&self) -> eyre::Result<Vec<String>>;
Expand Down
5 changes: 3 additions & 2 deletions src/cli/settings/ls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,6 @@ mod tests {
legacy_version_file = true
legacy_version_file_disable_tools = []
libgit2 = true
node_compile = false
not_found_auto_install = true
paranoid = false
pipx_uvx = false
Expand All @@ -98,6 +97,8 @@ mod tests {
vfox = false
yes = true

[node]

[ruby]
default_packages_file = "~/.default-gems"
ruby_build_repo = "https://github.com/rbenv/ruby-build.git"
Expand Down Expand Up @@ -139,7 +140,7 @@ mod tests {
legacy_version_file
legacy_version_file_disable_tools
libgit2
node_compile
node
not_found_auto_install
paranoid
pipx_uvx
Expand Down
22 changes: 17 additions & 5 deletions src/cli/settings/set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,9 @@ impl SettingsSet {
self.value.split(',').map(|s| s.to_string()).collect()
}
"libgit2" => parse_bool(&self.value)?,
"node_compile" => parse_bool(&self.value)?,
"node.compile" => parse_bool(&self.value)?,
"node.flavor" => self.value.into(),
"node.mirror_url" => self.value.into(),
"not_found_auto_install" => parse_bool(&self.value)?,
"paranoid" => parse_bool(&self.value)?,
"pipx_uvx" => parse_bool(&self.value)?,
Expand All @@ -57,6 +59,14 @@ impl SettingsSet {
"python_venv_auto_create" => parse_bool(&self.value)?,
"quiet" => parse_bool(&self.value)?,
"raw" => parse_bool(&self.value)?,
"ruby.apply_patches" => self.value.into(),
"ruby.default_packages_file" => self.value.into(),
"ruby.ruby_build_repo" => self.value.into(),
"ruby.ruby_build_opts" => self.value.into(),
"ruby.ruby_install" => parse_bool(&self.value)?,
"ruby.ruby_install_repo" => self.value.into(),
"ruby.ruby_install_opts" => self.value.into(),
"ruby.verbose_install" => parse_bool(&self.value)?,
"shorthands_file" => self.value.into(),
"status.missing_tools" => self.value.into(),
"status.show_env" => parse_bool(&self.value)?,
Expand All @@ -77,13 +87,14 @@ impl SettingsSet {
config["settings"] = toml_edit::Item::Table(toml_edit::Table::new());
}
let settings = config["settings"].as_table_mut().unwrap();
if self.setting.as_str().starts_with("status.") {
if self.setting.as_str().contains(".") {
let mut parts = self.setting.splitn(2, '.');
let status = settings
.entry("status")
.entry(parts.next().unwrap())
.or_insert(toml_edit::Item::Table(toml_edit::Table::new()))
.as_table_mut()
.unwrap();
status.insert(&self.setting[7..], toml_edit::Item::Value(value));
status.insert(parts.next().unwrap(), toml_edit::Item::Value(value));
} else {
settings.insert(&self.setting, toml_edit::Item::Value(value));
}
Expand Down Expand Up @@ -159,7 +170,6 @@ pub mod tests {
legacy_version_file = false
legacy_version_file_disable_tools = []
libgit2 = true
node_compile = false
not_found_auto_install = true
paranoid = false
pipx_uvx = false
Expand All @@ -174,6 +184,8 @@ pub mod tests {
vfox = false
yes = true

[node]

[ruby]
default_packages_file = "~/.default-gems"
ruby_build_repo = "https://github.com/rbenv/ruby-build.git"
Expand Down
3 changes: 2 additions & 1 deletion src/cli/settings/unset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,6 @@ mod tests {
legacy_version_file = true
legacy_version_file_disable_tools = []
libgit2 = true
node_compile = false
not_found_auto_install = true
paranoid = false
pipx_uvx = false
Expand All @@ -89,6 +88,8 @@ mod tests {
vfox = false
yes = true

[node]

[ruby]
default_packages_file = "~/.default-gems"
ruby_build_repo = "https://github.com/rbenv/ruby-build.git"
Expand Down
43 changes: 36 additions & 7 deletions src/config/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ use std::iter::once;
use std::path::PathBuf;
use std::sync::{Arc, Mutex, RwLock};
use std::time::Duration;
use url::Url;

pub static SETTINGS: Lazy<Arc<Settings>> = Lazy::new(Settings::get);

#[rustfmt::skip]
#[derive(Config, Default, Debug, Clone, Serialize)]
Expand Down Expand Up @@ -93,8 +96,8 @@ pub struct Settings {
pub legacy_version_file_disable_tools: BTreeSet<String>,
#[config(env = "MISE_LIBGIT2", default = true)]
pub libgit2: bool,
#[config(env = "MISE_NODE_COMPILE", default = false)]
pub node_compile: bool,
#[config(nested)]
pub node: SettingsNode,
#[config(env = "MISE_NOT_FOUND_AUTO_INSTALL", default = true)]
pub not_found_auto_install: bool,
#[config(env = "MISE_PARANOID", default = false)]
Expand Down Expand Up @@ -163,6 +166,19 @@ pub struct Settings {
pub python_venv_auto_create: bool,
}

#[derive(Config, Default, Debug, Clone, Serialize)]
#[config(partial_attr(derive(Clone, Serialize, Default)))]
#[config(partial_attr(serde(deny_unknown_fields)))]
#[rustfmt::skip]
pub struct SettingsNode {
#[config(env = "MISE_NODE_COMPILE")]
pub compile: Option<bool>,
#[config(env = "MISE_NODE_FLAVOR")]
pub flavor: Option<String>,
#[config(env = "MISE_NODE_MIRROR_URL")]
pub mirror_url: Option<String>
}

#[derive(Config, Default, Debug, Clone, Serialize)]
#[config(partial_attr(derive(Clone, Serialize, Default)))]
#[config(partial_attr(serde(deny_unknown_fields)))]
Expand Down Expand Up @@ -221,7 +237,7 @@ pub enum SettingsStatusMissingTools {

pub type SettingsPartial = <Settings as Config>::Partial;

static SETTINGS: RwLock<Option<Arc<Settings>>> = RwLock::new(None);
static BASE_SETTINGS: RwLock<Option<Arc<Settings>>> = RwLock::new(None);
static CLI_SETTINGS: Mutex<Option<SettingsPartial>> = Mutex::new(None);
static DEFAULT_SETTINGS: Lazy<SettingsPartial> = Lazy::new(|| {
let mut s = SettingsPartial::empty();
Expand All @@ -245,7 +261,7 @@ impl Settings {
Self::try_get().unwrap()
}
pub fn try_get() -> Result<Arc<Self>> {
if let Some(settings) = SETTINGS.read().unwrap().as_ref() {
if let Some(settings) = BASE_SETTINGS.read().unwrap().as_ref() {
return Ok(settings.clone());
}

Expand Down Expand Up @@ -306,13 +322,13 @@ impl Settings {
settings.yes = true;
}
if settings.all_compile {
settings.node_compile = true;
settings.node.compile = Some(true);
if settings.python_compile.is_none() {
settings.python_compile = Some(true);
}
}
let settings = Arc::new(settings);
*SETTINGS.write().unwrap() = Some(settings.clone());
*BASE_SETTINGS.write().unwrap() = Some(settings.clone());
Ok(settings)
}
pub fn add_cli_matches(m: &clap::ArgMatches) {
Expand Down Expand Up @@ -429,7 +445,7 @@ impl Settings {

pub fn reset(cli_settings: Option<SettingsPartial>) {
*CLI_SETTINGS.lock().unwrap() = cli_settings;
*SETTINGS.write().unwrap() = None;
*BASE_SETTINGS.write().unwrap() = None;
}

pub fn ensure_experimental(&self, what: &str) -> Result<()> {
Expand Down Expand Up @@ -494,3 +510,16 @@ impl Display for Settings {
pub fn ensure_experimental(what: &str) -> Result<()> {
Settings::get().ensure_experimental(what)
}

pub const DEFAULT_NODE_MIRROR_URL: &str = "https://nodejs.org/dist/";

impl SettingsNode {
pub fn mirror_url(&self) -> Url {
let s = self
.mirror_url
.clone()
.or(env::var("NODE_BUILD_MIRROR_URL").ok())
.unwrap_or_else(|| DEFAULT_NODE_MIRROR_URL.to_string());
Url::parse(&s).unwrap()
}
}
10 changes: 0 additions & 10 deletions src/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ use std::{path, process};
use itertools::Itertools;
use log::LevelFilter;
use once_cell::sync::Lazy;
use url::Url;

use crate::cli::args::ProfileArg;
use crate::duration::HOURLY;
Expand Down Expand Up @@ -173,11 +172,6 @@ pub static PYENV_ROOT: Lazy<PathBuf> =
Lazy::new(|| var_path("PYENV_ROOT").unwrap_or_else(|| HOME.join(".pyenv")));

// node
pub static MISE_NODE_MIRROR_URL: Lazy<Url> = Lazy::new(|| {
var_url("MISE_NODE_MIRROR_URL")
.or_else(|| var_url("NODE_BUILD_MIRROR_URL"))
.unwrap_or_else(|| Url::parse("https://nodejs.org/dist/").unwrap())
});
pub static MISE_NODE_CONCURRENCY: Lazy<Option<usize>> = Lazy::new(|| {
var("MISE_NODE_CONCURRENCY")
.ok()
Expand Down Expand Up @@ -279,10 +273,6 @@ pub fn var_path(key: &str) -> Option<PathBuf> {
var_os(key).map(PathBuf::from).map(replace_path)
}

fn var_url(key: &str) -> Option<Url> {
var(key).ok().map(|v| Url::parse(&v).unwrap())
}

fn var_duration(key: &str) -> Option<Duration> {
var(key)
.ok()
Expand Down
Loading
Loading