Skip to content

Commit

Permalink
feat: add config for mode on file creation (pinojs#130)
Browse files Browse the repository at this point in the history
* Feat: Add config for mode on file creation

* Fix tests & add to README

- Use umask to reset the permissions mask
- Cater fow windows lack of ability to set permissions
- Add test for append

* Skip tests on windows
add readme link to fs.open()
  • Loading branch information
estherixz authored Jan 17, 2022
1 parent 01c8526 commit 4f2ffad
Show file tree
Hide file tree
Showing 5 changed files with 120 additions and 9 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ The options are:
to exceed `maxLength`, the data written is dropped and a `drop` event is emitted with the dropped data
* `sync`: perform writes synchronously (similar to `console.log`).
* `append`: appends writes to dest file instead of truncating it (default `true`).
* `mode`: specify the creating file `mode` (see [fs.open()](https://nodejs.org/api/fs.html#fsopenpath-flags-mode-callback) from Node.js core).
* `mkdir`: ensure directory for dest file exists when `true` (default `false`).
* `retryEAGAIN(err, writeBufferLen, remainingBufferLen)`: a function that will be called when sonic-boom
write/writeSync/flushSync encounters a EAGAIN error. If the return value is
Expand Down
13 changes: 8 additions & 5 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,13 @@ function openFile (file, sonic) {
}
}

const mode = sonic.append ? 'a' : 'w'
const flags = sonic.append ? 'a' : 'w'
const mode = sonic.mode

if (sonic.sync) {
try {
if (sonic.mkdir) fs.mkdirSync(path.dirname(file), { recursive: true })
const fd = fs.openSync(file, mode)
const fd = fs.openSync(file, flags, mode)
fileOpened(null, fd)
} catch (err) {
fileOpened(err)
Expand All @@ -75,10 +77,10 @@ function openFile (file, sonic) {
} else if (sonic.mkdir) {
fs.mkdir(path.dirname(file), { recursive: true }, (err) => {
if (err) return fileOpened(err)
fs.open(file, mode, fileOpened)
fs.open(file, flags, mode, fileOpened)
})
} else {
fs.open(file, mode, fileOpened)
fs.open(file, flags, mode, fileOpened)
}
}

Expand All @@ -87,7 +89,7 @@ function SonicBoom (opts) {
return new SonicBoom(opts)
}

let { fd, dest, minLength, maxLength, sync, append = true, mkdir, retryEAGAIN } = opts || {}
let { fd, dest, minLength, maxLength, sync, append = true, mode, mkdir, retryEAGAIN } = opts || {}

fd = fd || dest

Expand All @@ -106,6 +108,7 @@ function SonicBoom (opts) {
this.maxLength = maxLength || 0
this.sync = sync || false
this.append = append || false
this.mode = mode
this.retryEAGAIN = retryEAGAIN || (() => true)
this.mkdir = mkdir || false

Expand Down
108 changes: 107 additions & 1 deletion test.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ const path = require('path')
const proxyquire = require('proxyquire')
const SonicBoom = require('.')

const isWindows = process.platform === 'win32'

const MAX_WRITE = 64 * 1024
const files = []
let count = 0
Expand Down Expand Up @@ -43,6 +45,9 @@ test('sync true', (t) => {
})

function buildTests (test, sync) {
// Reset the umask for testing
process.umask(0o000)

test('write things to a file descriptor', (t) => {
t.plan(6)

Expand Down Expand Up @@ -638,7 +643,7 @@ function buildTests (test, sync) {
throw new Error('open error')
}
} else {
fakeFs.open = function (file, flags, cb) {
fakeFs.open = function (file, flags, mode, cb) {
t.pass('fake fs.open called')
setTimeout(() => cb(new Error('open error')), 0)
}
Expand Down Expand Up @@ -670,6 +675,107 @@ function buildTests (test, sync) {
}, 0)
})
})

test('mode', { skip: isWindows }, (t) => {
t.plan(6)

const dest = file()
const mode = 0o666
const stream = new SonicBoom({ dest, sync, mode })

stream.on('ready', () => {
t.pass('ready emitted')
})

t.ok(stream.write('hello world\n'))
t.ok(stream.write('something else\n'))

stream.end()

stream.on('finish', () => {
fs.readFile(dest, 'utf8', (err, data) => {
t.error(err)
t.equal(data, 'hello world\nsomething else\n')
t.equal(fs.statSync(dest).mode & 0o777, stream.mode)
})
})
})

test('mode default', { skip: isWindows }, (t) => {
t.plan(6)

const dest = file()
const defaultMode = 0o666
const stream = new SonicBoom({ dest, sync })

stream.on('ready', () => {
t.pass('ready emitted')
})

t.ok(stream.write('hello world\n'))
t.ok(stream.write('something else\n'))

stream.end()

stream.on('finish', () => {
fs.readFile(dest, 'utf8', (err, data) => {
t.error(err)
t.equal(data, 'hello world\nsomething else\n')
t.equal(fs.statSync(dest).mode & 0o777, defaultMode)
})
})
})

test('mode on mkdir', { skip: isWindows }, (t) => {
t.plan(5)

const dest = path.join(file(), 'out.log')
const mode = 0o666
const stream = new SonicBoom({ dest, mkdir: true, mode, sync })

stream.on('ready', () => {
t.pass('ready emitted')
})

t.ok(stream.write('hello world\n'))

stream.flush()

stream.on('drain', () => {
fs.readFile(dest, 'utf8', (err, data) => {
t.error(err)
t.equal(data, 'hello world\n')
t.equal(fs.statSync(dest).mode & 0o777, stream.mode)
stream.end()
})
})
})

test('mode on append', { skip: isWindows }, (t) => {
t.plan(5)

const dest = file()
fs.writeFileSync(dest, 'hello world\n', 'utf8', 0o422)
const mode = isWindows ? 0o444 : 0o666
const stream = new SonicBoom({ dest, append: false, mode, sync })

stream.on('ready', () => {
t.pass('ready emitted')
})

t.ok(stream.write('something else\n'))

stream.flush()

stream.on('drain', () => {
fs.readFile(dest, 'utf8', (err, data) => {
t.error(err)
t.equal(data, 'something else\n')
t.equal(fs.statSync(dest).mode & 0o777, stream.mode)
stream.end()
})
})
})
}

test('drain deadlock', (t) => {
Expand Down
1 change: 1 addition & 0 deletions types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export type SonicBoomOpts = {
minLength?: number
sync?: boolean
append?: boolean
mode?: string | number
mkdir?: boolean
retryEAGAIN?: (err: Error, writeBufferLen: number, remainingBufferLen: number) => boolean
}
Expand Down
6 changes: 3 additions & 3 deletions types/index.test-d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ sonic.end();

sonic.destroy();

const extraSonic = new SonicBoom({fd: 1, minLength: 0, sync: true, append: true, mkdir: true});
const sonicDest = new SonicBoom({fd: 1, minLength: 0, sync: true, append: true, mkdir: true, dest: '/dev/null'});
const sonicDest2 = new SonicBoom({fd: 1, minLength: 0, sync: true, append: true, mkdir: true, dest: 1});
const extraSonic = new SonicBoom({fd: 1, minLength: 0, sync: true, append: true, mode: 0o644, mkdir: true});
const sonicDest = new SonicBoom({fd: 1, minLength: 0, sync: true, append: true, mode: 0o644, mkdir: true, dest: '/dev/null'});
const sonicDest2 = new SonicBoom({fd: 1, minLength: 0, sync: true, append: true, mode: 0o644, mkdir: true, dest: 1});

extraSonic.write('extra sonic\n');

0 comments on commit 4f2ffad

Please sign in to comment.