"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const fs_1 = __importDefault(require("fs")); const path_1 = __importDefault(require("path")); const FileUtils_1 = __importDefault(require("../utils/FileUtils")); const MD5Utils_1 = __importDefault(require("../utils/MD5Utils")); const PackageScript_1 = require("./PackageScript"); const START_VERSION = 1000; const VERSION_SUPPORT = 50; function readExistPackageRecords(versionCacheDir) { const versions = []; const versionFiles = fs_1.default.readdirSync(versionCacheDir); versionFiles.forEach(versionFile => { const versionFilePath = path_1.default.join(versionCacheDir, versionFile); const stat = fs_1.default.statSync(versionFilePath); if (stat.isDirectory()) return; const versionString = path_1.default.basename(versionFile, path_1.default.extname(versionFile)); const version = parseInt(versionString); versions.push(version); }); return versions.sort((a, b) => a - b).slice(-VERSION_SUPPORT); } function readPackageRecord(version, versionCacheDir) { const infoFilePath = path_1.default.join(versionCacheDir, `${version}.json`); if (!fs_1.default.existsSync(infoFilePath)) return null; const subpackageInfoContent = fs_1.default.readFileSync(infoFilePath); const info = JSON.parse(subpackageInfoContent.toString()); return info; } function writePackageRecord(version, record, versionCacheDir) { const content = JSON.stringify(record); const infoFilePath = path_1.default.join(versionCacheDir, `${version}.json`); FileUtils_1.default.mkdir(path_1.default.dirname(infoFilePath)); fs_1.default.writeFileSync(infoFilePath, content); } function loadMainConfig(url) { const configCache = path_1.default.join(process.env.HOME || process.env.USERPROFILE, '.sgp', 'config', `${MD5Utils_1.default.md5(url)}`, `subgame_config.json`); if (fs_1.default.existsSync(configCache)) { const mainConfig = JSON.parse(fs_1.default.readFileSync(configCache).toString()); return mainConfig; } return []; } function loadPackageConfig(url, key) { const configCache = path_1.default.join(process.env.HOME || process.env.USERPROFILE, '.sgp', 'config', `${MD5Utils_1.default.md5(url)}`, `subgame_config_${key}.json`); if (fs_1.default.existsSync(configCache)) { const packageConfig = JSON.parse(fs_1.default.readFileSync(configCache).toString()); return packageConfig; } return null; } function writeMainConfig(url, mainConfigs) { const configCacheDir = path_1.default.join(process.env.HOME || process.env.USERPROFILE, '.sgp', 'config', `${MD5Utils_1.default.md5(url)}`); FileUtils_1.default.mkdir(configCacheDir); fs_1.default.writeFileSync(path_1.default.join(configCacheDir, `subgame_config.json`), JSON.stringify(mainConfigs)); } function writePackageConfig(url, key, packageConfig) { const configCacheDir = path_1.default.join(process.env.HOME || process.env.USERPROFILE, '.sgp', 'config', `${MD5Utils_1.default.md5(url)}`); FileUtils_1.default.mkdir(configCacheDir); fs_1.default.writeFileSync(path_1.default.join(configCacheDir, `subgame_config_${key}.json`), JSON.stringify(packageConfig)); } function PackageAndroid(projectDir, key, frameworkVersion, mode, url, xxtea, zipCompressJs, isolate = false) { return __awaiter(this, void 0, void 0, function* () { console.log(`-----------------------------------------------------Handle package [${key}] start-----------------------------------------------------`); const outputDir = path_1.default.join(projectDir, 'build', 'subgame', 'android'); console.log(`Make package [${key}] zip dir: ${outputDir}`); FileUtils_1.default.mkdir(outputDir); const versionCacheDir = path_1.default.join(projectDir, 'version', key, mode); console.log(`Make package [${key}] info dir: ${versionCacheDir}`); FileUtils_1.default.mkdir(versionCacheDir); const buildDir = path_1.default.join(projectDir, 'build', 'jsb-default'); const bundleDir = path_1.default.join(buildDir, 'assets', key); (0, PackageScript_1.PackageScript)(key, buildDir, isolate, xxtea, zipCompressJs); const mainConfigs = loadMainConfig(url); if (!mainConfigs) throw new Error(`load main config fail`); const existVersions = readExistPackageRecords(versionCacheDir); const haveExistVersion = existVersions && existVersions.length; const config = loadPackageConfig(url, key) || { version: START_VERSION, packages: [] }; const previousVersion = config.version; const previousRecord = haveExistVersion ? readPackageRecord(previousVersion, versionCacheDir) : { md5: [] }; console.log(`Package [${key}] previous version: ${previousVersion}`); const md5 = MD5Utils_1.default.md5Dir(bundleDir, null); const md5Compare = MD5Utils_1.default.md5Compare(md5, previousRecord.md5); console.log(`Package [${key}] compare with last: added=${md5Compare.added.length}, deleted:${md5Compare.deleted.length}, same:${md5Compare.same.length}, changed:${md5Compare.changed.length}`); const packageResult = { project: projectDir, key, frameworkVersion, mode, url, xxtea, zipCompressJs, isolate, packageVersion: previousVersion, supportVersion: existVersions, added: md5Compare.added.length, changed: md5Compare.changed.length, deleted: md5Compare.deleted.length, size: -1 }; if (md5Compare.changed.length || md5Compare.added.length) { console.log(`Package [${key}] changed`); const zipCacheOutputDir = path_1.default.join(outputDir, 'cache'); console.log(`Make package [${key}] zip cache dir: ${zipCacheOutputDir}`); FileUtils_1.default.rm(zipCacheOutputDir); FileUtils_1.default.mkdir(zipCacheOutputDir); const packages = []; const newVersion = previousVersion + 1; for (const versionItem of existVersions) { console.log(`Pick package [${key}] assets for version ${versionItem} to ${newVersion}`); const versionInfo = readPackageRecord(versionItem, versionCacheDir); if (!versionInfo) { console.warn(`ackage [${key}] skip exits version ${versionItem}, no version info.`); continue; } const versionCompareResult = MD5Utils_1.default.md5Compare(md5, versionInfo.md5); console.log(`Package [${key}] compare with version ${versionItem}: added=${versionCompareResult.added.length}, deleted:${versionCompareResult.deleted.length} , same:${versionCompareResult.same.length}, changed:${versionCompareResult.changed.length}`); const files = versionCompareResult.changed.concat(versionCompareResult.added); const zipCacheDir = path_1.default.join(zipCacheOutputDir, `${versionItem}_${newVersion}`); FileUtils_1.default.mkdir(zipCacheDir); files.forEach(value => { const outPath = path_1.default.join(zipCacheDir, value.path); FileUtils_1.default.mkdir(path_1.default.dirname(outPath)); fs_1.default.copyFileSync(path_1.default.join(bundleDir, value.path), outPath); }); const zipOutFile = path_1.default.join(outputDir, `${key}_${versionItem}_${newVersion}.zip`); const fileCount = FileUtils_1.default.fileCount(zipCacheDir, true); yield FileUtils_1.default.zipdir(zipCacheDir, zipOutFile); FileUtils_1.default.rm(zipCacheDir); const zipStat = fs_1.default.statSync(zipOutFile); const zipMD5 = MD5Utils_1.default.md5Dir(zipOutFile)[0].md5; packages.push({ version: versionItem, size: zipStat.size, files: fileCount, md5: zipMD5 }); } FileUtils_1.default.rm(zipCacheOutputDir); const zipOutFile = path_1.default.join(outputDir, `${key}_${newVersion}.zip`); const fileCount = FileUtils_1.default.fileCount(bundleDir, true); yield FileUtils_1.default.zipdir(bundleDir, zipOutFile); const zipStat = fs_1.default.statSync(zipOutFile); const zipMD5 = MD5Utils_1.default.md5Dir(zipOutFile)[0].md5; packages.push({ version: 0, size: zipStat.size, files: fileCount, md5: zipMD5 }); writePackageRecord(newVersion, { md5 }, versionCacheDir); const mainConfig = mainConfigs.find(value => value.key === key); if (mainConfig) { mainConfig.version = newVersion; mainConfig.supports = existVersions; } else { mainConfigs.push({ key, version: newVersion, supports: existVersions }); } writeMainConfig(url, mainConfigs); config.version = newVersion; config.packages = packages; writePackageConfig(url, key, config); packageResult.packageVersion = newVersion; packageResult.size = zipStat.size; console.log(`Package [${key}] build finished`); } else if (md5Compare.deleted.length) { console.log(`Package [${key}] no changes (but delete)`); } else { console.log(`Package [${key}] no changes`); } console.log(`save package [${key}] config`); const configFileName = `subgame_config_${key}_${frameworkVersion}.json`; const configFilePath = path_1.default.join(outputDir, configFileName); fs_1.default.writeFileSync(configFilePath, JSON.stringify(config)); console.log(`save main config`); fs_1.default.writeFileSync(path_1.default.join(outputDir, `subgame_config_${frameworkVersion}.json`), JSON.stringify(mainConfigs)); FileUtils_1.default.rm(bundleDir); console.log(`Package [${key}] build result: \n ${JSON.stringify(packageResult)}`); console.log(`-----------------------------------------------------Handle package [${key}] end-------------------------------------------------------\n\n`); return packageResult; }); } exports.default = PackageAndroid;