Skip to content

Commit

Permalink
minor: Automatically generate Capitano Configuration
Browse files Browse the repository at this point in the history
Signed-off-by: Vipul Gupta (@vipulgupta2048) <[email protected]>
  • Loading branch information
vipulgupta2048 committed Nov 6, 2023
1 parent 47a1a9c commit 4919d1b
Showing 1 changed file with 128 additions and 233 deletions.
361 changes: 128 additions & 233 deletions automation/capitanodoc/capitanodoc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

import * as path from 'path';
import { MarkdownFileParser } from './utils';
import { globSync } from 'glob';

Check failure on line 20 in automation/capitanodoc/capitanodoc.ts

View workflow job for this annotation

GitHub Actions / Flowzone / Test custom (self-hosted, Linux, distro:focal, X64)

'"glob"' has no exported member named 'globSync'. Did you mean 'GlobSync'?

Check failure on line 20 in automation/capitanodoc/capitanodoc.ts

View workflow job for this annotation

GitHub Actions / Flowzone / Test custom (self-hosted, Linux, distro:focal, ARM64)

'"glob"' has no exported member named 'globSync'. Did you mean 'GlobSync'?

Check failure on line 20 in automation/capitanodoc/capitanodoc.ts

View workflow job for this annotation

GitHub Actions / Flowzone / Test custom (macos-12)

'"glob"' has no exported member named 'globSync'. Did you mean 'GlobSync'?

Check failure on line 20 in automation/capitanodoc/capitanodoc.ts

View workflow job for this annotation

GitHub Actions / Flowzone / Test custom (windows-2019)

'"glob"' has no exported member named 'globSync'. Did you mean 'GlobSync'?

Check failure on line 20 in automation/capitanodoc/capitanodoc.ts

View workflow job for this annotation

GitHub Actions / Flowzone / Test npm (18.x)

'"glob"' has no exported member named 'globSync'. Did you mean 'GlobSync'?

/**
* This is the skeleton of CLI documentation/reference web page at:
Expand All @@ -26,249 +27,143 @@ import { MarkdownFileParser } from './utils';
* some content to this object.
*
* IMPORTANT
*
* Only build files listed here will be documented by Capitano
* Make sure to add your files in alphabetical order
*
*
* All commands need to be stored under a folder in lib/commands to maintain uniformity
* Generating docs will error out if directive not followed
* To add a custom heading for command docs, add the heading next to the folder name
* in the `commandHeadings` dictionary.
*
* This dictionary is the source of truth that creates the docs config which is used
* to generate the CLI documentation. By default, the folder name will be used.
*
* Resources with plural names needs to have 2 sections if they have commands like:
* "fleet, fleets" or "device, devices" or "tag, tags"
*
*/
const capitanoDoc = {
title: 'balena CLI Documentation',
introduction: '',
categories: [
{
title: 'API Key',
files: ['build/commands/api-keys/index.js'],
},
{
title: 'API Keys',
files: [
'build/commands/api-key/generate.js',
'build/commands/api-key/revoke.js',
],
},
{
title: 'App',
files: ['build/commands/app/create.js'],
},
{
title: 'Authentication',
files: [
'build/commands/login.js',
'build/commands/logout.js',
'build/commands/whoami.js',
],
},
{
title: 'Block',
files: ['build/commands/app/create.js'],
},
{
title: 'Config',
files: [
'build/commands/config/generate.js',
'build/commands/config/inject.js',
'build/commands/config/read.js',
'build/commands/config/reconfigure.js',
'build/commands/config/write.js',
],
},
{
title: 'Deploy',
files: ['build/commands/build.js', 'build/commands/deploy.js'],
},
{
title: 'Device',
files: [
'build/commands/device/deactivate.js',
'build/commands/device/identify.js',
'build/commands/device/index.js',
'build/commands/device/init.js',
'build/commands/device/local-mode.js',
'build/commands/device/move.js',
'build/commands/device/os-update.js',
'build/commands/device/pin.js',
'build/commands/device/public-url.js',
'build/commands/device/purge.js',
'build/commands/device/reboot.js',
'build/commands/device/register.js',
'build/commands/device/rename.js',
'build/commands/device/restart.js',
'build/commands/device/rm.js',
'build/commands/device/shutdown.js',
'build/commands/device/track-fleet.js',
'build/commands/device/start-service.js',
'build/commands/device/stop-service.js',
],
},
{
title: 'Devices',
files: [
'build/commands/devices/index.js',
'build/commands/devices/supported.js',
],
},
{
title: 'Environment Variable',
files: [
'build/commands/env/add.js',
'build/commands/env/rename.js',
'build/commands/env/rm.js',
],
},
{
title: 'Environment Variables',
files: ['build/commands/envs.js'],
},
{
title: 'Fleet',
files: [
'build/commands/fleet/create.js',
'build/commands/fleet/index.js',
'build/commands/fleet/pin.js',
'build/commands/fleet/purge.js',
'build/commands/fleet/rename.js',
'build/commands/fleet/restart.js',
'build/commands/fleet/rm.js',
'build/commands/fleet/track-latest.js',
],
},
{
title: 'Fleets',
files: ['build/commands/fleets.js'],
},
{
title: 'Help and Version',
files: ['help', 'build/commands/version.js'],
},
{
title: 'Local',
files: [
'build/commands/local/configure.js',
'build/commands/local/flash.js',
],
},
{
title: 'Logs',
files: ['build/commands/logs.js'],
},
{
title: 'Network',
files: [
'build/commands/scan.js',
'build/commands/ssh.js',
'build/commands/tunnel.js',
],
},
{
title: 'Notes',
files: ['build/commands/note.js'],
},
{
title: 'Organizations',
files: ['build/commands/orgs.js'],
},
{
title: 'OS',
files: [
'build/commands/os/build-config.js',
'build/commands/os/configure.js',
'build/commands/os/download.js',
'build/commands/os/initialize.js',
'build/commands/os/versions.js',
],
},
{
title: 'Preload',
files: ['build/commands/preload.js'],
},
{
title: 'Push',
files: ['build/commands/push.js'],
},
{
title: 'Platform',
files: ['build/commands/join.js', 'build/commands/leave.js'],
},
{
title: 'Release',
files: [
'build/commands/release/finalize.js',
'build/commands/release/index.js',
'build/commands/release/invalidate.js',
'build/commands/release/validate.js',
],
},
{
title: 'Releases',
files: ['build/commands/releases.js'],
},
{
title: 'Settings',
files: ['build/commands/settings.js'],
},
{
title: 'Support',
files: ['build/commands/support.js'],
},

{
title: 'SSH Key',
files: [
'build/commands/key/add.js',
'build/commands/key/index.js',
'build/commands/key/rm.js',
],
},
{
title: 'SSH Keys',
files: ['build/commands/keys.js'],
},
{
title: 'Tags',
files: ['build/commands/tag/rm.js', 'build/commands/tag/set.js'],
},
{
title: 'Tags',
files: ['build/commands/tags.js'],
},
{
title: 'Utilities',
files: ['build/commands/util/available-drives.js'],
},
],
};
// TODO: Generate an error if commands are not in their folder

interface Category {
title: string;
files: string[];
}

interface Documentation {
title: string;
introduction: string;
categories: Category[];
}

// Mapping folders names to custom headings in the docs
let commandHeadings: { [key: string]: string } = {
'api-key': "API Key",
'api-keys': "API Keys",
'app': "App",
"auth": "Authentication",
'block': 'Block',
'config': 'Config',
'deploy': 'Deploy',
'device': 'Device',
'devices': 'Devices',
'env': "Environment Variable",
'envs': "Environment Variables",
'fleet': "Fleet",
'fleets': "Fleets",
'help': "Help and Version",
'key': "SSH Key",
'keys': "SSH Keys",
'local': "local",
'logs': "logs",
'note': "Notes",
'orgs': "Organizations",
'os': "OS",
'platform': "Platform",
'preload': "Preload",
'push': "Push",
'release': "Release",
'releases': "Releases",
'settings': "Settings",
'support': "Support",
'tag': 'Tag',
'tags': 'Tags',
'util': "Utilities",
}

// Fetch all available commands
const allCommandsPaths = globSync('build/commands/**/*.js', { ignore: 'build/commands/internal/**' })

// Docs config template
let capitanoDoc: Documentation = {
title: 'balena CLI Documentation',
introduction: '',
categories: []
}

for (let commandPath of allCommandsPaths) {
let flag = false
let commandDir = path.basename(path.dirname(commandPath))

// Add a new entry if no existing headings found
if (!Object.keys(commandHeadings).includes(commandDir)) {
// Capitalize each word of directory name
// commandDir = commandDir.replace(/(^\w|\s\w)/g, word => word.toUpperCase());
capitanoDoc.categories.push({ 'title': commandDir, 'files': [commandPath] })
commandHeadings[commandDir] = commandDir
flag = true
}

for (let commandHeading of Object.keys(commandHeadings)) {
if (commandDir === commandHeading) {
for (let category of capitanoDoc.categories) {
if (category["title"] === commandHeadings[commandDir]) {
if (flag) {
break
}
category["files"].push(commandPath)
flag = true
break
}
}
if (flag) {
break
}
capitanoDoc.categories.push({ 'title': commandHeadings[commandDir], 'files': [commandPath] })
break
}
}
}

// Sort categories alphabetically
capitanoDoc.categories = capitanoDoc.categories.sort((a, b) => a.title.localeCompare(b.title))


/**
* Modify and return the `capitanoDoc` object above in order to render the
* CLI documentation/reference web page at:
* https://www.balena.io/docs/reference/cli/
* Modify and return the `capitanoDoc` object above in order to generate the
* CLI documentation at docs/balena-cli.md
*
* This function parses the README.md file to extract relevant sections
* for the documentation web page.
*/
export async function getCapitanoDoc(): Promise<typeof capitanoDoc> {
const readmePath = path.join(__dirname, '..', '..', 'README.md');
const mdParser = new MarkdownFileParser(readmePath);
const sections: string[] = await Promise.all([
mdParser.getSectionOfTitle('About').then((sectionLines: string) => {
// delete the title of the 'About' section for the web page
const match = /^(#+)\s+.+?\n\s*([^]*)/.exec(sectionLines);
if (!match || match.length < 3) {
throw new Error(`Error parsing section title`);
}
// match[1] has the title, match[2] has the rest
return match && match[2];
}),
mdParser.getSectionOfTitle('Installation'),
mdParser.getSectionOfTitle('Choosing a shell (command prompt/terminal)'),
mdParser.getSectionOfTitle('Logging in'),
mdParser.getSectionOfTitle('Proxy support'),
mdParser.getSectionOfTitle('Support, FAQ and troubleshooting'),
mdParser.getSectionOfTitle('Deprecation policy'),
]);
capitanoDoc.introduction = sections.join('\n');
return capitanoDoc;
const readmePath = path.join(__dirname, '..', '..', 'README.md');
const mdParser = new MarkdownFileParser(readmePath);
const sections: string[] = await Promise.all([
mdParser.getSectionOfTitle('About').then((sectionLines: string) => {
// delete the title of the 'About' section for the web page
const match = /^(#+)\s+.+?\n\s*([^]*)/.exec(sectionLines);
if (!match || match.length < 3) {
throw new Error(`Error parsing section title`);
}
// match[1] has the title, match[2] has the rest
return match && match[2];
}),
mdParser.getSectionOfTitle('Installation'),
mdParser.getSectionOfTitle('Choosing a shell (command prompt/terminal)'),
mdParser.getSectionOfTitle('Logging in'),
mdParser.getSectionOfTitle('Proxy support'),
mdParser.getSectionOfTitle('Support, FAQ and troubleshooting'),
mdParser.getSectionOfTitle('Deprecation policy'),
]);
capitanoDoc.introduction = sections.join('\n');
return capitanoDoc;
}

0 comments on commit 4919d1b

Please sign in to comment.