Auto-generate configuration documentation in README (#26)
Auto-generate the documentation of the configuration options in `README.md` from `config.schema.json`.
This commit is contained in:
parent
261fa74ac9
commit
6f7686ba34
2 changed files with 130 additions and 30 deletions
88
README.md
88
README.md
|
@ -116,51 +116,81 @@ Once *Prometheus* is restarted, metrics with the `homebridge_` prefix should sta
|
||||||
|
|
||||||
*homebridge-prometheus-exporter* offers a few advanced settings to customize its behavior.
|
*homebridge-prometheus-exporter* offers a few advanced settings to customize its behavior.
|
||||||
|
|
||||||
```json lines
|
<!-- AUTOGENERATED CONFIG DOCS BEGIN -->
|
||||||
|
```json5
|
||||||
{
|
{
|
||||||
// …
|
// ...
|
||||||
"platforms": [
|
"platforms": [
|
||||||
{
|
{
|
||||||
"platform": "PrometheusExporter",
|
"platform": "PrometheusExporter",
|
||||||
// Homebridge PIN for service authentication. String of digits, format XXX-XX-XXX. Required
|
|
||||||
"pin": string,
|
|
||||||
|
|
||||||
// Toggle debug mode. Run homebridge with -D if you want to see the debug output. Default: false
|
|
||||||
"debug": boolean,
|
|
||||||
|
|
||||||
// Prefix for all metrics. Default: "homebridge"
|
// Pin
|
||||||
"prefix": string,
|
//
|
||||||
|
// Homebridge PIN for service authentication
|
||||||
|
"pin": "<string>",
|
||||||
|
|
||||||
// TCP port where the Prometheus metrics server listens. Default: 36123
|
|
||||||
"port": number,
|
|
||||||
|
|
||||||
// Interface where the Prometheus metrics server listens. Default: "::" which means "any interface".
|
// Debug
|
||||||
// Can be an IP, a hostname, "0.0.0.0" for all IPv4 interfaces, "::1" for all IPv6 interfaces.
|
"debug": "<boolean>",
|
||||||
// Default is "::" which means any interface
|
|
||||||
"interface": string,
|
|
||||||
|
|
||||||
// How frequently the services should be rediscovered (in seconds). Default: 60
|
|
||||||
"refresh_interval": number,
|
|
||||||
|
|
||||||
// Timeout for the HTTP request that retrieves the homekit devices (in seconds). Default: 10
|
// Metrics prefix
|
||||||
"request_timeout": number,
|
"prefix": "<string>",
|
||||||
|
|
||||||
// Timeout for the service discovery (in seconds). Default: 20
|
|
||||||
"discovery_timeout": number,
|
|
||||||
|
|
||||||
|
// Metrics server port
|
||||||
|
//
|
||||||
|
// TCP port where the Prometheus metrics server listens
|
||||||
|
"port": "<integer>",
|
||||||
|
|
||||||
|
|
||||||
|
// Metrics server interface
|
||||||
|
//
|
||||||
|
// Interface where the Prometheus metrics server listens. Can be an IP, a
|
||||||
|
// hostname, "0.0.0.0" for all IPv4 interfaces, "::1" for all IPv6 interfaces.
|
||||||
|
// Default is "::" which means "any interface"
|
||||||
|
"interface": "<string>",
|
||||||
|
|
||||||
|
|
||||||
|
// Service refresh interval
|
||||||
|
//
|
||||||
|
// Discover new services every <interval> seconds
|
||||||
|
"refresh_interval": "<integer>",
|
||||||
|
|
||||||
|
|
||||||
|
// Request timeout
|
||||||
|
//
|
||||||
|
// Request timeout when interacting with homebridge instances
|
||||||
|
"request_timeout": "<integer>",
|
||||||
|
|
||||||
|
|
||||||
|
// Service discovery timeout
|
||||||
|
//
|
||||||
|
// Discovery timeout after which the current discovery is considered failed
|
||||||
|
"discovery_timeout": "<integer>",
|
||||||
|
|
||||||
|
|
||||||
|
// TLS cert file
|
||||||
|
//
|
||||||
// Path to TLS certificate file (in PEM format)
|
// Path to TLS certificate file (in PEM format)
|
||||||
"tls_cert_file": string,
|
"tls_cert_file": "<string>",
|
||||||
|
|
||||||
|
|
||||||
|
// TLS key file
|
||||||
|
//
|
||||||
// Path to TLS key file
|
// Path to TLS key file
|
||||||
"tls_key_file": string,
|
"tls_key_file": "<string>",
|
||||||
|
|
||||||
// Usernames and passwords for basic auth. Key is the username, value is the password.
|
|
||||||
// Password must be encoded with bcrypt
|
// Basic auth username/password pairs
|
||||||
"basic_auth": {
|
//
|
||||||
"username": "<password encoded with bcrypt>"
|
// Usernames and passwords for basic auth. Object key is the username, object
|
||||||
}
|
// value is the password. Password must be encoded with bcrypt. Example:
|
||||||
},
|
// {"joanna": "$2a$12$5/mmmRB28wg9yzaXhee5Iupq3UrFr/qMgAe9LvAxGoY5jLcfVGTUq"}
|
||||||
// …
|
"basic_auth": "<object>"
|
||||||
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
<!-- AUTOGENERATED CONFIG DOCS END -->
|
|
@ -5,7 +5,7 @@ const { schema } = require('../config.schema.json')
|
||||||
const { format } = require('prettier')
|
const { format } = require('prettier')
|
||||||
const { join, basename } = require('path')
|
const { join, basename } = require('path')
|
||||||
const prettierConfig = require('../prettier.config')
|
const prettierConfig = require('../prettier.config')
|
||||||
const { writeFileSync } = require('fs')
|
const { writeFileSync, readFileSync } = require('fs')
|
||||||
|
|
||||||
const file = join(__dirname, '../src/generated/config_boundary.ts')
|
const file = join(__dirname, '../src/generated/config_boundary.ts')
|
||||||
|
|
||||||
|
@ -26,4 +26,74 @@ export const ConfigBoundary = ${zodSchema}
|
||||||
|
|
||||||
writeFileSync(file, code)
|
writeFileSync(file, code)
|
||||||
|
|
||||||
|
const note = 'AUTOGENERATED CONFIG DOCS'
|
||||||
|
const comment = (...strings) => `<!-- ${strings.join(' ')} -->`
|
||||||
|
const readmePath = join(__dirname, '../README.md')
|
||||||
|
const readme = readFileSync(readmePath).toString()
|
||||||
|
const regex = new RegExp(`${comment(note, 'BEGIN')}.*${comment(note, 'END')}`, 'mgs')
|
||||||
|
if (!readme.match(regex)) {
|
||||||
|
console.log('Could not update README.md')
|
||||||
|
process.exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
writeFileSync(
|
||||||
|
readmePath,
|
||||||
|
readme.replace(
|
||||||
|
regex,
|
||||||
|
`${comment(note, 'BEGIN')}\n\`\`\`json5\n${generateDocs(schema)}\n\`\`\`\n${comment(note, 'END')}`,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
function generateDocs(schema) {
|
||||||
|
const doc = indent(
|
||||||
|
Object.entries(schema.properties)
|
||||||
|
.map(([property, definition]) => {
|
||||||
|
const lines = []
|
||||||
|
|
||||||
|
if (definition.title) {
|
||||||
|
lines.push(`// ${definition.title}`)
|
||||||
|
}
|
||||||
|
if (definition.description) {
|
||||||
|
lines.push(`//\n// ${wordwrap(definition.description, 80, '\n// ')}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
lines.push(`${JSON.stringify(property)}: ${JSON.stringify('<' + definition.type + '>')}`)
|
||||||
|
|
||||||
|
return lines.join('\n')
|
||||||
|
})
|
||||||
|
.join(',\n\n\n'),
|
||||||
|
6,
|
||||||
|
)
|
||||||
|
|
||||||
|
return `{
|
||||||
|
// ...
|
||||||
|
"platforms": [
|
||||||
|
{
|
||||||
|
"platform": "PrometheusExporter",
|
||||||
|
|
||||||
|
|
||||||
|
${doc}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}`
|
||||||
|
}
|
||||||
|
|
||||||
|
function wordwrap(word, length, wrap = '\n') {
|
||||||
|
const wrapped = []
|
||||||
|
while (word.length > length) {
|
||||||
|
const cut = word.substring(0, length)
|
||||||
|
const pos = cut.lastIndexOf(' ')
|
||||||
|
wrapped.push(cut.substring(0, pos))
|
||||||
|
word = word.substring(pos + 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
wrapped.push(word)
|
||||||
|
|
||||||
|
return wrapped.join(wrap)
|
||||||
|
}
|
||||||
|
|
||||||
|
function indent(string, indent) {
|
||||||
|
return string.replace(/^(.+)$/gm, `${' '.repeat(indent)}$1`)
|
||||||
|
}
|
||||||
|
|
||||||
console.log(`Finished code generation for ${file}`)
|
console.log(`Finished code generation for ${file}`)
|
||||||
|
|
Loading…
Reference in a new issue