directory-tree 2.3.1 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/node.js.yml +31 -0
- package/.idea/encodings.xml +4 -0
- package/.idea/modules.xml +8 -0
- package/.idea/node-directory-tree.iml +8 -0
- package/.idea/vcs.xml +6 -0
- package/README.md +24 -3
- package/bin/index.js +102 -0
- package/index.d.ts +2 -1
- package/lib/directory-tree.js +38 -12
- package/package.json +6 -1
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# This workflow will do a clean install of node dependencies, cache/restore them, build the source code and run tests across different versions of node
|
|
2
|
+
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions
|
|
3
|
+
|
|
4
|
+
name: Node.js CI
|
|
5
|
+
|
|
6
|
+
on:
|
|
7
|
+
push:
|
|
8
|
+
branches: [ master ]
|
|
9
|
+
pull_request:
|
|
10
|
+
branches: [ master ]
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
build:
|
|
14
|
+
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
|
|
17
|
+
strategy:
|
|
18
|
+
matrix:
|
|
19
|
+
node-version: [12.x, 14.x, 16.x]
|
|
20
|
+
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/
|
|
21
|
+
|
|
22
|
+
steps:
|
|
23
|
+
- uses: actions/checkout@v2
|
|
24
|
+
- name: Use Node.js ${{ matrix.node-version }}
|
|
25
|
+
uses: actions/setup-node@v2
|
|
26
|
+
with:
|
|
27
|
+
node-version: ${{ matrix.node-version }}
|
|
28
|
+
cache: 'npm'
|
|
29
|
+
- run: npm ci
|
|
30
|
+
- run: npm run build --if-present
|
|
31
|
+
- run: npm test
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<project version="4">
|
|
3
|
+
<component name="ProjectModuleManager">
|
|
4
|
+
<modules>
|
|
5
|
+
<module fileurl="file://$PROJECT_DIR$/.idea/node-directory-tree.iml" filepath="$PROJECT_DIR$/.idea/node-directory-tree.iml" />
|
|
6
|
+
</modules>
|
|
7
|
+
</component>
|
|
8
|
+
</project>
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<module type="WEB_MODULE" version="4">
|
|
3
|
+
<component name="NewModuleRootManager">
|
|
4
|
+
<content url="file://$MODULE_DIR$" />
|
|
5
|
+
<orderEntry type="inheritedJdk" />
|
|
6
|
+
<orderEntry type="sourceFolder" forTests="false" />
|
|
7
|
+
</component>
|
|
8
|
+
</module>
|
package/.idea/vcs.xml
ADDED
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
[](https://travis-ci.com/mihneadb/node-directory-tree)
|
|
1
|
+
[](https://api.travis-ci.com/mihneadb/node-directory-tree.svg?branch=master)
|
|
2
2
|
|
|
3
3
|
# directory-tree
|
|
4
4
|
|
|
@@ -48,7 +48,7 @@ const dirTree = require('directory-tree');
|
|
|
48
48
|
const filteredTree = dirTree('/some/path', {attributes:['mode', 'mtime']});
|
|
49
49
|
```
|
|
50
50
|
|
|
51
|
-
The default attributes are `[name,
|
|
51
|
+
The default attributes are `[name, path]` for Files and `[name, path, children]` for Directories
|
|
52
52
|
|
|
53
53
|
A callback function can be executed with each file that matches the extensions provided:
|
|
54
54
|
|
|
@@ -83,6 +83,8 @@ const tree = dirTree('./test/test_data', {extensions:/\.txt$/}, null, (item, PAT
|
|
|
83
83
|
|
|
84
84
|
`normalizePath` : `Boolean` - If true, windows style paths will be normalized to unix style pathes (/ instead of \\).
|
|
85
85
|
|
|
86
|
+
`depth` : `number` - If presented, reads so many nested dirs as specified in argument. Usage of size attribute with depth option is prohibited.
|
|
87
|
+
|
|
86
88
|
## Result
|
|
87
89
|
|
|
88
90
|
Given a directory structured like this:
|
|
@@ -98,7 +100,7 @@ photos
|
|
|
98
100
|
└── snowboard.jpg
|
|
99
101
|
```
|
|
100
102
|
|
|
101
|
-
`directory-tree` will return this JS object:
|
|
103
|
+
`directory-tree` with `attributes: ["size", "type", "extension"]` will return this JS object:
|
|
102
104
|
|
|
103
105
|
```json
|
|
104
106
|
{
|
|
@@ -186,3 +188,22 @@ Make sure you have the dev dependencies installed (e.g. `npm install .`)
|
|
|
186
188
|
|
|
187
189
|
This project requires at least Node v4.2.
|
|
188
190
|
Check out version `0.1.1` if you need support for older versions of Node.
|
|
191
|
+
|
|
192
|
+
## CLI usage
|
|
193
|
+
|
|
194
|
+
You can use script directly from command line for generating json data.
|
|
195
|
+
|
|
196
|
+
```bash
|
|
197
|
+
$ npx directory-tree --help
|
|
198
|
+
```
|
|
199
|
+
```bash
|
|
200
|
+
$ npx directory-tree --path /Users/user/target --attributes type,extension --pretty -o ./xz.json --depth 1
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
### Available options
|
|
204
|
+
-p, --path string 🗂 The input folder to process. Required.
|
|
205
|
+
-e, --exclude string 🐒 Exclude some folders from processing by regexp string. Ex -e "test_data/some_dir$|js|.DS_Store"
|
|
206
|
+
-o, --output string 📝 Put result into file provided by this options. Overwrites if exists.
|
|
207
|
+
-d, --depth number ☞ Reads dirs in deep as specified. Usage of size attribute with depth option is prohibited.
|
|
208
|
+
--attributes string ℹ️ Grab file attributes. Example: --attributes size,type,extension. Usage of size attribute with depth option is prohibited
|
|
209
|
+
--pretty 💎 Json pretty print
|
package/bin/index.js
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
const commandLineUsage = require('command-line-usage')
|
|
5
|
+
const commandLineArgs = require('command-line-args')
|
|
6
|
+
const directoryTree = require('../lib/directory-tree');
|
|
7
|
+
|
|
8
|
+
const optionList = [
|
|
9
|
+
{
|
|
10
|
+
name: 'path',
|
|
11
|
+
alias: 'p',
|
|
12
|
+
required: true,
|
|
13
|
+
defaultOption: true,
|
|
14
|
+
typeLabel: '{underline string}',
|
|
15
|
+
description: '🗂 The input folder to process. Required.'
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
name: 'exclude',
|
|
19
|
+
alias: 'e',
|
|
20
|
+
type: String,
|
|
21
|
+
description: '🐒 Exclude some folders from processing by regexp string. Ex -e "test_data/some_dir$|js|.DS_Store"'
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
name: 'output',
|
|
25
|
+
alias: 'o',
|
|
26
|
+
type: String,
|
|
27
|
+
description: '📝 Put result into file provided by this options. Overwrites if exists.'
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
name: 'depth',
|
|
31
|
+
alias: 'd',
|
|
32
|
+
type: Number,
|
|
33
|
+
description: '☞ Reads dirs in deep as specified. Usage of size attribute with depth option is prohibited.'
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
name: 'attributes',
|
|
37
|
+
type: String,
|
|
38
|
+
description: 'ℹ️ Grab file attributes. Example: --attributes size,type,extension. Usage of size attribute with depth option is prohibited'
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
name: 'pretty',
|
|
42
|
+
type: Boolean,
|
|
43
|
+
description: '💎 Json pretty print'
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
name: 'help',
|
|
47
|
+
alias: 'h',
|
|
48
|
+
type: Boolean,
|
|
49
|
+
description: '⁉️ Print this usage guide.'
|
|
50
|
+
}
|
|
51
|
+
]
|
|
52
|
+
|
|
53
|
+
const usageNotes = [
|
|
54
|
+
{
|
|
55
|
+
header: '⛄️️ Folder-tree command line script',
|
|
56
|
+
content: 'Used for generates json representation of folder internals'
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
header: '🔥 Options 🔥',
|
|
60
|
+
optionList: optionList
|
|
61
|
+
}
|
|
62
|
+
]
|
|
63
|
+
|
|
64
|
+
const usage = commandLineUsage(usageNotes)
|
|
65
|
+
let options = null;
|
|
66
|
+
try {
|
|
67
|
+
options = commandLineArgs(optionList)
|
|
68
|
+
} catch(e) {
|
|
69
|
+
console.log(usage);
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if (Object.keys(options).length === 0 || options.help || !options.path) {
|
|
74
|
+
console.log(usage)
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (!fs.existsSync(options.path)) {
|
|
79
|
+
console.log('-----------------------------------------------------------------------------------------------------')
|
|
80
|
+
console.log(`doesn't exist; please check your args`);
|
|
81
|
+
console.log('-----------------------------------------------------------------------------------------------------')
|
|
82
|
+
console.log(usage)
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
try {
|
|
87
|
+
const result = directoryTree(options.path, {
|
|
88
|
+
depth: options.depth,
|
|
89
|
+
exclude: options.exclude ? [new RegExp(options.exclude)] : undefined,
|
|
90
|
+
attributes: options.attributes ? options.attributes.split(',') : undefined
|
|
91
|
+
})
|
|
92
|
+
|
|
93
|
+
const resultString = JSON.stringify(result, null, options.pretty ? ' ' : '');
|
|
94
|
+
if (options.output) {
|
|
95
|
+
fs.writeFileSync(options.output, resultString);
|
|
96
|
+
} else {
|
|
97
|
+
console.log(resultString);
|
|
98
|
+
}
|
|
99
|
+
} catch(e) {
|
|
100
|
+
console.log(e);
|
|
101
|
+
console.log(usage);
|
|
102
|
+
}
|
package/index.d.ts
CHANGED
|
@@ -22,9 +22,10 @@ declare namespace directoryTree {
|
|
|
22
22
|
export interface DirectoryTreeOptions {
|
|
23
23
|
normalizePath ? : boolean;
|
|
24
24
|
exclude ? : RegExp | RegExp[];
|
|
25
|
-
attributes ? : (keyof Stats)[];
|
|
25
|
+
attributes ? : (keyof Stats | "type" | "extension")[];
|
|
26
26
|
extensions ? : RegExp;
|
|
27
27
|
followSymlink ? : boolean;
|
|
28
|
+
depth ? : number;
|
|
28
29
|
}
|
|
29
30
|
export type DirectoryTreeCallback = (item: DirectoryTree, path: string, stats: Stats) => void;
|
|
30
31
|
}
|
package/lib/directory-tree.js
CHANGED
|
@@ -48,7 +48,11 @@ function isRegExp(regExp) {
|
|
|
48
48
|
* @param {function} onEachDirectory
|
|
49
49
|
* @return {Object}
|
|
50
50
|
*/
|
|
51
|
-
function directoryTree (path, options, onEachFile, onEachDirectory) {
|
|
51
|
+
function directoryTree (path, options, onEachFile, onEachDirectory, currentDepth = 0) {
|
|
52
|
+
if (options.depth !== undefined && options.attributes.indexOf('size') !== -1) {
|
|
53
|
+
throw new Error('usage of size attribute with depth option is prohibited');
|
|
54
|
+
}
|
|
55
|
+
|
|
52
56
|
const name = PATH.basename(path);
|
|
53
57
|
options = options || {};
|
|
54
58
|
path = options.normalizePath ? normalizePath(path) : path;
|
|
@@ -80,7 +84,7 @@ function directoryTree (path, options, onEachFile, onEachDirectory) {
|
|
|
80
84
|
options = { ...options, symlinks: [] };
|
|
81
85
|
// Skip if a cyclic symbolic link has been found
|
|
82
86
|
if (options.symlinks.find(ino => ino === lstat.ino)) {
|
|
83
|
-
return null;
|
|
87
|
+
return null;
|
|
84
88
|
} else {
|
|
85
89
|
options.symlinks.push(lstat.ino);
|
|
86
90
|
}
|
|
@@ -94,13 +98,20 @@ function directoryTree (path, options, onEachFile, onEachDirectory) {
|
|
|
94
98
|
if (options.extensions && !options.extensions.test(ext))
|
|
95
99
|
return null;
|
|
96
100
|
|
|
97
|
-
item.size = stats.size; // File size in bytes
|
|
98
|
-
item.extension = ext;
|
|
99
|
-
item.type = constants.FILE;
|
|
100
101
|
|
|
101
102
|
if (options.attributes) {
|
|
102
103
|
options.attributes.forEach((attribute) => {
|
|
103
|
-
|
|
104
|
+
switch (attribute) {
|
|
105
|
+
case 'extension':
|
|
106
|
+
item.extension = ext;
|
|
107
|
+
break;
|
|
108
|
+
case 'type':
|
|
109
|
+
item.type = constants.FILE;
|
|
110
|
+
break;
|
|
111
|
+
default:
|
|
112
|
+
item[attribute] = stats[attribute];
|
|
113
|
+
break;
|
|
114
|
+
}
|
|
104
115
|
});
|
|
105
116
|
}
|
|
106
117
|
|
|
@@ -112,16 +123,31 @@ function directoryTree (path, options, onEachFile, onEachDirectory) {
|
|
|
112
123
|
let dirData = safeReadDirSync(path);
|
|
113
124
|
if (dirData === null) return null;
|
|
114
125
|
|
|
126
|
+
if (options.depth === undefined || options.depth > currentDepth) {
|
|
127
|
+
item.children = dirData
|
|
128
|
+
.map(child => directoryTree(PATH.join(path, child), options, onEachFile, onEachDirectory, currentDepth + 1))
|
|
129
|
+
.filter(e => !!e);
|
|
130
|
+
}
|
|
131
|
+
|
|
115
132
|
if (options.attributes) {
|
|
116
133
|
options.attributes.forEach((attribute) => {
|
|
117
|
-
|
|
134
|
+
switch (attribute) {
|
|
135
|
+
case 'size':
|
|
136
|
+
item.size = item.children.reduce((prev, cur) => prev + cur.size, 0);
|
|
137
|
+
break;
|
|
138
|
+
case 'type':
|
|
139
|
+
item.type = constants.DIRECTORY;
|
|
140
|
+
break;
|
|
141
|
+
case 'extension':
|
|
142
|
+
break;
|
|
143
|
+
default:
|
|
144
|
+
item[attribute] = stats[attribute];
|
|
145
|
+
break;
|
|
146
|
+
}
|
|
147
|
+
|
|
118
148
|
});
|
|
119
149
|
}
|
|
120
|
-
|
|
121
|
-
.map(child => directoryTree(PATH.join(path, child), options, onEachFile, onEachDirectory))
|
|
122
|
-
.filter(e => !!e);
|
|
123
|
-
item.size = item.children.reduce((prev, cur) => prev + cur.size, 0);
|
|
124
|
-
item.type = constants.DIRECTORY;
|
|
150
|
+
|
|
125
151
|
if (onEachDirectory) {
|
|
126
152
|
onEachDirectory(item, path, stats);
|
|
127
153
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "directory-tree",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.1.0",
|
|
4
4
|
"description": "Convert a directory tree to a JS object.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -17,10 +17,15 @@
|
|
|
17
17
|
"url": "https://github.com/mihneadb/node-directory-tree/issues"
|
|
18
18
|
},
|
|
19
19
|
"homepage": "https://github.com/mihneadb/node-directory-tree",
|
|
20
|
+
"dependencies": {
|
|
21
|
+
"command-line-args": "^5.2.0",
|
|
22
|
+
"command-line-usage": "^6.1.1"
|
|
23
|
+
},
|
|
20
24
|
"devDependencies": {
|
|
21
25
|
"chai": "^2.3.0",
|
|
22
26
|
"mocha": "^8.3.2"
|
|
23
27
|
},
|
|
28
|
+
"bin": "bin/index.js",
|
|
24
29
|
"engines": {
|
|
25
30
|
"node": ">=10.0"
|
|
26
31
|
},
|