Class: Pindo::GradleHelper
- Inherits:
-
Object
- Object
- Pindo::GradleHelper
- Defined in:
- lib/pindo/module/android/gradle_helper.rb
Constant Summary collapse
- GRADLE_CACHE_DIR =
Gradle缓存目录
File.("~/.pindo/android_tools/gradle-cache")
- GRADLE_PLUGIN_VERSION_MAP =
Gradle 插件版本映射表(AGP版本映射)仅升级旧版本到 4.2.2,不降级新版本
{ # 旧版本升级到 4.2.2 '3.4.0' => '4.2.2', '3.4.1' => '4.2.2', '3.5.0' => '4.2.2', '3.5.1' => '4.2.2', '3.6.0' => '4.2.2', '3.6.1' => '4.2.2', '4.0.0' => '4.2.2', '4.0.1' => '4.2.2', '4.1.0' => '4.2.2', '4.2.0' => '4.2.2', '4.2.1' => '4.2.2', '4.2.2' => '4.2.2' # 保持当前版本 }
Class Method Summary collapse
-
.check_gradle_with_project(project_path, configure_main: false) ⇒ Object
核心功能 ===================.
-
.ensure_gradlew_runnable!(gradle_dir) ⇒ Object
确保工程根目录下 gradlew 可被当前环境执行:补齐执行位;在 macOS 上尝试移除 com.apple.quarantine(无该属性时 xattr 失败可忽略)。用于避免 「bad interpreter: Operation not permitted」类错误,无用户交互。.
-
.extract_gradle_version(properties_path) ⇒ Object
提取 gradle 版本(parse_gradle_version 的别名).
-
.get_gradle_paths(project_path) ⇒ Hash
获取项目的 Gradle 配置路径(统一管理三种工程结构的路径).
-
.parse_gradle_version(properties_path) ⇒ Object
解析gradle版本.
-
.setup_gradle_wrapper(gradle_dir, wrapper_properties_path) ⇒ Object
设置 Gradle Wrapper(简化后的核心函数).
-
.setup_gradle_wrapper_with_version(gradle_dir, wrapper_properties_path, gradle_version) ⇒ Object
使用指定版本设置 Gradle Wrapper.
- .update_build_gradle(project_path) ⇒ Object
-
.update_launcher_build_gradle(project_dir, pack_modules) ⇒ Object
更新 launcher/build.gradle 文件,添加 assetPacks 配置.
-
.update_settings_gradle(project_dir, pack_modules) ⇒ Object
更新 settings.gradle 文件,注册 asset pack 模块.
Class Method Details
.check_gradle_with_project(project_path, configure_main: false) ⇒ Object
核心功能 ===================
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 |
# File 'lib/pindo/module/android/gradle_helper.rb', line 84 def check_gradle_with_project(project_path, configure_main: false) Funlog.("检查Gradle Wrapper配置") # 使用统一的路径获取方法 paths = get_gradle_paths(project_path) if paths[:type] == :unity_as_lib if configure_main # 配置主工程的 Gradle(在 SO 编译完成后调用) Funlog.info("配置主工程的Gradle Wrapper用于编译APK...") unless File.exist?(paths[:main_wrapper_properties]) Funlog.("未找到主工程的gradle-wrapper.properties: #{paths[:main_wrapper_properties]}") return false end main_gradle_version = extract_gradle_version(paths[:main_wrapper_properties]) Funlog.info("主工程Gradle版本: #{main_gradle_version}") # 确保主工程的 Gradle 缓存存在 unless ensure_gradle_available(main_gradle_version) Funlog.("无法获取主工程的Gradle #{main_gradle_version}") return false end # 配置主工程的 Gradle Wrapper unless setup_gradle_wrapper(paths[:main_gradle_dir], paths[:main_wrapper_properties]) Funlog.("主工程Gradle Wrapper配置失败") return false end Funlog.("主工程Gradle配置完成,准备编译APK") true else # 配置 Unity 模块的 Gradle(默认行为,在 SO 编译前调用) Funlog.info("检测到 Unity as lib 工程,配置Unity模块的Gradle") # 1. 配置 Unity 模块的 Gradle(7.5.1 + Java 11,用于编译SO库) unless File.exist?(paths[:unity_wrapper_properties]) Funlog.("未找到Unity模块的gradle-wrapper.properties: #{paths[:unity_wrapper_properties]}") return false end unity_gradle_version = extract_gradle_version(paths[:unity_wrapper_properties]) Funlog.info("配置Unity模块的Gradle Wrapper (版本: #{unity_gradle_version})...") unless setup_gradle_wrapper(paths[:unity_gradle_dir], paths[:unity_wrapper_properties]) Funlog.("Unity模块Gradle Wrapper配置失败") return false end # 2. 检查主工程的 Gradle 配置文件是否存在 unless File.exist?(paths[:main_wrapper_properties]) Funlog.("未找到主工程的gradle-wrapper.properties: #{paths[:main_wrapper_properties]}") return false end main_gradle_version = extract_gradle_version(paths[:main_wrapper_properties]) Funlog.info("主工程Gradle配置 (版本: #{main_gradle_version}),待SO编译完成后配置") # 确保主工程的 Gradle 缓存存在 unless ensure_gradle_available(main_gradle_version) Funlog.info("下载主工程所需的Gradle #{main_gradle_version}...") end Funlog.info("Unity模块: Gradle #{unity_gradle_version} + Java 11 (编译SO库)") Funlog.info("主工程: Gradle #{main_gradle_version} + Java 17 (编译APK)") Funlog.("Unity模块Gradle配置完成,准备编译SO库") true end else # Unity standalone 或原生 Android 工程:只配置一个 Gradle unless File.exist?(paths[:wrapper_properties]) Funlog.("未找到gradle-wrapper.properties文件: #{paths[:wrapper_properties]}") return false end if setup_gradle_wrapper(paths[:gradle_dir], paths[:wrapper_properties]) Funlog.("Gradle Wrapper配置成功") true else Funlog.("Gradle Wrapper配置失败") false end end end |
.ensure_gradlew_runnable!(gradle_dir) ⇒ Object
确保工程根目录下 gradlew 可被当前环境执行:补齐执行位;在 macOS 上尝试移除com.apple.quarantine(无该属性时 xattr 失败可忽略)。用于避免「bad interpreter: Operation not permitted」类错误,无用户交互。
257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 |
# File 'lib/pindo/module/android/gradle_helper.rb', line 257 def ensure_gradlew_runnable!(gradle_dir) return if gradle_dir.nil? || gradle_dir.to_s.empty? gradlew = File.join(gradle_dir, "gradlew") return unless File.file?(gradlew) begin st = File.stat(gradlew) File.chmod(st.mode | 0o111, gradlew) rescue StandardError # 只读卷等场景下忽略 end return unless RUBY_PLATFORM.match?(/darwin/i) system("xattr", "-d", "com.apple.quarantine", gradlew, out: File::NULL, err: File::NULL) end |
.extract_gradle_version(properties_path) ⇒ Object
提取 gradle 版本(parse_gradle_version 的别名)
231 232 233 |
# File 'lib/pindo/module/android/gradle_helper.rb', line 231 def extract_gradle_version(properties_path) parse_gradle_version(properties_path) end |
.get_gradle_paths(project_path) ⇒ Hash
获取项目的 Gradle 配置路径(统一管理三种工程结构的路径)
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/pindo/module/android/gradle_helper.rb', line 37 def get_gradle_paths(project_path) paths = {} if Pindo::AndroidProjectHelper.unity_android_project?(project_path) # Unity 独立工程 paths[:type] = :unity_standalone paths[:gradle_dir] = project_path paths[:wrapper_properties] = File.join(project_path, "gradle/wrapper/gradle-wrapper.properties") paths[:build_gradle] = File.join(project_path, "build.gradle") paths[:build_gradle_kts] = File.join(project_path, "build.gradle.kts") elsif Pindo::AndroidProjectHelper.unity_as_lib_android_project?(project_path) # Unity 作为 lib 的原生工程 - 需要处理两套配置 paths[:type] = :unity_as_lib # Unity 模块的路径 paths[:unity_gradle_dir] = File.join(project_path, "Unity") paths[:unity_wrapper_properties] = File.join(project_path, "Unity/gradle/wrapper/gradle-wrapper.properties") paths[:unity_build_gradle] = File.join(project_path, "Unity/build.gradle") paths[:unity_build_gradle_kts] = File.join(project_path, "Unity/build.gradle.kts") # 主工程的路径 paths[:main_gradle_dir] = project_path paths[:main_wrapper_properties] = File.join(project_path, "gradle/wrapper/gradle-wrapper.properties") paths[:main_build_gradle] = File.join(project_path, "build.gradle") paths[:main_build_gradle_kts] = File.join(project_path, "build.gradle.kts") # 保留原有路径以兼容其他代码 paths[:gradle_dir] = paths[:unity_gradle_dir] paths[:wrapper_properties] = paths[:unity_wrapper_properties] paths[:build_gradle] = paths[:unity_build_gradle] paths[:build_gradle_kts] = paths[:unity_build_gradle_kts] else # Android 原生工程 paths[:type] = :native_android paths[:gradle_dir] = project_path paths[:wrapper_properties] = File.join(project_path, "gradle/wrapper/gradle-wrapper.properties") paths[:build_gradle] = File.join(project_path, "build.gradle") paths[:build_gradle_kts] = File.join(project_path, "build.gradle.kts") end paths end |
.parse_gradle_version(properties_path) ⇒ Object
解析gradle版本
214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 |
# File 'lib/pindo/module/android/gradle_helper.rb', line 214 def parse_gradle_version(properties_path) content = File.read(properties_path) # 匹配distributionUrl中的gradle版本 if content =~ /distributionUrl=.*gradle-(\d+\.\d+(?:\.\d+)?(?:-.*)?)-bin\.zip/ return $1 end # 匹配gradleVersion属性 if content =~ /gradleVersion=(\d+\.\d+(?:\.\d+)?(?:-.*)?)/ return $1 end nil end |
.setup_gradle_wrapper(gradle_dir, wrapper_properties_path) ⇒ Object
设置 Gradle Wrapper(简化后的核心函数)
193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 |
# File 'lib/pindo/module/android/gradle_helper.rb', line 193 def setup_gradle_wrapper(gradle_dir, wrapper_properties_path) # 解析gradle版本 gradle_version = parse_gradle_version(wrapper_properties_path) if gradle_version.nil? Funlog.error("无法解析gradle版本") return false end # 下载并设置 Gradle unless ensure_gradle_available(gradle_version) Funlog.error("无法获取 Gradle #{gradle_version}") return false end # 生成 Wrapper ok = generate_gradle_wrapper(gradle_dir, gradle_version) ensure_gradlew_runnable!(gradle_dir) ok end |
.setup_gradle_wrapper_with_version(gradle_dir, wrapper_properties_path, gradle_version) ⇒ Object
使用指定版本设置 Gradle Wrapper
236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 |
# File 'lib/pindo/module/android/gradle_helper.rb', line 236 def setup_gradle_wrapper_with_version(gradle_dir, wrapper_properties_path, gradle_version) if gradle_version.nil? Funlog.error("Gradle版本不能为空") return false end # 下载并设置 Gradle unless ensure_gradle_available(gradle_version) Funlog.error("无法获取 Gradle #{gradle_version}") return false end # 生成 Wrapper ok = generate_gradle_wrapper(gradle_dir, gradle_version) ensure_gradlew_runnable!(gradle_dir) ok end |
.update_build_gradle(project_path) ⇒ Object
171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 |
# File 'lib/pindo/module/android/gradle_helper.rb', line 171 def update_build_gradle(project_path) paths = get_gradle_paths(project_path) if paths[:type] == :unity_as_lib # Unity as lib 工程:只更新 Unity 模块的 build.gradle # 主工程的 AGP 保持原版本(如 8.8.0),因为它使用独立的 Gradle 8.10.2 Funlog.info("检测到 Unity as lib 工程,仅更新Unity模块的AGP版本") # 更新 Unity 模块的 build.gradle(根据映射表更新旧版本) if paths[:unity_build_gradle] || paths[:unity_build_gradle_kts] Funlog.info("更新Unity模块的build.gradle...") update_single_build_gradle(paths[:unity_build_gradle], paths[:unity_build_gradle_kts]) end Funlog.info("Unity模块的AGP版本更新完成(主工程保持原版本)") else # Unity standalone 或原生 Android 工程:只更新一个 build.gradle update_single_build_gradle(paths[:build_gradle], paths[:build_gradle_kts]) end end |
.update_launcher_build_gradle(project_dir, pack_modules) ⇒ Object
更新 launcher/build.gradle 文件,添加 assetPacks 配置
642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 |
# File 'lib/pindo/module/android/gradle_helper.rb', line 642 def self.update_launcher_build_gradle(project_dir, pack_modules) launcher_build_gradle_path = File.join(project_dir, "launcher", "build.gradle") unless File.exist?(launcher_build_gradle_path) puts "警告:未找到 launcher/build.gradle 文件" return end content = File.read(launcher_build_gradle_path) original_content = content.dup # 检查是否已有 assetPacks 配置 if content.match(/assetPacks\s*=\s*\[/) # 更新现有的 assetPacks 配置 content.gsub!(/assetPacks\s*=\s*\[[^\]]*\]/, "assetPacks = #{pack_modules.inspect}") else # 在 android 块中添加 assetPacks 配置 android_block_pattern = /(android\s*\{)/ if content.match(android_block_pattern) # 在 android { 后添加 assetPacks 配置 content.gsub!(android_block_pattern, "\\1\n assetPacks = #{pack_modules.inspect}") else puts "警告:未找到 android 块,无法添加 assetPacks 配置" return end end # 只有当内容发生变化时才写入 if content != original_content File.write(launcher_build_gradle_path, content) puts "✓ 已更新 launcher/build.gradle,添加 assetPacks 配置" else puts "✓ launcher/build.gradle 已包含 assetPacks 配置" end end |
.update_settings_gradle(project_dir, pack_modules) ⇒ Object
更新 settings.gradle 文件,注册 asset pack 模块
594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 |
# File 'lib/pindo/module/android/gradle_helper.rb', line 594 def self.update_settings_gradle(project_dir, pack_modules) settings_gradle_path = File.join(project_dir, "settings.gradle") settings_gradle_kts_path = File.join(project_dir, "settings.gradle.kts") # 优先使用 settings.gradle.kts,否则使用 settings.gradle settings_file = File.exist?(settings_gradle_kts_path) ? settings_gradle_kts_path : settings_gradle_path unless File.exist?(settings_file) puts "警告:未找到 settings.gradle 或 settings.gradle.kts 文件" return end content = File.read(settings_file) original_content = content.dup # 模块名已经是正确的格式(如 :FGUI.androidpack) pack_module_names = pack_modules # 移除已存在的 asset pack 模块引用(避免重复) pack_module_names.each do |module_name| # 移除可能存在的旧引用 content.gsub!(/^\s*include\s+['"]#{Regexp.escape(module_name)}['"]\s*$/, '') content.gsub!(/,\s*['"]#{Regexp.escape(module_name)}['"]/, '') end # 查找 include 语句的位置 include_pattern = /include\s+(['"]:launcher['"],\s*['"]:unityLibrary['"])/ if content.match(include_pattern) # 在现有的 include 语句中添加 asset pack 模块 pack_includes = pack_module_names.map { |m| "'#{m}'" }.join(', ') content.gsub!(include_pattern, "include \\1, #{pack_includes}") else # 如果没有找到标准格式,尝试在文件末尾添加 pack_includes = pack_module_names.map { |m| "'#{m}'" }.join(', ') content += "\ninclude #{pack_includes}\n" unless content.include?(pack_includes) end # 只有当内容发生变化时才写入 if content != original_content File.write(settings_file, content) puts "✓ 已更新 #{File.basename(settings_file)},注册 #{pack_modules.length} 个 Asset Pack 模块" puts " 模块: #{pack_module_names.join(', ')}" else puts "✓ #{File.basename(settings_file)} 已包含 Asset Pack 模块引用" end end |