UNPKG

9.22 kBPlain TextView Raw
1import * as fs from 'fs-extra';
2import * as path from 'path';
3import * as _ from 'lodash';
4
5import { Application } from './app/application';
6
7import { COMPODOC_DEFAULTS } from './utils/defaults';
8import { logger } from './logger';
9
10let pkg = require('../package.json'),
11 program = require('commander'),
12 files = [],
13 cwd = process.cwd();
14
15process.setMaxListeners(0);
16
17export class CliApplication extends Application
18{
19 /**
20 * Run compodoc from the command line.
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 //.option('-i, --includes [path]', 'Path of external markdown files to include')
34 //.option('-j, --includesName [name]', 'Name of item menu of externals markdown file')
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 // if -s & -d, serve it
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 // if only -s find ./documentation, if ok serve, else error provide -d
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 // use the current directory of tsconfig.json as a working directory
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}