pindo 5.7.1 → 5.8.0
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/funlog.rb +41 -0
- data/lib/pindo/command/android/autobuild.rb +22 -51
- data/lib/pindo/command/android/build.rb +4 -16
- data/lib/pindo/command/android/debug.rb +4 -16
- data/lib/pindo/command/ios/adhoc.rb +4 -27
- data/lib/pindo/command/ios/autobuild.rb +27 -51
- data/lib/pindo/command/ios/build.rb +4 -23
- data/lib/pindo/module/android/android_build_config_helper.rb +142 -21
- data/lib/pindo/module/android/androidreshelper.rb +176 -0
- data/lib/pindo/module/android/apk_helper.rb +19 -4
- data/lib/pindo/module/android/gradle_helper.rb +2 -108
- data/lib/pindo/module/build/buildhelper.rb +2 -2
- data/lib/pindo/module/pgyer/pgyerhelper.rb +1 -1
- data/lib/pindo/module/unity/nugethelper.rb +71 -1
- data/lib/pindo/module/xcode/xcodebuildconfig.rb +101 -83
- data/lib/pindo/version.rb +1 -1
- metadata +3 -2
|
@@ -1,27 +1,34 @@
|
|
|
1
1
|
require 'fileutils'
|
|
2
2
|
require 'xcodeproj'
|
|
3
3
|
require 'json'
|
|
4
|
+
require 'open-uri'
|
|
4
5
|
require_relative '../../base/funlog'
|
|
5
6
|
|
|
6
7
|
module Pindo
|
|
7
8
|
|
|
8
9
|
class XcodeBuildConfig
|
|
9
10
|
|
|
10
|
-
# 使用package_name
|
|
11
|
+
# 使用package_name一次性更新Display Name、Bundle ID和URL Schemes
|
|
12
|
+
# 优化版本:只读写一次plist文件,提高性能
|
|
11
13
|
# @param project_dir [String] iOS项目目录路径
|
|
12
14
|
# @param package_name [String] 工作流的package_name(如:"Test Demo")
|
|
13
15
|
# @return [Boolean] 是否成功更新
|
|
14
|
-
def self.
|
|
16
|
+
def self.update_project_with_packagename(project_dir: nil, package_name: nil)
|
|
15
17
|
raise ArgumentError, "项目目录不能为空" if project_dir.nil?
|
|
16
18
|
raise ArgumentError, "Package Name不能为空" if package_name.nil?
|
|
17
19
|
|
|
18
|
-
#
|
|
20
|
+
# 生成各种值
|
|
19
21
|
display_name = package_name.gsub(/[^a-zA-Z0-9\s]/, '').gsub(/\s+/, '')
|
|
22
|
+
bundle_id_suffix = package_name.gsub(/[^a-zA-Z0-9]/, '').downcase
|
|
23
|
+
final_bundle_id = "com.heroneverdie101.#{bundle_id_suffix}"
|
|
24
|
+
package_scheme = package_name.gsub(/[^a-zA-Z0-9]/, '').downcase
|
|
25
|
+
bundle_scheme = final_bundle_id.gsub(/[^a-zA-Z0-9]/, '').downcase
|
|
20
26
|
|
|
21
27
|
project_fullname = Dir.glob(File.join(project_dir, "/*.xcodeproj")).max_by {|f| File.mtime(f)}
|
|
22
28
|
return false if project_fullname.nil?
|
|
23
29
|
|
|
24
30
|
info_plist_path = nil
|
|
31
|
+
app_target = nil
|
|
25
32
|
|
|
26
33
|
project_obj = Xcodeproj::Project.open(project_fullname)
|
|
27
34
|
project_obj.targets.each do |target|
|
|
@@ -30,59 +37,39 @@ module Pindo
|
|
|
30
37
|
if temp_info_file && !temp_info_file.empty?
|
|
31
38
|
info_plist_path = File.join(project_dir, temp_info_file)
|
|
32
39
|
end
|
|
40
|
+
app_target = target
|
|
33
41
|
break # 找到第一个application target即可
|
|
34
42
|
end
|
|
35
43
|
end
|
|
36
44
|
|
|
37
45
|
return false unless info_plist_path && File.exist?(info_plist_path)
|
|
38
46
|
|
|
39
|
-
#
|
|
47
|
+
# 一次性读取plist
|
|
40
48
|
info_plist_dict = Xcodeproj::Plist.read_from_path(info_plist_path)
|
|
41
|
-
info_plist_dict["CFBundleDisplayName"] = display_name
|
|
42
|
-
Xcodeproj::Plist.write_to_path(info_plist_dict, info_plist_path)
|
|
43
49
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
# 使用package_name更新Bundle ID到iOS工程(同时修改plist和xcodeproj)
|
|
49
|
-
# @param project_dir [String] iOS项目目录路径
|
|
50
|
-
# @param package_name [String] 工作流的package_name(如:"Test Demo")
|
|
51
|
-
# @return [Boolean] 是否成功更新
|
|
52
|
-
def self.update_bundleid_with_packagename(project_dir: nil, package_name: nil)
|
|
53
|
-
raise ArgumentError, "项目目录不能为空" if project_dir.nil?
|
|
54
|
-
raise ArgumentError, "Package Name不能为空" if package_name.nil?
|
|
55
|
-
|
|
56
|
-
# 从 package_name 生成 Bundle ID
|
|
57
|
-
bundle_id_suffix = package_name.gsub(/[^a-zA-Z0-9]/, '').downcase
|
|
58
|
-
final_bundle_id = "com.heroneverdie101.#{bundle_id_suffix}"
|
|
50
|
+
# 1. 更新 Display Name
|
|
51
|
+
info_plist_dict["CFBundleDisplayName"] = display_name
|
|
59
52
|
|
|
60
|
-
|
|
61
|
-
|
|
53
|
+
# 2. 更新 Bundle ID(plist)
|
|
54
|
+
info_plist_dict["CFBundleIdentifier"] = final_bundle_id
|
|
62
55
|
|
|
63
|
-
|
|
64
|
-
|
|
56
|
+
# 3. 添加 URL Schemes
|
|
57
|
+
info_plist_dict["CFBundleURLTypes"] ||= []
|
|
65
58
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
temp_info_file = target.build_configurations.first.build_settings['INFOPLIST_FILE']
|
|
70
|
-
if temp_info_file && !temp_info_file.empty?
|
|
71
|
-
info_plist_path = File.join(project_dir, temp_info_file)
|
|
72
|
-
end
|
|
73
|
-
app_target = target
|
|
74
|
-
break # 找到第一个application target即可
|
|
75
|
-
end
|
|
59
|
+
# 添加基于 package_name 的 URL Scheme
|
|
60
|
+
if add_single_scheme(info_plist_dict, package_scheme)
|
|
61
|
+
puts " ✓ 已添加URL Scheme: #{package_scheme} (基于 Package Name)"
|
|
76
62
|
end
|
|
77
63
|
|
|
78
|
-
|
|
64
|
+
# 添加基于 Bundle ID 的 URL Scheme
|
|
65
|
+
if add_single_scheme(info_plist_dict, bundle_scheme)
|
|
66
|
+
puts " ✓ 已添加URL Scheme: #{bundle_scheme} (基于 Bundle ID)"
|
|
67
|
+
end
|
|
79
68
|
|
|
80
|
-
#
|
|
81
|
-
info_plist_dict = Xcodeproj::Plist.read_from_path(info_plist_path)
|
|
82
|
-
info_plist_dict["CFBundleIdentifier"] = final_bundle_id
|
|
69
|
+
# 一次性写入plist
|
|
83
70
|
Xcodeproj::Plist.write_to_path(info_plist_dict, info_plist_path)
|
|
84
71
|
|
|
85
|
-
#
|
|
72
|
+
# 4. 更新 Xcode 项目中的 PRODUCT_BUNDLE_IDENTIFIER
|
|
86
73
|
if app_target
|
|
87
74
|
app_target.build_configurations.each do |config|
|
|
88
75
|
config.build_settings['PRODUCT_BUNDLE_IDENTIFIER'] = final_bundle_id
|
|
@@ -90,49 +77,8 @@ module Pindo
|
|
|
90
77
|
project_obj.save
|
|
91
78
|
end
|
|
92
79
|
|
|
93
|
-
puts " ✓
|
|
94
|
-
|
|
95
|
-
end
|
|
96
|
-
|
|
97
|
-
# 使用package_name添加URL Scheme到iOS工程的Info.plist
|
|
98
|
-
# @param project_dir [String] iOS项目目录路径
|
|
99
|
-
# @param package_name [String] 工作流的package_name(如:"Test Demo")
|
|
100
|
-
# @return [Boolean] 是否成功添加
|
|
101
|
-
def self.add_url_scheme_packagename(project_dir: nil, package_name: nil)
|
|
102
|
-
raise ArgumentError, "项目目录不能为空" if project_dir.nil?
|
|
103
|
-
raise ArgumentError, "Package Name不能为空" if package_name.nil?
|
|
104
|
-
|
|
105
|
-
# 从 package_name 生成 URL Scheme(去除特殊字符,转小写)
|
|
106
|
-
scheme_value = package_name.to_s.gsub(/[^a-zA-Z0-9]/, '').downcase
|
|
107
|
-
|
|
108
|
-
project_fullname = Dir.glob(File.join(project_dir, "/*.xcodeproj")).max_by {|f| File.mtime(f)}
|
|
109
|
-
return false if project_fullname.nil?
|
|
110
|
-
|
|
111
|
-
info_plist_path = nil
|
|
112
|
-
|
|
113
|
-
project_obj = Xcodeproj::Project.open(project_fullname)
|
|
114
|
-
project_obj.targets.each do |target|
|
|
115
|
-
if target.product_type.to_s.eql?("com.apple.product-type.application")
|
|
116
|
-
temp_info_file = target.build_configurations.first.build_settings['INFOPLIST_FILE']
|
|
117
|
-
if temp_info_file && !temp_info_file.empty?
|
|
118
|
-
info_plist_path = File.join(project_dir, temp_info_file)
|
|
119
|
-
end
|
|
120
|
-
break # 找到第一个application target即可
|
|
121
|
-
end
|
|
122
|
-
end
|
|
123
|
-
|
|
124
|
-
return false unless info_plist_path && File.exist?(info_plist_path)
|
|
125
|
-
|
|
126
|
-
# 使用Xcodeproj::Plist读写plist
|
|
127
|
-
info_plist_dict = Xcodeproj::Plist.read_from_path(info_plist_path)
|
|
128
|
-
info_plist_dict["CFBundleURLTypes"] ||= []
|
|
129
|
-
|
|
130
|
-
# 添加基于package_name的URL Scheme
|
|
131
|
-
if add_single_scheme(info_plist_dict, scheme_value)
|
|
132
|
-
Xcodeproj::Plist.write_to_path(info_plist_dict, info_plist_path)
|
|
133
|
-
puts " ✓ 已添加URL Scheme: #{scheme_value} (来自: #{package_name})"
|
|
134
|
-
end
|
|
135
|
-
|
|
80
|
+
puts " ✓ Display Name 已更新为: #{display_name}"
|
|
81
|
+
puts " ✓ Bundle ID 已更新为: #{final_bundle_id}"
|
|
136
82
|
return true
|
|
137
83
|
end
|
|
138
84
|
|
|
@@ -368,6 +314,78 @@ module Pindo
|
|
|
368
314
|
return false
|
|
369
315
|
end
|
|
370
316
|
|
|
317
|
+
# 从URL下载Icon并替换iOS工程的Icon
|
|
318
|
+
# @param project_dir [String] iOS项目目录路径
|
|
319
|
+
# @param icon_url [String] Icon的下载URL地址
|
|
320
|
+
# @return [Boolean] 是否成功下载并替换Icon
|
|
321
|
+
def self.download_and_replace_icon_from_url(project_dir: nil, icon_url: nil)
|
|
322
|
+
# 参数校验 - 不抛出异常,返回 false
|
|
323
|
+
if project_dir.nil?
|
|
324
|
+
Funlog.instance.fancyinfo_error("Icon 替换失败: 项目目录不能为空")
|
|
325
|
+
return false
|
|
326
|
+
end
|
|
327
|
+
|
|
328
|
+
if icon_url.nil? || icon_url.empty?
|
|
329
|
+
Funlog.instance.fancyinfo_error("Icon 替换失败: Icon URL不能为空")
|
|
330
|
+
return false
|
|
331
|
+
end
|
|
332
|
+
|
|
333
|
+
puts "\n检测到项目 Icon URL: #{icon_url}"
|
|
334
|
+
|
|
335
|
+
# 创建临时目录(所有 icon 处理都在此目录内完成)
|
|
336
|
+
temp_icon_dir = File.join(project_dir, ".pindo_temp_icon")
|
|
337
|
+
icon_download_path = nil
|
|
338
|
+
replace_success = false
|
|
339
|
+
|
|
340
|
+
begin
|
|
341
|
+
FileUtils.mkdir_p(temp_icon_dir) unless File.exist?(temp_icon_dir)
|
|
342
|
+
icon_download_path = File.join(temp_icon_dir, "downloaded_icon.png")
|
|
343
|
+
|
|
344
|
+
# 下载 icon
|
|
345
|
+
Funlog.instance.fancyinfo_start("正在从 JPS 下载项目 Icon...")
|
|
346
|
+
URI.open(icon_url) do |file|
|
|
347
|
+
File.binwrite(icon_download_path, file.read)
|
|
348
|
+
end
|
|
349
|
+
Funlog.instance.fancyinfo_success("Icon 下载成功!")
|
|
350
|
+
|
|
351
|
+
# 验证文件已下载
|
|
352
|
+
unless File.exist?(icon_download_path)
|
|
353
|
+
Funlog.instance.fancyinfo_error("Icon 下载失败: 文件未创建")
|
|
354
|
+
return false
|
|
355
|
+
end
|
|
356
|
+
|
|
357
|
+
# 生成新的 icon 目录(放在临时目录内部)
|
|
358
|
+
new_icon_dir = File.join(temp_icon_dir, "generated_icons")
|
|
359
|
+
|
|
360
|
+
# 创建各种尺寸的 icon
|
|
361
|
+
Funlog.instance.fancyinfo_start("正在创建 icon...")
|
|
362
|
+
XcodeResHelper.create_icons(
|
|
363
|
+
icon_name: icon_download_path,
|
|
364
|
+
new_icon_dir: new_icon_dir
|
|
365
|
+
)
|
|
366
|
+
Funlog.instance.fancyinfo_success("创建 icon 完成!")
|
|
367
|
+
|
|
368
|
+
# 替换工程中的 icon
|
|
369
|
+
Funlog.instance.fancyinfo_start("正在替换 icon...")
|
|
370
|
+
XcodeResHelper.install_icon(
|
|
371
|
+
proj_dir: project_dir,
|
|
372
|
+
new_icon_dir: new_icon_dir
|
|
373
|
+
)
|
|
374
|
+
Funlog.instance.fancyinfo_success("替换 icon 完成!")
|
|
375
|
+
replace_success = true
|
|
376
|
+
|
|
377
|
+
rescue => e
|
|
378
|
+
Funlog.instance.fancyinfo_error("Icon 处理失败: #{e.message}")
|
|
379
|
+
puts e.backtrace
|
|
380
|
+
replace_success = false
|
|
381
|
+
ensure
|
|
382
|
+
# 清理临时文件(无论成功失败都清理)
|
|
383
|
+
FileUtils.rm_rf(temp_icon_dir) if temp_icon_dir && File.exist?(temp_icon_dir)
|
|
384
|
+
end
|
|
385
|
+
|
|
386
|
+
return replace_success
|
|
387
|
+
end
|
|
388
|
+
|
|
371
389
|
end
|
|
372
390
|
|
|
373
391
|
end
|
data/lib/pindo/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: pindo
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 5.
|
|
4
|
+
version: 5.8.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- wade
|
|
8
8
|
bindir: bin
|
|
9
9
|
cert_chain: []
|
|
10
|
-
date: 2025-10-
|
|
10
|
+
date: 2025-10-22 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
12
|
- !ruby/object:Gem::Dependency
|
|
13
13
|
name: claide
|
|
@@ -421,6 +421,7 @@ files:
|
|
|
421
421
|
- lib/pindo/config/pindoconfig.rb
|
|
422
422
|
- lib/pindo/config/pindouserlocalconfig.rb
|
|
423
423
|
- lib/pindo/module/android/android_build_config_helper.rb
|
|
424
|
+
- lib/pindo/module/android/androidreshelper.rb
|
|
424
425
|
- lib/pindo/module/android/apk_helper.rb
|
|
425
426
|
- lib/pindo/module/android/base_helper.rb
|
|
426
427
|
- lib/pindo/module/android/build_helper.rb
|