New upstream version 1.1.1

parent 1b33e182
language: node_js
before_script: npm install -g npm@latest
sudo: false
node_js:
- '0.8'
- '0.10'
- '0.12'
- 'iojs'
- 6
- 8
- 10
notifications:
email: false
cache:
directories:
- $HOME/.npm
module.exports = chownr
chownr.sync = chownrSync
'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)
})
var fs = require("fs")
, path = require("path")
function chownr (p, uid, gid, cb) {
fs.readdir(p, function (er, children) {
// any error other than ENOTDIR means it's not readable, or
// doesn't exist. give up.
if (er && er.code !== "ENOTDIR") return cb(er)
if (er || !children.length) return fs.chown(p, uid, gid, cb)
var len = children.length
, errState = null
children.forEach(function (child) {
var pathChild = path.resolve(p, child);
fs.lstat(pathChild, function(er, stats) {
if (er)
return cb(er)
if (!stats.isSymbolicLink())
chownr(pathChild, uid, gid, then)
else
then()
})
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)
})
function then (er) {
} 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.chown(p, uid, gid, cb)
if (-- len === 0) return fs[LCHOWN](p, uid, gid, cb)
}
children.forEach(child => chownrKid(p, child, uid, gid, then))
})
}
function chownrSync (p, uid, gid) {
var children
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 = fs.readdirSync(p)
children = readdirSync(p, { withFileTypes: true })
} catch (er) {
if (er && er.code === "ENOTDIR") return fs.chownSync(p, uid, gid)
if (er && er.code === 'ENOTDIR' && er.code !== 'ENOTSUP')
return fs[LCHOWNSYNC](p, uid, gid)
throw er
}
if (!children.length) return fs.chownSync(p, uid, gid)
children.forEach(function (child) {
var pathChild = path.resolve(p, child)
var stats = fs.lstatSync(pathChild)
if (!stats.isSymbolicLink())
chownrSync(pathChild, uid, gid)
})
return fs.chownSync(p, uid, gid)
if (children.length)
children.forEach(child => chownrKidSync(p, child, uid, gid))
return fs[LCHOWNSYNC](p, uid, gid)
}
module.exports = chownr
chownr.sync = chownrSync
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -2,7 +2,7 @@
"author": "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me/)",
"name": "chownr",
"description": "like `chown -R`",
"version": "1.0.1",
"version": "1.1.1",
"repository": {
"type": "git",
"url": "git://github.com/isaacs/chownr.git"
......@@ -14,10 +14,13 @@
"devDependencies": {
"mkdirp": "0.3",
"rimraf": "",
"tap": "^1.2.0"
"tap": "^12.0.1"
},
"scripts": {
"test": "tap test/*.js"
"test": "tap test/*.js --cov",
"preversion": "npm test",
"postversion": "npm publish",
"postpublish": "git push origin --all; git push origin --tags"
},
"license": "ISC"
}
if (!process.getuid || !process.getgid) {
throw new Error("Tests require getuid/getgid support")
}
const fs = require('fs')
const readdir = fs.readdir
fs.readdir = (path, options, cb) => readdir(path, cb || options)
const readdirSync = fs.readdirSync
fs.readdirSync = (path, options) => readdirSync(path)
var curUid = +process.getuid()
, curGid = +process.getgid()
, chownr = require("../")
, test = require("tap").test
, mkdirp = require("mkdirp")
, rimraf = require("rimraf")
// sniff the 'id' command for other groups that i can legally assign to
var exec = require("child_process").exec
, groups
, dirs = []
exec("id", function (code, output) {
if (code) throw new Error("failed to run 'id' command")
groups = output.trim().split("=")[3].split(",").map(function (s) {
return parseInt(s, 10)
}).filter(function (g) {
return g !== curGid
})
// console.error([curUid, groups[0]], "uid, gid")
rimraf("/tmp/chownr", function (er) {
if (er) throw er
var cnt = 5
for (var i = 0; i < 5; i ++) {
mkdirp(getDir(), then)
}
function then (er) {
if (er) throw er
if (-- cnt === 0) {
runTest()
}
}
})
})
function getDir () {
var x = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
var y = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
var z = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
var dir = "/tmp/chownr/" + [x,y,z].join("/")
dirs.push(dir)
return dir
}
function runTest () {
test("should complete successfully", function (t) {
// console.error("calling chownr", curUid, groups[0], typeof curUid, typeof groups[0])
chownr.sync("/tmp/chownr", curUid, groups[0])
t.end()
})
dirs.forEach(function (dir) {
test("verify "+dir, function (t) {
fs.stat(dir, function (er, st) {
if (er) {
t.ifError(er)
return t.end()
}
t.equal(st.uid, curUid, "uid should be " + curUid)
t.equal(st.gid, groups[0], "gid should be "+groups[0])
t.end()
})
})
})
test("cleanup", function (t) {
rimraf("/tmp/chownr/", function (er) {
t.ifError(er)
t.end()
})
})
}
if (!process.getuid || !process.getgid) {
throw new Error("Tests require getuid/getgid support")
}
const fs = require('fs')
const readdir = fs.readdir
fs.readdir = (path, options, cb) => readdir(path, cb || options)
const readdirSync = fs.readdirSync
fs.readdirSync = (path, options) => readdirSync(path)
var curUid = +process.getuid()
, curGid = +process.getgid()
, chownr = require("../")
, test = require("tap").test
, mkdirp = require("mkdirp")
, rimraf = require("rimraf")
// sniff the 'id' command for other groups that i can legally assign to
var exec = require("child_process").exec
, groups
, dirs = []
exec("id", function (code, output) {
if (code) throw new Error("failed to run 'id' command")
groups = output.trim().split("=")[3].split(",").map(function (s) {
return parseInt(s, 10)
}).filter(function (g) {
return g !== curGid
})
// console.error([curUid, groups[0]], "uid, gid")
rimraf("/tmp/chownr", function (er) {
if (er) throw er
var cnt = 5
for (var i = 0; i < 5; i ++) {
mkdirp(getDir(), then)
}
function then (er) {
if (er) throw er
if (-- cnt === 0) {
runTest()
}
}
})
})
function getDir () {
var dir = "/tmp/chownr"
dir += "/" + Math.floor(Math.random() * Math.pow(16,4)).toString(16)
dirs.push(dir)
dir += "/" + Math.floor(Math.random() * Math.pow(16,4)).toString(16)
dirs.push(dir)
dir += "/" + Math.floor(Math.random() * Math.pow(16,4)).toString(16)
dirs.push(dir)
return dir
}
function runTest () {
test("should complete successfully", function (t) {
// console.error("calling chownr", curUid, groups[0], typeof curUid, typeof groups[0])
chownr("/tmp/chownr", curUid, groups[0], function (er) {
t.ifError(er)
t.end()
})
})
dirs.forEach(function (dir) {
test("verify "+dir, function (t) {
fs.stat(dir, function (er, st) {
if (er) {
t.ifError(er)
return t.end()
}
t.equal(st.uid, curUid, "uid should be " + curUid)
t.equal(st.gid, groups[0], "gid should be "+groups[0])
t.end()
})
})
})
test("cleanup", function (t) {
rimraf("/tmp/chownr/", function (er) {
t.ifError(er)
t.end()
})
})
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment