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

Improve ensurefile error #744

Merged
merged 6 commits into from Jan 31, 2020
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
26 changes: 26 additions & 0 deletions lib/ensure/__tests__/create.test.js
Expand Up @@ -42,6 +42,18 @@ describe('fs-extra', () => {
done()
})
})

it('should give clear error if node in directory tree is a file', done => {
const existingFile = path.join(TEST_DIR, Math.random() + 'ts-e', Math.random() + '.txt')
fse.mkdirsSync(path.dirname(existingFile))
fs.writeFileSync(existingFile)

const file = path.join(existingFile, Math.random() + '.txt')
fse.createFile(file, err => {
assert.strictEqual(err.code, 'ENOTDIR')
done()
})
})
})
})

Expand All @@ -63,6 +75,20 @@ describe('fs-extra', () => {
fse.createFileSync(file)
assert.strictEqual(fs.readFileSync(file, 'utf8'), 'hello world')
})

it('should give clear error if node in directory tree is a file', () => {
const existingFile = path.join(TEST_DIR, Math.random() + 'ts-e', Math.random() + '.txt')
fse.mkdirsSync(path.dirname(existingFile))
fs.writeFileSync(existingFile)

const file = path.join(existingFile, Math.random() + '.txt')
try {
fse.createFileSync(file)
assert.fail()
} catch (err) {
assert.strictEqual(err.code, 'ENOTDIR')
}
})
})
})
})
40 changes: 30 additions & 10 deletions lib/ensure/file.js
Expand Up @@ -4,7 +4,6 @@ const u = require('universalify').fromCallback
const path = require('path')
const fs = require('graceful-fs')
const mkdir = require('../mkdirs')
const pathExists = require('../path-exists').pathExists

function createFile (file, callback) {
function makeFile () {
Expand All @@ -17,13 +16,26 @@ function createFile (file, callback) {
fs.stat(file, (err, stats) => { // eslint-disable-line handle-callback-err
if (!err && stats.isFile()) return callback()
const dir = path.dirname(file)
pathExists(dir, (err, dirExists) => {
if (err) return callback(err)
if (dirExists) return makeFile()
mkdir.mkdirs(dir, err => {
if (err) return callback(err)
makeFile()
})
fs.stat(dir, (err, stats) => {
if (err) {
// if the directory doesn't exist, make it
if (err.code === 'ENOENT') {
return mkdir.mkdirs(dir, err => {
if (err) return callback(err)
makeFile()
})
}
return callback(err)
}

if (stats.isDirectory()) makeFile()
else {
// parent is not a directory
// This is just to cause an internal ENOTDIR error to be thrown
fs.readdir(dir, err => {
if (err) return callback(err)
})
}
})
})
}
Expand All @@ -36,8 +48,16 @@ function createFileSync (file) {
if (stats && stats.isFile()) return

const dir = path.dirname(file)
if (!fs.existsSync(dir)) {
mkdir.mkdirsSync(dir)
try {
if (!fs.statSync(dir).isDirectory()) {
// parent is not a directory
// This is just to cause an internal ENOTDIR error to be thrown
fs.readdirSync(dir)
}
} catch (err) {
// If the stat call above failed because the directory doesn't exist, create it
if (err && err.code === 'ENOENT') mkdir.mkdirsSync(dir)
else throw err
}

fs.writeFileSync(file, '')
Expand Down