Skip to content

Commit 4bf8250

Browse files
committed
feat!: esm, async/await, updates and add linting
1 parent 6ba1eb7 commit 4bf8250

4 files changed

Lines changed: 60 additions & 122 deletions

File tree

README.md

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,17 @@ Deserialise an file/directory tree into an object. Available in npm as *readfile
66

77
Particularly useful for testing where you need to do a `deepStrictEqual()` on a simple tree of files. **See [mkfiletree](https://github.com/rvagg/mkfiletree) for file tree serialisation.**
88

9-
### require('readfiletree')(directory[, callback])
9+
### async readfiletree(directory)
1010

11-
Read the directory and the files it contains, recursively, and return an object representing the directory structure with nodes containing the utf8 string contents of each file. The arguments of the optional callback are: `(err, object)`. If no callback is supplied, a `Promise` is returned which can be used to `await` the serialised `object`.
11+
Read the directory and the files it contains, recursively, and return an object representing the directory structure with nodes containing the utf8 string contents of each file.
1212

1313
Using both *mkfiletree* and *readfiletree* we can do the following:
1414

1515
```js
16-
const mkfiletree = require('mkfiletree')
17-
const readfiletree = require('readfiletree')
16+
import * as mkfiletree from 'mkfiletree'
17+
import { readfiletree } from 'readfiletree'
1818

19-
let dir = await mkfiletree.makeTemp('testfiles',
19+
const dir = await mkfiletree.makeTemp('testfiles',
2020
{
2121
'adir': {
2222
'one.txt': '1\n2\n3\n',
@@ -28,7 +28,7 @@ let dir = await mkfiletree.makeTemp('testfiles',
2828
'afile.txt': 'file contents'
2929
})
3030

31-
let obj = await readfiletree(dir)
31+
const obj = await readfiletree(dir)
3232
console.log(obj)
3333
```
3434

@@ -67,14 +67,6 @@ And the output of the program should be the same as the input to *mkfiletree*:
6767
}
6868
```
6969

70-
## Contributing
71-
72-
Tests can be run with `npm test`. I'm more than happy to receive contributions so fork away!
73-
74-
## Synchronous version
75-
76-
No, there is no sync version, do it async, it's good for your health and contains additional vitamin C, B1, B2 and folate.
77-
7870
*Copyright (c) 2012 [Rod Vagg](https://github.com/rvagg)
7971

8072
Made available under the MIT licence:

package.json

Lines changed: 28 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,30 @@
11
{
2-
"author": "Rod Vagg @rvagg <rod@vagg.org>",
3-
"name": "readfiletree",
4-
"description": "Serialize a tree of files and directories into object form",
5-
"keywords": [
6-
"temp",
7-
"tree",
8-
"test",
9-
"serialize",
10-
"deserialize"
11-
],
12-
"version": "1.1.1",
13-
"main": "readfiletree.js",
14-
"scripts": {
15-
"test": "node tests.js"
16-
},
17-
"dependencies": {
18-
"after": "~0.8.2"
19-
},
20-
"devDependencies": {
21-
"mkfiletree": "~2.0.0"
22-
},
23-
"repository": {
24-
"type": "git",
25-
"url": "https://github.com/rvagg/node-readfiletree.git"
26-
}
2+
"author": "Rod Vagg @rvagg <rod@vagg.org>",
3+
"name": "readfiletree",
4+
"description": "Serialize a tree of files and directories into object form",
5+
"keywords": [
6+
"temp",
7+
"tree",
8+
"test",
9+
"serialize",
10+
"deserialize"
11+
],
12+
"version": "1.1.1",
13+
"main": "readfiletree.js",
14+
"type": "module",
15+
"license": "MIT",
16+
"scripts": {
17+
"lint": "standard",
18+
"test": "npm run lint && node tests.js",
19+
"test:ci": "npm run lint && node tests.js",
20+
"build": "true"
21+
},
22+
"devDependencies": {
23+
"mkfiletree": "^3.0.0",
24+
"standard": "^17.1.0"
25+
},
26+
"repository": {
27+
"type": "git",
28+
"url": "https://github.com/rvagg/node-readfiletree.git"
29+
}
2730
}

readfiletree.js

Lines changed: 15 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,65 +1,21 @@
11
/* Copyright (c) 2012 Rod Vagg <@rvagg> */
2-
const fs = require('fs')
3-
const path = require('path')
4-
const after = require('after')
2+
import fs from 'fs/promises'
3+
import path from 'path'
54

6-
function readfiletree (dir, obj, callback) {
7-
if (typeof obj === 'function') {
8-
callback = obj
5+
export async function readfiletree (dir, obj) {
6+
if (obj == null) {
97
obj = {}
108
}
11-
12-
fs.readdir(dir, afterReaddir)
13-
14-
function afterReaddir (err, list) {
15-
if (err) {
16-
return callback(err)
17-
}
18-
19-
const done = after(list.length, (err) => {
20-
if (err) {
21-
return callback(err)
22-
}
23-
callback(null, obj)
24-
})
25-
list.forEach((f) => eachFile(f, done))
26-
}
27-
28-
function eachFile (f, callback) {
29-
var p = path.join(dir, f)
30-
fs.stat(p, (err, stat) => {
31-
if (err) {
32-
return callback(err)
33-
}
34-
if (stat.isDirectory()) {
35-
obj[f] = {}
36-
return readfiletree(p, obj[f], callback)
37-
} else if (stat.isFile()) {
38-
fs.readFile(p, 'utf8', (err, data) => {
39-
if (err) {
40-
return callback(err)
41-
}
42-
obj[f] = data
43-
callback()
44-
})
45-
}
46-
})
47-
}
48-
}
49-
50-
module.exports = function maybePromiseWrap (dir, callback) {
51-
if (typeof callback === 'function') {
52-
return readfiletree(dir, callback)
53-
}
54-
55-
return new Promise((resolve, reject) => {
56-
callback = (err, data) => {
57-
if (err) {
58-
return reject(err)
59-
}
60-
resolve(data)
9+
const list = await fs.readdir(dir)
10+
await Promise.all(list.map(async (f) => {
11+
const p = path.join(dir, f)
12+
const stat = await fs.stat(p)
13+
if (stat.isDirectory()) {
14+
obj[f] = {}
15+
await readfiletree(p, obj[f])
16+
} else if (stat.isFile()) {
17+
obj[f] = await fs.readFile(p, 'utf8')
6118
}
62-
63-
readfiletree(dir, callback)
64-
})
19+
}))
20+
return obj
6521
}

tests.js

Lines changed: 11 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,29 @@
1-
const assert = require('assert')
2-
const mkfiletree = require('mkfiletree')
3-
const readfiletree = require('./readfiletree')
1+
import assert from 'assert'
2+
import * as mkfiletree from 'mkfiletree'
3+
import { readfiletree } from './readfiletree.js'
4+
45
function mkfixture () { // make a new copy each time, ensure no edits at any depth
56
return {
67
'foo.txt': 'FOO!',
7-
'bar': {
8-
'bang': {
8+
bar: {
9+
bang: {
910
'1.dat': '1\n',
1011
'2.dat': '2\n\n',
1112
'3.dat': '3\n\n\n'
1213
},
13-
'BAM': 'WOO HOO!!!\n'
14+
BAM: 'WOO HOO!!!\n'
1415
}
1516
}
1617
}
1718

18-
async function test (asPromises) {
19+
async function test () {
1920
const dir = await mkfiletree.makeTemp('readfiletree_test', mkfixture())
2021
assert(dir)
21-
22-
if (!asPromises) {
23-
readfiletree(dir, (err, obj) => {
24-
assert(!err)
25-
verify(obj)
26-
})
27-
} else {
28-
readfiletree(dir)
29-
.then(verify)
30-
}
31-
32-
function verify (obj) {
33-
assert.deepStrictEqual(obj, mkfixture())
34-
}
22+
const obj = await readfiletree(dir)
23+
assert.deepStrictEqual(obj, mkfixture())
3524
}
3625

37-
test(false).then(() => {
38-
return test(true)
39-
}).catch((err) => {
26+
test().catch((err) => {
4027
console.error(err)
4128
process.exit(1)
4229
})

0 commit comments

Comments
 (0)