mirror of
https://github.com/Palakis/obs-websocket.git
synced 2024-08-30 18:12:16 +00:00
Merge pull request #159 from haganbmj/docs-safety
docs: fail CI build if documentation is invalid
This commit is contained in:
commit
6d47bd6477
@ -1,4 +1,5 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
echo "-- Generating documentation."
|
echo "-- Generating documentation."
|
||||||
echo "-- Node version: $(node -v)"
|
echo "-- Node version: $(node -v)"
|
||||||
echo "-- NPM version: $(npm -v)"
|
echo "-- NPM version: $(npm -v)"
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
|
const path = require('path');
|
||||||
const glob = require('glob');
|
const glob = require('glob');
|
||||||
const parseComments = require('parse-comments');
|
const parseComments = require('parse-comments');
|
||||||
|
const config = require('./config.json');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read each file and call `parse-comments` on it.
|
* Read each file and call `parse-comments` on it.
|
||||||
@ -25,9 +27,15 @@ const parseFiles = files => {
|
|||||||
*/
|
*/
|
||||||
const processComments = comments => {
|
const processComments = comments => {
|
||||||
let sorted = {};
|
let sorted = {};
|
||||||
|
let errors = [];
|
||||||
|
|
||||||
comments.forEach(comment => {
|
comments.forEach(comment => {
|
||||||
if (typeof comment.api === 'undefined') return;
|
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).
|
// Store the object based on its api (ie. requests, events) and category (ie. general, scenes, etc).
|
||||||
comment.category = comment.category || 'miscellaneous';
|
comment.category = comment.category || 'miscellaneous';
|
||||||
@ -44,9 +52,47 @@ const processComments = comments => {
|
|||||||
sorted[comment.api][comment.category].push(comment);
|
sorted[comment.api][comment.category].push(comment);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (errors.length) {
|
||||||
|
throw JSON.stringify(errors, null, 2);
|
||||||
|
}
|
||||||
|
|
||||||
return sorted;
|
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));
|
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));
|
||||||
|
5
docs/config.json
Normal file
5
docs/config.json
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"srcGlob": "./../src/**/*.@(cpp|h)",
|
||||||
|
"srcTemplate": "./protocol.hbs",
|
||||||
|
"outDirectory": "./generated"
|
||||||
|
}
|
17
docs/docs.js
17
docs/docs.js
@ -1,6 +1,8 @@
|
|||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
|
const path = require('path');
|
||||||
const toc = require('markdown-toc');
|
const toc = require('markdown-toc');
|
||||||
const handlebars = require('handlebars');
|
const handlebars = require('handlebars');
|
||||||
|
const config = require('./config.json');
|
||||||
|
|
||||||
const helpers = require('handlebars-helpers')({
|
const helpers = require('handlebars-helpers')({
|
||||||
handlebars: handlebars
|
handlebars: handlebars
|
||||||
@ -8,10 +10,7 @@ const helpers = require('handlebars-helpers')({
|
|||||||
|
|
||||||
// Allows pipe characters to be used within markdown tables.
|
// Allows pipe characters to be used within markdown tables.
|
||||||
handlebars.registerHelper('depipe', (text) => {
|
handlebars.registerHelper('depipe', (text) => {
|
||||||
if (!text) {
|
return typeof text === 'string' ? text.replace('|', '\\|') : text;
|
||||||
return text;
|
|
||||||
}
|
|
||||||
return text.replace('|', `\\|`);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const insertHeader = (text) => {
|
const insertHeader = (text) => {
|
||||||
@ -29,6 +28,10 @@ const generateProtocol = (templatePath, data) => {
|
|||||||
return insertHeader(toc.insert(generated));
|
return insertHeader(toc.insert(generated));
|
||||||
};
|
};
|
||||||
|
|
||||||
const comments = fs.readFileSync('./generated/comments.json', 'utf8');
|
if (!fs.existsSync(config.outDirectory)){
|
||||||
const markdown = generateProtocol('./protocol.hbs', JSON.parse(comments));
|
fs.mkdirSync(config.outDirectory);
|
||||||
fs.writeFileSync('./generated/protocol.md', markdown);
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
@ -33,7 +33,7 @@
|
|||||||
| Name | Type | Description |
|
| Name | Type | Description |
|
||||||
| ---- | :---: | ------------|
|
| ---- | :---: | ------------|
|
||||||
{{#each returns}}
|
{{#each returns}}
|
||||||
| `{{name}}` | _{{depipe type}}_ | {{{description}}} |
|
| `{{name}}` | _{{depipe type}}_ | {{{depipe description}}} |
|
||||||
{{/each}}
|
{{/each}}
|
||||||
|
|
||||||
{{else}}
|
{{else}}
|
||||||
@ -73,7 +73,7 @@ _No additional response items._
|
|||||||
| Name | Type | Description |
|
| Name | Type | Description |
|
||||||
| ---- | :---: | ------------|
|
| ---- | :---: | ------------|
|
||||||
{{#each params}}
|
{{#each params}}
|
||||||
| `{{name}}` | _{{depipe type}}_ | {{{description}}} |
|
| `{{name}}` | _{{depipe type}}_ | {{{depipe description}}} |
|
||||||
{{/each}}
|
{{/each}}
|
||||||
|
|
||||||
{{else}}
|
{{else}}
|
||||||
@ -86,7 +86,7 @@ _No specified parameters._
|
|||||||
| Name | Type | Description |
|
| Name | Type | Description |
|
||||||
| ---- | :---: | ------------|
|
| ---- | :---: | ------------|
|
||||||
{{#each returns}}
|
{{#each returns}}
|
||||||
| `{{name}}` | _{{depipe type}}_ | {{{description}}} |
|
| `{{name}}` | _{{depipe type}}_ | {{{depipe description}}} |
|
||||||
{{/each}}
|
{{/each}}
|
||||||
|
|
||||||
{{else}}
|
{{else}}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user