UNPKG

35.6 kBPlain TextView Raw
1import * as fs from 'fs-extra';
2import * as path from 'path';
3
4import { Application } from './app/application';
5
6import { COMPODOC_DEFAULTS } from './utils/defaults';
7import { logger } from './logger';
8import { readConfig, handlePath } from './utils/utils';
9
10import { ts } from 'ts-simple-ast';
11import { ParserUtil } from './utils/parser.util.class';
12
13import I18nEngineInstance from './app/engines/i18n.engine';
14
15const pkg = require('../package.json');
16const program = require('commander');
17const os = require('os');
18const osName = require('os-name');
19const cosmiconfig = require('cosmiconfig');
20
21const cosmiconfigModuleName = 'compodoc';
22
23let scannedFiles = [];
24let excludeFiles;
25let includeFiles;
26let cwd = process.cwd();
27
28process.setMaxListeners(0);
29
30export class CliApplication extends Application {
31 /**
32 * Run compodoc from the command line.
33 */
34 protected generate(): any {
35 function list(val) {
36 return val.split(',');
37 }
38
39 program
40 .version(pkg.version)
41 .usage('<src> [options]')
42 .option(
43 '-c, --config [config]',
44 'A configuration file : .compodocrc, .compodocrc.json, .compodocrc.yaml or compodoc property in package.json'
45 )
46 .option('-p, --tsconfig [config]', 'A tsconfig.json file')
47 .option(
48 '-d, --output [folder]',
49 'Where to store the generated documentation',
50 COMPODOC_DEFAULTS.folder
51 )
52 .option('-y, --extTheme [file]', 'External styling theme file')
53 .option('-n, --name [name]', 'Title documentation', COMPODOC_DEFAULTS.title)
54 .option(
55 '-a, --assetsFolder [folder]',
56 'External assets folder to copy in generated documentation folder'
57 )
58 .option('-o, --open [value]', 'Open the generated documentation')
59 .option(
60 '-t, --silent',
61 "In silent mode, log messages aren't logged in the console",
62 false
63 )
64 .option(
65 '-s, --serve',
66 'Serve generated documentation (default http://localhost:8080/)',
67 false
68 )
69 .option('-r, --port [port]', 'Change default serving port', COMPODOC_DEFAULTS.port)
70 .option(
71 '-w, --watch',
72 'Watch source files after serve and force documentation rebuild',
73 false
74 )
75 .option(
76 '-e, --exportFormat [format]',
77 'Export in specified format (json, html)',
78 COMPODOC_DEFAULTS.exportFormat
79 )
80 .option('--language [language]', 'Language used for the generated documentation (en-US, fr-FR, zh-CN)', COMPODOC_DEFAULTS.language)
81 .option(
82 '--theme [theme]',
83 "Choose one of available themes, default is 'gitbook' (laravel, original, material, postmark, readthedocs, stripe, vagrant)"
84 )
85 .option(
86 '--hideGenerator',
87 'Do not print the Compodoc link at the bottom of the page',
88 false
89 )
90 .option(
91 '--toggleMenuItems <items>',
92 "Close by default items in the menu values : ['all'] or one of these ['modules','components','directives','classes','injectables','interfaces','pipes','additionalPages']",
93 list,
94 COMPODOC_DEFAULTS.toggleMenuItems
95 )
96 .option(
97 '--navTabConfig <tab configs>',
98 `List navigation tab objects in the desired order with two string properties ("id" and "label"). \
99Double-quotes must be escaped with '\\'. \
100Available tab IDs are "info", "readme", "source", "templateData", "tree", and "example". \
101Note: Certain tabs will only be shown if applicable to a given dependency`,
102 list,
103 JSON.stringify(COMPODOC_DEFAULTS.navTabConfig)
104 )
105 .option(
106 '--templates [folder]',
107 'Path to directory of Handlebars templates to override built-in templates'
108 )
109 .option('--includes [path]', 'Path of external markdown files to include')
110 .option(
111 '--includesName [name]',
112 'Name of item menu of externals markdown files',
113 COMPODOC_DEFAULTS.additionalEntryName
114 )
115 .option(
116 '--coverageTest [threshold]',
117 'Test command of documentation coverage with a threshold (default 70)'
118 )
119 .option(
120 '--coverageMinimumPerFile [minimum]',
121 'Test command of documentation coverage per file with a minimum (default 0)'
122 )
123 .option(
124 '--coverageTestThresholdFail [true|false]',
125 'Test command of documentation coverage (global or per file) will fail with error or just warn user (true: error, false: warn)',
126 COMPODOC_DEFAULTS.coverageTestThresholdFail
127 )
128 .option('--coverageTestShowOnlyFailed', 'Display only failed files for a coverage test')
129 .option(
130 '--unitTestCoverage [json-summary]',
131 'To include unit test coverage, specify istanbul JSON coverage summary file'
132 )
133 .option(
134 '--disableSourceCode',
135 'Do not add source code tab and links to source code',
136 false
137 )
138 .option('--disableDomTree', 'Do not add dom tree tab', false)
139 .option('--disableTemplateTab', 'Do not add template tab', false)
140 .option('--disableGraph', 'Do not add the dependency graph', false)
141 .option('--disableCoverage', 'Do not add the documentation coverage report', false)
142 .option('--disablePrivate', 'Do not show private in generated documentation', false)
143 .option('--disableProtected', 'Do not show protected in generated documentation', false)
144 .option('--disableInternal', 'Do not show @internal in generated documentation', false)
145 .option(
146 '--disableLifeCycleHooks',
147 'Do not show Angular lifecycle hooks in generated documentation',
148 false
149 )
150 .option(
151 '--disableRoutesGraph',
152 'Do not add the routes graph',
153 COMPODOC_DEFAULTS.disableRoutesGraph
154 )
155 .option('--disableSearch', 'Do not add the search input', false)
156 .option(
157 '--minimal',
158 'Minimal mode with only documentation. No search, no graph, no coverage.',
159 false
160 )
161 .option('--customFavicon [path]', 'Use a custom favicon')
162 .option('--gaID [id]', 'Google Analytics tracking ID')
163 .option('--gaSite [site]', 'Google Analytics site name', COMPODOC_DEFAULTS.gaSite)
164 .parse(process.argv);
165
166 let outputHelp = () => {
167 program.outputHelp();
168 process.exit(1);
169 };
170
171 const configExplorer = cosmiconfig(cosmiconfigModuleName);
172
173 let configExplorerResult;
174
175 let configFile = {};
176
177 if (program.config) {
178 let configFilePath = program.config;
179 let testConfigFilePath = configFilePath.match(process.cwd());
180 if (testConfigFilePath && testConfigFilePath.length > 0) {
181 configFilePath = configFilePath.replace(process.cwd() + path.sep, '');
182 }
183 configExplorerResult = configExplorer.loadSync(path.resolve(configFilePath));
184 } else {
185 configExplorerResult = configExplorer.searchSync();
186 }
187 if (configExplorerResult) {
188 if (typeof configExplorerResult.config !== 'undefined') {
189 configFile = configExplorerResult.config;
190 }
191 }
192
193 if (configFile.output) {
194 this.configuration.mainData.output = configFile.output;
195 }
196 if (program.output && program.output !== COMPODOC_DEFAULTS.folder) {
197 this.configuration.mainData.output = program.output;
198 }
199
200 if (configFile.extTheme) {
201 this.configuration.mainData.extTheme = configFile.extTheme;
202 }
203 if (program.extTheme) {
204 this.configuration.mainData.extTheme = program.extTheme;
205 }
206
207 if (configFile.language) {
208 this.configuration.mainData.language = configFile.language;
209 }
210 if (program.language) {
211 this.configuration.mainData.language = program.language;
212 }
213
214 if (configFile.theme) {
215 this.configuration.mainData.theme = configFile.theme;
216 }
217 if (program.theme) {
218 this.configuration.mainData.theme = program.theme;
219 }
220
221 if (configFile.name) {
222 this.configuration.mainData.documentationMainName = configFile.name;
223 }
224 if (program.name && program.name !== COMPODOC_DEFAULTS.title) {
225 this.configuration.mainData.documentationMainName = program.name;
226 }
227
228 if (configFile.assetsFolder) {
229 this.configuration.mainData.assetsFolder = configFile.assetsFolder;
230 }
231 if (program.assetsFolder) {
232 this.configuration.mainData.assetsFolder = program.assetsFolder;
233 }
234
235 if (configFile.open) {
236 this.configuration.mainData.open = configFile.open;
237 }
238 if (program.open) {
239 this.configuration.mainData.open = program.open;
240 }
241
242 if (configFile.toggleMenuItems) {
243 this.configuration.mainData.toggleMenuItems = configFile.toggleMenuItems;
244 }
245 if (
246 program.toggleMenuItems &&
247 program.toggleMenuItems !== COMPODOC_DEFAULTS.toggleMenuItems
248 ) {
249 this.configuration.mainData.toggleMenuItems = program.toggleMenuItems;
250 }
251
252 if (configFile.templates) {
253 this.configuration.mainData.templates = configFile.templates;
254 }
255 if (program.templates) {
256 this.configuration.mainData.templates = program.templates;
257 }
258
259 if (configFile.navTabConfig) {
260 this.configuration.mainData.navTabConfig = configFile.navTabConfig;
261 }
262 if (
263 program.navTabConfig &&
264 JSON.parse(program.navTabConfig).length !== COMPODOC_DEFAULTS.navTabConfig.length
265 ) {
266 this.configuration.mainData.navTabConfig = JSON.parse(program.navTabConfig);
267 }
268
269 if (configFile.includes) {
270 this.configuration.mainData.includes = configFile.includes;
271 }
272 if (program.includes) {
273 this.configuration.mainData.includes = program.includes;
274 }
275
276 if (configFile.includesName) {
277 this.configuration.mainData.includesName = configFile.includesName;
278 }
279 if (
280 program.includesName &&
281 program.includesName !== COMPODOC_DEFAULTS.additionalEntryName
282 ) {
283 this.configuration.mainData.includesName = program.includesName;
284 }
285
286 if (configFile.silent) {
287 logger.silent = false;
288 }
289 if (program.silent) {
290 logger.silent = false;
291 }
292
293 if (configFile.serve) {
294 this.configuration.mainData.serve = configFile.serve;
295 }
296 if (program.serve) {
297 this.configuration.mainData.serve = program.serve;
298 }
299
300 if (configFile.port) {
301 this.configuration.mainData.port = configFile.port;
302 }
303 if (program.port && program.port !== COMPODOC_DEFAULTS.port) {
304 this.configuration.mainData.port = program.port;
305 }
306
307 if (configFile.watch) {
308 this.configuration.mainData.watch = configFile.watch;
309 }
310 if (program.watch) {
311 this.configuration.mainData.watch = program.watch;
312 }
313
314 if (configFile.exportFormat) {
315 this.configuration.mainData.exportFormat = configFile.exportFormat;
316 }
317 if (program.exportFormat && program.exportFormat !== COMPODOC_DEFAULTS.exportFormat) {
318 this.configuration.mainData.exportFormat = program.exportFormat;
319 }
320
321 if (configFile.hideGenerator) {
322 this.configuration.mainData.hideGenerator = configFile.hideGenerator;
323 }
324 if (program.hideGenerator) {
325 this.configuration.mainData.hideGenerator = program.hideGenerator;
326 }
327
328 if (configFile.coverageTest) {
329 this.configuration.mainData.coverageTest = true;
330 this.configuration.mainData.coverageTestThreshold =
331 typeof configFile.coverageTest === 'string'
332 ? parseInt(configFile.coverageTest, 10)
333 : COMPODOC_DEFAULTS.defaultCoverageThreshold;
334 }
335 if (program.coverageTest) {
336 this.configuration.mainData.coverageTest = true;
337 this.configuration.mainData.coverageTestThreshold =
338 typeof program.coverageTest === 'string'
339 ? parseInt(program.coverageTest, 10)
340 : COMPODOC_DEFAULTS.defaultCoverageThreshold;
341 }
342
343 if (configFile.coverageMinimumPerFile) {
344 this.configuration.mainData.coverageTestPerFile = true;
345 this.configuration.mainData.coverageMinimumPerFile =
346 typeof configFile.coverageMinimumPerFile === 'string'
347 ? parseInt(configFile.coverageMinimumPerFile, 10)
348 : COMPODOC_DEFAULTS.defaultCoverageMinimumPerFile;
349 }
350 if (program.coverageMinimumPerFile) {
351 this.configuration.mainData.coverageTestPerFile = true;
352 this.configuration.mainData.coverageMinimumPerFile =
353 typeof program.coverageMinimumPerFile === 'string'
354 ? parseInt(program.coverageMinimumPerFile, 10)
355 : COMPODOC_DEFAULTS.defaultCoverageMinimumPerFile;
356 }
357
358 if (configFile.coverageTestThresholdFail) {
359 this.configuration.mainData.coverageTestThresholdFail =
360 configFile.coverageTestThresholdFail === 'false' ? false : true;
361 }
362 if (program.coverageTestThresholdFail) {
363 this.configuration.mainData.coverageTestThresholdFail =
364 program.coverageTestThresholdFail === 'false' ? false : true;
365 }
366
367 if (configFile.coverageTestShowOnlyFailed) {
368 this.configuration.mainData.coverageTestShowOnlyFailed =
369 configFile.coverageTestShowOnlyFailed;
370 }
371 if (program.coverageTestShowOnlyFailed) {
372 this.configuration.mainData.coverageTestShowOnlyFailed =
373 program.coverageTestShowOnlyFailed;
374 }
375
376 if (configFile.unitTestCoverage) {
377 this.configuration.mainData.unitTestCoverage = configFile.unitTestCoverage;
378 }
379 if (program.unitTestCoverage) {
380 this.configuration.mainData.unitTestCoverage = program.unitTestCoverage;
381 }
382
383 if (configFile.disableSourceCode) {
384 this.configuration.mainData.disableSourceCode = configFile.disableSourceCode;
385 }
386 if (program.disableSourceCode) {
387 this.configuration.mainData.disableSourceCode = program.disableSourceCode;
388 }
389
390 if (configFile.disableDomTree) {
391 this.configuration.mainData.disableDomTree = configFile.disableDomTree;
392 }
393 if (program.disableDomTree) {
394 this.configuration.mainData.disableDomTree = program.disableDomTree;
395 }
396
397 if (configFile.disableTemplateTab) {
398 this.configuration.mainData.disableTemplateTab = configFile.disableTemplateTab;
399 }
400 if (program.disableTemplateTab) {
401 this.configuration.mainData.disableTemplateTab = program.disableTemplateTab;
402 }
403
404 if (configFile.disableGraph) {
405 this.configuration.mainData.disableGraph = configFile.disableGraph;
406 }
407 if (program.disableGraph) {
408 this.configuration.mainData.disableGraph = program.disableGraph;
409 }
410
411 if (configFile.disableCoverage) {
412 this.configuration.mainData.disableCoverage = configFile.disableCoverage;
413 }
414 if (program.disableCoverage) {
415 this.configuration.mainData.disableCoverage = program.disableCoverage;
416 }
417
418 if (configFile.disablePrivate) {
419 this.configuration.mainData.disablePrivate = configFile.disablePrivate;
420 }
421 if (program.disablePrivate) {
422 this.configuration.mainData.disablePrivate = program.disablePrivate;
423 }
424
425 if (configFile.disableProtected) {
426 this.configuration.mainData.disableProtected = configFile.disableProtected;
427 }
428 if (program.disableProtected) {
429 this.configuration.mainData.disableProtected = program.disableProtected;
430 }
431
432 if (configFile.disableInternal) {
433 this.configuration.mainData.disableInternal = configFile.disableInternal;
434 }
435 if (program.disableInternal) {
436 this.configuration.mainData.disableInternal = program.disableInternal;
437 }
438
439 if (configFile.disableLifeCycleHooks) {
440 this.configuration.mainData.disableLifeCycleHooks = configFile.disableLifeCycleHooks;
441 }
442 if (program.disableLifeCycleHooks) {
443 this.configuration.mainData.disableLifeCycleHooks = program.disableLifeCycleHooks;
444 }
445
446 if (configFile.disableRoutesGraph) {
447 this.configuration.mainData.disableRoutesGraph = configFile.disableRoutesGraph;
448 }
449 if (program.disableRoutesGraph) {
450 this.configuration.mainData.disableRoutesGraph = program.disableRoutesGraph;
451 }
452
453 if (configFile.disableSearch) {
454 this.configuration.mainData.disableSearch = configFile.disableSearch;
455 }
456 if (program.disableSearch) {
457 this.configuration.mainData.disableSearch = program.disableSearch;
458 }
459
460 if (configFile.minimal) {
461 this.configuration.mainData.disableSearch = true;
462 this.configuration.mainData.disableRoutesGraph = true;
463 this.configuration.mainData.disableGraph = true;
464 this.configuration.mainData.disableCoverage = true;
465 }
466 if (program.minimal) {
467 this.configuration.mainData.disableSearch = true;
468 this.configuration.mainData.disableRoutesGraph = true;
469 this.configuration.mainData.disableGraph = true;
470 this.configuration.mainData.disableCoverage = true;
471 }
472
473 if (configFile.customFavicon) {
474 this.configuration.mainData.customFavicon = configFile.customFavicon;
475 }
476 if (program.customFavicon) {
477 this.configuration.mainData.customFavicon = program.customFavicon;
478 }
479
480 if (configFile.gaID) {
481 this.configuration.mainData.gaID = configFile.gaID;
482 }
483 if (program.gaID) {
484 this.configuration.mainData.gaID = program.gaID;
485 }
486
487 if (configFile.gaSite) {
488 this.configuration.mainData.gaSite = configFile.gaSite;
489 }
490 if (program.gaSite && program.gaSite !== COMPODOC_DEFAULTS.gaSite) {
491 this.configuration.mainData.gaSite = program.gaSite;
492 }
493
494 if (!this.isWatching) {
495 console.log(fs.readFileSync(path.join(__dirname, '../src/banner')).toString());
496 console.log(pkg.version);
497 console.log('');
498 console.log(`Typescript version : ${ts.version}`);
499 console.log('');
500 console.log(`Node.js version : ${process.version}`);
501 console.log('');
502 console.log(`Operating system : ${osName(os.platform(), os.release())}`);
503 console.log('');
504 }
505
506 if (configExplorerResult) {
507 if (typeof configExplorerResult.config !== 'undefined') {
508 logger.info(`Using configuration file : ${configExplorerResult.filepath}`);
509 }
510 }
511
512 if (!configExplorerResult) {
513 logger.warn(`No configuration file found, switching to CLI flags.`);
514 }
515
516 if (program.language && !I18nEngineInstance.supportLanguage(program.language)) {
517 logger.warn(`The language ${program.language} is not available, falling back to ${I18nEngineInstance.fallbackLanguage}`);
518 }
519
520 if (program.tsconfig && typeof program.tsconfig === 'boolean') {
521 logger.error(`Please provide a tsconfig file.`);
522 process.exit(1);
523 }
524
525 if (configFile.tsconfig) {
526 this.configuration.mainData.tsconfig = configFile.tsconfig;
527 }
528 if (program.tsconfig) {
529 this.configuration.mainData.tsconfig = program.tsconfig;
530 }
531
532 if (configFile.files) {
533 scannedFiles = configFile.files;
534 }
535 if (configFile.exclude) {
536 excludeFiles = configFile.exclude;
537 }
538 if (configFile.include) {
539 includeFiles = configFile.include;
540 }
541
542 if (program.serve && !this.configuration.mainData.tsconfig && program.output) {
543 // if -s & -d, serve it
544 if (!this.fileEngine.existsSync(program.output)) {
545 logger.error(`${program.output} folder doesn't exist`);
546 process.exit(1);
547 } else {
548 logger.info(
549 `Serving documentation from ${program.output} at http://127.0.0.1:${
550 program.port
551 }`
552 );
553 super.runWebServer(program.output);
554 }
555 } else if (program.serve && !this.configuration.mainData.tsconfig && !program.output) {
556 // if only -s find ./documentation, if ok serve, else error provide -d
557 if (!this.fileEngine.existsSync(program.output)) {
558 logger.error('Provide output generated folder with -d flag');
559 process.exit(1);
560 } else {
561 logger.info(
562 `Serving documentation from ${program.output} at http://127.0.0.1:${
563 program.port
564 }`
565 );
566 super.runWebServer(program.output);
567 }
568 } else {
569 if (program.hideGenerator) {
570 this.configuration.mainData.hideGenerator = true;
571 }
572
573 if (this.configuration.mainData.tsconfig && program.args.length === 0) {
574 /**
575 * tsconfig file provided only
576 */
577 let testTsConfigPath = this.configuration.mainData.tsconfig.indexOf(process.cwd());
578 if (testTsConfigPath !== -1) {
579 this.configuration.mainData.tsconfig = this.configuration.mainData.tsconfig.replace(
580 process.cwd() + path.sep,
581 ''
582 );
583 }
584
585 if (!this.fileEngine.existsSync(this.configuration.mainData.tsconfig)) {
586 logger.error(
587 `"${
588 this.configuration.mainData.tsconfig
589 }" file was not found in the current directory`
590 );
591 process.exit(1);
592 } else {
593 let _file = path.join(
594 path.join(
595 process.cwd(),
596 path.dirname(this.configuration.mainData.tsconfig)
597 ),
598 path.basename(this.configuration.mainData.tsconfig)
599 );
600 // use the current directory of tsconfig.json as a working directory
601 cwd = _file
602 .split(path.sep)
603 .slice(0, -1)
604 .join(path.sep);
605 logger.info('Using tsconfig file ', _file);
606
607 let tsConfigFile = readConfig(_file);
608 scannedFiles = tsConfigFile.files;
609 if (scannedFiles) {
610 scannedFiles = handlePath(scannedFiles, cwd);
611 }
612
613 if (typeof scannedFiles === 'undefined') {
614 excludeFiles = tsConfigFile.exclude || [];
615 includeFiles = tsConfigFile.include || [];
616 scannedFiles = [];
617
618 let excludeParser = new ParserUtil(),
619 includeParser = new ParserUtil();
620
621 excludeParser.init(excludeFiles, cwd);
622 includeParser.init(includeFiles, cwd);
623
624 let startCwd = cwd;
625
626 let excludeParserTestFilesWithCwdDepth = excludeParser.testFilesWithCwdDepth();
627 if (!excludeParserTestFilesWithCwdDepth.status) {
628 startCwd = excludeParser.updateCwd(
629 cwd,
630 excludeParserTestFilesWithCwdDepth.level
631 );
632 }
633 let includeParserTestFilesWithCwdDepth = includeParser.testFilesWithCwdDepth();
634 if (!includeParser.testFilesWithCwdDepth().status) {
635 startCwd = includeParser.updateCwd(
636 cwd,
637 includeParserTestFilesWithCwdDepth.level
638 );
639 }
640
641 let finder = require('findit2')(startCwd || '.');
642
643 finder.on('directory', function(dir, stat, stop) {
644 let base = path.basename(dir);
645 if (base === '.git' || base === 'node_modules') {
646 stop();
647 }
648 });
649
650 finder.on('file', (file, stat) => {
651 if (/(spec|\.d)\.ts/.test(file)) {
652 logger.warn('Ignoring', file);
653 } else if (
654 excludeParser.testFile(file) &&
655 path.extname(file) === '.ts'
656 ) {
657 logger.warn('Excluding', file);
658 } else if (includeFiles.length > 0) {
659 /**
660 * If include provided in tsconfig, use only this source,
661 * and not files found with global findit scan in working directory
662 */
663 if (path.extname(file) === '.ts' && includeParser.testFile(file)) {
664 logger.debug('Including', file);
665 scannedFiles.push(file);
666 } else {
667 if (path.extname(file) === '.ts') {
668 logger.warn('Excluding', file);
669 }
670 }
671 } else {
672 logger.debug('Including', file);
673 scannedFiles.push(file);
674 }
675 });
676
677 finder.on('end', () => {
678 super.setFiles(scannedFiles);
679 if (program.coverageTest || program.coverageTestPerFile) {
680 logger.info('Run documentation coverage test');
681 super.testCoverage();
682 } else {
683 super.generate();
684 }
685 });
686 } else {
687 super.setFiles(scannedFiles);
688 if (program.coverageTest || program.coverageTestPerFile) {
689 logger.info('Run documentation coverage test');
690 super.testCoverage();
691 } else {
692 super.generate();
693 }
694 }
695 }
696 } else if (this.configuration.mainData.tsconfig && program.args.length > 0) {
697 /**
698 * tsconfig file provided with source folder in arg
699 */
700 let testTsConfigPath = this.configuration.mainData.tsconfig.indexOf(process.cwd());
701 if (testTsConfigPath !== -1) {
702 this.configuration.mainData.tsconfig = this.configuration.mainData.tsconfig.replace(
703 process.cwd() + path.sep,
704 ''
705 );
706 }
707
708 let sourceFolder = program.args[0];
709 if (!this.fileEngine.existsSync(sourceFolder)) {
710 logger.error(
711 `Provided source folder ${sourceFolder} was not found in the current directory`
712 );
713 process.exit(1);
714 } else {
715 logger.info('Using provided source folder');
716
717 if (!this.fileEngine.existsSync(this.configuration.mainData.tsconfig)) {
718 logger.error(
719 `"${
720 this.configuration.mainData.tsconfig
721 }" file was not found in the current directory`
722 );
723 process.exit(1);
724 } else {
725 let _file = path.join(
726 path.join(
727 process.cwd(),
728 path.dirname(this.configuration.mainData.tsconfig)
729 ),
730 path.basename(this.configuration.mainData.tsconfig)
731 );
732 // use the current directory of tsconfig.json as a working directory
733 cwd = _file
734 .split(path.sep)
735 .slice(0, -1)
736 .join(path.sep);
737 logger.info('Using tsconfig file ', _file);
738
739 let tsConfigFile = readConfig(_file);
740 scannedFiles = tsConfigFile.files;
741 if (scannedFiles) {
742 scannedFiles = handlePath(scannedFiles, cwd);
743 }
744
745 if (typeof scannedFiles === 'undefined') {
746 excludeFiles = tsConfigFile.exclude || [];
747 includeFiles = tsConfigFile.include || [];
748 scannedFiles = [];
749
750 let excludeParser = new ParserUtil(),
751 includeParser = new ParserUtil();
752
753 excludeParser.init(excludeFiles, cwd);
754 includeParser.init(includeFiles, cwd);
755
756 let startCwd = sourceFolder;
757
758 let excludeParserTestFilesWithCwdDepth = excludeParser.testFilesWithCwdDepth();
759 if (!excludeParserTestFilesWithCwdDepth.status) {
760 startCwd = excludeParser.updateCwd(
761 cwd,
762 excludeParserTestFilesWithCwdDepth.level
763 );
764 }
765 let includeParserTestFilesWithCwdDepth = includeParser.testFilesWithCwdDepth();
766 if (!includeParser.testFilesWithCwdDepth().status) {
767 startCwd = includeParser.updateCwd(
768 cwd,
769 includeParserTestFilesWithCwdDepth.level
770 );
771 }
772
773 let finder = require('findit2')(path.resolve(startCwd));
774
775 finder.on('directory', function(dir, stat, stop) {
776 let base = path.basename(dir);
777 if (base === '.git' || base === 'node_modules') {
778 stop();
779 }
780 });
781
782 finder.on('file', (file, stat) => {
783 if (/(spec|\.d)\.ts/.test(file)) {
784 logger.warn('Ignoring', file);
785 } else if (excludeParser.testFile(file)) {
786 logger.warn('Excluding', file);
787 } else if (includeFiles.length > 0) {
788 /**
789 * If include provided in tsconfig, use only this source,
790 * and not files found with global findit scan in working directory
791 */
792 if (
793 path.extname(file) === '.ts' &&
794 includeParser.testFile(file)
795 ) {
796 logger.debug('Including', file);
797 scannedFiles.push(file);
798 } else {
799 if (path.extname(file) === '.ts') {
800 logger.warn('Excluding', file);
801 }
802 }
803 } else {
804 logger.debug('Including', file);
805 scannedFiles.push(file);
806 }
807 });
808
809 finder.on('end', () => {
810 super.setFiles(scannedFiles);
811 if (program.coverageTest || program.coverageTestPerFile) {
812 logger.info('Run documentation coverage test');
813 super.testCoverage();
814 } else {
815 super.generate();
816 }
817 });
818 } else {
819 super.setFiles(scannedFiles);
820 if (program.coverageTest || program.coverageTestPerFile) {
821 logger.info('Run documentation coverage test');
822 super.testCoverage();
823 } else {
824 super.generate();
825 }
826 }
827 }
828 }
829 } else {
830 logger.error('tsconfig.json file was not found, please use -p flag');
831 outputHelp();
832 }
833 }
834 }
835}