mirror of
https://github.com/balena-io/balena-cli.git
synced 2024-12-19 05:37:51 +00:00
d94a74dfee
Also add more non-interactive configuration options: --config-network, --config-wifi-*, --config-app-update-poll-interval Change-type: minor Signed-off-by: Paulo Castro <paulo@balena.io>
161 lines
4.4 KiB
TypeScript
161 lines
4.4 KiB
TypeScript
/**
|
|
* @license
|
|
* Copyright 2019 Balena Ltd.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
import { flagUsages } from '@oclif/parser';
|
|
import * as ent from 'ent';
|
|
import * as _ from 'lodash';
|
|
|
|
import { getManualSortCompareFunction } from '../../lib/utils/helpers';
|
|
import { capitanoizeOclifUsage } from '../../lib/utils/oclif-utils';
|
|
import { CapitanoCommand, Category, Document, OclifCommand } from './doc-types';
|
|
import * as utils from './utils';
|
|
|
|
function renderCapitanoCommand(command: CapitanoCommand): string[] {
|
|
const result = [`## ${ent.encode(command.signature)}`, command.help];
|
|
|
|
if (!_.isEmpty(command.options)) {
|
|
result.push('### Options');
|
|
|
|
for (const option of command.options!) {
|
|
if (option == null) {
|
|
throw new Error(`Undefined option in markdown generation!`);
|
|
}
|
|
result.push(
|
|
`#### ${utils.parseCapitanoOption(option)}`,
|
|
option.description,
|
|
);
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
function renderOclifCommand(command: OclifCommand): string[] {
|
|
const result = [`## ${ent.encode(command.usage)}`];
|
|
const description = (command.description || '')
|
|
.split('\n')
|
|
.slice(1) // remove the first line, which oclif uses as help header
|
|
.join('\n')
|
|
.trim();
|
|
result.push(description);
|
|
|
|
if (!_.isEmpty(command.examples)) {
|
|
result.push('Examples:', command.examples!.map(v => `\t${v}`).join('\n'));
|
|
}
|
|
|
|
if (!_.isEmpty(command.args)) {
|
|
result.push('### Arguments');
|
|
for (const arg of command.args!) {
|
|
result.push(`#### ${arg.name.toUpperCase()}`, arg.description || '');
|
|
}
|
|
}
|
|
|
|
if (!_.isEmpty(command.flags)) {
|
|
result.push('### Options');
|
|
for (const [name, flag] of Object.entries(command.flags!)) {
|
|
if (name === 'help') {
|
|
continue;
|
|
}
|
|
flag.name = name;
|
|
const flagUsage = flagUsages([flag])
|
|
.map(([usage, _description]) => usage)
|
|
.join()
|
|
.trim();
|
|
result.push(`#### ${flagUsage}`);
|
|
result.push(flag.description || '');
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
function renderCategory(category: Category): string[] {
|
|
const result = [`# ${category.title}`];
|
|
for (const command of category.commands) {
|
|
result.push(
|
|
...(typeof command === 'object'
|
|
? renderCapitanoCommand(command)
|
|
: renderOclifCommand(command)),
|
|
);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
function getAnchor(cmdSignature: string): string {
|
|
return `#${_.trim(cmdSignature.replace(/\W+/g, '-'), '-').toLowerCase()}`;
|
|
}
|
|
|
|
function renderToc(categories: Category[]): string[] {
|
|
const result = [`# CLI Command Reference`];
|
|
|
|
for (const category of categories) {
|
|
result.push(`- ${category.title}`);
|
|
result.push(
|
|
category.commands
|
|
.map(command => {
|
|
const signature =
|
|
typeof command === 'object'
|
|
? command.signature // Capitano
|
|
: capitanoizeOclifUsage(command.usage); // oclif
|
|
return `\t- [${ent.encode(signature)}](${getAnchor(signature)})`;
|
|
})
|
|
.join('\n'),
|
|
);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
const manualCategorySorting: { [category: string]: string[] } = {
|
|
'Environment Variables': ['envs', 'env rm', 'env add', 'env rename'],
|
|
OS: [
|
|
'os versions',
|
|
'os download',
|
|
'os build config',
|
|
'os configure',
|
|
'os initialize',
|
|
],
|
|
};
|
|
|
|
function sortCommands(doc: Document): void {
|
|
for (const category of doc.categories) {
|
|
if (category.title in manualCategorySorting) {
|
|
category.commands = category.commands.sort(
|
|
getManualSortCompareFunction<CapitanoCommand | OclifCommand, string>(
|
|
manualCategorySorting[category.title],
|
|
(cmd: CapitanoCommand | OclifCommand, x: string) =>
|
|
typeof cmd === 'object' // Capitano vs oclif command
|
|
? cmd.signature.replace(/\W+/g, ' ').includes(x)
|
|
: (cmd.usage || '')
|
|
.toString()
|
|
.replace(/\W+/g, ' ')
|
|
.includes(x),
|
|
),
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
export function render(doc: Document) {
|
|
sortCommands(doc);
|
|
const result = [
|
|
`# ${doc.title}`,
|
|
doc.introduction,
|
|
...renderToc(doc.categories),
|
|
];
|
|
for (const category of doc.categories) {
|
|
result.push(...renderCategory(category));
|
|
}
|
|
return result.join('\n\n');
|
|
}
|