pindo 5.2.4 → 5.3.7
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 +23 -2
- data/lib/pindo/base/pindocontext.rb +259 -0
- data/lib/pindo/client/pgyer_feishu_oauth_cli.rb +343 -80
- data/lib/pindo/client/pgyerclient.rb +30 -20
- data/lib/pindo/command/android/autobuild.rb +52 -22
- data/lib/pindo/command/android/build.rb +27 -16
- data/lib/pindo/command/android/debug.rb +25 -15
- data/lib/pindo/command/dev/debug.rb +2 -51
- data/lib/pindo/command/dev/feishu.rb +19 -2
- data/lib/pindo/command/ios/adhoc.rb +2 -1
- data/lib/pindo/command/ios/autobuild.rb +35 -8
- data/lib/pindo/command/ios/debug.rb +2 -132
- data/lib/pindo/command/lib/lint.rb +24 -1
- data/lib/pindo/command/setup.rb +24 -4
- data/lib/pindo/command/unity/apk.rb +15 -0
- data/lib/pindo/command/unity/ipa.rb +16 -0
- data/lib/pindo/command.rb +13 -2
- data/lib/pindo/module/android/android_build_config_helper.rb +425 -0
- data/lib/pindo/module/android/apk_helper.rb +23 -25
- data/lib/pindo/module/android/base_helper.rb +572 -0
- data/lib/pindo/module/android/build_helper.rb +8 -318
- data/lib/pindo/module/android/gp_compliance_helper.rb +668 -0
- data/lib/pindo/module/android/gradle_helper.rb +746 -3
- data/lib/pindo/module/appselect.rb +18 -5
- data/lib/pindo/module/build/buildhelper.rb +120 -29
- data/lib/pindo/module/build/unityhelper.rb +675 -18
- data/lib/pindo/module/build/versionhelper.rb +146 -0
- data/lib/pindo/module/cert/certhelper.rb +33 -2
- data/lib/pindo/module/cert/xcodecerthelper.rb +3 -1
- data/lib/pindo/module/pgyer/pgyerhelper.rb +114 -31
- data/lib/pindo/module/xcode/xcodebuildconfig.rb +232 -0
- data/lib/pindo/module/xcode/xcodebuildhelper.rb +0 -1
- data/lib/pindo/version.rb +356 -86
- data/lib/pindo.rb +72 -3
- metadata +5 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3dda2ad2ab5ff48d50a3ff942ac1407f1a641fe132698af831e86153695ab822
|
4
|
+
data.tar.gz: '08347a7f63339395c8572cfed87bc6ab3aac40289dece2ff52ba5486a180c879'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a9535a1eb328a8f8b38eebaccff014192b485d818c9fbe5a1b1053e720b8505f1b3a2568105fa4d4ee8206690e11bf6867222e3f74bbb89a45dde7d5d30ab7ba
|
7
|
+
data.tar.gz: ddc013f1c82a0b7e6705612eaf9e5c23006fab8ccb12c937facf9e6769b1de6d77529df0b0ff52fc4cd6b1beb3ebd0011591fc81af81b61757cc18c891719a2f
|
data/lib/pindo/base/aeshelper.rb
CHANGED
@@ -8,7 +8,7 @@ module Pindo
|
|
8
8
|
module AESHelper
|
9
9
|
|
10
10
|
|
11
|
-
def self.fetch_password(keychain_name:nil)
|
11
|
+
def self.fetch_password(keychain_name:nil, test_file:nil)
|
12
12
|
# password = ENV["MATCH_PASSWORD"]
|
13
13
|
|
14
14
|
server_name = ["match", keychain_name].join("_")
|
@@ -18,9 +18,30 @@ module Pindo
|
|
18
18
|
password = item.password if item
|
19
19
|
|
20
20
|
unless password
|
21
|
+
puts "\e[33m[DEBUG] Keychain中未找到密码,需要用户输入: #{server_name}\e[0m" if ENV['PINDO_DEBUG']
|
21
22
|
password = FastlaneCore::Helper.ask_password(message: "请输入证书仓库的加密密码: ", confirm: true)
|
22
|
-
|
23
|
+
# 尝试添加密码到Keychain,如果已存在则先删除再添加
|
24
|
+
begin
|
25
|
+
# 先检查是否已存在,如果存在则删除
|
26
|
+
existing_item = Security::InternetPassword.find(server: server_name)
|
27
|
+
if existing_item
|
28
|
+
# 重定向stderr到/dev/null来隐藏Keychain的详细输出
|
29
|
+
system("security delete-internet-password -s '#{server_name}' 2>/dev/null")
|
30
|
+
puts "\e[33m[DEBUG] 删除Keychain中的旧密码项: #{server_name}\e[0m" if ENV['PINDO_DEBUG']
|
31
|
+
end
|
32
|
+
|
33
|
+
# 添加新密码,重定向stderr到/dev/null来隐藏Keychain的详细输出
|
34
|
+
system("security add-internet-password -s '#{server_name}' -w '#{password}' 2>/dev/null")
|
35
|
+
puts "\e[32m[DEBUG] 密码已保存到Keychain: #{server_name}\e[0m" if ENV['PINDO_DEBUG']
|
36
|
+
rescue => e
|
37
|
+
# 忽略Keychain错误,继续使用密码
|
38
|
+
# 错误信息可能包含 "already exists" 等,但不影响功能
|
39
|
+
puts "\e[31m[DEBUG] Keychain操作错误: #{e.message}\e[0m" if ENV['PINDO_DEBUG']
|
40
|
+
end
|
41
|
+
else
|
42
|
+
puts "\e[32m[DEBUG] 从Keychain获取密码成功: #{server_name}\e[0m" if ENV['PINDO_DEBUG']
|
23
43
|
end
|
44
|
+
|
24
45
|
return password
|
25
46
|
end
|
26
47
|
|
@@ -0,0 +1,259 @@
|
|
1
|
+
require 'singleton'
|
2
|
+
require 'digest'
|
3
|
+
require 'json'
|
4
|
+
require 'fileutils'
|
5
|
+
|
6
|
+
module Pindo
|
7
|
+
class PindoContext
|
8
|
+
include Singleton
|
9
|
+
|
10
|
+
attr_reader :current_command, :current_directory
|
11
|
+
|
12
|
+
def initialize
|
13
|
+
@current_command = nil
|
14
|
+
@current_directory = nil
|
15
|
+
@is_nested_call = false
|
16
|
+
@memory_selections = {} # 内存缓存
|
17
|
+
@file_cache_loaded = false # 标记文件缓存是否已加载
|
18
|
+
ensure_cache_dir
|
19
|
+
end
|
20
|
+
|
21
|
+
# 设置当前上下文
|
22
|
+
def set_context(command, directory = nil)
|
23
|
+
# 判断是否是嵌套调用
|
24
|
+
if @current_command.nil?
|
25
|
+
# 第一次设置,是顶层命令
|
26
|
+
@is_nested_call = false
|
27
|
+
@current_command = normalize_command(command)
|
28
|
+
@current_directory = directory || Dir.pwd
|
29
|
+
|
30
|
+
# 顶层命令时加载文件缓存并确认
|
31
|
+
if !@file_cache_loaded
|
32
|
+
load_file_cache_with_confirmation
|
33
|
+
@file_cache_loaded = true
|
34
|
+
end
|
35
|
+
|
36
|
+
puts "[PindoContext] 顶层命令: #{command}" if ENV['PINDO_DEBUG']
|
37
|
+
else
|
38
|
+
# 已有命令在执行,是嵌套调用
|
39
|
+
@is_nested_call = true
|
40
|
+
# 保持原有的命令组不变,确保缓存共享
|
41
|
+
puts "[PindoContext] 嵌套调用: #{command} (使用 #{@current_command} 的缓存)" if ENV['PINDO_DEBUG']
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# 重置上下文(顶层命令结束时调用)
|
46
|
+
def reset_context
|
47
|
+
# 保存文件缓存
|
48
|
+
save_file_cache if @current_command && !@is_nested_call
|
49
|
+
|
50
|
+
@current_command = nil
|
51
|
+
@current_directory = nil
|
52
|
+
@is_nested_call = false
|
53
|
+
@file_cache_loaded = false
|
54
|
+
# 暂不清理内存缓存,让同一进程内可以复用
|
55
|
+
end
|
56
|
+
|
57
|
+
# 设置用户选择
|
58
|
+
def set_selection(key, value)
|
59
|
+
context_key = get_context_key
|
60
|
+
return unless context_key
|
61
|
+
|
62
|
+
@memory_selections[context_key] ||= {}
|
63
|
+
@memory_selections[context_key][key] = value
|
64
|
+
|
65
|
+
# 立即保存到文件缓存
|
66
|
+
save_file_cache
|
67
|
+
|
68
|
+
if ENV['PINDO_DEBUG']
|
69
|
+
puts "[PindoContext] 记录选择: #{key} = #{value.inspect}"
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
# 获取用户选择
|
74
|
+
def get_selection(key)
|
75
|
+
context_key = get_context_key
|
76
|
+
return nil unless context_key
|
77
|
+
|
78
|
+
value = @memory_selections[context_key] && @memory_selections[context_key][key]
|
79
|
+
|
80
|
+
if value && ENV['PINDO_DEBUG']
|
81
|
+
puts "[PindoContext] 使用缓存: #{key} = #{value.inspect}"
|
82
|
+
end
|
83
|
+
|
84
|
+
value
|
85
|
+
end
|
86
|
+
|
87
|
+
# 检查是否有缓存的选择
|
88
|
+
def has_selection?(key)
|
89
|
+
!get_selection(key).nil?
|
90
|
+
end
|
91
|
+
|
92
|
+
# 是否是嵌套调用
|
93
|
+
def nested_call?
|
94
|
+
@is_nested_call
|
95
|
+
end
|
96
|
+
|
97
|
+
# 选择键定义
|
98
|
+
module SelectionKey
|
99
|
+
TAG_DECISION = :tag_decision # 打Tag决定
|
100
|
+
APP_KEY = :app_key # 项目名称/App代号
|
101
|
+
BUNDLE_ID = :bundle_id # Bundle ID
|
102
|
+
CERT_TYPE = :cert_type # 证书类型
|
103
|
+
end
|
104
|
+
|
105
|
+
private
|
106
|
+
|
107
|
+
# 确保缓存目录存在
|
108
|
+
def ensure_cache_dir
|
109
|
+
cache_dir = File.expand_path('~/.pindo/cache')
|
110
|
+
FileUtils.mkdir_p(cache_dir) unless File.exist?(cache_dir)
|
111
|
+
end
|
112
|
+
|
113
|
+
# 获取缓存文件路径
|
114
|
+
def cache_file_path
|
115
|
+
cache_dir = File.expand_path('~/.pindo/cache')
|
116
|
+
File.join(cache_dir, 'context_selections.json')
|
117
|
+
end
|
118
|
+
|
119
|
+
# 加载文件缓存并确认
|
120
|
+
def load_file_cache_with_confirmation
|
121
|
+
file_path = cache_file_path
|
122
|
+
return unless File.exist?(file_path)
|
123
|
+
|
124
|
+
begin
|
125
|
+
file_content = File.read(file_path)
|
126
|
+
file_cache = JSON.parse(file_content)
|
127
|
+
|
128
|
+
# 获取当前上下文的缓存
|
129
|
+
context_key = get_context_key
|
130
|
+
cached_selections = file_cache[context_key]
|
131
|
+
|
132
|
+
if cached_selections && !cached_selections.empty?
|
133
|
+
# 显示缓存的选择
|
134
|
+
puts "\n检测到之前的选择:"
|
135
|
+
puts "────────────────────────────────────────"
|
136
|
+
|
137
|
+
cached_selections.each do |key, value|
|
138
|
+
case key
|
139
|
+
when 'bundle_id', :bundle_id
|
140
|
+
puts " Bundle ID: #{value}"
|
141
|
+
when 'app_key', :app_key
|
142
|
+
puts " App代号: #{value}"
|
143
|
+
when 'tag_decision', :tag_decision
|
144
|
+
if value.is_a?(Hash)
|
145
|
+
action_desc = value['description'] || value['action']
|
146
|
+
puts " Tag决定: #{action_desc}"
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
puts "────────────────────────────────────────"
|
151
|
+
|
152
|
+
# 询问用户是否使用缓存
|
153
|
+
require 'highline/import'
|
154
|
+
cli = HighLine.new
|
155
|
+
confirm = cli.agree("\n是否使用以上缓存的选择? (y/n) ")
|
156
|
+
|
157
|
+
if confirm
|
158
|
+
puts "使用缓存的选择\n"
|
159
|
+
# 合并文件缓存到内存缓存
|
160
|
+
file_cache.each do |ctx_key, selections|
|
161
|
+
@memory_selections[ctx_key] ||= {}
|
162
|
+
selections.each do |key, value|
|
163
|
+
symbol_key = key.to_sym
|
164
|
+
@memory_selections[ctx_key][symbol_key] = value
|
165
|
+
end
|
166
|
+
end
|
167
|
+
else
|
168
|
+
puts "清除缓存,重新选择\n"
|
169
|
+
# 清除当前上下文的文件缓存
|
170
|
+
file_cache.delete(context_key)
|
171
|
+
File.write(file_path, JSON.pretty_generate(file_cache))
|
172
|
+
# 不加载任何缓存到内存
|
173
|
+
end
|
174
|
+
else
|
175
|
+
# 加载其他上下文的缓存(不需要确认)
|
176
|
+
file_cache.each do |ctx_key, selections|
|
177
|
+
next if ctx_key == context_key # 跳过当前上下文(已经是空的)
|
178
|
+
@memory_selections[ctx_key] ||= {}
|
179
|
+
selections.each do |key, value|
|
180
|
+
symbol_key = key.to_sym
|
181
|
+
@memory_selections[ctx_key][symbol_key] = value
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
puts "[PindoContext] 处理文件缓存: #{file_path}" if ENV['PINDO_DEBUG']
|
187
|
+
rescue => e
|
188
|
+
puts "[PindoContext] 加载缓存失败: #{e.message}" if ENV['PINDO_DEBUG']
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
# 保存文件缓存
|
193
|
+
def save_file_cache
|
194
|
+
file_path = cache_file_path
|
195
|
+
|
196
|
+
begin
|
197
|
+
# 转换内存缓存为可序列化的格式
|
198
|
+
file_cache = {}
|
199
|
+
@memory_selections.each do |context_key, selections|
|
200
|
+
file_cache[context_key] = {}
|
201
|
+
selections.each do |key, value|
|
202
|
+
# 将符号键转换为字符串
|
203
|
+
string_key = key.to_s
|
204
|
+
file_cache[context_key][string_key] = value
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
# 写入文件
|
209
|
+
File.write(file_path, JSON.pretty_generate(file_cache))
|
210
|
+
|
211
|
+
puts "[PindoContext] 保存文件缓存: #{file_path}" if ENV['PINDO_DEBUG']
|
212
|
+
rescue => e
|
213
|
+
puts "[PindoContext] 保存缓存失败: #{e.message}" if ENV['PINDO_DEBUG']
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
# 命令归一化,将相关命令映射到同一组
|
218
|
+
def normalize_command(command)
|
219
|
+
case command
|
220
|
+
when 'ios:autobuild', 'unity:ipa'
|
221
|
+
'ios_build_group'
|
222
|
+
when 'android:autobuild', 'android:build', 'unity:apk'
|
223
|
+
'android_build_group'
|
224
|
+
when 'unity:webgl'
|
225
|
+
'webgl_build_group'
|
226
|
+
else
|
227
|
+
command
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
# 生成上下文键
|
232
|
+
def get_context_key
|
233
|
+
return nil unless @current_command
|
234
|
+
|
235
|
+
# 使用命令组和目录哈希作为键
|
236
|
+
dir_hash = Digest::MD5.hexdigest(@current_directory || Dir.pwd)[0..7]
|
237
|
+
"#{@current_command}:#{dir_hash}"
|
238
|
+
end
|
239
|
+
|
240
|
+
public
|
241
|
+
|
242
|
+
# 调试信息
|
243
|
+
def debug_info
|
244
|
+
puts "\n=== PindoContext Debug Info ==="
|
245
|
+
puts "当前命令: #{@current_command || '无'}"
|
246
|
+
puts "当前目录: #{@current_directory || Dir.pwd}"
|
247
|
+
puts "是否嵌套: #{@is_nested_call}"
|
248
|
+
puts "上下文键: #{get_context_key || '无'}"
|
249
|
+
|
250
|
+
if @memory_selections[get_context_key]
|
251
|
+
puts "当前缓存的选择:"
|
252
|
+
@memory_selections[get_context_key].each do |k, v|
|
253
|
+
puts " #{k}: #{v.inspect}"
|
254
|
+
end
|
255
|
+
end
|
256
|
+
puts "================================\n"
|
257
|
+
end
|
258
|
+
end
|
259
|
+
end
|