codeplay-common 4.9.2 → 4.9.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -4258,6 +4258,103 @@ function patchFile() {
|
|
|
4258
4258
|
|
|
4259
4259
|
//################################## SystemBars.java update for "@capacitor/android": "^8.3.0" plugin END ###############################
|
|
4260
4260
|
|
|
4261
|
+
// Android build optimization START
|
|
4262
|
+
function findAndroidBuildBlock(content, name) {
|
|
4263
|
+
// Mask comments and strings without changing offsets or line endings.
|
|
4264
|
+
const masked = content.replace(/\/\*[\s\S]*?\*\/|\/\/[^\r\n]*|"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'/g,
|
|
4265
|
+
value => value.replace(/[^\r\n]/g, ' '));
|
|
4266
|
+
const header = new RegExp(`\\b${name}\\s*\\{`, 'g');
|
|
4267
|
+
let depth = 0;
|
|
4268
|
+
for (let index = 0; index < masked.length; index += 1) {
|
|
4269
|
+
if (depth === 0) {
|
|
4270
|
+
header.lastIndex = index;
|
|
4271
|
+
const match = header.exec(masked);
|
|
4272
|
+
if (match && match.index === index) {
|
|
4273
|
+
const start = header.lastIndex;
|
|
4274
|
+
let blockDepth = 1;
|
|
4275
|
+
for (let end = start; end < masked.length; end += 1) {
|
|
4276
|
+
if (masked[end] === '{') blockDepth += 1;
|
|
4277
|
+
if (masked[end] === '}' && --blockDepth === 0) return { start, end };
|
|
4278
|
+
}
|
|
4279
|
+
throw new Error(`Unclosed Android Gradle ${name} block.`);
|
|
4280
|
+
}
|
|
4281
|
+
}
|
|
4282
|
+
if (masked[index] === '{') depth += 1;
|
|
4283
|
+
if (masked[index] === '}') depth -= 1;
|
|
4284
|
+
}
|
|
4285
|
+
return null;
|
|
4286
|
+
}
|
|
4287
|
+
|
|
4288
|
+
function syncAndroidBuildOptimization() {
|
|
4289
|
+
if (buildPlatform !== 'android' || !fs.existsSync(androidAppBuildGradlePath)) return;
|
|
4290
|
+
|
|
4291
|
+
const original = fs.readFileSync(androidAppBuildGradlePath, 'utf8');
|
|
4292
|
+
const newline = original.includes('\r\n') ? '\r\n' : '\n';
|
|
4293
|
+
const androidBlock = findAndroidBuildBlock(original, 'android');
|
|
4294
|
+
if (!androidBlock) throw new Error('Android Gradle android block was not found.');
|
|
4295
|
+
let androidContent = original.slice(androidBlock.start, androidBlock.end);
|
|
4296
|
+
const buildTypesBlock = findAndroidBuildBlock(androidContent, 'buildTypes');
|
|
4297
|
+
if (!buildTypesBlock) throw new Error('Android Gradle buildTypes block was not found.');
|
|
4298
|
+
let buildTypesContent = androidContent.slice(buildTypesBlock.start, buildTypesBlock.end);
|
|
4299
|
+
|
|
4300
|
+
// Match the existing finalrelease compatibility exception for this native plugin.
|
|
4301
|
+
const ffmpegPluginXml = path.join(process.cwd(), 'node_modules', 'codeplay-fmpg', 'plugin.xml');
|
|
4302
|
+
const optimizeRelease = !(fs.existsSync(ffmpegPluginXml)
|
|
4303
|
+
&& /<plugin\b/.test(fs.readFileSync(ffmpegPluginXml, 'utf8')));
|
|
4304
|
+
|
|
4305
|
+
for (const name of ['debug', 'release']) {
|
|
4306
|
+
const enabled = name === 'debug' || optimizeRelease;
|
|
4307
|
+
const block = findAndroidBuildBlock(buildTypesContent, name);
|
|
4308
|
+
const blockComments = buildTypesContent.match(/\/\*[\s\S]*?\*\/|\/\/[^\r\n]*|"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'/g) || [];
|
|
4309
|
+
if (!block && blockComments.some(comment => (comment.startsWith('//') || comment.startsWith('/*'))
|
|
4310
|
+
&& new RegExp(`\\b${name}\\s*\\{`).test(comment))) continue;
|
|
4311
|
+
let body = block ? buildTypesContent.slice(block.start, block.end) : `${newline} `;
|
|
4312
|
+
const comments = (body.match(/\/\*[\s\S]*?\*\/|\/\/[^\r\n]*|"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'/g) || [])
|
|
4313
|
+
.filter(value => value.startsWith('//') || value.startsWith('/*'));
|
|
4314
|
+
for (const setting of ['minifyEnabled', 'shrinkResources']) {
|
|
4315
|
+
const masked = body.replace(/\/\*[\s\S]*?\*\/|\/\/[^\r\n]*|"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'/g,
|
|
4316
|
+
value => value.replace(/[^\r\n]/g, ' '));
|
|
4317
|
+
const settingPattern = new RegExp(`\\b${setting}\\b`);
|
|
4318
|
+
// Existing values, expressions and commented opt-outs take precedence.
|
|
4319
|
+
if (settingPattern.test(masked) || comments.some(comment => settingPattern.test(comment))) continue;
|
|
4320
|
+
const value = setting === 'shrinkResources'
|
|
4321
|
+
? enabled && /\bminifyEnabled\s*(?:=\s*)?true\b/.test(masked)
|
|
4322
|
+
: enabled;
|
|
4323
|
+
body = `${newline} ${setting} ${value}${body}`;
|
|
4324
|
+
}
|
|
4325
|
+
const activeBody = body.replace(/\/\*[\s\S]*?\*\/|\/\/[^\r\n]*|"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'/g,
|
|
4326
|
+
value => value.startsWith('//') || value.startsWith('/*') ? value.replace(/[^\r\n]/g, ' ') : value);
|
|
4327
|
+
const defaultRules = [...activeBody.matchAll(/getDefaultProguardFile\(\s*(['"])proguard-android\.txt\1\s*\)/g)];
|
|
4328
|
+
for (const match of defaultRules.reverse()) {
|
|
4329
|
+
body = body.slice(0, match.index) + "getDefaultProguardFile('proguard-android-optimize.txt')"
|
|
4330
|
+
+ body.slice(match.index + match[0].length);
|
|
4331
|
+
}
|
|
4332
|
+
if (!/\bproguardFiles\b/.test(activeBody)
|
|
4333
|
+
&& !comments.some(comment => /\bproguardFiles\b/.test(comment))) {
|
|
4334
|
+
body = `${newline} proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'${body}`;
|
|
4335
|
+
}
|
|
4336
|
+
buildTypesContent = block
|
|
4337
|
+
? buildTypesContent.slice(0, block.start) + body + buildTypesContent.slice(block.end)
|
|
4338
|
+
: `${buildTypesContent.trimEnd()}${newline} ${name} {${body}}${newline} `;
|
|
4339
|
+
}
|
|
4340
|
+
|
|
4341
|
+
androidContent = androidContent.slice(0, buildTypesBlock.start) + buildTypesContent
|
|
4342
|
+
+ androidContent.slice(buildTypesBlock.end);
|
|
4343
|
+
const next = original.slice(0, androidBlock.start) + androidContent + original.slice(androidBlock.end);
|
|
4344
|
+
if (next !== original) fs.writeFileSync(androidAppBuildGradlePath, next, 'utf8');
|
|
4345
|
+
|
|
4346
|
+
const propertiesPath = path.join(androidPlatformPath, 'gradle.properties');
|
|
4347
|
+
const properties = fs.existsSync(propertiesPath) ? fs.readFileSync(propertiesPath, 'utf8') : '';
|
|
4348
|
+
const property = 'android.r8.optimizedResourceShrinking=true';
|
|
4349
|
+
const propertyPattern = /^[ \t]*[#!]?[ \t]*android\.r8\.optimizedResourceShrinking(?:[ \t]*[=:]|[ \t]+|[ \t]*$)/m;
|
|
4350
|
+
const nextProperties = propertyPattern.test(properties)
|
|
4351
|
+
? properties
|
|
4352
|
+
: `${properties.trimEnd()}${newline}${property}${newline}`;
|
|
4353
|
+
if (nextProperties !== properties) fs.writeFileSync(propertiesPath, nextProperties, 'utf8');
|
|
4354
|
+
console.log('✅ Android build optimization defaults checked; existing settings and commented opt-outs preserved.');
|
|
4355
|
+
}
|
|
4356
|
+
// Android build optimization END
|
|
4357
|
+
|
|
4261
4358
|
async function main() {
|
|
4262
4359
|
validateThemeFolderLocation();
|
|
4263
4360
|
validateAndRestoreSignDetails();
|
|
@@ -4276,6 +4373,7 @@ async function main() {
|
|
|
4276
4373
|
checkAndupdateDropInViteConfig();
|
|
4277
4374
|
checkAdmobConfigurationProperty();
|
|
4278
4375
|
syncAndroidAdIdPermission();
|
|
4376
|
+
syncAndroidBuildOptimization();
|
|
4279
4377
|
}
|
|
4280
4378
|
|
|
4281
4379
|
await main();
|
|
@@ -4291,6 +4389,8 @@ await main();
|
|
|
4291
4389
|
Release Notes
|
|
4292
4390
|
|
|
4293
4391
|
6.5
|
|
4392
|
+
Enable debug/release optimization and optimized resource shrinking before Android builds.
|
|
4393
|
+
Preserve existing values and commented opt-outs without adding duplicate settings.
|
|
4294
4394
|
Kids ad configuration disables iOS ATT prompts and excludes Android AD_ID during builds.
|
|
4295
4395
|
Non-kids apps retain tracking prompts and normal permission behavior.
|
|
4296
4396
|
Ad configuration migration preserves newer local configuration versions.
|