Skip to content

Commit fb84ced

Browse files
authored
Merge pull request #915 from charlespierce/check_arch
[Small] Check Node OS & Arch availability and support M1 native builds
2 parents 21c8fa0 + 859028a commit fb84ced

File tree

3 files changed

+71
-67
lines changed

3 files changed

+71
-67
lines changed

crates/volta-core/src/tool/node/metadata.rs

Lines changed: 17 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,21 @@
11
use std::collections::HashSet;
2-
use std::str::FromStr;
32

3+
use super::NODE_DISTRO_IDENTIFIER;
44
use crate::version::{option_version_serde, version_serde};
55
use semver::Version;
66
use serde::{Deserialize, Deserializer};
7-
use serde_json::Error;
87

98
/// The index of the public Node server.
109
pub struct NodeIndex {
1110
pub(super) entries: Vec<NodeEntry>,
1211
}
1312

14-
impl FromStr for NodeIndex {
15-
type Err = Error;
16-
17-
fn from_str(s: &str) -> Result<Self, Self::Err> {
18-
let raw: RawNodeIndex = serde_json::de::from_str(s)?;
19-
Ok(raw.into())
20-
}
21-
}
22-
2313
#[derive(Debug)]
2414
pub struct NodeEntry {
2515
pub version: Version,
26-
pub npm: Version,
27-
pub files: NodeDistroFiles,
2816
pub lts: bool,
2917
}
3018

31-
/// The set of available files on the public Node server for a given Node version.
32-
#[derive(Debug)]
33-
pub struct NodeDistroFiles {
34-
pub files: HashSet<String>,
35-
}
36-
3719
#[derive(Deserialize)]
3820
pub struct RawNodeIndex(Vec<RawNodeEntry>);
3921

@@ -44,27 +26,28 @@ pub struct RawNodeEntry {
4426
#[serde(default)] // handles Option
4527
#[serde(with = "option_version_serde")]
4628
npm: Option<Version>,
47-
files: Vec<String>,
29+
files: HashSet<String>,
4830
#[serde(deserialize_with = "lts_version_serde")]
4931
lts: bool,
5032
}
5133

5234
impl From<RawNodeIndex> for NodeIndex {
5335
fn from(raw: RawNodeIndex) -> NodeIndex {
54-
let mut entries = Vec::new();
55-
for entry in raw.0 {
56-
if let Some(npm) = entry.npm {
57-
let data = NodeDistroFiles {
58-
files: entry.files.into_iter().collect(),
59-
};
60-
entries.push(NodeEntry {
61-
version: entry.version,
62-
npm,
63-
files: data,
64-
lts: entry.lts,
65-
});
66-
}
67-
}
36+
let entries = raw
37+
.0
38+
.into_iter()
39+
.filter_map(|entry| {
40+
if entry.npm.is_some() && entry.files.contains(NODE_DISTRO_IDENTIFIER) {
41+
Some(NodeEntry {
42+
version: entry.version,
43+
lts: entry.lts,
44+
})
45+
} else {
46+
None
47+
}
48+
})
49+
.collect();
50+
6851
NodeIndex { entries }
6952
}
7053
}

crates/volta-core/src/tool/node/mod.rs

Lines changed: 54 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -21,45 +21,67 @@ pub use fetch::load_default_npm_version;
2121
pub use resolve::resolve;
2222

2323
cfg_if! {
24-
if #[cfg(target_os = "windows")] {
25-
/// The OS component of a Node distro's filename.
24+
if #[cfg(all(target_os = "windows", target_arch = "x86"))] {
25+
/// The OS component of a Node distro filename
2626
pub const NODE_DISTRO_OS: &str = "win";
27-
} else if #[cfg(target_os = "macos")] {
28-
/// The OS component of a Node distro's filename.
27+
/// The architecture component of a Node distro filename
28+
pub const NODE_DISTRO_ARCH: &str = "x86";
29+
/// The extension for Node distro files
30+
pub const NODE_DISTRO_EXTENSION: &str = "zip";
31+
/// The file identifier in the Node index `files` array
32+
pub const NODE_DISTRO_IDENTIFIER: &str = "win-x86-zip";
33+
} else if #[cfg(all(target_os = "windows", target_arch = "x86_64"))] {
34+
/// The OS component of a Node distro filename
35+
pub const NODE_DISTRO_OS: &str = "win";
36+
/// The architecture component of a Node distro filename
37+
pub const NODE_DISTRO_ARCH: &str = "x64";
38+
/// The extension for Node distro files
39+
pub const NODE_DISTRO_EXTENSION: &str = "zip";
40+
/// The file identifier in the Node index `files` array
41+
pub const NODE_DISTRO_IDENTIFIER: &str = "win-x64-zip";
42+
} else if #[cfg(all(target_os = "macos", any(target_arch = "x86_64", target_arch = "aarch64")))] {
43+
// NOTE: Currently, Node does not provide prebuilt binaries for Apple M1 machines, so we
44+
// fall back to using the x64 binaries through Rosetta 2. When Node starts shipping M1
45+
// binaries, then we will need to adjust our logic to search for those first and only fall
46+
// back if they aren't found
47+
48+
/// The OS component of a Node distro filename
2949
pub const NODE_DISTRO_OS: &str = "darwin";
30-
} else if #[cfg(target_os = "linux")] {
31-
/// The OS component of a Node distro's filename.
50+
/// The architecture component of a Node distro filename
51+
pub const NODE_DISTRO_ARCH: &str = "x64";
52+
/// The extension for Node distro files
53+
pub const NODE_DISTRO_EXTENSION: &str = "tar.gz";
54+
/// The file identifier in the Node index `files` array
55+
pub const NODE_DISTRO_IDENTIFIER: &str = "osx-x64-tar";
56+
} else if #[cfg(all(target_os = "linux", target_arch = "x86_64"))] {
57+
/// The OS component of a Node distro filename
3258
pub const NODE_DISTRO_OS: &str = "linux";
33-
} else {
34-
compile_error!("Unsupported operating system (expected Windows, macOS, or Linux).");
35-
}
36-
}
37-
38-
cfg_if! {
39-
if #[cfg(target_arch = "x86")] {
40-
/// The system architecture component of a Node distro's name.
41-
pub const NODE_DISTRO_ARCH: &str = "x86";
42-
} else if #[cfg(target_arch = "x86_64")] {
43-
/// The system architecture component of a Node distro's name.
59+
/// The architecture component of a Node distro filename
4460
pub const NODE_DISTRO_ARCH: &str = "x64";
45-
} else if #[cfg(target_arch = "aarch64")] {
46-
/// The system architecture component of a Node distro's name.
61+
/// The extension for Node distro files
62+
pub const NODE_DISTRO_EXTENSION: &str = "tar.gz";
63+
/// The file identifier in the Node index `files` array
64+
pub const NODE_DISTRO_IDENTIFIER: &str = "linux-x64";
65+
} else if #[cfg(all(target_os = "linux", target_arch = "aarch64"))] {
66+
/// The OS component of a Node distro filename
67+
pub const NODE_DISTRO_OS: &str = "linux";
68+
/// The architecture component of a Node distro filename
4769
pub const NODE_DISTRO_ARCH: &str = "arm64";
48-
} else if #[cfg(target_arch = "arm")] {
49-
/// The system architecture component of a Node distro's name.
70+
/// The extension for Node distro files
71+
pub const NODE_DISTRO_EXTENSION: &str = "tar.gz";
72+
/// The file identifier in the Node index `files` array
73+
pub const NODE_DISTRO_IDENTIFIER: &str = "linux-arm64";
74+
} else if #[cfg(all(target_os = "linux", target_arch = "arm"))] {
75+
/// The OS component of a Node distro filename
76+
pub const NODE_DISTRO_OS: &str = "linux";
77+
/// The architecture component of a Node distro filename
5078
pub const NODE_DISTRO_ARCH: &str = "armv7l";
51-
} else {
52-
compile_error!("Unsupported target_arch variant (expected 'x86', 'x64', or 'aarch64').");
53-
}
54-
}
55-
56-
cfg_if! {
57-
if #[cfg(target_os = "windows")] {
58-
/// Filename extension for Node distro files.
59-
pub const NODE_DISTRO_EXTENSION: &str = "zip";
60-
} else {
61-
/// Filename extension for Node distro files.
79+
/// The extension for Node distro files
6280
pub const NODE_DISTRO_EXTENSION: &str = "tar.gz";
81+
/// The file identifier in the Node index `files` array
82+
pub const NODE_DISTRO_IDENTIFIER: &str = "linux-armv7l";
83+
} else {
84+
compile_error!("Unsuppored operating system + architecture combination");
6385
}
6486
}
6587

crates/volta-core/src/tool/node/resolve.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,6 @@ fn resolve_lts(hooks: Option<&ToolHooks<Node>>) -> Fallible<Version> {
106106
}
107107

108108
fn resolve_semver(matching: VersionReq, hooks: Option<&ToolHooks<Node>>) -> Fallible<Version> {
109-
// ISSUE #34: also make sure this OS is available for this version
110109
let url = match hooks {
111110
Some(&ToolHooks {
112111
index: Some(ref hook),

0 commit comments

Comments
 (0)