spa/.claude/skills/softcopyright/scripts/index.js.pdf-backup

364 lines
12 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env node
const { Command } = require('commander');
const chalk = require('chalk');
const inquirer = require('inquirer');
const path = require('path');
const fs = require('fs-extra');
const scanner = require('./scanner');
const docGenerator = require('./doc-generator');
const sourceExporter = require('./source-exporter');
// 软著关键词检测
const COPYRIGHT_KEYWORDS = [
'软著', '著作权', '软件著作权', '版权', 'copyright', 'patent', '专利'
];
/**
* 检测用户输入是否包含软著相关关键词
* @param {string} input 用户输入
* @returns {boolean} 是否包含软著关键词
*/
function containsCopyrightKeyword(input) {
return COPYRIGHT_KEYWORDS.some(keyword =>
input.toLowerCase().includes(keyword.toLowerCase())
);
}
/**
* 智能关键词处理和软著材料生成
* @param {string} input 用户输入
* @param {string} projectPath 项目路径
* @param {string} outputDir 输出路径
* @returns {Promise<boolean>} 是否执行了软著生成
*/
async function handleCopyrightKeywords(input, projectPath, outputDir) {
if (!containsCopyrightKeyword(input)) {
return false;
}
console.log(chalk.blue.bold('🎯 检测到软著相关关键词启动SoftCopyright功能'));
console.log(chalk.cyan(`关键词: "${input}"`));
console.log(chalk.gray('='.repeat(50)));
try {
// 扫描项目
console.log(chalk.yellow('📊 分析项目源码...'));
const projectInfo = await scanner.scanProject(projectPath || process.cwd());
console.log(chalk.green(`✅ 项目分析完成: ${projectInfo.name}`));
console.log(chalk.white(` - 文件数: ${projectInfo.files.length}`));
console.log(chalk.white(` - 代码行数: ${projectInfo.totalLines}`));
console.log(chalk.white(` - 主要语言: ${projectInfo.languages.join(', ')}`));
// 显示项目信息并确认
console.log(chalk.cyan('\n📋 项目信息确认:'));
const { confirmed } = await inquirer.prompt([
{
type: 'confirm',
name: 'confirmed',
message: '是否为该项目生成软著申请材料?',
default: true
}
]);
if (!confirmed) {
console.log(chalk.yellow('❌ 用户取消操作'));
return false;
}
// 询问生成类型
const { generateType } = await inquirer.prompt([
{
type: 'list',
name: 'generateType',
message: '请选择要生成的材料类型:',
choices: [
{ name: '📋 生成全部材料 (HTML自动转PDF)', value: 'auto-pdf' },
{ name: '📖 仅生成软件说明书 (HTML)', value: 'manual' },
{ name: '💻 仅生成源代码文档 (PDF)', value: 'source' },
{ name: '📊 仅查看项目分析', value: 'scan' }
]
}
]);
// 根据选择执行相应操作
if (generateType === 'scan') {
console.log(chalk.green('✅ 项目分析完成'));
return true;
}
// 生成材料
if (generateType === 'auto-pdf') {
const { generateAutoPrintPDF } = require('./auto-print-pdf');
console.log(chalk.yellow('📄 生成HTML并自动转换为PDF...'));
await generateAutoPrintPDF(projectInfo, outputDir);
} else if (generateType === 'manual') {
console.log(chalk.yellow('📝 生成软件说明书(HTML格式)...'));
await docGenerator.generateManual(projectInfo, outputDir);
} else if (generateType === 'source') {
console.log(chalk.yellow('💻 生成源代码文档...'));
await sourceExporter.exportSourceCode(projectInfo, outputDir);
}
console.log(chalk.green.bold('\n🎉 软著材料生成完成!'));
return true;
} catch (error) {
console.error(chalk.red('❌ 软著材料生成失败:'), error.message);
return false;
}
}
const program = new Command();
// 版本信息
program
.name('softcopyright')
.description('智能软件著作权申请材料生成工具')
.version('1.0.0');
// 主命令 - 生成软著材料
program
.command('generate')
.description('生成软件著作权申请材料')
.option('-p, --path <path>', '项目路径', process.cwd())
.option('-t, --type <type>', '生成类型 (manual|source|all)', 'all')
.option('-o, --output <path>', '输出路径', process.cwd())
.action(async (options) => {
try {
console.log(chalk.blue.bold('🚀 SoftCopyright - 软件著作权申请材料生成工具'));
console.log(chalk.gray('='.repeat(60)));
// 确认项目路径
const projectPath = path.resolve(options.path);
if (!await fs.pathExists(projectPath)) {
console.error(chalk.red(`❌ 项目路径不存在: ${projectPath}`));
process.exit(1);
}
console.log(chalk.cyan(`📁 项目路径: ${projectPath}`));
// 询问生成类型
if (options.type === 'all') {
const { type } = await inquirer.prompt([
{
type: 'list',
name: 'type',
message: '请选择要生成的材料类型:',
choices: [
{ name: '📋 生成全部材料 (推荐)', value: 'all' },
{ name: '📖 仅生成软件说明书', value: 'manual' },
{ name: '💻 仅生成源代码文档', value: 'source' }
]
}
]);
options.type = type;
}
console.log(chalk.yellow(`🔍 开始分析项目...`));
// 扫描项目
const projectInfo = await scanner.scanProject(projectPath);
console.log(chalk.green(`✅ 项目分析完成,发现 ${projectInfo.files.length} 个源代码文件`));
const outputDir = path.resolve(options.output);
await fs.ensureDir(outputDir);
// 生成材料
if (options.type === 'manual' || options.type === 'all') {
console.log(chalk.yellow('📝 生成软件说明书...'));
const manualPath = await docGenerator.generateManual(projectInfo, outputDir);
console.log(chalk.green(`✅ 软件说明书已生成: ${manualPath}`));
}
if (options.type === 'source' || options.type === 'all') {
console.log(chalk.yellow('💻 生成源代码文档...'));
const sourcePath = await sourceExporter.exportSourceCode(projectInfo, outputDir);
console.log(chalk.green(`✅ 源代码文档已生成: ${sourcePath}`));
}
console.log(chalk.blue.bold('\n🎉 生成完成!'));
console.log(chalk.gray(`输出目录: ${outputDir}`));
} catch (error) {
console.error(chalk.red('❌ 生成失败:'), error.message);
process.exit(1);
}
});
// 扫描命令
program
.command('scan')
.description('扫描项目源码')
.argument('<path>', '项目路径')
.action(async (projectPath) => {
try {
const resolvedPath = path.resolve(projectPath);
console.log(chalk.blue(`🔍 扫描项目: ${resolvedPath}`));
const projectInfo = await scanner.scanProject(resolvedPath);
console.log(chalk.green('\n📊 扫描结果:'));
console.log(chalk.white(`项目名称: ${projectInfo.name}`));
console.log(chalk.white(`源代码文件: ${projectInfo.files.length}`));
console.log(chalk.white(`总代码行数: ${projectInfo.totalLines}`));
console.log(chalk.white(`主要语言: ${projectInfo.languages.join(', ')}`));
// 显示文件统计
console.log(chalk.cyan('\n📁 文件类型统计:'));
Object.entries(projectInfo.fileStats).forEach(([ext, count]) => {
console.log(chalk.white(` ${ext}: ${count} 个文件`));
});
} catch (error) {
console.error(chalk.red('❌ 扫描失败:'), error.message);
process.exit(1);
}
});
// 交互式命令
program
.command('interactive')
.description('交互式生成软著材料')
.action(async () => {
try {
console.log(chalk.blue.bold('🎯 欢迎使用 SoftCopyright 交互式向导'));
console.log(chalk.gray('='.repeat(60)));
// 询问项目路径
const { projectPath } = await inquirer.prompt([
{
type: 'input',
name: 'projectPath',
message: '请输入项目路径:',
default: process.cwd(),
validate: async (input) => {
const resolvedPath = path.resolve(input);
return await fs.pathExists(resolvedPath) || '路径不存在,请重新输入';
}
}
]);
console.log(chalk.yellow(`🔍 分析项目: ${projectPath}`));
const projectInfo = await scanner.scanProject(projectPath);
// 显示项目信息
console.log(chalk.cyan('\n📊 项目信息:'));
console.log(chalk.white(` 检测到的项目名称: ${projectInfo.name}`));
console.log(chalk.white(` 源代码文件数: ${projectInfo.files.length}`));
console.log(chalk.white(` 主要编程语言: ${projectInfo.languages.join(', ')}`));
// 确认项目信息
const { confirmed } = await inquirer.prompt([
{
type: 'confirm',
name: 'confirmed',
message: '项目信息是否正确?',
default: true
}
]);
if (!confirmed) {
console.log(chalk.yellow('❌ 操作已取消'));
return;
}
// 选择生成内容
const { generateType } = await inquirer.prompt([
{
type: 'checkbox',
name: 'generateType',
message: '请选择要生成的内容:',
choices: [
{ name: '📋 软件说明书 (约2000-3000字)', value: 'manual', checked: true },
{ name: '💻 源代码文档 (60页每页50行)', value: 'source', checked: true }
]
}
]);
if (generateType.length === 0) {
console.log(chalk.yellow('⚠️ 请至少选择一种生成内容'));
return;
}
// 输出路径
const { outputPath } = await inquirer.prompt([
{
type: 'input',
name: 'outputPath',
message: '输出目录路径:',
default: path.join(projectPath, 'softcopyright-output')
}
]);
await fs.ensureDir(outputPath);
// 开始生成
console.log(chalk.blue('\n🚀 开始生成...'));
if (generateType.includes('manual')) {
console.log(chalk.yellow('📝 生成软件说明书...'));
const manualPath = await docGenerator.generateManual(projectInfo, outputPath);
console.log(chalk.green(`✅ 软件说明书: ${manualPath}`));
}
if (generateType.includes('source')) {
console.log(chalk.yellow('💻 生成源代码文档...'));
const sourcePath = await sourceExporter.exportSourceCode(projectInfo, outputPath);
console.log(chalk.green(`✅ 源代码文档: ${sourcePath}`));
}
console.log(chalk.blue.bold('\n🎉 生成完成!'));
console.log(chalk.gray(`文件已保存到: ${outputPath}`));
} catch (error) {
console.error(chalk.red('❌ 操作失败:'), error.message);
process.exit(1);
}
});
// 错误处理
program.on('command:*', () => {
console.error(chalk.red('❌ 未知命令,使用 --help 查看可用命令'));
process.exit(1);
});
// 检查是否包含软著关键词(在命令解析之前)
const userArgs = process.argv.slice(2);
const userArgsStr = userArgs.join(' ');
const projectPath = process.cwd(); // 默认使用当前目录作为项目路径
const outputDir = process.cwd(); // 默认使用当前目录作为输出路径
// 检查是否包含命令选项(以--或-开头的参数)
const hasCommandOptions = userArgs.some(arg => arg.startsWith('--') || arg.startsWith('-'));
// 只有当用户输入纯关键词(不含命令选项和明确命令)时才触发自动功能
if (containsCopyrightKeyword(userArgsStr) &&
!hasCommandOptions &&
!userArgs.includes('generate') &&
!userArgs.includes('scan') &&
!userArgs.includes('interactive') &&
!userArgs.includes('help') &&
userArgs.length > 0 &&
userArgs.length <= 3) { // 限制参数数量,避免复杂的命令被误判
console.log(chalk.blue.bold('🎯 检测到软著相关关键词启动SoftCopyright功能'));
console.log(chalk.cyan(`关键词: "${userArgsStr}"`));
handleCopyrightKeywords(userArgsStr, projectPath, outputDir).then(() => {
process.exit(0);
}).catch(error => {
console.error(chalk.red('❌ 软著生成失败:'), error.message);
process.exit(1);
});
}
// 解析命令行参数
program.parse();
// 如果没有提供命令,显示帮助
if (!process.argv.slice(2).length) {
program.outputHelp();
}