From de4e95ef92f7ae15439f3c4282dcc135db57a63a Mon Sep 17 00:00:00 2001 From: Dmitriy Kuznetsov Date: Tue, 2 Jul 2019 12:23:51 +0300 Subject: [PATCH 1/3] [Tests] add failing symlink tests --- .../resolver/symlinked/_/node_modules/package | 1 + test/resolver/symlinked/package/bar.js | 1 + test/resolver/symlinked/package/package.json | 3 +++ test/symlinks.js | 20 +++++++++++++++++++ 4 files changed, 25 insertions(+) create mode 120000 test/resolver/symlinked/_/node_modules/package create mode 100644 test/resolver/symlinked/package/bar.js create mode 100644 test/resolver/symlinked/package/package.json diff --git a/test/resolver/symlinked/_/node_modules/package b/test/resolver/symlinked/_/node_modules/package new file mode 120000 index 00000000..46c82413 --- /dev/null +++ b/test/resolver/symlinked/_/node_modules/package @@ -0,0 +1 @@ +../../package \ No newline at end of file diff --git a/test/resolver/symlinked/package/bar.js b/test/resolver/symlinked/package/bar.js new file mode 100644 index 00000000..cb1c2c01 --- /dev/null +++ b/test/resolver/symlinked/package/bar.js @@ -0,0 +1 @@ +module.exports = 'bar'; diff --git a/test/resolver/symlinked/package/package.json b/test/resolver/symlinked/package/package.json new file mode 100644 index 00000000..8e1b5859 --- /dev/null +++ b/test/resolver/symlinked/package/package.json @@ -0,0 +1,3 @@ +{ + "main": "bar.js" +} \ No newline at end of file diff --git a/test/symlinks.js b/test/symlinks.js index 54b883fd..b4e205eb 100644 --- a/test/symlinks.js +++ b/test/symlinks.js @@ -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 @@ -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(); + }); +}); From cc0f4e49d1f0166352eb8a710d3a427317f200e5 Mon Sep 17 00:00:00 2001 From: Jordan Harband Date: Wed, 31 Jul 2019 12:06:46 -0700 Subject: [PATCH 2/3] [Tests] fix symlinks in windows/appveyor --- appveyor.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/appveyor.yml b/appveyor.yml index 0ad94a1e..729e8ea0 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -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 npm@1.3 From f7da566f6bb5f4415514b9b183f095feb487df1c Mon Sep 17 00:00:00 2001 From: Jordan Harband Date: Mon, 29 Jul 2019 19:42:56 -0700 Subject: [PATCH 3/3] [Fix] `preserveSymlinks: false` ensure that files are realpathed Fixes #196. --- .eslintrc | 10 ++++++- lib/async.js | 22 +++++++++++++--- lib/sync.js | 4 +-- package.json | 1 + .../common/node_modules/buffer/index.js | 1 + .../common/node_modules/buffer/package.json | 7 +++++ test/resolver/nested_symlinks/mylib/async.js | 26 +++++++++++++++++++ .../nested_symlinks/mylib/node_modules/buffer | 1 + .../mylib/node_modules/resolve | 1 + .../nested_symlinks/mylib/package.json | 15 +++++++++++ test/resolver/nested_symlinks/mylib/sync.js | 12 +++++++++ 11 files changed, 93 insertions(+), 7 deletions(-) create mode 100644 test/resolver/nested_symlinks/common/node_modules/buffer/index.js create mode 100644 test/resolver/nested_symlinks/common/node_modules/buffer/package.json create mode 100644 test/resolver/nested_symlinks/mylib/async.js create mode 120000 test/resolver/nested_symlinks/mylib/node_modules/buffer create mode 120000 test/resolver/nested_symlinks/mylib/node_modules/resolve create mode 100644 test/resolver/nested_symlinks/mylib/package.json create mode 100644 test/resolver/nested_symlinks/mylib/sync.js diff --git a/.eslintrc b/.eslintrc index 4f5155ee..d7485182 100644 --- a/.eslintrc +++ b/.eslintrc @@ -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, + }, + }, + ], } diff --git a/lib/async.js b/lib/async.js index 310ea698..a46e3f18 100644 --- a/lib/async.js +++ b/lib/async.js @@ -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); @@ -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); diff --git a/lib/sync.js b/lib/sync.js index a025df6e..3af96a72 100644 --- a/lib/sync.js +++ b/lib/sync.js @@ -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; diff --git a/package.json b/package.json index 9fbd9e2f..19b634c8 100644 --- a/package.json +++ b/package.json @@ -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", diff --git a/test/resolver/nested_symlinks/common/node_modules/buffer/index.js b/test/resolver/nested_symlinks/common/node_modules/buffer/index.js new file mode 100644 index 00000000..66c989cb --- /dev/null +++ b/test/resolver/nested_symlinks/common/node_modules/buffer/index.js @@ -0,0 +1 @@ +module.exports = Buffer; diff --git a/test/resolver/nested_symlinks/common/node_modules/buffer/package.json b/test/resolver/nested_symlinks/common/node_modules/buffer/package.json new file mode 100644 index 00000000..79ff3830 --- /dev/null +++ b/test/resolver/nested_symlinks/common/node_modules/buffer/package.json @@ -0,0 +1,7 @@ +{ + "description": "fake buffer shim", + "main": "index.js", + "name": "buffer", + "version": "0.0.0", + "private": true +} diff --git a/test/resolver/nested_symlinks/mylib/async.js b/test/resolver/nested_symlinks/mylib/async.js new file mode 100644 index 00000000..9b4846a8 --- /dev/null +++ b/test/resolver/nested_symlinks/mylib/async.js @@ -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(); } +}); + diff --git a/test/resolver/nested_symlinks/mylib/node_modules/buffer b/test/resolver/nested_symlinks/mylib/node_modules/buffer new file mode 120000 index 00000000..b46997bb --- /dev/null +++ b/test/resolver/nested_symlinks/mylib/node_modules/buffer @@ -0,0 +1 @@ +../../common/node_modules/buffer \ No newline at end of file diff --git a/test/resolver/nested_symlinks/mylib/node_modules/resolve b/test/resolver/nested_symlinks/mylib/node_modules/resolve new file mode 120000 index 00000000..59307833 --- /dev/null +++ b/test/resolver/nested_symlinks/mylib/node_modules/resolve @@ -0,0 +1 @@ +../../../../.. \ No newline at end of file diff --git a/test/resolver/nested_symlinks/mylib/package.json b/test/resolver/nested_symlinks/mylib/package.json new file mode 100644 index 00000000..acfe9e95 --- /dev/null +++ b/test/resolver/nested_symlinks/mylib/package.json @@ -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": "*" + } +} diff --git a/test/resolver/nested_symlinks/mylib/sync.js b/test/resolver/nested_symlinks/mylib/sync.js new file mode 100644 index 00000000..3283efc2 --- /dev/null +++ b/test/resolver/nested_symlinks/mylib/sync.js @@ -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');