CoolFace
Apppublic

AK-21/Graphite-Industrial-Intelligence

sourceHugging Faceupdated 3mo agoView on Hugging Face
0likes
chownr.js168 linesDownload Raw Back to chownr
1'use strict'2const fs = require('fs')3const path = require('path')4 5/* istanbul ignore next */6const LCHOWN = fs.lchown ? 'lchown' : 'chown'7/* istanbul ignore next */8const LCHOWNSYNC = fs.lchownSync ? 'lchownSync' : 'chownSync'9 10/* istanbul ignore next */11const needEISDIRHandled = fs.lchown &&12  !process.version.match(/v1[1-9]+\./) &&13  !process.version.match(/v10\.[6-9]/)14 15const lchownSync = (path, uid, gid) => {16  try {17    return fs[LCHOWNSYNC](path, uid, gid)18  } catch (er) {19    if (er.code !== 'ENOENT')20      throw er21  }22}23 24/* istanbul ignore next */25const chownSync = (path, uid, gid) => {26  try {27    return fs.chownSync(path, uid, gid)28  } catch (er) {29    if (er.code !== 'ENOENT')30      throw er31  }32}33 34/* istanbul ignore next */35const handleEISDIR =36  needEISDIRHandled ? (path, uid, gid, cb) => er => {37    // Node prior to v10 had a very questionable implementation of38    // fs.lchown, which would always try to call fs.open on a directory39    // Fall back to fs.chown in those cases.40    if (!er || er.code !== 'EISDIR')41      cb(er)42    else43      fs.chown(path, uid, gid, cb)44  }45  : (_, __, ___, cb) => cb46 47/* istanbul ignore next */48const handleEISDirSync =49  needEISDIRHandled ? (path, uid, gid) => {50    try {51      return lchownSync(path, uid, gid)52    } catch (er) {53      if (er.code !== 'EISDIR')54        throw er55      chownSync(path, uid, gid)56    }57  }58  : (path, uid, gid) => lchownSync(path, uid, gid)59 60// fs.readdir could only accept an options object as of node v661const nodeVersion = process.version62let readdir = (path, options, cb) => fs.readdir(path, options, cb)63let readdirSync = (path, options) => fs.readdirSync(path, options)64/* istanbul ignore next */65if (/^v4\./.test(nodeVersion))66  readdir = (path, options, cb) => fs.readdir(path, cb)67 68const chown = (cpath, uid, gid, cb) => {69  fs[LCHOWN](cpath, uid, gid, handleEISDIR(cpath, uid, gid, er => {70    // Skip ENOENT error71    cb(er && er.code !== 'ENOENT' ? er : null)72  }))73}74 75const chownrKid = (p, child, uid, gid, cb) => {76  if (typeof child === 'string')77    return fs.lstat(path.resolve(p, child), (er, stats) => {78      // Skip ENOENT error79      if (er)80        return cb(er.code !== 'ENOENT' ? er : null)81      stats.name = child82      chownrKid(p, stats, uid, gid, cb)83    })84 85  if (child.isDirectory()) {86    chownr(path.resolve(p, child.name), uid, gid, er => {87      if (er)88        return cb(er)89      const cpath = path.resolve(p, child.name)90      chown(cpath, uid, gid, cb)91    })92  } else {93    const cpath = path.resolve(p, child.name)94    chown(cpath, uid, gid, cb)95  }96}97 98 99const chownr = (p, uid, gid, cb) => {100  readdir(p, { withFileTypes: true }, (er, children) => {101    // any error other than ENOTDIR or ENOTSUP means it's not readable,102    // or doesn't exist.  give up.103    if (er) {104      if (er.code === 'ENOENT')105        return cb()106      else if (er.code !== 'ENOTDIR' && er.code !== 'ENOTSUP')107        return cb(er)108    }109    if (er || !children.length)110      return chown(p, uid, gid, cb)111 112    let len = children.length113    let errState = null114    const then = er => {115      if (errState)116        return117      if (er)118        return cb(errState = er)119      if (-- len === 0)120        return chown(p, uid, gid, cb)121    }122 123    children.forEach(child => chownrKid(p, child, uid, gid, then))124  })125}126 127const chownrKidSync = (p, child, uid, gid) => {128  if (typeof child === 'string') {129    try {130      const stats = fs.lstatSync(path.resolve(p, child))131      stats.name = child132      child = stats133    } catch (er) {134      if (er.code === 'ENOENT')135        return136      else137        throw er138    }139  }140 141  if (child.isDirectory())142    chownrSync(path.resolve(p, child.name), uid, gid)143 144  handleEISDirSync(path.resolve(p, child.name), uid, gid)145}146 147const chownrSync = (p, uid, gid) => {148  let children149  try {150    children = readdirSync(p, { withFileTypes: true })151  } catch (er) {152    if (er.code === 'ENOENT')153      return154    else if (er.code === 'ENOTDIR' || er.code === 'ENOTSUP')155      return handleEISDirSync(p, uid, gid)156    else157      throw er158  }159 160  if (children && children.length)161    children.forEach(child => chownrKidSync(p, child, uid, gid))162 163  return handleEISDirSync(p, uid, gid)164}165 166module.exports = chownr167chownr.sync = chownrSync168