1 | ;
|
2 | var command_run_1 = require("./command.run");
|
3 | var task_resolve_1 = require("./task.resolve");
|
4 | var Rx = require("rx");
|
5 | var reporter_resolve_1 = require("./reporter.resolve");
|
6 | var task_utils_1 = require("./task.utils");
|
7 | var fs_1 = require("fs");
|
8 | var file = require("./file.utils");
|
9 | var defaultReporter_1 = require("./reporters/defaultReporter");
|
10 | var logger_1 = require("./logger");
|
11 | var debug = require("debug")("cb:command:docs");
|
12 | (function (DocsErrorTypes) {
|
13 | DocsErrorTypes[DocsErrorTypes["DocsInputFileNotFound"] = "DocsInputFileNotFound"] = "DocsInputFileNotFound";
|
14 | DocsErrorTypes[DocsErrorTypes["DocsOutputFileExists"] = "DocsOutputFileExists"] = "DocsOutputFileExists";
|
15 | })(exports.DocsErrorTypes || (exports.DocsErrorTypes = {}));
|
16 | var DocsErrorTypes = exports.DocsErrorTypes;
|
17 | exports.docStartComment = "<!--crossbow-docs-start-->";
|
18 | exports.docEndComment = "<!--crossbow-docs-end-->";
|
19 | exports.hasRegExp = /<!--crossbow-docs-start-->([\s\S]+?)?<!--crossbow-docs-end-->/g;
|
20 | exports.hasExistingComments = function (inputString) { return exports.hasRegExp.test(inputString); };
|
21 | exports.readmeRegExp = /readme\.(md|markdown)$/i;
|
22 | function execute(trigger) {
|
23 | var input = trigger.input, config = trigger.config, reporter = trigger.reporter;
|
24 | /**
|
25 | * Resolve all top-level tasks as these are the ones
|
26 | * that will used in the docs
|
27 | * @type {Tasks}
|
28 | */
|
29 | var toResolve = task_utils_1.getPossibleTaskNames(input);
|
30 | var tasks = task_resolve_1.resolveTasks(toResolve
|
31 | .filter(task_utils_1.isPublicTask)
|
32 | .filter(function (x) { return !task_utils_1.isInternal(x); }), trigger);
|
33 | /**
|
34 | * If there were 0 tasks, exit with error
|
35 | */
|
36 | if (tasks.all.length === 0) {
|
37 | reporter({ type: reporter_resolve_1.ReportTypes.NoTasksAvailable });
|
38 | return Rx.Observable.just({
|
39 | setup: {
|
40 | tasks: tasks,
|
41 | errors: []
|
42 | }
|
43 | });
|
44 | }
|
45 | debug("Amount of tasks to consider " + tasks.all.length);
|
46 | /**
|
47 | * If any tasks were invalid, refuse to generate docs
|
48 | * and prompt to run tasks command (for the full error output)
|
49 | */
|
50 | if (tasks.invalid.length) {
|
51 | debug("Tasks were invalid, so skipping doc generation completely");
|
52 | reporter({ type: reporter_resolve_1.ReportTypes.DocsInvalidTasksSimple });
|
53 | return Rx.Observable.just({
|
54 | setup: {
|
55 | tasks: tasks,
|
56 | errors: []
|
57 | }
|
58 | });
|
59 | }
|
60 | var markdown = getMarkdown(tasks.valid);
|
61 | /**
|
62 | * If the user provided the --file flag,
|
63 | * try to load that file & either wedge in the new docs or
|
64 | * append them
|
65 | */
|
66 | if (config.file) {
|
67 | return Rx.Observable.just({ setup: handleFileFlag(tasks, markdown, trigger) });
|
68 | }
|
69 | /**
|
70 | * If a user provides the 'output' flag, it means they want a new file creating
|
71 | */
|
72 | if (config.output) {
|
73 | return Rx.Observable.just({ setup: handleOutputFlag(tasks, markdown, trigger) });
|
74 | }
|
75 | /**
|
76 | * If both --flag and --output were NOT given, look for a readme in this current
|
77 | * directory
|
78 | * @type {Array}
|
79 | */
|
80 | var existingReadmeFiles = fs_1.readdirSync(process.cwd())
|
81 | .filter(function (x) { return exports.readmeRegExp.test(x); })
|
82 | .reduce(function (acc, item) { return acc.concat(file.readFilesFromDiskWithContent([item], config.cwd)); }, []);
|
83 | if (existingReadmeFiles.length) {
|
84 | var output_1 = existingReadmeFiles.map(function (x) { return getFileOutput(x, markdown); });
|
85 | reportAddToDocs(output_1, trigger);
|
86 | return Rx.Observable.just({
|
87 | setup: {
|
88 | errors: [],
|
89 | tasks: tasks,
|
90 | markdown: markdown,
|
91 | output: output_1
|
92 | }
|
93 | });
|
94 | }
|
95 | /**
|
96 | * At this point:
|
97 | * 1. NO --file flag given
|
98 | * 2. NO --output flag given
|
99 | * 3. NO existing readme files in cwd
|
100 | *
|
101 | * so, create a new one :)
|
102 | */
|
103 | var output = [{
|
104 | file: file.getStubFile("readme.md", config.cwd),
|
105 | content: markdown
|
106 | }];
|
107 | reportAddToDocs(output, trigger);
|
108 | return Rx.Observable.just({
|
109 | setup: {
|
110 | errors: [],
|
111 | tasks: tasks,
|
112 | markdown: markdown,
|
113 | output: output
|
114 | }
|
115 | });
|
116 | }
|
117 | /**
|
118 | * When adding docs to a file
|
119 | * 1. if file content does not exist, use raw markdown
|
120 | * 2. if docs exist, replace them
|
121 | * 3. if 1 & 2 fail, append
|
122 | */
|
123 | function getFileOutput(file, markdown) {
|
124 | /**
|
125 | * If there's no exisitng file content, just use the markdown
|
126 | */
|
127 | if (!file.content) {
|
128 | debug(file.relative + " DOES NOT have any content");
|
129 | return { file: file, content: markdown };
|
130 | }
|
131 | /**
|
132 | * If there's existing docs, wedge.
|
133 | */
|
134 | if (exports.hasExistingComments(file.content)) {
|
135 | debug(file.relative + " has the comments already in the file, so will replace");
|
136 | var replaced = file.content.replace(exports.hasRegExp, markdown);
|
137 | return {
|
138 | file: file,
|
139 | content: replaced
|
140 | };
|
141 | }
|
142 | debug(file.relative + " DOES NOT have the comments, so will append to the end of the file");
|
143 | return {
|
144 | file: file,
|
145 | content: file.content + "\n" + markdown
|
146 | };
|
147 | }
|
148 | /**
|
149 | * When the --output flag was given
|
150 | *
|
151 | * eg:
|
152 | *
|
153 | * $ crossbow docs --output newfile.md
|
154 | */
|
155 | function handleOutputFlag(tasks, markdown, trigger) {
|
156 | var config = trigger.config, reporter = trigger.reporter;
|
157 | var maybe = file.readFilesFromDiskWithContent([config.output], config.cwd);
|
158 | var available = maybe
|
159 | .filter(function (x) { return x.errors.length > 0; })
|
160 | .filter(function (x) { return x.errors[0].type === task_utils_1.InputErrorTypes.FileNotFound; });
|
161 | if (!available.length) {
|
162 | var error = { type: DocsErrorTypes.DocsOutputFileExists, file: maybe[0] };
|
163 | if (!config.handoff) {
|
164 | reporter({ type: reporter_resolve_1.ReportTypes.DocsOutputFileExists, data: { error: error } });
|
165 | }
|
166 | return {
|
167 | errors: [error],
|
168 | tasks: tasks,
|
169 | markdown: markdown,
|
170 | output: []
|
171 | };
|
172 | }
|
173 | var output = [{
|
174 | file: maybe[0],
|
175 | content: markdown
|
176 | }];
|
177 | // Now we can report about writing to disk
|
178 | reportAddToDocs(output, trigger);
|
179 | return {
|
180 | errors: [],
|
181 | tasks: tasks,
|
182 | markdown: markdown,
|
183 | output: output
|
184 | };
|
185 | }
|
186 | /**
|
187 | * When the --file flag was given.
|
188 | *
|
189 | * eg:
|
190 | *
|
191 | * $ crossbow docs --file readme.md
|
192 | */
|
193 | function handleFileFlag(tasks, markdown, trigger) {
|
194 | var config = trigger.config, reporter = trigger.reporter;
|
195 | /**
|
196 | * Try to read the file from disk with content appended
|
197 | * @type {file.ExternalFileContent[]}
|
198 | */
|
199 | var maybes = file.readFilesFromDiskWithContent([config.file], config.cwd);
|
200 | var withErrors = maybes
|
201 | .filter(function (x) { return x.errors.length > 0; })
|
202 | .map(function (x) {
|
203 | return {
|
204 | type: DocsErrorTypes.DocsInputFileNotFound,
|
205 | file: x
|
206 | };
|
207 | });
|
208 | /**
|
209 | * If the --file flag produced an error,
|
210 | * eg: --file shane.md -> but shane.md did not exist
|
211 | */
|
212 | if (withErrors.length) {
|
213 | /**
|
214 | * If we're not handing off, report the error
|
215 | */
|
216 | if (!config.handoff) {
|
217 | reporter({ type: reporter_resolve_1.ReportTypes.DocsInputFileNotFound, data: { error: withErrors[0] } });
|
218 | }
|
219 | return {
|
220 | errors: withErrors,
|
221 | tasks: tasks,
|
222 | markdown: markdown,
|
223 | output: []
|
224 | };
|
225 | }
|
226 | /**
|
227 | * At this point we have files to work with so we
|
228 | * either append the docs or insert them between existing
|
229 | * comments
|
230 | * @type {{content: string, file: file.ExternalFileContent}[]}
|
231 | */
|
232 | var output = maybes.map(function (x) { return getFileOutput(x, markdown); });
|
233 | /**
|
234 | * Now write to file
|
235 | */
|
236 | reportAddToDocs(output, trigger);
|
237 | /**
|
238 | * Always return everything gathered
|
239 | */
|
240 | return {
|
241 | errors: [],
|
242 | tasks: tasks,
|
243 | markdown: markdown,
|
244 | output: output
|
245 | };
|
246 | }
|
247 | function getMarkdown(tasks) {
|
248 | /**
|
249 | * Create the header for the markdown table
|
250 | * @type {string|string[]}
|
251 | */
|
252 | var tasksHeader = ["## Crossbow tasks\n\nThe following tasks have been defined by this project's Crossbow configuration.\nRun any of them in the following way\n \n```shell\n$ crossbow run <taskname>\n```"];
|
253 | var tableHeader = "|Task name|Description|\n|---|---|";
|
254 | /**
|
255 | * Create the body for the table with taskname + description
|
256 | * @type {string[]}
|
257 | */
|
258 | var body = tasks.map(function (task) {
|
259 | var isParent = task.type === task_resolve_1.TaskTypes.ParentGroup;
|
260 | var name = (function () {
|
261 | if (isParent) {
|
262 | return "|<pre>`" + task.baseTaskName + ":" + task.subTasks[0] + "`</pre>";
|
263 | }
|
264 | return "|<pre>`" + task.baseTaskName + "`</pre>";
|
265 | })();
|
266 | var desc = (function () {
|
267 | if (task.description)
|
268 | return task_utils_1.removeNewlines(task.description);
|
269 | if (isParent) {
|
270 | if (task.tasks[0].description) {
|
271 | return task_utils_1.removeNewlines(task.tasks[0].description);
|
272 | }
|
273 | }
|
274 | if (task.tasks.length) {
|
275 | var subject = task.tasks;
|
276 | return ["**Alias for:**"]
|
277 | .concat(subject
|
278 | .map(function (x) { return ("- `" + defaultReporter_1.getLabel(x) + "`"); })
|
279 | .map(function (x) { return logger_1.clean(x); }))
|
280 | .join("<br>");
|
281 | }
|
282 | })() + "|";
|
283 | return [name, desc].join("|");
|
284 | }).join("\n");
|
285 | /**
|
286 | * Join the lines with a \n for correct formatting in markdown
|
287 | * @type {string}
|
288 | */
|
289 | return [exports.docStartComment, tasksHeader, tableHeader, body, exports.docEndComment].join("\n");
|
290 | }
|
291 | function reportAddToDocs(output, trigger) {
|
292 | var config = trigger.config;
|
293 | if (!config.handoff) {
|
294 | output.forEach(function (x) {
|
295 | trigger.reporter({
|
296 | type: reporter_resolve_1.ReportTypes.DocsAddedToFile,
|
297 | data: {
|
298 | file: x.file
|
299 | }
|
300 | });
|
301 | });
|
302 | }
|
303 | }
|
304 | function handleIncomingDocsCommand(cli, input, config, reporter) {
|
305 | return execute({
|
306 | cli: cli,
|
307 | input: input,
|
308 | config: config,
|
309 | reporter: reporter,
|
310 | type: command_run_1.TriggerTypes.command
|
311 | });
|
312 | }
|
313 | Object.defineProperty(exports, "__esModule", { value: true });
|
314 | exports.default = handleIncomingDocsCommand;
|
315 | //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tbWFuZC5kb2NzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2NvbW1hbmQuZG9jcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsNEJBQTJDLGVBQWUsQ0FBQyxDQUFBO0FBRzNELDZCQUE2QyxnQkFBZ0IsQ0FBQyxDQUFBO0FBRTlELElBQU8sRUFBRSxXQUFXLElBQUksQ0FBQyxDQUFDO0FBQzFCLGlDQUEwQixvQkFBb0IsQ0FBQyxDQUFBO0FBRS9DLDJCQUE4RixjQUFjLENBQUMsQ0FBQTtBQUM3RyxtQkFBMEIsSUFBSSxDQUFDLENBQUE7QUFDL0IsSUFBWSxJQUFJLFdBQU0sY0FBYyxDQUFDLENBQUE7QUFFckMsZ0NBQXVCLDZCQUE2QixDQUFDLENBQUE7QUFDckQsdUJBQW9CLFVBQVUsQ0FBQyxDQUFBO0FBRS9CLElBQU0sS0FBSyxHQUFHLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO0FBU2xELFdBQVksY0FBYztJQUN0Qix5REFBNkIsdUJBQXVCLDJCQUFBLENBQUE7SUFDcEQsd0RBQTRCLHNCQUFzQiwwQkFBQSxDQUFBO0FBQ3RELENBQUMsRUFIVyxzQkFBYyxLQUFkLHNCQUFjLFFBR3pCO0FBSEQsSUFBWSxjQUFjLEdBQWQsc0JBR1gsQ0FBQTtBQUNZLHVCQUFlLEdBQUcsNEJBQTRCLENBQUM7QUFDL0MscUJBQWEsR0FBRywwQkFBMEIsQ0FBQztBQUMzQyxpQkFBUyxHQUFHLGdFQUFnRSxDQUFDO0FBQzdFLDJCQUFtQixHQUFHLFVBQUMsV0FBVyxJQUFLLE9BQUEsaUJBQVMsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLEVBQTNCLENBQTJCLENBQUM7QUFDbkUsb0JBQVksR0FBRyx5QkFBeUIsQ0FBQztBQWV0RCxpQkFBaUIsT0FBdUI7SUFFN0IseUJBQUssRUFBRSx1QkFBTSxFQUFFLDJCQUFRLENBQVk7SUFFMUM7Ozs7T0FJRztJQUNILElBQU0sU0FBUyxHQUFHLGlDQUFvQixD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 |
\ | No newline at end of file |