From 3c452cfbd3482f9995db7359cee38552351b0b69 Mon Sep 17 00:00:00 2001 From: lafay <2021211506@stu.hit.edu.cn> Date: Thu, 18 Jun 2026 13:22:15 +0800 Subject: [PATCH] fix(push): add allprojects.repositories for runtime dependency resolution Ensure Honor and Huawei Maven repos are added to both buildscript.repositories and allprojects.repositories in root build.gradle. Runtime dependencies like com.hihonor.mcs:push and com.huawei.hms:push are resolved via allprojects, not buildscript. Also consolidate all build.gradle modifications to use withDangerousMod directly, avoiding silent hook drops in Expo SDK 56+. --- plugins/withHonorPush.js | 76 ++++++++++++++++++++++++--------------- plugins/withHuaweiPush.js | 37 +++++++++++++++++++ 2 files changed, 85 insertions(+), 28 deletions(-) diff --git a/plugins/withHonorPush.js b/plugins/withHonorPush.js index d5b6501..c443884 100644 --- a/plugins/withHonorPush.js +++ b/plugins/withHonorPush.js @@ -1,5 +1,4 @@ const { - withProjectBuildGradle, withSettingsGradle, withDangerousMod, } = require('@expo/config-plugins'); @@ -11,14 +10,14 @@ const path = require('path'); // 客户端职责(依据极光官方文档 https://docs.jiguang.cn/jpush/client/Android/android_3rd_guide): // 1) 添加 cn.jiguang.sdk.plugin:honor 依赖 // 2) 注入 manifestPlaceholders: HONOR_APPID -// 3) 添加荣耀 Maven 仓库 https://developer.hihonor.com/repo (v5.9.0+ 必需) +// 3) 添加荣耀 Maven 仓库 https://developer.hihonor.com/repo 到 settings.gradle 和根 build.gradle +// 注意: 必须加到根 build.gradle 的 allprojects.repositories,因为 honor:6.1.0 的传递依赖 +// com.hihonor.mcs:push 是运行时依赖(通过 allprojects 解析,不走 buildscript)。 // 4) 添加 Proguard 规则 (com.hihonor.push.** 保留 + 5 条 -keepattributes) // -// 实现说明:app/build.gradle 改动用 withDangerousMod 直接读写磁盘文件。 -// 原因:Expo SDK 56+ 的 withAppBuildGradle hook 链中,第二个以后的 plugin 写回 -// modResults.contents 会被静默忽略,导致多个 vendor plugin 只能写入第一个的修改。 -// 仓库(settings.gradle / build.gradle)改动用 withProjectBuildGradle / withSettingsGradle -// 没有这个问题。 +// 实现说明:build.gradle 改动统一用 withDangerousMod 直接读写磁盘文件。 +// 原因:Expo SDK 56+ 的 withProjectBuildGradle / withAppBuildGradle hook 链中,第二个以后的 +// plugin 写回 modResults.contents 会被静默忽略,导致多个 vendor plugin 只能写入第一个的修改。 const withHonorPush = (config, options = {}) => { const { jpushVersion = '6.1.0', @@ -70,28 +69,14 @@ const withHonorPush = (config, options = {}) => { return config; }); - // 2. 根 build.gradle: 添加荣耀 Maven 仓库到 buildscript.repositories - config = withProjectBuildGradle(config, (config) => { - let contents = config.modResults.contents; - - if (!contents.includes('developer.hihonor.com/repo')) { - const bsRepoPattern = /(buildscript\s*\{[\s\S]*?repositories\s*\{)/; - if (bsRepoPattern.test(contents)) { - contents = contents.replace( - bsRepoPattern, - `$1\n maven { url '${honorRepoUrl}' }` - ); - } - } - - config.modResults.contents = contents; - return config; - }); - - // 3. app/build.gradle: 注入 AAR 依赖 + manifestPlaceholders (用 withDangerousMod 直接读文件) + // 2. 根 build.gradle: 添加荣耀 Maven 仓库到 buildscript + allprojects (用 withDangerousMod 直接改文件) config = withDangerousMod(config, [ 'android', async (config) => { + const rootBuildGradlePath = path.join( + config.modRequest.platformProjectRoot, + 'build.gradle' + ); const appBuildGradlePath = path.join( config.modRequest.platformProjectRoot, 'app', @@ -103,7 +88,42 @@ const withHonorPush = (config, options = {}) => { 'proguard-rules.pro' ); - // --- 3a. 处理 build.gradle --- + // --- 2a. 根 build.gradle: 仓库注入 --- + if (fs.existsSync(rootBuildGradlePath)) { + let gradle = fs.readFileSync(rootBuildGradlePath, 'utf-8'); + let changed = false; + const repoLine = ` maven { url '${honorRepoUrl}' }`; + + // 注入到 buildscript.repositories(用于解析 buildscript classpath) + if (!gradle.match(/buildscript\s*\{[\s\S]*?developer\.hihonor\.com\/repo/)) { + const bsRepoPattern = /(buildscript\s*\{[\s\S]*?repositories\s*\{)/; + if (bsRepoPattern.test(gradle)) { + gradle = gradle.replace(bsRepoPattern, `$1\n${repoLine}`); + changed = true; + } + } + + // 注入到 allprojects.repositories(用于解析运行时依赖如 com.hihonor.mcs:push) + if (!gradle.match(/allprojects\s*\{[\s\S]*?developer\.hihonor\.com\/repo/)) { + const allProjectsPattern = /(allprojects\s*\{[\s\S]*?repositories\s*\{)/; + if (allProjectsPattern.test(gradle)) { + gradle = gradle.replace(allProjectsPattern, `$1\n${repoLine}`); + changed = true; + } else { + // 没有 allprojects 块时新建 + const allProjectsBlock = `\nallprojects {\n repositories {${repoLine}\n }\n}\n`; + gradle = gradle + allProjectsBlock; + changed = true; + } + } + + if (changed) { + fs.writeFileSync(rootBuildGradlePath, gradle); + console.log('[withHonorPush] updated root build.gradle (buildscript + allprojects repos)'); + } + } + + // --- 2b. app/build.gradle: AAR 依赖 + manifestPlaceholders --- if (fs.existsSync(appBuildGradlePath)) { let gradle = fs.readFileSync(appBuildGradlePath, 'utf-8'); let changed = false; @@ -176,7 +196,7 @@ const withHonorPush = (config, options = {}) => { } } - // --- 3b. 处理 proguard-rules.pro --- + // --- 2c. proguard-rules.pro --- if (fs.existsSync(proguardFilePath)) { let proguard = fs.readFileSync(proguardFilePath, 'utf-8'); if (!proguard.includes('-keep class com.hihonor.push.**')) { diff --git a/plugins/withHuaweiPush.js b/plugins/withHuaweiPush.js index 27d729c..367389e 100644 --- a/plugins/withHuaweiPush.js +++ b/plugins/withHuaweiPush.js @@ -179,6 +179,43 @@ const withHuaweiPush = (config, options = {}) => { config = withDangerousMod(config, [ 'android', async (config) => { + // Ensure Huawei Maven repo is in allprojects.repositories (not just buildscript). + // Runtime dependencies like com.huawei.hms:push must be resolved via allprojects, + // and the earlier withProjectBuildGradle hook may be silently dropped in Expo SDK 56+. + const rootBuildGradlePath = path.join(config.modRequest.platformProjectRoot, 'build.gradle'); + if (fs.existsSync(rootBuildGradlePath)) { + let rootGradle = fs.readFileSync(rootBuildGradlePath, 'utf-8'); + const huaweiRepoLine = ` maven { url 'https://developer.huawei.com/repo/' }`; + let rootChanged = false; + + // buildscript.repositories + if (!rootGradle.match(/buildscript\s*\{[\s\S]*?developer\.huawei\.com\/repo/)) { + const bsPattern = /(buildscript\s*\{[\s\S]*?repositories\s*\{)/; + if (bsPattern.test(rootGradle)) { + rootGradle = rootGradle.replace(bsPattern, `$1\n${huaweiRepoLine}`); + rootChanged = true; + } + } + + // allprojects.repositories (runtime deps resolution) + if (!rootGradle.match(/allprojects\s*\{[\s\S]*?developer\.huawei\.com\/repo/)) { + const allProjectsPattern = /(allprojects\s*\{[\s\S]*?repositories\s*\{)/; + if (allProjectsPattern.test(rootGradle)) { + rootGradle = rootGradle.replace(allProjectsPattern, `$1\n${huaweiRepoLine}`); + rootChanged = true; + } else { + const allProjectsBlock = `\nallprojects {\n repositories {${huaweiRepoLine}\n }\n}\n`; + rootGradle = rootGradle + allProjectsBlock; + rootChanged = true; + } + } + + if (rootChanged) { + fs.writeFileSync(rootBuildGradlePath, rootGradle); + console.log('[withHuaweiPush] ensured Huawei Maven repo in buildscript + allprojects'); + } + } + const appDir = path.join(config.modRequest.platformProjectRoot, 'app'); const srcFile = path.join(config.modRequest.projectRoot, 'plugins', 'agconnect-services.json'); const destFile = path.join(appDir, 'agconnect-services.json');