diff --git a/node_modules/infer-owner/LICENSE b/node_modules/infer-owner/LICENSE new file mode 100644 index 0000000000000..20a4762540923 --- /dev/null +++ b/node_modules/infer-owner/LICENSE @@ -0,0 +1,15 @@ +The ISC License + +Copyright (c) npm, Inc. and Contributors + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/node_modules/infer-owner/README.md b/node_modules/infer-owner/README.md new file mode 100644 index 0000000000000..146caf7b8c801 --- /dev/null +++ b/node_modules/infer-owner/README.md @@ -0,0 +1,41 @@ +# infer-owner + +Infer the owner of a path based on the owner of its nearest existing parent + +## USAGE + +```js +const inferOwner = require('infer-owner') + +inferOwner('/some/cache/folder/file').then(owner => { + // owner is {uid, gid} that should be attached to + // the /some/cache/folder/file, based on ownership + // of /some/cache/folder, /some/cache, /some, or /, + // whichever is the first to exist +}) + +// same, but not async +const owner = inferOwner.sync('/some/cache/folder/file') + +// results are cached! to reset the cache (eg, to change +// permissions for whatever reason), do this: +inferOwner.clearCache() +``` + +This module endeavors to be as performant as possible. Parallel requests +for ownership of the same path will only stat the directories one time. + +## API + +* `inferOwner(path) -> Promise<{ uid, gid }>` + + If the path exists, return its uid and gid. If it does not, look to + its parent, then its grandparent, and so on. + +* `inferOwner(path) -> { uid, gid }` + + Sync form of `inferOwner(path)`. + +* `inferOwner.clearCache()` + + Delete all cached ownership information and in-flight tracking. diff --git a/node_modules/infer-owner/index.js b/node_modules/infer-owner/index.js new file mode 100644 index 0000000000000..a7bddcbd2288b --- /dev/null +++ b/node_modules/infer-owner/index.js @@ -0,0 +1,71 @@ +const cache = new Map() +const fs = require('fs') +const { dirname, resolve } = require('path') + + +const lstat = path => new Promise((res, rej) => + fs.lstat(path, (er, st) => er ? rej(er) : res(st))) + +const inferOwner = path => { + path = resolve(path) + if (cache.has(path)) + return Promise.resolve(cache.get(path)) + + const statThen = st => { + const { uid, gid } = st + cache.set(path, { uid, gid }) + return { uid, gid } + } + const parent = dirname(path) + const parentTrap = parent === path ? null : er => { + return inferOwner(parent).then((owner) => { + cache.set(path, owner) + return owner + }) + } + return lstat(path).then(statThen, parentTrap) +} + +const inferOwnerSync = path => { + path = resolve(path) + if (cache.has(path)) + return cache.get(path) + + const parent = dirname(path) + + // avoid obscuring call site by re-throwing + // "catch" the error by returning from a finally, + // only if we're not at the root, and the parent call works. + let threw = true + try { + const st = fs.lstatSync(path) + threw = false + const { uid, gid } = st + cache.set(path, { uid, gid }) + return { uid, gid } + } finally { + if (threw && parent !== path) { + const owner = inferOwnerSync(parent) + cache.set(path, owner) + return owner // eslint-disable-line no-unsafe-finally + } + } +} + +const inflight = new Map() +module.exports = path => { + path = resolve(path) + if (inflight.has(path)) + return Promise.resolve(inflight.get(path)) + const p = inferOwner(path).then(owner => { + inflight.delete(path) + return owner + }) + inflight.set(path, p) + return p +} +module.exports.sync = inferOwnerSync +module.exports.clearCache = () => { + cache.clear() + inflight.clear() +} diff --git a/node_modules/infer-owner/package.json b/node_modules/infer-owner/package.json new file mode 100644 index 0000000000000..1b7b3e0509f42 --- /dev/null +++ b/node_modules/infer-owner/package.json @@ -0,0 +1,63 @@ +{ + "_from": "infer-owner@1.0.4", + "_id": "infer-owner@1.0.4", + "_inBundle": false, + "_integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", + "_location": "/infer-owner", + "_phantomChildren": {}, + "_requested": { + "type": "version", + "registry": true, + "raw": "infer-owner@1.0.4", + "name": "infer-owner", + "escapedName": "infer-owner", + "rawSpec": "1.0.4", + "saveSpec": null, + "fetchSpec": "1.0.4" + }, + "_requiredBy": [ + "#USER", + "/" + ], + "_resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", + "_shasum": "c4cefcaa8e51051c2a40ba2ce8a3d27295af9467", + "_spec": "infer-owner@1.0.4", + "_where": "/Users/isaacs/dev/npm/cli", + "author": { + "name": "Isaac Z. Schlueter", + "email": "i@izs.me", + "url": "https://izs.me" + }, + "bugs": { + "url": "https://github.com/npm/infer-owner/issues" + }, + "bundleDependencies": false, + "deprecated": false, + "description": "Infer the owner of a path based on the owner of its nearest existing parent", + "devDependencies": { + "mutate-fs": "^2.1.1", + "tap": "^12.4.2" + }, + "files": [ + "index.js" + ], + "homepage": "https://github.com/npm/infer-owner#readme", + "license": "ISC", + "main": "index.js", + "name": "infer-owner", + "publishConfig": { + "access": "public" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/npm/infer-owner.git" + }, + "scripts": { + "postpublish": "git push origin --follow-tags", + "postversion": "npm publish", + "preversion": "npm test", + "snap": "TAP_SNAPSHOT=1 tap -J test/*.js --100", + "test": "tap -J test/*.js --100" + }, + "version": "1.0.4" +} diff --git a/package-lock.json b/package-lock.json index f922ffb569564..40f6a8c8dc322 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2564,6 +2564,11 @@ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=" }, + "infer-owner": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", + "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==" + }, "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", diff --git a/package.json b/package.json index 94bec8c449806..3353a0a969c41 100644 --- a/package.json +++ b/package.json @@ -65,6 +65,7 @@ "has-unicode": "~2.0.1", "hosted-git-info": "^2.7.1", "iferr": "^1.0.2", + "infer-owner": "^1.0.4", "inflight": "~1.0.6", "inherits": "^2.0.4", "ini": "^1.3.5", @@ -182,6 +183,7 @@ "hosted-git-info", "iferr", "imurmurhash", + "infer-owner", "inflight", "inherits", "ini",