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