pindo 5.17.4 → 5.18.3
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/git_handler.rb +120 -38
- data/lib/pindo/command/android/autobuild.rb +92 -31
- data/lib/pindo/command/appstore/adhocbuild.rb +1 -1
- data/lib/pindo/command/appstore/autobuild.rb +1 -1
- data/lib/pindo/command/appstore/autoresign.rb +1 -1
- data/lib/pindo/command/appstore/updateid.rb +229 -0
- data/lib/pindo/command/appstore.rb +1 -0
- data/lib/pindo/command/ios/autobuild.rb +70 -33
- data/lib/pindo/command/ios/podpush.rb +1 -1
- data/lib/pindo/command/unity/autobuild.rb +38 -18
- data/lib/pindo/command/utils/allcopyconfig.rb +144 -0
- data/lib/pindo/command/utils/copyconfig.rb +207 -0
- data/lib/pindo/command/utils/icon.rb +2 -2
- data/lib/pindo/command/utils/renewbundleid.rb +199 -0
- data/lib/pindo/command/utils/renewcert.rb +56 -54
- data/lib/pindo/command/utils.rb +3 -0
- data/lib/pindo/command/web/autobuild.rb +10 -8
- data/lib/pindo/config/build_info_manager.rb +1 -3
- data/lib/pindo/module/android/android_build_helper.rb +198 -33
- data/lib/pindo/module/android/android_config_helper.rb +305 -88
- data/lib/pindo/module/android/android_project_helper.rb +124 -14
- data/lib/pindo/module/android/android_res_helper.rb +349 -51
- data/lib/pindo/module/android/keystore_helper.rb +611 -295
- data/lib/pindo/module/android/workflow_gradle_injector.rb +702 -0
- data/lib/pindo/module/appselect.rb +4 -4
- data/lib/pindo/module/appstore/bundleid_helper.rb +204 -14
- data/lib/pindo/module/build/build_helper.rb +76 -10
- data/lib/pindo/module/build/git_repo_helper.rb +4 -4
- data/lib/pindo/module/cert/mode/base_cert_operator.rb +12 -6
- data/lib/pindo/module/pgyer/pgyerhelper.rb +124 -39
- data/lib/pindo/module/task/model/build/android_build_dev_task.rb +64 -6
- data/lib/pindo/module/task/model/git/git_commit_task.rb +70 -54
- data/lib/pindo/module/task/model/git/git_tag_task.rb +13 -9
- data/lib/pindo/module/task/model/jps/jps_upload_task.rb +110 -3
- data/lib/pindo/module/task/model/unity/unity_export_task.rb +2 -1
- data/lib/pindo/module/task/model/unity/unity_update_task.rb +2 -1
- data/lib/pindo/module/task/model/unity/unity_yoo_asset_task.rb +2 -1
- data/lib/pindo/module/task/model/unity_task.rb +2 -1
- data/lib/pindo/module/unity/unity_helper.rb +13 -10
- data/lib/pindo/module/unity/unity_proc_helper.rb +27 -2
- data/lib/pindo/module/xcode/applovin_xcode_helper.rb +6 -2
- data/lib/pindo/module/xcode/res/xcode_res_constant.rb +72 -0
- data/lib/pindo/module/xcode/res/xcode_res_handler.rb +3 -3
- data/lib/pindo/module/xcode/xcode_build_config.rb +46 -17
- data/lib/pindo/module/xcode/xcode_build_helper.rb +186 -25
- data/lib/pindo/module/xcode/xcode_project_helper.rb +1 -1
- data/lib/pindo/module/xcode/xcode_res_helper.rb +32 -16
- data/lib/pindo/options/groups/build_options.rb +5 -5
- data/lib/pindo/options/groups/git_options.rb +7 -5
- data/lib/pindo/options/groups/unity_options.rb +11 -0
- data/lib/pindo/options/helpers/bundleid_selector.rb +25 -0
- data/lib/pindo/options/helpers/git_constants.rb +7 -6
- data/lib/pindo/version.rb +3 -3
- metadata +12 -7
|
@@ -15,7 +15,7 @@ module Pindo
|
|
|
15
15
|
end
|
|
16
16
|
|
|
17
17
|
# 初始化上传任务
|
|
18
|
-
# @param file_type [String] 文件类型:'ipa' | 'apk' | 'html' | 'mac'
|
|
18
|
+
# @param file_type [String] 文件类型:'ipa' | 'apk' | 'html' | 'mac' | 'exe'
|
|
19
19
|
# @param upload_path [String] 搜索文件的路径
|
|
20
20
|
# @param upload_file [String] 要上传的文件(nil 表示自动查找)
|
|
21
21
|
# @param options [Hash] 选项
|
|
@@ -24,7 +24,7 @@ module Pindo
|
|
|
24
24
|
# @option options [String] :project_name 项目名称(可选)
|
|
25
25
|
# @option options [String] :upload_desc 上传描述(可选)
|
|
26
26
|
def initialize(file_type, upload_path, upload_file, options = {})
|
|
27
|
-
@file_type = file_type # 'ipa' | 'apk' | 'html' | 'mac'
|
|
27
|
+
@file_type = file_type # 'ipa' | 'apk' | 'html' | 'mac' | 'exe'
|
|
28
28
|
@upload_path = upload_path # 搜索文件的路径
|
|
29
29
|
@upload_file = upload_file # 要上传的文件(nil 表示自动查找)
|
|
30
30
|
@upload_desc = options[:upload_desc] # 上传描述
|
|
@@ -41,6 +41,8 @@ module Pindo
|
|
|
41
41
|
"上传 WebGL包"
|
|
42
42
|
when 'mac'
|
|
43
43
|
"上传 macOS App包"
|
|
44
|
+
when 'exe'
|
|
45
|
+
"上传 Windows EXE包"
|
|
44
46
|
else
|
|
45
47
|
"上传 #{file_type.upcase}"
|
|
46
48
|
end
|
|
@@ -109,7 +111,10 @@ module Pindo
|
|
|
109
111
|
)
|
|
110
112
|
end
|
|
111
113
|
|
|
112
|
-
# 3.
|
|
114
|
+
# 3. 自动解析上传描述(未手动指定时)
|
|
115
|
+
@upload_desc = resolve_upload_desc(file_to_upload) if @upload_desc.nil?
|
|
116
|
+
|
|
117
|
+
# 4. 上传到 JPS
|
|
113
118
|
app_version_info = upload_to_jps(file_to_upload)
|
|
114
119
|
|
|
115
120
|
{
|
|
@@ -149,11 +154,113 @@ module Pindo
|
|
|
149
154
|
File.join(@upload_path, "**", "*.html")
|
|
150
155
|
when 'mac'
|
|
151
156
|
File.join(@upload_path, "**", "*.app")
|
|
157
|
+
when 'exe'
|
|
158
|
+
File.join(@upload_path, "**", "*.exe")
|
|
152
159
|
else
|
|
153
160
|
raise "不支持的文件类型: #{@file_type}"
|
|
154
161
|
end
|
|
155
162
|
end
|
|
156
163
|
|
|
164
|
+
# 根据依赖任务类型或 IPA 描述文件类型自动推断上传描述
|
|
165
|
+
# 规则:
|
|
166
|
+
# 依赖 IosBuildAdhocTask → "Commit id: <commit_id>"
|
|
167
|
+
# 依赖 IosBuildAppStoreTask → "重签名"
|
|
168
|
+
# 依赖其他 IosBuildTask 子类 → nil(不传描述)
|
|
169
|
+
# 直接上传 IPA(无构建依赖) → 检测描述文件类型后同上
|
|
170
|
+
def resolve_upload_desc(file_path)
|
|
171
|
+
# 路径1:检查任务依赖
|
|
172
|
+
if @dependencies && !@dependencies.empty?
|
|
173
|
+
@dependencies.each do |dep_id|
|
|
174
|
+
dep_task = get_dependency_task(dep_id)
|
|
175
|
+
next unless dep_task
|
|
176
|
+
|
|
177
|
+
class_name = dep_task.class.name || ''
|
|
178
|
+
is_ios_build = dep_task.class.ancestors.any? do |a|
|
|
179
|
+
a.name == 'Pindo::TaskSystem::IosBuildTask'
|
|
180
|
+
end
|
|
181
|
+
next unless is_ios_build
|
|
182
|
+
|
|
183
|
+
if class_name == 'Pindo::TaskSystem::IosBuildAdhocTask'
|
|
184
|
+
commit_id = get_current_commit_id
|
|
185
|
+
return commit_id ? "Commit id: #{commit_id}" : nil
|
|
186
|
+
elsif class_name == 'Pindo::TaskSystem::IosBuildAppStoreTask'
|
|
187
|
+
return "重签名"
|
|
188
|
+
else
|
|
189
|
+
return nil
|
|
190
|
+
end
|
|
191
|
+
end
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
# 路径2:直接上传 IPA 时,检测 Xcode 工程描述文件类型
|
|
195
|
+
if @file_type == 'ipa'
|
|
196
|
+
profile_type = detect_xcode_profile_type
|
|
197
|
+
case profile_type
|
|
198
|
+
when :adhoc
|
|
199
|
+
commit_id = get_current_commit_id
|
|
200
|
+
return commit_id ? "Commit id: #{commit_id}" : nil
|
|
201
|
+
when :appstore
|
|
202
|
+
return "重签名"
|
|
203
|
+
end
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
nil
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
# 获取当前 git commit id(从 upload_path 所在的 git 仓库)
|
|
210
|
+
def get_current_commit_id
|
|
211
|
+
dir = @upload_path || Dir.pwd
|
|
212
|
+
commit_id = `git -C "#{dir}" rev-parse HEAD 2>/dev/null`.strip
|
|
213
|
+
commit_id.empty? ? nil : commit_id
|
|
214
|
+
rescue
|
|
215
|
+
nil
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
# 检测当前目录下 Xcode 工程的描述文件类型
|
|
219
|
+
# 通过读取主 target Release 配置的 PROVISIONING_PROFILE_SPECIFIER 判断
|
|
220
|
+
# @return [Symbol, nil] :adhoc / :appstore / :development / nil
|
|
221
|
+
def detect_xcode_profile_type
|
|
222
|
+
require 'xcodeproj'
|
|
223
|
+
|
|
224
|
+
# 从 upload_path 向上查找包含 .xcodeproj 的目录
|
|
225
|
+
search_dir = File.expand_path(@upload_path || Dir.pwd)
|
|
226
|
+
project_fullname = nil
|
|
227
|
+
loop do
|
|
228
|
+
candidates = Dir.glob(File.join(search_dir, '*.xcodeproj'))
|
|
229
|
+
if candidates.any?
|
|
230
|
+
project_fullname = candidates.max_by { |f| File.mtime(f) }
|
|
231
|
+
break
|
|
232
|
+
end
|
|
233
|
+
parent = File.dirname(search_dir)
|
|
234
|
+
break if parent == search_dir # 已到文件系统根目录
|
|
235
|
+
search_dir = parent
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
return nil unless project_fullname && File.exist?(project_fullname)
|
|
239
|
+
|
|
240
|
+
project_obj = Xcodeproj::Project.open(project_fullname)
|
|
241
|
+
main_target = project_obj.targets.select do |t|
|
|
242
|
+
t.respond_to?(:product_type) &&
|
|
243
|
+
t.product_type.include?(Xcodeproj::Constants::PRODUCT_TYPE_UTI[:application])
|
|
244
|
+
end.first
|
|
245
|
+
return nil unless main_target
|
|
246
|
+
|
|
247
|
+
# 优先取 Release 配置,找不到则取第一个
|
|
248
|
+
release_config = main_target.build_configurations.find { |c| c.name == 'Release' } ||
|
|
249
|
+
main_target.build_configurations.first
|
|
250
|
+
return nil unless release_config
|
|
251
|
+
|
|
252
|
+
specifier = release_config.build_settings['PROVISIONING_PROFILE_SPECIFIER'].to_s.downcase
|
|
253
|
+
if specifier.include?('adhoc')
|
|
254
|
+
:adhoc
|
|
255
|
+
elsif specifier.include?('development')
|
|
256
|
+
:development
|
|
257
|
+
else
|
|
258
|
+
:appstore
|
|
259
|
+
end
|
|
260
|
+
rescue
|
|
261
|
+
nil
|
|
262
|
+
end
|
|
263
|
+
|
|
157
264
|
# 延迟获取 JPS 配置(上传任务专用)
|
|
158
265
|
# @return [Array] 返回 [app_info_obj, workflow_info]
|
|
159
266
|
def fetch_jps_config(working_directory: Dir.pwd, package_type: nil)
|
|
@@ -81,7 +81,8 @@ module Pindo
|
|
|
81
81
|
# 调用 UnityHelper 的 force_update_libraries 方法
|
|
82
82
|
result = unity_helper.force_update_libraries(
|
|
83
83
|
unity_exe_full_path: @unity_exe_path,
|
|
84
|
-
project_path: @unity_root_path
|
|
84
|
+
project_path: @unity_root_path,
|
|
85
|
+
auto_kill: @auto_kill
|
|
85
86
|
)
|
|
86
87
|
|
|
87
88
|
# 返回成功结果
|
|
@@ -100,7 +100,8 @@ module Pindo
|
|
|
100
100
|
result = unity_helper.build_yoo_asset(
|
|
101
101
|
unity_exe_full_path: @unity_exe_path,
|
|
102
102
|
project_path: @unity_root_path,
|
|
103
|
-
platform: platform_name
|
|
103
|
+
platform: platform_name,
|
|
104
|
+
auto_kill: @auto_kill
|
|
104
105
|
)
|
|
105
106
|
|
|
106
107
|
# 如果跳过(YooAsset 不存在),输出警告并显示命令
|
|
@@ -8,11 +8,12 @@ module Pindo
|
|
|
8
8
|
# Unity 任务基类
|
|
9
9
|
# 所有 Unity 相关任务的父类,提供通用的 Unity 操作和配置
|
|
10
10
|
class UnityTask < PindoTask
|
|
11
|
-
attr_reader :project_path, :unity_root_path
|
|
11
|
+
attr_reader :project_path, :unity_root_path, :auto_kill
|
|
12
12
|
|
|
13
13
|
def initialize(name, options = {})
|
|
14
14
|
@project_path = options[:project_path] ? normalize_path(options[:project_path]) : nil
|
|
15
15
|
@unity_root_path = options[:unity_root_path] ? normalize_path(options[:unity_root_path]) : @project_path
|
|
16
|
+
@auto_kill = options[:auto_kill] || false
|
|
16
17
|
|
|
17
18
|
super(name, options)
|
|
18
19
|
end
|
|
@@ -46,11 +46,11 @@ module Pindo
|
|
|
46
46
|
# ============================================
|
|
47
47
|
|
|
48
48
|
# 检查 GoodUnityBuild 版本是否满足要求
|
|
49
|
-
def check_goodunitybuild_version(unity_exe_full_path, project_path)
|
|
49
|
+
def check_goodunitybuild_version(unity_exe_full_path, project_path, auto_kill: false)
|
|
50
50
|
Funlog.instance.fancyinfo_start("检查 GoodUnityBuild 版本")
|
|
51
51
|
|
|
52
52
|
# 检查是否有Unity进程在运行
|
|
53
|
-
UnityProcHelper.check_unity_processes(unity_exe_full_path: unity_exe_full_path, project_path: project_path)
|
|
53
|
+
UnityProcHelper.check_unity_processes(unity_exe_full_path: unity_exe_full_path, project_path: project_path, auto_kill: auto_kill)
|
|
54
54
|
|
|
55
55
|
# 执行 Unity 命令获取库版本
|
|
56
56
|
result = UnityCommandHelper.execute_unity_command(
|
|
@@ -112,10 +112,10 @@ module Pindo
|
|
|
112
112
|
Funlog.warning("GoodUnityBuild 库版本检查失败: #{e.message}")
|
|
113
113
|
end
|
|
114
114
|
|
|
115
|
-
def export_project(unity_exe_full_path:nil, project_path:nil, platform: nil, isLibrary: false, indexNo: nil, deployMode: nil)
|
|
115
|
+
def export_project(unity_exe_full_path:nil, project_path:nil, platform: nil, isLibrary: false, indexNo: nil, deployMode: nil, auto_kill: false)
|
|
116
116
|
|
|
117
117
|
# 检查是否有Unity进程在运行,传入Unity路径和项目路径以精确匹配
|
|
118
|
-
UnityProcHelper.check_unity_processes(unity_exe_full_path: unity_exe_full_path, project_path: project_path)
|
|
118
|
+
UnityProcHelper.check_unity_processes(unity_exe_full_path: unity_exe_full_path, project_path: project_path, auto_kill: auto_kill)
|
|
119
119
|
|
|
120
120
|
additional_args = {}
|
|
121
121
|
additional_args[:platform] = platform if platform
|
|
@@ -201,8 +201,9 @@ module Pindo
|
|
|
201
201
|
# @param unity_exe_full_path [String] Unity 可执行文件路径
|
|
202
202
|
# @param project_path [String] Unity 项目路径
|
|
203
203
|
# @param platform [String] 目标平台 ('Android', 'iOS' 等)
|
|
204
|
+
# @param auto_kill [Boolean] 是否自动关闭进程(不询问用户)
|
|
204
205
|
# @return [Hash] 执行结果,如果跳过则返回 { skipped: true }
|
|
205
|
-
def build_yoo_asset(unity_exe_full_path:nil, project_path:nil, platform: nil)
|
|
206
|
+
def build_yoo_asset(unity_exe_full_path:nil, project_path:nil, platform: nil, auto_kill: false)
|
|
206
207
|
# 检查项目中是否存在 YooAsset
|
|
207
208
|
unless yoo_asset_exists?(project_path)
|
|
208
209
|
return { skipped: true, reason: 'YooAsset not found' }
|
|
@@ -211,7 +212,7 @@ module Pindo
|
|
|
211
212
|
puts "检测到 YooAsset,开始构建资源..."
|
|
212
213
|
|
|
213
214
|
# 检查是否有Unity进程在运行
|
|
214
|
-
UnityProcHelper.check_unity_processes(unity_exe_full_path: unity_exe_full_path, project_path: project_path)
|
|
215
|
+
UnityProcHelper.check_unity_processes(unity_exe_full_path: unity_exe_full_path, project_path: project_path, auto_kill: auto_kill)
|
|
215
216
|
|
|
216
217
|
additional_args = {}
|
|
217
218
|
additional_args[:platform] = platform if platform
|
|
@@ -244,10 +245,11 @@ module Pindo
|
|
|
244
245
|
# 强制更新必备库(NugetForUnity)
|
|
245
246
|
# @param unity_exe_full_path [String] Unity 可执行文件路径
|
|
246
247
|
# @param project_path [String] Unity 项目路径
|
|
248
|
+
# @param auto_kill [Boolean] 是否自动关闭进程(不询问用户)
|
|
247
249
|
# @return [Hash] 执行结果
|
|
248
|
-
def force_update_libraries(unity_exe_full_path:nil, project_path:nil)
|
|
250
|
+
def force_update_libraries(unity_exe_full_path:nil, project_path:nil, auto_kill: false)
|
|
249
251
|
# 检查是否有Unity进程在运行
|
|
250
|
-
UnityProcHelper.check_unity_processes(unity_exe_full_path: unity_exe_full_path, project_path: project_path)
|
|
252
|
+
UnityProcHelper.check_unity_processes(unity_exe_full_path: unity_exe_full_path, project_path: project_path, auto_kill: auto_kill)
|
|
251
253
|
|
|
252
254
|
# 使用 NugetForUnity.Joy.JoyTools.CheckForceUpdate 强制更新库
|
|
253
255
|
result = UnityCommandHelper.execute_unity_command(
|
|
@@ -278,8 +280,9 @@ module Pindo
|
|
|
278
280
|
# @param unity_exe_full_path [String] Unity 可执行文件路径
|
|
279
281
|
# @param project_path [String] Unity 项目路径
|
|
280
282
|
# @param deploy_mode [String] 部署模式 ('dev', 'adhoc', 'release')
|
|
283
|
+
# @param auto_kill [Boolean] 是否自动关闭进程(不询问用户)
|
|
281
284
|
# @return [Hash] 执行结果
|
|
282
|
-
def config_build_mode(unity_exe_full_path:nil, project_path:nil, deploy_mode: 'dev')
|
|
285
|
+
def config_build_mode(unity_exe_full_path:nil, project_path:nil, deploy_mode: 'dev', auto_kill: false)
|
|
283
286
|
# 验证 deploy_mode 参数
|
|
284
287
|
valid_modes = ['dev', 'adhoc', 'release']
|
|
285
288
|
unless valid_modes.include?(deploy_mode)
|
|
@@ -287,7 +290,7 @@ module Pindo
|
|
|
287
290
|
end
|
|
288
291
|
|
|
289
292
|
# 检查是否有Unity进程在运行
|
|
290
|
-
UnityProcHelper.check_unity_processes(unity_exe_full_path: unity_exe_full_path, project_path: project_path)
|
|
293
|
+
UnityProcHelper.check_unity_processes(unity_exe_full_path: unity_exe_full_path, project_path: project_path, auto_kill: auto_kill)
|
|
291
294
|
|
|
292
295
|
puts "配置 GoodUnityBuild 编译模式为: #{deploy_mode}"
|
|
293
296
|
|
|
@@ -5,10 +5,11 @@ module Pindo
|
|
|
5
5
|
# 所有方法均为类方法,无需实例化
|
|
6
6
|
class UnityProcHelper
|
|
7
7
|
|
|
8
|
-
# 构建前检查 Unity
|
|
8
|
+
# 构建前检查 Unity 进程(交互式或自动关闭)
|
|
9
9
|
# @param unity_exe_full_path [String] Unity 可执行文件路径
|
|
10
10
|
# @param project_path [String] Unity 项目路径
|
|
11
|
-
|
|
11
|
+
# @param auto_kill [Boolean] 是否自动关闭进程(不询问用户)
|
|
12
|
+
def self.check_unity_processes(unity_exe_full_path: nil, project_path: nil, auto_kill: false)
|
|
12
13
|
# 如果没有提供路径参数,直接跳过Unity进程检查
|
|
13
14
|
if unity_exe_full_path.nil? && project_path.nil?
|
|
14
15
|
return
|
|
@@ -32,6 +33,30 @@ module Pindo
|
|
|
32
33
|
end
|
|
33
34
|
puts ""
|
|
34
35
|
|
|
36
|
+
# 如果指定了 auto_kill,直接关闭进程
|
|
37
|
+
if auto_kill
|
|
38
|
+
puts "自动关闭 Unity 进程..."
|
|
39
|
+
success_count = 0
|
|
40
|
+
unity_pids.each do |process_info|
|
|
41
|
+
if kill_unity_process(process_info[:pid])
|
|
42
|
+
puts "✅ 成功关闭进程 #{process_info[:pid]}"
|
|
43
|
+
success_count += 1
|
|
44
|
+
else
|
|
45
|
+
puts "❌ 关闭进程 #{process_info[:pid]} 失败"
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
if success_count > 0
|
|
50
|
+
puts "\n✅ 已关闭 #{success_count} 个 Unity 相关进程"
|
|
51
|
+
puts "等待3秒后继续编译..."
|
|
52
|
+
sleep(3)
|
|
53
|
+
else
|
|
54
|
+
puts "\n❌ 无法关闭 Unity 相关进程,请手动关闭后重试"
|
|
55
|
+
raise "Unity进程冲突:无法自动关闭 Unity 相关进程,请手动关闭后重试"
|
|
56
|
+
end
|
|
57
|
+
return
|
|
58
|
+
end
|
|
59
|
+
|
|
35
60
|
# 询问用户是否要自动关闭Unity进程
|
|
36
61
|
loop do
|
|
37
62
|
puts "批处理模式需要关闭这些 Unity 进程以避免冲突"
|
|
@@ -4,6 +4,7 @@ require 'faraday'
|
|
|
4
4
|
require 'xcodeproj'
|
|
5
5
|
require 'pindo/base/git_handler'
|
|
6
6
|
require 'pindo/config/pindoconfig'
|
|
7
|
+
require 'pindo/module/xcode/xcode_build_helper'
|
|
7
8
|
|
|
8
9
|
module Pindo
|
|
9
10
|
# Applovin Xcode 辅助类
|
|
@@ -255,9 +256,12 @@ module Pindo
|
|
|
255
256
|
project_obj = Xcodeproj::Project.open(xcodeproj_file)
|
|
256
257
|
|
|
257
258
|
project_obj.targets.each do |target|
|
|
259
|
+
# 跳过非 native target(如 PBXAggregateTarget)
|
|
260
|
+
next unless target.respond_to?(:product_type)
|
|
258
261
|
if target.product_type.to_s == "com.apple.product-type.application"
|
|
259
|
-
|
|
260
|
-
|
|
262
|
+
raw_path = target.build_configurations.first.build_settings['INFOPLIST_FILE']
|
|
263
|
+
resolved = Pindo::XcodeBuildHelper.resolve_info_plist_path(project_dir, raw_path, target: target)
|
|
264
|
+
return resolved if resolved
|
|
261
265
|
end
|
|
262
266
|
end
|
|
263
267
|
rescue => e
|
|
@@ -176,6 +176,78 @@ module Pindo
|
|
|
176
176
|
# return model_data
|
|
177
177
|
# end
|
|
178
178
|
|
|
179
|
+
def self.xcode_macos_icon_json
|
|
180
|
+
model_data = {
|
|
181
|
+
"images" => [
|
|
182
|
+
{
|
|
183
|
+
"size" => "16x16",
|
|
184
|
+
"idiom" => "mac",
|
|
185
|
+
"filename" => "app_icon_16.png",
|
|
186
|
+
"scale" => "1x"
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
"size" => "16x16",
|
|
190
|
+
"idiom" => "mac",
|
|
191
|
+
"filename" => "app_icon_32.png",
|
|
192
|
+
"scale" => "2x"
|
|
193
|
+
},
|
|
194
|
+
{
|
|
195
|
+
"size" => "32x32",
|
|
196
|
+
"idiom" => "mac",
|
|
197
|
+
"filename" => "app_icon_32.png",
|
|
198
|
+
"scale" => "1x"
|
|
199
|
+
},
|
|
200
|
+
{
|
|
201
|
+
"size" => "32x32",
|
|
202
|
+
"idiom" => "mac",
|
|
203
|
+
"filename" => "app_icon_64.png",
|
|
204
|
+
"scale" => "2x"
|
|
205
|
+
},
|
|
206
|
+
{
|
|
207
|
+
"size" => "128x128",
|
|
208
|
+
"idiom" => "mac",
|
|
209
|
+
"filename" => "app_icon_128.png",
|
|
210
|
+
"scale" => "1x"
|
|
211
|
+
},
|
|
212
|
+
{
|
|
213
|
+
"size" => "128x128",
|
|
214
|
+
"idiom" => "mac",
|
|
215
|
+
"filename" => "app_icon_256.png",
|
|
216
|
+
"scale" => "2x"
|
|
217
|
+
},
|
|
218
|
+
{
|
|
219
|
+
"size" => "256x256",
|
|
220
|
+
"idiom" => "mac",
|
|
221
|
+
"filename" => "app_icon_256.png",
|
|
222
|
+
"scale" => "1x"
|
|
223
|
+
},
|
|
224
|
+
{
|
|
225
|
+
"size" => "256x256",
|
|
226
|
+
"idiom" => "mac",
|
|
227
|
+
"filename" => "app_icon_512.png",
|
|
228
|
+
"scale" => "2x"
|
|
229
|
+
},
|
|
230
|
+
{
|
|
231
|
+
"size" => "512x512",
|
|
232
|
+
"idiom" => "mac",
|
|
233
|
+
"filename" => "app_icon_512.png",
|
|
234
|
+
"scale" => "1x"
|
|
235
|
+
},
|
|
236
|
+
{
|
|
237
|
+
"size" => "512x512",
|
|
238
|
+
"idiom" => "mac",
|
|
239
|
+
"filename" => "app_icon_1024.png",
|
|
240
|
+
"scale" => "2x"
|
|
241
|
+
}
|
|
242
|
+
],
|
|
243
|
+
"info" => {
|
|
244
|
+
"author" => "xcode",
|
|
245
|
+
"version" => 1
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
return model_data
|
|
249
|
+
end
|
|
250
|
+
|
|
179
251
|
def self.xcode_ios_imessage_icon_json
|
|
180
252
|
model_data = {
|
|
181
253
|
"images" => [
|
|
@@ -15,7 +15,7 @@ module Pindo
|
|
|
15
15
|
def get_xcodeproj_icon_path()
|
|
16
16
|
|
|
17
17
|
icon_path = nil
|
|
18
|
-
select_target = @project_obj.targets.select { |target| target.product_type.include?(Xcodeproj::Constants::PRODUCT_TYPE_UTI[:application]) }.first
|
|
18
|
+
select_target = @project_obj.targets.select { |target| target.respond_to?(:product_type) && target.product_type.include?(Xcodeproj::Constants::PRODUCT_TYPE_UTI[:application]) }.first
|
|
19
19
|
|
|
20
20
|
project_dir = @project_obj.project_dir
|
|
21
21
|
|
|
@@ -91,7 +91,7 @@ module Pindo
|
|
|
91
91
|
|
|
92
92
|
def get_xcodeproj_imessage_icon_path
|
|
93
93
|
icon_path = nil
|
|
94
|
-
select_target = @project_obj.targets.select { |target| target.product_type.include?(Xcodeproj::Constants::PRODUCT_TYPE_UTI[:messages_extension]) }.first
|
|
94
|
+
select_target = @project_obj.targets.select { |target| target.respond_to?(:product_type) && target.product_type.include?(Xcodeproj::Constants::PRODUCT_TYPE_UTI[:messages_extension]) }.first
|
|
95
95
|
project_dir = @project_obj.project_dir
|
|
96
96
|
if !select_target.nil?
|
|
97
97
|
file_refs = select_target.resources_build_phase.files_references.select { |file| file.display_name.include?("Assets.xcassets") } || []
|
|
@@ -170,7 +170,7 @@ module Pindo
|
|
|
170
170
|
|
|
171
171
|
launchimg_path = nil
|
|
172
172
|
assets_path = nil
|
|
173
|
-
select_target = @project_obj.targets.select { |target| target.product_type.include?(Xcodeproj::Constants::PRODUCT_TYPE_UTI[:application]) }.first
|
|
173
|
+
select_target = @project_obj.targets.select { |target| target.respond_to?(:product_type) && target.product_type.include?(Xcodeproj::Constants::PRODUCT_TYPE_UTI[:application]) }.first
|
|
174
174
|
project_dir = @project_obj.project_dir
|
|
175
175
|
if !select_target.nil?
|
|
176
176
|
assets_objs = select_target.resources_build_phase.files_references.select { |file| file.display_name.include?("Assets.xcassets") } || []
|
|
@@ -2,6 +2,7 @@ require 'fileutils'
|
|
|
2
2
|
require 'xcodeproj'
|
|
3
3
|
require 'json'
|
|
4
4
|
require 'pindo/module/xcode/xcode_res_helper'
|
|
5
|
+
require 'pindo/module/xcode/xcode_build_helper'
|
|
5
6
|
require 'pindo/module/utils/file_downloader'
|
|
6
7
|
require 'open-uri'
|
|
7
8
|
require_relative '../../base/funlog'
|
|
@@ -36,16 +37,22 @@ module Pindo
|
|
|
36
37
|
|
|
37
38
|
project_obj = Xcodeproj::Project.open(project_fullname)
|
|
38
39
|
project_obj.targets.each do |target|
|
|
40
|
+
# 跳过非 native target(如 PBXAggregateTarget)
|
|
41
|
+
next unless target.respond_to?(:product_type)
|
|
39
42
|
if target.product_type.to_s.eql?("com.apple.product-type.application")
|
|
40
|
-
temp_info_file = target.build_configurations.first.build_settings['INFOPLIST_FILE']
|
|
41
|
-
if temp_info_file && !temp_info_file.empty?
|
|
42
|
-
info_plist_path = File.join(project_dir, temp_info_file)
|
|
43
|
-
end
|
|
44
43
|
app_target = target
|
|
45
44
|
break # 找到第一个application target即可
|
|
46
45
|
end
|
|
47
46
|
end
|
|
48
47
|
|
|
48
|
+
return false unless app_target
|
|
49
|
+
|
|
50
|
+
# 确保 Info.plist 存在(不存在时自动创建)
|
|
51
|
+
info_plist_path = Pindo::XcodeBuildHelper.ensure_info_plist_exists(
|
|
52
|
+
project_dir: project_dir,
|
|
53
|
+
target: app_target,
|
|
54
|
+
project_obj: project_obj
|
|
55
|
+
)
|
|
49
56
|
return false unless info_plist_path && File.exist?(info_plist_path)
|
|
50
57
|
|
|
51
58
|
# 一次性读取plist
|
|
@@ -136,18 +143,26 @@ module Pindo
|
|
|
136
143
|
current_bundle_id = nil
|
|
137
144
|
|
|
138
145
|
project_obj = Xcodeproj::Project.open(project_fullname)
|
|
146
|
+
app_target = nil
|
|
139
147
|
project_obj.targets.each do |target|
|
|
148
|
+
# 跳过非 native target(如 PBXAggregateTarget)
|
|
149
|
+
next unless target.respond_to?(:product_type)
|
|
140
150
|
if target.product_type.to_s.eql?("com.apple.product-type.application")
|
|
141
|
-
|
|
142
|
-
if temp_info_file && !temp_info_file.empty?
|
|
143
|
-
info_plist_path = File.join(project_dir, temp_info_file)
|
|
144
|
-
end
|
|
151
|
+
app_target = target
|
|
145
152
|
# 获取当前实际的 Bundle ID
|
|
146
153
|
current_bundle_id = target.build_configurations.first.build_settings['PRODUCT_BUNDLE_IDENTIFIER']
|
|
147
154
|
break # 找到第一个application target即可
|
|
148
155
|
end
|
|
149
156
|
end
|
|
150
157
|
|
|
158
|
+
return false unless app_target
|
|
159
|
+
|
|
160
|
+
# 确保 Info.plist 存在
|
|
161
|
+
info_plist_path = Pindo::XcodeBuildHelper.ensure_info_plist_exists(
|
|
162
|
+
project_dir: project_dir,
|
|
163
|
+
target: app_target,
|
|
164
|
+
project_obj: project_obj
|
|
165
|
+
)
|
|
151
166
|
return false unless info_plist_path && File.exist?(info_plist_path)
|
|
152
167
|
return false unless current_bundle_id && !current_bundle_id.empty?
|
|
153
168
|
|
|
@@ -205,17 +220,25 @@ module Pindo
|
|
|
205
220
|
bundleid_scheme_name = nil
|
|
206
221
|
|
|
207
222
|
project_obj = Xcodeproj::Project.open(project_fullname)
|
|
223
|
+
app_target = nil
|
|
208
224
|
project_obj.targets.each do |target|
|
|
225
|
+
# 跳过非 native target(如 PBXAggregateTarget)
|
|
226
|
+
next unless target.respond_to?(:product_type)
|
|
209
227
|
if target.product_type.to_s.eql?("com.apple.product-type.application")
|
|
210
|
-
|
|
211
|
-
if temp_info_file && !temp_info_file.empty?
|
|
212
|
-
info_plist_path = File.join(project_dir, temp_info_file)
|
|
213
|
-
end
|
|
228
|
+
app_target = target
|
|
214
229
|
bundleid_scheme_name = target.build_configurations.first.build_settings['PRODUCT_BUNDLE_IDENTIFIER']
|
|
215
230
|
break # 找到第一个application target即可
|
|
216
231
|
end
|
|
217
232
|
end
|
|
218
233
|
|
|
234
|
+
return false unless app_target
|
|
235
|
+
|
|
236
|
+
# 确保 Info.plist 存在
|
|
237
|
+
info_plist_path = Pindo::XcodeBuildHelper.ensure_info_plist_exists(
|
|
238
|
+
project_dir: project_dir,
|
|
239
|
+
target: app_target,
|
|
240
|
+
project_obj: project_obj
|
|
241
|
+
)
|
|
219
242
|
return false unless info_plist_path && File.exist?(info_plist_path)
|
|
220
243
|
|
|
221
244
|
info_plist_dict = Xcodeproj::Plist.read_from_path(info_plist_path)
|
|
@@ -295,6 +318,8 @@ module Pindo
|
|
|
295
318
|
# 更新所有application类型target的版本号
|
|
296
319
|
updated_targets = []
|
|
297
320
|
project.targets.each do |target|
|
|
321
|
+
# 跳过非 native target(如 PBXAggregateTarget)
|
|
322
|
+
next unless target.respond_to?(:product_type)
|
|
298
323
|
# 只处理application类型的target
|
|
299
324
|
if target.product_type.to_s.eql?("com.apple.product-type.application")
|
|
300
325
|
target.build_configurations.each do |config|
|
|
@@ -303,9 +328,10 @@ module Pindo
|
|
|
303
328
|
config.build_settings['CURRENT_PROJECT_VERSION'] = build_number.to_s
|
|
304
329
|
|
|
305
330
|
# 兼容旧的设置方式,通过Info.plist更新
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
331
|
+
raw_plist_path = config.build_settings['INFOPLIST_FILE']
|
|
332
|
+
if raw_plist_path
|
|
333
|
+
info_plist_path = Pindo::XcodeBuildHelper.resolve_info_plist_path(project_dir, raw_plist_path, target: target)
|
|
334
|
+
if info_plist_path
|
|
309
335
|
update_info_plist(info_plist_path, version, build_number.to_s)
|
|
310
336
|
end
|
|
311
337
|
end
|
|
@@ -384,6 +410,8 @@ module Pindo
|
|
|
384
410
|
project_obj = Xcodeproj::Project.open(project_fullname)
|
|
385
411
|
|
|
386
412
|
project_obj.targets.each do |target|
|
|
413
|
+
# 跳过非 native target(如 PBXAggregateTarget)
|
|
414
|
+
next unless target.respond_to?(:product_type)
|
|
387
415
|
if target.product_type.to_s.eql?("com.apple.product-type.application")
|
|
388
416
|
temp_entitlements_file = target.build_configurations.first.build_settings['CODE_SIGN_ENTITLEMENTS']
|
|
389
417
|
if temp_entitlements_file && !temp_entitlements_file.empty?
|
|
@@ -468,7 +496,8 @@ module Pindo
|
|
|
468
496
|
Funlog.instance.fancyinfo_start("正在创建 icon...")
|
|
469
497
|
XcodeResHelper.create_icons(
|
|
470
498
|
icon_name: icon_download_path,
|
|
471
|
-
new_icon_dir: new_icon_dir
|
|
499
|
+
new_icon_dir: new_icon_dir,
|
|
500
|
+
proj_dir: project_dir
|
|
472
501
|
)
|
|
473
502
|
Funlog.instance.fancyinfo_success("创建 icon 完成!")
|
|
474
503
|
|
|
@@ -548,7 +577,7 @@ module Pindo
|
|
|
548
577
|
new_icon_dir = File.join(project_dir, "icon_#{time}")
|
|
549
578
|
|
|
550
579
|
Funlog.instance.fancyinfo_start("正在创建 icon...")
|
|
551
|
-
Pindo::XcodeResHelper.create_icons(icon_name: icon_name, new_icon_dir: new_icon_dir)
|
|
580
|
+
Pindo::XcodeResHelper.create_icons(icon_name: icon_name, new_icon_dir: new_icon_dir, proj_dir: project_dir)
|
|
552
581
|
Funlog.instance.fancyinfo_success("创建 icon 完成!")
|
|
553
582
|
|
|
554
583
|
Funlog.instance.fancyinfo_start("正在替换 icon...")
|