UNPKG

sync-upstream

Version:

A tool for synchronizing code with upstream repositories with incremental updates and parallel processing.

177 lines (176 loc) 7.2 kB
#!/usr/bin/env node "use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const chalk_1 = __importDefault(require("chalk")); const minimist_1 = __importDefault(require("minimist")); const package_json_1 = __importDefault(require("../package.json")); const simple_git_1 = __importDefault(require("simple-git")); const config_1 = require("./config"); const prompts_1 = require("./prompts"); const sync_1 = require("./sync"); // 检查当前目录是否是Git仓库 async function isGitRepository() { try { const git = (0, simple_git_1.default)(); await git.status(); return true; } catch (error) { return false; } } // 解析命令行参数 const args = (0, minimist_1.default)(process.argv.slice(2), { // 使用string类型并在后续代码中转换为数字 string: ['repo', 'branch', 'company-branch', 'dirs', 'message', 'config', 'config-format', 'retry-max', 'retry-delay', 'retry-backoff', 'concurrency'], boolean: ['push', 'v', 'version', 'force', 'verbose', 'silent', 'dry-run', 'preview-only'], alias: { r: 'repo', b: 'branch', c: 'company-branch', d: 'dirs', m: 'message', p: 'push', f: 'force', h: 'help', v: 'version', V: 'verbose', s: 'silent', n: 'dry-run', P: 'preview-only', C: 'config', F: 'config-format', rm: 'retry-max', rd: 'retry-delay', rb: 'retry-backoff', cl: 'concurrency', }, default: { 'branch': 'master', 'company-branch': 'master', 'dirs': '', 'message': 'Sync upstream changes to specified directories', 'push': false, 'force': true, 'verbose': false, 'silent': false, 'dry-run': false, 'preview-only': false, 'config': '', 'config-format': 'json', 'retry-max': undefined, 'retry-delay': undefined, 'retry-backoff': undefined, 'concurrency': undefined, }, }); // 显示版本信息 if (args.version) { console.log(chalk_1.default.bold.cyan(`sync-upstream v${package_json_1.default.version}`)); process.exit(0); } // 显示帮助信息 if (args.help) { console.log(chalk_1.default.bold.cyan('仓库目录 - 交互版\n')); console.log('用法: sync-upstream [选项]\n'); console.log('选项:'); console.log(' -r, --repo <url> 上游仓库 URL'); console.log(' -d, --dirs <目录> 要同步的目录,多个目录用逗号分隔'); console.log(' -b, --branch <分支> 上游分支 (默认: main)'); console.log(' -c, --company-branch <分支> 公司仓库分支 (默认: main)'); console.log(' -m, --message <消息> 提交消息'); console.log(' -p, --push 自动推送变更'); console.log(' -f, --force 强制覆盖本地文件,不使用增量复制 (默认: true)'); console.log(' -V, --verbose 显示详细日志信息'); console.log(' -s, --silent 静默模式,不输出日志'); console.log(' -n, --dry-run 试运行模式,不实际执行同步操作'); console.log(' -P, --preview-only 预览模式,只显示变更,不实际修改文件'); console.log(' -C, --config <路径> 指定配置文件路径'); console.log(' -F, --config-format <格式> 配置文件格式 (json, yaml, toml)'); console.log(' --rm, --retry-max <次数> 网络请求最大重试次数 (默认: 3)'); console.log(' --rd, --retry-delay <毫秒> 初始重试延迟时间 (默认: 2000)'); console.log(' --rb, --retry-backoff <因子> 重试退避因子 (默认: 1.5)'); console.log(' --cl, --concurrency <数量> 并行处理的最大文件数量 (默认: 5)'); console.log(' -v, --version 显示版本信息'); console.log(' -h, --help 显示帮助信息\n'); console.log('示例:'); console.log(' sync-upstream -r https://github.com/open-source/project.git -d src/core,docs'); console.log('\n如果没有提供参数,将启动交互式向导'); process.exit(0); } // 检查是否在Git仓库中 async function run() { const isGitRepo = await isGitRepository(); if (!isGitRepo) { console.error(chalk_1.default.red('错误: 当前目录不是Git仓库。请在Git初始化后的目录中运行此工具。')); process.exit(1); } // 准备初始配置 const initialOptions = { upstreamRepo: args.repo, upstreamBranch: args.branch, companyBranch: args['company-branch'], syncDirs: args.dirs ? args.dirs.split(',').map((dir) => dir.trim()) : [], commitMessage: args.message, autoPush: args.push, forceOverwrite: args.force, verbose: args.verbose, silent: args.silent, dryRun: args['dry-run'], previewOnly: args['preview-only'], concurrencyLimit: args['concurrency'] ? parseInt(args['concurrency'], 10) : undefined, retryConfig: { maxRetries: args['retry-max'], initialDelay: args['retry-delay'], backoffFactor: args['retry-backoff'], }, }; // 加载配置文件 let configOptions = {}; // 如果指定了配置文件路径,则使用该文件 const configPath = args.config ? args.config : null; const configFormat = args['config-format']; // 加载配置文件 configOptions = await (0, config_1.loadConfig)(); // 合并配置文件和命令行参数,命令行参数优先级更高 // 使用对象展开运算符,命令行参数会覆盖配置文件中的同名参数 const mergedOptions = { ...configOptions, ...initialOptions, }; // 特别处理 syncDirs,如果命令行参数为空但配置文件有值,则使用配置文件的值 if (!mergedOptions.syncDirs || mergedOptions.syncDirs.length === 0) { mergedOptions.syncDirs = configOptions.syncDirs; } // 如果缺少必要参数,启动交互式提示 let options; if (!mergedOptions.upstreamRepo || !mergedOptions.syncDirs || mergedOptions.syncDirs.length === 0) { options = await (0, prompts_1.promptForOptions)(mergedOptions); } else { // 使用合并后的参数 options = { upstreamRepo: mergedOptions.upstreamRepo, upstreamBranch: mergedOptions.upstreamBranch || 'master', companyBranch: mergedOptions.companyBranch || 'master', syncDirs: mergedOptions.syncDirs, commitMessage: mergedOptions.commitMessage || 'Sync upstream changes', autoPush: mergedOptions.autoPush || false, }; } try { const syncer = new sync_1.UpstreamSyncer(options); await syncer.run(); } catch (error) { console.error(chalk_1.default.red('发生错误:'), error); process.exit(1); } } // 运行主函数 run();