Skip to content

Commit 52da2c8

Browse files
Ben Demboskibestander
authored andcommitted
Fix #1435 (failing dependencies of optional dependencies) (#2811)
* Fix #1435 (failing dependencies of optional dependencies) Mark all dependencies of optional dependencies as themselves optional, so that if they fail, the whole install process doesn't fail. * Update tests Add a test to make sure code marking sub-dependencies as optional doesn't do so when another dependency marks it as non-optional, and convert a test (plus a pre-existing one) to use file: URIs instead of offline mirroring, for readability.
1 parent 06bd1fe commit 52da2c8

File tree

26 files changed

+171
-2
lines changed

26 files changed

+171
-2
lines changed

__tests__/commands/install/integration.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -894,6 +894,14 @@ test.concurrent('install a module with incompatible optional dependency should s
894894
});
895895
});
896896

897+
test.concurrent('install a module with optional dependency should skip incompatible transient dependency',
898+
(): Promise<void> => {
899+
return runInstall({}, 'install-should-skip-incompatible-optional-sub-dep', async (config) => {
900+
assert.ok(await fs.exists(path.join(config.cwd, 'node_modules', 'dep-optional')));
901+
assert.ok(!(await fs.exists(path.join(config.cwd, 'node_modules', 'dep-incompatible'))));
902+
});
903+
});
904+
897905
// this tests for a problem occuring due to optional dependency incompatible with os, in this case fsevents
898906
// this would fail on os's incompatible with fsevents, which is everything except osx.
899907
if (process.platform !== 'darwin') {
@@ -914,6 +922,14 @@ test.concurrent('optional dependency that fails to build should not be installed
914922
});
915923
});
916924

925+
test.concurrent('failing dependency of optional dependency should not be installed',
926+
(): Promise<void> => {
927+
return runInstall({}, 'should-not-install-failing-deps-of-optional-deps', async (config) => {
928+
assert.equal(await fs.exists(path.join(config.cwd, 'node_modules', 'optional-dep')), true);
929+
assert.equal(await fs.exists(path.join(config.cwd, 'node_modules', 'sub-failing')), false);
930+
});
931+
});
932+
917933
// Covers current behavior, issue opened whether this should be changed https://github.com/yarnpkg/yarn/issues/2274
918934
test.concurrent('a subdependency of an optional dependency that fails should be installed',
919935
(): Promise<void> => {
@@ -923,6 +939,19 @@ test.concurrent('a subdependency of an optional dependency that fails should be
923939
});
924940
});
925941

942+
test.concurrent('a sub-dependency should be non-optional if any parents mark it non-optional',
943+
async (): Promise<void> => {
944+
let thrown = false;
945+
try {
946+
await runInstall({}, 'failing-sub-dep-optional-and-normal', () => {});
947+
} catch (err) {
948+
thrown = true;
949+
expect(err.message).toContain('sub-failing: Command failed');
950+
}
951+
assert(thrown);
952+
});
953+
954+
926955
test.concurrent('should not loose dependencies when installing with --production',
927956
(): Promise<void> => {
928957
// revealed https://github.com/yarnpkg/yarn/issues/2263
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
process.exit(0);
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"name": "normal-dep",
3+
"version": "0.0.0",
4+
"scripts": {
5+
"install": "node install.js"
6+
},
7+
"dependencies": {
8+
"sub-failing": "file:../sub-failing"
9+
}
10+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
process.exit(0);
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"name": "optional-dep",
3+
"version": "0.0.0",
4+
"scripts": {
5+
"install": "node install.js"
6+
},
7+
"dependencies": {
8+
"sub-failing": "file:../sub-failing"
9+
}
10+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"dependencies": {
3+
"normal-dep": "file:normal-dep"
4+
},
5+
"optionalDependencies": {
6+
"optional-dep": "file:optional-dep"
7+
}
8+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
process.exit(1);
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"name": "sub-failing",
3+
"version": "0.0.0",
4+
"scripts": {
5+
"install": "node install.js"
6+
}
7+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"name": "dep-a",
3+
"version": "1.0.0",
4+
"description": "",
5+
"main": "index.js",
6+
"scripts": {
7+
"postinstall": "mkdir lib"
8+
},
9+
"keywords": [],
10+
"author": "",
11+
"license": "ISC"
12+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"name": "dep-incompatible",
3+
"version": "1.0.0",
4+
"description": "",
5+
"main": "index.js",
6+
"scripts": {
7+
"postinstall": "mkdir lib"
8+
},
9+
"dependencies": {
10+
"dep-a": "file:../dep-a"
11+
},
12+
"os": [
13+
"invalid"
14+
],
15+
"keywords": [],
16+
"author": "",
17+
"license": "ISC"
18+
}

0 commit comments

Comments
 (0)