Skip to content

Commit

Permalink
Fix: nested relative link: protocal dependency symlinks (#3605)
Browse files Browse the repository at this point in the history
* Add test case for broken nested symlinks using link: protocol

* attempt fix by borrowing logic from file-resolver

* make flow-type happy
  • Loading branch information
stipsan authored and bestander committed Jun 26, 2017
1 parent 576687b commit a7e6efe
Showing 7 changed files with 78 additions and 1 deletion.
19 changes: 19 additions & 0 deletions __tests__/commands/install/integration.js
Original file line number Diff line number Diff line change
@@ -124,6 +124,25 @@ test.concurrent(
},
);

test.concurrent(
'resolves the symlinks of other symlinked packages relative to the package using the link: protocol',
async () => {
await runInstall({}, 'install-link-nested', async (config): Promise<void> => {
const expectPath = path.join(config.cwd, 'node_modules', 'b');

const stat = await fs.lstat(expectPath);
expect(stat.isSymbolicLink()).toEqual(true);

const target = await fs.readlink(expectPath);
if (process.platform !== 'win32') {
expect(target).toEqual('../a/b');
} else {
expect(target).toMatch(/[\\\/]b[\\\/]$/);
}
});
},
);

test('changes the cache path when bumping the cache version', async () => {
await runInstall({}, 'install-github', async (config): Promise<void> => {
const inOut = new stream.PassThrough();
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
b;
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"name": "b",
"version": "0.0.0",
"main": "index.js"
}
1 change: 1 addition & 0 deletions __tests__/fixtures/install/install-link-nested/a/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
a;
8 changes: 8 additions & 0 deletions __tests__/fixtures/install/install-link-nested/a/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"name": "a",
"version": "0.0.0",
"main": "index.js",
"dependencies": {
"b": "link:b"
}
}
5 changes: 5 additions & 0 deletions __tests__/fixtures/install/install-link-nested/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"dependencies": {
"a": "link:a"
}
}
40 changes: 39 additions & 1 deletion src/resolvers/exotics/link-resolver.js
Original file line number Diff line number Diff line change
@@ -9,6 +9,10 @@ import * as fs from '../../util/fs.js';

const path = require('path');

type Dependencies = {
[key: string]: string,
};

export default class LinkResolver extends ExoticResolver {
constructor(request: PackageRequest, fragment: string) {
super(request, fragment);
@@ -41,6 +45,40 @@ export default class LinkResolver extends ExoticResolver {

manifest._uid = manifest.version;

return manifest;
// Normalize relative paths; if anything changes, make a copy of the manifest
const dependencies = this.normalizeDependencyPaths(manifest.dependencies, loc);
const optionalDependencies = this.normalizeDependencyPaths(manifest.optionalDependencies, loc);

if (dependencies !== manifest.dependencies || optionalDependencies !== manifest.optionalDependencies) {
const _manifest = Object.assign({}, manifest);
if (dependencies != null) {
_manifest.dependencies = dependencies;
}
if (optionalDependencies != null) {
_manifest.optionalDependencies = optionalDependencies;
}
return _manifest;
} else {
return manifest;
}
}

normalizeDependencyPaths(section: ?Dependencies, loc: string): ?Dependencies {
if (section == null) {
return section;
}

let temp = section;

for (const [k, v] of util.entries(section)) {
if (typeof v === 'string' && v.startsWith('link:') && !path.isAbsolute(v)) {
if (temp === section) {
temp = Object.assign({}, section);
}
temp[k] = `link:${path.relative(this.config.cwd, path.join(loc, util.removePrefix(v, 'link:')))}`;
}
}

return temp;
}
}

0 comments on commit a7e6efe

Please sign in to comment.