├── .gitignore ├── .prettierrc ├── README.md ├── README_zh-CN.md ├── bin └── parser.js ├── dir-info.txt ├── images ├── demo.png └── dir-parser.jpg ├── index.d.ts ├── index.js ├── myapp ├── app.js ├── bin │ └── www ├── dir-info.txt ├── info.txt ├── package.json ├── parser.conf.json ├── public │ └── stylesheets │ │ └── style.css ├── routes │ ├── index.js │ └── users.js ├── test.js └── views │ ├── error.jade │ ├── index.jade │ └── layout.jade ├── package.json ├── parser.conf.json ├── src ├── base.js └── dir-parser.js └── test └── test.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | package-lock.json 3 | yarn.lock 4 | **/.DS_Store -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 120, 3 | "singleQuote": true, 4 | "semi": false, 5 | "tabWidth": 2, 6 | "trailingComma": "es5" 7 | } 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

😎 Dir Parser v2 😎

2 |

3 | 4 |

5 | 6 | # dir-parser 7 | 8 | [![npm](https://img.shields.io/npm/v/dir-parser.svg)](https://www.npmjs.com/package/dir-parser) 9 | [![LICENSE MIT](https://img.shields.io/npm/l/dir-parser.svg)](https://www.npmjs.com/package/dir-parser) 10 | [![NPM Downloads](https://img.shields.io/npm/dm/dir-parser.svg?style=flat)](https://npmcharts.com/compare/dir-parser?minimal=true) 11 | [![Install Size](https://packagephobia.now.sh/badge?p=dir-parser)](https://packagephobia.now.sh/result?p=dir-parser) 12 | 13 | > Parse a directory and generate it's structure tree. 14 | 15 | Read this in other languages: English | [简体中文](./README_zh-CN.md) 16 | 17 | - [dir-parser](#dir-parser) 18 | - [1. What is dir-parser](#1-what-is-dir-parser) 19 | - [1.1 Introduction](#11-introduction) 20 | - [1.2 Installation](#12-installation) 21 | - [2. Command Line](#2-command-line) 22 | - [2.1 Print help info](#21-print-help-info) 23 | - [2.2 Generate dir-tree](#22-generate-dir-tree) 24 | - [2.3 With parameters](#23-with-parameters) 25 | - [2.3.1 excludes](#231-excludes) 26 | - [2.3.2 ignores](#232-ignores) 27 | - [2.3.3 glob](#233-glob) 28 | - [2.3.4 patterns](#234-patterns) 29 | - [2.3.5 lineType](#235-lineType) 30 | - [2.3.6 depth](#236-depth) 31 | - [2.3.7 reverse](#237-reverse) 32 | - [2.3.8 fileFirst](#238-fileFirst) 33 | - [2.3.9 fileOnly](#239-fileOnly) 34 | - [2.3.10 dirOnly](#2310-dirOnly) 35 | - [2.3.11 dirInfo](#2311-dirInfo) 36 | - [2.3.12 excPaths](#2312-excPaths) 37 | - [2.3.13 excPatterns](#2313-excPatterns) 38 | - [2.3.14 silent](#2314-silent) 39 | - [2.3.15 generate](#2315-generate) 40 | - [2.3.16 config](#2316-config) 41 | - [2.4 Use multiple commands together](#24-use-multiple-commands-together) 42 | - [3. In JavaScript](#3-in-javascript) 43 | - [3.1 Interface](#31-interface) 44 | - [3.1.1 Main Function-parser](#311-main-function-parser) 45 | - [3.1.2 Options](#312-options) 46 | - [3.1.3 Parsed](#313-parsed) 47 | - [3.1.4 DirInfo](#314-dirinfo) 48 | - [3.1.5 FileInfo](#315-fileinfo) 49 | - [3.2 Get dir-tree](#32-get-dir-tree) 50 | - [3.2.1 Make dir-tree example](#321-make-dir-tree-example) 51 | - [3.2.2 Run dir-tree example](#322-run-dir-tree-example) 52 | - [3.3 Get dir-info](#33-get-dir-info) 53 | - [3.3.1 Make dir-info example](#331-make-dir-info-example) 54 | - [3.3.2 Run dir-info example](#332-run-dir-info-example) 55 | - [3.3.3 Make dir-children example](#333-make-dir-children-example) 56 | - [3.3.4 Run dir-children example](#334-run-dir-children-example) 57 | - [3.3.5 Make dir-files example](#335-make-dir-files-example) 58 | - [3.3.6 Run dir-files example](#336-run-dir-files-example) 59 | 60 | ## 1. What is dir-parser 61 | 62 | ### 1.1 Introduction 63 | 👍👍👍Dir parser is a powerful folder analysis tool based on nodejs, which can be used in command line or JavaScript code. There are many practical parameters that can be set to help you get the formatted folder tree and internal information. 64 | 65 | ### 1.2 Installation 66 | 67 | #### 1.2.1 Global install 68 | - yarn: `$ yarn global add dir-parser` 69 | - npm: `$ npm install -g dir-parser` 70 | 71 | #### 1.2.2 Local install 72 | - yarn: `$ yarn add dir-parser` or `$ yarn add dir-parser -D` 73 | - npm: `$ npm install dir-parser` or `$ npm install dir-parser -D` 74 | 75 | ## 2. Command Line 76 | 77 | ### 2.1 Print help info 78 | `$ parser -h` (or: `$ parser --help`) 79 | ``` 80 | Usage: parser [options] 81 | 82 | Options: 83 | -V, --version output the version number 84 | -v, --version output the version number 85 | -c, --config [config] config file, Optional. 86 | -i, --input target directory (default: "./") 87 | -o, --output output path (default: "./") 88 | -d, --depth depth of a parse process, 0 means no limit (default: 0) 89 | -l, --lineType line type of tree, "dash" or "solid" (default: "solid") 90 | -e, --excludes exclude some directories or files by name. 91 | -x, --excPaths exclude directories or files by path. 92 | -p, --patterns filter directories or files by RegExp. 93 | -g, --generate [fileName] generate a dir-info file to the output path, "dir-info.txt" is default. 94 | -r, --reverse reverse the parsed dir-tree nodes. 95 | -s, --silent not show the parsed dir-tree in terminal. 96 | -f, --fileFirst print files first, before directories. 97 | -F, --fileOnly pase files only. 98 | -D, --dirOnly pase directories only, and it only takes effect when fileOnly is false. 99 | -I, --ignores ignore some directories or files by name. 100 | -N, --no-dirInfo hide file and directory number info on the result top. 101 | -G, --glob filter files with glob patterns. 102 | --paths filter directories or files by path. 103 | --includes filter directories or files by name. 104 | --excPatterns exclude directories or files by RegExp. 105 | -H, --Help output chinese usage information.(打印中文帮助信息.) 106 | -h, --help output usage information 107 | ``` 108 | 109 | ### 2.2 Generate dir-tree 110 | To run demo, you need to install `express-generator`:
111 | Run:
112 | `$ npm install -g express-generator`
113 | `$ express myapp`
114 | `$ cd myapp`
115 | `$ parser`
116 | ``` 117 | myapp ( Directories: 7, Files: 9 ) 118 | ├── bin 119 | │ └── www 120 | ├── public 121 | │ ├── images/ 122 | │ ├── javascripts/ 123 | │ └── stylesheets 124 | │ └── style.css 125 | ├── routes 126 | │ ├── index.js 127 | │ └── users.js 128 | ├── views 129 | │ ├── error.jade 130 | │ ├── index.jade 131 | │ └── layout.jade 132 | ├── app.js 133 | └── package.json 134 | ``` 135 | 136 | ### 2.3 With parameters 137 | 138 | #### 2.3.1 excludes 139 | 👉 Exclude some directories or files by name.
140 | `$ # git init`
141 | `$ npm install`
142 | `$ parser -e .git,node_modules,public`
143 | or: `$ parser --excludes .git,node_modules,public` 144 | ``` 145 | myapp ( Directories: 3, Files: 9 ) 146 | ├── bin 147 | │ └── www 148 | ├── routes 149 | │ ├── index.js 150 | │ └── users.js 151 | ├── views 152 | │ ├── error.jade 153 | │ ├── index.jade 154 | │ └── layout.jade 155 | ├── app.js 156 | ├── package-lock.json 157 | └── package.json 158 | ``` 159 | Name has white space:
160 | `$ touch 'white space.txt'`
161 | `$ parser -e '[".git", "node_modules", "public", "white space.txt"]'`
162 | `$ rm -rf white\ space.txt` 163 | ``` 164 | myapp ( Directories: 3, Files: 9 ) 165 | ├── bin 166 | │ └── www 167 | ├── routes 168 | │ ├── index.js 169 | │ └── users.js 170 | ├── views 171 | │ ├── error.jade 172 | │ ├── index.jade 173 | │ └── layout.jade 174 | ├── app.js 175 | ├── package-lock.json 176 | └── package.json 177 | ``` 178 | 179 | #### 2.3.2 ignores 180 | 👉 Ignore some directories or files by name.
181 | `$ parser -e node_modules -I bin,public`
182 | or: `$ parser -e node_modules --ignores bin,public` 183 | ``` 184 | myapp ( Directories: 4, Files: 8 ) 185 | ├── bin/ 186 | ├── public/ 187 | ├── routes 188 | │ ├── index.js 189 | │ └── users.js 190 | ├── views 191 | │ ├── error.jade 192 | │ ├── index.jade 193 | │ └── layout.jade 194 | ├── app.js 195 | ├── package-lock.json 196 | └── package.json 197 | ``` 198 | 199 | #### 2.3.3 glob 200 | 👉 Filter by glob pattern. Note: glob pattern must be enclosed in quotation marks
201 | `$ parser -e node_modules -G '**/*.js'`
202 | or: `$ parser -e node_modules --glob '**/*.js'` 203 | ``` 204 | myapp ( Directories: 1, Files: 3 ) 205 | ├── routes 206 | │ ├── index.js 207 | │ └── users.js 208 | └── app.js 209 | ``` 210 | 211 | #### 2.3.4 patterns 212 | 👉 Filter directories or files by RegExp.
213 | `$ parser -e node_modules -p .js$`
214 | or: `$ parser -e node_modules --patterns .js$` 215 | ``` 216 | myapp ( Directories: 1, Files: 3 ) 217 | ├── routes 218 | │ ├── index.js 219 | │ └── users.js 220 | └── app.js 221 | ``` 222 | 223 | #### 2.3.5 lineType 224 | 👉 Line type of tree, "dash" or "solid" (default: "solid")
225 | `$ parser -e bin,node_modules -l dash`
226 | or: `$ parser -e bin,node_modules --lineType dash` 227 | ``` 228 | myapp ( Directories: 6, Files: 9 ) 229 | +-- public 230 | ¦ +-- images/ 231 | ¦ +-- javascripts/ 232 | ¦ +-- stylesheets 233 | ¦ +-- style.css 234 | +-- routes 235 | ¦ +-- index.js 236 | ¦ +-- users.js 237 | +-- views 238 | ¦ +-- error.jade 239 | ¦ +-- index.jade 240 | ¦ +-- layout.jade 241 | +-- app.js 242 | +-- package-lock.json 243 | +-- package.json 244 | ``` 245 | 246 | #### 2.3.6 depth 247 | 👉 Depth of a parse process, 0 means no limit (default: 0)
248 | `$ parser -e node_modules,views -d 2`
249 | or: `$ parser -e node_modules,views --depth 2` 250 | ``` 251 | myapp ( Directories: 6, Files: 6 ) 252 | ├── bin 253 | │ └── www 254 | ├── public 255 | │ ├── images/ 256 | │ ├── javascripts/ 257 | │ └── stylesheets/* 258 | ├── routes 259 | │ ├── index.js 260 | │ └── users.js 261 | ├── app.js 262 | ├── package-lock.json 263 | └── package.json 264 | ``` 265 | 266 | #### 2.3.7 reverse 267 | 👉 Reverse the parsed dir-tree nodes.
268 | `$ parser -e node_modules,views -d 2 -r`
269 | or: `$ parser -e node_modules,views -d 2 --reverse` 270 | ``` 271 | myapp ( Directories: 6, Files: 6 ) 272 | ├── routes 273 | │ ├── users.js 274 | │ └── index.js 275 | ├── public 276 | │ ├── stylesheets/* 277 | │ ├── javascripts/ 278 | │ └── images/ 279 | ├── bin 280 | │ └── www 281 | ├── package.json 282 | ├── package-lock.json 283 | └── app.js 284 | ``` 285 | 286 | #### 2.3.8 fileFirst 287 | 👉 Print files first, before directories.
288 | `$ parser -e node_modules,bin,views -f`
289 | or: `$ parser -e node_modules,bin,views --fileFirst` 290 | ``` 291 | myapp ( Directories: 5, Files: 6 ) 292 | ├── app.js 293 | ├── package-lock.json 294 | ├── package.json 295 | ├── public 296 | │ ├── images/ 297 | │ ├── javascripts/ 298 | │ └── stylesheets 299 | │ └── style.css 300 | └── routes 301 | ├── index.js 302 | └── users.js 303 | ``` 304 | 305 | #### 2.3.9 fileOnly 306 | 👉 Pase files only.
307 | `$ parser -e node_modules,bin,views -F`
308 | or: `$ parser -e node_modules,bin,views --fileOnly` 309 | ``` 310 | myapp ( Directories: 3, Files: 6 ) 311 | ├── public 312 | │ └── stylesheets 313 | │ └── style.css 314 | ├── routes 315 | │ ├── index.js 316 | │ └── users.js 317 | ├── app.js 318 | ├── package-lock.json 319 | └── package.json 320 | ``` 321 | 322 | #### 2.3.10 dirOnly 323 | 👉 Pase directories only, and it only takes effect when fileOnly is false.
324 | `$ parser -e node_modules,bin,views -D`
325 | or: `$ parser -e node_modules,bin,views --dirOnly` 326 | ``` 327 | myapp ( Directories: 5 ) 328 | ├── public 329 | │ ├── images/ 330 | │ ├── javascripts/ 331 | │ └── stylesheets/ 332 | └── routes/ 333 | ``` 334 | 335 | #### 2.3.11 dirInfo 336 | 👉 Hide file and directory number info on the result top.
337 | `$ parser -e node_modules,bin,public -N`
338 | or: `$ parser -e node_modules,bin,public --no-dirInfo` 339 | ``` 340 | myapp 341 | ├── routes 342 | │ ├── index.js 343 | │ └── users.js 344 | ├── views 345 | │ ├── error.jade 346 | │ ├── index.jade 347 | │ └── layout.jade 348 | ├── app.js 349 | ├── package-lock.json 350 | └── package.json 351 | ``` 352 | 353 | #### 2.3.12 excPaths 354 | 👉 Exclude directories or files by path.
355 | `$ parser -e node_modules,bin -x myapp/public`
356 | or: `$ parser -e node_modules,bin -excPath myapp/public` 357 | ``` 358 | myapp ( Directories: 2, Files: 8 ) 359 | ├── routes 360 | │ ├── index.js 361 | │ └── users.js 362 | ├── views 363 | │ ├── error.jade 364 | │ ├── index.jade 365 | │ └── layout.jade 366 | ├── app.js 367 | ├── package-lock.json 368 | └── package.json 369 | ``` 370 | 371 | #### 2.3.13 excPatterns 372 | 👉 Exclude directories or files by RegExp.
373 | `$ parser -e node_modules,bin --excPatterns .jade$,.css$` 374 | ``` 375 | myapp ( Directories: 6, Files: 5 ) 376 | ├── public 377 | │ ├── images/ 378 | │ ├── javascripts/ 379 | │ └── stylesheets/ 380 | ├── routes 381 | │ ├── index.js 382 | │ └── users.js 383 | ├── views/ 384 | ├── app.js 385 | ├── package-lock.json 386 | └── package.json 387 | ``` 388 | 389 | #### 2.3.14 silent 390 | 👉 Not show the parsed dir-tree in terminal.
391 | `$ parser -e node_modules,bin,public -s`
392 | or: `$ parser -e node_modules,bin,public --silent` 393 | 394 | #### 2.3.15 generate 395 | 👉 Generate a dir-info file to the output path, "dir-info.txt" is default.
396 | `$ parser -e node_modules,bin,public -sg`
397 | or: `$ parser -e node_modules,bin,public -s --generate`
398 | `$ cat dir-info.txt` 399 | ``` 400 | myapp ( Directories: 2, Files: 8 ) 401 | ├── routes 402 | │ ├── index.js 403 | │ └── users.js 404 | ├── views 405 | │ ├── error.jade 406 | │ ├── index.jade 407 | │ └── layout.jade 408 | ├── app.js 409 | ├── package-lock.json 410 | └── package.json 411 | ``` 412 | 413 | #### 2.3.16 config 414 | 👉 Config file, Optional.
415 | `$ touch parser.conf.json`
416 | `$ vi parser.conf.json` 417 | ```json 418 | { 419 | "directory": "./", 420 | "excludes": [ ".git", "node_modules", "bin", "public", "parser.conf.json" ], 421 | "depth": "2", 422 | "generate": "info.txt" 423 | } 424 | ``` 425 | `$ parser -c ./parser.conf.json` 426 | ``` 427 | myapp ( Directories: 2, Files: 9 ) 428 | ├── routes 429 | │ ├── index.js 430 | │ └── users.js 431 | ├── views 432 | │ ├── error.jade 433 | │ ├── index.jade 434 | │ └── layout.jade 435 | ├── app.js 436 | ├── dir-info.txt 437 | ├── package-lock.json 438 | └── package.json 439 | ``` 440 | 441 | ### 2.4 Use multiple commands together 442 | `parser -e node_modules,bin -I views -d 2 -Nr` 443 | ``` 444 | myapp 445 | ├── views/ 446 | ├── routes 447 | │ ├── users.js 448 | │ └── index.js 449 | ├── public 450 | │ ├── stylesheets/* 451 | │ ├── javascripts/ 452 | │ └── images/ 453 | ├── parser.conf.json 454 | ├── package.json 455 | ├── package-lock.json 456 | ├── info.txt 457 | ├── dir-info.txt 458 | └── app.js 459 | ``` 460 | 461 | ## 3. In JavaScript 462 | 463 | ### 3.1 Interface 464 | 465 | #### 3.1.1 Main Function-parser 466 | ```ts 467 | parser(dirPath: string, options: Options): Promise 468 | ``` 469 | 470 | #### 3.1.2 Options 471 | ```ts 472 | interface Options { 473 | depth?: number; 474 | reverse?: boolean; 475 | fileFirst?: boolean; 476 | fileOnly?: boolean; 477 | dirOnly?: boolean; 478 | getFiles?: boolean; 479 | getChildren?: boolean; 480 | dirTree?: boolean; // default: true 481 | dirInfo?: boolean; // default: true 482 | lineType?: 'solid' | 'dash'; // default: 'solid' 483 | excludes?: Array; // eg: [ '.git', 'node_modules', '.idea' ]; 484 | excPaths?: Array; // eg: [ 'src/app' ]; 485 | excPatterns?: Array; // eg: [ 'src/*.js ]'; 486 | ignores: Array; // eg: [ 'public' ]; 487 | includes: Array; // eg: [ 'app.js' ]; 488 | paths?: Array; // eg: [ 'src/public' ]; 489 | patterns?: Array; // eg: [ '*.js ]'; 490 | glob?: string; // eg: '**/*.js'; 491 | } 492 | ``` 493 | #### 3.1.3 Parsed 494 | ```ts 495 | interface Parsed extends DirInfo { 496 | dirTree: string; 497 | children: Array 498 | files: Array 499 | } 500 | ``` 501 | 502 | #### 3.1.4 DirInfo 503 | ```ts 504 | interface DirInfo { 505 | name: string; 506 | type: 'directory'; 507 | size: number; 508 | size_kb: number; 509 | path: string; 510 | absPath: string; 511 | dir: string; 512 | absDir: string; 513 | dirNum: number; 514 | fileNum: number; 515 | children: Array 516 | } 517 | ``` 518 | 519 | #### 3.1.5 FileInfo 520 | ```ts 521 | interface FileInfo { 522 | name: string; 523 | base: string; 524 | ext: string; 525 | type: 'file'; 526 | size: number; 527 | size_kb: number; 528 | path: string; 529 | absPath: string; 530 | dir: string; 531 | absDir: string; 532 | } 533 | ``` 534 | 535 | ### 3.2 Get dir-tree 536 | 537 | #### 3.2.1 Make dir-tree example 538 | `$ npm install dir-parser funclib`
539 | `$ touch test.js`
540 | `$ vi test.js`
541 | ```js 542 | const fn = require('funclib'); 543 | const parser = require('dir-parser'); 544 | 545 | parser('./', { 546 | excludes: ['.git', 'node_modules'], 547 | // lineType: 'dash', 548 | // fileFirst: true, 549 | }).then(parsed => { 550 | fn.log(parsed.dirTree, '# parsed.dirTree'); 551 | 552 | // fn.log(fn.pick(parsed, prop => prop !== 'dirTree'), '# parsed result info'); 553 | // fn.log(parsed.children, '# parsed.children'); 554 | // fn.log(parsed.files, '# parsed.files'); 555 | }); 556 | ``` 557 | 558 | #### 3.2.2 Run dir-tree example 559 | `$ node test.js` 560 | ``` 561 | ================================================================== 562 | [09:48:55] # parsed.dirTree 563 | ------------------------------------------------------------------ 564 | myapp 565 | ├── bin 566 | │ └── www 567 | ├── public 568 | │ ├── images/ 569 | │ ├── javascripts/ 570 | │ └── stylesheets 571 | │ └── style.css 572 | ├── routes 573 | │ ├── index.js 574 | │ └── users.js 575 | ├── views 576 | │ ├── error.jade 577 | │ ├── index.jade 578 | │ └── layout.jade 579 | ├── app.js 580 | ├── dir-info.txt 581 | ├── info.txt 582 | ├── package-lock.json 583 | ├── package.json 584 | ├── parser.conf.json 585 | └── test.js 586 | ================================================================== 587 | ``` 588 | 589 | ### 3.3 Get dir-info 590 | 591 | #### 3.3.1 Make dir-info example 592 | `$ vi test.js` 593 | ```js 594 | parser('./', { 595 | excludes: ['.git', 'node_modules'], 596 | // lineType: 'dash', 597 | // fileFirst: true, 598 | }).then(parsed => { 599 | console.log(fn.pretty(fn.pick(parsed, prop => prop !== 'dirTree'))); 600 | 601 | // fn.log(parsed.dirTree, '# parsed.dirTree'); 602 | // fn.log(parsed.children, '# parsed.children'); 603 | // fn.log(parsed.files, '# parsed.files'); 604 | }); 605 | ``` 606 | #### 3.3.2 Run dir-info example 607 | `$ node test.js` 608 | ```json 609 | { 610 | "name": "myapp", 611 | "type": "directory", 612 | "path": "./", 613 | "absPath": "/Users/cntower/code/@cntower/dir-parser/myapp", 614 | "dir": ".", 615 | "absDir": "/Users/cntower/code/@cntower/dir-parser", 616 | "dirNum": 7, 617 | "fileNum": 14 618 | } 619 | ``` 620 | 621 | #### 3.3.3 Make dir-children example 622 | `$ vi test.js` 623 | ```js 624 | parser('./', { 625 | excludes: ['.git', 'node_modules', 'public'], 626 | getFiles: true, // Default is false, If true, returns will conatins an array of all subfiles's info; 627 | getChildren: true, // Default is false, If true, returns will conatins an object of all children's info; 628 | dirTree: false // Default is true, returns will conatins a tree of the directory; 629 | }).then(parsed => { 630 | console.log(fn.pretty(parsed.children)); 631 | // fn.log(parsed.files, '# parsed.files'); 632 | }); 633 | ``` 634 | 635 | #### 3.3.4 Run dir-children example 636 | `$ node test.js` 637 | ```json 638 | [ 639 | { 640 | "name": "bin", 641 | "type": "directory", 642 | "size": 1591, 643 | "size_kb": "1.55kb", 644 | "path": "bin", 645 | "absPath": "/Users/cntower/code/@cntower/dir-parser/myapp/bin", 646 | "dir": ".", 647 | "absDir": "/Users/cntower/code/@cntower/dir-parser/myapp", 648 | "dirNum": 0, 649 | "fileNum": 1, 650 | "children": [ 651 | { 652 | "name": "www", 653 | "base": "www", 654 | "ext": "", 655 | "type": "file", 656 | "size": 1591, 657 | "size_kb": "1.55kb", 658 | "path": "bin/www", 659 | "absPath": "/Users/cntower/code/@cntower/dir-parser/myapp/bin/www", 660 | "dir": "bin", 661 | "absDir": "/Users/cntower/code/@cntower/dir-parser/myapp/bin" 662 | } 663 | ] 664 | }, 665 | { 666 | "name": "routes", 667 | "type": "directory", 668 | "size": 408, 669 | "size_kb": "0.4kb", 670 | "path": "routes", 671 | "absPath": "/Users/cntower/code/@cntower/dir-parser/myapp/routes", 672 | "dir": ".", 673 | "absDir": "/Users/cntower/code/@cntower/dir-parser/myapp", 674 | "dirNum": 0, 675 | "fileNum": 2, 676 | "children": [ 677 | { 678 | "name": "index.js", 679 | "base": "index", 680 | "ext": ".js", 681 | "type": "file", 682 | "size": 205, 683 | "size_kb": "0.2kb", 684 | "path": "routes/index.js", 685 | "absPath": "/Users/cntower/code/@cntower/dir-parser/myapp/routes/index.js", 686 | "dir": "routes", 687 | "absDir": "/Users/cntower/code/@cntower/dir-parser/myapp/routes" 688 | }, 689 | { 690 | "name": "users.js", 691 | "base": "users", 692 | "ext": ".js", 693 | "type": "file", 694 | "size": 203, 695 | "size_kb": "0.2kb", 696 | "path": "routes/users.js", 697 | "absPath": "/Users/cntower/code/@cntower/dir-parser/myapp/routes/users.js", 698 | "dir": "routes", 699 | "absDir": "/Users/cntower/code/@cntower/dir-parser/myapp/routes" 700 | } 701 | ] 702 | }, 703 | { 704 | "name": "app.js", 705 | "base": "app", 706 | "ext": ".js", 707 | "type": "file", 708 | "size": 1075, 709 | "size_kb": "1.05kb", 710 | "path": "app.js", 711 | "absPath": "/Users/cntower/code/@cntower/dir-parser/myapp/app.js", 712 | "dir": "", 713 | "absDir": "/Users/cntower/code/@cntower/dir-parser/myapp" 714 | }, 715 | { 716 | "name": "dir-info.txt", 717 | "base": "dir-info", 718 | "ext": ".txt", 719 | "type": "file", 720 | "size": 277, 721 | "size_kb": "0.27kb", 722 | "path": "dir-info.txt", 723 | "absPath": "/Users/cntower/code/@cntower/dir-parser/myapp/dir-info.txt", 724 | "dir": "", 725 | "absDir": "/Users/cntower/code/@cntower/dir-parser/myapp" 726 | }, 727 | { 728 | "name": "info.txt", 729 | "base": "info", 730 | "ext": ".txt", 731 | "type": "file", 732 | "size": 301, 733 | "size_kb": "0.29kb", 734 | "path": "info.txt", 735 | "absPath": "/Users/cntower/code/@cntower/dir-parser/myapp/info.txt", 736 | "dir": "", 737 | "absDir": "/Users/cntower/code/@cntower/dir-parser/myapp" 738 | }, 739 | { 740 | "name": "package-lock.json", 741 | "base": "package-lock", 742 | "ext": ".json", 743 | "type": "file", 744 | "size": 68550, 745 | "size_kb": "66.94kb", 746 | "path": "package-lock.json", 747 | "absPath": "/Users/cntower/code/@cntower/dir-parser/myapp/package-lock.json", 748 | "dir": "", 749 | "absDir": "/Users/cntower/code/@cntower/dir-parser/myapp" 750 | }, 751 | { 752 | "name": "package.json", 753 | "base": "package", 754 | "ext": ".json", 755 | "type": "file", 756 | "size": 347, 757 | "size_kb": "0.34kb", 758 | "path": "package.json", 759 | "absPath": "/Users/cntower/code/@cntower/dir-parser/myapp/package.json", 760 | "dir": "", 761 | "absDir": "/Users/cntower/code/@cntower/dir-parser/myapp" 762 | }, 763 | { 764 | "name": "parser.conf.json", 765 | "base": "parser.conf", 766 | "ext": ".json", 767 | "type": "file", 768 | "size": 145, 769 | "size_kb": "0.14kb", 770 | "path": "parser.conf.json", 771 | "absPath": "/Users/cntower/code/@cntower/dir-parser/myapp/parser.conf.json", 772 | "dir": "", 773 | "absDir": "/Users/cntower/code/@cntower/dir-parser/myapp" 774 | }, 775 | { 776 | "name": "test.js", 777 | "base": "test", 778 | "ext": ".js", 779 | "type": "file", 780 | "size": 554, 781 | "size_kb": "0.54kb", 782 | "path": "test.js", 783 | "absPath": "/Users/cntower/code/@cntower/dir-parser/myapp/test.js", 784 | "dir": "", 785 | "absDir": "/Users/cntower/code/@cntower/dir-parser/myapp" 786 | } 787 | ] 788 | ``` 789 | 790 | #### 3.3.5 Make dir-files example 791 | `$ vi test.js` 792 | ```js 793 | parser('./', { 794 | excludes: ['.git', 'node_modules', 'public'], 795 | getFiles: true, 796 | getChildren: true, 797 | dirTree: false 798 | }).then(parsed => { 799 | // fn.log(parsed.children, '# parsed.children'); 800 | console.log(fn.pretty(parsed.files)); 801 | }); 802 | ``` 803 | 804 | #### 3.3.6 Run dir-files example 805 | `$ node test.js` 806 | ```json 807 | [ 808 | { 809 | "name": "www", 810 | "base": "www", 811 | "ext": "", 812 | "type": "file", 813 | "size": 1591, 814 | "size_kb": "1.55kb", 815 | "path": "bin/www", 816 | "absPath": "/Users/cntower/code/@cntower/dir-parser/myapp/bin/www", 817 | "dir": "bin", 818 | "absDir": "/Users/cntower/code/@cntower/dir-parser/myapp/bin" 819 | }, 820 | { 821 | "name": "index.js", 822 | "base": "index", 823 | "ext": ".js", 824 | "type": "file", 825 | "size": 205, 826 | "size_kb": "0.2kb", 827 | "path": "routes/index.js", 828 | "absPath": "/Users/cntower/code/@cntower/dir-parser/myapp/routes/index.js", 829 | "dir": "routes", 830 | "absDir": "/Users/cntower/code/@cntower/dir-parser/myapp/routes" 831 | }, 832 | { 833 | "name": "users.js", 834 | "base": "users", 835 | "ext": ".js", 836 | "type": "file", 837 | "size": 203, 838 | "size_kb": "0.2kb", 839 | "path": "routes/users.js", 840 | "absPath": "/Users/cntower/code/@cntower/dir-parser/myapp/routes/users.js", 841 | "dir": "routes", 842 | "absDir": "/Users/cntower/code/@cntower/dir-parser/myapp/routes" 843 | }, 844 | { 845 | "name": "error.jade", 846 | "base": "error", 847 | "ext": ".jade", 848 | "type": "file", 849 | "size": 84, 850 | "size_kb": "0.08kb", 851 | "path": "views/error.jade", 852 | "absPath": "/Users/cntower/code/@cntower/dir-parser/myapp/views/error.jade", 853 | "dir": "views", 854 | "absDir": "/Users/cntower/code/@cntower/dir-parser/myapp/views" 855 | }, 856 | { 857 | "name": "index.jade", 858 | "base": "index", 859 | "ext": ".jade", 860 | "type": "file", 861 | "size": 66, 862 | "size_kb": "0.06kb", 863 | "path": "views/index.jade", 864 | "absPath": "/Users/cntower/code/@cntower/dir-parser/myapp/views/index.jade", 865 | "dir": "views", 866 | "absDir": "/Users/cntower/code/@cntower/dir-parser/myapp/views" 867 | }, 868 | { 869 | "name": "layout.jade", 870 | "base": "layout", 871 | "ext": ".jade", 872 | "type": "file", 873 | "size": 125, 874 | "size_kb": "0.12kb", 875 | "path": "views/layout.jade", 876 | "absPath": "/Users/cntower/code/@cntower/dir-parser/myapp/views/layout.jade", 877 | "dir": "views", 878 | "absDir": "/Users/cntower/code/@cntower/dir-parser/myapp/views" 879 | }, 880 | { 881 | "name": "app.js", 882 | "base": "app", 883 | "ext": ".js", 884 | "type": "file", 885 | "size": 1075, 886 | "size_kb": "1.05kb", 887 | "path": "app.js", 888 | "absPath": "/Users/cntower/code/@cntower/dir-parser/myapp/app.js", 889 | "dir": "", 890 | "absDir": "/Users/cntower/code/@cntower/dir-parser/myapp" 891 | }, 892 | { 893 | "name": "dir-info.txt", 894 | "base": "dir-info", 895 | "ext": ".txt", 896 | "type": "file", 897 | "size": 277, 898 | "size_kb": "0.27kb", 899 | "path": "dir-info.txt", 900 | "absPath": "/Users/cntower/code/@cntower/dir-parser/myapp/dir-info.txt", 901 | "dir": "", 902 | "absDir": "/Users/cntower/code/@cntower/dir-parser/myapp" 903 | }, 904 | { 905 | "name": "info.txt", 906 | "base": "info", 907 | "ext": ".txt", 908 | "type": "file", 909 | "size": 301, 910 | "size_kb": "0.29kb", 911 | "path": "info.txt", 912 | "absPath": "/Users/cntower/code/@cntower/dir-parser/myapp/info.txt", 913 | "dir": "", 914 | "absDir": "/Users/cntower/code/@cntower/dir-parser/myapp" 915 | }, 916 | { 917 | "name": "package-lock.json", 918 | "base": "package-lock", 919 | "ext": ".json", 920 | "type": "file", 921 | "size": 68550, 922 | "size_kb": "66.94kb", 923 | "path": "package-lock.json", 924 | "absPath": "/Users/cntower/code/@cntower/dir-parser/myapp/package-lock.json", 925 | "dir": "", 926 | "absDir": "/Users/cntower/code/@cntower/dir-parser/myapp" 927 | }, 928 | { 929 | "name": "package.json", 930 | "base": "package", 931 | "ext": ".json", 932 | "type": "file", 933 | "size": 347, 934 | "size_kb": "0.34kb", 935 | "path": "package.json", 936 | "absPath": "/Users/cntower/code/@cntower/dir-parser/myapp/package.json", 937 | "dir": "", 938 | "absDir": "/Users/cntower/code/@cntower/dir-parser/myapp" 939 | }, 940 | { 941 | "name": "parser.conf.json", 942 | "base": "parser.conf", 943 | "ext": ".json", 944 | "type": "file", 945 | "size": 145, 946 | "size_kb": "0.14kb", 947 | "path": "parser.conf.json", 948 | "absPath": "/Users/cntower/code/@cntower/dir-parser/myapp/parser.conf.json", 949 | "dir": "", 950 | "absDir": "/Users/cntower/code/@cntower/dir-parser/myapp" 951 | }, 952 | { 953 | "name": "test.js", 954 | "base": "test", 955 | "ext": ".js", 956 | "type": "file", 957 | "size": 303, 958 | "size_kb": "0.3kb", 959 | "path": "test.js", 960 | "absPath": "/Users/cntower/code/@cntower/dir-parser/myapp/test.js", 961 | "dir": "", 962 | "absDir": "/Users/cntower/code/@cntower/dir-parser/myapp" 963 | } 964 | ] 965 | ``` 966 | -------------------------------------------------------------------------------- /README_zh-CN.md: -------------------------------------------------------------------------------- 1 |

😎 文件夹解析器[Dir Parser v2] 😎

2 |

3 | 4 |

5 | 6 | # 文件夹解析器 dir-parser 7 | 8 | [![npm](https://img.shields.io/npm/v/dir-parser.svg)](https://www.npmjs.com/package/dir-parser) 9 | [![LICENSE MIT](https://img.shields.io/npm/l/dir-parser.svg)](https://www.npmjs.com/package/dir-parser) 10 | [![NPM Downloads](https://img.shields.io/npm/dm/dir-parser.svg?style=flat)](https://npmcharts.com/compare/dir-parser?minimal=true) 11 | [![Install Size](https://packagephobia.now.sh/badge?p=dir-parser)](https://packagephobia.now.sh/result?p=dir-parser) 12 | 13 | > 解析一个文件夹并生成它的结构树 14 | 15 | 使用其它语言阅读: [English](https://github.com/CN-Tower/dir-parser) | 简体中文 16 | 17 | - [文件夹解析器 dir-parser](#文件夹解析器-dir-parser) 18 | - [一、什么是文件夹解析器 dir-parser](#一什么是文件夹解析器-dir-parser) 19 | - [1.1 工具简介](#11-工具简介) 20 | - [1.2 安装使用](#12-安装使用) 21 | - [二、在命令行中使用](#二在命令行中使用) 22 | - [2.1 打印帮助信息](#21-打印帮助信息) 23 | - [2.2 生成文件树](#22-生成文件树) 24 | - [2.3 使用解析参数](#23-使用解析参数) 25 | - [2.3.1 排除项-excludes](#231-排除项-excludes) 26 | - [2.3.2 忽略项-ignores](#232-忽略项-ignores) 27 | - [2.3.3 Glob过滤-glob](#233-Glob过滤-glob) 28 | - [2.3.4 正则匹配-patterns](#234-正则匹配-patterns) 29 | - [2.3.5 结构线型-lineType](#235-结构线型-lineType) 30 | - [2.3.6 解析深度-depth](#236-解析深度-depth) 31 | - [2.3.7 节点逆序-reverse](#237-节点逆序-reverse) 32 | - [2.3.8 文件优先-fileFirst](#238-文件优先-fileFirst) 33 | - [2.3.9 仅文件-fileOnly](#239-仅文件-fileOnly) 34 | - [2.3.10 仅文件夹-dirOnly](#2310-仅文件夹-dirOnly) 35 | - [2.3.11 解析信息-dirInfo](#2311-解析信息-dirInfo) 36 | - [2.3.12 路径排除-excPaths](#2312-路径排除-excPaths) 37 | - [2.3.13 正则排除-excPatterns](#2313-正则排除-excPatterns) 38 | - [2.3.14 静默解析-silent](#2314-静默解析-silent) 39 | - [2.3.15 生成结果-generate](#2315-生成结果-generate) 40 | - [2.3.16 配置文件-config](#2316-配置文件-config) 41 | - [2.4 多个命令混合使用](#24-多个命令混合使用) 42 | - [三、在Js代码中使用](#三在Js代码中使用) 43 | - [3.1 方法接口](#31-方法接口) 44 | - [3.1.1 主函数-parser](#311-主函数-parser) 45 | - [3.1.2 参数选项-Options](#312-参数选项-options) 46 | - [3.1.3 解析结果-Parsed](#313-解析结果-parsed) 47 | - [3.1.4 文件夹信息-DirInfo](#314-文件夹信息-dirinfo) 48 | - [3.1.5 文件信息-FileInfo](#315-文件信息-fileinfo) 49 | - [3.2 获取文件树](#32-获取文件树) 50 | - [3.2.1 构建文件树案例](#321-构建文件树案例) 51 | - [3.2.2 执行文件树案例](#322-执行文件树案例) 52 | - [3.3 获取文件信息](#33-获取文件信息) 53 | - [3.3.1 构建文件夹信息案例](#331-构建文件夹信息案例) 54 | - [3.3.2 执行文件夹信息案例](#332-执行文件夹信息案例) 55 | - [3.3.3 构建子文件信息案例](#333-构建子文件信息案例) 56 | - [3.3.4 执行子文件信息案例](#334-执行子文件信息案例) 57 | - [3.3.5 构建纯文件信息案例](#335-构建纯文件信息案例) 58 | - [3.3.6 执行纯文件信息案例](#336-执行纯文件信息案例) 59 | 60 | ## 一、什么是文件夹解析器 dir-parser 61 | 62 | ### 1.1 工具简介 63 | 👍👍👍dir-parser是一个基于nodejs的强大的文件夹分析工具,可以在命令行中使用也可以在javascript代码中应用。有很多实用的参数可以设置,可以帮助你获取格式化的文件夹树和内部信息。 64 | 65 | ### 1.2 安装使用 66 | 67 | #### 1.2.1 全局安装 68 | - yarn: `$ yarn global add dir-parser` 69 | - npm: `$ npm install -g dir-parser` 70 | 71 | #### 1.2.2 局部安装 72 | - yarn: `$ yarn add dir-parser` or `$ yarn add dir-parser -D` 73 | - npm: `$ npm install dir-parser` or `$ npm install dir-parser -D` 74 | 75 | ## 二、在命令行中使用 76 | 77 | ### 2.1 打印帮助信息 78 | `$ parser -H` (或: `$ parser --Help`) 79 | ``` 80 | 用例: parser [参数options] 81 | 82 | 参数 Options: 83 | -V, --version 打印输出版本号。 84 | -v, --version 打印输出版本号。 85 | -c, --config [config] 根据配置文件解析,可选。 86 | -i, --input 指定个目标文件夹,(默认: "./")。 87 | -o, --output 解析结果输出目录,(默认: "./")。 88 | -d, --depth 解析深度,0表示不限制。(默认: 0)。 89 | -l, --lineType 生成的文件树线型, "dash" 或 "solid",(默认: "solid")。 90 | -e, --excludes 根据名称排除文件夹或文件。 91 | -x, --excPaths 根据路径排除文件夹或文件。 92 | -p, --patterns 根据正则解析文件夹或文件。 93 | -g, --generate [fileName] 生成一个解析结果的文件,默认文件名为"dir-info.txt"。 94 | -r, --reverse 生成节点逆序的文件树。 95 | -s, --silent 静默解析,不在控制台输出解析结果。 96 | -f, --fileFirst 先输出文件节点,先于文件夹节点。 97 | -F, --fileOnly 只解析文件。 98 | -D, --dirOnly 只解析文件夹,只有当fileOnly为false时才生效。 99 | -I, --ignores 根据名称忽略一些文件夹或文件。 100 | -N, --no-dirInfo 不在解析结果中显示文件夹和文件的数量信息。 101 | -G, --glob 使用glob语法过虑文件. 102 | --paths 根据路径解析文件夹或文件。 103 | --includes 根据名称解析文件夹或文件。 104 | --excPatterns 根据正则排队文件夹或文件。 105 | -H, --Help 打印中文帮助信息。 106 | -h, --help 打印英语帮助信息。(output usage information) 107 | ``` 108 | 109 | ### 2.2 生成文件树 110 | 如果需要跑例子的话,你可能需要安装 `express-generator`,但这也不是必需的:
111 | 运行:
112 | `$ npm install -g express-generator`
113 | `$ express myapp`
114 | `$ cd myapp`
115 | `$ parser`
116 | ``` 117 | myapp ( Directories: 7, Files: 9 ) 118 | ├── bin 119 | │ └── www 120 | ├── public 121 | │ ├── images/ 122 | │ ├── javascripts/ 123 | │ └── stylesheets 124 | │ └── style.css 125 | ├── routes 126 | │ ├── index.js 127 | │ └── users.js 128 | ├── views 129 | │ ├── error.jade 130 | │ ├── index.jade 131 | │ └── layout.jade 132 | ├── app.js 133 | └── package.json 134 | ``` 135 | 136 | ### 2.3 使用解析参数 137 | 138 | #### 2.3.1 排除项-excludes 139 | 👉 根据名称排除文件夹或文件。
140 | `$ # git init`
141 | `$ npm install`
142 | `$ parser -e .git,node_modules,public`
143 | 或: `$ parser --excludes .git,node_modules,public` 144 | ``` 145 | myapp ( Directories: 3, Files: 9 ) 146 | ├── bin 147 | │ └── www 148 | ├── routes 149 | │ ├── index.js 150 | │ └── users.js 151 | ├── views 152 | │ ├── error.jade 153 | │ ├── index.jade 154 | │ └── layout.jade 155 | ├── app.js 156 | ├── package-lock.json 157 | └── package.json 158 | ``` 159 | 文件或文件名称中包含空格:
160 | `$ touch 'white space.txt'`
161 | `$ parser -e '[".git", "node_modules", "public", "white space.txt"]'` 162 | `$ rm -rf white\ space.txt` 163 | ``` 164 | myapp ( Directories: 3, Files: 9 ) 165 | ├── bin 166 | │ └── www 167 | ├── routes 168 | │ ├── index.js 169 | │ └── users.js 170 | ├── views 171 | │ ├── error.jade 172 | │ ├── index.jade 173 | │ └── layout.jade 174 | ├── app.js 175 | ├── package-lock.json 176 | └── package.json 177 | ``` 178 | 179 | #### 2.3.2 忽略项-ignores 180 | 👉 根据名称忽略一些文件夹或文件。
181 | `$ parser -e node_modules -I bin,public`
182 | 或: `$ parser -e node_modules --ignores bin,public` 183 | ``` 184 | myapp ( Directories: 4, Files: 8 ) 185 | ├── bin/ 186 | ├── public/ 187 | ├── routes 188 | │ ├── index.js 189 | │ └── users.js 190 | ├── views 191 | │ ├── error.jade 192 | │ ├── index.jade 193 | │ └── layout.jade 194 | ├── app.js 195 | ├── package-lock.json 196 | └── package.json 197 | ``` 198 | 199 | #### 2.3.3 Glob过滤-glob 200 | 👉 使用glob规则过滤,注意:glob规则必需要有引号!
201 | `$ parser -e node_modules -G '**/*.js'`
202 | 或: `$ parser -e node_modules --glob '**/*.js'` 203 | ``` 204 | myapp ( Directories: 1, Files: 3 ) 205 | ├── routes 206 | │ ├── index.js 207 | │ └── users.js 208 | └── app.js 209 | ``` 210 | 211 | #### 2.3.4 正则匹配-patterns 212 | 👉 根据正则解析文件夹或文件。
213 | `$ parser -e node_modules -p .js$`
214 | 或: `$ parser -e node_modules --patterns .js$` 215 | ``` 216 | myapp ( Directories: 1, Files: 3 ) 217 | ├── routes 218 | │ ├── index.js 219 | │ └── users.js 220 | └── app.js 221 | ``` 222 | 223 | #### 2.3.5 结构线型-lineType 224 | 👉 生成的文件树线型, "dash" 或 "solid",(默认: "solid")。
225 | `$ parser -e bin,node_modules -l dash`
226 | 或: `$ parser -e bin,node_modules --lineType dash` 227 | ``` 228 | myapp ( Directories: 6, Files: 9 ) 229 | +-- public 230 | ¦ +-- images/ 231 | ¦ +-- javascripts/ 232 | ¦ +-- stylesheets 233 | ¦ +-- style.css 234 | +-- routes 235 | ¦ +-- index.js 236 | ¦ +-- users.js 237 | +-- views 238 | ¦ +-- error.jade 239 | ¦ +-- index.jade 240 | ¦ +-- layout.jade 241 | +-- app.js 242 | +-- package-lock.json 243 | +-- package.json 244 | ``` 245 | 246 | #### 2.3.6 解析深度-depth 247 | 👉 解析深度,0表示不限制。(默认: 0)
248 | `$ parser -e node_modules,views -d 2`
249 | 或: `$ parser -e node_modules,views --depth 2` 250 | ``` 251 | myapp ( Directories: 6, Files: 6 ) 252 | ├── bin 253 | │ └── www 254 | ├── public 255 | │ ├── images/ 256 | │ ├── javascripts/ 257 | │ └── stylesheets/* 258 | ├── routes 259 | │ ├── index.js 260 | │ └── users.js 261 | ├── app.js 262 | ├── package-lock.json 263 | └── package.json 264 | ``` 265 | 266 | #### 2.3.7 节点逆序-reverse 267 | 👉 生成节点逆序的文件树。
268 | `$ parser -e node_modules,views -d 2 -r`
269 | 或: `$ parser -e node_modules,views -d 2 --reverse` 270 | ``` 271 | myapp ( Directories: 6, Files: 6 ) 272 | ├── routes 273 | │ ├── users.js 274 | │ └── index.js 275 | ├── public 276 | │ ├── stylesheets/* 277 | │ ├── javascripts/ 278 | │ └── images/ 279 | ├── bin 280 | │ └── www 281 | ├── package.json 282 | ├── package-lock.json 283 | └── app.js 284 | ``` 285 | 286 | #### 2.3.8 文件优先-fileFirst 287 | 👉 先输出文件节点,先于文件夹节点。
288 | `$ parser -e node_modules,bin,views -f`
289 | 或: `$ parser -e node_modules,bin,views --fileFirst` 290 | ``` 291 | myapp ( Directories: 5, Files: 6 ) 292 | ├── app.js 293 | ├── package-lock.json 294 | ├── package.json 295 | ├── public 296 | │ ├── images/ 297 | │ ├── javascripts/ 298 | │ └── stylesheets 299 | │ └── style.css 300 | └── routes 301 | ├── index.js 302 | └── users.js 303 | ``` 304 | 305 | #### 2.3.9 仅文件-fileOnly 306 | 👉 只解析文件。
307 | `$ parser -e node_modules,bin,views -F`
308 | 或: `$ parser -e node_modules,bin,views --fileOnly` 309 | ``` 310 | myapp ( Directories: 3, Files: 6 ) 311 | ├── public 312 | │ └── stylesheets 313 | │ └── style.css 314 | ├── routes 315 | │ ├── index.js 316 | │ └── users.js 317 | ├── app.js 318 | ├── package-lock.json 319 | └── package.json 320 | ``` 321 | 322 | #### 2.3.10 仅文件夹-dirOnly 323 | 👉 只解析文件夹,只有当fileOnly为false时才生效。
324 | `$ parser -e node_modules,bin,views -D`
325 | 或: `$ parser -e node_modules,bin,views --dirOnly` 326 | ``` 327 | myapp ( Directories: 5 ) 328 | ├── public 329 | │ ├── images/ 330 | │ ├── javascripts/ 331 | │ └── stylesheets/ 332 | └── routes/ 333 | ``` 334 | 335 | #### 2.3.11 解析信息-dirInfo 336 | 👉 不在解析结果中显示文件夹和文件的数量信息。
337 | `$ parser -e node_modules,bin,public -N`
338 | 或: `$ parser -e node_modules,bin,public --no-dirInfo` 339 | ``` 340 | myapp 341 | ├── routes 342 | │ ├── index.js 343 | │ └── users.js 344 | ├── views 345 | │ ├── error.jade 346 | │ ├── index.jade 347 | │ └── layout.jade 348 | ├── app.js 349 | ├── package-lock.json 350 | └── package.json 351 | ``` 352 | 353 | #### 2.3.12 路径排除-excPaths 354 | 👉 根据路径排除文件夹或文件。
355 | `$ parser -e node_modules,bin -x myapp/public`
356 | 或: `$ parser -e node_modules,bin -excPath myapp/public` 357 | ``` 358 | myapp ( Directories: 2, Files: 8 ) 359 | ├── routes 360 | │ ├── index.js 361 | │ └── users.js 362 | ├── views 363 | │ ├── error.jade 364 | │ ├── index.jade 365 | │ └── layout.jade 366 | ├── app.js 367 | ├── package-lock.json 368 | └── package.json 369 | ``` 370 | 371 | #### 2.3.13 正则排除-excPatterns 372 | 👉 根据正则排队文件夹或文件。
373 | `$ parser -e node_modules,bin --excPatterns .jade$,.css$` 374 | ``` 375 | myapp ( Directories: 6, Files: 5 ) 376 | ├── public 377 | │ ├── images/ 378 | │ ├── javascripts/ 379 | │ └── stylesheets/ 380 | ├── routes 381 | │ ├── index.js 382 | │ └── users.js 383 | ├── views/ 384 | ├── app.js 385 | ├── package-lock.json 386 | └── package.json 387 | ``` 388 | 389 | #### 2.3.14 静默解析-silent 390 | 👉 静默解析,不在控制台输出解析结果。
391 | `$ parser -e node_modules,bin,public -s`
392 | 或: `$ parser -e node_modules,bin,public --silent` 393 | 394 | #### 2.3.15 生成结果-generate 395 | 👉 生成一个解析结果的文件,默认文件名为"dir-info.txt"。
396 | `$ parser -e node_modules,bin,public -sg`
397 | 或: `$ parser -e node_modules,bin,public -s --generate`
398 | `$ cat dir-info.txt` 399 | ``` 400 | myapp ( Directories: 2, Files: 8 ) 401 | ├── routes 402 | │ ├── index.js 403 | │ └── users.js 404 | ├── views 405 | │ ├── error.jade 406 | │ ├── index.jade 407 | │ └── layout.jade 408 | ├── app.js 409 | ├── package-lock.json 410 | └── package.json 411 | ``` 412 | 413 | #### 2.3.16 配置文件-config 414 | 👉 根据配置文件解析,可选。
415 | `$ touch parser.conf.json`
416 | `$ vi parser.conf.json` 417 | ```json 418 | { 419 | "directory": "./", 420 | "excludes": [ ".git", "node_modules", "bin", "public", "parser.conf.json" ], 421 | "depth": "2", 422 | "generate": "info.txt" 423 | } 424 | ``` 425 | `$ parser -c ./parser.conf.json` 426 | ``` 427 | myapp ( Directories: 2, Files: 9 ) 428 | ├── routes 429 | │ ├── index.js 430 | │ └── users.js 431 | ├── views 432 | │ ├── error.jade 433 | │ ├── index.jade 434 | │ └── layout.jade 435 | ├── app.js 436 | ├── dir-info.txt 437 | ├── package-lock.json 438 | └── package.json 439 | ``` 440 | 441 | ### 2.4 多个命令混合使用 442 | `parser -e node_modules,bin -I views -d 2 -Nr` 443 | ``` 444 | myapp 445 | ├── views/ 446 | ├── routes 447 | │ ├── users.js 448 | │ └── index.js 449 | ├── public 450 | │ ├── stylesheets/* 451 | │ ├── javascripts/ 452 | │ └── images/ 453 | ├── parser.conf.json 454 | ├── package.json 455 | ├── package-lock.json 456 | ├── info.txt 457 | ├── dir-info.txt 458 | └── app.js 459 | ``` 460 | 461 | ## 三、在Js代码中使用 462 | 463 | ### 3.1 方法接口 464 | 465 | #### 3.1.1 主函数-parser 466 | ```ts 467 | parser(dirPath: string, options: Options): Promise 468 | ``` 469 | 470 | #### 3.1.2 参数选项-Options 471 | ```ts 472 | interface Options { 473 | depth?: number; 474 | reverse?: boolean; 475 | fileFirst?: boolean; 476 | fileOnly?: boolean; 477 | dirOnly?: boolean; 478 | getFiles?: boolean; 479 | getChildren?: boolean; 480 | dirTree?: boolean; // default: true 481 | dirInfo?: boolean; // default: true 482 | lineType?: 'solid' | 'dash'; // default: 'solid' 483 | excludes?: Array; // eg: [ '.git', 'node_modules', '.idea' ]; 484 | excPaths?: Array; // eg: [ 'src/app' ]; 485 | excPatterns?: Array; // eg: [ 'src/*.js ]'; 486 | ignores: Array; // eg: [ 'public' ]; 487 | includes: Array; // eg: [ 'app.js' ]; 488 | paths?: Array; // eg: [ 'src/public' ]; 489 | patterns?: Array; // eg: [ '*.js ]'; 490 | } 491 | ``` 492 | #### 3.1.3 解析结果-Parsed 493 | ```ts 494 | interface Parsed extends DirInfo { 495 | dirTree: string; 496 | children: Array 497 | files: Array 498 | } 499 | ``` 500 | 501 | #### 3.1.4 文件夹信息-DirInfo 502 | ```ts 503 | interface DirInfo { 504 | name: string; 505 | type: 'directory'; 506 | size: number; 507 | size_kb: number; 508 | path: string; 509 | absPath: string; 510 | dir: string; 511 | absDir: string; 512 | dirNum: number; 513 | fileNum: number; 514 | children: Array 515 | } 516 | ``` 517 | 518 | #### 3.1.5 文件信息-FileInfo 519 | ```ts 520 | interface FileInfo { 521 | name: string; 522 | base: string; 523 | ext: string; 524 | type: 'file'; 525 | size: number; 526 | size_kb: number; 527 | path: string; 528 | absPath: string; 529 | dir: string; 530 | absDir: string; 531 | } 532 | ``` 533 | 534 | ### 3.2 获取文件树 535 | 536 | #### 3.2.1 构建文件树案例 537 | `$ npm install funclib`
538 | `$ touch test.js`
539 | `$ vi test.js`
540 | ```js 541 | const fn = require('funclib'); 542 | const parser = require('dir-parser'); 543 | 544 | parser('./', { 545 | excludes: ['.git', 'node_modules'], 546 | // lineType: 'dash', 547 | // fileFirst: true, 548 | }).then(parsed => { 549 | fn.log(parsed.dirTree, '# parsed.dirTree'); 550 | 551 | // fn.log(fn.pick(parsed, prop => prop !== 'dirTree'), '# parsed result info'); 552 | // fn.log(parsed.children, '# parsed.children'); 553 | // fn.log(parsed.files, '# parsed.files'); 554 | }); 555 | ``` 556 | 557 | #### 3.2.2 执行文件树案例 558 | `$ node test.js` 559 | ``` 560 | ================================================================== 561 | [09:48:55] # parsed.dirTree 562 | ------------------------------------------------------------------ 563 | myapp 564 | ├── bin 565 | │ └── www 566 | ├── public 567 | │ ├── images/ 568 | │ ├── javascripts/ 569 | │ └── stylesheets 570 | │ └── style.css 571 | ├── routes 572 | │ ├── index.js 573 | │ └── users.js 574 | ├── views 575 | │ ├── error.jade 576 | │ ├── index.jade 577 | │ └── layout.jade 578 | ├── app.js 579 | ├── dir-info.txt 580 | ├── info.txt 581 | ├── package-lock.json 582 | ├── package.json 583 | ├── parser.conf.json 584 | └── test.js 585 | ================================================================== 586 | ``` 587 | 588 | ### 3.3 获取文件信息 589 | 590 | #### 3.3.1 构建文件夹信息案例 591 | `$ vi test.js` 592 | ```js 593 | parser('./', { 594 | excludes: ['.git', 'node_modules'], 595 | // lineType: 'dash', 596 | // fileFirst: true, 597 | }).then(parsed => { 598 | console.log(fn.pretty(fn.pick(parsed, prop => prop !== 'dirTree'))); 599 | 600 | // fn.log(parsed.dirTree, '# parsed.dirTree'); 601 | // fn.log(parsed.children, '# parsed.children'); 602 | // fn.log(parsed.files, '# parsed.files'); 603 | }); 604 | ``` 605 | #### 3.3.2 执行文件夹信息案例 606 | `$ node test.js` 607 | ```json 608 | { 609 | "name": "myapp", 610 | "type": "directory", 611 | "path": "./", 612 | "absPath": "/Users/cntower/code/@cntower/dir-parser/myapp", 613 | "dir": ".", 614 | "absDir": "/Users/cntower/code/@cntower/dir-parser", 615 | "dirNum": 7, 616 | "fileNum": 14 617 | } 618 | ``` 619 | 620 | #### 3.3.3 构建子文件信息案例 621 | `$ vi test.js` 622 | ```js 623 | parser('./', { 624 | excludes: ['.git', 'node_modules', 'public'], 625 | getFiles: true, // 默认为false,返回结果是否包含一个包含所有子文件信息的数组。 626 | getChildren: true, // 默认为false,返回结果是否包含一个所有子文件夹和子文件信息的数组。 627 | dirTree: false // 默认为true,返回结果是否包含生成的文件树信息 628 | }).then(parsed => { 629 | console.log(fn.pretty(parsed.children)); 630 | // fn.log(parsed.files, '# parsed.files'); 631 | }); 632 | ``` 633 | 634 | #### 3.3.4 执行子文件信息案例 635 | `$ node test.js` 636 | ```json 637 | 、 638 | { 639 | "name": "bin", 640 | "type": "directory", 641 | "size": 1591, 642 | "size_kb": "1.55kb", 643 | "path": "bin", 644 | "absPath": "/Users/cntower/code/@cntower/dir-parser/myapp/bin", 645 | "dir": ".", 646 | "absDir": "/Users/cntower/code/@cntower/dir-parser/myapp", 647 | "dirNum": 0, 648 | "fileNum": 1, 649 | "children": [ 650 | { 651 | "name": "www", 652 | "base": "www", 653 | "ext": "", 654 | "type": "file", 655 | "size": 1591, 656 | "size_kb": "1.55kb", 657 | "path": "bin/www", 658 | "absPath": "/Users/cntower/code/@cntower/dir-parser/myapp/bin/www", 659 | "dir": "bin", 660 | "absDir": "/Users/cntower/code/@cntower/dir-parser/myapp/bin" 661 | } 662 | ] 663 | }, 664 | { 665 | "name": "routes", 666 | "type": "directory", 667 | "size": 408, 668 | "size_kb": "0.4kb", 669 | "path": "routes", 670 | "absPath": "/Users/cntower/code/@cntower/dir-parser/myapp/routes", 671 | "dir": ".", 672 | "absDir": "/Users/cntower/code/@cntower/dir-parser/myapp", 673 | "dirNum": 0, 674 | "fileNum": 2, 675 | "children": [ 676 | { 677 | "name": "index.js", 678 | "base": "index", 679 | "ext": ".js", 680 | "type": "file", 681 | "size": 205, 682 | "size_kb": "0.2kb", 683 | "path": "routes/index.js", 684 | "absPath": "/Users/cntower/code/@cntower/dir-parser/myapp/routes/index.js", 685 | "dir": "routes", 686 | "absDir": "/Users/cntower/code/@cntower/dir-parser/myapp/routes" 687 | }, 688 | { 689 | "name": "users.js", 690 | "base": "users", 691 | "ext": ".js", 692 | "type": "file", 693 | "size": 203, 694 | "size_kb": "0.2kb", 695 | "path": "routes/users.js", 696 | "absPath": "/Users/cntower/code/@cntower/dir-parser/myapp/routes/users.js", 697 | "dir": "routes", 698 | "absDir": "/Users/cntower/code/@cntower/dir-parser/myapp/routes" 699 | } 700 | ] 701 | }, 702 | { 703 | "name": "app.js", 704 | "base": "app", 705 | "ext": ".js", 706 | "type": "file", 707 | "size": 1075, 708 | "size_kb": "1.05kb", 709 | "path": "app.js", 710 | "absPath": "/Users/cntower/code/@cntower/dir-parser/myapp/app.js", 711 | "dir": "", 712 | "absDir": "/Users/cntower/code/@cntower/dir-parser/myapp" 713 | }, 714 | { 715 | "name": "dir-info.txt", 716 | "base": "dir-info", 717 | "ext": ".txt", 718 | "type": "file", 719 | "size": 277, 720 | "size_kb": "0.27kb", 721 | "path": "dir-info.txt", 722 | "absPath": "/Users/cntower/code/@cntower/dir-parser/myapp/dir-info.txt", 723 | "dir": "", 724 | "absDir": "/Users/cntower/code/@cntower/dir-parser/myapp" 725 | }, 726 | { 727 | "name": "info.txt", 728 | "base": "info", 729 | "ext": ".txt", 730 | "type": "file", 731 | "size": 301, 732 | "size_kb": "0.29kb", 733 | "path": "info.txt", 734 | "absPath": "/Users/cntower/code/@cntower/dir-parser/myapp/info.txt", 735 | "dir": "", 736 | "absDir": "/Users/cntower/code/@cntower/dir-parser/myapp" 737 | }, 738 | { 739 | "name": "package-lock.json", 740 | "base": "package-lock", 741 | "ext": ".json", 742 | "type": "file", 743 | "size": 68550, 744 | "size_kb": "66.94kb", 745 | "path": "package-lock.json", 746 | "absPath": "/Users/cntower/code/@cntower/dir-parser/myapp/package-lock.json", 747 | "dir": "", 748 | "absDir": "/Users/cntower/code/@cntower/dir-parser/myapp" 749 | }, 750 | { 751 | "name": "package.json", 752 | "base": "package", 753 | "ext": ".json", 754 | "type": "file", 755 | "size": 347, 756 | "size_kb": "0.34kb", 757 | "path": "package.json", 758 | "absPath": "/Users/cntower/code/@cntower/dir-parser/myapp/package.json", 759 | "dir": "", 760 | "absDir": "/Users/cntower/code/@cntower/dir-parser/myapp" 761 | }, 762 | { 763 | "name": "parser.conf.json", 764 | "base": "parser.conf", 765 | "ext": ".json", 766 | "type": "file", 767 | "size": 145, 768 | "size_kb": "0.14kb", 769 | "path": "parser.conf.json", 770 | "absPath": "/Users/cntower/code/@cntower/dir-parser/myapp/parser.conf.json", 771 | "dir": "", 772 | "absDir": "/Users/cntower/code/@cntower/dir-parser/myapp" 773 | }, 774 | { 775 | "name": "test.js", 776 | "base": "test", 777 | "ext": ".js", 778 | "type": "file", 779 | "size": 554, 780 | "size_kb": "0.54kb", 781 | "path": "test.js", 782 | "absPath": "/Users/cntower/code/@cntower/dir-parser/myapp/test.js", 783 | "dir": "", 784 | "absDir": "/Users/cntower/code/@cntower/dir-parser/myapp" 785 | } 786 | ] 787 | ``` 788 | 789 | #### 3.3.5 构建纯文件信息案例 790 | `$ vi test.js` 791 | ```js 792 | parser('./', { 793 | excludes: ['.git', 'node_modules', 'public'], 794 | getFiles: true, 795 | getChildren: true, 796 | dirTree: false 797 | }).then(parsed => { 798 | // fn.log(parsed.children, '# parsed.children'); 799 | console.log(fn.pretty(parsed.files)); 800 | }); 801 | ``` 802 | 803 | #### 3.3.6 执行纯文件信息案例 804 | `$ node test.js` 805 | ```json 806 | [ 807 | { 808 | "name": "www", 809 | "base": "www", 810 | "ext": "", 811 | "type": "file", 812 | "size": 1591, 813 | "size_kb": "1.55kb", 814 | "path": "bin/www", 815 | "absPath": "/Users/cntower/code/@cntower/dir-parser/myapp/bin/www", 816 | "dir": "bin", 817 | "absDir": "/Users/cntower/code/@cntower/dir-parser/myapp/bin" 818 | }, 819 | { 820 | "name": "index.js", 821 | "base": "index", 822 | "ext": ".js", 823 | "type": "file", 824 | "size": 205, 825 | "size_kb": "0.2kb", 826 | "path": "routes/index.js", 827 | "absPath": "/Users/cntower/code/@cntower/dir-parser/myapp/routes/index.js", 828 | "dir": "routes", 829 | "absDir": "/Users/cntower/code/@cntower/dir-parser/myapp/routes" 830 | }, 831 | { 832 | "name": "users.js", 833 | "base": "users", 834 | "ext": ".js", 835 | "type": "file", 836 | "size": 203, 837 | "size_kb": "0.2kb", 838 | "path": "routes/users.js", 839 | "absPath": "/Users/cntower/code/@cntower/dir-parser/myapp/routes/users.js", 840 | "dir": "routes", 841 | "absDir": "/Users/cntower/code/@cntower/dir-parser/myapp/routes" 842 | }, 843 | { 844 | "name": "error.jade", 845 | "base": "error", 846 | "ext": ".jade", 847 | "type": "file", 848 | "size": 84, 849 | "size_kb": "0.08kb", 850 | "path": "views/error.jade", 851 | "absPath": "/Users/cntower/code/@cntower/dir-parser/myapp/views/error.jade", 852 | "dir": "views", 853 | "absDir": "/Users/cntower/code/@cntower/dir-parser/myapp/views" 854 | }, 855 | { 856 | "name": "index.jade", 857 | "base": "index", 858 | "ext": ".jade", 859 | "type": "file", 860 | "size": 66, 861 | "size_kb": "0.06kb", 862 | "path": "views/index.jade", 863 | "absPath": "/Users/cntower/code/@cntower/dir-parser/myapp/views/index.jade", 864 | "dir": "views", 865 | "absDir": "/Users/cntower/code/@cntower/dir-parser/myapp/views" 866 | }, 867 | { 868 | "name": "layout.jade", 869 | "base": "layout", 870 | "ext": ".jade", 871 | "type": "file", 872 | "size": 125, 873 | "size_kb": "0.12kb", 874 | "path": "views/layout.jade", 875 | "absPath": "/Users/cntower/code/@cntower/dir-parser/myapp/views/layout.jade", 876 | "dir": "views", 877 | "absDir": "/Users/cntower/code/@cntower/dir-parser/myapp/views" 878 | }, 879 | { 880 | "name": "app.js", 881 | "base": "app", 882 | "ext": ".js", 883 | "type": "file", 884 | "size": 1075, 885 | "size_kb": "1.05kb", 886 | "path": "app.js", 887 | "absPath": "/Users/cntower/code/@cntower/dir-parser/myapp/app.js", 888 | "dir": "", 889 | "absDir": "/Users/cntower/code/@cntower/dir-parser/myapp" 890 | }, 891 | { 892 | "name": "dir-info.txt", 893 | "base": "dir-info", 894 | "ext": ".txt", 895 | "type": "file", 896 | "size": 277, 897 | "size_kb": "0.27kb", 898 | "path": "dir-info.txt", 899 | "absPath": "/Users/cntower/code/@cntower/dir-parser/myapp/dir-info.txt", 900 | "dir": "", 901 | "absDir": "/Users/cntower/code/@cntower/dir-parser/myapp" 902 | }, 903 | { 904 | "name": "info.txt", 905 | "base": "info", 906 | "ext": ".txt", 907 | "type": "file", 908 | "size": 301, 909 | "size_kb": "0.29kb", 910 | "path": "info.txt", 911 | "absPath": "/Users/cntower/code/@cntower/dir-parser/myapp/info.txt", 912 | "dir": "", 913 | "absDir": "/Users/cntower/code/@cntower/dir-parser/myapp" 914 | }, 915 | { 916 | "name": "package-lock.json", 917 | "base": "package-lock", 918 | "ext": ".json", 919 | "type": "file", 920 | "size": 68550, 921 | "size_kb": "66.94kb", 922 | "path": "package-lock.json", 923 | "absPath": "/Users/cntower/code/@cntower/dir-parser/myapp/package-lock.json", 924 | "dir": "", 925 | "absDir": "/Users/cntower/code/@cntower/dir-parser/myapp" 926 | }, 927 | { 928 | "name": "package.json", 929 | "base": "package", 930 | "ext": ".json", 931 | "type": "file", 932 | "size": 347, 933 | "size_kb": "0.34kb", 934 | "path": "package.json", 935 | "absPath": "/Users/cntower/code/@cntower/dir-parser/myapp/package.json", 936 | "dir": "", 937 | "absDir": "/Users/cntower/code/@cntower/dir-parser/myapp" 938 | }, 939 | { 940 | "name": "parser.conf.json", 941 | "base": "parser.conf", 942 | "ext": ".json", 943 | "type": "file", 944 | "size": 145, 945 | "size_kb": "0.14kb", 946 | "path": "parser.conf.json", 947 | "absPath": "/Users/cntower/code/@cntower/dir-parser/myapp/parser.conf.json", 948 | "dir": "", 949 | "absDir": "/Users/cntower/code/@cntower/dir-parser/myapp" 950 | }, 951 | { 952 | "name": "test.js", 953 | "base": "test", 954 | "ext": ".js", 955 | "type": "file", 956 | "size": 303, 957 | "size_kb": "0.3kb", 958 | "path": "test.js", 959 | "absPath": "/Users/cntower/code/@cntower/dir-parser/myapp/test.js", 960 | "dir": "", 961 | "absDir": "/Users/cntower/code/@cntower/dir-parser/myapp" 962 | } 963 | ] 964 | ``` 965 | -------------------------------------------------------------------------------- /bin/parser.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | const fs = require('fs'); 4 | const fn = require('funclib'); 5 | const path = require('path'); 6 | const program = require('commander'); 7 | const pkg = require('../package.json'); 8 | const parser = require('../src/dir-parser'); 9 | 10 | program.version(pkg.version) 11 | .option('-v, --version', 'output the version number') 12 | .option('-c, --config [config]', 'config file, Optional.') 13 | .option('-i, --input ', 'target directory', './') 14 | .option('-o, --output ', 'output path', './') 15 | .option('-d, --depth ', 'depth of a parse process, 0 means no limit', 0) 16 | .option('-l, --lineType ', 'line type of tree, "dash" or "solid"', 'solid') 17 | .option('-e, --excludes ', 'exclude some directories or files by name.') 18 | .option('-x, --excPaths ', 'exclude directories or files by path.') 19 | .option('-p, --patterns ', 'filter directories or files by RegExp.') 20 | .option('-g, --generate [fileName]', 'generate a dir-info file to the output path, "dir-info.txt" is default.') 21 | .option('-r, --reverse', 'reverse the parsed dir-tree nodes.') 22 | .option('-s, --silent', 'not show the parsed dir-tree in terminal.') 23 | .option('-f, --fileFirst', 'print files first, before directories.') 24 | .option('-F, --fileOnly', 'pase files only.') 25 | .option('-D, --dirOnly', 'pase directories only, and it only takes effect when fileOnly is false.') 26 | .option('-I, --ignores ', 'ignore some directories or files by name.') 27 | .option('-N, --no-dirInfo', 'hide file and directory number info on the result top.') 28 | .option('-G, --glob ', 'filter files with glob patterns.') 29 | .option('--paths ', 'filter directories or files by path.') 30 | .option('--includes ', 'filter directories or files by name.') 31 | .option('--excPatterns ', 'exclude directories or files by RegExp.') 32 | .option('-H, --Help', 'output chinese usage information.(打印中文帮助信息.)') 33 | .parse(process.argv); 34 | 35 | if (program.Help) { 36 | console.log(`用例: parser [参数options] 37 | 38 | 参数 Options: 39 | -V, --version 打印输出版本号。 40 | -v, --version 打印输出版本号。 41 | -c, --config [config] 根据配置文件解析,可选。 42 | -i, --input 指定个目标文件夹,(默认: "./")。 43 | -o, --output 解析结果输出目录,(默认: "./")。 44 | -d, --depth 解析深度,0表示不限制。(默认: 0)。 45 | -l, --lineType 生成的文件树线型, "dash" 或 "solid",(默认: "solid")。 46 | -e, --excludes 根据名称排除文件夹或文件。 47 | -x, --excPaths 根据路径排除文件夹或文件。 48 | -p, --patterns 根据正则解析文件夹或文件。 49 | -g, --generate [fileName] 生成一个解析结果的文件,默认文件名为"dir-info.txt"。 50 | -r, --reverse 生成节点逆序的文件树。 51 | -s, --silent 静默解析,不在控制台输出解析结果。 52 | -f, --fileFirst 先输出文件节点,先于文件夹节点。 53 | -F, --fileOnly 只解析文件。 54 | -D, --dirOnly 只解析文件夹,只有当fileOnly为false时才生效。 55 | -I, --ignores 根据名称忽略一些文件夹或文件。 56 | -N, --no-dirInfo 不在解析结果中显示文件夹和文件的数量信息。 57 | -G, --glob 使用glob语法过虑文件. 58 | --paths 根据路径解析文件夹或文件。 59 | --includes 根据名称解析文件夹或文件。 60 | --excPatterns 根据正则排队文件夹或文件。 61 | -H, --Help 打印中文帮助信息。 62 | -h, --help 打印英语帮助信息。(output usage information)`); 63 | return process.exit(0); 64 | } 65 | 66 | let config = {}; 67 | if (program.config) { 68 | config = require(path.resolve(program.config)); 69 | } 70 | 71 | const target = rmQuote(program.input || fn.get(config, 'input', 'str') || path.resolve('./')); 72 | const output = rmQuote(program.output || fn.get(config, 'output', 'str') || path.resolve('./')); 73 | const lineType = program.lineType || fn.get(config, 'lineType', 'str') || 'solid'; 74 | const depth = parseInt(program.depth) || parseInt(fn.get(config, 'depth', 'str')) || 0; 75 | const excludes = matchHandler(program.excludes || fn.get(config, 'excludes', 'arr') || [], 'excludes'); 76 | const excPaths = matchHandler(program.excPaths || fn.get(config, 'excPaths', 'arr') || [], 'excPaths'); 77 | const excPatterns = matchHandler(program.excPatterns || fn.get(config, 'excPatterns', 'arr') || [], 'excPatterns'); 78 | const ignores = matchHandler(program.ignores || fn.get(config, 'ignores', 'arr') || [], 'ignores'); 79 | const includes = matchHandler(program.includes || fn.get(config, 'includes', 'arr') || [], 'includes'); 80 | const paths = matchHandler(program.paths || fn.get(config, 'paths', 'arr') || [], 'paths'); 81 | const patterns = matchHandler(program.patterns || fn.get(config, 'patterns', 'arr') || [], 'patterns'); 82 | const glob = program.glob || fn.get(config, 'glob', 'str') || ''; 83 | const generate = program.generate || fn.get(config, 'generate'); 84 | const reverse = program.reverse || fn.get(config, 'reverse', 'bol'); 85 | const silent = program.silent || fn.get(config, 'silent', 'bol'); 86 | const fileFirst = program.fileFirst || fn.get(config, 'fileFirst', 'bol'); 87 | const fileOnly = program.fileOnly || fn.get(config, 'fileOnly', 'bol'); 88 | const dirOnly = program.dirOnly || fn.get(config, 'dirOnly', 'bol'); 89 | const dInfo = program.dirInfo || fn.get(config, 'dirInfo', 'bol'); 90 | const dirInfo = fn.isBol(dInfo) ? dInfo : true; 91 | const outputName = fn.isStr(generate) && generate || 'dir-info.txt'; 92 | 93 | if (!fs.statSync(target).isDirectory()) { 94 | throw new Error('Target must be a directory!') 95 | } 96 | const outputStat = fs.statSync(output); 97 | if (!outputStat.isDirectory() && !outputStat.isFile()) { 98 | throw new Error('Output must be a file or a directory!') 99 | } 100 | if (outputStat.isDirectory()) { 101 | outputFile = path.join(output, outputName) 102 | } 103 | // excPaths.push(outputFile); 104 | 105 | /** 106 | * Format the target and output 107 | */ 108 | function rmQuote(str) { 109 | return str.replace(/^['"`]|['"`]$/mg, ''); 110 | } 111 | 112 | /** 113 | * Format the matchs 114 | */ 115 | function matchHandler(match, type_) { 116 | if (fn.typeOf(match, 'str')) { 117 | match = rmQuote(match); 118 | if (match.startsWith('[')) { 119 | try { 120 | eval('match =' + match); 121 | } catch (e) { 122 | match = fn.get(config, type_, 'arr') || []; 123 | } 124 | } else { 125 | match = match.replace(/,/mg, ' ').split(' '); 126 | } 127 | } 128 | return fn.toArr(match); 129 | } 130 | 131 | /** 132 | * Log the parameters 133 | */ 134 | // fn.log({ 135 | // target, output, depth, lineType, excludes, excPaths, excPatterns, ignores, includes, 136 | // paths, patterns, reverse, silent, generate, dirInfo, fileFirst, fileOnly, dirOnly, 137 | // }, '#Cmd Params'); 138 | 139 | /** 140 | * Parse target dir by options 141 | */ 142 | parser(target, { 143 | depth, reverse, lineType, excludes, excPaths, excPatterns, ignores, 144 | includes, paths, patterns, dirInfo, fileFirst, fileOnly, dirOnly, glob, 145 | }).then( 146 | parsed => { 147 | if (!silent) console.log(parsed.dirTree); 148 | if (generate || silent) fn.wt(outputFile, parsed.dirTree); 149 | }, 150 | error => { 151 | console.log(fn.chalk(error.message, 'red')); 152 | } 153 | ); 154 | -------------------------------------------------------------------------------- /dir-info.txt: -------------------------------------------------------------------------------- 1 | dir-parser 2 | ├── bin 3 | │ └── parser.js 4 | ├── images 5 | │ ├── demo.png 6 | │ └── dir-parser.jpg 7 | ├── src 8 | │ ├── base.js 9 | │ └── dir-parser.js 10 | ├── test 11 | │ └── test.js 12 | ├── .gitignore 13 | ├── .prettierrc 14 | ├── README.md 15 | ├── README_zh-CN.md 16 | ├── index.d.ts 17 | ├── index.js 18 | ├── package-lock.json 19 | ├── package.json 20 | └── parser.conf.json -------------------------------------------------------------------------------- /images/demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CN-Tower/dir-parser/4155f69feb001708c5d4316491d4c9cc28dd9ccd/images/demo.png -------------------------------------------------------------------------------- /images/dir-parser.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CN-Tower/dir-parser/4155f69feb001708c5d4316491d4c9cc28dd9ccd/images/dir-parser.jpg -------------------------------------------------------------------------------- /index.d.ts: -------------------------------------------------------------------------------- 1 | export = parser; 2 | export as namespace parser; 3 | 4 | declare var parser: parser.Parser; 5 | 6 | declare namespace parser { 7 | interface Parser { 8 | /** 9 | * parser() main method 10 | * @param dirPath { string } 11 | * @param ptions { Options } 12 | */ 13 | (dirPath: string, ptions: Options): Promise 14 | } 15 | 16 | /** 17 | * options of dirparse 18 | */ 19 | interface Options { 20 | depth?: number; 21 | reverse?: boolean; 22 | fileFirst?: boolean; 23 | fileOnly?: boolean; 24 | dirOnly?: boolean; 25 | getFiles?: boolean; 26 | getChildren?: boolean; 27 | dirTree?: boolean; // default: true 28 | dirInfo?: boolean; // default: true 29 | lineType?: 'solid' | 'dash' | 'dashed'; // default: 'solid' 30 | excludes?: Array; // eg: [ '.git', 'node_modules', '.idea' ]; 31 | excPaths?: Array; // eg: [ 'src/app' ]; 32 | excPatterns?: Array; // eg: [ 'src/*.js ]'; 33 | ignores: Array; // eg: [ 'public' ]; 34 | includes: Array; // eg: [ 'app.js' ]; 35 | paths?: Array; // eg: [ 'src/public' ]; 36 | patterns?: Array; // eg: [ '*.js' ]'; 37 | glob?: string; // eg: '**/*.js'; 38 | } 39 | 40 | /** 41 | * the pased result. 42 | */ 43 | interface Parsed extends DirInfo { 44 | dirTree: string; 45 | children: Array 46 | files: Array 47 | } 48 | 49 | 50 | /** 51 | * field of directory info. 52 | */ 53 | interface DirInfo { 54 | name: string; 55 | type: 'directory'; 56 | size: number; 57 | size_kb: number; 58 | path: string; 59 | absPath: string; 60 | dir: string; 61 | absDir: string; 62 | dirNum: number; 63 | fileNum: number; 64 | children: Array 65 | } 66 | 67 | /** 68 | * field of file info. 69 | */ 70 | interface FileInfo { 71 | name: string; 72 | base: string; 73 | ext: string; 74 | type: 'file'; 75 | size: number; 76 | size_kb: number; 77 | path: string; 78 | absPath: string; 79 | dir: string; 80 | absDir: string; 81 | } 82 | } -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | module.exports = require('./src/dir-parser'); -------------------------------------------------------------------------------- /myapp/app.js: -------------------------------------------------------------------------------- 1 | var createError = require('http-errors'); 2 | var express = require('express'); 3 | var path = require('path'); 4 | var cookieParser = require('cookie-parser'); 5 | var logger = require('morgan'); 6 | 7 | var indexRouter = require('./routes/index'); 8 | var usersRouter = require('./routes/users'); 9 | 10 | var app = express(); 11 | 12 | // view engine setup 13 | app.set('views', path.join(__dirname, 'views')); 14 | app.set('view engine', 'jade'); 15 | 16 | app.use(logger('dev')); 17 | app.use(express.json()); 18 | app.use(express.urlencoded({ extended: false })); 19 | app.use(cookieParser()); 20 | app.use(express.static(path.join(__dirname, 'public'))); 21 | 22 | app.use('/', indexRouter); 23 | app.use('/users', usersRouter); 24 | 25 | // catch 404 and forward to error handler 26 | app.use(function(req, res, next) { 27 | next(createError(404)); 28 | }); 29 | 30 | // error handler 31 | app.use(function(err, req, res, next) { 32 | // set locals, only providing error in development 33 | res.locals.message = err.message; 34 | res.locals.error = req.app.get('env') === 'development' ? err : {}; 35 | 36 | // render the error page 37 | res.status(err.status || 500); 38 | res.render('error'); 39 | }); 40 | 41 | module.exports = app; 42 | -------------------------------------------------------------------------------- /myapp/bin/www: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | /** 4 | * Module dependencies. 5 | */ 6 | 7 | var app = require('../app'); 8 | var debug = require('debug')('myapp:server'); 9 | var http = require('http'); 10 | 11 | /** 12 | * Get port from environment and store in Express. 13 | */ 14 | 15 | var port = normalizePort(process.env.PORT || '3000'); 16 | app.set('port', port); 17 | 18 | /** 19 | * Create HTTP server. 20 | */ 21 | 22 | var server = http.createServer(app); 23 | 24 | /** 25 | * Listen on provided port, on all network interfaces. 26 | */ 27 | 28 | server.listen(port); 29 | server.on('error', onError); 30 | server.on('listening', onListening); 31 | 32 | /** 33 | * Normalize a port into a number, string, or false. 34 | */ 35 | 36 | function normalizePort(val) { 37 | var port = parseInt(val, 10); 38 | 39 | if (isNaN(port)) { 40 | // named pipe 41 | return val; 42 | } 43 | 44 | if (port >= 0) { 45 | // port number 46 | return port; 47 | } 48 | 49 | return false; 50 | } 51 | 52 | /** 53 | * Event listener for HTTP server "error" event. 54 | */ 55 | 56 | function onError(error) { 57 | if (error.syscall !== 'listen') { 58 | throw error; 59 | } 60 | 61 | var bind = typeof port === 'string' 62 | ? 'Pipe ' + port 63 | : 'Port ' + port; 64 | 65 | // handle specific listen errors with friendly messages 66 | switch (error.code) { 67 | case 'EACCES': 68 | console.error(bind + ' requires elevated privileges'); 69 | process.exit(1); 70 | break; 71 | case 'EADDRINUSE': 72 | console.error(bind + ' is already in use'); 73 | process.exit(1); 74 | break; 75 | default: 76 | throw error; 77 | } 78 | } 79 | 80 | /** 81 | * Event listener for HTTP server "listening" event. 82 | */ 83 | 84 | function onListening() { 85 | var addr = server.address(); 86 | var bind = typeof addr === 'string' 87 | ? 'pipe ' + addr 88 | : 'port ' + addr.port; 89 | debug('Listening on ' + bind); 90 | } 91 | -------------------------------------------------------------------------------- /myapp/dir-info.txt: -------------------------------------------------------------------------------- 1 | myapp ( Directories: 2, Files: 8 ) 2 | ├── routes 3 | │ ├── index.js 4 | │ └── users.js 5 | ├── views 6 | │ ├── error.jade 7 | │ ├── index.jade 8 | │ └── layout.jade 9 | ├── app.js 10 | ├── package-lock.json 11 | └── package.json -------------------------------------------------------------------------------- /myapp/info.txt: -------------------------------------------------------------------------------- 1 | myapp ( Directories: 2, Files: 9 ) 2 | ├── routes 3 | │ ├── index.js 4 | │ └── users.js 5 | ├── views 6 | │ ├── error.jade 7 | │ ├── index.jade 8 | │ └── layout.jade 9 | ├── app.js 10 | ├── dir-info.txt 11 | ├── package-lock.json 12 | └── package.json -------------------------------------------------------------------------------- /myapp/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "myapp", 3 | "version": "0.0.0", 4 | "private": true, 5 | "scripts": { 6 | "start": "node ./bin/www" 7 | }, 8 | "dependencies": { 9 | "cookie-parser": "~1.4.4", 10 | "debug": "~2.6.9", 11 | "dir-parser": "file:..", 12 | "express": "~4.16.1", 13 | "funclib": "^6.0.6", 14 | "http-errors": "~1.6.3", 15 | "jade": "~1.11.0", 16 | "morgan": "~1.9.1" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /myapp/parser.conf.json: -------------------------------------------------------------------------------- 1 | { 2 | "directory": "./", 3 | "excludes": [ ".git", "node_modules", "bin", "public", "parser.conf.json" ], 4 | "depth": "2", 5 | "generate": "info.txt" 6 | } 7 | -------------------------------------------------------------------------------- /myapp/public/stylesheets/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding: 50px; 3 | font: 14px "Lucida Grande", Helvetica, Arial, sans-serif; 4 | } 5 | 6 | a { 7 | color: #00B7FF; 8 | } 9 | -------------------------------------------------------------------------------- /myapp/routes/index.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var router = express.Router(); 3 | 4 | /* GET home page. */ 5 | router.get('/', function(req, res, next) { 6 | res.render('index', { title: 'Express' }); 7 | }); 8 | 9 | module.exports = router; 10 | -------------------------------------------------------------------------------- /myapp/routes/users.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var router = express.Router(); 3 | 4 | /* GET users listing. */ 5 | router.get('/', function(req, res, next) { 6 | res.send('respond with a resource'); 7 | }); 8 | 9 | module.exports = router; 10 | -------------------------------------------------------------------------------- /myapp/test.js: -------------------------------------------------------------------------------- 1 | const fn = require('funclib'); 2 | const parser = require('dir-parser'); 3 | 4 | parser('./', { 5 | excludes: ['.git', 'node_modules', 'public'], 6 | getFiles: true, 7 | getChildren: true, 8 | dirTree: false 9 | }).then(parsed => { 10 | // fn.log(parsed.children, '# parsed.children'); 11 | console.log(fn.pretty(parsed.files)); 12 | }); -------------------------------------------------------------------------------- /myapp/views/error.jade: -------------------------------------------------------------------------------- 1 | extends layout 2 | 3 | block content 4 | h1= message 5 | h2= error.status 6 | pre #{error.stack} 7 | -------------------------------------------------------------------------------- /myapp/views/index.jade: -------------------------------------------------------------------------------- 1 | extends layout 2 | 3 | block content 4 | h1= title 5 | p Welcome to #{title} 6 | -------------------------------------------------------------------------------- /myapp/views/layout.jade: -------------------------------------------------------------------------------- 1 | doctype html 2 | html 3 | head 4 | title= title 5 | link(rel='stylesheet', href='/stylesheets/style.css') 6 | body 7 | block content 8 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "dir-parser", 3 | "version": "2.1.8", 4 | "description": "Parse a directory and generate it's structure tree.", 5 | "main": "index.js", 6 | "bin": { 7 | "parser": "./bin/parser.js" 8 | }, 9 | "scripts": { 10 | "test": "node test/test.js" 11 | }, 12 | "repository": { 13 | "type": "git", 14 | "url": "git+https://github.com/CN-Tower/dir-parser.git" 15 | }, 16 | "files": [ 17 | "bin/", 18 | "src/", 19 | "index.d.ts", 20 | "index.js", 21 | "README_zh-CN.md", 22 | "README.md" 23 | ], 24 | "keywords": [ 25 | "dir-parser", 26 | "directory-parser", 27 | "dir-tree", 28 | "directory-tree", 29 | "dir-info", 30 | "parse-dir", 31 | "parse-directory", 32 | "tree", 33 | "dir", 34 | "directory", 35 | "file", 36 | "files", 37 | "parse", 38 | "parser", 39 | "util", 40 | "utils", 41 | "path", 42 | "paths", 43 | "filepath", 44 | "glob", 45 | "command" 46 | ], 47 | "author": "CN-Tower", 48 | "license": "MIT", 49 | "bugs": { 50 | "url": "https://github.com/CN-Tower/dir-parser/issues" 51 | }, 52 | "homepage": "https://github.com/CN-Tower/dir-parser#readme", 53 | "dependencies": { 54 | "commander": "^2.20.3", 55 | "funclib": "^6.0.1", 56 | "glob": "^8.0.3" 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /parser.conf.json: -------------------------------------------------------------------------------- 1 | { 2 | "filesFirst": false, 3 | "noNum": false, 4 | "silent": false, 5 | "directory": "your/demo/app", 6 | "output": "your/output/dir", 7 | "excludes": [ ".git", "node_modules" ] 8 | } -------------------------------------------------------------------------------- /src/base.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const path = require('path'); 3 | 4 | function calcSizekb(size){ 5 | return `${Math.round((size / 1024) * 100) / 100}kb`; 6 | } 7 | 8 | exports.DirInfo = class DirInfo { 9 | constructor(name, dirPath) { 10 | this.name = name; 11 | this.type = 'directory'; 12 | this.size = 0; 13 | this.size_kb = 0; 14 | this.path = dirPath; 15 | this.absPath = path.resolve(dirPath); 16 | this.dir = path.dirname(dirPath); 17 | this.absDir = path.dirname(this.absPath); 18 | this.dirNum = 0; 19 | this.fileNum = 0; 20 | this.children = []; 21 | } 22 | } 23 | 24 | exports.FileInfo = class FileInfo { 25 | constructor (name, filePath) { 26 | const infos = path.parse(filePath); 27 | this.name = name; 28 | this.base = infos.name; 29 | this.ext = infos.ext; 30 | this.type = 'file'; 31 | this.size = fs.statSync(filePath).size; 32 | this.size_kb = calcSizekb(this.size); 33 | this.path = filePath; 34 | this.absPath = path.resolve(filePath); 35 | this.dir = infos.dir; 36 | this.absDir = path.dirname(this.absPath); 37 | } 38 | } 39 | 40 | exports.calcSizekb = calcSizekb; -------------------------------------------------------------------------------- /src/dir-parser.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs') 2 | const path = require('path') 3 | const glob = require('glob') 4 | const { drop, typeVal, typeOf, get, isNum } = require('funclib/lib') 5 | const { DirInfo, FileInfo, calcSizekb } = require('./base') 6 | 7 | /** 8 | * Order of dir name's or file name's special first char. 9 | */ 10 | const charOrder = ['_', '-', '.', '(', ')', '@', '&', '#', '^', '+', '~', '$'] 11 | 12 | /** 13 | * Export a dir-parser promise 14 | * @param target string 15 | * @param options object 16 | */ 17 | module.exports = (target, options) => { 18 | return new Promise((resolve, reject) => { 19 | try { 20 | resolve(dirParser(target, options)) 21 | } catch (err) { 22 | reject(err) 23 | } 24 | }) 25 | } 26 | 27 | /** 28 | * Format excludes or includes 29 | * @param {*} exs 30 | */ 31 | function fmtMatchs(exs) { 32 | return drop(exs.map((ex) => typeVal(ex, 'str'))) 33 | } 34 | 35 | /** 36 | * Format paths 37 | * @param {*} pts 38 | */ 39 | function fmtPaths(pts) { 40 | return drop(pts.map((ex) => (typeVal(ex, 'str') ? path.resolve(ex) : ''))) 41 | } 42 | 43 | /** 44 | * Format patterns 45 | * @param {*} ptns 46 | */ 47 | function fmtPatterns(ptns) { 48 | return drop( 49 | ptns.map((ptn) => { 50 | if (typeOf(ptn, 'ptn')) { 51 | return ptn 52 | } else if (typeVal(ptn, 'str')) { 53 | return new RegExp(ptn.replace(/(\*?)\.([\w\d]*\$+)$/, () => `${(RegExp.$1 && '.*') || ''}\.${RegExp.$2}`)) 54 | } else { 55 | return '' 56 | } 57 | }) 58 | ) 59 | } 60 | 61 | /** 62 | * Parse the target directory and generate it's structure tree. 63 | * @param target string 64 | * @param options object 65 | */ 66 | function dirParser(target, options = {}) { 67 | if (!fs.statSync(target).isDirectory()) { 68 | throw new Error('Target must be a directory!') 69 | } 70 | 71 | let depth = get(options, 'depth', 'num') 72 | if (!isNum(depth)) depth = 0 73 | 74 | const isReverse = get(options, 'reverse', 'bol') 75 | const isFileFirst = get(options, 'fileFirst', 'bol') 76 | const isFileOnly = get(options, 'fileOnly', 'bol') 77 | const isDirOnly = isFileOnly ? false : get(options, 'dirOnly', 'bol') 78 | const isHideDirInfo = !get(options, 'dirInfo', 'bol') 79 | const isGetFiles = get(options, 'getFiles', 'bol') 80 | const isGetChildren = get(options, 'getChildren', 'bol') 81 | const isGetDirTree = typeOf(options.dirTree, 'bol') ? options.dirTree : true 82 | const lineType = get(options, 'lineType', 'str') || 'solid' 83 | const excludes = fmtMatchs(get(options, 'excludes', 'arr') || []) 84 | const excPaths = fmtPaths(get(options, 'excPaths', 'arr') || []) 85 | const excPatterns = fmtPatterns(get(options, 'excPatterns', 'arr') || []) 86 | const ignores = fmtMatchs(get(options, 'ignores', 'arr') || []) 87 | const includes = fmtMatchs(get(options, 'includes', 'arr') || []) 88 | const paths = fmtPaths(get(options, 'paths', 'arr') || []) 89 | const patterns = fmtPatterns(get(options, 'patterns', 'arr') || []) 90 | const globStr = get(options, 'glob', 'str') || '' 91 | 92 | let dirTree = '' 93 | const dirs = [] 94 | const files = [] 95 | const absTarget = path.resolve(target) 96 | const tarName = path.basename(absTarget) 97 | const tarInfo = new DirInfo(tarName, target) 98 | if (isGetChildren) { 99 | dirs.push({ path: target, info: tarInfo }) 100 | } 101 | let globFiles 102 | if (globStr) { 103 | globFiles = glob.sync(globStr, { cwd: target }).map((pth) => path.resolve(target, pth)) 104 | } 105 | 106 | parseDir(target, tarInfo.children) 107 | 108 | /** 109 | * Parser The target directory 110 | */ 111 | function parseDir(dirPath, children, deep = 1, prev = '') { 112 | let filesSize = 0 113 | const subDirs = [] 114 | const subFiles = [] 115 | const dirSubArr = fs.readdirSync(dirPath) 116 | const padLeft = deep > 1 ? ' ' : '' 117 | 118 | let dirSubs = [], 119 | i = -1 120 | charOrder.forEach((char) => { 121 | while (++i < dirSubArr.length) { 122 | if (dirSubArr[i] && dirSubArr[i].startsWith(char)) { 123 | dirSubs = dirSubs.concat(dirSubArr.splice(i, 1)) 124 | i-- 125 | } 126 | } 127 | }) 128 | dirSubs = dirSubs.concat(dirSubArr) 129 | if (isReverse) dirSubs.reverse() 130 | 131 | getOrCheckValidSubs(dirPath, dirSubs, deep, false, subDirs, subFiles) 132 | 133 | if (isDirOnly) { 134 | directoriesHandler() 135 | } else if (isFileFirst) { 136 | filesHandler() 137 | directoriesHandler() 138 | } else { 139 | directoriesHandler() 140 | filesHandler() 141 | } 142 | 143 | /** 144 | * handle directories 145 | */ 146 | function directoriesHandler() { 147 | let split = '' 148 | let dirInfo = {} 149 | subDirs.forEach((dir, i) => { 150 | if (!isFileOnly || dir.hasSubs) { 151 | if (isGetChildren) { 152 | dirInfo = new DirInfo(dir.name, dir.path) 153 | dirs.push({ path: dirInfo.path, info: dirInfo }) 154 | children.push(dirInfo) 155 | } 156 | if (isGetDirTree) { 157 | const isMiddleDir = i < subDirs.length - 1 || (!isDirOnly && !isFileFirst && subFiles.length > 0) 158 | const isShowDMark = !dir.hasSubs || dir.ignored || (depth && deep === depth) 159 | const dirEndMark = isShowDMark ? (dir.hasSubs && !dir.ignored ? '/*' : '/') : '' 160 | if (lineType === 'dash' || lineType === 'dashed') { 161 | if (isMiddleDir) { 162 | dirTree += `${prev}${padLeft}+-- ${dir.name}${dirEndMark}\r\n` 163 | split = `${padLeft}¦ ` 164 | } else { 165 | dirTree += `${prev}${padLeft}+-- ${dir.name}${dirEndMark}\r\n` 166 | split = `${padLeft} ` 167 | } 168 | } else { 169 | if (isMiddleDir) { 170 | dirTree += `${prev}${padLeft}├── ${dir.name}${dirEndMark}\r\n` 171 | split = `${padLeft}│ ` 172 | } else { 173 | dirTree += `${prev}${padLeft}└── ${dir.name}${dirEndMark}\r\n` 174 | split = `${padLeft} ` 175 | } 176 | } 177 | } 178 | if (!dir.ignored && (!depth || deep < depth)) { 179 | const nextPath = path.join(dirPath, dir.name) 180 | const nextMemb = isGetChildren ? dirInfo.children : children 181 | const nextDeep = deep + 1 182 | const nextSplit = prev + split 183 | parseDir(nextPath, nextMemb, nextDeep, nextSplit) 184 | } 185 | } 186 | }) 187 | } 188 | 189 | /** 190 | * Handle files 191 | */ 192 | function filesHandler() { 193 | subFiles.forEach((file, i) => { 194 | if (isGetChildren || isGetFiles) { 195 | const fileInfo = new FileInfo(file.name, file.path) 196 | if (isGetFiles) { 197 | files.push(fileInfo) 198 | } 199 | if (isGetChildren) { 200 | children.push(fileInfo) 201 | } 202 | filesSize += fileInfo.size 203 | } 204 | if (isGetDirTree) { 205 | if (lineType === 'dash' || lineType === 'dashed') { 206 | if (i < subFiles.length - 1 || (isFileFirst && subDirs.length > 0)) { 207 | dirTree += `${prev}${padLeft}+-- ${file.name}\r\n` 208 | } else { 209 | dirTree += `${prev}${padLeft}+-- ${file.name}\r\n` 210 | } 211 | } else { 212 | if (i < subFiles.length - 1 || (isFileFirst && subDirs.length > 0)) { 213 | dirTree += `${prev}${padLeft}├── ${file.name}\r\n` 214 | } else { 215 | dirTree += `${prev}${padLeft}└── ${file.name}\r\n` 216 | } 217 | } 218 | } 219 | }) 220 | } 221 | 222 | if (isGetChildren) { 223 | dirs.forEach((dir) => { 224 | if (dirPath.includes(dir.path)) { 225 | dir.info.dirNum += subDirs.length 226 | dir.info.fileNum += subFiles.length 227 | dir.info.size += filesSize 228 | dir.info.size_kb = calcSizekb(dir.info.size) 229 | } 230 | }) 231 | } else { 232 | tarInfo.dirNum += subDirs.length 233 | tarInfo.fileNum += subFiles.length 234 | } 235 | } 236 | 237 | /** 238 | * Get or check has valid sub dir or sub files. 239 | */ 240 | function getOrCheckValidSubs(dirPath, dirSubs, deep, isCheck, subDirs = [], subFiles = []) { 241 | let i = -1 242 | while (++i < dirSubs.length) { 243 | const sub = dirSubs[i] 244 | const iPath = path.join(dirPath, sub) 245 | const sPath = iPath.replace(/\\/gm, '/') 246 | const isExclude = getIsExclude(sub, iPath, sPath) 247 | if (!isExclude) { 248 | const isIgnore = ignores.length && ignores.includes(sub) 249 | const isInclude = getIsInclude(sub, iPath, sPath) 250 | const stat = fs.statSync(iPath) 251 | const iDir = { name: sub, path: iPath } 252 | if (stat.isDirectory()) { 253 | const isSubsValid = getOrCheckValidSubs(iPath, fs.readdirSync(iPath), deep + 1, true) 254 | if (isSubsValid) { 255 | if (!isFileOnly || !depth || deep < depth) { 256 | if (isCheck) return true 257 | subDirs.push({ ...iDir, hasSubs: true, ignored: isIgnore }) 258 | } 259 | } else if (isInclude && !isFileOnly) { 260 | if (isCheck && isDirOnly) return true 261 | subDirs.push({ ...iDir, hasSubs: false, ignored: isIgnore }) 262 | } 263 | } else if (stat.isFile() && !isIgnore && isInclude) { 264 | if (isCheck && isFileOnly) return true 265 | subFiles.push(iDir) 266 | } 267 | } 268 | } 269 | if (isCheck) { 270 | if (isDirOnly) { 271 | return subDirs.length 272 | } else if (isFileOnly) { 273 | return subFiles.length || ((!depth || deep < depth) && subDirs.some((dir) => dir.hasSubs)) 274 | } else { 275 | return subDirs.length || subFiles.length || subDirs.some((dir) => dir.hasSubs) 276 | } 277 | } 278 | } 279 | 280 | function getIsExclude(sub, iPath, sPath) { 281 | return ( 282 | excludes.includes(sub) || 283 | excPaths.some((pth) => iPath === pth || pth.endsWith(iPath)) || 284 | excPatterns.some((ptn) => iPath.match(ptn) || sPath.match(ptn)) 285 | ) 286 | } 287 | 288 | function getIsInclude(sub, iPath, sPath) { 289 | return ( 290 | (!includes.length || includes.includes(sub)) && 291 | (!paths.length || paths.some((pth) => iPath === pth || pth.endsWith(iPath))) && 292 | (!patterns.length || patterns.some((ptn) => iPath.match(ptn) || sPath.match(ptn))) && 293 | (!globFiles || globFiles.some((pth) => iPath === pth || pth.endsWith(iPath))) 294 | ) 295 | } 296 | 297 | if (!isGetChildren) { 298 | delete tarInfo.children 299 | if (!isGetFiles) { 300 | delete tarInfo.size 301 | delete tarInfo.size_kb 302 | } 303 | } 304 | if (isGetFiles) { 305 | tarInfo.files = files 306 | tarInfo.size = files.reduce((size, file) => size + file.size, tarInfo.size) 307 | tarInfo.size_kb = calcSizekb(tarInfo.size) 308 | } 309 | if (isGetDirTree) { 310 | if (isHideDirInfo) { 311 | dirTree = `${tarName}\r\n${dirTree}` 312 | } else if (isDirOnly) { 313 | dirTree = `${tarName} ( Directories: ${tarInfo.dirNum} )\r\n${dirTree}` 314 | } else { 315 | dirTree = `${tarName} ( Directories: ${tarInfo.dirNum}, Files: ${tarInfo.fileNum} )\r\n${dirTree}` 316 | } 317 | tarInfo.dirTree = dirTree.replace(/\r\n$/, '') 318 | } 319 | 320 | return tarInfo 321 | } 322 | -------------------------------------------------------------------------------- /test/test.js: -------------------------------------------------------------------------------- 1 | const fn = require('funclib'); 2 | const parser = require('../index'); 3 | 4 | /** 5 | * ============================================================ 6 | * Get parsed dir-tree 7 | * ============================================================ 8 | */ 9 | let excludes = ['.git', 'dir-info.txt', 'package-lock.json']; 10 | parser('./', { 11 | excludes: excludes, 12 | // lineType: 'dashed', 13 | // filesFirst: true, 14 | }).then(parsed => { 15 | fn.log(parsed.dirTree, '# parsed.dirTree'); 16 | fn.log(fn.pick(parsed, prop => prop !== 'dirTree'), '# parsed result info'); 17 | // fn.log(parsed.children, '# parsed.children'); 18 | // fn.log(parsed.files, '# parsed.files'); 19 | }); 20 | 21 | /** 22 | * ============================================================ 23 | * Get parsed dir-info (children & files) 24 | * ============================================================ 25 | */ 26 | excludes = ['.git', 'node_modules', 'dir-info.txt', 'package-lock.json']; 27 | parser('./', { 28 | excludes: excludes, 29 | getFiles: true, // Default is false, If true, returns will conatins an array of all subfiles's info; 30 | getChildren: true, // Default is false, If true, returns will conatins an object of all children's info; 31 | dirTree: false // Default is true, returns will conatins a tree of the directory; 32 | }).then(parsed => { 33 | fn.log(parsed.children, '# parsed.children'); 34 | fn.log(parsed.files, '# parsed.files'); 35 | }); 36 | --------------------------------------------------------------------------------