Skip to content

Commit bee4a53

Browse files
Merge pull request #1394 from charlespierce/pnpm_feature_flag
Gate pnpm support behind a feature flag to avoid compatibility issues
2 parents 640d337 + 845a6cf commit bee4a53

File tree

10 files changed

+64
-8
lines changed

10 files changed

+64
-8
lines changed

crates/volta-core/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,5 @@ pub mod sync;
2020
pub mod tool;
2121
pub mod toolchain;
2222
pub mod version;
23+
24+
const VOLTA_FEATURE_PNPM: &str = "VOLTA_FEATURE_PNPM";

crates/volta-core/src/platform/mod.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1+
use std::env;
12
use std::fmt;
23

34
use crate::error::{ErrorKind, Fallible};
45
use crate::session::Session;
56
use crate::tool::{Node, Npm, Pnpm, Yarn};
7+
use crate::VOLTA_FEATURE_PNPM;
68
use semver::Version;
79

810
mod image;
@@ -284,8 +286,13 @@ impl Platform {
284286
Npm::new(version.clone()).ensure_fetched(session)?;
285287
}
286288

287-
if let Some(Sourced { value: version, .. }) = &self.pnpm {
288-
Pnpm::new(version.clone()).ensure_fetched(session)?;
289+
// Only force download of the pnpm version if the pnpm feature flag is set. If it isn't,
290+
// then we won't be using the `Pnpm` tool to execute (we will be relying on the global
291+
// package logic), so fetching the Pnpm version would only be redundant work.
292+
if env::var_os(VOLTA_FEATURE_PNPM).is_some() {
293+
if let Some(Sourced { value: version, .. }) = &self.pnpm {
294+
Pnpm::new(version.clone()).ensure_fetched(session)?;
295+
}
289296
}
290297

291298
if let Some(Sourced { value: version, .. }) = &self.yarn {

crates/volta-core/src/run/mod.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use std::process::ExitStatus;
77
use crate::error::{ErrorKind, Fallible};
88
use crate::platform::{CliPlatform, Image, Sourced};
99
use crate::session::Session;
10+
use crate::VOLTA_FEATURE_PNPM;
1011
use log::debug;
1112
use semver::Version;
1213

@@ -85,7 +86,16 @@ fn get_executor(
8586
Some("node") => node::command(args, session),
8687
Some("npm") => npm::command(args, session),
8788
Some("npx") => npx::command(args, session),
88-
Some("pnpm") => pnpm::command(args, session),
89+
Some("pnpm") => {
90+
// If the pnpm feature flag variable is set, delegate to the pnpm handler
91+
// If not, use the binary handler as a fallback (prior to pnpm support, installing
92+
// pnpm would be handled the same as any other global binary)
93+
if env::var_os(VOLTA_FEATURE_PNPM).is_some() {
94+
pnpm::command(args, session)
95+
} else {
96+
binary::command(exe, args, session)
97+
}
98+
}
8999
Some("yarn") => yarn::command(args, session),
90100
_ => binary::command(exe, args, session),
91101
}

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

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1+
use std::env;
12
use std::fmt::{self, Display};
23

34
use crate::error::{ErrorKind, Fallible};
45
use crate::session::Session;
56
use crate::style::{note_prefix, success_prefix, tool_version};
67
use crate::sync::VoltaLock;
78
use crate::version::VersionSpec;
9+
use crate::VOLTA_FEATURE_PNPM;
810
use log::{debug, info};
911

1012
pub mod node;
@@ -87,8 +89,17 @@ impl Spec {
8789
None => Ok(Box::new(BundledNpm)),
8890
},
8991
Spec::Pnpm(version) => {
90-
let version = pnpm::resolve(version, session)?;
91-
Ok(Box::new(Pnpm::new(version)))
92+
// If the pnpm feature flag is set, use the special-cased package manager logic
93+
// to handle resolving (and ultimately fetching / installing) pnpm. If not, then
94+
// fall back to the global package behavior, which was the case prior to pnpm
95+
// support being added
96+
if env::var_os(VOLTA_FEATURE_PNPM).is_some() {
97+
let version = pnpm::resolve(version, session)?;
98+
Ok(Box::new(Pnpm::new(version)))
99+
} else {
100+
let package = Package::new("pnpm".to_owned(), version)?;
101+
Ok(Box::new(package))
102+
}
92103
}
93104
Spec::Yarn(version) => {
94105
let version = yarn::resolve(version, session)?;
@@ -116,10 +127,16 @@ impl Spec {
116127
feature: "Uninstalling npm".into(),
117128
}
118129
.into()),
119-
Spec::Pnpm(_) => Err(ErrorKind::Unimplemented {
120-
feature: "Uninstalling pnpm".into(),
130+
Spec::Pnpm(_) => {
131+
if env::var_os(VOLTA_FEATURE_PNPM).is_some() {
132+
Err(ErrorKind::Unimplemented {
133+
feature: "Uninstalling pnpm".into(),
134+
}
135+
.into())
136+
} else {
137+
package::uninstall("pnpm")
138+
}
121139
}
122-
.into()),
123140
Spec::Yarn(_) => Err(ErrorKind::Unimplemented {
124141
feature: "Uninstalling yarn".into(),
125142
}

tests/acceptance/corrupted_download.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ fn install_corrupted_pnpm_leaves_inventory_unchanged() {
108108
.pnpm_available_versions(PNPM_VERSION_INFO)
109109
.distro_mocks::<NodeFixture>(&NODE_VERSION_FIXTURES)
110110
.distro_mocks::<PnpmFixture>(&PNPM_VERSION_FIXTURES)
111+
.env("VOLTA_FEATURE_PNPM", "1")
111112
.build();
112113

113114
assert_that!(
@@ -126,6 +127,7 @@ fn install_valid_pnpm_saves_to_inventory() {
126127
.pnpm_available_versions(PNPM_VERSION_INFO)
127128
.distro_mocks::<NodeFixture>(&NODE_VERSION_FIXTURES)
128129
.distro_mocks::<PnpmFixture>(&PNPM_VERSION_FIXTURES)
130+
.env("VOLTA_FEATURE_PNPM", "1")
129131
.build();
130132

131133
assert_that!(

tests/acceptance/hooks.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,7 @@ fn pnpm_latest_with_hook_reads_index() {
342342
let s = sandbox()
343343
.default_hooks(&pnpm_hooks_json())
344344
.env("VOLTA_LOGLEVEL", "debug")
345+
.env("VOLTA_FEATURE_PNPM", "1")
345346
.build();
346347
let _mock = mock("GET", "/pnpm/index")
347348
.with_status(200)
@@ -376,6 +377,7 @@ fn pnpm_no_version_with_hook_reads_index() {
376377
let s = sandbox()
377378
.default_hooks(&pnpm_hooks_json())
378379
.env("VOLTA_LOGLEVEL", "debug")
380+
.env("VOLTA_FEATURE_PNPM", "1")
379381
.build();
380382
let _mock = mock("GET", "/pnpm/index")
381383
.with_status(200)

tests/acceptance/merged_platform.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,7 @@ fn uses_project_pnpm_if_available() {
381381
.distro_mocks::<PnpmFixture>(&PNPM_VERSION_FIXTURES)
382382
.env("VOLTA_LOGLEVEL", "debug")
383383
.env("VOLTA_WRITE_EVENTS_FILE", "true")
384+
.env("VOLTA_FEATURE_PNPM", "1")
384385
.default_hooks(&events_hooks_json())
385386
.executable_file(SCRIPT_FILENAME, EVENTS_EXECUTABLE)
386387
.build();
@@ -417,6 +418,7 @@ fn uses_default_pnpm_in_project_without_pnpm() {
417418
.distro_mocks::<NodeFixture>(&NODE_VERSION_FIXTURES)
418419
.distro_mocks::<PnpmFixture>(&PNPM_VERSION_FIXTURES)
419420
.env("VOLTA_LOGLEVEL", "debug")
421+
.env("VOLTA_FEATURE_PNPM", "1")
420422
.build();
421423

422424
assert_that!(
@@ -436,6 +438,7 @@ fn uses_default_pnpm_outside_project() {
436438
.distro_mocks::<NodeFixture>(&NODE_VERSION_FIXTURES)
437439
.distro_mocks::<PnpmFixture>(&PNPM_VERSION_FIXTURES)
438440
.env("VOLTA_LOGLEVEL", "debug")
441+
.env("VOLTA_FEATURE_PNPM", "1")
439442
.build();
440443

441444
assert_that!(
@@ -453,6 +456,7 @@ fn uses_pnpm_throws_project_error_in_project() {
453456
let s = sandbox()
454457
.platform(PLATFORM_NODE_ONLY)
455458
.package_json(PACKAGE_JSON_NODE_ONLY)
459+
.env("VOLTA_FEATURE_PNPM", "1")
456460
.build();
457461

458462
assert_that!(

tests/acceptance/volta_install.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,7 @@ fn install_pnpm_without_node_errors() {
335335
let s = sandbox()
336336
.pnpm_available_versions(PNPM_VERSION_INFO)
337337
.distro_mocks::<PnpmFixture>(&PNPM_VERSION_FIXTURES)
338+
.env("VOLTA_FEATURE_PNPM", "1")
338339
.build();
339340

340341
assert_that!(

tests/acceptance/volta_pin.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -954,6 +954,7 @@ fn pin_pnpm_no_node() {
954954
.package_json(BASIC_PACKAGE_JSON)
955955
.pnpm_available_versions(PNPM_VERSION_INFO)
956956
.distro_mocks::<PnpmFixture>(&PNPM_VERSION_FIXTURES)
957+
.env("VOLTA_FEATURE_PNPM", "1")
957958
.build();
958959

959960
assert_that!(
@@ -974,6 +975,7 @@ fn pin_pnpm() {
974975
.package_json(&package_json_with_pinned_node("1.2.3"))
975976
.pnpm_available_versions(PNPM_VERSION_INFO)
976977
.distro_mocks::<PnpmFixture>(&PNPM_VERSION_FIXTURES)
978+
.env("VOLTA_FEATURE_PNPM", "1")
977979
.build();
978980

979981
assert_that!(
@@ -994,6 +996,7 @@ fn pin_pnpm_reports_info() {
994996
.pnpm_available_versions(PNPM_VERSION_INFO)
995997
.distro_mocks::<PnpmFixture>(&PNPM_VERSION_FIXTURES)
996998
.env(VOLTA_LOGLEVEL, "info")
999+
.env("VOLTA_FEATURE_PNPM", "1")
9971000
.build();
9981001

9991002
assert_that!(
@@ -1010,6 +1013,7 @@ fn pin_pnpm_latest() {
10101013
.package_json(&package_json_with_pinned_node("1.2.3"))
10111014
.pnpm_available_versions(PNPM_VERSION_INFO)
10121015
.distro_mocks::<PnpmFixture>(&PNPM_VERSION_FIXTURES)
1016+
.env("VOLTA_FEATURE_PNPM", "1")
10131017
.build();
10141018

10151019
assert_that!(
@@ -1029,6 +1033,7 @@ fn pin_pnpm_no_version() {
10291033
.package_json(&package_json_with_pinned_node("1.2.3"))
10301034
.pnpm_available_versions(PNPM_VERSION_INFO)
10311035
.distro_mocks::<PnpmFixture>(&PNPM_VERSION_FIXTURES)
1036+
.env("VOLTA_FEATURE_PNPM", "1")
10321037
.build();
10331038

10341039
assert_that!(
@@ -1046,6 +1051,7 @@ fn pin_pnpm_no_version() {
10461051
fn pin_pnpm_missing_release() {
10471052
let s = sandbox()
10481053
.package_json(&package_json_with_pinned_node("1.2.3"))
1054+
.env("VOLTA_FEATURE_PNPM", "1")
10491055
.mock_not_found()
10501056
.build();
10511057

@@ -1070,6 +1076,7 @@ fn pin_node_and_pnpm() {
10701076
.distro_mocks::<NodeFixture>(&NODE_VERSION_FIXTURES)
10711077
.pnpm_available_versions(PNPM_VERSION_INFO)
10721078
.distro_mocks::<PnpmFixture>(&PNPM_VERSION_FIXTURES)
1079+
.env("VOLTA_FEATURE_PNPM", "1")
10731080
.build();
10741081

10751082
assert_that!(
@@ -1089,6 +1096,7 @@ fn pin_pnpm_leaves_npm() {
10891096
.package_json(&package_json_with_pinned_node_npm("1.2.3", "3.4.5"))
10901097
.pnpm_available_versions(PNPM_VERSION_INFO)
10911098
.distro_mocks::<PnpmFixture>(&PNPM_VERSION_FIXTURES)
1099+
.env("VOLTA_FEATURE_PNPM", "1")
10921100
.build();
10931101

10941102
assert_that!(

tests/acceptance/volta_run.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -459,6 +459,7 @@ fn command_line_pnpm() {
459459
.pnpm_available_versions(PNPM_VERSION_INFO)
460460
.distro_mocks::<PnpmFixture>(&PNPM_VERSION_FIXTURES)
461461
.env(VOLTA_LOGLEVEL, "debug")
462+
.env("VOLTA_FEATURE_PNPM", "1")
462463
.build();
463464

464465
assert_that!(
@@ -478,6 +479,7 @@ fn inherited_pnpm() {
478479
.distro_mocks::<PnpmFixture>(&PNPM_VERSION_FIXTURES)
479480
.package_json(&package_json_with_pinned_node_pnpm("10.99.1040", "7.7.1"))
480481
.env(VOLTA_LOGLEVEL, "debug")
482+
.env("VOLTA_FEATURE_PNPM", "1")
481483
.build();
482484

483485
assert_that!(
@@ -497,6 +499,7 @@ fn force_no_pnpm() {
497499
.distro_mocks::<PnpmFixture>(&PNPM_VERSION_FIXTURES)
498500
.package_json(&package_json_with_pinned_node_pnpm("10.99.1040", "7.7.1"))
499501
.env(VOLTA_LOGLEVEL, "debug")
502+
.env("VOLTA_FEATURE_PNPM", "1")
500503
.build();
501504

502505
assert_that!(

0 commit comments

Comments
 (0)