Skip to content

Commit 5df8b5f

Browse files
committed
feat(pnpm): consider workspace protocol valid by default
Closes #252
1 parent 64aa8bf commit 5df8b5f

File tree

3 files changed

+86
-1
lines changed

3 files changed

+86
-1
lines changed

src/rcfile.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@ fn default_true() -> bool {
2424
true
2525
}
2626

27+
fn default_false() -> bool {
28+
false
29+
}
30+
2731
fn default_indent() -> String {
2832
" ".to_string()
2933
}
@@ -118,6 +122,8 @@ pub struct Rcfile {
118122
pub sort_packages: bool,
119123
#[serde(default = "default_source")]
120124
pub source: Vec<String>,
125+
#[serde(default = "default_false")]
126+
pub strict: bool,
121127
#[serde(default)]
122128
pub version_groups: Vec<AnyVersionGroup>,
123129
}
@@ -137,6 +143,7 @@ impl Rcfile {
137143
sort_first: sort_first(),
138144
sort_packages: default_true(),
139145
source: default_source(),
146+
strict: default_false(),
140147
version_groups: vec![],
141148
}
142149
}

src/visit_packages.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use {
99
format,
1010
instance_state::{FixableInstance::*, SemverGroupAndVersionConflict::*, SuspectInstance::*, UnfixableInstance::*, ValidInstance::*},
1111
package_json::{FormatMismatch, FormatMismatchVariant::*, PackageJson},
12-
specifier::{semver_range::SemverRange, Specifier},
12+
specifier::{non_semver::NonSemver, semver_range::SemverRange, Specifier},
1313
version_group::VersionGroupVariant,
1414
},
1515
itertools::Itertools,
@@ -89,6 +89,18 @@ pub fn visit_packages(ctx: Context) -> Context {
8989
return;
9090
}
9191
debug!(" it depends on the local instance");
92+
if matches!(instance.actual_specifier, Specifier::NonSemver(NonSemver::WorkspaceProtocol(_))) {
93+
debug!(" it is using the workspace protocol");
94+
if !ctx.config.rcfile.strict {
95+
debug!(" strict mode is off");
96+
debug!(" mark as satisfying local");
97+
instance.mark_valid(SatisfiesLocal, &instance.actual_specifier);
98+
return;
99+
}
100+
debug!(" strict mode is on");
101+
} else {
102+
debug!(" it is not using the workspace protocol");
103+
}
92104
debug!(" its version number (without a range):");
93105
if !instance.actual_specifier.has_same_version_number_as(&local_specifier) {
94106
debug!(" differs to the local instance");

src/visit_packages_test.rs

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1292,6 +1292,72 @@ fn no_instances_are_semver_and_they_differ() {
12921292
]);
12931293
}
12941294

1295+
#[test]
1296+
fn workspace_protocol_version_differs_to_local_version_is_invalid_in_strict_mode() {
1297+
let config = test::mock::config_from_mock(json!({
1298+
"strict": true
1299+
}));
1300+
let packages = test::mock::packages_from_mocks(vec![json!({
1301+
"name": "package-a",
1302+
"version": "1.0.0",
1303+
"devDependencies": {
1304+
"package-a": "workspace:*"
1305+
}
1306+
})]);
1307+
let ctx = Context::create(config, packages);
1308+
let ctx = visit_packages(ctx);
1309+
expect(&ctx).to_have_instances(vec![
1310+
ExpectedInstance {
1311+
state: InstanceState::valid(IsLocalAndValid),
1312+
dependency_name: "package-a",
1313+
id: "package-a in /version of package-a",
1314+
actual: "1.0.0",
1315+
expected: Some("1.0.0"),
1316+
overridden: None,
1317+
},
1318+
ExpectedInstance {
1319+
state: InstanceState::fixable(DiffersToLocal),
1320+
dependency_name: "package-a",
1321+
id: "package-a in /devDependencies of package-a",
1322+
actual: "workspace:*",
1323+
expected: Some("1.0.0"),
1324+
overridden: None,
1325+
},
1326+
]);
1327+
}
1328+
1329+
#[test]
1330+
fn workspace_protocol_version_differs_to_local_version_is_valid_by_default() {
1331+
let config = test::mock::config_from_mock(json!({}));
1332+
let packages = test::mock::packages_from_mocks(vec![json!({
1333+
"name": "package-a",
1334+
"version": "1.0.0",
1335+
"devDependencies": {
1336+
"package-a": "workspace:*"
1337+
}
1338+
})]);
1339+
let ctx = Context::create(config, packages);
1340+
let ctx = visit_packages(ctx);
1341+
expect(&ctx).to_have_instances(vec![
1342+
ExpectedInstance {
1343+
state: InstanceState::valid(IsLocalAndValid),
1344+
dependency_name: "package-a",
1345+
id: "package-a in /version of package-a",
1346+
actual: "1.0.0",
1347+
expected: Some("1.0.0"),
1348+
overridden: None,
1349+
},
1350+
ExpectedInstance {
1351+
state: InstanceState::valid(SatisfiesLocal),
1352+
dependency_name: "package-a",
1353+
id: "package-a in /devDependencies of package-a",
1354+
actual: "workspace:*",
1355+
expected: Some("workspace:*"),
1356+
overridden: None,
1357+
},
1358+
]);
1359+
}
1360+
12951361
// = Ignored Version Group =====================================================
12961362

12971363
#[test]

0 commit comments

Comments
 (0)