|
@@ -10,7 +10,7 @@ const { execSync } = require('child_process');
|
|
|
|
|
|
|
|
// 获取脚本所在目录和项目根目录
|
|
// 获取脚本所在目录和项目根目录
|
|
|
const scriptDir = __dirname;
|
|
const scriptDir = __dirname;
|
|
|
-const projectRoot = path.dirname(scriptDir);
|
|
|
|
|
|
|
+const projectRoot = path.dirname(path.dirname(scriptDir));
|
|
|
const packageJsonPath = path.join(projectRoot, 'package.json');
|
|
const packageJsonPath = path.join(projectRoot, 'package.json');
|
|
|
const dependenciesFile = path.join(scriptDir, 'dependencies.txt');
|
|
const dependenciesFile = path.join(scriptDir, 'dependencies.txt');
|
|
|
const nodeModulesPath = path.join(projectRoot, 'node_modules');
|
|
const nodeModulesPath = path.join(projectRoot, 'node_modules');
|
|
@@ -133,31 +133,119 @@ for (const depName of depNames) {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-// 如果有缺失的依赖,显示必要信息并安装
|
|
|
|
|
-if (missingCount > 0) {
|
|
|
|
|
- log(`[X] Missing ${missingCount} package(s) out of ${Object.keys(allDependencies).length}`, 'red');
|
|
|
|
|
-
|
|
|
|
|
- log('Missing dependencies:', 'yellow');
|
|
|
|
|
- missingDependencies.forEach(missing => {
|
|
|
|
|
- log(` - ${missing}`, 'red');
|
|
|
|
|
- });
|
|
|
|
|
|
|
+// Install missing dependencies with retry loop
|
|
|
|
|
+let maxRetries = 5;
|
|
|
|
|
+let retryCount = 0;
|
|
|
|
|
+let currentMissing = [...missingDependencies];
|
|
|
|
|
+
|
|
|
|
|
+while (currentMissing.length > 0 && retryCount < maxRetries) {
|
|
|
|
|
+ if (retryCount > 0) {
|
|
|
|
|
+ log(`\nRetry ${retryCount}/${maxRetries - 1}: Re-checking missing dependencies...`, 'cyan');
|
|
|
|
|
+ } else {
|
|
|
|
|
+ log(`[X] Missing ${currentMissing.length} package(s) out of ${Object.keys(allDependencies).length}`, 'red');
|
|
|
|
|
+ log('Missing dependencies:', 'yellow');
|
|
|
|
|
+ currentMissing.forEach(missing => {
|
|
|
|
|
+ log(` - ${missing}`, 'red');
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
log('\nInstalling missing dependencies...', 'yellow');
|
|
log('\nInstalling missing dependencies...', 'yellow');
|
|
|
|
|
|
|
|
- try {
|
|
|
|
|
- // 切换到项目根目录
|
|
|
|
|
- process.chdir(projectRoot);
|
|
|
|
|
- // 执行 npm install,隐藏输出
|
|
|
|
|
|
|
+ // Switch to project root directory
|
|
|
|
|
+ process.chdir(projectRoot);
|
|
|
|
|
+
|
|
|
|
|
+ // Try multiple npm registries in order
|
|
|
|
|
+ const registries = [
|
|
|
|
|
+ { name: 'Tencent Cloud', url: 'https://mirrors.cloud.tencent.com/npm/' },
|
|
|
|
|
+ { name: 'Huawei Cloud', url: 'https://repo.huaweicloud.com/repository/npm/' },
|
|
|
|
|
+ { name: 'Taobao Mirror', url: 'https://registry.npmmirror.com' }
|
|
|
|
|
+ ];
|
|
|
|
|
+
|
|
|
|
|
+ let installSuccess = false;
|
|
|
|
|
+ for (const registry of registries) {
|
|
|
|
|
+ log(`\nTrying ${registry.name} registry...`, 'cyan');
|
|
|
|
|
+ execSync(`npm config set registry ${registry.url}`, {
|
|
|
|
|
+ stdio: 'inherit',
|
|
|
|
|
+ cwd: projectRoot
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ // Run npm install with output visible
|
|
|
|
|
+ const installResult = execSync('npm install', {
|
|
|
|
|
+ stdio: 'inherit',
|
|
|
|
|
+ cwd: projectRoot,
|
|
|
|
|
+ encoding: 'utf-8'
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ // Check if installation was successful by re-checking packages
|
|
|
|
|
+ const installedPackagesSetAfterInstall = getInstalledPackagesFromFilesystem();
|
|
|
|
|
+ const stillMissing = [];
|
|
|
|
|
+ for (const depName of depNames) {
|
|
|
|
|
+ const depNameLower = depName.toLowerCase();
|
|
|
|
|
+ if (!installedPackagesSetAfterInstall.has(depNameLower)) {
|
|
|
|
|
+ stillMissing.push(depName);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (stillMissing.length === 0) {
|
|
|
|
|
+ installSuccess = true;
|
|
|
|
|
+ log(`\n[OK] Installation successful using ${registry.name} registry`, 'green');
|
|
|
|
|
+ break;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ log(`\n[~] ${stillMissing.length} package(s) still missing, trying next registry...`, 'yellow');
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (!installSuccess) {
|
|
|
|
|
+ // Final attempt with original registry
|
|
|
|
|
+ log('\nTrying default npm registry...', 'cyan');
|
|
|
|
|
+ execSync('npm config set registry https://registry.npmjs.org/', {
|
|
|
|
|
+ stdio: 'inherit',
|
|
|
|
|
+ cwd: projectRoot
|
|
|
|
|
+ });
|
|
|
execSync('npm install', {
|
|
execSync('npm install', {
|
|
|
- stdio: 'ignore',
|
|
|
|
|
|
|
+ stdio: 'inherit',
|
|
|
cwd: projectRoot
|
|
cwd: projectRoot
|
|
|
});
|
|
});
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // Re-check installed packages after installation
|
|
|
|
|
+ log('\nRe-checking installed packages...', 'cyan');
|
|
|
|
|
+ const installedPackagesSetAfterInstall = getInstalledPackagesFromFilesystem();
|
|
|
|
|
+ const stillMissing = [];
|
|
|
|
|
+
|
|
|
|
|
+ for (const depName of depNames) {
|
|
|
|
|
+ const depNameLower = depName.toLowerCase();
|
|
|
|
|
+ if (!installedPackagesSetAfterInstall.has(depNameLower)) {
|
|
|
|
|
+ stillMissing.push(depName);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (stillMissing.length === 0) {
|
|
|
log('[OK] All dependencies installed successfully', 'green');
|
|
log('[OK] All dependencies installed successfully', 'green');
|
|
|
- } catch (error) {
|
|
|
|
|
- log('[X] Dependency installation failed', 'red');
|
|
|
|
|
- process.exit(1);
|
|
|
|
|
|
|
+ currentMissing = [];
|
|
|
|
|
+ break;
|
|
|
|
|
+ } else if (stillMissing.length < currentMissing.length) {
|
|
|
|
|
+ log(`[~] Progress: ${currentMissing.length - stillMissing.length} package(s) installed, ${stillMissing.length} remaining`, 'yellow');
|
|
|
|
|
+ currentMissing = stillMissing;
|
|
|
|
|
+ retryCount++;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ log(`[X] Still missing ${stillMissing.length} package(s)`, 'red');
|
|
|
|
|
+ stillMissing.forEach(missing => {
|
|
|
|
|
+ log(` - ${missing}`, 'red');
|
|
|
|
|
+ });
|
|
|
|
|
+ retryCount++;
|
|
|
|
|
+ currentMissing = stillMissing;
|
|
|
}
|
|
}
|
|
|
-} else {
|
|
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+if (currentMissing.length > 0) {
|
|
|
|
|
+ log(`\n[X] Failed to install ${currentMissing.length} package(s) after ${retryCount} attempts:`, 'red');
|
|
|
|
|
+ currentMissing.forEach(missing => {
|
|
|
|
|
+ log(` - ${missing}`, 'red');
|
|
|
|
|
+ });
|
|
|
|
|
+ log('\n[WARN] Some packages may require additional setup', 'yellow');
|
|
|
|
|
+ process.exit(1);
|
|
|
|
|
+} else if (missingCount === 0) {
|
|
|
log(`[OK] All dependencies are installed (${Object.keys(allDependencies).length} packages)`, 'green');
|
|
log(`[OK] All dependencies are installed (${Object.keys(allDependencies).length} packages)`, 'green');
|
|
|
}
|
|
}
|
|
|
|
|
|