feat(update): 添加跳过依赖安装选项并优化依赖检测逻辑
This commit is contained in:
@@ -53,6 +53,7 @@ function parseArgs() {
|
|||||||
skipMigrate: args.includes('--skip-migrate'),
|
skipMigrate: args.includes('--skip-migrate'),
|
||||||
skipBuild: args.includes('--skip-build'),
|
skipBuild: args.includes('--skip-build'),
|
||||||
skipRestart: args.includes('--skip-restart'),
|
skipRestart: args.includes('--skip-restart'),
|
||||||
|
skipDeps: args.includes('--skip-deps'),
|
||||||
dryRun: args.includes('--dry-run'),
|
dryRun: args.includes('--dry-run'),
|
||||||
force: args.includes('--force'),
|
force: args.includes('--force'),
|
||||||
help: args.includes('--help') || args.includes('-h')
|
help: args.includes('--help') || args.includes('-h')
|
||||||
@@ -68,6 +69,7 @@ ${colors.bright}IDC设备管理系统 - 一键更新脚本 v${SCRIPT_VERSION}${c
|
|||||||
选项:
|
选项:
|
||||||
--skip-git 跳过 Git 拉取
|
--skip-git 跳过 Git 拉取
|
||||||
--skip-backup 跳过数据库备份
|
--skip-backup 跳过数据库备份
|
||||||
|
--skip-deps 跳过依赖安装
|
||||||
--skip-migrate 跳过数据库迁移
|
--skip-migrate 跳过数据库迁移
|
||||||
--skip-build 跳过前端构建
|
--skip-build 跳过前端构建
|
||||||
--skip-restart 跳过服务重启
|
--skip-restart 跳过服务重启
|
||||||
@@ -77,7 +79,7 @@ ${colors.bright}IDC设备管理系统 - 一键更新脚本 v${SCRIPT_VERSION}${c
|
|||||||
|
|
||||||
示例:
|
示例:
|
||||||
node update.js # 完整更新流程
|
node update.js # 完整更新流程
|
||||||
node update.js --skip-backup # 跳过备份
|
node update.js --skip-deps # 跳过依赖安装
|
||||||
node update.js --dry-run # 模拟运行
|
node update.js --dry-run # 模拟运行
|
||||||
`);
|
`);
|
||||||
process.exit(0);
|
process.exit(0);
|
||||||
@@ -298,33 +300,102 @@ function pullCode(options) {
|
|||||||
return { success: false };
|
return { success: false };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function checkDepsNeedInstall(dirPath, dirName) {
|
||||||
|
const nodeModulesPath = path.join(dirPath, 'node_modules');
|
||||||
|
const packageJsonPath = path.join(dirPath, 'package.json');
|
||||||
|
const packageLockPath = path.join(dirPath, 'package-lock.json');
|
||||||
|
|
||||||
|
if (!fs.existsSync(packageJsonPath)) {
|
||||||
|
return { needInstall: false, reason: '未找到 package.json' };
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!fs.existsSync(nodeModulesPath)) {
|
||||||
|
return { needInstall: true, reason: 'node_modules 不存在' };
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const gitDiff = execSync(`git diff HEAD~1 --name-only -- "${dirName}/package.json" "${dirName}/package-lock.json" 2>nul`, {
|
||||||
|
encoding: 'utf8',
|
||||||
|
stdio: ['pipe', 'pipe', 'pipe'],
|
||||||
|
cwd: __dirname
|
||||||
|
}).trim();
|
||||||
|
|
||||||
|
if (gitDiff) {
|
||||||
|
return { needInstall: true, reason: 'package.json 或 package-lock.json 有更新' };
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
// Git 检查失败,继续其他检测
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
|
||||||
|
const depsCount = Object.keys(packageJson.dependencies || {}).length +
|
||||||
|
Object.keys(packageJson.devDependencies || {}).length;
|
||||||
|
|
||||||
|
const installedCount = fs.readdirSync(nodeModulesPath).filter(f =>
|
||||||
|
!f.startsWith('.') && fs.statSync(path.join(nodeModulesPath, f)).isDirectory()
|
||||||
|
).length;
|
||||||
|
|
||||||
|
if (depsCount > 0 && installedCount < depsCount * 0.5) {
|
||||||
|
return { needInstall: true, reason: `已安装依赖数量不足 (${installedCount}/${depsCount})` };
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
// 检测失败,保守起见执行安装
|
||||||
|
return { needInstall: true, reason: '依赖状态检测失败' };
|
||||||
|
}
|
||||||
|
|
||||||
|
return { needInstall: false, reason: '依赖已是最新' };
|
||||||
|
}
|
||||||
|
|
||||||
function installDependencies(options) {
|
function installDependencies(options) {
|
||||||
|
if (options.skipDeps) {
|
||||||
|
log.info('已跳过依赖安装');
|
||||||
|
return { success: true, skipped: true };
|
||||||
|
}
|
||||||
|
|
||||||
const backendPath = path.join(__dirname, 'backend');
|
const backendPath = path.join(__dirname, 'backend');
|
||||||
const frontendPath = path.join(__dirname, 'frontend');
|
const frontendPath = path.join(__dirname, 'frontend');
|
||||||
|
|
||||||
if (options.dryRun) {
|
if (options.dryRun) {
|
||||||
log.subStep('[模拟] 安装后端依赖');
|
log.subStep('[模拟] 检测后端依赖');
|
||||||
log.subStep('[模拟] 安装前端依赖');
|
log.subStep('[模拟] 检测前端依赖');
|
||||||
return { success: true, dryRun: true };
|
return { success: true, dryRun: true };
|
||||||
}
|
}
|
||||||
|
|
||||||
log.subStep('安装后端依赖...');
|
let backendSkipped = false;
|
||||||
const backendResult = runCommand('npm install --production=false', { cwd: backendPath });
|
let frontendSkipped = false;
|
||||||
if (!backendResult.success) {
|
|
||||||
log.error('后端依赖安装失败');
|
|
||||||
return { success: false, step: 'backend' };
|
|
||||||
}
|
|
||||||
log.success('后端依赖安装完成');
|
|
||||||
|
|
||||||
log.subStep('安装前端依赖...');
|
log.subStep('检测后端依赖状态...');
|
||||||
const frontendResult = runCommand('npm install', { cwd: frontendPath });
|
const backendCheck = checkDepsNeedInstall(backendPath, 'backend');
|
||||||
if (!frontendResult.success) {
|
if (backendCheck.needInstall) {
|
||||||
log.error('前端依赖安装失败');
|
log.info(`后端依赖需要更新: ${backendCheck.reason}`);
|
||||||
return { success: false, step: 'frontend' };
|
const backendResult = runCommand('npm install --production=false', { cwd: backendPath });
|
||||||
|
if (!backendResult.success) {
|
||||||
|
log.error('后端依赖安装失败');
|
||||||
|
return { success: false, step: 'backend' };
|
||||||
|
}
|
||||||
|
log.success('后端依赖安装完成');
|
||||||
|
} else {
|
||||||
|
log.success(`后端依赖已是最新 (${backendCheck.reason})`);
|
||||||
|
backendSkipped = true;
|
||||||
}
|
}
|
||||||
log.success('前端依赖安装完成');
|
|
||||||
|
|
||||||
return { success: true };
|
log.subStep('检测前端依赖状态...');
|
||||||
|
const frontendCheck = checkDepsNeedInstall(frontendPath, 'frontend');
|
||||||
|
if (frontendCheck.needInstall) {
|
||||||
|
log.info(`前端依赖需要更新: ${frontendCheck.reason}`);
|
||||||
|
const frontendResult = runCommand('npm install', { cwd: frontendPath });
|
||||||
|
if (!frontendResult.success) {
|
||||||
|
log.error('前端依赖安装失败');
|
||||||
|
return { success: false, step: 'frontend' };
|
||||||
|
}
|
||||||
|
log.success('前端依赖安装完成');
|
||||||
|
} else {
|
||||||
|
log.success(`前端依赖已是最新 (${frontendCheck.reason})`);
|
||||||
|
frontendSkipped = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return { success: true, skipped: backendSkipped && frontendSkipped };
|
||||||
}
|
}
|
||||||
|
|
||||||
function runMigrations(options) {
|
function runMigrations(options) {
|
||||||
@@ -461,7 +532,7 @@ async function healthCheck() {
|
|||||||
|
|
||||||
for (let i = 1; i <= maxRetries; i++) {
|
for (let i = 1; i <= maxRetries; i++) {
|
||||||
try {
|
try {
|
||||||
const result = execSync('curl -s -o /dev/null -w "%{http_code}" http://localhost:8000/api/health 2>nul || echo "000"', {
|
const result = execSync('curl -s -o /dev/null -w "%{http_code}" http://localhost:8000/health 2>nul || echo "000"', {
|
||||||
encoding: 'utf8',
|
encoding: 'utf8',
|
||||||
stdio: ['pipe', 'pipe', 'pipe'],
|
stdio: ['pipe', 'pipe', 'pipe'],
|
||||||
timeout: 5000
|
timeout: 5000
|
||||||
@@ -520,7 +591,7 @@ function printSummary(options, results) {
|
|||||||
console.log(`\n ${colors.cyan}步骤状态:${colors.reset}`);
|
console.log(`\n ${colors.cyan}步骤状态:${colors.reset}`);
|
||||||
console.log(` 数据库备份: ${results.backup?.skipped ? '已跳过' : results.backup?.success ? '成功' : '失败'}`);
|
console.log(` 数据库备份: ${results.backup?.skipped ? '已跳过' : results.backup?.success ? '成功' : '失败'}`);
|
||||||
console.log(` 代码更新: ${results.git?.skipped ? '已跳过' : results.git?.success ? '成功' : '失败'}`);
|
console.log(` 代码更新: ${results.git?.skipped ? '已跳过' : results.git?.success ? '成功' : '失败'}`);
|
||||||
console.log(` 依赖安装: ${results.deps?.success ? '成功' : '失败'}`);
|
console.log(` 依赖安装: ${results.deps?.skipped ? '已跳过' : results.deps?.success ? '成功' : '失败'}`);
|
||||||
console.log(` 数据库迁移: ${results.migrate?.skipped ? '已跳过' : results.migrate?.success ? '成功' : '失败'}`);
|
console.log(` 数据库迁移: ${results.migrate?.skipped ? '已跳过' : results.migrate?.success ? '成功' : '失败'}`);
|
||||||
console.log(` 前端构建: ${results.build?.skipped ? '已跳过' : results.build?.success ? '成功' : '失败'}`);
|
console.log(` 前端构建: ${results.build?.skipped ? '已跳过' : results.build?.success ? '成功' : '失败'}`);
|
||||||
console.log(` 服务重启: ${results.restart?.skipped ? '已跳过' : results.restart?.success ? '成功' : '失败'}`);
|
console.log(` 服务重启: ${results.restart?.skipped ? '已跳过' : results.restart?.success ? '成功' : '失败'}`);
|
||||||
|
|||||||
Reference in New Issue
Block a user