Skip to content

Commit 994d24d

Browse files
fix: resolve symbol links until their are no more symbolic links
Depending on your npm / yarn set up a global install may have to resolve through several symlinks before it correctly arrives the the baseDir that actually contains the other subcommands. The changes the resolution logic to resolve symlinks until their are no more to resolve by using realpath which will resolve links all the way to the final destination.
1 parent 291fc04 commit 994d24d

File tree

6 files changed

+27
-7
lines changed

6 files changed

+27
-7
lines changed

index.js

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -527,14 +527,11 @@ Command.prototype.executeSubCommand = function(argv, args, unknown) {
527527

528528
// In case of globally installed, get the base dir where executable
529529
// subcommand file should be located at
530-
var baseDir,
531-
link = fs.lstatSync(f).isSymbolicLink() ? fs.readlinkSync(f) : f;
530+
var baseDir;
532531

533-
// when symbolink is relative path
534-
if (link !== f && link.charAt(0) !== '/') {
535-
link = path.join(dirname(f), link);
536-
}
537-
baseDir = dirname(link);
532+
var resolvedLink = fs.realpathSync(f);
533+
534+
baseDir = dirname(resolvedLink);
538535

539536
// prefer local `./<bin>` to bin in the $PATH
540537
var localBin = path.join(baseDir, bin);

test/fixtures/another-dir/pm

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../other-dir/pm

test/fixtures/other-dir/pm

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../pm

test/test.command.executableSubcommand.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,10 @@ var bin = path.join(__dirname, './fixtures/pmlink')
3434
exec(bin + ' install', function (error, stdout, stderr) {
3535
stdout.should.equal('install\n');
3636
});
37+
38+
// when `bin` is a symbol link pointing at a symbolic for mocking global install
39+
var bin = path.join(__dirname, './fixtures/another-dir/pm')
40+
// success case
41+
exec(bin + ' install', function (error, stdout, stderr) {
42+
stdout.should.equal('install\n');
43+
});

test/test.command.executableSubcommandAlias.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,10 @@ var bin = path.join(__dirname, './fixtures/pmlink')
2626
exec(bin + ' i', function (error, stdout, stderr) {
2727
stdout.should.equal('install\n');
2828
});
29+
30+
// when `bin` is a symbol link pointing at a symbolic for mocking global install
31+
var bin = path.join(__dirname, './fixtures/another-dir/pm')
32+
// success case
33+
exec(bin + ' install', function (error, stdout, stderr) {
34+
stdout.should.equal('install\n');
35+
});

test/test.command.executableSubcommandDefault.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,3 +44,10 @@ var bin = path.join(__dirname, './fixtures/pmlink')
4444
exec(bin + ' install', function (error, stdout, stderr) {
4545
stdout.should.equal('install\n');
4646
});
47+
48+
// when `bin` is a symbol link pointing at a symbolic for mocking global install
49+
var bin = path.join(__dirname, './fixtures/another-dir/pm')
50+
// success case
51+
exec(bin + ' install', function (error, stdout, stderr) {
52+
stdout.should.equal('install\n');
53+
});

0 commit comments

Comments
 (0)