pindo 5.11.4 → 5.12.2

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 (48) hide show
  1. checksums.yaml +4 -4
  2. data/lib/pindo/base/githelper.rb +16 -0
  3. data/lib/pindo/base/pindocontext.rb +13 -4
  4. data/lib/pindo/command/android/autobuild.rb +108 -185
  5. data/lib/pindo/command/android/build.rb +10 -2
  6. data/lib/pindo/command/ios/autobuild.rb +116 -213
  7. data/lib/pindo/command/ios/build.rb +12 -3
  8. data/lib/pindo/command/jps/upload.rb +253 -118
  9. data/lib/pindo/command/unity/autobuild.rb +297 -227
  10. data/lib/pindo/command/unity.rb +0 -3
  11. data/lib/pindo/command/utils/boss.rb +18 -15
  12. data/lib/pindo/command/utils/clearcert.rb +26 -18
  13. data/lib/pindo/command/utils/device.rb +28 -19
  14. data/lib/pindo/command/utils/feishu.rb +11 -4
  15. data/lib/pindo/command/utils/icon.rb +26 -20
  16. data/lib/pindo/command/utils/renewcert.rb +35 -29
  17. data/lib/pindo/command/utils/renewproj.rb +32 -25
  18. data/lib/pindo/command/utils/repoinit.rb +1 -1
  19. data/lib/pindo/command/utils/tag.rb +6 -180
  20. data/lib/pindo/command/utils/tgate.rb +34 -28
  21. data/lib/pindo/command/utils/xcassets.rb +30 -20
  22. data/lib/pindo/command/web/autobuild.rb +148 -128
  23. data/lib/pindo/module/android/android_build_helper.rb +0 -6
  24. data/lib/pindo/module/android/android_config_helper.rb +4 -26
  25. data/lib/pindo/module/build/build_helper.rb +18 -294
  26. data/lib/pindo/module/build/git_repo_helper.rb +530 -0
  27. data/lib/pindo/module/build/icon_downloader.rb +85 -0
  28. data/lib/pindo/module/pgyer/pgyerhelper.rb +16 -11
  29. data/lib/pindo/module/task/model/build/android_dev_build_task.rb +209 -0
  30. data/lib/pindo/module/task/model/build/android_release_build_task.rb +29 -0
  31. data/lib/pindo/module/task/model/build/ios_adhoc_build_task.rb +53 -0
  32. data/lib/pindo/module/task/model/build/ios_dev_build_task.rb +251 -0
  33. data/lib/pindo/module/task/model/build/ios_release_build_task.rb +53 -0
  34. data/lib/pindo/module/task/model/build/web_dev_build_task.rb +43 -0
  35. data/lib/pindo/module/task/model/build_task.rb +125 -301
  36. data/lib/pindo/module/task/model/git_tag_task.rb +80 -0
  37. data/lib/pindo/module/task/model/unity_export_task.rb +53 -41
  38. data/lib/pindo/module/task/model/upload_task.rb +149 -208
  39. data/lib/pindo/module/task/pindo_task.rb +135 -95
  40. data/lib/pindo/module/task/task_manager.rb +202 -352
  41. data/lib/pindo/module/unity/unity_helper.rb +7 -3
  42. data/lib/pindo/module/xcode/xcode_build_config.rb +4 -10
  43. data/lib/pindo/module/xcode/xcode_build_helper.rb +19 -0
  44. data/lib/pindo/version.rb +1 -1
  45. metadata +10 -4
  46. data/lib/pindo/command/unity/apk.rb +0 -185
  47. data/lib/pindo/command/unity/ipa.rb +0 -198
  48. data/lib/pindo/command/unity/web.rb +0 -163
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a75938a4d1faa0bfd2b4495da318e4eabda71704345a47af18fa252c0f8d78ca
4
- data.tar.gz: 8cb15952591243cee1081720169bd5835626ac990cc3e91a1fac6964114e122e
3
+ metadata.gz: 6095e9d8ae3f34ca9e43e111344d3769c62e4d23b929ed2f8dcbab2288296107
4
+ data.tar.gz: 9c45c852836d6c9549d1625866fbee560dd38abb1b793401b80ff3c103e2f5a8
5
5
  SHA512:
6
- metadata.gz: 11e4c1ba858176b538827aa9bed454f1d1294d10a90ea6f6c0f4665e12ed02e0a32ad33145dade2adda700b8e41098b79e4775e8fca71191c67cc85d7da26552
7
- data.tar.gz: f50d76e666f5d061c41e89c23791aa347299e4c157a52eb5080c37f7bd750e58bb76f0ad6c3ddace280e7c64d69223ca61b152b1c0fd56b2c6a8d78dd5aa42f5
6
+ metadata.gz: 74666b706663478292b86f5caacd7c17846507ce8aef44b8b7481c73d84f89f9a766c425939c2b5954dc536b480e150d3fff174325683f2b44e5b5d067e8477d
7
+ data.tar.gz: ca31fa0a538fac32db28d7e657a04b0eb3c3304880e3dbb219c1787c26e4bf6f264e4b2e3181acb84378fdb48f4250a13bc6f719c3e30546ab848e271d090058
@@ -646,6 +646,22 @@ module Pindo
646
646
  new_tag
647
647
  end
648
648
 
649
+ # 检查仓库是否有未提交的更改(包括未暂存和已暂存的更改)
650
+ # @param git_root_dir [String] 项目目录路径
651
+ # @return [Boolean] 如果有未提交的更改返回true,否则返回false
652
+ def has_uncommitted_changes?(git_root_dir:nil)
653
+ return false if git_root_dir.nil?
654
+
655
+ begin
656
+ # 使用 git status --porcelain 检查是否有更改
657
+ # 如果输出不为空,说明有未提交的更改
658
+ status_output = git!(%W(-C #{git_root_dir} status --porcelain)).strip
659
+ !status_output.empty?
660
+ rescue StandardError => e
661
+ false
662
+ end
663
+ end
664
+
649
665
  # 检查tag是否在指定的commit上
650
666
  # @param git_root_dir [String] 项目目录路径
651
667
  # @param tag_name [String] 标签名称
@@ -109,13 +109,19 @@ module Pindo
109
109
  # 初始化三级结构(总是保存到内存,不管是否启用缓存)
110
110
  @memory_selections[project_path] ||= {}
111
111
  @memory_selections[project_path][root_command] ||= {}
112
- @memory_selections[project_path][root_command][key] = value
112
+
113
+ # 如果值为 nil,则删除该键而不是保存 nil
114
+ if value.nil?
115
+ @memory_selections[project_path][root_command].delete(key)
116
+ puts "[PindoContext] 从内存删除: [#{project_path}][#{root_command}][#{key}]" if verbose?
117
+ else
118
+ @memory_selections[project_path][root_command][key] = value
119
+ puts "[PindoContext] 保存到内存: [#{project_path}][#{root_command}][#{key}] = #{value.inspect}" if verbose?
120
+ end
113
121
 
114
122
  # 更新该命令组的最后修改时间
115
123
  @memory_selections[project_path][root_command]['__last_modified__'] = Time.now.to_i
116
124
 
117
- puts "[PindoContext] 保存到内存: [#{project_path}][#{root_command}][#{key}] = #{value.inspect}" if verbose?
118
-
119
125
  # 仅在启用缓存时保存到文件
120
126
  if @cache_enabled
121
127
  save_file_cache
@@ -306,6 +312,8 @@ module Pindo
306
312
  commands.each do |command, selections|
307
313
  file_cache[project_path][command] ||= {}
308
314
  selections.each do |key, value|
315
+ # 跳过 nil 值,不保存到文件
316
+ next if value.nil?
309
317
  # 将符号键转换为字符串
310
318
  string_key = key.to_s
311
319
  file_cache[project_path][command][string_key] = value
@@ -503,8 +511,9 @@ module Pindo
503
511
  puts "────────────────────────────────────────"
504
512
 
505
513
  cached_selections.each do |key, value|
506
- # 跳过内部字段
514
+ # 跳过内部字段和 nil 值
507
515
  next if key.to_s.start_with?('__')
516
+ next if value.nil?
508
517
 
509
518
  case key.to_s
510
519
  when 'bundle_id'
@@ -5,6 +5,11 @@ require 'pindo/module/build/build_helper'
5
5
  require 'pindo/module/build/version_helper'
6
6
  require 'pindo/module/android/android_build_helper'
7
7
  require 'pindo/module/android/android_config_helper'
8
+ require 'pindo/module/task/task_manager'
9
+ require 'pindo/module/task/model/git_tag_task'
10
+ require 'pindo/module/task/model/unity_export_task'
11
+ require 'pindo/module/task/model/build_task'
12
+ require 'pindo/module/task/model/upload_task'
8
13
 
9
14
  module Pindo
10
15
  class Command
@@ -85,214 +90,132 @@ module Pindo
85
90
  # 确认并应用缓存(如果有)
86
91
  context.confirm_and_apply_cache
87
92
 
93
+ # 准备配置
94
+ config = prepare_android_config(pindo_project_dir)
88
95
 
89
- @main_bundle_name = nil
90
- if @args_bundle_name
91
- @main_bundle_name = @args_bundle_name
92
- else
93
- @main_bundle_name = get_selected_dev_bundle_name()
94
- end
95
-
96
+ # 创建并执行任务
97
+ tasks = make_build_task(config)
96
98
 
97
- build_helper = Pindo::BuildHelper.share_instance
98
- project_type = build_helper.project_type(pindo_project_dir)
99
-
100
- args_temp = []
101
- args_temp << "--proj=#{@args_proj_name}" if @args_proj_name
102
- args_temp << "--bundle_name=#{@main_bundle_name}" if @main_bundle_name
103
- args_temp << "--upload" if @args_upload_flag
104
- args_temp << "--send" if @args_send_flag
99
+ # 添加到任务管理器并执行
100
+ task_manager = Pindo::TaskSystem::TaskManager.instance
101
+ task_manager.clear_all
102
+ tasks.each { |task| task_manager.add_task(task) }
103
+ task_manager.start
105
104
 
106
- case project_type
107
- when :ios
108
- puts "iOS 工程, 请使用 pindo ios build"
109
- when :android
110
- android_autobuild
111
- when :unity
112
- Pindo::Command::Unity::Apk::run(args_temp)
113
- else
114
- raise Informative, "当前目录不是工程目录,不能编译"
115
- end
105
+ system "open #{pindo_project_dir}"
116
106
  end
117
107
 
118
108
  private
119
109
 
120
- def android_autobuild
121
- # 记录构建开始时间
122
- build_start_time = Time.now
123
-
124
- pindo_project_dir = Dir.pwd
110
+ # 准备 Android 配置
111
+ def prepare_android_config(pindo_project_dir)
112
+ # 获取 Bundle Name
113
+ bundle_name = @args_bundle_name || get_selected_dev_bundle_name()
125
114
 
126
- build_helper = Pindo::BuildHelper.share_instance
127
- if @args_upload_flag
128
- is_need_add_tag,tag_action_parms = build_helper.check_is_need_add_tag?(pindo_project_dir)
129
- if is_need_add_tag
130
- Pindo::Command::Utils::Tag::run(tag_action_parms)
131
- end
132
- end
133
-
134
-
135
-
136
- app_info_obj = nil
137
- workflow_info = nil
138
- proj_name = @args_proj_name
139
- # 传入 package_type 获取 workflow_info
115
+ # 获取 JPS 配置
140
116
  app_info_obj, workflow_info = PgyerHelper.share_instace.prepare_upload(
141
- working_directory: Dir.pwd,
142
- proj_name: proj_name,
117
+ working_directory: pindo_project_dir,
118
+ proj_name: @args_proj_name,
143
119
  package_type: 'apk'
144
120
  )
145
121
 
146
- # ===== 使用 workflow 配置更新 Android 项目 =====
147
- if workflow_info && workflow_info[:package_name]
148
- workflow_packname = workflow_info[:package_name]
149
-
150
- puts "\n使用工作流配置更新 Android 项目:"
151
- puts " Workflow Package Name: #{workflow_packname}"
152
-
153
- # 一次性更新 App Name、Application ID 和 URL Schemes
154
- Pindo::AndroidConfigHelper.update_project_with_workflow(
155
- project_dir: pindo_project_dir,
156
- workflow_packname: workflow_packname
157
- )
158
- else
159
- raise Informative, "未获取到工作流信息"
160
- end
122
+ {
123
+ project_path: pindo_project_dir,
124
+ bundle_name: bundle_name,
125
+ app_info_obj: app_info_obj,
126
+ workflow_info: workflow_info
127
+ }
128
+ end
161
129
 
162
- # ===== 从 JPS 下载并替换项目 Icon =====
163
- if app_info_obj && app_info_obj["projectIcon"] && !app_info_obj["projectIcon"].empty?
164
- icon_replace_success = Pindo::AndroidConfigHelper.download_and_replace_icon_from_url(
165
- project_dir: pindo_project_dir,
166
- icon_url: app_info_obj["projectIcon"]
167
- )
130
+ # 创建构建任务
131
+ def make_build_task(config)
132
+ # 检测项目类型
133
+ build_helper = Pindo::BuildHelper.share_instance
134
+ project_type = build_helper.project_type(config[:project_path])
168
135
 
169
- # 如果 projectIcon 不为空且下载失败,抛出异常终止执行
170
- unless icon_replace_success
171
- raise Informative, "Icon 下载或替换失败,请检查 Icon URL 是否有效: #{app_info_obj["projectIcon"]}"
136
+ case project_type
137
+ when :ios
138
+ raise Informative, "iOS 工程, 请使用 pindo ios build"
139
+ when :android, :unity
140
+ # 判断是否是 Unity 工程
141
+ is_unity = (project_type == :unity)
142
+
143
+ tasks = []
144
+
145
+ # 1. Git 标签任务(所有编译场景都需要打 Tag)
146
+ git_tag_task = Pindo::TaskSystem::GitTagTask.new(config[:project_path])
147
+ tasks << git_tag_task
148
+
149
+ # 2. Unity 导出任务(仅 Unity 工程)
150
+ if is_unity
151
+ # 确定 Android 导出路径
152
+ base_android_path = File.join(config[:project_path], "GoodPlatform", "BaseAndroid")
153
+ android_path = File.join(config[:project_path], "GoodPlatform", "Android")
154
+ android_export_path = File.exist?(base_android_path) ? base_android_path : android_path
155
+
156
+ unity_context = {}
157
+ unity_context[:project_name] = @args_proj_name if @args_proj_name
158
+
159
+ unity_task = Pindo::TaskSystem::UnityExportTask.new(
160
+ 'android',
161
+ project_path: config[:project_path],
162
+ export_path: android_export_path,
163
+ context: unity_context
164
+ )
165
+ unity_task.dependencies << git_tag_task.id
166
+ tasks << unity_task
172
167
  end
173
- else
174
- Funlog.warning("未配置 Icon URL,跳过 Icon 替换")
175
- end
176
-
177
- # ===== 更新版本号和Build号(仅在Git仓库中)=====
178
- version_helper = Pindo::VersionHelper.share_instance
179
- version_info = version_helper.get_version_info(project_dir: pindo_project_dir)
180
-
181
- if version_info[:is_git_repo]
182
- # 更新Android工程版本
183
- Pindo::AndroidConfigHelper.update_android_project_version(
184
- project_dir: pindo_project_dir,
185
- version_name: version_info[:version],
186
- version_code: version_info[:build_number]
187
- )
188
- else
189
- Funlog.warning("非Git仓库,保持工程原有版本号")
190
- end
191
168
 
169
+ # 3. 构建任务
170
+ build_mode = @args_release_flag ? :release : :dev
192
171
 
193
- # ===== 如果指定了 bundle_name,覆盖 Application ID 和 google-services.json =====
194
- # 注意:这必须在 update_project_with_workflow 之后,以覆盖工作流的默认配置
195
- if @main_bundle_name && !@main_bundle_name.empty?
196
- puts "\n正在处理指定的 Bundle Name: #{@main_bundle_name}..."
197
-
198
- # 检查是否为通配符或通用 bundle_name
199
- # 如果是 com.test.* 或 com.test 这样的通配符,跳过配置更新
200
- is_wildcard = @main_bundle_name.include?('*') ||
201
- @main_bundle_name.end_with?('.') ||
202
- ['com.test', 'com.example', 'com.demo'].include?(@main_bundle_name)
203
-
204
- if is_wildcard
205
- puts " ⚠️ 检测到通配符或通用 Bundle Name: #{@main_bundle_name}"
206
- puts " ⚠️ 跳过 google-services.json 和 Application ID 更新"
172
+ # 确定 Android 项目路径
173
+ if is_unity
174
+ android_project_path = android_export_path
207
175
  else
208
- # 只有具体的 bundle_name 才执行配置更新
209
- # 直接使用 clong_buildconfig_repo 拉取配置仓库
210
- config_repo_dir = clong_buildconfig_repo(repo_name: @main_bundle_name)
211
-
212
- if config_repo_dir && File.exist?(config_repo_dir)
213
- # 1. 拷贝 google-services.json 到 launcher 目录
214
- Pindo::AndroidConfigHelper.copy_google_services_from_config_repo(
215
- config_repo_dir: config_repo_dir,
216
- project_dir: pindo_project_dir
217
- )
218
-
219
- # 2. 更新 Application ID 为指定的 bundle_name(覆盖工作流设置)
220
- Pindo::AndroidConfigHelper.update_application_id(
221
- project_dir: pindo_project_dir,
222
- application_id: @main_bundle_name
223
- )
224
-
225
- puts " ✓ Bundle Name 配置处理完成"
226
- else
227
- raise Informative, "无法获取配置仓库"
228
- end
176
+ android_project_path = config[:project_path]
229
177
  end
230
- end
231
178
 
232
- # 添加基于 Application ID 的 Scheme
233
- # 无论是使用 workflow 的默认 Application ID,还是通过 bundle_name 覆盖的,都需要添加对应的 Scheme
234
- Pindo::AndroidConfigHelper.add_application_id_based_scheme(
235
- project_dir: pindo_project_dir
236
- )
237
-
238
- begin
239
- android_build_helper = Pindo::AndroidBuildHelper.share_instance
240
- apk_path = android_build_helper.auto_build_apk(pindo_project_dir, !@args_release_flag)
241
- ipa_file_upload = Dir.glob(apk_path).max_by {|f| File.mtime(f)}
242
-
243
- if !ipa_file_upload.nil? && !app_info_obj.nil? && @args_upload_flag
244
- description = nil
245
- result_data = PgyerHelper.share_instace.start_upload(
246
- app_info_obj: app_info_obj,
247
- ipa_file_upload: ipa_file_upload,
248
- description: description,
249
- workflow_info: workflow_info
250
- )
251
- if !result_data.nil? && !result_data["data"].nil? && !result_data["data"]["id"].nil?
252
- PgyerHelper.share_instace.print_app_version_info(
253
- app_info_obj: app_info_obj,
254
- app_version_info_obj: result_data["data"]
255
- )
256
- # 始终发送给自己
257
- PgyerHelper.share_instace.send_apptest_msg(
258
- app_info_obj: app_info_obj,
259
- app_version_info_obj: result_data["data"],
260
- receiveType: "self"
261
- )
262
-
263
- # 如果有 --send 参数,额外发送到测试群
264
- if @args_send_flag
265
- PgyerHelper.share_instace.send_apptest_msg(
266
- app_info_obj: app_info_obj,
267
- app_version_info_obj: result_data["data"],
268
- chatEnv: "DevTest",
269
- receiveType: "chat"
270
- )
271
- end
272
- end
179
+ build_options = {
180
+ project_path: android_project_path,
181
+ bundle_name: config[:bundle_name],
182
+ proj_name: @args_proj_name,
183
+ upload: @args_upload_flag,
184
+ send: @args_send_flag,
185
+ app_info_obj: config[:app_info_obj],
186
+ workflow_info: config[:workflow_info]
187
+ }
188
+ build_options[:unity_root_path] = config[:project_path] if is_unity
189
+
190
+ build_task = Pindo::TaskSystem::BuildTask.create_task(
191
+ platform: :android,
192
+ mode: build_mode,
193
+ options: build_options
194
+ )
195
+ build_task.dependencies << tasks.last.id if tasks.any?
196
+ tasks << build_task
197
+
198
+ # 4. 上传任务(如果需要)
199
+ if @args_upload_flag
200
+ upload_task = Pindo::TaskSystem::UploadTask.new(
201
+ 'apk',
202
+ File.join(android_project_path, 'build'),
203
+ nil,
204
+ app_info_obj: config[:app_info_obj],
205
+ workflow_info: config[:workflow_info],
206
+ project_name: @args_proj_name,
207
+ context: {
208
+ send_to_chat: @args_send_flag
209
+ },
210
+ dependencies: [build_task.id]
211
+ )
212
+ tasks << upload_task
273
213
  end
274
214
 
275
- # 计算并显示总耗时
276
- total_time = Time.now - build_start_time
277
- minutes = (total_time / 60).to_i
278
- seconds = (total_time % 60).to_i
279
-
280
- if minutes > 0
281
- puts "\e[32m构建完成!总耗时: #{minutes}分#{seconds}秒\e[0m"
282
- else
283
- puts "\e[32m构建完成!总耗时: #{seconds}秒\e[0m"
284
- end
285
-
286
- puts "\e[32m正在打开目标文件夹...\e[0m"
287
- system "open #{pindo_project_dir}"
288
-
289
- rescue => e
290
- puts "\e[31m构建失败: #{e.message}\e[0m"
291
- puts "\e[33m正在打开项目文件夹以便检查错误...\e[0m"
292
- system "open #{pindo_project_dir}"
293
- raise e
215
+ tasks
216
+ else
217
+ raise Informative, "当前目录不是工程目录,不能编译"
294
218
  end
295
-
296
219
  end
297
220
  end
298
221
  end
@@ -2,6 +2,7 @@ require 'highline/import'
2
2
  require 'fileutils'
3
3
  require 'json'
4
4
  require 'pindo/module/build/build_helper'
5
+ require 'pindo/module/build/git_repo_helper'
5
6
  require 'pindo/module/android/android_build_helper'
6
7
 
7
8
  module Pindo
@@ -82,9 +83,16 @@ module Pindo
82
83
  pindo_project_dir = Dir.pwd
83
84
  build_helper = Pindo::BuildHelper.share_instance
84
85
  if @args_upload_flag
85
- is_need_add_tag,tag_action_parms = build_helper.check_is_need_add_tag?(pindo_project_dir)
86
+ git_repo_helper = Pindo::GitRepoHelper.share_instance
87
+ is_need_add_tag, tag_action_parms = git_repo_helper.check_is_need_add_tag?(pindo_project_dir)
86
88
  if is_need_add_tag
87
- Pindo::Command::Utils::Tag::run(tag_action_parms)
89
+ git_repo_helper.create_and_push_tag(
90
+ project_dir: pindo_project_dir,
91
+ mode: 'minor',
92
+ force_retag: tag_action_parms&.include?('--retag') || false,
93
+ custom_tag: nil,
94
+ release_branch: 'master'
95
+ )
88
96
  end
89
97
  end
90
98