pindo 5.14.7 → 5.15.1

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 (42) hide show
  1. checksums.yaml +4 -4
  2. data/lib/pindo/base/aeshelper.rb +53 -22
  3. data/lib/pindo/base/git_handler.rb +295 -32
  4. data/lib/pindo/client/giteeclient.rb +15 -6
  5. data/lib/pindo/command/android/autobuild.rb +7 -5
  6. data/lib/pindo/command/appstore/autobuild.rb +5 -2
  7. data/lib/pindo/command/appstore/cert.rb +6 -0
  8. data/lib/pindo/command/appstore/iap.rb +2 -3
  9. data/lib/pindo/command/ios/autobuild.rb +31 -21
  10. data/lib/pindo/command/ios/cert.rb +1 -1
  11. data/lib/pindo/command/jps/apptest.rb +1 -1
  12. data/lib/pindo/command/jps/bind.rb +6 -2
  13. data/lib/pindo/command/jps/media.rb +6 -2
  14. data/lib/pindo/command/jps/upload.rb +6 -4
  15. data/lib/pindo/command/repo/clone.rb +110 -32
  16. data/lib/pindo/command/repo/subgit.rb +91 -0
  17. data/lib/pindo/command/repo.rb +1 -0
  18. data/lib/pindo/command/unity/autobuild.rb +6 -4
  19. data/lib/pindo/command/unity/packbuild.rb +14 -7
  20. data/lib/pindo/command/utils/tag.rb +5 -3
  21. data/lib/pindo/command/web/autobuild.rb +7 -5
  22. data/lib/pindo/command.rb +1 -1
  23. data/lib/pindo/config/build_info_manager.rb +37 -14
  24. data/lib/pindo/module/appstore/bundleid_helper.rb +7 -3
  25. data/lib/pindo/module/build/git_repo_helper.rb +14 -35
  26. data/lib/pindo/module/cert/cert_helper.rb +33 -9
  27. data/lib/pindo/module/cert/xcode_cert_helper.rb +17 -7
  28. data/lib/pindo/module/pgyer/pgyerhelper.rb +110 -22
  29. data/lib/pindo/module/task/model/build/android_build_dev_task.rb +3 -2
  30. data/lib/pindo/module/task/model/build/ios_build_dev_task.rb +3 -2
  31. data/lib/pindo/module/task/model/git/git_commit_task.rb +107 -48
  32. data/lib/pindo/module/task/model/git/git_tag_task.rb +21 -20
  33. data/lib/pindo/module/task/model/git_task.rb +49 -0
  34. data/lib/pindo/module/task/model/jps/jps_bind_package_task.rb +8 -5
  35. data/lib/pindo/module/task/model/jps/jps_upload_media_task.rb +21 -13
  36. data/lib/pindo/module/task/model/jps/jps_workflow_message_task.rb +8 -4
  37. data/lib/pindo/module/task/model/resign/ipa_local_resign_task.rb +5 -0
  38. data/lib/pindo/options/core/option_item.rb +4 -5
  39. data/lib/pindo/options/groups/git_options.rb +40 -0
  40. data/lib/pindo/options/helpers/git_constants.rb +28 -0
  41. data/lib/pindo/version.rb +1 -1
  42. metadata +11 -15
@@ -146,14 +146,15 @@ module Pindo
146
146
 
147
147
  if git_root
148
148
  # 是 Git 仓库,自己计算版本号
149
- build_number = git_repo_helper.get_build_number_from_commit(project_dir: @project_path)
149
+ build_number, commit_hash = git_repo_helper.get_build_number_from_commit(project_dir: @project_path)
150
150
  build_version = git_repo_helper.calculate_build_version(
151
151
  project_dir: @project_path,
152
152
  tag_prefix: @tag_pre,
153
153
  create_tag_type: @tag_type,
154
154
  version_increase_type: @ver_inc
155
155
  )
156
- Funlog.instance.fancyinfo_success("自己计算版本号: #{build_version}, Build: #{build_number}")
156
+ commit_short = commit_hash ? commit_hash[0..7] : "unknown"
157
+ Funlog.instance.fancyinfo_success("自己计算版本号: #{build_version}, Build: #{build_number}, Commit: #{commit_short}")
157
158
  else
158
159
  # 不是 Git 仓库且没有从 GitCommitTask 获取到版本号,跳过版本更新
159
160
  Funlog.warning("非Git仓库且未从 GitCommitTask 获取到版本号,保持工程原有版本号")
@@ -159,14 +159,15 @@ module Pindo
159
159
 
160
160
  if git_root
161
161
  # 是 Git 仓库,自己计算版本号
162
- build_number = git_repo_helper.get_build_number_from_commit(project_dir: @project_path)
162
+ build_number, commit_hash = git_repo_helper.get_build_number_from_commit(project_dir: @project_path)
163
163
  build_version = git_repo_helper.calculate_build_version(
164
164
  project_dir: @project_path,
165
165
  tag_prefix: @tag_pre,
166
166
  create_tag_type: @tag_type,
167
167
  version_increase_type: @ver_inc
168
168
  )
169
- Funlog.instance.fancyinfo_success("自己计算版本号: #{build_version}, Build: #{build_number}")
169
+ commit_short = commit_hash ? commit_hash[0..7] : "unknown"
170
+ Funlog.instance.fancyinfo_success("自己计算版本号: #{build_version}, Build: #{build_number}, Commit: #{commit_short}")
170
171
  else
171
172
  # 不是 Git 仓库且没有从 GitCommitTask 获取到版本号,跳过版本更新
172
173
  Funlog.warning("非Git仓库且未从 GitCommitTask 获取到版本号,保持工程原有版本号")
@@ -1,15 +1,13 @@
1
1
  require 'pindo/module/task/model/git_task'
2
2
  require 'pindo/base/git_handler'
3
3
  require 'pindo/module/build/git_repo_helper'
4
+ require 'pindo/options/helpers/git_constants'
4
5
 
5
6
  module Pindo
6
7
  module TaskSystem
7
8
  # Git 提交任务
8
9
  # 负责检查并提交仓库的未提交修改
9
10
  class GitCommitTask < GitTask
10
- attr_reader :release_branch, :ver_inc, :tag_type, :tag_pre
11
- attr_reader :build_version, :build_number
12
-
13
11
  # 任务键
14
12
  def self.task_key
15
13
  :git_commit
@@ -37,18 +35,13 @@ module Pindo
37
35
  # 2. 执行 check_gitignore(可能创建新提交)
38
36
  # 3. 最终使用 fixed_version(如果有)或计算新版本号
39
37
  def initialize(project_path, options = {})
40
- @release_branch = options[:release_branch] || 'master'
41
- @ver_inc = options[:ver_inc] || Pindo::VersionIncreaseType::MINI
42
- @tag_type = options[:tag_type] || Pindo::CreateTagType::NEW
43
- @tag_pre = options[:tag_pre] || 'v'
38
+ # GitCommitTask 特有的属性
44
39
  @fixed_version = options[:fixed_version] # 外部指定的固定版本号
45
- @process_type = options[:process_type] || 'skip' # 默认跳过
40
+ @process_type = options[:process_type] || Pindo::UncommittedFilesProcessType::SKIP # 默认跳过
46
41
  @commit_message = options[:commit_message] || 'build: 构建产生提交' # 默认提交消息
47
42
 
48
- @build_version = nil
49
- @build_number = nil
50
43
  options[:project_path] = project_path
51
-
44
+ # 调用基类初始化(基类会设置 release_branch, ver_inc, tag_type, tag_pre 等通用属性)
52
45
  super("Git仓库文件提交检查", options)
53
46
  end
54
47
 
@@ -79,7 +72,7 @@ module Pindo
79
72
  # 1. 如果 fixed_version 为 nil,尝试从 HEAD 的 tag 获取版本
80
73
  # 必须在 check_gitignore 之前检查,因为 check_gitignore 可能创建提交导致 HEAD 移动
81
74
  if (@fixed_version.nil? || @fixed_version.empty?) &&
82
- git_repo_helper.head_has_version_tag?(project_dir: root_dir, tag_prefix: @tag_pre) &&
75
+ Pindo::GitHandler.head_has_version_tag?(project_dir: root_dir, tag_prefix: @tag_pre) &&
83
76
  !Pindo::GitHandler.has_uncommitted_changes?(git_root_dir: root_dir)
84
77
  # HEAD 有 tag 且工作目录干净,使用 tag 的版本
85
78
  latest_tag = Pindo::GitHandler.get_latest_version_tag(
@@ -87,7 +80,7 @@ module Pindo
87
80
  tag_prefix: @tag_pre
88
81
  )
89
82
  @fixed_version = latest_tag.sub(/^#{@tag_pre}/, '') if latest_tag
90
- Funlog.instance.fancyinfo_success("HEAD 存在 tag 且工作目录干净,设置 fixed_version: #{@fixed_version}")
83
+ Funlog.instance.fancyinfo_success("HEAD 存在 tag 且工作目录干净,会强制使用HEAD上的版本号: #{@fixed_version}")
91
84
  end
92
85
 
93
86
  # 2. 检查并修复 .gitignore(可能创建新提交,但 fixed_version 已经确定)
@@ -98,7 +91,7 @@ module Pindo
98
91
  begin
99
92
  Pindo::GitHandler.process_need_add_files(
100
93
  project_dir: root_dir,
101
- process_type: @process_type || 'skip',
94
+ process_type: @process_type || Pindo::UncommittedFilesProcessType::NONE,
102
95
  commit_message: @commit_message
103
96
  )
104
97
  rescue Pindo::Informative => e
@@ -112,10 +105,11 @@ module Pindo
112
105
 
113
106
  # 4. Stash 工作目录的残留修改(为分支同步做准备)
114
107
  stash_saved = false
108
+ stash_name = "pindo_stash_#{Time.now.strftime('%Y%m%d%H%M%S')}_#{rand(1000)}"
115
109
  status = Pindo::GitHandler.git!(%W(-C #{root_dir} status --porcelain)).strip
116
110
  unless status.empty?
117
- Funlog.instance.fancyinfo_update("工作目录有未提交更改,暂存到 stash")
118
- Pindo::GitHandler.git!(%W(-C #{root_dir} stash -u))
111
+ Funlog.instance.fancyinfo_update("工作目录有未提交更改,暂存到 stash: #{stash_name}")
112
+ Pindo::GitHandler.git!(%W(-C #{root_dir} stash push -u -m #{stash_name}))
119
113
  stash_saved = true
120
114
  end
121
115
 
@@ -141,26 +135,40 @@ module Pindo
141
135
  # 优先级 1: 如果指定了 fixed_version(外部传入或从 HEAD tag 获取),使用它
142
136
  if @fixed_version && !@fixed_version.empty?
143
137
  @build_version = @fixed_version
144
- @build_number = git_repo_helper.get_build_number_from_commit(project_dir: root_dir)
145
- Funlog.instance.fancyinfo_success("使用 fixed_version: #{@build_version}, Build: #{@build_number}")
138
+ @build_number, @commit_hash = git_repo_helper.get_build_number_from_commit(project_dir: root_dir)
139
+ commit_short = @commit_hash ? @commit_hash[0..7] : "unknown"
140
+ Funlog.instance.fancyinfo_success("Version: #{@build_version}, Build: #{@build_number}, Commit: #{commit_short}")
146
141
 
147
142
  # 优先级 2: 计算新版本号
148
143
  else
149
- @build_number = git_repo_helper.get_build_number_from_commit(project_dir: root_dir)
144
+ @build_number, @commit_hash = git_repo_helper.get_build_number_from_commit(project_dir: root_dir)
150
145
  @build_version = git_repo_helper.calculate_build_version(
151
146
  project_dir: root_dir,
152
147
  tag_prefix: @tag_pre,
153
148
  create_tag_type: @tag_type,
154
149
  version_increase_type: @ver_inc
155
150
  )
156
- Funlog.instance.fancyinfo_success("计算新版本号: #{@build_version}, Build: #{@build_number}")
151
+ commit_short = @commit_hash ? @commit_hash[0..7] : "unknown"
152
+ Funlog.instance.fancyinfo_success("Version: #{@build_version}, Build: #{@build_number}, Commit: #{commit_short}")
157
153
  end
158
154
 
155
+
159
156
  # 9. 还原 stash(如果之前有 stash)
160
157
  if stash_saved
161
158
  begin
162
- Pindo::GitHandler.git!(%W(-C #{root_dir} stash pop))
163
- Funlog.instance.fancyinfo_success("已还原 stash")
159
+ # 查找指定名字的 stash
160
+ stash_list = Pindo::GitHandler.git!(%W(-C #{root_dir} stash list)).strip
161
+ matched_line = stash_list.lines.find { |l| l.include?(stash_name) }
162
+
163
+ if matched_line && (stash_id = matched_line.match(/(stash@\{\d+\})/)&.[](1))
164
+ # 先应用 stash(不删除)
165
+ Pindo::GitHandler.git!(%W(-C #{root_dir} stash apply #{stash_id}))
166
+ # 应用成功后再删除 stash
167
+ Pindo::GitHandler.git!(%W(-C #{root_dir} stash drop #{stash_id}))
168
+ Funlog.instance.fancyinfo_success("已还原 stash: #{stash_name} (#{stash_id})")
169
+ else
170
+ Funlog.instance.fancyinfo_warning("未找到名为 #{stash_name} 的 stash,请手动检查")
171
+ end
164
172
  rescue => e
165
173
  Funlog.instance.fancyinfo_warning("stash 还原时发生冲突: #{e.message}")
166
174
  Funlog.instance.fancyinfo_warning("stash 已保留,请手动执行 'git stash pop' 处理冲突")
@@ -168,6 +176,10 @@ module Pindo
168
176
  end
169
177
  end
170
178
 
179
+
180
+ # 10. 显示主仓库和所有子仓库的 commit info
181
+ display_all_repos_commit_info(root_dir)
182
+
171
183
  {
172
184
  success: true,
173
185
  root_dir: root_dir,
@@ -176,39 +188,86 @@ module Pindo
176
188
  }
177
189
  end
178
190
 
179
- # 构建任务参数(供其他任务使用)
180
- def build_task_param
181
- return {} unless @status == TaskStatus::SUCCESS
191
+ # ----------------------------------------------------
192
+ # 10. 显示主仓库和所有子仓库的 commit id 和 commit message
193
+ # ----------------------------------------------------
194
+ def display_all_repos_commit_info(root_dir)
195
+ Funlog.instance.fancyinfo_start("仓库及子模块 Commit 信息概览")
182
196
 
183
- # 如果不是 Git 仓库,返回空参数(让依赖任务知道没有有效数据)
184
- return {} if @build_version.nil? || @build_number.nil?
197
+ # 10.1 主仓库
198
+ begin
199
+ main_info = Pindo::GitHandler.git!(%W(-C #{root_dir} log -1 --format=%h|%s)).strip
200
+ main_id, main_msg = main_info.split('|', 2)
201
+ puts ""
202
+ puts " [Main Repo] #{File.basename(root_dir)}".green
203
+ puts " Commit: #{main_id} - #{main_msg}"
204
+ rescue => e
205
+ Funlog.instance.warning("获取主仓库信息失败: #{e.message}")
206
+ end
185
207
 
186
- param = {
187
- release_branch: @release_branch,
188
- build_version: @build_version,
189
- build_number: @build_number,
190
- tag_pre: @tag_pre,
191
- tag_type: @tag_type,
192
- ver_inc: @ver_inc
193
- }
208
+ # 10.2 子模块
209
+ begin
210
+ # 使用 git submodule status 获取列表,更可靠
211
+ submodule_status_output = Pindo::GitHandler.git!(%W(-C #{root_dir} submodule status --recursive)).strip
212
+
213
+ unless submodule_status_output.empty?
214
+ puts ""
215
+ puts " [Submodules]".yellow
216
+ submodule_status_output.each_line do |line|
217
+ # line format: " 923... path/to/sub (v1.2)" or "-..." for uninitialized
218
+ parts = line.strip.split(' ')
219
+ next if parts.length < 2
220
+
221
+ clean_sha = parts[0].gsub(/^[-+U]/, '') # 去除状态前缀
222
+ short_sha = clean_sha[0..6]
223
+ sub_path = parts[1]
224
+ sub_abs_path = File.join(root_dir, sub_path)
225
+
226
+ # 只有当目录存在且是 git 仓库时才尝试读取 log
227
+ if File.directory?(sub_abs_path) && File.exist?(File.join(sub_abs_path, '.git'))
228
+ begin
229
+ # 使用 git show 指定 SHA 获取 message,避免 HEAD 指向不明的问题
230
+ raw_msg = Pindo::GitHandler.git!(%W(-C #{sub_abs_path} show -s --format=%s #{clean_sha}))
231
+ sub_msg = raw_msg.strip
232
+
233
+ # 处理编码问题:将 ASCII-8BIT 转换为 UTF-8,无效字符替换为 ?
234
+ if sub_msg.respond_to?(:force_encoding)
235
+ sub_msg.force_encoding("UTF-8")
236
+ unless sub_msg.valid_encoding?
237
+ sub_msg = sub_msg.encode("UTF-8", "binary", invalid: :replace, undef: :replace, replace: "?")
238
+ end
239
+ end
194
240
 
195
- # 添加 git commit 信息(供 JPSUploadMediaTask 等任务使用)
196
- if @git_root_path
197
- begin
198
- # 获取当前 HEAD commit 信息
199
- git_commit_info = Pindo::GitHandler.get_latest_conventional_commit(project_dir: @git_root_path)
200
- if git_commit_info
201
- param[:git_commit_id] = git_commit_info[:commit_id]
202
- param[:git_commit_time] = git_commit_info[:commit_time]
203
- param[:git_commit_desc] = git_commit_info[:commit_desc]
241
+ puts " • #{sub_path}: #{short_sha} - #{sub_msg}"
242
+ rescue => e
243
+ # 如果获取 log 失败,显示错误原因
244
+ puts " • #{sub_path}: #{short_sha} (获取Message失败: #{e.message.strip})"
245
+ end
246
+ else
247
+ # 未初始化或其他情况
248
+ status_char = parts[0][0] # 获取状态字符 (+, -, U, space)
249
+ status_desc = case status_char
250
+ when '-' then "未初始化"
251
+ when '+' then "版本不一致"
252
+ when 'U' then "合并冲突"
253
+ else "目录或.git不存在"
254
+ end
255
+ puts " • #{sub_path}: #{short_sha} (#{status_desc})"
256
+ end
204
257
  end
205
- rescue => e
206
- # 如果获取失败,不影响主流程
207
- Funlog.instance.fancyinfo_warning("获取 git commit 信息失败: #{e.message}") if ENV['PINDO_DEBUG']
208
258
  end
259
+ rescue => e
260
+ # 忽略子模块错误
261
+ # Funlog.instance.warning("获取子模块信息异常: #{e.message}")
209
262
  end
263
+
264
+ puts ""
265
+ Funlog.instance.fancyinfo_success("Commit 信息展示完成")
266
+ end
210
267
 
211
- param
268
+ # 在 do_work 结束前调用
269
+ def do_work_end_hook(root_dir)
270
+ display_all_repos_commit_info(root_dir)
212
271
  end
213
272
  end
214
273
  end
@@ -7,9 +7,6 @@ module Pindo
7
7
  # Git 标签任务
8
8
  # 负责在构建成功后创建 Git 标签
9
9
  class GitTagTask < GitTask
10
- attr_reader :release_branch, :ver_inc, :tag_type, :tag_pre
11
- attr_reader :build_version, :build_number
12
-
13
10
  # 任务键
14
11
  def self.task_key
15
12
  :git_tag
@@ -29,15 +26,8 @@ module Pindo
29
26
  # - tag_pre: tag前缀,默认 'v'
30
27
  # 注意:版本号从 GitCommitTask 获取(GitTagTask 必须依赖 GitCommitTask)
31
28
  def initialize(project_path, options = {})
32
- @release_branch = options[:release_branch] || 'master'
33
- @ver_inc = options[:ver_inc] || Pindo::VersionIncreaseType::MINI
34
- @tag_type = options[:tag_type] || Pindo::CreateTagType::NEW
35
- @tag_pre = options[:tag_pre] || 'v'
36
-
37
- @build_version = nil
38
- @build_number = nil
39
29
  options[:project_path] = project_path
40
-
30
+ # 调用基类初始化(基类会设置所有通用属性)
41
31
  super("Git仓库打Tag", options)
42
32
  end
43
33
 
@@ -62,14 +52,15 @@ module Pindo
62
52
  root_dir = @git_root_path
63
53
  git_repo_helper = Pindo::GitRepoHelper.share_instance
64
54
  stash_saved = false
55
+ stash_name = "pindo_stash_#{Time.now.strftime('%Y%m%d%H%M%S')}_#{rand(1000)}"
65
56
  coding_branch = Pindo::GitHandler.git!(%W(-C #{root_dir} rev-parse --abbrev-ref HEAD)).strip
66
57
 
67
58
  begin
68
59
  # 1. 检查工作目录,不干净则 stash
69
60
  status = Pindo::GitHandler.git!(%W(-C #{root_dir} status --porcelain)).strip
70
61
  unless status.empty?
71
- Funlog.instance.fancyinfo_update("工作目录有未提交更改,暂存到 stash")
72
- Pindo::GitHandler.git!(%W(-C #{root_dir} stash -u))
62
+ Funlog.instance.fancyinfo_update("工作目录有未提交更改,暂存到 stash: #{stash_name}")
63
+ Pindo::GitHandler.git!(%W(-C #{root_dir} stash push -u -m #{stash_name}))
73
64
  stash_saved = true
74
65
  end
75
66
 
@@ -98,14 +89,15 @@ module Pindo
98
89
 
99
90
  # 优先级 2: 自己计算(降级方案,用于向后兼容或 GitCommitTask 无有效数据)
100
91
  else
101
- @build_number = git_repo_helper.get_build_number_from_commit(project_dir: root_dir)
92
+ @build_number, @commit_hash = git_repo_helper.get_build_number_from_commit(project_dir: root_dir)
102
93
  @build_version = git_repo_helper.calculate_build_version(
103
94
  project_dir: root_dir,
104
95
  tag_prefix: @tag_pre,
105
96
  create_tag_type: @tag_type,
106
97
  version_increase_type: @ver_inc
107
98
  )
108
- Funlog.instance.fancyinfo_warning("未找到 GitCommitTask 依赖,降级为自己计算版本号: #{@build_version}")
99
+ commit_short = @commit_hash ? @commit_hash[0..7] : "unknown"
100
+ Funlog.instance.fancyinfo_warning("未找到 GitCommitTask 依赖,降级为自己计算版本号: #{@build_version}, Build: #{@build_number}, Commit: #{commit_short}")
109
101
  end
110
102
 
111
103
  # 4. 创建并推送 Tag
@@ -118,13 +110,22 @@ module Pindo
118
110
 
119
111
  ensure
120
112
  # 5. 还原 stash
113
+
121
114
  if stash_saved
122
115
  begin
123
- # 先应用 stash(不删除)
124
- Pindo::GitHandler.git!(%W(-C #{root_dir} stash apply))
125
- # 应用成功后再删除 stash
126
- Pindo::GitHandler.git!(%W(-C #{root_dir} stash drop))
127
- Funlog.instance.fancyinfo_success("已还原 stash")
116
+ # 查找指定名字的 stash
117
+ stash_list = Pindo::GitHandler.git!(%W(-C #{root_dir} stash list)).strip
118
+ matched_line = stash_list.lines.find { |l| l.include?(stash_name) }
119
+
120
+ if matched_line && (stash_id = matched_line.match(/(stash@\{\d+\})/)&.[](1))
121
+ # 先应用 stash(不删除)
122
+ Pindo::GitHandler.git!(%W(-C #{root_dir} stash apply #{stash_id}))
123
+ # 应用成功后再删除 stash
124
+ Pindo::GitHandler.git!(%W(-C #{root_dir} stash drop #{stash_id}))
125
+ Funlog.instance.fancyinfo_success("已还原 stash: #{stash_name} (#{stash_id})")
126
+ else
127
+ Funlog.instance.fancyinfo_warning("未找到名为 #{stash_name} 的 stash,请手动检查")
128
+ end
128
129
  rescue => e
129
130
  # 如果应用失败(通常是有冲突),stash 仍然保留,用户可以手动处理
130
131
  Funlog.instance.fancyinfo_warning("stash 还原时发生冲突: #{e.message}")
@@ -1,5 +1,6 @@
1
1
  require 'pindo/module/task/pindo_task'
2
2
  require 'pindo/base/git_handler'
3
+ require 'pindo/module/build/git_repo_helper'
3
4
 
4
5
  module Pindo
5
6
  module TaskSystem
@@ -7,10 +8,23 @@ module Pindo
7
8
  # 所有 Git 相关任务的父类,提供通用的 Git 操作和配置
8
9
  class GitTask < PindoTask
9
10
  attr_reader :project_path, :git_root_path
11
+ attr_reader :release_branch, :ver_inc, :tag_type, :tag_pre
12
+ attr_reader :build_version, :build_number, :commit_hash
10
13
 
11
14
  def initialize(name, options = {})
12
15
  @project_path = options[:project_path] ? File.expand_path(options[:project_path]) : nil
13
16
 
17
+ # Git 版本管理相关属性(子类可以覆盖默认值)
18
+ @release_branch = options[:release_branch] || 'master'
19
+ @ver_inc = options[:ver_inc] || Pindo::VersionIncreaseType::MINI
20
+ @tag_type = options[:tag_type] || Pindo::CreateTagType::NEW
21
+ @tag_pre = options[:tag_pre] || 'v'
22
+
23
+ # 版本信息(由子类在 do_work 中赋值)
24
+ @build_version = nil
25
+ @build_number = nil
26
+ @commit_hash = nil
27
+
14
28
  # 通过 project_path 获取 git_root_path
15
29
  @git_root_path = @project_path ? Pindo::GitHandler.git_root_directory(local_repo_dir: @project_path) : nil
16
30
 
@@ -76,6 +90,41 @@ module Pindo
76
90
  return nil unless @git_root_path
77
91
  Pindo::GitHandler.git!(%W(-C #{@git_root_path} rev-parse --abbrev-ref HEAD)).strip
78
92
  end
93
+
94
+ # 构建任务参数(供其他任务使用)
95
+ def build_task_param
96
+ return {} unless @status == TaskStatus::SUCCESS
97
+
98
+ # 如果不是 Git 仓库,返回空参数(让依赖任务知道没有有效数据)
99
+ return {} if @build_version.nil? || @build_number.nil?
100
+
101
+ param = {
102
+ release_branch: @release_branch,
103
+ build_version: @build_version,
104
+ build_number: @build_number,
105
+ tag_pre: @tag_pre,
106
+ tag_type: @tag_type,
107
+ ver_inc: @ver_inc
108
+ }
109
+
110
+ # 添加 git commit 信息(供 JPSUploadMediaTask 等任务使用)
111
+ if @git_root_path
112
+ begin
113
+ # 获取当前 HEAD commit 信息
114
+ git_commit_info = Pindo::GitHandler.get_latest_conventional_commit(project_dir: @git_root_path)
115
+ if git_commit_info
116
+ param[:git_commit_id] = git_commit_info[:commit_id]
117
+ param[:git_commit_time] = git_commit_info[:commit_time]
118
+ param[:git_commit_desc] = git_commit_info[:commit_desc]
119
+ end
120
+ rescue => e
121
+ # 如果获取失败,不影响主流程
122
+ Funlog.instance.fancyinfo_warning("获取 git commit 信息失败: #{e.message}") if ENV['PINDO_DEBUG']
123
+ end
124
+ end
125
+
126
+ param
127
+ end
79
128
  end
80
129
  end
81
130
  end
@@ -210,16 +210,19 @@ module Pindo
210
210
 
211
211
  # 从依赖任务获取或自动获取 git commit 信息
212
212
  def fetch_git_commit_info
213
- # 1. 首先尝试从 GitCommitTask 依赖任务获取
214
- git_commit_data = get_data_param_by_key(:git_commit)
215
- if git_commit_data && git_commit_data[:task_param]
216
- param = git_commit_data[:task_param]
213
+ # 1. 优先从 GitTagTask 依赖任务获取(打 tag 后的 commit 信息更准确)
214
+ git_data = get_data_param_by_key(:git_tag)
215
+ # 2. 降级到 GitCommitTask
216
+ git_data = get_data_param_by_key(:git_commit) if git_data.nil? || git_data.empty?
217
+
218
+ if git_data && git_data[:task_param]
219
+ param = git_data[:task_param]
217
220
  @git_commit_id = param[:git_commit_id] if param[:git_commit_id]
218
221
  @git_commit_time = param[:git_commit_time] if param[:git_commit_time]
219
222
  @git_commit_desc = param[:git_commit_desc] if param[:git_commit_desc]
220
223
  end
221
224
 
222
- # 2. 如果依赖任务没有提供,且指定了 project_dir,使用自动获取
225
+ # 3. 如果依赖任务都没有提供,且指定了 project_dir,使用自动获取
223
226
  if (@git_commit_id.nil? || @git_commit_id.empty?) && @project_dir
224
227
  # 查找 git 仓库根目录
225
228
  git_root = Pindo::GitHandler.git_root_directory(local_repo_dir: @project_dir)
@@ -97,17 +97,20 @@ module Pindo
97
97
 
98
98
  # 2. 如果没有提供 git_commit_id,尝试从依赖任务获取或自动获取
99
99
  if @git_commit_id.nil? || @git_commit_id.empty?
100
- # 2.1 首先尝试从 GitCommitTask 依赖任务获取
101
- git_commit_data = get_data_param_by_key(:git_commit)
102
- if git_commit_data && git_commit_data[:task_param]
103
- param = git_commit_data[:task_param]
100
+ # 2.1 优先从 GitTagTask 依赖任务获取(打 tag 后的 commit 信息更准确)
101
+ git_data = get_data_param_by_key(:git_tag)
102
+ # 2.2 降级到 GitCommitTask
103
+ git_data = get_data_param_by_key(:git_commit) if git_data.nil? || git_data.empty?
104
+
105
+ if git_data && git_data[:task_param]
106
+ param = git_data[:task_param]
104
107
  # 尝试从 task_param 获取 commit 信息
105
108
  @git_commit_id = param[:git_commit_id] if param[:git_commit_id]
106
109
  @git_commit_time = param[:git_commit_time] if param[:git_commit_time]
107
110
  @git_commit_desc = param[:git_commit_desc] if param[:git_commit_desc]
108
111
  end
109
112
 
110
- # 2.2 如果依赖任务没有提供,使用 get_latest_conventional_commit
113
+ # 2.3 如果依赖任务都没有提供,使用 get_latest_conventional_commit
111
114
  if @git_commit_id.nil? || @git_commit_id.empty?
112
115
  git_info = Pindo::GitHandler.get_latest_conventional_commit(project_dir: git_root)
113
116
  @git_commit_id = git_info[:commit_id]
@@ -291,7 +294,7 @@ module Pindo
291
294
  FileUtils.mkdir_p(backup_dir) unless Dir.exist?(backup_dir)
292
295
 
293
296
  # 移动文件
294
- file_name = File.basename(file_path)
297
+ file_name = File.basename(file_path).force_encoding('UTF-8').scrub('')
295
298
  dest_path = File.join(backup_dir, file_name)
296
299
 
297
300
  # 如果目标文件已存在,添加序号避免覆盖
@@ -388,11 +391,12 @@ module Pindo
388
391
  puts ""
389
392
  files.each_with_index do |file, index|
390
393
  size_str = format_file_size(File.size(file))
391
- file_name = File.basename(file)
394
+ file_name = File.basename(file).force_encoding('UTF-8').scrub('')
392
395
  # 对齐:序号(3位) + 文件名(左对齐) + 大小(右对齐)
393
396
  puts " \e[90m#{(index + 1).to_s.rjust(2)}.\e[0m %-40s \e[33m%8s\e[0m" % [file_name, size_str]
394
397
  if debug_mode
395
- puts " \e[90m路径: #{file}\e[0m"
398
+ safe_path = file.force_encoding('UTF-8').scrub('')
399
+ puts " \e[90m路径: #{safe_path}\e[0m"
396
400
  end
397
401
  end
398
402
  puts ""
@@ -419,7 +423,7 @@ module Pindo
419
423
  failed_files = []
420
424
 
421
425
  files.each_with_index do |file, index|
422
- file_name = File.basename(file)
426
+ file_name = File.basename(file).force_encoding('UTF-8').scrub('')
423
427
 
424
428
  # 显示进度(简洁模式)
425
429
  progress = "#{index + 1}/#{files.size}"
@@ -430,7 +434,10 @@ module Pindo
430
434
  # MacCompressCliTool 的 -f 参数需要一个包含文件路径列表的文本文件
431
435
  file_list_path = File.join(compress_dir, "file_list_#{index}.txt")
432
436
  File.open(file_list_path, 'w:UTF-8') do |f|
433
- f.puts(file)
437
+ # 强制将文件路径转换为 UTF-8 编码,处理无效字符
438
+ # 避免 "incompatible character encodings: UTF-8 and BINARY" 错误
439
+ safe_path = file.force_encoding('UTF-8').scrub('')
440
+ f.puts(safe_path)
434
441
  end
435
442
 
436
443
  # 调用压缩工具: compress-cli -s -f file_list.txt -o output_dir/
@@ -441,7 +448,8 @@ module Pindo
441
448
 
442
449
  if debug_mode
443
450
  puts ""
444
- puts " \e[90m完整路径: #{file}\e[0m"
451
+ safe_file = file.force_encoding('UTF-8').scrub('')
452
+ puts " \e[90m完整路径: #{safe_file}\e[0m"
445
453
  puts " \e[90m文件列表: #{file_list_path}\e[0m"
446
454
  puts " \e[90m执行命令: #{cmd}\e[0m"
447
455
  print " "
@@ -494,7 +502,7 @@ module Pindo
494
502
  if all_files.empty?
495
503
  puts " \e[90m(目录为空)\e[0m"
496
504
  else
497
- all_files.each { |f| puts " \e[90m- #{File.basename(f)}\e[0m" }
505
+ all_files.each { |f| puts " \e[90m- #{File.basename(f).force_encoding('UTF-8').scrub('')}\e[0m" }
498
506
  end
499
507
  else
500
508
  puts " \e[90m(目录不存在)\e[0m"
@@ -529,7 +537,7 @@ module Pindo
529
537
  puts ""
530
538
  puts " \e[31m失败文件 (#{failed_files.size}):\e[0m"
531
539
  failed_files.each do |f|
532
- puts " \e[31m✗\e[0m #{File.basename(f)}"
540
+ puts " \e[31m✗\e[0m #{File.basename(f).force_encoding('UTF-8').scrub('')}"
533
541
  end
534
542
  end
535
543
 
@@ -93,11 +93,15 @@ module Pindo
93
93
 
94
94
  # 从依赖任务获取数据
95
95
  def fetch_data_from_dependencies
96
- # 1. 从 GitCommitTask 获取 commit 信息
96
+ # 1. 获取 commit 信息(优先从 GitTagTask,降级到 GitCommitTask)
97
97
  if @git_commit_id.nil?
98
- git_commit_data = get_data_param_by_key(:git_commit)
99
- if git_commit_data && git_commit_data[:task_param]
100
- param = git_commit_data[:task_param]
98
+ # 1.1 优先从 GitTagTask 依赖任务获取(打 tag 后的 commit 信息更准确)
99
+ git_data = get_data_param_by_key(:git_tag)
100
+ # 1.2 降级到 GitCommitTask
101
+ git_data = get_data_param_by_key(:git_commit) if git_data.nil? || git_data.empty?
102
+
103
+ if git_data && git_data[:task_param]
104
+ param = git_data[:task_param]
101
105
  @git_commit_id = param[:git_commit_id] if param[:git_commit_id]
102
106
  @git_commit_time = param[:git_commit_time] if param[:git_commit_time]
103
107
  @git_commit_desc = param[:git_commit_desc] if param[:git_commit_desc]
@@ -13,6 +13,11 @@ module Pindo
13
13
  :resign
14
14
  end
15
15
 
16
+ # 任务键
17
+ def self.task_key
18
+ :ipa_local_resign
19
+ end
20
+
16
21
  # 任务类型显示名称
17
22
  def self.task_type_name
18
23
  "重签名"
@@ -154,11 +154,10 @@ module Pindo
154
154
 
155
155
  # 构建描述文本(描述 + 环境变量)
156
156
  def build_description_text
157
- if @env_name
158
- "#{@description} (环境变量: #{@env_name})"
159
- else
160
- @description
161
- end
157
+ desc = @description.dup
158
+ desc += " (环境变量: #{@env_name})" if @env_name
159
+ desc += " 示例: #{@example}" if @example && !@example.to_s.strip.empty?
160
+ desc
162
161
  end
163
162
 
164
163
  # 类型转换为提示字符串