const fs = require('fs'); const fsp = fs.promises; const path = require('path'); const { exec } = require('child_process'); const { promisify } = require('util'); const execAsync = promisify(exec); /** * 使用系统命令创建ZIP(跨平台) * @param {string} sourceDir - 要压缩的目录路径 * @param {string} outputDir - 压缩文件输出目录 * @returns {Promise} - 压缩文件的路径 */ async function createZipWithSystemCommand(sourceDir, outputDir) { // 检查源目录 if (!fs.existsSync(sourceDir)) { throw new Error(`源目录不存在: ${sourceDir}`); } // 获取当前 Git 提交 ID(短 hash) let commitId = 'unknown'; try { const { stdout } = await execAsync('git rev-parse --short HEAD', { cwd: path.join(__dirname, '..') }); commitId = stdout.trim(); } catch (e) { console.warn('无法获取 Git 提交 ID,使用 unknown 代替'); } // 生成文件名:mp-weixin-<日期时间>-<提交ID>.zip const now = new Date(); const dateString = `${now.getFullYear()}${String(now.getMonth()+1).padStart(2,'0')}${String(now.getDate()).padStart(2,'0')}-${String(now.getHours()).padStart(2,'0')}${String(now.getMinutes()).padStart(2,'0')}${String(now.getSeconds()).padStart(2,'0')}`; const zipFileName = `mp-weixin-${dateString}-${commitId}.zip`; const zipFilePath = path.join(outputDir, zipFileName); let command; // 根据操作系统选择命令 if (process.platform === 'win32') { // Windows: 使用PowerShell的Compress-Archive const sourcePath = sourceDir.replace(/'/g, "''"); const destPath = zipFilePath.replace(/'/g, "''"); command = `powershell -Command "Compress-Archive -Path '${sourcePath}\\*' -DestinationPath '${destPath}' -Force"`; } else { // Linux/Mac: 使用zip命令 const sourceBase = path.dirname(sourceDir); const sourceName = path.basename(sourceDir); command = `cd '${sourceBase}' && zip -r '${zipFilePath}' '${sourceName}' -x '*/node_modules/*' '*.git/*' '*.DS_Store' '*.log'`; } try { console.log(`执行命令: ${command}`); const { stdout, stderr } = await execAsync(command); if (stderr) { console.warn('警告:', stderr); } console.log(`✅ ZIP文件创建完成: ${zipFileName}`); return zipFilePath; } catch (error) { throw new Error(`系统命令执行失败: ${error.message}`); } } module.exports = { createZipWithSystemCommand }