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.
- checksums.yaml +4 -4
- data/lib/pindo/base/aeshelper.rb +53 -22
- data/lib/pindo/base/git_handler.rb +295 -32
- data/lib/pindo/client/giteeclient.rb +15 -6
- data/lib/pindo/command/android/autobuild.rb +7 -5
- data/lib/pindo/command/appstore/autobuild.rb +5 -2
- data/lib/pindo/command/appstore/cert.rb +6 -0
- data/lib/pindo/command/appstore/iap.rb +2 -3
- data/lib/pindo/command/ios/autobuild.rb +31 -21
- data/lib/pindo/command/ios/cert.rb +1 -1
- data/lib/pindo/command/jps/apptest.rb +1 -1
- data/lib/pindo/command/jps/bind.rb +6 -2
- data/lib/pindo/command/jps/media.rb +6 -2
- data/lib/pindo/command/jps/upload.rb +6 -4
- data/lib/pindo/command/repo/clone.rb +110 -32
- data/lib/pindo/command/repo/subgit.rb +91 -0
- data/lib/pindo/command/repo.rb +1 -0
- data/lib/pindo/command/unity/autobuild.rb +6 -4
- data/lib/pindo/command/unity/packbuild.rb +14 -7
- data/lib/pindo/command/utils/tag.rb +5 -3
- data/lib/pindo/command/web/autobuild.rb +7 -5
- data/lib/pindo/command.rb +1 -1
- data/lib/pindo/config/build_info_manager.rb +37 -14
- data/lib/pindo/module/appstore/bundleid_helper.rb +7 -3
- data/lib/pindo/module/build/git_repo_helper.rb +14 -35
- data/lib/pindo/module/cert/cert_helper.rb +33 -9
- data/lib/pindo/module/cert/xcode_cert_helper.rb +17 -7
- data/lib/pindo/module/pgyer/pgyerhelper.rb +110 -22
- data/lib/pindo/module/task/model/build/android_build_dev_task.rb +3 -2
- data/lib/pindo/module/task/model/build/ios_build_dev_task.rb +3 -2
- data/lib/pindo/module/task/model/git/git_commit_task.rb +107 -48
- data/lib/pindo/module/task/model/git/git_tag_task.rb +21 -20
- data/lib/pindo/module/task/model/git_task.rb +49 -0
- data/lib/pindo/module/task/model/jps/jps_bind_package_task.rb +8 -5
- data/lib/pindo/module/task/model/jps/jps_upload_media_task.rb +21 -13
- data/lib/pindo/module/task/model/jps/jps_workflow_message_task.rb +8 -4
- data/lib/pindo/module/task/model/resign/ipa_local_resign_task.rb +5 -0
- data/lib/pindo/options/core/option_item.rb +4 -5
- data/lib/pindo/options/groups/git_options.rb +40 -0
- data/lib/pindo/options/helpers/git_constants.rb +28 -0
- data/lib/pindo/version.rb +1 -1
- 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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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] ||
|
|
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
|
-
|
|
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
|
|
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 ||
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
163
|
-
|
|
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
|
-
|
|
181
|
-
|
|
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
|
-
#
|
|
184
|
-
|
|
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
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
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
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
#
|
|
124
|
-
Pindo::GitHandler.git!(%W(-C #{root_dir} stash
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
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.
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
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
|
-
#
|
|
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
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
96
|
+
# 1. 获取 commit 信息(优先从 GitTagTask,降级到 GitCommitTask)
|
|
97
97
|
if @git_commit_id.nil?
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
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]
|
|
@@ -154,11 +154,10 @@ module Pindo
|
|
|
154
154
|
|
|
155
155
|
# 构建描述文本(描述 + 环境变量)
|
|
156
156
|
def build_description_text
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
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
|
# 类型转换为提示字符串
|