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.
@@ -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,4 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="Encoding" addBOMForNewFiles="with NO BOM" />
4
+ </project>
@@ -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
@@ -0,0 +1,6 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="VcsDirectoryMappings">
4
+ <mapping directory="$PROJECT_DIR$" vcs="Git" />
5
+ </component>
6
+ </project>
package/README.md CHANGED
@@ -1,4 +1,4 @@
1
- [![Build Status](https://travis-ci.com/mihneadb/node-directory-tree.svg)](https://travis-ci.com/mihneadb/node-directory-tree)
1
+ [![Build Status](https://api.travis-ci.com/mihneadb/node-directory-tree.svg?branch=master)](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, size, extension, path]` for Files and `[name, size, path]` for Directories
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
  }
@@ -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
- item[attribute] = stats[attribute];
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
- item[attribute] = stats[attribute];
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
- item.children = dirData
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": "2.3.1",
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
  },