Skip to content

[Fix] preserveSymlinks: false ensure that files are realpathed #197

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jul 31, 2019
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
10 changes: 9 additions & 1 deletion .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,13 @@
"object-curly-newline": 0,
"operator-linebreak": [2, "before"],
"sort-keys": 0,
}
},
"overrides": [
{
"files": "test/resolver/nested_symlinks/mylib/*.js",
"rules": {
"no-throw-literal": 0,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of throw 'async: no match'; you could just do throw new Error('async: no match');

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sure, but then the failure output includes a stack trace, which makes it harder to read :-)

},
},
],
}
3 changes: 3 additions & 0 deletions appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ platform:

# Install scripts. (runs after repo cloning)
install:
# Fix symlinks in working copy (see https://github.com/appveyor/ci/issues/650#issuecomment-186592582) / https://github.com/charleskorn/batect/commit/d08986802ec43086902958c4ee7e57ff3e71dbef
- git config core.symlinks true
- git reset --hard
# Get the latest stable version of Node.js or io.js
- ps: Install-Product node $env:nodejs_version $env:platform
- IF %nodejs_version% EQU 0.6 npm config set strict-ssl false && npm -g install [email protected]
Expand Down
22 changes: 18 additions & 4 deletions lib/async.js
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,15 @@ module.exports = function resolve(x, options, callback) {
} else loadNodeModules(x, basedir, function (err, n, pkg) {
if (err) cb(err);
else if (core[x]) return cb(null, x);
else if (n) return cb(null, n, pkg);
else {
else if (n) {
return maybeUnwrapSymlink(n, opts, function (err, realN) {
if (err) {
cb(err);
} else {
cb(null, realN, pkg);
}
});
} else {
var moduleError = new Error("Cannot find module '" + x + "' from '" + parent + "'");
moduleError.code = 'MODULE_NOT_FOUND';
cb(moduleError);
Expand All @@ -113,8 +120,15 @@ module.exports = function resolve(x, options, callback) {
else if (m) cb(null, m, pkg);
else loadAsDirectory(res, function (err, d, pkg) {
if (err) cb(err);
else if (d) cb(null, d, pkg);
else {
else if (d) {
maybeUnwrapSymlink(d, opts, function (err, realD) {
if (err) {
cb(err);
} else {
cb(null, realD, pkg);
}
});
} else {
var moduleError = new Error("Cannot find module '" + x + "' from '" + parent + "'");
moduleError.code = 'MODULE_NOT_FOUND';
cb(moduleError);
Expand Down
4 changes: 2 additions & 2 deletions lib/sync.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,12 @@ module.exports = function (x, options) {
var res = path.resolve(absoluteStart, x);
if (x === '..' || x.slice(-1) === '/') res += '/';
var m = loadAsFileSync(res) || loadAsDirectorySync(res);
if (m) return m;
if (m) return maybeUnwrapSymlink(m, opts);
} else if (core[x]) {
return x;
} else {
var n = loadNodeModulesSync(x, absoluteStart);
if (n) return n;
if (n) return maybeUnwrapSymlink(n, opts);
}

if (core[x]) return x;
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"scripts": {
"prepublish": "safe-publish-latest",
"lint": "eslint .",
"pretests-only": "cd ./test/resolver/nested_symlinks && node mylib/sync && node mylib/async",
"tests-only": "tape test/*.js",
"pretest": "npm run lint",
"test": "npm run --silent tests-only",
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

26 changes: 26 additions & 0 deletions test/resolver/nested_symlinks/mylib/async.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
var a = require.resolve('buffer/').replace(process.cwd(), '$CWD');
var b;
var c;

var test = function test() {
console.log(a, ': require.resolve, preserveSymlinks ' + (process.execArgv.indexOf('preserve-symlinks') > -1 ? 'true' : 'false'));
console.log(b, ': preserveSymlinks true');
console.log(c, ': preserveSymlinks false');

if (a !== b && a !== c) {
throw 'async: no match';
}
console.log('async: success! a matched either b or c\n');
};

require('resolve')('buffer/', { preserveSymlinks: true }, function (err, result) {
if (err) { throw err; }
b = result.replace(process.cwd(), '$CWD');
if (b && c) { test(); }
});
require('resolve')('buffer/', { preserveSymlinks: false }, function (err, result) {
if (err) { throw err; }
c = result.replace(process.cwd(), '$CWD');
if (b && c) { test(); }
});

1 change: 1 addition & 0 deletions test/resolver/nested_symlinks/mylib/node_modules/buffer

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions test/resolver/nested_symlinks/mylib/node_modules/resolve

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 15 additions & 0 deletions test/resolver/nested_symlinks/mylib/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"name": "mylib",
"version": "0.0.0",
"description": "",
"private": true,
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"buffer": "*"
}
}
12 changes: 12 additions & 0 deletions test/resolver/nested_symlinks/mylib/sync.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
var a = require.resolve('buffer/').replace(process.cwd(), '$CWD');
var b = require('resolve').sync('buffer/', { preserveSymlinks: true }).replace(process.cwd(), '$CWD');
var c = require('resolve').sync('buffer/', { preserveSymlinks: false }).replace(process.cwd(), '$CWD');

console.log(a, ': require.resolve, preserveSymlinks ' + (process.execArgv.indexOf('preserve-symlinks') > -1 ? 'true' : 'false'));
console.log(b, ': preserveSymlinks true');
console.log(c, ': preserveSymlinks false');

if (a !== b && a !== c) {
throw 'sync: no match';
}
console.log('sync: success! a matched either b or c\n');
1 change: 1 addition & 0 deletions test/resolver/symlinked/_/node_modules/package

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions test/resolver/symlinked/package/bar.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = 'bar';
3 changes: 3 additions & 0 deletions test/resolver/symlinked/package/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"main": "bar.js"
}
20 changes: 20 additions & 0 deletions test/symlinks.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@ var test = require('tape');
var resolve = require('../');

var symlinkDir = path.join(__dirname, 'resolver', 'symlinked', 'symlink');
var packageDir = path.join(__dirname, 'resolver', 'symlinked', '_', 'node_modules', 'package');
try {
fs.unlinkSync(symlinkDir);
} catch (err) {}
try {
fs.symlinkSync('./_/symlink_target', symlinkDir, 'dir');
fs.symlinkSync('../../package', packageDir, 'dir');
} catch (err) {
if (err.code !== 'EEXIST') {
// if fails then it is probably on Windows and lets try to create a junction
Expand Down Expand Up @@ -56,3 +58,21 @@ test('sync symlink when preserveSymlinks = true', function (t) {
}, /Cannot find module 'foo'/);
t.end();
});

test('sync symlink from node_modules to other dir when preserveSymlinks = false', function (t) {
var basedir = path.join(__dirname, 'resolver', 'symlinked', '_');
var fn = resolve.sync('package', { basedir: basedir, preserveSymlinks: false });

t.equal(fn, path.resolve(__dirname, 'resolver/symlinked/package/bar.js'));
t.end();
});

test('async symlink from node_modules to other dir when preserveSymlinks = false', function (t) {
t.plan(2);
var basedir = path.join(__dirname, 'resolver', 'symlinked', '_');
resolve('package', { basedir: basedir, preserveSymlinks: false }, function (err, result) {
t.notOk(err, 'no error');
t.equal(result, path.resolve(__dirname, 'resolver/symlinked/package/bar.js'));
t.end();
});
});