UNPKG

21.5 kBJavaScriptView Raw
1"use strict";
2var command_run_1 = require("./command.run");
3var task_resolve_1 = require("./task.resolve");
4var Rx = require("rx");
5var reporter_resolve_1 = require("./reporter.resolve");
6var task_utils_1 = require("./task.utils");
7var fs_1 = require("fs");
8var file = require("./file.utils");
9var defaultReporter_1 = require("./reporters/defaultReporter");
10var logger_1 = require("./logger");
11var debug = require("debug")("cb:command:docs");
12var DocsErrorTypes;
13(function (DocsErrorTypes) {
14 DocsErrorTypes[DocsErrorTypes["DocsInputFileNotFound"] = "DocsInputFileNotFound"] = "DocsInputFileNotFound";
15 DocsErrorTypes[DocsErrorTypes["DocsOutputFileExists"] = "DocsOutputFileExists"] = "DocsOutputFileExists";
16})(DocsErrorTypes = exports.DocsErrorTypes || (exports.DocsErrorTypes = {}));
17exports.docStartComment = "<!--crossbow-docs-start-->";
18exports.docEndComment = "<!--crossbow-docs-end-->";
19exports.hasRegExp = /<!--crossbow-docs-start-->([\s\S]+?)?<!--crossbow-docs-end-->/g;
20exports.hasExistingComments = function (inputString) { return exports.hasRegExp.test(inputString); };
21exports.readmeRegExp = /readme\.(md|markdown)$/i;
22function 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: [{ type: reporter_resolve_1.ReportTypes.NoTasksAvailable }]
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: [{ type: reporter_resolve_1.ReportTypes.DocsInvalidTasksSimple }]
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 */
123function 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 */
155function 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 */
193function 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}
247function 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}
291function 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}
304function 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}
313Object.defineProperty(exports, "__esModule", { value: true });
314exports.default = handleIncomingDocsCommand;
315//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tbWFuZC5kb2NzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2NvbW1hbmQuZG9jcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsNkNBQTJEO0FBRzNELCtDQUE4RDtBQUU5RCx1QkFBMEI7QUFDMUIsdURBQStDO0FBRS9DLDJDQUE2RztBQUM3Ryx5QkFBK0I7QUFDL0IsbUNBQXFDO0FBRXJDLCtEQUFxRDtBQUNyRCxtQ0FBK0I7QUFFL0IsSUFBTSxLQUFLLEdBQUcsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDLGlCQUFpQixDQUFDLENBQUM7QUFTbEQsSUFBWSxjQUdYO0FBSEQsV0FBWSxjQUFjO0lBQ3RCLHlEQUE2Qix1QkFBdUIsMkJBQUEsQ0FBQTtJQUNwRCx3REFBNEIsc0JBQXNCLDBCQUFBLENBQUE7QUFDdEQsQ0FBQyxFQUhXLGNBQWMsR0FBZCxzQkFBYyxLQUFkLHNCQUFjLFFBR3pCO0FBQ1ksUUFBQSxlQUFlLEdBQUcsNEJBQTRCLENBQUM7QUFDL0MsUUFBQSxhQUFhLEdBQUcsMEJBQTBCLENBQUM7QUFDM0MsUUFBQSxTQUFTLEdBQUcsZ0VBQWdFLENBQUM7QUFDN0UsUUFBQSxtQkFBbUIsR0FBRyxVQUFDLFdBQVcsSUFBSyxPQUFBLGlCQUFTLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxFQUEzQixDQUEyQixDQUFDO0FBQ25FLFFBQUEsWUFBWSxHQUFHLHlCQUF5QixDQUFDO0FBZXRELGlCQUFpQixPQUF1QjtJQUU3QixJQUFBLHFCQUFLLEVBQUUsdUJBQU0sRUFBRSwyQkFBUSxDQUFZO0lBRTFDOzs7O09BSUc7SUFDSCxJQUFNLFNBQVMsR0FBRyxpQ0FBb0IsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUM5QyxJQUFNLEtBQUssR0FBRywyQkFBWSxDQUFDLFNBQVM7U0FDL0IsTUFBTSxDQUFDLHlCQUFZLENBQUM7U0FDcEIsTUFBTSxDQUFDLFVBQUEsQ0FBQyxJQUFJLE9BQUEsQ0FBQyx1QkFBVSxDQUFDLENB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
\No newline at end of file