memfs
memfs copied to clipboard
`readdir` on a symlinked dir fails with `ENOTDIR: not a directory, scandir '/foo'`
const {fs} = require('memfs')
const realFs = require('fs')
realFs.readdirSync('/')
realFs.symlinkSync('/', '/foo')
realFs.readdirSync('/')
realFs.readdirSync('/foo') // works
console.log('works')
fs.readdirSync('/')
fs.symlinkSync('/', '/foo')
fs.readdirSync('/')
fs.readdirSync('/foo') // fails
https://runkit.com/vjpr/5a87383e1ff7740012733bd1
Please see: https://github.com/streamich/memfs/pull/101
I think I fixed it with this line: https://github.com/streamich/memfs/pull/101/commits/0cf18dd3784f7079a8647d930edb5cf512bbcf21#diff-237b96688267edc5b8448d6322f36d8dL1477
@streamich BTW master version is 2.5.10. Latest published is 2.7.0.
Also, could you publish this version? Or add a post-install build step so that I can install from git.
When using globby when I run:
import glob from 'globby'
vol.writeFileSync('/app/foo.json', 'foo')
glob.sync('/app')
vol.symlinkSync('/app', '/app/foo')
glob.sync('/app') // This is empty array.
The second glob returns an empty array.
However, fs.readdirSync now works when reading the symlinked dir.
semantic-release should publish it automatically, hmmm, but it looks like it does not, I'll take a look.
with regards to globby:
How do you tell it to use memfs?
patcher.js
import {Volume} from 'memfs'
import {patchFs} from 'fs-monkey'
import {ufs} from 'unionfs'
import * as originalFs from 'fs'
let vol
function start() {
vol = new Volume()
ufs.use(vol).use(originalFs)
patchFs(ufs)
}
start()
export function reset() {
vol.reset()
}
export {vol}
import {vol} from './patcher'
// do stuff with vol
vol.reset()
NOTE: globby uses node-glob
Published manually under 2.7.1, will take a look at globby.
fast-glob internally uses readdir-enhanced and that seems to work:
const glob = require('globby');
const {Volume} = require('../lib/volume');
const {patchFs} = require('fs-monkey');
const {ufs} = require('unionfs');
const fs = require('fs');
var readdir = require('readdir-enhanced');
let vol
function start() {
vol = new Volume()
ufs.use(fs).use(vol);
patchFs(ufs)
}
start()
function reset() {
vol.reset()
}
// console.log('vol', vol);
vol.mkdirpSync('/app2');
vol.writeFileSync('/app2/foo.json', 'foo')
var files = readdir.sync('/app2');
console.log(files);
So, it must be something in globby or fast-glob, or glob.
Also globby has both, fast-glob and glob in its dependencies.
fast-glob does not seem to work with memfs, don't know why, giving it up for now.
fast-glob is swallowing errors in node_modules/fast-glob/out/providers/reader-sync.js:38.
Here is the error it was swallowing:
{ Error: ENOENT: no such file or directory, lstat '/dev/fd/12'
at createError (xxx/mock-fs-with-memfs/node_modules/.registry.npmjs.org/memfs/2.7.1/node_modules/memfs/lib/volume.js:105:17)
at throwError (xxx/mock-fs-with-memfs/node_modules/.registry.npmjs.org/memfs/2.7.1/node_modules/memfs/lib/volume.js:114:11)
at Volume.lstatBase (xxx/mock-fs-with-memfs/node_modules/.registry.npmjs.org/memfs/2.7.1/node_modules/memfs/lib/volume.js:1116:13)
at Volume.lstatSync (xxx/mock-fs-with-memfs/node_modules/.registry.npmjs.org/memfs/2.7.1/node_modules/memfs/lib/volume.js:1120:21)
at Union.syncMethod (xxx/mock-fs-with-memfs/node_modules/.registry.npmjs.org/unionfs/3.0.2/node_modules/unionfs/lib/union.js:61:35)
at Union.this_1.(anonymous function) [as lstatSync] (xxx/mock-fs-with-memfs/node_modules/.registry.npmjs.org/unionfs/3.0.2/node_modules/unionfs/lib/union.js:17:30)
at exports.lstat (xxx/xxx/node_modules/.registry.npmjs.org/@mrmlnc/readdir-enhanced/2.2.1/node_modules/@mrmlnc/readdir-enhanced/lib/sync/fs.js:58:20)
at Object.safeCall [as safe] (xxx/xxx/node_modules/.registry.npmjs.org/@mrmlnc/readdir-enhanced/2.2.1/node_modules/@mrmlnc/readdir-enhanced/lib/call.js:24:8)
at stat (xxx/xxx/node_modules/.registry.npmjs.org/@mrmlnc/readdir-enhanced/2.2.1/node_modules/@mrmlnc/readdir-enhanced/lib/stat.js:19:8)
at DirectoryReader.processItem (xxx/xxx/node_modules/.registry.npmjs.org/@mrmlnc/readdir-enhanced/2.2.1/node_modules/@mrmlnc/readdir-enhanced/lib/directory-reader.js:178:5)
at array.forEach.item (xxx/xxx/node_modules/.registry.npmjs.org/@mrmlnc/readdir-enhanced/2.2.1/node_modules/@mrmlnc/readdir-enhanced/lib/sync/for-each.js:14:5)
at Array.forEach (<anonymous>)
at Object.syncForEach [as forEach] (xxx/xxx/node_modules/.registry.npmjs.org/@mrmlnc/readdir-enhanced/2.2.1/node_modules/@mrmlnc/readdir-enhanced/lib/sync/for-each.js:13:9)
at call.safe (xxx/xxx/node_modules/.registry.npmjs.org/@mrmlnc/readdir-enhanced/2.2.1/node_modules/@mrmlnc/readdir-enhanced/lib/directory-reader.js:87:16)
at onceWrapper (xxx/xxx/node_modules/.registry.npmjs.org/@mrmlnc/readdir-enhanced/2.2.1/node_modules/@mrmlnc/readdir-enhanced/lib/call.js:45:17)
at onceWrapper (xxx/xxx/node_modules/.registry.npmjs.org/@mrmlnc/readdir-enhanced/2.2.1/node_modules/@mrmlnc/readdir-enhanced/lib/call.js:45:17)
at exports.readdir (xxx/xxx/node_modules/.registry.npmjs.org/@mrmlnc/readdir-enhanced/2.2.1/node_modules/@mrmlnc/readdir-enhanced/lib/sync/fs.js:19:5)
at Object.safeCall [as safe] (xxx/xxx/node_modules/.registry.npmjs.org/@mrmlnc/readdir-enhanced/2.2.1/node_modules/@mrmlnc/readdir-enhanced/lib/call.js:24:8)
at DirectoryReader.readNextDirectory (xxx/xxx/node_modules/.registry.npmjs.org/@mrmlnc/readdir-enhanced/2.2.1/node_modules/@mrmlnc/readdir-enhanced/lib/directory-reader.js:78:10)
at Readable.DirectoryReader.stream._read (xxx/xxx/node_modules/.registry.npmjs.org/@mrmlnc/readdir-enhanced/2.2.1/node_modules/@mrmlnc/readdir-enhanced/lib/directory-reader.js:57:18)
at Readable.read (_stream_readable.js:442:10)
at readdirSync (xxx/xxx/node_modules/.registry.npmjs.org/@mrmlnc/readdir-enhanced/2.2.1/node_modules/@mrmlnc/readdir-enhanced/lib/sync/index.js:27:21)
at Function.readdirSyncStat (xxx/xxx/node_modules/.registry.npmjs.org/@mrmlnc/readdir-enhanced/2.2.1/node_modules/@mrmlnc/readdir-enhanced/lib/index.js:34:10)
at ReaderSync.api (xxx/xxx/node_modules/.registry.npmjs.org/fast-glob/2.0.4/node_modules/fast-glob/out/providers/reader-sync.js:24:24)
at ReaderSync.read (xxx/xxx/node_modules/.registry.npmjs.org/fast-glob/2.0.4/node_modules/fast-glob/out/providers/reader-sync.js:33:32)
at Array.map (<anonymous>)
at getWorks (xxx/xxx/node_modules/.registry.npmjs.org/fast-glob/2.0.4/node_modules/fast-glob/out/index.js:18:18)
at Function.sync (xxx/xxx/node_modules/.registry.npmjs.org/fast-glob/2.0.4/node_modules/fast-glob/out/index.js:24:17)
at Test.fn (xxx/xxx/index.test.js:45:18)
at Test.callFn (xxx/xxx/node_modules/.registry.npmjs.org/ava/0.23.0/node_modules/ava/lib/test.js:305:18)
at Test.run (xxx/xxx/node_modules/.registry.npmjs.org/ava/0.23.0/node_modules/ava/lib/test.js:318:23)
at runNext (xxx/xxx/node_modules/.registry.npmjs.org/ava/0.23.0/node_modules/ava/lib/sequence.js:58:44)
at Sequence.run (xxx/xxx/node_modules/.registry.npmjs.org/ava/0.23.0/node_modules/ava/lib/sequence.js:90:10)
at Concurrent.run (xxx/xxx/node_modules/.registry.npmjs.org/ava/0.23.0/node_modules/ava/lib/concurrent.js:41:37)
at runNext (xxx/xxx/node_modules/.registry.npmjs.org/ava/0.23.0/node_modules/ava/lib/sequence.js:58:44)
at Sequence.run (xxx/xxx/node_modules/.registry.npmjs.org/ava/0.23.0/node_modules/ava/lib/sequence.js:90:10)
at runNext (xxx/xxx/node_modules/.registry.npmjs.org/ava/0.23.0/node_modules/ava/lib/sequence.js:58:44)
at Sequence.run (xxx/xxx/node_modules/.registry.npmjs.org/ava/0.23.0/node_modules/ava/lib/sequence.js:90:10)
at Bluebird.try (xxx/xxx/node_modules/.registry.npmjs.org/ava/0.23.0/node_modules/ava/lib/runner.js:224:48)
at tryCatcher (xxx/xxx/node_modules/.registry.npmjs.org/bluebird/3.5.1/node_modules/bluebird/js/release/util.js:16:23)
at Function.Promise.attempt.Promise.try (xxx/xxx/node_modules/.registry.npmjs.org/bluebird/3.5.1/node_modules/bluebird/js/release/method.js:39:29)
at Runner.run (xxx/xxx/node_modules/.registry.npmjs.org/ava/0.23.0/node_modules/ava/lib/runner.js:224:22)
at process.on.options (xxx/xxx/node_modules/.registry.npmjs.org/ava/0.23.0/node_modules/ava/lib/main.js:84:10)
at emitOne (events.js:116:13)
at process.emit (events.js:211:7)
at process.on.message (xxx/xxx/node_modules/.registry.npmjs.org/ava/0.23.0/node_modules/ava/lib/process-adapter.js:14:10)
at emitTwo (events.js:126:13)
at process.emit (events.js:214:7)
at emit (internal/child_process.js:772:12)
at _combinedTickCallback (internal/process/next_tick.js:141:11)
at process._tickCallback (internal/process/next_tick.js:180:9)
code: 'ENOENT',
prev:
{ Error: EBADF: bad file descriptor, lstat '/dev/fd/12'
at Object.fs.lstatSync (fs.js:941:11)
at Union.syncMethod (xxx/mock-fs-with-memfs/node_modules/.registry.npmjs.org/unionfs/3.0.2/node_modules/unionfs/lib/union.js:61:35)
at Union.this_1.(anonymous function) [as lstatSync] (xxx/mock-fs-with-memfs/node_modules/.registry.npmjs.org/unionfs/3.0.2/node_modules/unionfs/lib/union.js:17:30)
at exports.lstat (xxx/xxx/node_modules/.registry.npmjs.org/@mrmlnc/readdir-enhanced/2.2.1/node_modules/@mrmlnc/readdir-enhanced/lib/sync/fs.js:58:20)
at Object.safeCall [as safe] (xxx/xxx/node_modules/.registry.npmjs.org/@mrmlnc/readdir-enhanced/2.2.1/node_modules/@mrmlnc/readdir-enhanced/lib/call.js:24:8)
at stat (xxx/xxx/node_modules/.registry.npmjs.org/@mrmlnc/readdir-enhanced/2.2.1/node_modules/@mrmlnc/readdir-enhanced/lib/stat.js:19:8)
at DirectoryReader.processItem (xxx/xxx/node_modules/.registry.npmjs.org/@mrmlnc/readdir-enhanced/2.2.1/node_modules/@mrmlnc/readdir-enhanced/lib/directory-reader.js:178:5)
at array.forEach.item (xxx/xxx/node_modules/.registry.npmjs.org/@mrmlnc/readdir-enhanced/2.2.1/node_modules/@mrmlnc/readdir-enhanced/lib/sync/for-each.js:14:5)
at Array.forEach (<anonymous>)
at Object.syncForEach [as forEach] (xxx/xxx/node_modules/.registry.npmjs.org/@mrmlnc/readdir-enhanced/2.2.1/node_modules/@mrmlnc/readdir-enhanced/lib/sync/for-each.js:13:9)
at call.safe (xxx/xxx/node_modules/.registry.npmjs.org/@mrmlnc/readdir-enhanced/2.2.1/node_modules/@mrmlnc/readdir-enhanced/lib/directory-reader.js:87:16)
at onceWrapper (xxx/xxx/node_modules/.registry.npmjs.org/@mrmlnc/readdir-enhanced/2.2.1/node_modules/@mrmlnc/readdir-enhanced/lib/call.js:45:17)
at onceWrapper (xxx/xxx/node_modules/.registry.npmjs.org/@mrmlnc/readdir-enhanced/2.2.1/node_modules/@mrmlnc/readdir-enhanced/lib/call.js:45:17)
at exports.readdir (xxx/xxx/node_modules/.registry.npmjs.org/@mrmlnc/readdir-enhanced/2.2.1/node_modules/@mrmlnc/readdir-enhanced/lib/sync/fs.js:19:5)
at Object.safeCall [as safe] (xxx/xxx/node_modules/.registry.npmjs.org/@mrmlnc/readdir-enhanced/2.2.1/node_modules/@mrmlnc/readdir-enhanced/lib/call.js:24:8)
at DirectoryReader.readNextDirectory (xxx/xxx/node_modules/.registry.npmjs.org/@mrmlnc/readdir-enhanced/2.2.1/node_modules/@mrmlnc/readdir-enhanced/lib/directory-reader.js:78:10)
at Readable.DirectoryReader.stream._read (xxx/xxx/node_modules/.registry.npmjs.org/@mrmlnc/readdir-enhanced/2.2.1/node_modules/@mrmlnc/readdir-enhanced/lib/directory-reader.js:57:18)
at Readable.read (_stream_readable.js:442:10)
at readdirSync (xxx/xxx/node_modules/.registry.npmjs.org/@mrmlnc/readdir-enhanced/2.2.1/node_modules/@mrmlnc/readdir-enhanced/lib/sync/index.js:27:21)
at Function.readdirSyncStat (xxx/xxx/node_modules/.registry.npmjs.org/@mrmlnc/readdir-enhanced/2.2.1/node_modules/@mrmlnc/readdir-enhanced/lib/index.js:34:10)
at ReaderSync.api (xxx/xxx/node_modules/.registry.npmjs.org/fast-glob/2.0.4/node_modules/fast-glob/out/providers/reader-sync.js:24:24)
at ReaderSync.read (xxx/xxx/node_modules/.registry.npmjs.org/fast-glob/2.0.4/node_modules/fast-glob/out/providers/reader-sync.js:33:32)
at Array.map (<anonymous>)
at getWorks (xxx/xxx/node_modules/.registry.npmjs.org/fast-glob/2.0.4/node_modules/fast-glob/out/index.js:18:18)
at Function.sync (xxx/xxx/node_modules/.registry.npmjs.org/fast-glob/2.0.4/node_modules/fast-glob/out/index.js:24:17)
at Test.fn (xxx/xxx/index.test.js:45:18)
at Test.callFn (xxx/xxx/node_modules/.registry.npmjs.org/ava/0.23.0/node_modules/ava/lib/test.js:305:18)
at Test.run (xxx/xxx/node_modules/.registry.npmjs.org/ava/0.23.0/node_modules/ava/lib/test.js:318:23)
at runNext (xxx/xxx/node_modules/.registry.npmjs.org/ava/0.23.0/node_modules/ava/lib/sequence.js:58:44)
at Sequence.run (xxx/xxx/node_modules/.registry.npmjs.org/ava/0.23.0/node_modules/ava/lib/sequence.js:90:10)
at Concurrent.run (xxx/xxx/node_modules/.registry.npmjs.org/ava/0.23.0/node_modules/ava/lib/concurrent.js:41:37)
at runNext (xxx/xxx/node_modules/.registry.npmjs.org/ava/0.23.0/node_modules/ava/lib/sequence.js:58:44)
at Sequence.run (xxx/xxx/node_modules/.registry.npmjs.org/ava/0.23.0/node_modules/ava/lib/sequence.js:90:10)
at runNext (xxx/xxx/node_modules/.registry.npmjs.org/ava/0.23.0/node_modules/ava/lib/sequence.js:58:44)
at Sequence.run (xxx/xxx/node_modules/.registry.npmjs.org/ava/0.23.0/node_modules/ava/lib/sequence.js:90:10)
at Bluebird.try (xxx/xxx/node_modules/.registry.npmjs.org/ava/0.23.0/node_modules/ava/lib/runner.js:224:48)
at tryCatcher (xxx/xxx/node_modules/.registry.npmjs.org/bluebird/3.5.1/node_modules/bluebird/js/release/util.js:16:23)
at Function.Promise.attempt.Promise.try (xxx/xxx/node_modules/.registry.npmjs.org/bluebird/3.5.1/node_modules/bluebird/js/release/method.js:39:29)
at Runner.run (xxx/xxx/node_modules/.registry.npmjs.org/ava/0.23.0/node_modules/ava/lib/runner.js:224:22)
at process.on.options (xxx/xxx/node_modules/.registry.npmjs.org/ava/0.23.0/node_modules/ava/lib/main.js:84:10)
at emitOne (events.js:116:13)
at process.emit (events.js:211:7)
at process.on.message (xxx/xxx/node_modules/.registry.npmjs.org/ava/0.23.0/node_modules/ava/lib/process-adapter.js:14:10)
at emitTwo (events.js:126:13)
at process.emit (events.js:214:7)
at emit (internal/child_process.js:772:12)
at _combinedTickCallback (internal/process/next_tick.js:141:11)
at process._tickCallback (internal/process/next_tick.js:180:9)
errno: -9,
code: 'EBADF',
syscall: 'lstat',
path: '/dev/fd/12',
prev: null } } }
Looks like its a fast-glob issue: https://github.com/mrmlnc/fast-glob/issues/62
@streamich https://github.com/mrmlnc/fast-glob/issues/62#issuecomment-366525852
@vjpr is there a minimal reproducible example? Because if I do this
const { Volume } = require('../src/volume');
const vol = new Volume;
vol.mkdirpSync('./app');
vol.writeFileSync('./app/foo.json', 'foo')
vol.symlinkSync('./app', './app/foo')
console.log('fs', vol.readdirSync('./app'));
console.log('fs', vol.readdirSync('./app/foo'));
it works fine
fs [ 'foo', 'foo.json' ]
fs [ 'foo', 'foo.json' ]