From 52fd21061ff8b1a73429294620ffe5ebaaa60d3e Mon Sep 17 00:00:00 2001 From: isaacs Date: Wed, 11 Dec 2019 10:52:04 -0800 Subject: [PATCH] gentle-fs@2.3.0 --- node_modules/gentle-fs/CHANGELOG.md | 10 +++ node_modules/gentle-fs/index.js | 4 +- node_modules/gentle-fs/lib/bin-link.js | 96 ++++++++++++++++++++++++++ node_modules/gentle-fs/lib/link.js | 54 ++++++++++++++- node_modules/gentle-fs/package.json | 25 +++---- package-lock.json | 7 +- package.json | 2 +- 7 files changed, 180 insertions(+), 18 deletions(-) create mode 100644 node_modules/gentle-fs/lib/bin-link.js diff --git a/node_modules/gentle-fs/CHANGELOG.md b/node_modules/gentle-fs/CHANGELOG.md index 38fc91cba587d..50dfcd74c99f1 100644 --- a/node_modules/gentle-fs/CHANGELOG.md +++ b/node_modules/gentle-fs/CHANGELOG.md @@ -2,6 +2,16 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. + +# [2.3.0](https://github.com/npm/gentle-fs/compare/v2.2.1...v2.3.0) (2019-12-11) + + +### Features + +* add option to gently create bin links/shims ([a929196](https://github.com/npm/gentle-fs/commit/a929196)) + + + ## [2.2.1](https://github.com/npm/gentle-fs/compare/v2.2.0...v2.2.1) (2019-08-15) diff --git a/node_modules/gentle-fs/index.js b/node_modules/gentle-fs/index.js index 9807ed9d8580b..4aeda1c846bf2 100644 --- a/node_modules/gentle-fs/index.js +++ b/node_modules/gentle-fs/index.js @@ -3,10 +3,12 @@ const rm = require('./lib/rm.js') const link = require('./lib/link.js') const mkdir = require('./lib/mkdir.js') +const binLink = require('./lib/bin-link.js') exports = module.exports = { rm: rm, link: link.link, linkIfExists: link.linkIfExists, - mkdir: mkdir + mkdir: mkdir, + binLink: binLink } diff --git a/node_modules/gentle-fs/lib/bin-link.js b/node_modules/gentle-fs/lib/bin-link.js new file mode 100644 index 0000000000000..104c5b6c935c8 --- /dev/null +++ b/node_modules/gentle-fs/lib/bin-link.js @@ -0,0 +1,96 @@ +'use strict' +// calls linkIfExists on unix, or cmdShimIfExists on Windows +// reads the cmd shim to ensure it's where we need it to be in the case of +// top level global packages + +const readCmdShim = require('read-cmd-shim') +const cmdShim = require('cmd-shim') +const {linkIfExists} = require('./link.js') + +const binLink = (from, to, opts, cb) => { + // just for testing + const platform = opts._FAKE_PLATFORM_ || process.platform + if (platform !== 'win32') { + return linkIfExists(from, to, opts, cb) + } + + if (!opts.clobberLinkGently || + opts.force === true || + !opts.gently || + typeof opts.gently !== 'string') { + // easy, just go ahead and delete anything in the way + return cmdShim.ifExists(from, to, cb) + } + + // read all three shim targets + // if any exist, and are not a shim to our gently folder, then + // exit with a simulated EEXIST error. + + const shimFiles = [ + to, + to + '.cmd', + to + '.ps1' + ] + + // call this once we've checked all three, if we're good + const done = () => cmdShim.ifExists(from, to, cb) + const then = times(3, done, cb) + shimFiles.forEach(to => isClobberable(from, to, opts, then)) +} + +const times = (n, ok, cb) => { + let errState = null + return er => { + if (!errState) { + if (er) { + cb(errState = er) + } else if (--n === 0) { + ok() + } + } + } +} + +const isClobberable = (from, to, opts, cb) => { + readCmdShim(to, (er, target) => { + // either going to get an error, or the target of where this + // cmd shim points. + // shim, not in opts.gently: simulate EEXIST + // not a shim: simulate EEXIST + // ENOENT: fine, move forward + // shim in opts.gently: fine + if (er) { + switch (er.code) { + case 'ENOENT': + // totally fine, nothing there to clobber + return cb() + case 'ENOTASHIM': + // something is there, and it's not one of ours + return cb(simulateEEXIST(from, to)) + default: + // would probably fail this way later anyway + // can't read the file, likely can't write it either + return cb(er) + } + } + // no error, check the target + if (target.indexOf(opts.gently) !== 0) { + return cb(simulateEEXIST(from, to)) + } + // ok! it's one of ours. + return cb() + }) +} + +const simulateEEXIST = (from, to) => { + // simulate the EEXIST we'd get from fs.symlink to the file + const err = new Error('EEXIST: file already exists, cmd shim \'' + + from + '\' -> \'' + to + '\'') + + err.code = 'EEXIST' + err.path = from + err.dest = to + return err +} + +module.exports = binLink diff --git a/node_modules/gentle-fs/lib/link.js b/node_modules/gentle-fs/lib/link.js index 4623e7e82cf88..7cdfef4ca95d3 100644 --- a/node_modules/gentle-fs/lib/link.js +++ b/node_modules/gentle-fs/lib/link.js @@ -14,15 +14,22 @@ exports = module.exports = { } function linkIfExists (from, to, opts, cb) { + opts.currentIsLink = false + opts.currentExists = false fs.stat(from, function (er) { if (er) return cb() fs.readlink(to, function (er, fromOnDisk) { + if (!er || er.code !== 'ENOENT') { + opts.currentExists = true + } // if the link already exists and matches what we would do, // we don't need to do anything if (!er) { + opts.currentIsLink = true var toDir = path.dirname(to) var absoluteFrom = path.resolve(toDir, from) var absoluteFromOnDisk = path.resolve(toDir, fromOnDisk) + opts.currentTarget = absoluteFromOnDisk if (absoluteFrom === absoluteFromOnDisk) return cb() } link(from, to, opts, cb) @@ -58,7 +65,7 @@ function link (from, to, opts, cb) { const tasks = [ [ensureFromIsNotSource, absTarget, to], [fs, 'stat', absTarget], - [rm, to, opts], + [clobberLinkGently, from, to, opts], [mkdir, path.dirname(to)], [fs, 'symlink', target, to, 'junction'] ] @@ -72,3 +79,48 @@ function link (from, to, opts, cb) { }) } } + +exports._clobberLinkGently = clobberLinkGently +function clobberLinkGently (from, to, opts, cb) { + if (opts.currentExists === false) { + // nothing to clobber! + opts.log.silly('gently link', 'link does not already exist', { + link: to, + target: from + }) + return cb() + } + + if (!opts.clobberLinkGently || + opts.force === true || + !opts.gently || + typeof opts.gently !== 'string') { + opts.log.silly('gently link', 'deleting existing link forcefully', { + link: to, + target: from, + force: opts.force, + gently: opts.gently, + clobberLinkGently: opts.clobberLinkGently + }) + return rm(to, opts, cb) + } + + if (!opts.currentIsLink) { + opts.log.verbose('gently link', 'cannot remove, not a link', to) + // don't delete. it'll fail with EEXIST when it tries to symlink. + return cb() + } + + if (opts.currentTarget.indexOf(opts.gently) === 0) { + opts.log.silly('gently link', 'delete existing link', to) + return rm(to, opts, cb) + } else { + opts.log.verbose('gently link', 'refusing to delete existing link', { + link: to, + currentTarget: opts.currentTarget, + newTarget: from, + gently: opts.gently + }) + return cb() + } +} diff --git a/node_modules/gentle-fs/package.json b/node_modules/gentle-fs/package.json index bf4867c08d328..d162899757b0f 100644 --- a/node_modules/gentle-fs/package.json +++ b/node_modules/gentle-fs/package.json @@ -1,28 +1,28 @@ { - "_from": "gentle-fs@2.2.1", - "_id": "gentle-fs@2.2.1", + "_from": "gentle-fs@2.3.0", + "_id": "gentle-fs@2.3.0", "_inBundle": false, - "_integrity": "sha512-e7dRgUM5fsS+7wm2oggZpgcRx6sEvJHXujPH5RzgQ1ziQY4+HuVBYsnUzJwJ+C7mjOJN27DjiFy1TaL+TNltow==", + "_integrity": "sha512-3k2CgAmPxuz7S6nKK+AqFE2AdM1QuwqKLPKzIET3VRwK++3q96MsNFobScDjlCrq97ZJ8y5R725MOlm6ffUCjg==", "_location": "/gentle-fs", "_phantomChildren": {}, "_requested": { "type": "version", "registry": true, - "raw": "gentle-fs@2.2.1", + "raw": "gentle-fs@2.3.0", "name": "gentle-fs", "escapedName": "gentle-fs", - "rawSpec": "2.2.1", + "rawSpec": "2.3.0", "saveSpec": null, - "fetchSpec": "2.2.1" + "fetchSpec": "2.3.0" }, "_requiredBy": [ "#USER", "/", "/bin-links" ], - "_resolved": "https://registry.npmjs.org/gentle-fs/-/gentle-fs-2.2.1.tgz", - "_shasum": "1f38df4b4ead685566257201fd526de401ebb215", - "_spec": "gentle-fs@2.2.1", + "_resolved": "https://registry.npmjs.org/gentle-fs/-/gentle-fs-2.3.0.tgz", + "_shasum": "13538db5029400f98684be4894e8a7d8f0d1ea7f", + "_spec": "gentle-fs@2.3.0", "_where": "/Users/isaacs/dev/npm/cli", "author": { "name": "Mike Sherov" @@ -34,6 +34,7 @@ "dependencies": { "aproba": "^1.1.2", "chownr": "^1.1.2", + "cmd-shim": "^3.0.3", "fs-vacuum": "^1.2.10", "graceful-fs": "^4.1.11", "iferr": "^0.1.5", @@ -74,12 +75,12 @@ }, "scripts": { "postrelease": "npm publish && git push --follow-tags", + "posttest": "standard", "prerelease": "npm t", - "pretest": "standard", "release": "standard-version -s", - "test": "tap -J --nyc-arg=--all --coverage test/*.js test/**/*.js", + "test": "tap -J --nyc-arg=--all --coverage test", "update-coc": "weallbehave -o . && git add CODE_OF_CONDUCT.md && git commit -m 'docs(coc): updated CODE_OF_CONDUCT.md'", "update-contrib": "weallcontribute -o . && git add CONTRIBUTING.md && git commit -m 'docs(contributing): updated CONTRIBUTING.md'" }, - "version": "2.2.1" + "version": "2.3.0" } diff --git a/package-lock.json b/package-lock.json index 5b97c320a851c..18bd93f12f192 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2251,12 +2251,13 @@ "integrity": "sha512-KGDOARWVga7+rnB3z9Sd2Letx515owfk0hSxHGuqjANb1M+x2bGZGqHLiozPsYMdM2OubeMni/Hpwmjq6qIUhA==" }, "gentle-fs": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/gentle-fs/-/gentle-fs-2.2.1.tgz", - "integrity": "sha512-e7dRgUM5fsS+7wm2oggZpgcRx6sEvJHXujPH5RzgQ1ziQY4+HuVBYsnUzJwJ+C7mjOJN27DjiFy1TaL+TNltow==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/gentle-fs/-/gentle-fs-2.3.0.tgz", + "integrity": "sha512-3k2CgAmPxuz7S6nKK+AqFE2AdM1QuwqKLPKzIET3VRwK++3q96MsNFobScDjlCrq97ZJ8y5R725MOlm6ffUCjg==", "requires": { "aproba": "^1.1.2", "chownr": "^1.1.2", + "cmd-shim": "^3.0.3", "fs-vacuum": "^1.2.10", "graceful-fs": "^4.1.11", "iferr": "^0.1.5", diff --git a/package.json b/package.json index 3143f5193510a..833a79d59b8a8 100644 --- a/package.json +++ b/package.json @@ -59,7 +59,7 @@ "find-npm-prefix": "^1.0.2", "fs-vacuum": "~1.2.10", "fs-write-stream-atomic": "~1.0.10", - "gentle-fs": "^2.2.1", + "gentle-fs": "^2.3.0", "glob": "^7.1.4", "graceful-fs": "^4.2.3", "has-unicode": "~2.0.1",