mirror of
https://github.com/balena-io/balena-cli.git
synced 2024-12-29 18:18:50 +00:00
12cdb14638
Change-type: patch
138 lines
3.8 KiB
TypeScript
138 lines
3.8 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 { Parser } from '@oclif/core';
|
|
import * as ent from 'ent';
|
|
import * as _ from 'lodash';
|
|
|
|
import { getManualSortCompareFunction } from '../../src/utils/helpers';
|
|
import { capitanoizeOclifUsage } from '../../src/utils/oclif-utils';
|
|
import type { Category, Document, OclifCommand } from './doc-types';
|
|
|
|
function renderOclifCommand(command: Category['commands'][0]): string[] {
|
|
const result = [`## ${ent.encode(command.name || '')}`];
|
|
if (command.aliases?.length) {
|
|
result.push('### Aliases');
|
|
result.push(command.aliases.map((alias) => `- \`${alias}\``).join('\n'));
|
|
result.push(
|
|
`\nTo use one of the aliases, replace \`${command.name}\` with the alias.`,
|
|
);
|
|
}
|
|
|
|
result.push('### Description');
|
|
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 [name, arg] of Object.entries(command.args!)) {
|
|
result.push(`#### ${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 = Parser.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(...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 = capitanoizeOclifUsage(command.name);
|
|
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<OclifCommand, string>(
|
|
manualCategorySorting[category.title],
|
|
(cmd: OclifCommand, x: string) =>
|
|
(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');
|
|
}
|