Skip to content

Commit 50aaf9d

Browse files
committed
--watch and --serve flags
These new flags replace the functionality of dev-documentation
1 parent 4416acb commit 50aaf9d

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+2070
-1397
lines changed

Diff for: CHANGELOG.md

+13
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,16 @@
1+
## 4.0.0
2+
3+
**Revitalized documentation.js command line interface!**
4+
5+
The `documentation` utility now takes commands:
6+
7+
* `documentation build` extracts and formats documentation
8+
* `documentation serve` provides an auto-reloading server
9+
* `documentation lint` reviews files for inconsistencies
10+
11+
This functionality was previously included in `dev-documentation` and has
12+
been folded into `documentation` proper.
13+
114
## 3.0.4
215

316
* Allow parameter types to be mixed into explicit parameter documentation. (#239 and #232)

Diff for: bin/documentation.js

+60-21
Original file line numberDiff line numberDiff line change
@@ -5,41 +5,80 @@
55
'use strict';
66

77
var documentation = require('../'),
8+
chokidar = require('chokidar'),
9+
debounce = require('debounce'),
810
streamArray = require('stream-array'),
911
fs = require('fs'),
1012
vfs = require('vinyl-fs'),
11-
lint = require('../lib/lint'),
12-
args = require('../lib/args.js');
13+
errorPage = require('../lib/error_page'),
14+
Server = require('../lib/server'),
15+
args = require('../lib/args');
1316

14-
var parsedArgs = args(process.argv.slice(2)),
15-
formatterOptions = parsedArgs.formatterOptions,
16-
outputLocation = parsedArgs.output,
17-
formatter = documentation.formats[parsedArgs.formatter];
17+
var parsedArgs = args(process.argv.slice(2));
1818

19-
documentation(parsedArgs.inputs, parsedArgs.options, function (err, comments) {
19+
var generator = documentation.bind(null,
20+
parsedArgs.inputs, parsedArgs.options, onDocumented.bind(null, parsedArgs));
21+
22+
var server = new Server();
23+
server.on('listening', function () {
24+
process.stdout.write('documentation.js serving on port 4001\n');
25+
});
26+
27+
function onDocumented(parsedArgs, err, comments) {
2028
if (err) {
29+
if (parsedArgs.command === 'serve') {
30+
return server.setFiles([errorPage(err)]).start();
31+
}
2132
throw err;
2233
}
2334

24-
if (parsedArgs.options.lint) {
25-
var lintOutput = lint.format(comments);
35+
documentation.formats[parsedArgs.formatter](
36+
comments, parsedArgs.formatterOptions,
37+
onFormatted.bind(null, parsedArgs));
38+
}
39+
40+
function onFormatted(parsedArgs, err, output) {
41+
if (parsedArgs.watch) {
42+
updateWatcher();
43+
}
44+
45+
if (parsedArgs.command === 'serve') {
46+
server.setFiles(output).start();
47+
} else if (parsedArgs.output === 'stdout') {
48+
process.stdout.write(output);
49+
} else if (Array.isArray(output)) {
50+
streamArray(output).pipe(vfs.dest(parsedArgs.output));
51+
} else {
52+
fs.writeFileSync(parsedArgs.output, output);
53+
}
54+
}
55+
56+
if (parsedArgs.command === 'lint') {
57+
documentation.lint(parsedArgs.inputs, parsedArgs.options, function (err, lintOutput) {
58+
if (err) {
59+
throw err;
60+
}
2661
if (lintOutput) {
2762
console.log(lintOutput);
2863
process.exit(1);
2964
} else {
3065
process.exit(0);
3166
}
67+
});
68+
} else {
69+
generator();
70+
if (parsedArgs.watch) {
71+
var watcher = chokidar.watch(parsedArgs.inputs);
72+
watcher.on('all', debounce(generator, 300));
3273
}
74+
}
3375

34-
formatter(comments, formatterOptions, function (err, output) {
35-
if (outputLocation !== 'stdout') {
36-
if (parsedArgs.formatter === 'html') {
37-
streamArray(output).pipe(vfs.dest(outputLocation));
38-
} else {
39-
fs.writeFileSync(outputLocation, output);
40-
}
41-
} else {
42-
process.stdout.write(output);
43-
}
44-
});
45-
});
76+
function updateWatcher() {
77+
documentation.expandInputs(parsedArgs.inputs, parsedArgs.options, addNewFiles);
78+
}
79+
80+
function addNewFiles(err, files) {
81+
watcher.add(files.map(function (data) {
82+
return data.file;
83+
}));
84+
}

Diff for: index.js

+74-5
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ var sort = require('./lib/sort'),
1616
inferProperties = require('./lib/infer/properties'),
1717
inferMembership = require('./lib/infer/membership'),
1818
inferReturn = require('./lib/infer/return'),
19-
lint = require('./lib/lint');
19+
formatLint = require('./lib/lint').formatLint,
20+
lintComments = require('./lib/lint').lintComments;
2021

2122
/**
2223
* Build a pipeline of comment handlers.
@@ -45,6 +46,20 @@ function noop(comment) {
4546
return comment;
4647
}
4748

49+
/**
50+
* Given an array of indexes and options for whether to resolve shallow
51+
* or deep dependencies, resolve dependencies.
52+
*
53+
* @param {Array<string>|string} indexes files to process
54+
* @param {Object} options options
55+
* @param {Function} callback called with results
56+
* @returns {undefined}
57+
*/
58+
function expandInputs(indexes, options, callback) {
59+
var inputFn = (options.polyglot || options.shallow) ? shallow : dependency;
60+
inputFn(indexes, options, callback);
61+
}
62+
4863
/**
4964
* Generate JavaScript documentation as a list of parsed JSDoc
5065
* comments, given a root file as a path.
@@ -75,25 +90,23 @@ module.exports = function (indexes, options, callback) {
7590
indexes = [indexes];
7691
}
7792

78-
var inputFn = (options.polyglot || options.shallow) ? shallow : dependency;
7993
var parseFn = (options.polyglot) ? polyglot : parseJavaScript;
8094

81-
return inputFn(indexes, options, function (error, inputs) {
95+
return expandInputs(indexes, options, function (error, inputs) {
8296
if (error) {
8397
return callback(error);
8498
}
8599
try {
86100
callback(null,
87101
filterAccess(
88-
(options.private || options.lint) ? [] : undefined,
102+
options.private ? [] : undefined,
89103
hierarchy(
90104
inputs
91105
.filter(filterJS)
92106
.reduce(function (memo, file) {
93107
return memo.concat(parseFn(file));
94108
}, [])
95109
.map(pipeline(
96-
lint.lint,
97110
inferName(),
98111
inferKind(),
99112
inferParams(),
@@ -111,6 +124,62 @@ module.exports = function (indexes, options, callback) {
111124
});
112125
};
113126

127+
/**
128+
* Lint files for non-standard or incorrect documentation
129+
* information, returning a potentially-empty string
130+
* of lint information intended for human-readable output.
131+
*
132+
* @param {Array<string>|string} indexes files to process
133+
* @param {Object} options options
134+
* @param {Array<string>} options.external a string regex / glob match pattern
135+
* that defines what external modules will be whitelisted and included in the
136+
* generated documentation.
137+
* @param {Array<string>} options.transform source transforms given as strings
138+
* passed to [the module-deps transform option](https://github.com/substack/module-deps)
139+
* @param {boolean} [options.polyglot=false] parse comments with a regex rather than
140+
* a proper parser. This enables support of non-JavaScript languages but
141+
* reduces documentation's ability to infer structure of code.
142+
* @param {boolean} [options.shallow=false] whether to avoid dependency parsing
143+
* even in JavaScript code. With the polyglot option set, this has no effect.
144+
* @param {Function} callback to be called when the documentation generation
145+
* is complete, with (err, result) argumentsj
146+
* @returns {undefined} calls callback
147+
*/
148+
module.exports.lint = function lint(indexes, options, callback) {
149+
options = options || {};
150+
151+
if (typeof indexes === 'string') {
152+
indexes = [indexes];
153+
}
154+
155+
var parseFn = (options.polyglot) ? polyglot : parseJavaScript;
156+
157+
return expandInputs(indexes, options, function (error, inputs) {
158+
if (error) {
159+
return callback(error);
160+
}
161+
callback(null,
162+
formatLint(hierarchy(
163+
inputs
164+
.filter(filterJS)
165+
.reduce(function (memo, file) {
166+
return memo.concat(parseFn(file));
167+
}, [])
168+
.map(pipeline(
169+
lintComments,
170+
inferName(),
171+
inferKind(),
172+
inferParams(),
173+
inferProperties(),
174+
inferReturn(),
175+
inferMembership(),
176+
nest))
177+
.filter(Boolean))));
178+
});
179+
};
180+
181+
module.exports.expandInputs = expandInputs;
182+
114183
module.exports.formats = {
115184
html: require('./lib/output/html'),
116185
md: require('./lib/output/markdown'),

0 commit comments

Comments
 (0)