Skip to content
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
60 changes: 51 additions & 9 deletions packages/turbo-workspaces/__tests__/utils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,14 @@ describe("utils", () => {
["pnpm", "9.12.3"],
["yarn", "4.5.0+sha224.abc"],
["bun", "1.1.0"],
["nub", "0.1.0"]
["nub", "0.1.0"],
["pnpm", "^9.0.0"],
["pnpm", "9"],
["pnpm", ">=9.0.0 <10.0.0"],
["pnpm", ">=9.0.0 <10.0.0 || >=9.5.0 <10.0.0"],
["pnpm", "^6.35.1"],
["yarn", "^4.0.0"],
["yarn", "^1.22.0"]
] as const)("reads %s from devEngines.packageManager", (name, version) => {
const workspaceRoot = makeWorkspace({
devEngines: {
Expand Down Expand Up @@ -164,34 +171,69 @@ describe("utils", () => {
"version` must not contain"
],
[
{ devEngines: { packageManager: { name: "pnpm", version: "^9.0.0" } } },
"exact semantic version"
{
devEngines: {
packageManager: {
name: "pnpm",
version: "https://registry.npmjs.org/pnpm/-/pnpm-9.12.3.tgz"
}
}
},
"valid semantic version range"
],
[
{
devEngines: {
packageManager: {
name: "pnpm",
version: "https://registry.npmjs.org/pnpm/-/pnpm-9.12.3.tgz"
version: "9.12.3+sha512.Purxi/Zex=="
}
}
},
"exact semantic version"
"valid semantic version range"
],
[
{ devEngines: { packageManager: { name: "pnpm", version: "9" } } },
"exact semantic version"
{
devEngines: {
packageManager: { name: "pnpm", version: ">=1.0.0 <1.0.0" }
}
},
"at least one version"
],
[
{
devEngines: {
packageManager: {
name: "pnpm",
version: "9.12.3+sha512.Purxi/Zex=="
version: "9 || >=1.0.0 <1.0.0"
}
}
},
"exact semantic version"
"at least one version"
],
[
{ devEngines: { packageManager: { name: "pnpm", version: "*" } } },
"one major version"
],
[
{
devEngines: { packageManager: { name: "pnpm", version: ">=9.0.0" } }
},
"one major version"
],
[
{
devEngines: {
packageManager: { name: "pnpm", version: ">=6.0.0 <10.0.0" }
}
},
"one major version"
],
[
{
devEngines: { packageManager: { name: "pnpm", version: "9 || 10" } }
},
"one major version"
]
])(
"rejects invalid devEngines.packageManager %#",
Expand Down
34 changes: 27 additions & 7 deletions packages/turbo-workspaces/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,6 @@ const SUPPORTED_PACKAGE_MANAGERS = new Set<PackageManager>([
"nub",
"aube"
]);
const DEV_ENGINES_VERSION_REGEX =
/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?$/;

function getPackageJson({
workspaceRoot
Expand Down Expand Up @@ -189,15 +187,37 @@ function getWorkspacePackageManager({
);
}

if (
!DEV_ENGINES_VERSION_REGEX.test(version) ||
semver.valid(version) === null
) {
if (semver.validRange(version) === null) {
throw invalidDevEnginesPackageManager(
"`devEngines.packageManager.version` must be an exact semantic version"
"`devEngines.packageManager.version` must be a valid semantic version range"
);
}

const minVersion = semver.minVersion(version);
if (minVersion === null) {
throw invalidDevEnginesPackageManager(
"`devEngines.packageManager.version` must admit at least one version"
);
}

for (const disjunct of version.split("||")) {
const disjunctMinVersion = semver.minVersion(disjunct.trim());
if (disjunctMinVersion === null) {
throw invalidDevEnginesPackageManager(
"`devEngines.packageManager.version` must admit at least one version"
);
}

if (
disjunctMinVersion.major !== minVersion.major ||
semver.satisfies(`${disjunctMinVersion.major + 1}.0.0`, disjunct.trim())
) {
throw invalidDevEnginesPackageManager(
"`devEngines.packageManager.version` must only allow versions within one major version"
);
}
}

return name;
}

Expand Down
Loading