pindo 5.2.4 → 5.3.7

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.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/lib/pindo/base/aeshelper.rb +23 -2
  3. data/lib/pindo/base/pindocontext.rb +259 -0
  4. data/lib/pindo/client/pgyer_feishu_oauth_cli.rb +343 -80
  5. data/lib/pindo/client/pgyerclient.rb +30 -20
  6. data/lib/pindo/command/android/autobuild.rb +52 -22
  7. data/lib/pindo/command/android/build.rb +27 -16
  8. data/lib/pindo/command/android/debug.rb +25 -15
  9. data/lib/pindo/command/dev/debug.rb +2 -51
  10. data/lib/pindo/command/dev/feishu.rb +19 -2
  11. data/lib/pindo/command/ios/adhoc.rb +2 -1
  12. data/lib/pindo/command/ios/autobuild.rb +35 -8
  13. data/lib/pindo/command/ios/debug.rb +2 -132
  14. data/lib/pindo/command/lib/lint.rb +24 -1
  15. data/lib/pindo/command/setup.rb +24 -4
  16. data/lib/pindo/command/unity/apk.rb +15 -0
  17. data/lib/pindo/command/unity/ipa.rb +16 -0
  18. data/lib/pindo/command.rb +13 -2
  19. data/lib/pindo/module/android/android_build_config_helper.rb +425 -0
  20. data/lib/pindo/module/android/apk_helper.rb +23 -25
  21. data/lib/pindo/module/android/base_helper.rb +572 -0
  22. data/lib/pindo/module/android/build_helper.rb +8 -318
  23. data/lib/pindo/module/android/gp_compliance_helper.rb +668 -0
  24. data/lib/pindo/module/android/gradle_helper.rb +746 -3
  25. data/lib/pindo/module/appselect.rb +18 -5
  26. data/lib/pindo/module/build/buildhelper.rb +120 -29
  27. data/lib/pindo/module/build/unityhelper.rb +675 -18
  28. data/lib/pindo/module/build/versionhelper.rb +146 -0
  29. data/lib/pindo/module/cert/certhelper.rb +33 -2
  30. data/lib/pindo/module/cert/xcodecerthelper.rb +3 -1
  31. data/lib/pindo/module/pgyer/pgyerhelper.rb +114 -31
  32. data/lib/pindo/module/xcode/xcodebuildconfig.rb +232 -0
  33. data/lib/pindo/module/xcode/xcodebuildhelper.rb +0 -1
  34. data/lib/pindo/version.rb +356 -86
  35. data/lib/pindo.rb +72 -3
  36. metadata +5 -1
@@ -1,10 +1,38 @@
1
1
  require_relative 'base_helper'
2
+ require 'net/http'
3
+ require 'uri'
4
+ require 'zip'
2
5
 
3
6
  module Pindo
4
7
  module GradleHelper
5
8
  include BaseAndroidHelper
6
9
 
10
+ # 常量定义
11
+ RECOMMENDED_GRADLE_VERSION = '7.6.4'
12
+ MIN_GRADLE_WRAPPER_JAR_SIZE = 50_000 # 50KB
13
+ DOWNLOAD_TIMEOUT = 30 # 30秒
14
+
7
15
  def check_gradle_files(project_path)
16
+ puts "\e[36m=== 检查Gradle Wrapper配置 ===\e[0m"
17
+
18
+ # 优先使用基于gradle-wrapper.properties的自动配置
19
+ if File.exist?(File.join(project_path, "gradle/wrapper/gradle-wrapper.properties"))
20
+ puts "检测到gradle-wrapper.properties文件,使用自动配置..."
21
+ if setup_gradle_wrapper_from_properties(project_path)
22
+ puts "\e[32m✓ 基于gradle-wrapper.properties的自动配置成功\e[0m"
23
+ return true
24
+ else
25
+ puts "\e[33m⚠ 自动配置失败,回退到传统方式\e[0m"
26
+ end
27
+ end
28
+
29
+ # 回退到传统的文件复制方式
30
+ puts "使用传统方式配置Gradle Wrapper..."
31
+ setup_gradle_wrapper_traditional(project_path)
32
+ end
33
+
34
+ # 传统的gradle wrapper配置方式(作为回退方案)
35
+ def setup_gradle_wrapper_traditional(project_path)
8
36
  # 检查是否存在 gradlew 文件 如果没有则执行复制操作
9
37
  gradlew_path = File.join(project_path, "gradlew")
10
38
  if File.exist?(gradlew_path)
@@ -46,11 +74,726 @@ module Pindo
46
74
  end
47
75
 
48
76
  def update_gradle_version(project_path)
49
- # 更新gradle wrapper版本
77
+ # 智能更新gradle wrapper版本
50
78
  wrapper_path = File.join(project_path, "gradle/wrapper/gradle-wrapper.properties")
79
+
80
+ unless File.exist?(wrapper_path)
81
+ puts "\e[33m⚠ 未找到gradle-wrapper.properties文件,跳过版本更新\e[0m"
82
+ return false
83
+ end
84
+
51
85
  content = File.read(wrapper_path)
52
- content.gsub!("gradle-6.1.1-bin.zip", "gradle-7.2-bin.zip")
53
- File.write(wrapper_path, content)
86
+ original_content = content.dup
87
+
88
+ # 解析当前版本
89
+ current_version = parse_gradle_version(wrapper_path)
90
+ if current_version.nil?
91
+ puts "\e[33m⚠ 无法解析当前Gradle版本\e[0m"
92
+ return false
93
+ end
94
+
95
+ puts "当前Gradle版本: #{current_version}"
96
+
97
+ # 根据当前版本智能选择目标版本
98
+ target_version = determine_target_gradle_version(current_version)
99
+
100
+ if target_version == current_version
101
+ puts "\e[32m✓ Gradle版本已是最新,无需更新\e[0m"
102
+ return true
103
+ end
104
+
105
+ puts "更新Gradle版本: #{current_version} -> #{target_version}"
106
+
107
+ # 更新版本
108
+ content.gsub!("gradle-#{current_version}-bin.zip", "gradle-#{target_version}-bin.zip")
109
+ content.gsub!("gradleVersion=#{current_version}", "gradleVersion=#{target_version}")
110
+
111
+ if content != original_content
112
+ File.write(wrapper_path, content)
113
+ puts "\e[32m✓ Gradle版本更新完成\e[0m"
114
+
115
+ # 重新配置gradle wrapper
116
+ setup_gradle_wrapper_from_properties(project_path)
117
+ return true
118
+ else
119
+ puts "\e[33m⚠ Gradle版本更新失败,未找到匹配的版本字符串\e[0m"
120
+ return false
121
+ end
122
+ end
123
+
124
+ # 基于gradle-wrapper.properties自动配置gradle工具
125
+ def setup_gradle_wrapper_from_properties(project_path)
126
+ wrapper_properties_path = File.join(project_path, "gradle/wrapper/gradle-wrapper.properties")
127
+
128
+ unless File.exist?(wrapper_properties_path)
129
+ puts "\e[33m⚠ 未找到gradle-wrapper.properties文件: #{wrapper_properties_path}\e[0m"
130
+ return false
131
+ end
132
+
133
+ # 解析gradle-wrapper.properties文件
134
+ gradle_version = parse_gradle_version(wrapper_properties_path)
135
+ if gradle_version.nil?
136
+ puts "\e[31m✗ 无法解析gradle版本\e[0m"
137
+ return false
138
+ end
139
+
140
+ puts "\e[36m=== 自动配置Gradle Wrapper ===\e[0m"
141
+ puts "检测到Gradle版本: #{gradle_version}"
142
+
143
+ # 确保gradle wrapper目录存在
144
+ wrapper_dir = File.join(project_path, "gradle/wrapper")
145
+ FileUtils.mkdir_p(wrapper_dir)
146
+
147
+ # 下载并配置gradle-wrapper.jar
148
+ unless download_gradle_wrapper_jar(wrapper_dir, gradle_version)
149
+ puts "\e[31m✗ 下载gradle-wrapper.jar失败\e[0m"
150
+ return false
151
+ end
152
+
153
+ # 生成gradlew脚本
154
+ unless generate_gradlew_script(project_path)
155
+ puts "\e[31m✗ 生成gradlew脚本失败\e[0m"
156
+ return false
157
+ end
158
+
159
+ puts "\e[32m✓ Gradle Wrapper配置完成\e[0m"
160
+ true
161
+ end
162
+
163
+ # 检查gradle wrapper配置是否完整
164
+ def verify_gradle_wrapper_setup(project_path)
165
+ wrapper_dir = File.join(project_path, "gradle/wrapper")
166
+ wrapper_jar_path = File.join(wrapper_dir, "gradle-wrapper.jar")
167
+ gradlew_path = File.join(project_path, "gradlew")
168
+ properties_path = File.join(wrapper_dir, "gradle-wrapper.properties")
169
+
170
+ all_exist = File.exist?(wrapper_jar_path) &&
171
+ File.exist?(gradlew_path) &&
172
+ File.exist?(properties_path)
173
+
174
+ if all_exist
175
+ puts "\e[32m✓ Gradle Wrapper配置完整\e[0m"
176
+ return true
177
+ else
178
+ puts "\e[33m⚠ Gradle Wrapper配置不完整:\e[0m"
179
+ puts " gradle-wrapper.jar: #{File.exist?(wrapper_jar_path) ? '✓' : '✗'}"
180
+ puts " gradlew: #{File.exist?(gradlew_path) ? '✓' : '✗'}"
181
+ puts " gradle-wrapper.properties: #{File.exist?(properties_path) ? '✓' : '✗'}"
182
+ return false
183
+ end
184
+ end
185
+
186
+ private
187
+
188
+ # 解析gradle版本
189
+ def parse_gradle_version(properties_path)
190
+ content = File.read(properties_path)
191
+
192
+ # 匹配distributionUrl中的gradle版本
193
+ if content =~ /distributionUrl=.*gradle-(\d+\.\d+(?:\.\d+)?(?:-.*)?)-bin\.zip/
194
+ return $1
195
+ end
196
+
197
+ # 匹配gradleVersion属性
198
+ if content =~ /gradleVersion=(\d+\.\d+(?:\.\d+)?(?:-.*)?)/
199
+ return $1
200
+ end
201
+
202
+ nil
203
+ end
204
+
205
+ # 根据当前版本确定目标版本
206
+ def determine_target_gradle_version(current_version)
207
+
208
+ # 版本映射表:当前版本 -> 推荐版本
209
+ # 对于旧版本,统一升级到推荐的稳定版本
210
+ version_mapping = {
211
+ # Gradle 6.x 系列
212
+ '6.1.1' => RECOMMENDED_GRADLE_VERSION,
213
+ '6.1' => RECOMMENDED_GRADLE_VERSION,
214
+ '6.0' => RECOMMENDED_GRADLE_VERSION,
215
+
216
+ # Gradle 5.x 系列
217
+ '5.6' => RECOMMENDED_GRADLE_VERSION,
218
+ '5.5' => RECOMMENDED_GRADLE_VERSION,
219
+ '5.4' => RECOMMENDED_GRADLE_VERSION,
220
+ '5.3' => RECOMMENDED_GRADLE_VERSION,
221
+ '5.2' => RECOMMENDED_GRADLE_VERSION,
222
+ '5.1' => RECOMMENDED_GRADLE_VERSION,
223
+ '5.0' => RECOMMENDED_GRADLE_VERSION,
224
+
225
+ # Gradle 4.x 系列
226
+ '4.10' => RECOMMENDED_GRADLE_VERSION,
227
+ '4.9' => RECOMMENDED_GRADLE_VERSION,
228
+ '4.8' => RECOMMENDED_GRADLE_VERSION,
229
+ '4.7' => RECOMMENDED_GRADLE_VERSION,
230
+ '4.6' => RECOMMENDED_GRADLE_VERSION,
231
+ '4.5' => RECOMMENDED_GRADLE_VERSION,
232
+ '4.4' => RECOMMENDED_GRADLE_VERSION,
233
+ '4.3' => RECOMMENDED_GRADLE_VERSION,
234
+ '4.2' => RECOMMENDED_GRADLE_VERSION,
235
+ '4.1' => RECOMMENDED_GRADLE_VERSION,
236
+ '4.0' => RECOMMENDED_GRADLE_VERSION,
237
+
238
+ # Gradle 3.x 系列
239
+ '3.6' => RECOMMENDED_GRADLE_VERSION,
240
+ '3.5' => RECOMMENDED_GRADLE_VERSION,
241
+ '3.4' => RECOMMENDED_GRADLE_VERSION,
242
+ '3.3' => RECOMMENDED_GRADLE_VERSION,
243
+ '3.2' => RECOMMENDED_GRADLE_VERSION,
244
+ '3.1' => RECOMMENDED_GRADLE_VERSION,
245
+ '3.0' => RECOMMENDED_GRADLE_VERSION
246
+ }
247
+
248
+ # 精确匹配
249
+ if version_mapping.key?(current_version)
250
+ return version_mapping[current_version]
251
+ end
252
+
253
+ # 主版本号匹配
254
+ major_version = current_version.split('.').first.to_i
255
+ case major_version
256
+ when 0..6
257
+ return RECOMMENDED_GRADLE_VERSION # 旧版本升级到推荐版本
258
+ when 7
259
+ return current_version # 已经是7.x,保持当前版本
260
+ when 8
261
+ return current_version # 已经是8.x,保持当前版本
262
+ else
263
+ return RECOMMENDED_GRADLE_VERSION # 默认升级到推荐版本
264
+ end
265
+ end
266
+
267
+ # 生成gradle-wrapper.jar(使用gradle wrapper命令)
268
+ def download_gradle_wrapper_jar(wrapper_dir, gradle_version)
269
+ wrapper_jar_path = File.join(wrapper_dir, "gradle-wrapper.jar")
270
+
271
+ # 如果已存在且版本匹配,跳过生成
272
+ if File.exist?(wrapper_jar_path) && verify_gradle_wrapper_jar(wrapper_jar_path, gradle_version)
273
+ puts "\e[32m✓ gradle-wrapper.jar已存在且版本匹配\e[0m"
274
+ return true
275
+ end
276
+
277
+ puts "正在生成gradle-wrapper.jar (版本: #{gradle_version})..."
278
+
279
+ # 获取项目根目录
280
+ project_path = File.dirname(File.dirname(wrapper_dir))
281
+
282
+ # 检查是否有gradlew脚本
283
+ gradlew_path = File.join(project_path, "gradlew")
284
+
285
+ if File.exist?(gradlew_path)
286
+ puts "发现gradlew脚本,使用gradle wrapper命令生成..."
287
+ return generate_wrapper_with_gradlew(project_path, gradle_version)
288
+ else
289
+ puts "未发现gradlew脚本,使用gradle命令生成..."
290
+ return generate_wrapper_with_gradle(project_path, gradle_version)
291
+ end
292
+ end
293
+
294
+ # 使用gradlew脚本生成wrapper
295
+ def generate_wrapper_with_gradlew(project_path, gradle_version)
296
+ puts "使用gradlew脚本生成wrapper..."
297
+
298
+ # 切换到项目目录
299
+ Dir.chdir(project_path) do
300
+ # 使用gradlew wrapper命令生成wrapper
301
+ cmd = "./gradlew wrapper --gradle-version #{gradle_version}"
302
+ puts "执行命令: #{cmd}"
303
+
304
+ result = system(cmd)
305
+ if result
306
+ puts "\e[32m✓ gradle wrapper生成成功\e[0m"
307
+ return true
308
+ else
309
+ puts "\e[31m✗ gradle wrapper生成失败\e[0m"
310
+ return false
311
+ end
312
+ end
313
+ rescue => e
314
+ puts "\e[31m✗ gradle wrapper生成异常: #{e.message}\e[0m"
315
+ false
316
+ end
317
+
318
+ # 使用gradle命令生成wrapper
319
+ def generate_wrapper_with_gradle(project_path, gradle_version)
320
+ puts "使用gradle命令生成wrapper..."
321
+
322
+ # 检查系统是否有gradle命令
323
+ unless system("which gradle > /dev/null 2>&1")
324
+ puts "\e[33m⚠ 系统未安装gradle,使用简化的wrapper生成方式...\e[0m"
325
+ return generate_wrapper_manually(project_path, gradle_version)
326
+ end
327
+
328
+ # 切换到项目目录
329
+ Dir.chdir(project_path) do
330
+ # 使用gradle wrapper命令生成wrapper
331
+ cmd = "gradle wrapper --gradle-version #{gradle_version}"
332
+ puts "执行命令: #{cmd}"
333
+
334
+ result = system(cmd)
335
+ if result
336
+ puts "\e[32m✓ gradle wrapper生成成功\e[0m"
337
+ return true
338
+ else
339
+ puts "\e[31m✗ gradle wrapper生成失败\e[0m"
340
+ return false
341
+ end
342
+ end
343
+ rescue => e
344
+ puts "\e[31m✗ gradle wrapper生成异常: #{e.message}\e[0m"
345
+ false
346
+ end
347
+
348
+ # 手动生成wrapper(不使用临时目录)
349
+ def generate_wrapper_manually(project_path, gradle_version)
350
+ puts "手动生成gradle wrapper..."
351
+
352
+ # 确保wrapper目录存在
353
+ wrapper_dir = File.join(project_path, "gradle/wrapper")
354
+ FileUtils.mkdir_p(wrapper_dir)
355
+
356
+ # 生成gradlew脚本
357
+ gradlew_path = File.join(project_path, "gradlew")
358
+ unless File.exist?(gradlew_path)
359
+ puts "生成gradlew脚本..."
360
+ generate_gradlew_script(project_path)
361
+ end
362
+
363
+ # 生成gradle-wrapper.jar(使用预定义的jar文件)
364
+ wrapper_jar_path = File.join(wrapper_dir, "gradle-wrapper.jar")
365
+ unless File.exist?(wrapper_jar_path)
366
+ puts "生成gradle-wrapper.jar..."
367
+ # 这里可以使用一个通用的gradle-wrapper.jar文件
368
+ # 或者从网络下载一个标准的jar文件
369
+ return download_standard_wrapper_jar(wrapper_jar_path, gradle_version)
370
+ end
371
+
372
+ puts "\e[32m✓ gradle wrapper手动生成成功\e[0m"
373
+ true
374
+ rescue => e
375
+ puts "\e[31m✗ 手动生成wrapper异常: #{e.message}\e[0m"
376
+ false
377
+ end
378
+
379
+ # 下载标准的gradle-wrapper.jar
380
+ def download_standard_wrapper_jar(wrapper_jar_path, gradle_version)
381
+ puts "下载标准的gradle-wrapper.jar..."
382
+
383
+ # 使用gradle官方提供的wrapper jar下载URL
384
+ wrapper_jar_urls = [
385
+ "https://github.com/gradle/gradle/raw/v#{gradle_version}/gradle/wrapper/gradle-wrapper.jar",
386
+ "https://raw.githubusercontent.com/gradle/gradle/v#{gradle_version}/gradle/wrapper/gradle-wrapper.jar"
387
+ ]
388
+
389
+ wrapper_jar_urls.each do |url|
390
+ puts "尝试下载: #{url}"
391
+ if download_with_curl(url, wrapper_jar_path)
392
+ if File.exist?(wrapper_jar_path) && File.size(wrapper_jar_path) > 1000
393
+ puts "\e[32m✓ gradle-wrapper.jar下载成功\e[0m"
394
+ return true
395
+ end
396
+ end
397
+ end
398
+
399
+ puts "\e[31m✗ 下载gradle-wrapper.jar失败\e[0m"
400
+ false
401
+ end
402
+
403
+ # 下载gradle分发包并生成wrapper
404
+ def download_and_generate_wrapper(project_path, gradle_version)
405
+ puts "下载gradle分发包并生成wrapper..."
406
+
407
+ begin
408
+ # 创建临时目录
409
+ temp_dir = Dir.mktmpdir("gradle_download_")
410
+ gradle_dir = File.join(temp_dir, "gradle-#{gradle_version}")
411
+
412
+ # 下载gradle分发包
413
+ download_urls = [
414
+ "https://services.gradle.org/distributions/gradle-#{gradle_version}-bin.zip",
415
+ "https://github.com/gradle/gradle-distributions/releases/download/v#{gradle_version}/gradle-#{gradle_version}-bin.zip"
416
+ ]
417
+
418
+ download_success = false
419
+ download_urls.each do |url|
420
+ puts "尝试下载: #{url}"
421
+ zip_path = File.join(temp_dir, "gradle-#{gradle_version}-bin.zip")
422
+
423
+ if download_with_curl(url, zip_path)
424
+ # 解压gradle分发包
425
+ if system("cd #{temp_dir} && unzip -q gradle-#{gradle_version}-bin.zip")
426
+ download_success = true
427
+ puts "✓ gradle分发包下载并解压成功"
428
+ break
429
+ end
430
+ end
431
+ end
432
+
433
+ unless download_success
434
+ puts "\e[31m✗ 下载gradle分发包失败\e[0m"
435
+ return false
436
+ end
437
+
438
+ # 使用下载的gradle生成wrapper
439
+ gradle_bin = File.join(gradle_dir, "bin", "gradle")
440
+ if File.exist?(gradle_bin)
441
+ Dir.chdir(project_path) do
442
+ cmd = "#{gradle_bin} wrapper --gradle-version #{gradle_version}"
443
+ puts "执行命令: #{cmd}"
444
+
445
+ result = system(cmd)
446
+ if result
447
+ puts "\e[32m✓ gradle wrapper生成成功\e[0m"
448
+ # 重要:在清理临时目录之前,确保wrapper已经生成完成
449
+ # 等待一下确保文件写入完成
450
+ sleep(1)
451
+ return true
452
+ else
453
+ puts "\e[31m✗ gradle wrapper生成失败\e[0m"
454
+ return false
455
+ end
456
+ end
457
+ else
458
+ puts "\e[31m✗ 未找到gradle可执行文件\e[0m"
459
+ return false
460
+ end
461
+
462
+ rescue => e
463
+ puts "\e[31m✗ 下载并生成wrapper异常: #{e.message}\e[0m"
464
+ false
465
+ ensure
466
+ # 延迟清理临时目录,确保wrapper生成完成
467
+ if temp_dir && File.directory?(temp_dir)
468
+ puts "清理临时目录: #{temp_dir}"
469
+ FileUtils.rm_rf(temp_dir)
470
+ end
471
+ end
472
+ end
473
+
474
+ # 使用curl下载文件(备用方案)
475
+ def download_with_curl(url, file_path)
476
+ puts "使用curl下载: #{url}"
477
+
478
+ # 使用curl命令下载,支持重定向和SSL
479
+ curl_cmd = [
480
+ 'curl',
481
+ '-L', # 跟随重定向
482
+ '-s', # 静默模式
483
+ '--connect-timeout', '30', # 连接超时
484
+ '--max-time', '300', # 最大时间5分钟
485
+ '--retry', '3', # 重试3次
486
+ '--retry-delay', '2', # 重试延迟2秒
487
+ '--user-agent', 'Pindo Gradle Wrapper Helper/1.0',
488
+ '-o', file_path, # 输出文件
489
+ url
490
+ ]
491
+
492
+ if system(*curl_cmd)
493
+ if File.exist?(file_path) && File.size(file_path) > 0
494
+ puts "\e[32m✓ curl下载成功: #{File.size(file_path)} 字节\e[0m"
495
+ return true
496
+ else
497
+ puts "\e[31m✗ curl下载失败: 文件为空或不存在\e[0m"
498
+ return false
499
+ end
500
+ else
501
+ puts "\e[31m✗ curl下载失败: 命令执行失败\e[0m"
502
+ return false
503
+ end
504
+ rescue => e
505
+ puts "\e[31m✗ curl下载异常: #{e.message}\e[0m"
506
+ false
507
+ end
508
+
509
+ # 验证gradle-wrapper.jar文件
510
+ def verify_gradle_wrapper_jar(jar_path, expected_version)
511
+ # 检查文件是否存在且大小合理
512
+ File.exist?(jar_path) && File.size(jar_path) > MIN_GRADLE_WRAPPER_JAR_SIZE
513
+ end
514
+
515
+
516
+ # 从gradle分发包中提取gradle-wrapper.jar
517
+ def extract_gradle_wrapper_jar(zip_path, target_path)
518
+ puts "正在从gradle分发包中提取gradle-wrapper.jar..."
519
+ puts "ZIP文件: #{zip_path}"
520
+ puts "ZIP文件大小: #{File.size(zip_path)} 字节"
521
+
522
+ Zip::File.open(zip_path) do |zip_file|
523
+ puts "ZIP文件包含 #{zip_file.count} 个文件"
524
+
525
+ # 列出ZIP文件中的所有文件(用于调试)
526
+ puts "ZIP文件内容:"
527
+ zip_file.each_with_index do |entry, index|
528
+ puts " #{index + 1}. #{entry.name}"
529
+ break if index >= 10 # 只显示前10个文件
530
+ end
531
+ puts " ..." if zip_file.count > 10
532
+
533
+ # 查找gradle-wrapper.jar
534
+ wrapper_entry = zip_file.find { |entry| entry.name.include?('gradle-wrapper.jar') }
535
+
536
+ if wrapper_entry
537
+ puts "找到gradle-wrapper.jar: #{wrapper_entry.name}"
538
+ wrapper_entry.extract(target_path)
539
+ puts "\e[32m✓ gradle-wrapper.jar提取成功\e[0m"
540
+ return true
541
+ else
542
+ puts "\e[31m✗ 在gradle分发包中未找到gradle-wrapper.jar\e[0m"
543
+ puts "尝试查找其他可能的wrapper文件..."
544
+
545
+ # 查找其他可能的wrapper文件
546
+ wrapper_entries = zip_file.select { |entry| entry.name.include?('wrapper') }
547
+ if wrapper_entries.any?
548
+ puts "找到以下wrapper相关文件:"
549
+ wrapper_entries.each do |entry|
550
+ puts " - #{entry.name}"
551
+ end
552
+ else
553
+ puts "未找到任何wrapper相关文件"
554
+ end
555
+
556
+ return false
557
+ end
558
+ end
559
+ rescue => e
560
+ puts "\e[31m✗ 解压gradle-wrapper.jar失败: #{e.message}\e[0m"
561
+ false
562
+ end
563
+
564
+ # 生成gradlew脚本
565
+ def generate_gradlew_script(project_path)
566
+ gradlew_path = File.join(project_path, "gradlew")
567
+
568
+ # 如果已存在gradlew,检查是否需要更新
569
+ if File.exist?(gradlew_path)
570
+ puts "\e[32m✓ gradlew脚本已存在\e[0m"
571
+ return true
572
+ end
573
+
574
+ puts "正在生成gradlew脚本..."
575
+
576
+ # 生成gradlew脚本内容(通用脚本,不依赖版本)
577
+ gradlew_content = generate_gradlew_content()
578
+
579
+ # 写入gradlew文件
580
+ File.write(gradlew_path, gradlew_content)
581
+
582
+ # 设置执行权限
583
+ system("chmod", "+x", gradlew_path)
584
+
585
+ puts "\e[32m✓ gradlew脚本生成完成\e[0m"
586
+ true
587
+ end
588
+
589
+ # 生成gradlew脚本内容(通用脚本,适用于所有Gradle项目)
590
+ def generate_gradlew_content()
591
+ <<~GRADLEW
592
+ #!/bin/sh
593
+
594
+ #
595
+ # Copyright © 2015-2021 the original authors.
596
+ #
597
+ # Licensed under the Apache License, Version 2.0 (the "License");
598
+ # you may not use this file except in compliance with the License.
599
+ # You may obtain a copy of the License at
600
+ #
601
+ # https://www.apache.org/licenses/LICENSE-2.0
602
+ #
603
+ # Unless required by applicable law or agreed to in writing, software
604
+ # distributed under the License is distributed on an "AS IS" BASIS,
605
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
606
+ # See the License for the specific language governing permissions and
607
+ # limitations under the License.
608
+ #
609
+
610
+ ##############################################################################
611
+ #
612
+ # Gradle start up script for UNIX
613
+ #
614
+ ##############################################################################
615
+
616
+ # Attempt to set APP_HOME
617
+
618
+ # Resolve links: $0 may be a link
619
+ app_path=$0
620
+
621
+ # Need this for daisy-chained symlinks.
622
+ while
623
+ APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
624
+ [ -h "$app_path" ]
625
+ do
626
+ ls=$( ls -ld "$app_path" )
627
+ link=${ls#*' -> '}
628
+ case $link in #(
629
+ /*) app_path=$link ;; #(
630
+ *) app_path=$APP_HOME$link ;;
631
+ esac
632
+ done
633
+
634
+ # This is normally unused
635
+ # shellcheck disable=SC2034
636
+ APP_BASE_NAME=${0##*/}
637
+ APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
638
+
639
+ # Use the maximum available, or set MAX_FD != -1 to use that value.
640
+ MAX_FD=maximum
641
+
642
+ warn () {
643
+ echo "$*"
644
+ } >&2
645
+
646
+ die () {
647
+ echo
648
+ echo "$*"
649
+ echo
650
+ exit 1
651
+ } >&2
652
+
653
+ # OS specific support (must be 'true' or 'false').
654
+ cygwin=false
655
+ msys=false
656
+ darwin=false
657
+ nonstop=false
658
+ case "$( uname )" in #(
659
+ CYGWIN* ) cygwin=true ;; #(
660
+ Darwin* ) darwin=true ;; #(
661
+ MSYS* | MINGW* ) msys=true ;; #(
662
+ NONSTOP* ) nonstop=true ;;
663
+ esac
664
+
665
+ CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
666
+
667
+
668
+ # Determine the Java command to use to start the JVM.
669
+ if [ -n "$JAVA_HOME" ] ; then
670
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
671
+ # IBM's JDK on AIX uses strange locations for the executables
672
+ JAVACMD=$JAVA_HOME/jre/sh/java
673
+ else
674
+ JAVACMD=$JAVA_HOME/bin/java
675
+ fi
676
+ if [ ! -x "$JAVACMD" ] ; then
677
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
678
+
679
+ Please set the JAVA_HOME variable in your environment to match the
680
+ location of your Java installation."
681
+ fi
682
+ else
683
+ JAVACMD=java
684
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
685
+
686
+ Please set the JAVA_HOME variable in your environment to match the
687
+ location of your Java installation."
688
+ fi
689
+
690
+ # Increase the maximum file descriptors if we can.
691
+ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
692
+ case $MAX_FD in #(
693
+ max*)
694
+ # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
695
+ # shellcheck disable=SC2039,SC3045
696
+ MAX_FD=$( ulimit -H -n ) ||
697
+ warn "Could not query maximum file descriptor limit"
698
+ esac
699
+ case $MAX_FD in #(
700
+ '' | soft) :;; #(
701
+ *)
702
+ # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
703
+ # shellcheck disable=SC2039,SC3045
704
+ ulimit -n "$MAX_FD" ||
705
+ warn "Could not set maximum file descriptor limit to $MAX_FD"
706
+ esac
707
+ fi
708
+
709
+ # Collect all arguments for the java command, stacking in reverse order:
710
+ # * args from the command line
711
+ # * the main class name
712
+ # * -classpath
713
+ # * -D...appname settings
714
+ # * --module-path (only if needed)
715
+ # * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
716
+
717
+ # For Cygwin or MSYS, switch paths to Windows format before running java
718
+ if "$cygwin" || "$msys" ; then
719
+ APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
720
+ CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
721
+
722
+ JAVACMD=$( cygpath --unix "$JAVACMD" )
723
+
724
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
725
+ for arg do
726
+ if
727
+ case $arg in #(
728
+ -*) false ;; # don't mess with options #(
729
+ /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
730
+ [ -e "$t" ] ;; #(
731
+ *) false ;;
732
+ esac
733
+ then
734
+ arg=$( cygpath --path --ignore --mixed "$arg" )
735
+ fi
736
+ # Roll the args list around exactly as many times as the number of
737
+ # args, so each arg winds up back in the position where it started, but
738
+ # possibly modified.
739
+ #
740
+ # NB: a `for` loop captures its iteration list before it begins, so
741
+ # changing the positional parameters here affects neither the number of
742
+ # iterations, nor the values presented in `arg`.
743
+ shift # remove old arg
744
+ set -- "$@" "$arg" # push replacement arg
745
+ done
746
+ fi
747
+
748
+
749
+ # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
750
+ DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
751
+
752
+ # Collect all arguments for the java command:
753
+ # * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
754
+ # and any embedded shellness will be escaped.
755
+ # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
756
+ # treated as '${Hostname}' itself on the command line.
757
+
758
+ set -- \\
759
+ "-Dorg.gradle.appname=$APP_BASE_NAME" \\
760
+ -classpath "$CLASSPATH" \\
761
+ org.gradle.wrapper.GradleWrapperMain \\
762
+ "$@"
763
+
764
+ # Stop when "xargs" is not available.
765
+ if ! command -v xargs >/dev/null 2>&1
766
+ then
767
+ die "xargs is not available"
768
+ fi
769
+
770
+ # Use "xargs" to parse quoted args.
771
+ #
772
+ # With -n1 it outputs one arg per line, with the quotes and backslashes removed.
773
+ #
774
+ # In Bash we could simply go:
775
+ #
776
+ # readarray ARGS < <( xargs -n1 <<<"$var" ) &&
777
+ # set -- "${ARGS[@]}" "$@"
778
+ #
779
+ # but POSIX shell has neither arrays nor command substitution, so instead we
780
+ # post-process each arg (as a line of input to sed) to backslash-escape any
781
+ # character that might be a shell metacharacter, then use eval to reverse
782
+ # that process (while maintaining the separation between arguments).
783
+ #
784
+ # This will of course break if any of these variables contains a newline or
785
+ # an unmatched quote.
786
+ #
787
+
788
+ eval "set -- $(
789
+ printf '%s\\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
790
+ xargs -n1 |
791
+ sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |
792
+ tr '\\n' ' '
793
+ )" '"$@"'
794
+
795
+ exec "$JAVACMD" "$@"
796
+ GRADLEW
54
797
  end
55
798
 
56
799
  end