Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: do not alter file ownership #5703

Merged
merged 1 commit into from
Oct 17, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 0 additions & 3 deletions DEPENDENCIES.md
Original file line number Diff line number Diff line change
Expand Up @@ -814,8 +814,6 @@ graph LR;
npmcli-arborist-->json-stringify-nice;
npmcli-arborist-->minify-registry-metadata;
npmcli-arborist-->minimatch;
npmcli-arborist-->mkdirp-infer-owner;
npmcli-arborist-->mkdirp;
npmcli-arborist-->nock;
npmcli-arborist-->nopt;
npmcli-arborist-->npm-install-checks;
Expand All @@ -841,7 +839,6 @@ graph LR;
npmcli-arborist-->promise-call-limit;
npmcli-arborist-->read-package-json-fast;
npmcli-arborist-->readdir-scoped-modules;
npmcli-arborist-->rimraf;
npmcli-arborist-->semver;
npmcli-arborist-->ssri;
npmcli-arborist-->tap;
Expand Down
3 changes: 0 additions & 3 deletions package-lock.json
Original file line number Diff line number Diff line change
Expand Up @@ -13778,8 +13778,6 @@
"json-parse-even-better-errors": "^2.3.1",
"json-stringify-nice": "^1.1.4",
"minimatch": "^5.1.0",
"mkdirp": "^1.0.4",
"mkdirp-infer-owner": "^2.0.0",
"nopt": "^6.0.0",
"npm-install-checks": "^5.0.0",
"npm-package-arg": "^9.0.0",
Expand All @@ -13793,7 +13791,6 @@
"promise-call-limit": "^1.0.1",
"read-package-json-fast": "^2.0.2",
"readdir-scoped-modules": "^1.1.0",
"rimraf": "^3.0.2",
"semver": "^7.3.7",
"ssri": "^9.0.0",
"treeverse": "^2.0.0",
Expand Down
3 changes: 1 addition & 2 deletions workspaces/arborist/bin/lib/logging.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
const log = require('proc-log')
const mkdirp = require('mkdirp')
const fs = require('fs')
const { dirname } = require('path')
const os = require('os')
Expand Down Expand Up @@ -70,7 +69,7 @@ if (options.loglevel !== 'silent') {

if (options.logfile) {
log.silly('logfile', options.logfile)
mkdirp.sync(dirname(options.logfile))
fs.mkdirSync(dirname(options.logfile), { recursive: true })
const fd = fs.openSync(options.logfile, 'a')
addLogListener((str) => fs.writeSync(fd, str))
}
Expand Down
2 changes: 1 addition & 1 deletion workspaces/arborist/docs/reify.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ Fail: rename each retired `.${name}-hash` folder back to `${name}`

### step 2: create sparse tree

Now that the shallowest changing nodes are retired, `mkdirp` all leaf
Now that the shallowest changing nodes are retired, `mkdir` all leaf
nodes.

```
Expand Down
4 changes: 1 addition & 3 deletions workspaces/arborist/lib/arborist/build-ideal-tree.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,7 @@ const { resolve, dirname } = require('path')
const { promisify } = require('util')
const treeCheck = require('../tree-check.js')
const readdir = promisify(require('readdir-scoped-modules'))
const fs = require('fs')
const lstat = promisify(fs.lstat)
const readlink = promisify(fs.readlink)
const { lstat, readlink } = require('fs/promises')
const { depth } = require('treeverse')
const log = require('proc-log')

Expand Down
42 changes: 21 additions & 21 deletions workspaces/arborist/lib/arborist/reify.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,13 @@ const log = require('proc-log')

const { dirname, resolve, relative } = require('path')
const { depth: dfwalk } = require('treeverse')
const fs = require('fs')
const { promisify } = require('util')
const lstat = promisify(fs.lstat)
const symlink = promisify(fs.symlink)
const mkdirp = require('mkdirp-infer-owner')
const justMkdirp = require('mkdirp')
const {
lstat,
mkdir,
rm,
symlink,
} = require('fs/promises')
const moveFile = require('@npmcli/move-file')
const rimraf = promisify(require('rimraf'))
const PackageJson = require('@npmcli/package-json')
const packageContents = require('@npmcli/installed-package-contents')
const runScript = require('@npmcli/run-script')
Expand Down Expand Up @@ -175,7 +174,7 @@ module.exports = cls => class Reifier extends cls {
// we do NOT want to set ownership on this folder, especially
// recursively, because it can have other side effects to do that
// in a project directory. We just want to make it if it's missing.
await justMkdirp(resolve(this.path))
await mkdir(resolve(this.path), { recursive: true })

// do not allow the top-level node_modules to be a symlink
await this[_validateNodeModules](resolve(this.path, 'node_modules'))
Expand Down Expand Up @@ -433,10 +432,10 @@ module.exports = cls => class Reifier extends cls {
// handled the most common cause of ENOENT (dir doesn't exist yet),
// then just ignore any ENOENT.
if (er.code === 'ENOENT') {
return didMkdirp ? null : mkdirp(dirname(to)).then(() =>
return didMkdirp ? null : mkdir(dirname(to), { recursive: true }).then(() =>
this[_renamePath](from, to, true))
} else if (er.code === 'EEXIST') {
return rimraf(to).then(() => moveFile(from, to))
return rm(to, { recursive: true, force: true }).then(() => moveFile(from, to))
} else {
throw er
}
Expand Down Expand Up @@ -518,7 +517,7 @@ module.exports = cls => class Reifier extends cls {
await this[_renamePath](d, retired)
}
}
const made = await mkdirp(node.path)
const made = await mkdir(node.path, { recursive: true })
this[_sparseTreeDirs].add(node.path)
this[_sparseTreeRoots].add(made)
}))
Expand All @@ -533,7 +532,7 @@ module.exports = cls => class Reifier extends cls {
const failures = []
const targets = [...roots, ...Object.keys(this[_retiredPaths])]
const unlinks = targets
.map(path => rimraf(path).catch(er => failures.push([path, er])))
.map(path => rm(path, { recursive: true, force: true }).catch(er => failures.push([path, er])))
return promiseAllRejectLate(unlinks).then(() => {
// eslint-disable-next-line promise/always-return
if (failures.length) {
Expand Down Expand Up @@ -630,7 +629,7 @@ module.exports = cls => class Reifier extends cls {
return
}
log.warn('reify', 'Removing non-directory', nm)
await rimraf(nm)
await rm(nm, { recursive: true, force: true })
}

async [_extractOrLink] (node) {
Expand Down Expand Up @@ -664,7 +663,7 @@ module.exports = cls => class Reifier extends cls {
await this[_validateNodeModules](nm)

if (node.isLink) {
await rimraf(node.path)
await rm(node.path, { recursive: true, force: true })
await this[_symlink](node)
} else {
await debug(async () => {
Expand All @@ -690,7 +689,7 @@ module.exports = cls => class Reifier extends cls {
const dir = dirname(node.path)
const target = node.realpath
const rel = relative(dir, target)
await mkdirp(dir)
await mkdir(dir, { recursive: true })
return symlink(rel, node.path, 'junction')
}

Expand Down Expand Up @@ -953,7 +952,7 @@ module.exports = cls => class Reifier extends cls {

// ok! actually unpack stuff into their target locations!
// The sparse tree has already been created, so we walk the diff
// kicking off each unpack job. If any fail, we rimraf the sparse
// kicking off each unpack job. If any fail, we rm the sparse
// tree entirely and try to put everything back where it was.
[_unpackNewModules] () {
process.emit('time', 'reify:unpack')
Expand Down Expand Up @@ -1034,7 +1033,8 @@ module.exports = cls => class Reifier extends cls {
return promiseAllRejectLate(diff.unchanged.map(node => {
// no need to roll back links, since we'll just delete them anyway
if (node.isLink) {
return mkdirp(dirname(node.path)).then(() => this[_reifyNode](node))
return mkdir(dirname(node.path), { recursive: true, force: true })
.then(() => this[_reifyNode](node))
}

// will have been moved/unpacked along with bundler
Expand All @@ -1050,7 +1050,7 @@ module.exports = cls => class Reifier extends cls {
// skip it.
const bd = node.package.bundleDependencies
const dir = bd && bd.length ? node.path + '/node_modules' : node.path
return mkdirp(dir).then(() => this[_moveContents](node, fromPath))
return mkdir(dir, { recursive: true }).then(() => this[_moveContents](node, fromPath))
}))
}))
.then(() => process.emit('timeEnd', 'reify:unretire'))
Expand Down Expand Up @@ -1124,15 +1124,15 @@ module.exports = cls => class Reifier extends cls {
// the tree is pretty much built now, so it's cleanup time.
// remove the retired folders, and any deleted nodes
// If this fails, there isn't much we can do but tell the user about it.
// Thankfully, it's pretty unlikely that it'll fail, since rimraf is a tank.
// Thankfully, it's pretty unlikely that it'll fail, since rm is a node builtin.
async [_removeTrash] () {
process.emit('time', 'reify:trash')
const promises = []
const failures = []
const rm = path => rimraf(path).catch(er => failures.push([path, er]))
const _rm = path => rm(path, { recursive: true, force: true }).catch(er => failures.push([path, er]))

for (const path of this[_trashList]) {
promises.push(rm(path))
promises.push(_rm(path))
}

await promiseAllRejectLate(promises)
Expand Down
5 changes: 1 addition & 4 deletions workspaces/arborist/lib/realpath.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,7 @@
// built-in fs.realpath, because we only care about symbolic links,
// so we can handle many fewer edge cases.

const fs = require('fs')
const promisify = require('util').promisify
const readlink = promisify(fs.readlink)
const lstat = promisify(fs.lstat)
const { lstat, readlink } = require('fs/promises')
const { resolve, basename, dirname } = require('path')

const realpathCached = (path, rpcache, stcache, depth) => {
Expand Down
34 changes: 9 additions & 25 deletions workspaces/arborist/lib/shrinkwrap.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,30 +35,14 @@ const mismatch = (a, b) => a && b && a !== b

const log = require('proc-log')
const YarnLock = require('./yarn-lock.js')
const { promisify } = require('util')
const rimraf = promisify(require('rimraf'))
const fs = require('fs')
const readFile = promisify(fs.readFile)
const writeFile = promisify(fs.writeFile)
const stat = promisify(fs.stat)
const readdir_ = promisify(fs.readdir)
const readlink = promisify(fs.readlink)

// XXX remove when drop support for node v10
const lstat = promisify(fs.lstat)
/* istanbul ignore next - version specific polyfill */
const readdir = async (path, opt) => {
if (!opt || !opt.withFileTypes) {
return readdir_(path, opt)
}
const ents = await readdir_(path, opt)
if (typeof ents[0] === 'string') {
return Promise.all(ents.map(async ent => {
return Object.assign(await lstat(path + '/' + ent), { name: ent })
}))
}
return ents
}
const {
readFile,
readdir,
readlink,
rm,
stat,
writeFile,
} = require('fs/promises')

const { resolve, basename, relative } = require('path')
const specFromLock = require('./spec-from-lock.js')
Expand Down Expand Up @@ -1153,7 +1137,7 @@ class Shrinkwrap {
// a node_modules folder, but then the lockfile is not important.
// Remove the file, so that in case there WERE deps, but we just
// failed to update the file for some reason, it's not out of sync.
return rimraf(this.filename)
return rm(this.filename, { recursive: true, force: true })
}
throw er
}),
Expand Down
3 changes: 0 additions & 3 deletions workspaces/arborist/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@
"json-parse-even-better-errors": "^2.3.1",
"json-stringify-nice": "^1.1.4",
"minimatch": "^5.1.0",
"mkdirp": "^1.0.4",
"mkdirp-infer-owner": "^2.0.0",
"nopt": "^6.0.0",
"npm-install-checks": "^5.0.0",
"npm-package-arg": "^9.0.0",
Expand All @@ -34,7 +32,6 @@
"promise-call-limit": "^1.0.1",
"read-package-json-fast": "^2.0.2",
"readdir-scoped-modules": "^1.1.0",
"rimraf": "^3.0.2",
"semver": "^7.3.7",
"ssri": "^9.0.0",
"treeverse": "^2.0.0",
Expand Down
11 changes: 4 additions & 7 deletions workspaces/arborist/scripts/benchmark.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
process.env.ARBORIST_DEBUG = '0'
const { Suite } = require('benchmark')
const { relative, resolve } = require('path')
const rimraf = require('rimraf')
const { mkdir, rm } = require('fs/promises')
const { execSync } = require('child_process')
const shaCmd = 'git show --no-patch --pretty=%H HEAD'
const dirty = !!String(execSync('git status -s -uno')).trim()
const currentSha = String(execSync(shaCmd)).trim() + (dirty ? '-dirty' : '')
const { green, red } = require('chalk')
const lastBenchmark = resolve(__dirname, 'benchmark/saved/last-benchmark.json')
const mkdirp = require('mkdirp')
const { linkSync, writeFileSync, readdirSync } = require('fs')
const registryServer = require('../test/fixtures/registry-mocks/server.js')

Expand Down Expand Up @@ -152,8 +151,8 @@ const suite = new Suite({
},

async onComplete () {
rimraf.sync(lastBenchmark)
mkdirp.sync(resolve(__dirname, 'benchmark/saved'))
await rm(lastBenchmark, { recursive: true, force: true })
await mkdir(resolve(__dirname, 'benchmark/saved'), { recursive: true })
// always save with sha
const saveThis = resolve(__dirname, `benchmark/saved/${this.sha}.json`)
const data = JSON.stringify(this.reduce((acc, bench) => {
Expand All @@ -171,9 +170,7 @@ const suite = new Suite({
await teardown()
await Promise.all([
registryServer.stop(),
new Promise((res, rej) => {
rimraf(this.cache, er => er ? rej(er) : res())
}),
rm(this.cache, { recursive: true, force: true }),
])
},
})
Expand Down
12 changes: 7 additions & 5 deletions workspaces/arborist/scripts/benchmark/load-actual.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
const Arborist = require('../..')
const { resolve, basename } = require('path')
const { writeFileSync } = require('fs')
const mkdirp = require('mkdirp')
const {
mkdir,
rm,
} = require('fs/promises')
const dir = resolve(__dirname, basename(__filename, '.js'))
const rimraf = require('rimraf')

const suite = async (suite, { registry, cache }) => {
// setup two folders, one with a hidden lockfile, one without
await mkdirp(resolve(dir, 'with-hidden-lockfile'))
await mkdirp(resolve(dir, 'no-hidden-lockfile'))
await mkdir(resolve(dir, 'with-hidden-lockfile'), { recursive: true })
await mkdir(resolve(dir, 'no-hidden-lockfile'), { recursive: true })

const dependencies = {
'flow-parser': '0.114.0',
Expand Down Expand Up @@ -43,7 +45,7 @@ const suite = async (suite, { registry, cache }) => {
dependencies,
}))
promises.push(await arb.reify().then(() =>
rimraf.sync(resolve(arb.path, 'node_modules', '.package-lock.json'))))
rm(resolve(arb.path, 'node_modules', '.package-lock.json'), { recursive: true, force: true })))
}
await Promise.all(promises)

Expand Down
12 changes: 6 additions & 6 deletions workspaces/arborist/scripts/benchmark/reify.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
const Arborist = require('../..')
const { resolve, basename } = require('path')
const { writeFileSync } = require('fs')
const mkdirp = require('mkdirp')
const { mkdir } = require('fs/promises')
const { rmSync } = require('fs')
const dir = resolve(__dirname, basename(__filename, '.js'))
const rimraf = require('rimraf')

// these are not arbitrary, the empty/full and no-* bits matter
const folders = [
Expand All @@ -19,7 +19,7 @@ const folders = [

const suite = async (suite, { registry, cache }) => {
// setup two folders, one with a hidden lockfile, one without
await Promise.all(folders.map(f => mkdirp(f)))
await Promise.all(folders.map(f => mkdir(f, { recursive: true })))

const dependencies = {
'flow-parser': '0.114.0',
Expand Down Expand Up @@ -86,13 +86,13 @@ const suite = async (suite, { registry, cache }) => {
defer: true,
setup () {
if (/no-lockfile/.test(path)) {
rimraf.sync(resolve(path, 'package-lock.json'))
rmSync(resolve(path, 'package-lock.json'), { recursive: true, force: true })
}
if (/empty/.test(path)) {
rimraf.sync(resolve(path, 'node_modules'))
rmSync(resolve(path, 'node_modules'), { recursive: true, force: true })
}
if (/no-cache/.test(path)) {
rimraf.sync(resolve(path, 'cache'))
rmSync(resolve(path, 'cache'), { recursive: true, force: true })
}
},
async fn (d) {
Expand Down