From 10f6b6950740486006277ecf4cd20524b408a765 Mon Sep 17 00:00:00 2001 From: 7000pctAUTO Date: Fri, 30 Jan 2026 07:10:13 +0000 Subject: [PATCH] Add generators: code, completion, and docs generators --- src/generators/docs-generator.ts | 135 +++++++++++++++++++++++++++++++ 1 file changed, 135 insertions(+) create mode 100644 src/generators/docs-generator.ts diff --git a/src/generators/docs-generator.ts b/src/generators/docs-generator.ts new file mode 100644 index 0000000..be0cd03 --- /dev/null +++ b/src/generators/docs-generator.ts @@ -0,0 +1,135 @@ +import * as fs from 'fs'; +import * as path from 'path'; +import Handlebars from 'handlebars'; +import type { CLISpec } from '../types/spec.js'; + +const TEMPLATE_DIR = path.resolve(process.cwd(), 'src', 'templates'); + +function getTemplatePath(templateName: string): string { + return path.join(TEMPLATE_DIR, `${templateName}.handlebars`); +} + +function getTemplateContent(templateName: string): string { + const templatePath = getTemplatePath(templateName); + if (!fs.existsSync(templatePath)) { + throw new Error(`Template not found: ${templatePath}`); + } + return fs.readFileSync(templatePath, 'utf-8'); +} + +function compileTemplate(content: string): Handlebars.TemplateDelegate { + Handlebars.registerHelper('escape', function (str: string) { + return str.replace(/"/g, '\\"').replace(/\n/g, ' ').replace(/\s+/g, ' '); + }); + + Handlebars.registerHelper('defaultValue', function (value: unknown) { + if (value === undefined || value === null) return ''; + return String(value); + }); + + Handlebars.registerHelper('toJson', function (value: unknown) { + return JSON.stringify(value, null, 2); + }); + + return Handlebars.compile(content, { noEscape: true }); +} + +export interface DocsResult { + success: boolean; + content?: string; + error?: string; +} + +export function generateManPage(spec: CLISpec): DocsResult { + try { + const templateContent = getTemplateContent('manpage'); + const template = compileTemplate(templateContent); + const content = template({ spec }); + return { success: true, content }; + } catch (error) { + return { + success: false, + error: error instanceof Error ? error.message : 'Unknown error during man page generation', + }; + } +} + +export function generateReadmeSection(spec: CLISpec): DocsResult { + try { + const content = `## ${spec.name} + +${spec.description} + +### Installation + +\`\`\`bash +# For Node.js +npm install -g ${spec.bin || spec.name} + +# For Python +pip install ${spec.bin || spec.name} + +# For Go +go install github.com/${spec.author || 'user'}/${spec.bin || spec.name}@latest + +# For Rust +cargo install ${spec.bin || spec.name} +\`\`\` + +### Usage + +\`\`\`bash +${spec.bin || spec.name} --help +${spec.bin || spec.name} --version +\`\`\` + +### Commands + +${spec.commands.map(cmd => `#### \`${cmd.name}\` + +${cmd.description} + +${cmd.options ? `**Options:** +${cmd.options.map(opt => `- \`--${opt.name}${opt.short ? `, -${opt.short}` : ''}\`: ${opt.description}`).join('\n')} +` : ''}`).join('\n')} + +### Global Options + +${spec.globalOptions?.map(opt => `- \`--${opt.name}${opt.short ? `, -${opt.short}` : ''}\`: ${opt.description}`).join('\n') || 'None'} + +### Examples + +${spec.examples?.map(ex => `**${ex.description}** +\`\`\`bash +${ex.command} +\`\`\` +${ex.output ? `Output: +\`\`\` +${ex.output} +\`\`\` +` : ''}`).join('\n') || 'No examples available.'} + +### Version + +${spec.version} + +${spec.author ? `**Author:** ${spec.author}` : ''} +${spec.license ? `**License:** ${spec.license}` : ''} +`; + + return { success: true, content }; + } catch (error) { + return { + success: false, + error: error instanceof Error ? error.message : 'Unknown error during README generation', + }; + } +} + +export function getManPageFileName(spec: CLISpec): string { + return `${spec.bin || spec.name}.1`; +} + +export function getReadmeFileName(): string { + return 'CLI_DOCS.md'; +}