sync-upstream
Version:
A tool for synchronizing code with upstream repositories with incremental updates and parallel processing.
177 lines (176 loc) • 7.2 kB
JavaScript
;
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();