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: [{ 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 | */
|
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 |