Module: Pindo::BaseAndroidHelper
- Included in:
- AndroidBuildConfigHelper, AndroidBuildHelper, ApkHelper, BuildHelper, GPComplianceHelper, GradleHelper
- Defined in:
- lib/pindo/module/android/base_helper.rb
Instance Method Summary collapse
-
#build_jdk_path_from_unity_root(unity_path) ⇒ Object
根据 Unity 根路径构建 JDK 路径.
-
#check_and_replace_unity_jdk(jdk_path) ⇒ Object
检查并替换 Unity Editor 中的 JDK.
-
#check_and_update_unity_jdk ⇒ Object
检查并更新 Unity Editor 中的 JDK 版本.
-
#create_and_install_openjdk(jdk_path) ⇒ Object
创建 OpenJDK 目录并安装 Java 11.
-
#ensure_java_version_compliance ⇒ Object
检查并确保 Java 版本符合要求 (Java 11+).
- #extract_config_block_groovy(signing_configs_block, config_type) ⇒ Object
- #extract_config_block_kts(signing_configs_block, config_type) ⇒ Object
-
#extract_keystore_fields_common(fields, ext_values) ⇒ Object
通用字段递归解析.
- #extract_keystore_fields_groovy(config_block, ext_values) ⇒ Object
- #extract_keystore_fields_kts(config_block, ext_values) ⇒ Object
- #extract_signing_configs_groovy(content) ⇒ Object
-
#extract_signing_configs_kts(content) ⇒ Object
— 工具方法 —.
- #extract_var_or_value(val, ext_values, depth = 0) ⇒ Object
- #find_android_subproject(project_path) ⇒ Object
-
#find_java11_installation ⇒ Object
查找系统中的 Java 11 安装.
-
#find_java_command ⇒ Object
查找正确的 Java 命令 (Java 11+).
-
#find_unity_editor_paths ⇒ Object
查找 Unity Editor 安装路径.
- #fix_store_file_path(store_file, project_path) ⇒ Object
- #get_build_tools ⇒ Object
-
#get_ext_values(project_path) ⇒ Object
新增方法:从 ext 配置文件中获取变量值.
- #get_keystore_config(project_path, debug = false) ⇒ Object
-
#get_keystore_config_groovy(gradle_path, project_path, debug) ⇒ Object
处理 Groovy DSL (build.gradle).
-
#get_keystore_config_kts(gradle_kts_path, project_path, debug) ⇒ Object
处理 Kotlin DSL (build.gradle.kts).
-
#get_main_module(project_path) ⇒ Object
xml_content = File.read(strings_xml_path) doc = Nokogiri::XML(xml_content) doc.at_xpath(“//string”)&.text end.
-
#install_adoptium_java_11 ⇒ Object
下载并安装 Adoptium OpenJDK 11.
-
#install_java_11 ⇒ Object
自动安装 Java 11.
-
#install_java_11_macos ⇒ Object
在 macOS 上安装 Java 11.
- #modify_il2cpp_config(project_path) ⇒ Object
- #remove_desktop_google_service(project_path) ⇒ Object
- #remove_groovy_comments(block) ⇒ Object
- #remove_kts_comments(block) ⇒ Object
-
#replace_unity_jdk_with_java11(jdk_path) ⇒ Object
替换 Unity Editor 中的 JDK 为 Java 11.
- #resolve_var(val, ext_values, depth = 0) ⇒ Object
- #unity_android_project?(project_path) ⇒ Boolean
-
#verify_java_version(java_path) ⇒ Object
验证 Java 版本是否满足要求 (Java 11+).
Instance Method Details
#build_jdk_path_from_unity_root(unity_path) ⇒ Object
根据 Unity 根路径构建 JDK 路径
434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 |
# File 'lib/pindo/module/android/base_helper.rb', line 434 def build_jdk_path_from_unity_root(unity_path) # 1. 全局 Unity 路径 if unity_path == "/Applications/Unity" return "/Applications/Unity/PlaybackEngines/AndroidPlayer/OpenJDK" end # 2. Unity Hub 路径(包含版本号) if unity_path.include?("/Unity/Hub/Editor/") # 检查是否有 PlaybackEngines 目录 playback_engines_path = File.join(unity_path, "PlaybackEngines") if File.directory?(playback_engines_path) return File.join(playback_engines_path, "AndroidPlayer", "OpenJDK") end end # 3. 其他 Unity 版本路径 if unity_path.include?("/Unity/") && !unity_path.include?("/Hub/") # 检查是否有 PlaybackEngines 目录 playback_engines_path = File.join(unity_path, "PlaybackEngines") if File.directory?(playback_engines_path) return File.join(playback_engines_path, "AndroidPlayer", "OpenJDK") end end # 4. 默认尝试 File.join(unity_path, "PlaybackEngines", "AndroidPlayer", "OpenJDK") end |
#check_and_replace_unity_jdk(jdk_path) ⇒ Object
检查并替换 Unity Editor 中的 JDK
463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 |
# File 'lib/pindo/module/android/base_helper.rb', line 463 def check_and_replace_unity_jdk(jdk_path) begin # 检查当前 JDK 版本 java_bin = File.join(jdk_path, "bin", "java") if File.exist?(java_bin) version_output = `"#{java_bin}" -version 2>&1` if version_output =~ /version "(\d+)/ current_version = $1.to_i puts "Unity Editor JDK 当前版本: #{current_version}" if current_version >= 11 puts "\e[32m✓ Unity Editor JDK 版本 #{current_version} 符合要求\e[0m" return false else puts "\e[31m✗ Unity Editor JDK 版本 #{current_version} 不符合要求,需要 Java 11+\e[0m" return replace_unity_jdk_with_java11(jdk_path) end end else puts "\e[31m✗ Unity Editor JDK 中未找到 java 可执行文件\e[0m" return replace_unity_jdk_with_java11(jdk_path) end return false rescue => e puts "\e[31m检查 Unity Editor JDK 时出错: #{e.}\e[0m" return false end end |
#check_and_update_unity_jdk ⇒ Object
检查并更新 Unity Editor 中的 JDK 版本
294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 |
# File 'lib/pindo/module/android/base_helper.rb', line 294 def check_and_update_unity_jdk return false unless RbConfig::CONFIG['host_os'] =~ /darwin/ puts "\e[36m=== Unity Editor JDK 版本检测 ===\e[0m" # 查找 Unity Editor 安装路径 unity_paths = find_unity_editor_paths if unity_paths.empty? puts "\e[33m未找到 Unity Editor 安装路径\e[0m" return false end updated_any = false unity_paths.each do |unity_path| # 根据不同的 Unity 路径结构构建 JDK 路径 jdk_path = build_jdk_path_from_unity_root(unity_path) if File.directory?(jdk_path) puts "检查 Unity Editor JDK: #{jdk_path}" if check_and_replace_unity_jdk(jdk_path) updated_any = true end else # OpenJDK 目录不存在,尝试创建并安装 Java 11 puts "OpenJDK 目录不存在: #{jdk_path}" puts "正在创建 OpenJDK 目录并安装 Java 11..." if create_and_install_openjdk(jdk_path) puts "\e[32m✓ OpenJDK 目录创建并安装 Java 11 成功\e[0m" updated_any = true else puts "\e[31m✗ OpenJDK 目录创建并安装 Java 11 失败\e[0m" end end end updated_any end |
#create_and_install_openjdk(jdk_path) ⇒ Object
创建 OpenJDK 目录并安装 Java 11
334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 |
# File 'lib/pindo/module/android/base_helper.rb', line 334 def create_and_install_openjdk(jdk_path) begin # 创建 OpenJDK 目录(使用 sudo 权限) puts "\e[33m需要管理员权限来创建 OpenJDK 目录,请输入密码...\e[0m" if system("sudo mkdir -p \"#{jdk_path}\"") puts "创建 OpenJDK 目录: #{jdk_path}" else puts "\e[31m✗ 创建 OpenJDK 目录失败\e[0m" return false end # 查找或安装 Java 11 java11_path = find_java11_installation unless java11_path && File.directory?(java11_path) puts "\e[33m未找到系统中的 Java 11 安装,正在自动下载...\e[0m" # 自动下载并安装 Java 11 if install_java_11 java11_path = find_java11_installation unless java11_path && File.directory?(java11_path) puts "\e[31m✗ Java 11 自动安装失败\e[0m" return false end puts "\e[32m✓ Java 11 自动安装成功\e[0m" else puts "\e[31m✗ Java 11 自动安装失败\e[0m" return false end end puts "找到 Java 11 安装路径: #{java11_path}" # 复制 Java 11 到 OpenJDK 目录(使用 sudo 权限) puts "正在复制 Java 11 到 OpenJDK 目录..." if system("sudo cp -R \"#{java11_path}\"/* \"#{jdk_path}\"/") puts "\e[32m✓ Java 11 复制成功\e[0m" # 验证安装 java_bin = File.join(jdk_path, "bin", "java") if File.exist?(java_bin) version_output = `"#{java_bin}" -version 2>&1` if version_output =~ /version "(\d+)/ version = $1.to_i if version >= 11 puts "\e[32m✓ Unity Editor JDK 安装成功,版本: #{version}\e[0m" return true else puts "\e[31m✗ 安装的 JDK 版本 #{version} 不符合要求\e[0m" return false end end end return true else puts "\e[31m✗ Java 11 复制失败\e[0m" return false end rescue => e puts "\e[31m创建并安装 OpenJDK 时出错: #{e.}\e[0m" return false end end |
#ensure_java_version_compliance ⇒ Object
检查并确保 Java 版本符合要求 (Java 11+)
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/base_helper.rb', line 91 def ensure_java_version_compliance puts "\e[36m=== Java 版本检测 ===\e[0m" # 检查 Unity Editor 中的 JDK 版本(仅检测,不自动替换) # if check_and_update_unity_jdk # puts "\e[32m✓ Unity Editor JDK 已更新为 Java 11+\e[0m" # end # 仅检测Unity Editor JDK版本,不进行替换 unity_root_paths = find_unity_editor_paths if unity_root_paths.any? puts "\e[36m=== Unity Editor JDK 版本检测 ===\e[0m" unity_root_paths.each do |unity_root| # 构建JDK路径 jdk_path = build_jdk_path_from_unity_root(unity_root) puts "\e[33m[DEBUG] 检查Unity路径: #{unity_root} -> JDK路径: #{jdk_path}\e[0m" if ENV['PINDO_DEBUG'] if File.exist?(jdk_path) java_cmd = File.join(jdk_path, "bin", "java") if File.exist?(java_cmd) version_output = `"#{java_cmd}" -version 2>&1` if version_output =~ /version "(\d+)/ major_version = $1.to_i if major_version >= 11 puts "\e[32m✓ Unity Editor JDK 版本 #{major_version} 符合要求: #{jdk_path}\e[0m" else puts "\e[33m⚠ Unity Editor JDK 版本 #{major_version} 不符合要求 (需要 Java 11+): #{jdk_path}\e[0m" end else puts "\e[33m⚠ 无法解析Unity Editor JDK版本: #{jdk_path}\e[0m" end else puts "\e[33m⚠ Unity Editor JDK中未找到java命令: #{jdk_path}\e[0m" end else puts "\e[33m⚠ Unity Editor JDK路径不存在: #{jdk_path}\e[0m" end end else puts "\e[33m⚠ 未找到Unity Editor安装路径\e[0m" end # 查找当前可用的 Java 命令 current_java = find_java_command puts "当前 Java 命令: #{current_java}" # 验证当前 Java 版本 if verify_java_version(current_java) version_output = `"#{current_java}" -version 2>&1` if version_output =~ /version "(\d+)/ major_version = $1.to_i puts "\e[32m✓ Java 版本 #{major_version} 符合要求 (需要 Java 11+)\e[0m" return true end end puts "\e[31m✗ 当前 Java 版本不符合要求,需要 Java 11+\e[0m" puts "\e[33m请手动安装 Java 11 或更高版本:\e[0m" puts " • macOS: brew install openjdk@11" puts " • 或下载: https://adoptium.net/" puts " • 或使用 SDKMAN: sdk install java 11.0.21-tem" # 注释掉自动安装 Java 11 的逻辑 # puts "\e[33m正在尝试自动安装和配置 Java 11...\e[0m" # if install_java_11 # puts "\e[32m✓ Java 11 安装成功\e[0m" # return true # else # puts "\e[31m✗ Java 11 自动安装失败\e[0m" # puts "\e[33m请手动安装 Java 11 或更高版本:\e[0m" # puts " • macOS: brew install openjdk@11" # puts " • 或下载: https://adoptium.net/" # puts " • 或使用 SDKMAN: sdk install java 11.0.21-tem" # return false # end return false end |
#extract_config_block_groovy(signing_configs_block, config_type) ⇒ Object
801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 |
# File 'lib/pindo/module/android/base_helper.rb', line 801 def extract_config_block_groovy(signing_configs_block, config_type) # 支持 xxx { ... } all_blocks = signing_configs_block.scan(/([A-Za-z0-9_]+)\s*\{([\s\S]*?)^\s*\}/m) priority_names = [config_type, "Android_Sign", "release", "debug"] config_block = nil priority_names.each do |name| block = all_blocks.find { |n, b| n == name && b.include?("storeFile") } if block config_block = block[1] break end end if config_block.nil? all_blocks.each do |name, block| if block.include?("storeFile") config_block = block break end end end config_block end |
#extract_config_block_kts(signing_configs_block, config_type) ⇒ Object
776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 |
# File 'lib/pindo/module/android/base_helper.rb', line 776 def extract_config_block_kts(signing_configs_block, config_type) # 支持 create("xxx") { ... } all_blocks = signing_configs_block.scan(/create\(["']?([A-Za-z0-9_]+)["']?\)\s*\{([\s\S]*?)^\s*\}/m) # 优先 release/debug/Android_Sign/自定义名 priority_names = [config_type, "Android_Sign", "release", "debug"] config_block = nil priority_names.each do |name| block = all_blocks.find { |n, b| n == name && b.include?("storeFile") } if block config_block = block[1] break end end # 没找到就取第一个有 storeFile 的块 if config_block.nil? all_blocks.each do |name, block| if block.include?("storeFile") config_block = block break end end end config_block end |
#extract_keystore_fields_common(fields, ext_values) ⇒ Object
通用字段递归解析
836 837 838 |
# File 'lib/pindo/module/android/base_helper.rb', line 836 def extract_keystore_fields_common(fields, ext_values) fields.map { |val| extract_var_or_value(val, ext_values) } end |
#extract_keystore_fields_groovy(config_block, ext_values) ⇒ Object
840 841 842 843 844 845 846 847 |
# File 'lib/pindo/module/android/base_helper.rb', line 840 def extract_keystore_fields_groovy(config_block, ext_values) # 只处理 groovy 语法 store_file = config_block[/storeFile\s+file\(["']?([^\)"']+)["']?\)/, 1] store_password = config_block[/storePassword\s+["']?([^\)"']+)["']?/, 1] key_alias = config_block[/keyAlias\s+["']?([^\)"']+)["']?/, 1] key_password = config_block[/keyPassword\s+["']?([^\)"']+)["']?/, 1] extract_keystore_fields_common([store_file, store_password, key_alias, key_password], ext_values) end |
#extract_keystore_fields_kts(config_block, ext_values) ⇒ Object
849 850 851 852 853 854 855 856 857 |
# File 'lib/pindo/module/android/base_helper.rb', line 849 def extract_keystore_fields_kts(config_block, ext_values) # 只处理 kts 语法 store_file = config_block[/storeFile\s*=\s*file\(["']?([^\)"']+)["']?\)/, 1] || config_block[/storeFile\s*=\s*rootProject\.file\(["']?([^\)"']+)["']?\)/, 1] store_password = config_block[/storePassword\s*=\s*["']?([^\)"']+)["']?/, 1] key_alias = config_block[/keyAlias\s*=\s*["']?([^\)"']+)["']?/, 1] key_password = config_block[/keyPassword\s*=\s*["']?([^\)"']+)["']?/, 1] extract_keystore_fields_common([store_file, store_password, key_alias, key_password], ext_values) end |
#extract_signing_configs_groovy(content) ⇒ Object
770 771 772 773 774 |
# File 'lib/pindo/module/android/base_helper.rb', line 770 def extract_signing_configs_groovy(content) # 提取 signingConfigs { ... },支持多层嵌套 match = content.match(/signingConfigs\s*\{([\s\S]*?)^\}/m) match ? match[1] : nil end |
#extract_signing_configs_kts(content) ⇒ Object
— 工具方法 —
764 765 766 767 768 |
# File 'lib/pindo/module/android/base_helper.rb', line 764 def extract_signing_configs_kts(content) # 提取 signingConfigs { ... },支持多层嵌套 match = content.match(/signingConfigs\s*\{([\s\S]*?)^\}/m) match ? match[1] : nil end |
#extract_var_or_value(val, ext_values, depth = 0) ⇒ Object
859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 |
# File 'lib/pindo/module/android/base_helper.rb', line 859 def extract_var_or_value(val, ext_values, depth=0) return nil if val.nil? || val.empty? || depth > 5 # 匹配 ${KEY}、$KEY、"${KEY}"、'${KEY}' if val =~ /^\$\{?([A-Za-z0-9_]+)\}?$/ key = $1 v = ext_values[key] v ? extract_var_or_value(v, ext_values, depth+1) : nil elsif val =~ /^"?\$\{([A-Za-z0-9_]+)\}"?$/ key = $1 v = ext_values[key] v ? extract_var_or_value(v, ext_values, depth+1) : nil else val end end |
#find_android_subproject(project_path) ⇒ Object
948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 |
# File 'lib/pindo/module/android/base_helper.rb', line 948 def find_android_subproject(project_path) android_dir = File.join(project_path, "Unity") return nil unless File.directory?(android_dir) main_module = get_main_module(android_dir) return nil unless main_module src_main = File.join(main_module, "src/main") return nil unless File.directory?(src_main) manifest = File.join(src_main, "AndroidManifest.xml") return nil unless File.exist?(manifest) android_dir end |
#find_java11_installation ⇒ Object
查找系统中的 Java 11 安装
572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 |
# File 'lib/pindo/module/android/base_helper.rb', line 572 def find_java11_installation # 检查常见的 Java 11 安装路径 java11_paths = [ # Homebrew 安装路径 "/opt/homebrew/opt/openjdk@11", "/usr/local/opt/openjdk@11", # SDKMAN 安装路径 File.("~/.sdkman/candidates/java/11.0.21-tem"), File.("~/.sdkman/candidates/java/11.0.20-tem"), # 系统安装路径 "/Library/Java/JavaVirtualMachines/openjdk-11.jdk/Contents/Home", "/Library/Java/JavaVirtualMachines/adoptopenjdk-11.jdk/Contents/Home", # Pindo 安装的 Java 11 File.("~/.pindo/java11") ] java11_paths.each do |path| if File.directory?(path) java_bin = File.join(path, "bin", "java") if File.exist?(java_bin) # 验证版本 version_output = `"#{java_bin}" -version 2>&1` if version_output =~ /version "(\d+)/ version = $1.to_i if version >= 11 return path end end end end end nil end |
#find_java_command ⇒ Object
查找正确的 Java 命令 (Java 11+)
36 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 |
# File 'lib/pindo/module/android/base_helper.rb', line 36 def find_java_command # 检查 JAVA_HOME 环境变量 if ENV['JAVA_HOME'] && File.exist?(File.join(ENV['JAVA_HOME'], 'bin', 'java')) java_path = File.join(ENV['JAVA_HOME'], 'bin', 'java') # 验证 Java 版本 if verify_java_version(java_path) return java_path end end # 尝试常见的 Java 路径 common_java_paths = [ '/usr/libexec/java_home', # macOS '/usr/bin/java', '/usr/local/bin/java', '/opt/homebrew/bin/java', # macOS Homebrew '/usr/local/opt/openjdk/bin/java' # macOS Homebrew OpenJDK ] common_java_paths.each do |java_path| if File.exist?(java_path) # 对于 macOS 的 java_home,需要特殊处理 if java_path.include?('java_home') java_home_output = `#{java_path} 2>/dev/null`.strip if !java_home_output.empty? actual_java_path = File.join(java_home_output, 'bin', 'java') if File.exist?(actual_java_path) && verify_java_version(actual_java_path) return actual_java_path end end elsif verify_java_version(java_path) return java_path end end end # 如果都找不到,返回默认的 java 命令 'java' end |
#find_unity_editor_paths ⇒ Object
查找 Unity Editor 安装路径
400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 |
# File 'lib/pindo/module/android/base_helper.rb', line 400 def find_unity_editor_paths unity_paths = [] # 1. 检查全局 Unity PlaybackEngines 路径(最常见) global_playback_engines = "/Applications/Unity/PlaybackEngines" if File.directory?(global_playback_engines) unity_paths << "/Applications/Unity" end # 2. 检查 Unity Hub 中的多个版本(支持 2021.3.* 版本范围) unity_hub_patterns = [ "/Applications/Unity/Hub/Editor/2021.3.*/PlaybackEngines" ] unity_hub_patterns.each do |pattern| Dir.glob(pattern).each do |playback_engines_path| # Unity Hub 版本:/Applications/Unity/Hub/Editor/2022.3.15f1/PlaybackEngines unity_root = playback_engines_path.gsub("/PlaybackEngines", "") unity_paths << unity_root end end # 3. 检查其他常见的 Unity 安装路径 other_pattern = "/Applications/Unity/*/PlaybackEngines" Dir.glob(other_pattern).each do |playback_engines_path| # 其他 Unity 版本:/Applications/Unity/2022.3.15f1/PlaybackEngines unity_root = playback_engines_path.gsub("/PlaybackEngines", "") unity_paths << unity_root end unity_paths.uniq end |
#fix_store_file_path(store_file, project_path) ⇒ Object
884 885 886 887 888 889 890 891 892 |
# File 'lib/pindo/module/android/base_helper.rb', line 884 def fix_store_file_path(store_file, project_path) return nil if store_file.nil? || store_file.empty? # 兼容 $rootDir、${rootDir}、project.rootDir、rootProject.file store_file = store_file.gsub(/^\$?\{?rootDir\}?\/?/, project_path + "/") store_file = store_file.gsub(/^project\.rootDir\/?/, project_path + "/") store_file = store_file.gsub(/^rootProject\.file\(['"](.+?)['"]\)/, project_path + '/\\1') store_file = File.(store_file, project_path) unless File.exist?(store_file) store_file end |
#get_build_tools ⇒ Object
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
# File 'lib/pindo/module/android/base_helper.rb', line 4 def get_build_tools # 获取 gem 资源文件路径 pindo_dir ||= File.(ENV['PINDO_DIR'] || '~/.pindo') pindo_common_configdir ||= File.join(pindo_dir, "pindo_common_config") tools_dir = File.join(pindo_common_configdir, 'android_tools') # 如果开发环境找不到,尝试在 gem 安装目录找 unless File.directory?(tools_dir) raise "缺少必要的构建工具: #{tools_dir},请执行pindo setup更新pindo配置" end # 检查必要的工具是否存在 required_tools = { bundle_tool: 'bundletool.jar', gradlew: 'gradlew', gradle_wrapper: 'gradle-wrapper.jar' } tools = {} required_tools.each do |key, filename| path = File.join(tools_dir, filename) unless File.exist?(path) raise "缺少必要的构建工具: #{filename},请执行pindo setup更新pindo配置" end tools[key] = path end tools end |
#get_ext_values(project_path) ⇒ Object
新增方法:从 ext 配置文件中获取变量值
895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 |
# File 'lib/pindo/module/android/base_helper.rb', line 895 def get_ext_values(project_path) ext_values = {} ext_files = [ File.join(project_path, "buildScripts/cfg/ext_signing.gradle"), File.join(project_path, "buildScripts/cfg/ext_signing.gradle.kts"), File.join(project_path, "gradle.properties"), File.join(project_path, "local.properties") ] ext_files.each do |file_path| next unless File.exist?(file_path) content = File.read(file_path) # 支持 ext.KEY = "VALUE" content.scan(/ext\.(\w+)\s*=\s*["']([^"']+)["']/m).each do |key, value| ext_values[key] = value end # 支持 ext["KEY"] = "VALUE" content.scan(/ext\[\s*["'](\w+)["']\s*\]\s*=\s*["']([^"']+)["']/m).each do |key, value| ext_values[key] = value end # 支持 KEY = "VALUE" content.scan(/^(\w+)\s*=\s*["']([^"']+)["']/m).each do |key, value| ext_values[key] = value end end ext_values end |
#get_keystore_config(project_path, debug = false) ⇒ Object
678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 |
# File 'lib/pindo/module/android/base_helper.rb', line 678 def get_keystore_config(project_path, debug = false) main_module = get_main_module(project_path) return nil unless main_module gradle_kts_path = File.join(main_module, "build.gradle.kts") gradle_path = File.join(main_module, "build.gradle") if File.exist?(gradle_kts_path) puts "KTS 项目,读取 #{File.basename(gradle_kts_path)} 文件" get_keystore_config_kts(gradle_kts_path, project_path, debug) elsif File.exist?(gradle_path) puts "Groovy 项目,读取 #{File.basename(gradle_path)} 文件" get_keystore_config_groovy(gradle_path, project_path, debug) else puts "未找到 build.gradle 或 build.gradle.kts 文件" nil end end |
#get_keystore_config_groovy(gradle_path, project_path, debug) ⇒ Object
处理 Groovy DSL (build.gradle)
731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 |
# File 'lib/pindo/module/android/base_helper.rb', line 731 def get_keystore_config_groovy(gradle_path, project_path, debug) content = File.read(gradle_path) puts "读取 #{File.basename(gradle_path)} 文件" signing_configs_block = extract_signing_configs_groovy(content) # puts "==== signingConfigs block ====" # puts signing_configs_block # puts "==============================" if signing_configs_block return nil unless signing_configs_block config_type = debug ? 'debug' : 'release' config_block = extract_config_block_groovy(signing_configs_block, config_type) # puts "==== config_block ====" # puts config_block # puts "=====================" if config_block return nil unless config_block config_block = remove_groovy_comments(config_block) ext_values = get_ext_values(project_path) store_file, store_password, key_alias, key_password = extract_keystore_fields_groovy(config_block, ext_values) store_file = fix_store_file_path(store_file, project_path) keystore_config = { store_file: store_file, store_password: store_password, key_alias: key_alias, key_password: key_password } if keystore_config.values.any?(&:nil?) puts "警告: 部分 keystore 配置为 nil: #{keystore_config}" end keystore_config end |
#get_keystore_config_kts(gradle_kts_path, project_path, debug) ⇒ Object
处理 Kotlin DSL (build.gradle.kts)
698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 |
# File 'lib/pindo/module/android/base_helper.rb', line 698 def get_keystore_config_kts(gradle_kts_path, project_path, debug) content = File.read(gradle_kts_path) puts "读取 #{File.basename(gradle_kts_path)} 文件" signing_configs_block = extract_signing_configs_kts(content) # puts "==== signingConfigs block ====" # puts signing_configs_block # puts "==============================" if signing_configs_block return nil unless signing_configs_block config_type = debug ? 'debug' : 'release' config_block = extract_config_block_kts(signing_configs_block, config_type) # puts "==== config_block ====" # puts config_block # puts "=====================" if config_block return nil unless config_block config_block = remove_kts_comments(config_block) ext_values = get_ext_values(project_path) store_file, store_password, key_alias, key_password = extract_keystore_fields_kts(config_block, ext_values) store_file = fix_store_file_path(store_file, project_path) keystore_config = { store_file: store_file, store_password: store_password, key_alias: key_alias, key_password: key_password } if keystore_config.values.any?(&:nil?) puts "警告: 部分 keystore 配置为 nil: #{keystore_config}" end keystore_config end |
#get_main_module(project_path) ⇒ Object
xml_content = File.read(strings_xml_path)
doc = Nokogiri::XML(xml_content)
doc.at_xpath("//string[@name='app_name']")&.text
end
640 641 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 676 |
# File 'lib/pindo/module/android/base_helper.rb', line 640 def get_main_module(project_path) settings_gradle_path = File.join(project_path, "settings.gradle") settings_gradle_kts_path = File.join(project_path, "settings.gradle.kts") # 优先使用 settings.gradle.kts,如果不存在则使用 settings.gradle if File.exist?(settings_gradle_kts_path) settings_gradle_path = settings_gradle_kts_path elsif !File.exist?(settings_gradle_path) return nil end content = File.read(settings_gradle_path) # 兼容 include ':app' 和 include(":app") modules = content.scan(/include\s*\(?\s*['\"]?([:\w\-]+)['\"]?\s*\)?/).flatten main_module = modules.find do |m| module_name = m.split(':').last gradle_path = File.join(project_path, module_name, "build.gradle") gradle_kts_path = File.join(project_path, module_name, "build.gradle.kts") # 优先使用 build.gradle.kts,如果不存在则使用 build.gradle if File.exist?(gradle_kts_path) gradle_path = gradle_kts_path end if File.exist?(gradle_path) gradle_content = File.read(gradle_path) gradle_content.include?("apply plugin: 'com.android.application") || gradle_content.include?("id 'com.android.application") || (gradle_content.include?("plugins {") && gradle_content.include?("com.android.application")) end end return nil unless main_module module_name = main_module.split(':').last File.join(project_path, module_name) end |
#install_adoptium_java_11 ⇒ Object
下载并安装 Adoptium OpenJDK 11
237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 |
# File 'lib/pindo/module/android/base_helper.rb', line 237 def install_adoptium_java_11 begin # 创建临时目录 temp_dir = Dir.mktmpdir("java_install_") # 下载 URL (macOS x64) download_url = "https://github.com/adoptium/temurin11-binaries/releases/download/jdk-11.0.21%2B9/OpenJDK11U-jdk_x64_mac_hotspot_11.0.21_9.tar.gz" tar_file = File.join(temp_dir, "openjdk11.tar.gz") puts "下载 OpenJDK 11..." if system("curl -L -o \"#{tar_file}\" \"#{download_url}\"") puts "解压 OpenJDK 11..." if system("tar -xzf \"#{tar_file}\" -C \"#{temp_dir}\"") # 查找解压后的目录 jdk_dir = Dir.glob(File.join(temp_dir, "jdk-11*")).first if jdk_dir && File.directory?(jdk_dir) # 尝试安装到用户目录而不是系统目录 user_install_dir = File.("~/.pindo/java11") if system("mkdir -p \"#{File.dirname(user_install_dir)}\" && mv \"#{jdk_dir}\" \"#{user_install_dir}\"") # 设置环境变量 ENV['JAVA_HOME'] = user_install_dir puts "\e[32m✓ 已安装并设置 JAVA_HOME: #{user_install_dir}\e[0m" return true else puts "\e[33m无法安装到用户目录,尝试系统目录...\e[0m" # 回退到系统目录 install_dir = "/usr/local/openjdk11" if system("sudo mkdir -p /usr/local && sudo mv \"#{jdk_dir}\" \"#{install_dir}\"") # 设置环境变量 ENV['JAVA_HOME'] = install_dir puts "\e[32m✓ 已安装并设置 JAVA_HOME: #{install_dir}\e[0m" return true else puts "\e[31m无法安装到系统目录,需要管理员权限\e[0m" end end else puts "\e[31m解压后未找到 JDK 目录\e[0m" end else puts "\e[31m解压 OpenJDK 11 失败\e[0m" end else puts "\e[31m下载 OpenJDK 11 失败\e[0m" end return false rescue => e puts "\e[31m下载安装 OpenJDK 11 失败: #{e.}\e[0m" return false ensure # 清理临时目录 FileUtils.rm_rf(temp_dir) if temp_dir && File.directory?(temp_dir) end end |
#install_java_11 ⇒ Object
自动安装 Java 11
171 172 173 174 175 176 177 178 179 180 181 182 183 184 |
# File 'lib/pindo/module/android/base_helper.rb', line 171 def install_java_11 begin # 检查是否在 macOS 上 if RbConfig::CONFIG['host_os'] =~ /darwin/ return install_java_11_macos else puts "\e[33m当前系统不是 macOS,请手动安装 Java 11\e[0m" return false end rescue => e puts "\e[31m安装 Java 11 时出错: #{e.}\e[0m" return false end end |
#install_java_11_macos ⇒ Object
在 macOS 上安装 Java 11
187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 |
# File 'lib/pindo/module/android/base_helper.rb', line 187 def install_java_11_macos puts "\e[36m在 macOS 上安装 Java 11...\e[0m" # 方法1: 使用 Homebrew 安装 if system("which brew > /dev/null 2>&1") puts "使用 Homebrew 安装 OpenJDK 11..." if system("brew install openjdk@11") # 设置 JAVA_HOME java_home_path = `brew --prefix openjdk@11`.strip if !java_home_path.empty? && File.directory?(java_home_path) java_bin_path = File.join(java_home_path, "bin", "java") if File.exist?(java_bin_path) # 设置环境变量 ENV['JAVA_HOME'] = java_home_path puts "\e[32m✓ 已设置 JAVA_HOME: #{java_home_path}\e[0m" return true end end else puts "\e[33mHomebrew 安装 OpenJDK 11 失败\e[0m" end else puts "\e[33m未找到 Homebrew,跳过 Homebrew 安装方式\e[0m" end # 方法2: 使用 SDKMAN 安装 if system("which sdk > /dev/null 2>&1") puts "使用 SDKMAN 安装 Java 11..." if system("sdk install java 11.0.21-tem") # 设置环境变量 sdkman_home = ENV['SDKMAN_DIR'] || File.("~/.sdkman") java_home_path = File.join(sdkman_home, "candidates", "java", "11.0.21-tem") if File.directory?(java_home_path) ENV['JAVA_HOME'] = java_home_path puts "\e[32m✓ 已设置 JAVA_HOME: #{java_home_path}\e[0m" return true end else puts "\e[33mSDKMAN 安装 Java 11 失败\e[0m" end else puts "\e[33m未找到 SDKMAN,跳过 SDKMAN 安装方式\e[0m" end # 方法3: 下载并安装 Adoptium OpenJDK puts "尝试下载并安装 Adoptium OpenJDK 11..." return install_adoptium_java_11 end |
#modify_il2cpp_config(project_path) ⇒ Object
607 608 609 610 611 612 613 614 615 616 |
# File 'lib/pindo/module/android/base_helper.rb', line 607 def modify_il2cpp_config(project_path) # 设置Il2CppOutputProject可执行权限 system("chmod", "-R", "777", File.join(project_path, "unityLibrary/src/main/Il2CppOutputProject")) il2cpp_config_path = File.join(project_path, "unityLibrary/src/main/Il2CppOutputProject/IL2CPP/libil2cpp/il2cpp-config.h") content = File.read(il2cpp_config_path) content.gsub!("il2cpp::vm::Exception::Raise", "//il2cpp::vm::Exception::Raise") File.write(il2cpp_config_path, content) end |
#remove_desktop_google_service(project_path) ⇒ Object
618 619 620 621 622 623 |
# File 'lib/pindo/module/android/base_helper.rb', line 618 def remove_desktop_google_service(project_path) # 删除google-services-desktop.json desktop_google_service_path = File.join(project_path, "unityLibrary/src/main/assets/google-services-desktop.json") File.delete(desktop_google_service_path) if File.exist?(desktop_google_service_path) end |
#remove_groovy_comments(block) ⇒ Object
829 830 831 832 833 |
# File 'lib/pindo/module/android/base_helper.rb', line 829 def remove_groovy_comments(block) # 去除 // 和 /* ... */ 注释 block = block.gsub(/\/\*[\s\S]*?\*\//, "") block.lines.reject { |line| line.strip.start_with?("//") }.join end |
#remove_kts_comments(block) ⇒ Object
824 825 826 827 |
# File 'lib/pindo/module/android/base_helper.rb', line 824 def remove_kts_comments(block) # 去除 // 注释 block.lines.reject { |line| line.strip.start_with?("//") }.join end |
#replace_unity_jdk_with_java11(jdk_path) ⇒ Object
替换 Unity Editor 中的 JDK 为 Java 11
494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 |
# File 'lib/pindo/module/android/base_helper.rb', line 494 def replace_unity_jdk_with_java11(jdk_path) begin puts "\e[33m正在替换 Unity Editor JDK 为 Java 11...\e[0m" # 查找系统中的 Java 11 java11_path = find_java11_installation unless java11_path && File.directory?(java11_path) puts "\e[33m未找到系统中的 Java 11 安装,正在自动下载...\e[0m" # 自动下载并安装 Java 11 if install_java_11 java11_path = find_java11_installation unless java11_path && File.directory?(java11_path) puts "\e[31m✗ Java 11 自动安装失败\e[0m" return false end puts "\e[32m✓ Java 11 自动安装成功\e[0m" else puts "\e[31m✗ Java 11 自动安装失败\e[0m" return false end end puts "找到 Java 11 安装路径: #{java11_path}" # 备份原始 JDK(使用 sudo 权限) backup_path = "#{jdk_path}_backup_#{Time.now.strftime('%Y%m%d_%H%M%S')}" puts "备份原始 JDK 到: #{backup_path}" puts "\e[33m需要管理员权限来备份和替换 Unity Editor JDK,请输入密码...\e[0m" if system("sudo cp -R \"#{jdk_path}\" \"#{backup_path}\"") puts "\e[32m✓ 原始 JDK 备份成功\e[0m" else puts "\e[31m✗ 原始 JDK 备份失败\e[0m" return false end # 删除原始 JDK 内容(使用 sudo 权限) puts "删除原始 JDK 内容..." if system("sudo rm -rf \"#{jdk_path}/*\"") puts "\e[32m✓ 原始 JDK 内容删除成功\e[0m" else puts "\e[31m✗ 原始 JDK 内容删除失败\e[0m" return false end # 复制 Java 11 到 Unity JDK 目录(使用 sudo 权限) puts "复制 Java 11 到 Unity JDK 目录..." if system("sudo cp -R \"#{java11_path}\"/* \"#{jdk_path}/\"") puts "\e[32m✓ Java 11 复制成功\e[0m" # 验证替换结果 new_java_bin = File.join(jdk_path, "bin", "java") if File.exist?(new_java_bin) version_output = `"#{new_java_bin}" -version 2>&1` if version_output =~ /version "(\d+)/ new_version = $1.to_i if new_version >= 11 puts "\e[32m✓ Unity Editor JDK 已成功替换为 Java #{new_version}\e[0m" return true else puts "\e[31m✗ 替换后的 JDK 版本仍然不符合要求: #{new_version}\e[0m" end end end else puts "\e[31m✗ Java 11 复制失败\e[0m" return false end return false rescue => e puts "\e[31m替换 Unity Editor JDK 时出错: #{e.}\e[0m" return false end end |
#resolve_var(val, ext_values, depth = 0) ⇒ Object
875 876 877 878 879 880 881 882 |
# File 'lib/pindo/module/android/base_helper.rb', line 875 def resolve_var(val, ext_values, depth=0) return val if val.nil? || depth > 5 if ext_values[val] resolve_var(ext_values[val], ext_values, depth+1) else val end end |
#unity_android_project?(project_path) ⇒ Boolean
929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 |
# File 'lib/pindo/module/android/base_helper.rb', line 929 def unity_android_project?(project_path) # 检查 unityLibrary 模块是否存在 unity_library_path = File.join(project_path, "unityLibrary") return false unless File.directory?(unity_library_path) # 检查 unityLibrary 的 build.gradle 或 build.gradle.kts 是否存在 unity_gradle_path = File.join(unity_library_path, "build.gradle") unity_gradle_kts_path = File.join(unity_library_path, "build.gradle.kts") if File.exist?(unity_gradle_kts_path) unity_gradle_path = unity_gradle_kts_path elsif !File.exist?(unity_gradle_path) return false end # 检查 build.gradle 中是否包含 Unity 特有的配置 content = File.read(unity_gradle_path) content.include?("com.android.library") && content.include?("BuildIl2Cpp") end |
#verify_java_version(java_path) ⇒ Object
验证 Java 版本是否满足要求 (Java 11+)
77 78 79 80 81 82 83 84 85 86 87 88 |
# File 'lib/pindo/module/android/base_helper.rb', line 77 def verify_java_version(java_path) begin version_output = `"#{java_path}" -version 2>&1` if version_output =~ /version "(\d+)/ major_version = $1.to_i return major_version >= 11 end rescue # 如果执行失败,返回 false end false end |