diff --git a/CI/generate-docs.sh b/CI/generate-docs.sh index 54b07dd9..2afdaacb 100755 --- a/CI/generate-docs.sh +++ b/CI/generate-docs.sh @@ -1,4 +1,5 @@ #!/bin/bash +set -e echo "-- Generating documentation." echo "-- Node version: $(node -v)" echo "-- NPM version: $(npm -v)" diff --git a/docs/comments.js b/docs/comments.js index 5536a427..46a00fc2 100644 --- a/docs/comments.js +++ b/docs/comments.js @@ -1,6 +1,8 @@ const fs = require('fs'); +const path = require('path'); const glob = require('glob'); const parseComments = require('parse-comments'); +const config = require('./config.json'); /** * Read each file and call `parse-comments` on it. @@ -25,9 +27,15 @@ const parseFiles = files => { */ const processComments = comments => { let sorted = {}; + let errors = []; comments.forEach(comment => { if (typeof comment.api === 'undefined') return; + let validationFailures = validateComment(comment); + + if (validationFailures) { + errors.push(validationFailures); + } // Store the object based on its api (ie. requests, events) and category (ie. general, scenes, etc). comment.category = comment.category || 'miscellaneous'; @@ -44,9 +52,47 @@ const processComments = comments => { sorted[comment.api][comment.category].push(comment); }); + if (errors.length) { + throw JSON.stringify(errors, null, 2); + } + return sorted; }; -const files = glob.sync("./../src/*.@(cpp|h)"); +// Rudimentary validation of documentation content, returns an error object or undefined. +const validateComment = comment => { + let errors = []; + [].concat(comment.params).concat(comment.returns).filter(Boolean).forEach(param => { + if (typeof param.name !== 'string' || param.name === '') { + errors.push({ + description: `Invalid param or return value name`, + param: param + }); + } + + if (typeof param.type !== 'string' || param.type === '') { + errors.push({ + description: `Invalid param or return value type`, + param: param + }); + } + }); + + if (errors.length) { + return { + errors: errors, + fullContext: Object.assign({}, comment) + }; + } + + return; +} + +const files = glob.sync(config.srcGlob); const comments = processComments(parseFiles(files)); -fs.writeFileSync('./generated/comments.json', JSON.stringify(comments, null, 2)); + +if (!fs.existsSync(config.outDirectory)){ + fs.mkdirSync(config.outDirectory); +} + +fs.writeFileSync(path.join(config.outDirectory, 'comments.json'), JSON.stringify(comments, null, 2)); diff --git a/docs/config.json b/docs/config.json new file mode 100644 index 00000000..ab2a2391 --- /dev/null +++ b/docs/config.json @@ -0,0 +1,5 @@ +{ + "srcGlob": "./../src/**/*.@(cpp|h)", + "srcTemplate": "./protocol.hbs", + "outDirectory": "./generated" +} diff --git a/docs/docs.js b/docs/docs.js index f0353091..b66cb0f3 100644 --- a/docs/docs.js +++ b/docs/docs.js @@ -1,6 +1,8 @@ const fs = require('fs'); +const path = require('path'); const toc = require('markdown-toc'); const handlebars = require('handlebars'); +const config = require('./config.json'); const helpers = require('handlebars-helpers')({ handlebars: handlebars @@ -8,10 +10,7 @@ const helpers = require('handlebars-helpers')({ // Allows pipe characters to be used within markdown tables. handlebars.registerHelper('depipe', (text) => { - if (!text) { - return text; - } - return text.replace('|', `\\|`); + return typeof text === 'string' ? text.replace('|', '\\|') : text; }); const insertHeader = (text) => { @@ -29,6 +28,10 @@ const generateProtocol = (templatePath, data) => { return insertHeader(toc.insert(generated)); }; -const comments = fs.readFileSync('./generated/comments.json', 'utf8'); -const markdown = generateProtocol('./protocol.hbs', JSON.parse(comments)); -fs.writeFileSync('./generated/protocol.md', markdown); +if (!fs.existsSync(config.outDirectory)){ + fs.mkdirSync(config.outDirectory); +} + +const comments = fs.readFileSync(path.join(config.outDirectory, 'comments.json'), 'utf8'); +const markdown = generateProtocol(config.srcTemplate, JSON.parse(comments)); +fs.writeFileSync(path.join(config.outDirectory, 'protocol.md'), markdown); diff --git a/docs/protocol.hbs b/docs/protocol.hbs index 592d03b7..313a5442 100644 --- a/docs/protocol.hbs +++ b/docs/protocol.hbs @@ -33,7 +33,7 @@ | Name | Type | Description | | ---- | :---: | ------------| {{#each returns}} -| `{{name}}` | _{{depipe type}}_ | {{{description}}} | +| `{{name}}` | _{{depipe type}}_ | {{{depipe description}}} | {{/each}} {{else}} @@ -73,7 +73,7 @@ _No additional response items._ | Name | Type | Description | | ---- | :---: | ------------| {{#each params}} -| `{{name}}` | _{{depipe type}}_ | {{{description}}} | +| `{{name}}` | _{{depipe type}}_ | {{{depipe description}}} | {{/each}} {{else}} @@ -86,7 +86,7 @@ _No specified parameters._ | Name | Type | Description | | ---- | :---: | ------------| {{#each returns}} -| `{{name}}` | _{{depipe type}}_ | {{{description}}} | +| `{{name}}` | _{{depipe type}}_ | {{{depipe description}}} | {{/each}} {{else}}