Skip to content

Commit

Permalink
BREAKING: Use bigint everywhere (#895)
Browse files Browse the repository at this point in the history
Refs #886
  • Loading branch information
RyanZim committed Apr 30, 2021
1 parent c551140 commit 588d770
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 49 deletions.
18 changes: 3 additions & 15 deletions lib/util/__tests__/stat.test.js
Expand Up @@ -4,11 +4,8 @@ const fs = require(process.cwd())
const os = require('os')
const path = require('path')
const assert = require('assert')
const atLeastNode = require('at-least-node')
const stat = require('../stat.js')

const NODE_VERSION_WITH_BIGINT = '10.5.0'

/* global beforeEach, afterEach, describe, it */

describe('util/stat', () => {
Expand All @@ -21,20 +18,15 @@ describe('util/stat', () => {

afterEach(done => fs.remove(TEST_DIR, done))

describe('should use stats with bigint type for node versions >= 10.5.0 and number type for older versions', () => {
describe('should use stats with bigint type', () => {
it('stat.checkPaths()', () => {
const src = path.join(TEST_DIR, 'src')
const dest = path.join(TEST_DIR, 'dest')
fs.ensureFileSync(src)
fs.ensureFileSync(dest)
stat.checkPaths(src, dest, 'copy', {}, (err, stats) => {
assert.ifError(err)
const { srcStat } = stats
if (atLeastNode(NODE_VERSION_WITH_BIGINT)) {
assert.strictEqual(typeof srcStat.ino, 'bigint')
} else {
assert.strictEqual(typeof srcStat.ino, 'number')
}
assert.strictEqual(typeof stats.srcStat.ino, 'bigint')
})
})

Expand All @@ -44,11 +36,7 @@ describe('util/stat', () => {
fs.ensureFileSync(src)
fs.ensureFileSync(dest)
const { srcStat } = stat.checkPathsSync(src, dest, 'copy', {})
if (atLeastNode(NODE_VERSION_WITH_BIGINT)) {
assert.strictEqual(typeof srcStat.ino, 'bigint')
} else {
assert.strictEqual(typeof srcStat.ino, 'number')
}
assert.strictEqual(typeof srcStat.ino, 'bigint')
})
})

Expand Down
44 changes: 10 additions & 34 deletions lib/util/stat.js
Expand Up @@ -3,16 +3,11 @@
const fs = require('../fs')
const path = require('path')
const util = require('util')
const atLeastNode = require('at-least-node')

const nodeSupportsBigInt = atLeastNode('10.5.0')
const stat = (file) => nodeSupportsBigInt ? fs.stat(file, { bigint: true }) : fs.stat(file)
const lstat = (file) => nodeSupportsBigInt ? fs.lstat(file, { bigint: true }) : fs.lstat(file)
const statSync = (file) => nodeSupportsBigInt ? fs.statSync(file, { bigint: true }) : fs.statSync(file)
const lstatSync = (file) => nodeSupportsBigInt ? fs.lstatSync(file, { bigint: true }) : fs.lstatSync(file)

function getStats (src, dest, opts) {
const statFunc = opts.dereference ? stat : lstat
const statFunc = opts.dereference
? (file) => fs.stat(file, { bigint: true })
: (file) => fs.lstat(file, { bigint: true })
return Promise.all([
statFunc(src),
statFunc(dest).catch(err => {
Expand All @@ -24,7 +19,9 @@ function getStats (src, dest, opts) {

function getStatsSync (src, dest, opts) {
let destStat
const statFunc = opts.dereference ? statSync : lstatSync
const statFunc = opts.dereference
? (file) => fs.statSync(file, { bigint: true })
: (file) => fs.lstatSync(file, { bigint: true })
const srcStat = statFunc(src)
try {
destStat = statFunc(dest)
Expand Down Expand Up @@ -102,7 +99,7 @@ function checkParentPaths (src, srcStat, dest, funcName, cb) {
const srcParent = path.resolve(path.dirname(src))
const destParent = path.resolve(path.dirname(dest))
if (destParent === srcParent || destParent === path.parse(destParent).root) return cb()
const callback = (err, destStat) => {
fs.stat(destParent, { bigint: true }, (err, destStat) => {
if (err) {
if (err.code === 'ENOENT') return cb()
return cb(err)
Expand All @@ -111,9 +108,7 @@ function checkParentPaths (src, srcStat, dest, funcName, cb) {
return cb(new Error(errMsg(src, dest, funcName)))
}
return checkParentPaths(src, srcStat, destParent, funcName, cb)
}
if (nodeSupportsBigInt) fs.stat(destParent, { bigint: true }, callback)
else fs.stat(destParent, callback)
})
}

function checkParentPathsSync (src, srcStat, dest, funcName) {
Expand All @@ -122,7 +117,7 @@ function checkParentPathsSync (src, srcStat, dest, funcName) {
if (destParent === srcParent || destParent === path.parse(destParent).root) return
let destStat
try {
destStat = statSync(destParent)
destStat = fs.statSync(destParent, { bigint: true })
} catch (err) {
if (err.code === 'ENOENT') return
throw err
Expand All @@ -134,26 +129,7 @@ function checkParentPathsSync (src, srcStat, dest, funcName) {
}

function areIdentical (srcStat, destStat) {
if (destStat.ino && destStat.dev && destStat.ino === srcStat.ino && destStat.dev === srcStat.dev) {
if (nodeSupportsBigInt || destStat.ino < Number.MAX_SAFE_INTEGER) {
// definitive answer
return true
}
// Use additional heuristics if we can't use 'bigint'.
// Different 'ino' could be represented the same if they are >= Number.MAX_SAFE_INTEGER
// See issue 657
if (destStat.size === srcStat.size &&
destStat.mode === srcStat.mode &&
destStat.nlink === srcStat.nlink &&
destStat.atimeMs === srcStat.atimeMs &&
destStat.mtimeMs === srcStat.mtimeMs &&
destStat.ctimeMs === srcStat.ctimeMs &&
destStat.birthtimeMs === srcStat.birthtimeMs) {
// heuristic answer
return true
}
}
return false
return destStat.ino && destStat.dev && destStat.ino === srcStat.ino && destStat.dev === srcStat.dev
}

// return true if dest is a subdir of src, otherwise false.
Expand Down

0 comments on commit 588d770

Please sign in to comment.