1 | import * as fs from 'fs-extra';
|
2 | import * as path from 'path';
|
3 | import * as _ from 'lodash';
|
4 |
|
5 | import { Application } from './app/application';
|
6 |
|
7 | import { COMPODOC_DEFAULTS } from './utils/defaults';
|
8 | import { logger } from './logger';
|
9 |
|
10 | let pkg = require('../package.json'),
|
11 | program = require('commander'),
|
12 | files = [],
|
13 | cwd = process.cwd();
|
14 |
|
15 | process.setMaxListeners(0);
|
16 |
|
17 | export class CliApplication extends Application
|
18 | {
|
19 | |
20 |
|
21 |
|
22 | protected generate() {
|
23 |
|
24 | program
|
25 | .version(pkg.version)
|
26 | .usage('<src> [options]')
|
27 | .option('-p, --tsconfig [config]', 'A tsconfig.json file')
|
28 | .option('-d, --output [folder]', 'Where to store the generated documentation (default: ./documentation)', COMPODOC_DEFAULTS.folder)
|
29 | .option('-y, --extTheme [file]', 'External styling theme file')
|
30 | .option('-n, --name [name]', 'Title documentation', COMPODOC_DEFAULTS.title)
|
31 | .option('-a, --assetsFolder [folder]', 'External assets folder to copy in generated documentation folder')
|
32 | .option('-o, --open', 'Open the generated documentation', false)
|
33 |
|
34 |
|
35 | .option('-t, --silent', 'In silent mode, log messages aren\'t logged in the console', false)
|
36 | .option('-s, --serve', 'Serve generated documentation (default http://localhost:8080/)', false)
|
37 | .option('-r, --port [port]', 'Change default serving port', COMPODOC_DEFAULTS.port)
|
38 | .option('--theme [theme]', 'Choose one of available themes, default is \'gitbook\' (laravel, original, postmark, readthedocs, stripe, vagrant)')
|
39 | .option('--hideGenerator', 'Do not print the Compodoc link at the bottom of the page', false)
|
40 | .option('--disableSourceCode', 'Do not add source code tab', false)
|
41 | .option('--disableGraph', 'Do not add the dependency graph', false)
|
42 | .option('--disableCoverage', 'Do not add the documentation coverage report', false)
|
43 | .option('--disablePrivateOrInternalSupport', 'Do not show private or @internal in generated documentation', false)
|
44 | .parse(process.argv);
|
45 |
|
46 | let outputHelp = () => {
|
47 | program.outputHelp()
|
48 | process.exit(1);
|
49 | }
|
50 |
|
51 | if (program.output) {
|
52 | this.configuration.mainData.output = program.output;
|
53 | }
|
54 |
|
55 | if (program.extTheme) {
|
56 | this.configuration.mainData.extTheme = program.extTheme;
|
57 | }
|
58 |
|
59 | if (program.theme) {
|
60 | this.configuration.mainData.theme = program.theme;
|
61 | }
|
62 |
|
63 | if (program.name) {
|
64 | this.configuration.mainData.documentationMainName = program.name;
|
65 | }
|
66 |
|
67 | if (program.assetsFolder) {
|
68 | this.configuration.mainData.assetsFolder = program.assetsFolder;
|
69 | }
|
70 |
|
71 | if (program.open) {
|
72 | this.configuration.mainData.open = program.open;
|
73 | }
|
74 |
|
75 | if (program.includes) {
|
76 | this.configuration.mainData.includes = program.includes;
|
77 | }
|
78 |
|
79 | if (program.includesName) {
|
80 | this.configuration.mainData.includesName = program.includesName;
|
81 | }
|
82 |
|
83 | if (program.silent) {
|
84 | logger.silent = false;
|
85 | }
|
86 |
|
87 | if (program.serve) {
|
88 | this.configuration.mainData.serve = program.serve;
|
89 | }
|
90 |
|
91 | if (program.port) {
|
92 | this.configuration.mainData.port = program.port;
|
93 | }
|
94 |
|
95 | if (program.hideGenerator) {
|
96 | this.configuration.mainData.hideGenerator = program.hideGenerator;
|
97 | }
|
98 |
|
99 | if (program.disableSourceCode) {
|
100 | this.configuration.mainData.disableSourceCode = program.disableSourceCode;
|
101 | }
|
102 |
|
103 | if (program.disableGraph) {
|
104 | this.configuration.mainData.disableGraph = program.disableGraph;
|
105 | }
|
106 |
|
107 | if (program.disableCoverage) {
|
108 | this.configuration.mainData.disableCoverage = program.disableCoverage;
|
109 | }
|
110 |
|
111 | if (program.disablePrivateOrInternalSupport) {
|
112 | this.configuration.mainData.disablePrivateOrInternalSupport = program.disablePrivateOrInternalSupport;
|
113 | }
|
114 |
|
115 | console.log(`
|
116 | _
|
117 | | |
|
118 | ___ ___ _ __ ___ _ __ ___ __| | ___ ___
|
119 | / __| / _ \\ | '_ \` _ \\ | '_ \\ / _ \\ / _\` | / _ \\ / __|
|
120 | | (__ | (_) | | | | | | | | |_) | | (_) | | (_| | | (_) | | (__ ${pkg.version}
|
121 | \\___| \\___/ |_| |_| |_| | .__/ \\___/ \\__,_| \\___/ \\___|
|
122 | | |
|
123 | |_|
|
124 | `);
|
125 |
|
126 | if (program.serve && !program.tsconfig && program.output) {
|
127 |
|
128 | if (!fs.existsSync(program.output)) {
|
129 | logger.error(`${program.output} folder doesn't exist`);
|
130 | process.exit(1);
|
131 | } else {
|
132 | logger.info(`Serving documentation from ${program.output} at http://127.0.0.1:${program.port}`);
|
133 | super.runWebServer(program.output);
|
134 | }
|
135 | } else if (program.serve && !program.tsconfig && !program.output) {
|
136 |
|
137 | if (!fs.existsSync(program.output)) {
|
138 | logger.error('Provide output generated folder with -d flag');
|
139 | process.exit(1);
|
140 | } else {
|
141 | logger.info(`Serving documentation from ${program.output} at http://127.0.0.1:${program.port}`);
|
142 | super.runWebServer(program.output);
|
143 | }
|
144 | } else {
|
145 | if (program.hideGenerator) {
|
146 | this.configuration.mainData.hideGenerator = true;
|
147 | }
|
148 |
|
149 | let defaultWalkFOlder = cwd || '.',
|
150 | walk = (dir, exclude) => {
|
151 | let results = [];
|
152 | let list = fs.readdirSync(dir);
|
153 | list.forEach((file) => {
|
154 | var excludeTest = _.find(exclude, function(o) {
|
155 | return path.basename(o) === file;
|
156 | });
|
157 | if (typeof excludeTest === 'undefined' && dir.indexOf('node_modules') < 0) {
|
158 | file = path.join(dir, file);
|
159 | let stat = fs.statSync(file);
|
160 | if (stat && stat.isDirectory()) {
|
161 | results = results.concat(walk(file, exclude));
|
162 | }
|
163 | else if (/(spec|\.d)\.ts/.test(file)) {
|
164 | logger.debug('Ignoring', file);
|
165 | }
|
166 | else if (path.extname(file) === '.ts') {
|
167 | logger.debug('Including', file);
|
168 | results.push(file);
|
169 | }
|
170 | }
|
171 | });
|
172 | return results;
|
173 | };
|
174 |
|
175 | if (program.tsconfig && program.args.length === 0) {
|
176 | this.configuration.mainData.tsconfig = program.tsconfig;
|
177 | if (!fs.existsSync(program.tsconfig)) {
|
178 | logger.error('"tsconfig.json" file was not found in the current directory');
|
179 | process.exit(1);
|
180 | } else {
|
181 | let _file = path.join(
|
182 | path.join(process.cwd(), path.dirname(this.configuration.mainData.tsconfig)),
|
183 | path.basename(this.configuration.mainData.tsconfig)
|
184 | );
|
185 | logger.info('Using tsconfig', _file);
|
186 |
|
187 | files = require(_file).files;
|
188 |
|
189 |
|
190 | cwd = _file.split(path.sep).slice(0, -1).join(path.sep);
|
191 |
|
192 | if (!files) {
|
193 | let exclude = require(_file).exclude || [];
|
194 |
|
195 | files = walk(cwd || '.', exclude);
|
196 | }
|
197 |
|
198 | super.setFiles(files);
|
199 | super.generate();
|
200 | }
|
201 | } else if (program.tsconfig && program.args.length > 0) {
|
202 | this.configuration.mainData.tsconfig = program.tsconfig;
|
203 | let sourceFolder = program.args[0];
|
204 | if (!fs.existsSync(sourceFolder)) {
|
205 | logger.error(`Provided source folder ${sourceFolder} was not found in the current directory`);
|
206 | process.exit(1);
|
207 | } else {
|
208 | logger.info('Using provided source folder');
|
209 |
|
210 | files = walk(path.resolve(sourceFolder), []);
|
211 |
|
212 | super.setFiles(files);
|
213 | super.generate();
|
214 | }
|
215 | } else {
|
216 | logger.error('tsconfig.json file was not found, please use -p flag');
|
217 | outputHelp();
|
218 | }
|
219 | }
|
220 | }
|
221 | }
|