summaryrefslogtreecommitdiff
path: root/deps/npm/node_modules/cacache/node_modules/chownr/chownr.js
diff options
context:
space:
mode:
Diffstat (limited to 'deps/npm/node_modules/cacache/node_modules/chownr/chownr.js')
-rw-r--r--deps/npm/node_modules/cacache/node_modules/chownr/chownr.js88
1 files changed, 88 insertions, 0 deletions
diff --git a/deps/npm/node_modules/cacache/node_modules/chownr/chownr.js b/deps/npm/node_modules/cacache/node_modules/chownr/chownr.js
new file mode 100644
index 0000000000..7e63928827
--- /dev/null
+++ b/deps/npm/node_modules/cacache/node_modules/chownr/chownr.js
@@ -0,0 +1,88 @@
+'use strict'
+const fs = require('fs')
+const path = require('path')
+
+/* istanbul ignore next */
+const LCHOWN = fs.lchown ? 'lchown' : 'chown'
+/* istanbul ignore next */
+const LCHOWNSYNC = fs.lchownSync ? 'lchownSync' : 'chownSync'
+
+// fs.readdir could only accept an options object as of node v6
+const nodeVersion = process.version
+let readdir = (path, options, cb) => fs.readdir(path, options, cb)
+let readdirSync = (path, options) => fs.readdirSync(path, options)
+/* istanbul ignore next */
+if (/^v4\./.test(nodeVersion))
+ readdir = (path, options, cb) => fs.readdir(path, cb)
+
+const chownrKid = (p, child, uid, gid, cb) => {
+ if (typeof child === 'string')
+ return fs.lstat(path.resolve(p, child), (er, stats) => {
+ if (er)
+ return cb(er)
+ stats.name = child
+ chownrKid(p, stats, uid, gid, cb)
+ })
+
+ if (child.isDirectory()) {
+ chownr(path.resolve(p, child.name), uid, gid, er => {
+ if (er)
+ return cb(er)
+ fs[LCHOWN](path.resolve(p, child.name), uid, gid, cb)
+ })
+ } else
+ fs[LCHOWN](path.resolve(p, child.name), uid, gid, cb)
+}
+
+
+const chownr = (p, uid, gid, cb) => {
+ readdir(p, { withFileTypes: true }, (er, children) => {
+ // any error other than ENOTDIR or ENOTSUP means it's not readable,
+ // or doesn't exist. give up.
+ if (er && er.code !== 'ENOTDIR' && er.code !== 'ENOTSUP')
+ return cb(er)
+ if (er || !children.length) return fs[LCHOWN](p, uid, gid, cb)
+
+ let len = children.length
+ let errState = null
+ const then = er => {
+ if (errState) return
+ if (er) return cb(errState = er)
+ if (-- len === 0) return fs[LCHOWN](p, uid, gid, cb)
+ }
+
+ children.forEach(child => chownrKid(p, child, uid, gid, then))
+ })
+}
+
+const chownrKidSync = (p, child, uid, gid) => {
+ if (typeof child === 'string') {
+ const stats = fs.lstatSync(path.resolve(p, child))
+ stats.name = child
+ child = stats
+ }
+
+ if (child.isDirectory())
+ chownrSync(path.resolve(p, child.name), uid, gid)
+
+ fs[LCHOWNSYNC](path.resolve(p, child.name), uid, gid)
+}
+
+const chownrSync = (p, uid, gid) => {
+ let children
+ try {
+ children = readdirSync(p, { withFileTypes: true })
+ } catch (er) {
+ if (er && er.code === 'ENOTDIR' && er.code !== 'ENOTSUP')
+ return fs[LCHOWNSYNC](p, uid, gid)
+ throw er
+ }
+
+ if (children.length)
+ children.forEach(child => chownrKidSync(p, child, uid, gid))
+
+ return fs[LCHOWNSYNC](p, uid, gid)
+}
+
+module.exports = chownr
+chownr.sync = chownrSync