Add generators: code, completion, and docs generators
This commit is contained in:
135
src/generators/docs-generator.ts
Normal file
135
src/generators/docs-generator.ts
Normal file
@@ -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';
|
||||
}
|
||||
Reference in New Issue
Block a user