pindo 5.3.7 → 5.4.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/pindocontext.rb +330 -102
- data/lib/pindo/command/android/autobuild.rb +6 -0
- data/lib/pindo/command/ios/autobuild.rb +8 -5
- data/lib/pindo/command/ios/build.rb +7 -0
- data/lib/pindo/command/unity/apk.rb +5 -0
- data/lib/pindo/command/unity/ipa.rb +11 -3
- data/lib/pindo/command/unity/web.rb +15 -10
- data/lib/pindo/command/web/autobuild.rb +5 -0
- data/lib/pindo/command.rb +64 -12
- data/lib/pindo/module/android/android_build_config_helper.rb +8 -6
- data/lib/pindo/module/build/unityhelper.rb +4 -5
- data/lib/pindo/module/pgyer/pgyerhelper.rb +2 -2
- data/lib/pindo/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 11f6f7b05adc236bf8e379152b9e2d6dbd1bb62da99067637915d3f17768fe77
|
4
|
+
data.tar.gz: 7dd2e73b4bb8edb542d3f274eecf64d3c76b8877ac76aa31ca0e574e7606e3bd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4396cfc57f38554634ca62437021ef29c193a347ffbe460a09cf1bfb9f8ac8e0d1e6e584628c044be1935d41be4e5b131c6d9036f3527d9031ab821e79e713e4
|
7
|
+
data.tar.gz: 135931aae0cdc3c823e59764611f6e64d30d7e58775c1975776073a551b7e849b937859ba9283f45ca3e40dc37035f23594732fd51fb4b943cb1a2c9bd928783
|
@@ -10,75 +10,124 @@ module Pindo
|
|
10
10
|
attr_reader :current_command, :current_directory
|
11
11
|
|
12
12
|
def initialize
|
13
|
-
@current_command = nil
|
14
|
-
@current_directory = nil
|
15
|
-
@
|
16
|
-
@
|
17
|
-
@
|
13
|
+
@current_command = nil # 根命令(第一个设置的命令)
|
14
|
+
@current_directory = nil # 项目路径
|
15
|
+
@memory_selections = {} # 三级结构的内存缓存
|
16
|
+
@file_cache_loaded = false # 标记文件缓存是否已加载
|
17
|
+
@cache_enabled = false # 默认禁用缓存
|
18
|
+
@command_group = nil # 命令组名称
|
19
|
+
@verbose = false # 是否输出详细日志
|
18
20
|
ensure_cache_dir
|
19
21
|
end
|
20
22
|
|
23
|
+
# 判断是否处于 verbose 模式
|
24
|
+
def verbose?
|
25
|
+
@verbose || ENV['PINDO_VERBOSE'] == '1' || ENV['PINDO_DEBUG'] == '1'
|
26
|
+
end
|
27
|
+
|
21
28
|
# 设置当前上下文
|
22
|
-
def set_context(command, directory = nil)
|
23
|
-
#
|
24
|
-
|
25
|
-
#
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
29
|
+
def set_context(command, directory = nil, options = {})
|
30
|
+
# 如果已有命令在执行,这是嵌套调用,不需要做任何事
|
31
|
+
unless @current_command.nil?
|
32
|
+
puts "[PindoContext] 嵌套调用 #{command},使用已有上下文 (根命令: #{@current_command},命令组: #{@command_group})" if verbose?
|
33
|
+
return
|
34
|
+
end
|
35
|
+
|
36
|
+
# 第一次设置,是顶层命令
|
37
|
+
@current_command = command # 保持原始命令名称
|
38
|
+
@current_directory = directory || Dir.pwd # 固定项目目录
|
39
|
+
|
40
|
+
# 从选项中获取缓存配置
|
41
|
+
@cache_enabled = options[:cache_enabled] || false
|
42
|
+
@verbose = options[:verbose] || false
|
43
|
+
# 使用 get_command_group 来确定缓存组
|
44
|
+
@command_group = get_command_group(command)
|
45
|
+
|
46
|
+
if verbose?
|
47
|
+
puts "\n[PindoContext] ========== 设置顶层命令上下文 =========="
|
48
|
+
puts "[PindoContext] 命令: #{command}"
|
49
|
+
puts "[PindoContext] 目录: #{@current_directory}"
|
50
|
+
puts "[PindoContext] 缓存启用: #{@cache_enabled}"
|
51
|
+
puts "[PindoContext] 命令组: #{@command_group}"
|
52
|
+
puts "[PindoContext] options: #{options.inspect}"
|
53
|
+
end
|
35
54
|
|
36
|
-
|
55
|
+
# 仅在启用缓存时加载文件缓存
|
56
|
+
if @cache_enabled && !@file_cache_loaded
|
57
|
+
puts "[PindoContext] 准备加载文件缓存..." if verbose?
|
58
|
+
load_file_cache_with_confirmation
|
59
|
+
@file_cache_loaded = true
|
37
60
|
else
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
61
|
+
if verbose?
|
62
|
+
if !@cache_enabled
|
63
|
+
puts "[PindoContext] 缓存未启用,跳过文件缓存加载"
|
64
|
+
elsif @file_cache_loaded
|
65
|
+
puts "[PindoContext] 文件缓存已加载,跳过重复加载"
|
66
|
+
end
|
67
|
+
end
|
42
68
|
end
|
69
|
+
puts "[PindoContext] ======================================\n" if verbose?
|
43
70
|
end
|
44
71
|
|
45
72
|
# 重置上下文(顶层命令结束时调用)
|
46
73
|
def reset_context
|
47
|
-
#
|
48
|
-
save_file_cache if @
|
74
|
+
# 仅在启用缓存时保存文件缓存
|
75
|
+
save_file_cache if @cache_enabled && @current_command
|
49
76
|
|
50
77
|
@current_command = nil
|
51
78
|
@current_directory = nil
|
52
|
-
@is_nested_call = false
|
53
79
|
@file_cache_loaded = false
|
80
|
+
@cache_enabled = false
|
81
|
+
@command_group = nil
|
54
82
|
# 暂不清理内存缓存,让同一进程内可以复用
|
55
83
|
end
|
56
84
|
|
57
|
-
#
|
85
|
+
# 设置用户选择(三级结构:项目路径 -> 根命令 -> 键值)
|
58
86
|
def set_selection(key, value)
|
59
|
-
|
60
|
-
|
87
|
+
# 构建三级键 - 使用统一的项目路径获取方法
|
88
|
+
project_path = get_project_path
|
89
|
+
root_command = @command_group || @current_command
|
90
|
+
|
91
|
+
# 如果没有有效的项目路径或命令,不保存
|
92
|
+
unless project_path && root_command
|
93
|
+
puts "[PindoContext] 警告: 无法保存选择,缺少项目路径或命令上下文"
|
94
|
+
return
|
95
|
+
end
|
96
|
+
|
97
|
+
# 初始化三级结构(总是保存到内存,不管是否启用缓存)
|
98
|
+
@memory_selections[project_path] ||= {}
|
99
|
+
@memory_selections[project_path][root_command] ||= {}
|
100
|
+
@memory_selections[project_path][root_command][key] = value
|
61
101
|
|
62
|
-
|
63
|
-
@memory_selections[
|
102
|
+
# 更新该命令组的最后修改时间
|
103
|
+
@memory_selections[project_path][root_command]['__last_modified__'] = Time.now.to_i
|
64
104
|
|
65
|
-
#
|
66
|
-
save_file_cache
|
105
|
+
puts "[PindoContext] 保存到内存: [#{project_path}][#{root_command}][#{key}] = #{value.inspect}" if verbose?
|
67
106
|
|
68
|
-
|
69
|
-
|
107
|
+
# 仅在启用缓存时保存到文件
|
108
|
+
if @cache_enabled
|
109
|
+
save_file_cache
|
110
|
+
puts "[PindoContext] 已保存到文件缓存" if verbose?
|
111
|
+
else
|
112
|
+
puts "[PindoContext] 缓存未启用,仅保存到内存" if verbose?
|
70
113
|
end
|
71
114
|
end
|
72
115
|
|
73
|
-
#
|
116
|
+
# 获取用户选择(三级结构访问)
|
74
117
|
def get_selection(key)
|
75
|
-
|
76
|
-
|
118
|
+
# 使用统一的项目路径获取方法
|
119
|
+
project_path = get_project_path
|
120
|
+
root_command = @command_group || @current_command
|
121
|
+
|
122
|
+
return nil unless project_path && root_command
|
77
123
|
|
78
|
-
|
124
|
+
# 从三级结构中获取值(总是从内存获取,不管是否启用缓存)
|
125
|
+
value = @memory_selections.dig(project_path, root_command, key)
|
79
126
|
|
80
|
-
if value
|
81
|
-
puts "[PindoContext]
|
127
|
+
if value
|
128
|
+
puts "[PindoContext] 从内存获取: [#{project_path}][#{root_command}][#{key}] = #{value.inspect}" if verbose?
|
129
|
+
else
|
130
|
+
puts "[PindoContext] 内存中未找到: [#{project_path}][#{root_command}][#{key}]" if verbose?
|
82
131
|
end
|
83
132
|
|
84
133
|
value
|
@@ -86,18 +135,82 @@ module Pindo
|
|
86
135
|
|
87
136
|
# 检查是否有缓存的选择
|
88
137
|
def has_selection?(key)
|
138
|
+
# 总是检查内存中是否有值,不管是否启用缓存
|
89
139
|
!get_selection(key).nil?
|
90
140
|
end
|
91
141
|
|
142
|
+
# 启用/禁用缓存
|
143
|
+
def enable_cache(enabled = true)
|
144
|
+
@cache_enabled = enabled
|
145
|
+
if enabled && !@file_cache_loaded && @current_command
|
146
|
+
load_file_cache_with_confirmation
|
147
|
+
@file_cache_loaded = true
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
# 检查缓存是否启用
|
152
|
+
def cache_enabled?
|
153
|
+
@cache_enabled
|
154
|
+
end
|
155
|
+
|
92
156
|
# 是否是嵌套调用
|
93
157
|
def nested_call?
|
94
|
-
|
158
|
+
!@current_command.nil?
|
159
|
+
end
|
160
|
+
|
161
|
+
# 是否是顶层命令(非嵌套)
|
162
|
+
def top_level_command?
|
163
|
+
@current_command.nil?
|
164
|
+
end
|
165
|
+
|
166
|
+
# 获取当前根命令
|
167
|
+
def root_command
|
168
|
+
@command_group || @current_command
|
169
|
+
end
|
170
|
+
|
171
|
+
# 获取当前项目路径(统一的获取方法,确保一致性)
|
172
|
+
def project_path
|
173
|
+
get_project_path
|
174
|
+
end
|
175
|
+
|
176
|
+
# 内部使用的项目路径获取方法
|
177
|
+
# 优先使用已设置的目录,如果没有则尝试获取Git仓库根目录
|
178
|
+
def get_project_path
|
179
|
+
# 如果已经设置了目录,直接返回
|
180
|
+
return @current_directory if @current_directory
|
181
|
+
|
182
|
+
# 尝试获取Git仓库根目录
|
183
|
+
begin
|
184
|
+
git_root = `git rev-parse --show-toplevel 2>/dev/null`.strip
|
185
|
+
return git_root if $?.success? && !git_root.empty?
|
186
|
+
rescue
|
187
|
+
# git命令失败
|
188
|
+
end
|
189
|
+
|
190
|
+
# 最后的后备:使用当前目录
|
191
|
+
Dir.pwd
|
192
|
+
end
|
193
|
+
|
194
|
+
# 清除当前上下文的缓存
|
195
|
+
def clear_current_cache
|
196
|
+
return unless @cache_enabled
|
197
|
+
|
198
|
+
proj_path = get_project_path
|
199
|
+
cmd = root_command
|
200
|
+
return unless proj_path && cmd
|
201
|
+
|
202
|
+
if @memory_selections[proj_path] && @memory_selections[proj_path][cmd]
|
203
|
+
@memory_selections[proj_path].delete(cmd)
|
204
|
+
@memory_selections.delete(proj_path) if @memory_selections[proj_path].empty?
|
205
|
+
save_file_cache
|
206
|
+
puts "[PindoContext] 清除缓存: [#{proj_path}][#{cmd}]" if verbose?
|
207
|
+
end
|
95
208
|
end
|
96
209
|
|
97
210
|
# 选择键定义
|
98
211
|
module SelectionKey
|
99
212
|
TAG_DECISION = :tag_decision # 打Tag决定
|
100
|
-
|
213
|
+
PROJECT_NAME = :project_name # 项目名称
|
101
214
|
BUNDLE_ID = :bundle_id # Bundle ID
|
102
215
|
CERT_TYPE = :cert_type # 证书类型
|
103
216
|
end
|
@@ -116,35 +229,65 @@ module Pindo
|
|
116
229
|
File.join(cache_dir, 'context_selections.json')
|
117
230
|
end
|
118
231
|
|
119
|
-
#
|
232
|
+
# 加载文件缓存并确认(三级结构)
|
120
233
|
def load_file_cache_with_confirmation
|
121
234
|
file_path = cache_file_path
|
122
|
-
|
235
|
+
|
236
|
+
puts "[PindoContext] 检查文件缓存: #{file_path}" if verbose?
|
237
|
+
|
238
|
+
unless File.exist?(file_path)
|
239
|
+
puts "[PindoContext] 文件缓存不存在,跳过加载" if verbose?
|
240
|
+
return
|
241
|
+
end
|
123
242
|
|
124
243
|
begin
|
125
244
|
file_content = File.read(file_path)
|
126
245
|
file_cache = JSON.parse(file_content)
|
127
246
|
|
128
|
-
#
|
129
|
-
|
130
|
-
|
247
|
+
# 清理过期缓存(超过7天)
|
248
|
+
file_cache = clean_expired_cache(file_cache)
|
249
|
+
|
250
|
+
# 获取当前项目和命令的缓存
|
251
|
+
project_path = get_project_path
|
252
|
+
root_command = @command_group || @current_command
|
253
|
+
|
254
|
+
puts "[PindoContext] 查找缓存: [#{project_path}][#{root_command}]" if verbose?
|
255
|
+
|
256
|
+
# 检查三级结构中是否有当前上下文的缓存
|
257
|
+
cached_selections = file_cache.dig(project_path, root_command)
|
131
258
|
|
132
259
|
if cached_selections && !cached_selections.empty?
|
133
|
-
#
|
134
|
-
|
260
|
+
# 根据命令组显示更友好的描述
|
261
|
+
group_desc = case root_command
|
262
|
+
when 'ios:autobuild'
|
263
|
+
'iOS 构建'
|
264
|
+
when 'and:autobuild', 'android:autobuild'
|
265
|
+
'Android 构建'
|
266
|
+
when 'web:autobuild'
|
267
|
+
'Web 构建'
|
268
|
+
else
|
269
|
+
@current_command # 其他命令显示原始命令名
|
270
|
+
end
|
271
|
+
|
272
|
+
puts "\n检测到之前的选择 (#{group_desc}):"
|
135
273
|
puts "────────────────────────────────────────"
|
136
274
|
|
137
275
|
cached_selections.each do |key, value|
|
138
|
-
|
139
|
-
|
276
|
+
# 跳过内部字段
|
277
|
+
next if key.to_s.start_with?('__')
|
278
|
+
|
279
|
+
case key.to_s
|
280
|
+
when 'bundle_id'
|
140
281
|
puts " Bundle ID: #{value}"
|
141
|
-
when '
|
142
|
-
puts "
|
143
|
-
when 'tag_decision'
|
282
|
+
when 'project_name', 'app_key' # 兼容旧的 app_key
|
283
|
+
puts " 项目名称: #{value}"
|
284
|
+
when 'tag_decision'
|
144
285
|
if value.is_a?(Hash)
|
145
286
|
action_desc = value['description'] || value['action']
|
146
287
|
puts " Tag决定: #{action_desc}"
|
147
288
|
end
|
289
|
+
when 'cert_type'
|
290
|
+
puts " 证书类型: #{value}"
|
148
291
|
end
|
149
292
|
end
|
150
293
|
puts "────────────────────────────────────────"
|
@@ -156,100 +299,185 @@ module Pindo
|
|
156
299
|
|
157
300
|
if confirm
|
158
301
|
puts "使用缓存的选择\n"
|
159
|
-
#
|
160
|
-
file_cache.each do |
|
161
|
-
@memory_selections[
|
162
|
-
|
163
|
-
|
164
|
-
|
302
|
+
# 恢复三级结构的文件缓存到内存缓存
|
303
|
+
file_cache.each do |proj_path, commands|
|
304
|
+
@memory_selections[proj_path] ||= {}
|
305
|
+
commands.each do |cmd, selections|
|
306
|
+
@memory_selections[proj_path][cmd] ||= {}
|
307
|
+
selections.each do |key, value|
|
308
|
+
symbol_key = key.to_sym
|
309
|
+
@memory_selections[proj_path][cmd][symbol_key] = value
|
310
|
+
end
|
165
311
|
end
|
166
312
|
end
|
167
313
|
else
|
168
314
|
puts "清除缓存,重新选择\n"
|
169
|
-
#
|
170
|
-
file_cache
|
315
|
+
# 清除当前上下文的文件缓存(三级结构)
|
316
|
+
if file_cache[project_path] && file_cache[project_path][root_command]
|
317
|
+
file_cache[project_path].delete(root_command)
|
318
|
+
# 如果项目路径下没有任何命令缓存了,删除项目路径键
|
319
|
+
file_cache.delete(project_path) if file_cache[project_path].empty?
|
320
|
+
end
|
171
321
|
File.write(file_path, JSON.pretty_generate(file_cache))
|
172
322
|
# 不加载任何缓存到内存
|
173
323
|
end
|
174
324
|
else
|
175
|
-
#
|
176
|
-
file_cache.each do |
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
325
|
+
# 加载整个文件缓存到内存(不需要确认)
|
326
|
+
file_cache.each do |proj_path, commands|
|
327
|
+
@memory_selections[proj_path] ||= {}
|
328
|
+
commands.each do |cmd, selections|
|
329
|
+
# 跳过当前上下文(已经是空的)
|
330
|
+
next if proj_path == project_path && cmd == root_command
|
331
|
+
|
332
|
+
@memory_selections[proj_path][cmd] ||= {}
|
333
|
+
selections.each do |key, value|
|
334
|
+
symbol_key = key.to_sym
|
335
|
+
@memory_selections[proj_path][cmd][symbol_key] = value
|
336
|
+
end
|
182
337
|
end
|
183
338
|
end
|
184
339
|
end
|
185
340
|
|
186
|
-
puts "[PindoContext] 处理文件缓存: #{file_path}" if
|
341
|
+
puts "[PindoContext] 处理文件缓存: #{file_path}" if verbose?
|
187
342
|
rescue => e
|
188
|
-
puts "[PindoContext] 加载缓存失败: #{e.message}" if
|
343
|
+
puts "[PindoContext] 加载缓存失败: #{e.message}" if verbose?
|
189
344
|
end
|
190
345
|
end
|
191
346
|
|
192
|
-
#
|
347
|
+
# 保存文件缓存(三级结构)
|
193
348
|
def save_file_cache
|
194
349
|
file_path = cache_file_path
|
195
350
|
|
196
351
|
begin
|
197
|
-
#
|
352
|
+
# 转换内存缓存为可序列化的格式(保持三级结构)
|
198
353
|
file_cache = {}
|
199
|
-
@memory_selections.each do |
|
200
|
-
file_cache[
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
354
|
+
@memory_selections.each do |project_path, commands|
|
355
|
+
file_cache[project_path] ||= {}
|
356
|
+
commands.each do |command, selections|
|
357
|
+
file_cache[project_path][command] ||= {}
|
358
|
+
selections.each do |key, value|
|
359
|
+
# 将符号键转换为字符串
|
360
|
+
string_key = key.to_s
|
361
|
+
file_cache[project_path][command][string_key] = value
|
362
|
+
end
|
205
363
|
end
|
206
364
|
end
|
207
365
|
|
208
366
|
# 写入文件
|
209
367
|
File.write(file_path, JSON.pretty_generate(file_cache))
|
210
368
|
|
211
|
-
puts "[PindoContext] 保存文件缓存: #{file_path}" if
|
369
|
+
puts "[PindoContext] 保存文件缓存: #{file_path}" if verbose?
|
212
370
|
rescue => e
|
213
|
-
puts "[PindoContext] 保存缓存失败: #{e.message}" if
|
371
|
+
puts "[PindoContext] 保存缓存失败: #{e.message}" if verbose?
|
214
372
|
end
|
215
373
|
end
|
216
374
|
|
217
|
-
#
|
218
|
-
def
|
375
|
+
# 获取命令组名称(统一管理命令缓存组)
|
376
|
+
def get_command_group(command)
|
377
|
+
# 根据需求文档定义命令组,相关命令共享同一缓存
|
219
378
|
case command
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
379
|
+
# iOS 构建相关命令组
|
380
|
+
when 'unity:ipa'
|
381
|
+
'ios:autobuild'
|
382
|
+
|
383
|
+
# Android 构建相关命令组
|
384
|
+
when 'unity:apk'
|
385
|
+
'and:autobuild'
|
386
|
+
|
387
|
+
# Web 构建相关命令组
|
388
|
+
when 'unity:web'
|
389
|
+
'web:autobuild'
|
390
|
+
|
226
391
|
else
|
227
|
-
command
|
392
|
+
command # 其他命令使用独立缓存(命令名本身作为组)
|
228
393
|
end
|
229
394
|
end
|
230
395
|
|
231
|
-
#
|
232
|
-
def
|
233
|
-
return
|
396
|
+
# 清理过期缓存(超过7天的缓存)
|
397
|
+
def clean_expired_cache(cache_data)
|
398
|
+
return {} unless cache_data.is_a?(Hash)
|
399
|
+
|
400
|
+
current_time = Time.now.to_i
|
401
|
+
seven_days_in_seconds = 7 * 24 * 60 * 60
|
402
|
+
cleaned_cache = {}
|
403
|
+
expired_commands = []
|
404
|
+
expired_projects = []
|
405
|
+
|
406
|
+
cache_data.each do |project_path, commands|
|
407
|
+
# 初始化项目路径
|
408
|
+
cleaned_commands = {}
|
409
|
+
|
410
|
+
commands.each do |command, selections|
|
411
|
+
# 获取最后修改时间
|
412
|
+
last_modified = selections['__last_modified__']
|
413
|
+
|
414
|
+
# 如果没有时间戳,视为过期
|
415
|
+
if last_modified.nil?
|
416
|
+
expired_commands << "[#{project_path}][#{command}] (无时间戳)"
|
417
|
+
puts "[PindoContext] 清理无时间戳缓存: [#{project_path}][#{command}]" if verbose?
|
418
|
+
next
|
419
|
+
end
|
420
|
+
|
421
|
+
# 检查是否过期(超过7天)
|
422
|
+
if (current_time - last_modified.to_i) > seven_days_in_seconds
|
423
|
+
days_old = (current_time - last_modified.to_i) / (24 * 60 * 60)
|
424
|
+
expired_commands << "[#{project_path}][#{command}] (#{days_old}天前)"
|
425
|
+
puts "[PindoContext] 清理过期缓存 (#{days_old}天前): [#{project_path}][#{command}]" if verbose?
|
426
|
+
next
|
427
|
+
end
|
428
|
+
|
429
|
+
# 保留未过期的缓存
|
430
|
+
cleaned_commands[command] = selections
|
431
|
+
end
|
432
|
+
|
433
|
+
# 如果该项目路径下还有有效的命令缓存,保留它
|
434
|
+
if cleaned_commands.any?
|
435
|
+
cleaned_cache[project_path] = cleaned_commands
|
436
|
+
else
|
437
|
+
# 整个项目路径下的所有命令都过期了,删除整个项目路径
|
438
|
+
expired_projects << project_path
|
439
|
+
puts "[PindoContext] 删除空项目路径: #{project_path}" if verbose?
|
440
|
+
end
|
441
|
+
end
|
442
|
+
|
443
|
+
# 输出清理总结
|
444
|
+
if expired_commands.any? || expired_projects.any?
|
445
|
+
puts "[PindoContext] 缓存清理完成:"
|
446
|
+
if expired_commands.any?
|
447
|
+
puts " - 清理了 #{expired_commands.size} 个过期命令缓存"
|
448
|
+
expired_commands.each { |cmd| puts " • #{cmd}" } if verbose?
|
449
|
+
end
|
450
|
+
if expired_projects.any?
|
451
|
+
puts " - 删除了 #{expired_projects.size} 个空项目路径"
|
452
|
+
expired_projects.each { |proj| puts " • #{proj}" } if verbose?
|
453
|
+
end
|
234
454
|
|
235
|
-
|
236
|
-
|
237
|
-
|
455
|
+
# 立即保存清理后的缓存到文件
|
456
|
+
File.write(cache_file_path, JSON.pretty_generate(cleaned_cache))
|
457
|
+
end
|
458
|
+
|
459
|
+
cleaned_cache
|
238
460
|
end
|
239
461
|
|
462
|
+
|
240
463
|
public
|
241
464
|
|
242
465
|
# 调试信息
|
243
466
|
def debug_info
|
244
467
|
puts "\n=== PindoContext Debug Info ==="
|
245
468
|
puts "当前命令: #{@current_command || '无'}"
|
246
|
-
puts "
|
247
|
-
puts "
|
248
|
-
puts "
|
469
|
+
puts "命令组: #{@command_group || '无'}"
|
470
|
+
puts "设置的目录: #{@current_directory || '未设置'}"
|
471
|
+
puts "实际项目路径: #{get_project_path}"
|
472
|
+
puts "缓存启用: #{@cache_enabled}"
|
473
|
+
|
474
|
+
proj_path = get_project_path
|
475
|
+
root_cmd = @command_group || @current_command
|
249
476
|
|
250
|
-
if @memory_selections
|
477
|
+
if root_cmd && @memory_selections.dig(proj_path, root_cmd)
|
251
478
|
puts "当前缓存的选择:"
|
252
|
-
@memory_selections[
|
479
|
+
@memory_selections[proj_path][root_cmd].each do |k, v|
|
480
|
+
next if k.to_s.start_with?('__') # 跳过内部字段
|
253
481
|
puts " #{k}: #{v.inspect}"
|
254
482
|
end
|
255
483
|
end
|
@@ -12,11 +12,18 @@ module Pindo
|
|
12
12
|
class Command
|
13
13
|
class Ios < Command
|
14
14
|
class Autobuild < Ios
|
15
|
-
|
15
|
+
|
16
16
|
include Appselect
|
17
17
|
include Pindo::Githelper
|
18
18
|
# 命令的简要说明 - 打包iOS工程并发布到蒲公英
|
19
19
|
self.summary = '打包iOS工程并发布到蒲公英'
|
20
|
+
|
21
|
+
# 启用缓存机制
|
22
|
+
def self.use_cache?
|
23
|
+
true # 此命令启用缓存
|
24
|
+
end
|
25
|
+
# 缓存组已在 PindoContext#get_command_group 中定义
|
26
|
+
# ios:autobuild 与 unity:ipa 共享 'ios:autobuild' 缓存组
|
20
27
|
|
21
28
|
# 命令的详细说明,包含用法示例
|
22
29
|
self.description = <<-DESC
|
@@ -84,10 +91,6 @@ module Pindo
|
|
84
91
|
def run
|
85
92
|
pindo_project_dir = Dir.pwd
|
86
93
|
|
87
|
-
# 设置 PindoContext 上下文
|
88
|
-
context = Pindo::PindoContext.instance
|
89
|
-
context.set_context('ios:autobuild', pindo_project_dir)
|
90
|
-
|
91
94
|
build_helper = Pindo::BuildHelper.share_instance
|
92
95
|
project_type = build_helper.project_type(pindo_project_dir)
|
93
96
|
|
@@ -13,6 +13,13 @@ module Pindo
|
|
13
13
|
# 命令的简要说明 - 编译iOS工程并可选择上传到测试平台
|
14
14
|
self.summary = '编译iOS工程,并支持上传ipa'
|
15
15
|
|
16
|
+
# 启用缓存机制
|
17
|
+
def self.use_cache?
|
18
|
+
true # 此命令启用缓存
|
19
|
+
end
|
20
|
+
# 缓存组已在 PindoContext#get_command_group 中定义
|
21
|
+
# ios:build 与 ios:autobuild 共享 'ios:autobuild' 缓存组
|
22
|
+
|
16
23
|
# 命令的详细说明,包含用法示例
|
17
24
|
self.description = <<-DESC
|
18
25
|
编译iOS工程并生成ipa文件。
|
@@ -13,11 +13,18 @@ module Pindo
|
|
13
13
|
class Ipa < Unity
|
14
14
|
|
15
15
|
include Appselect
|
16
|
-
|
16
|
+
|
17
17
|
include Pindo::Githelper
|
18
18
|
# Unity IPA包编译和上传命令
|
19
19
|
self.summary = '编译Unity工程生成iOS IPA并支持上传到测试平台'
|
20
20
|
|
21
|
+
# 启用缓存机制
|
22
|
+
def self.use_cache?
|
23
|
+
true # 此命令启用缓存
|
24
|
+
end
|
25
|
+
# 缓存组已在 PindoContext#get_command_group 中定义
|
26
|
+
# unity:ipa 与 ios:autobuild 共享 'ios:autobuild' 缓存组
|
27
|
+
|
21
28
|
# 详细说明
|
22
29
|
self.description = <<-DESC
|
23
30
|
编译Unity工程生成iOS IPA并支持上传到测试平台。
|
@@ -158,9 +165,10 @@ module Pindo
|
|
158
165
|
if @args_send_flag
|
159
166
|
args_temp << "--send"
|
160
167
|
end
|
161
|
-
|
168
|
+
|
169
|
+
|
162
170
|
Dir.chdir(pindo_ios_project_dir)
|
163
|
-
|
171
|
+
|
164
172
|
Pindo::Command::Ios::Autobuild::run(args_temp)
|
165
173
|
|
166
174
|
|
@@ -14,30 +14,35 @@ module Pindo
|
|
14
14
|
include Appselect
|
15
15
|
|
16
16
|
include Pindo::Githelper
|
17
|
-
# Unity
|
18
|
-
self.summary = '编译Unity工程生成
|
17
|
+
# Unity WebGL包编译和上传命令
|
18
|
+
self.summary = '编译Unity工程生成WebGL并支持上传到测试平台'
|
19
|
+
|
20
|
+
# 启用缓存机制
|
21
|
+
def self.use_cache?
|
22
|
+
true # 此命令启用缓存
|
23
|
+
end
|
19
24
|
|
20
25
|
# 详细说明
|
21
26
|
self.description = <<-DESC
|
22
|
-
编译Unity工程生成
|
27
|
+
编译Unity工程生成WebGL并支持上传到测试平台。
|
23
28
|
|
24
29
|
支持功能:
|
25
30
|
|
26
|
-
* 编译生成
|
31
|
+
* 编译生成WebGL
|
27
32
|
|
28
|
-
* 上传到测试平台
|
33
|
+
* 上传到测试平台
|
29
34
|
|
30
35
|
* 发送测试通知
|
31
36
|
|
32
37
|
使用示例:
|
33
38
|
|
34
|
-
$ pindo unity
|
39
|
+
$ pindo unity web # 编译WebGL
|
35
40
|
|
36
|
-
$ pindo unity
|
41
|
+
$ pindo unity web --upload # 编译并上传
|
37
42
|
|
38
|
-
$ pindo unity
|
43
|
+
$ pindo unity web --send # 编译上传并发送通知
|
39
44
|
|
40
|
-
$ pindo unity
|
45
|
+
$ pindo unity web --proj=myapp # 指定项目名称
|
41
46
|
DESC
|
42
47
|
|
43
48
|
# 命令参数
|
@@ -49,7 +54,7 @@ module Pindo
|
|
49
54
|
def self.options
|
50
55
|
[
|
51
56
|
['--proj', '指定上传到测试平台的项目名称'],
|
52
|
-
['--upload', '上传编译后的
|
57
|
+
['--upload', '上传编译后的WebGL到测试平台'],
|
53
58
|
['--send', '上传成功后发送测试通知'],
|
54
59
|
['--base', 'Unity工程编译lib模式'],
|
55
60
|
['--unity-version', '切换Unity版本']
|
data/lib/pindo/command.rb
CHANGED
@@ -60,6 +60,13 @@ module Pindo
|
|
60
60
|
self.version = VERSION
|
61
61
|
self.description = 'pindo, make it easy!'
|
62
62
|
|
63
|
+
# 缓存配置:子类可以重写此方法来启用缓存
|
64
|
+
def self.use_cache?
|
65
|
+
false # 默认不使用缓存
|
66
|
+
end
|
67
|
+
# 注意:缓存组的定义已经移至 PindoContext#get_command_group 中统一管理
|
68
|
+
# 使用命令名作为组名,如 ios:autobuild, and:autobuild, web:autobuild
|
69
|
+
|
63
70
|
|
64
71
|
DEFAULT_ROOT_OPTIONS = [
|
65
72
|
['--version', '查看pindo版本'],
|
@@ -67,6 +74,7 @@ module Pindo
|
|
67
74
|
|
68
75
|
DEFAULT_OPTIONS = [
|
69
76
|
['--help', '查看命令行用法'],
|
77
|
+
['--verbose', '显示详细的调试信息'],
|
70
78
|
]
|
71
79
|
|
72
80
|
|
@@ -90,23 +98,67 @@ module Pindo
|
|
90
98
|
end
|
91
99
|
|
92
100
|
def self.run(argv)
|
93
|
-
#
|
94
|
-
|
95
|
-
|
96
|
-
context.set_context(command_name)
|
97
|
-
|
98
|
-
begin
|
99
|
-
result = super(argv)
|
100
|
-
ensure
|
101
|
-
# 确保在命令结束时重置上下文
|
102
|
-
context.reset_context
|
103
|
-
end
|
104
|
-
result
|
101
|
+
# 直接调用父类的 run 方法
|
102
|
+
# PindoContext 的设置在 initialize 中处理
|
103
|
+
super(argv)
|
105
104
|
end
|
106
105
|
|
107
106
|
def initialize(argv)
|
108
107
|
super
|
109
108
|
@args_help_flag = argv.flag?('help', false)
|
109
|
+
@args_verbose_flag = argv.flag?('verbose', false)
|
110
|
+
|
111
|
+
# 设置全局 verbose 标志
|
112
|
+
ENV['PINDO_VERBOSE'] = '1' if @args_verbose_flag
|
113
|
+
|
114
|
+
# 在非抽象命令初始化时设置上下文
|
115
|
+
if !self.class.abstract_command? && !@args_help_flag
|
116
|
+
context = Pindo::PindoContext.instance
|
117
|
+
|
118
|
+
# 只在上下文未设置时才设置(避免重复设置)
|
119
|
+
if context.instance_variable_get(:@current_command).nil?
|
120
|
+
# 获取完整的命令路径
|
121
|
+
command_parts = []
|
122
|
+
current = self.class
|
123
|
+
while current < Pindo::Command
|
124
|
+
if current.command && current.command != 'pindo'
|
125
|
+
command_parts.unshift(current.command)
|
126
|
+
end
|
127
|
+
current = current.superclass
|
128
|
+
end
|
129
|
+
command_name = command_parts.empty? ? self.class.command : command_parts.join(':')
|
130
|
+
|
131
|
+
# 配置选项
|
132
|
+
cache_enabled_value = self.class.respond_to?(:use_cache?) ? self.class.use_cache? : false
|
133
|
+
options = {
|
134
|
+
cache_enabled: cache_enabled_value,
|
135
|
+
verbose: @args_verbose_flag
|
136
|
+
}
|
137
|
+
|
138
|
+
# 获取项目根目录(Git仓库根目录或当前目录)
|
139
|
+
project_dir = get_project_root_directory(Dir.pwd)
|
140
|
+
|
141
|
+
context.set_context(command_name, project_dir, options)
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
private
|
147
|
+
|
148
|
+
# 获取项目根目录(优先使用Git仓库根目录)
|
149
|
+
def get_project_root_directory(current_dir)
|
150
|
+
# 尝试获取Git仓库根目录
|
151
|
+
begin
|
152
|
+
git_root = `cd "#{current_dir}" && git rev-parse --show-toplevel 2>/dev/null`.strip
|
153
|
+
if $?.success? && !git_root.empty?
|
154
|
+
return git_root
|
155
|
+
end
|
156
|
+
rescue
|
157
|
+
# git命令失败,继续使用当前目录
|
158
|
+
end
|
159
|
+
|
160
|
+
# 如果不是Git仓库,返回当前目录
|
161
|
+
current_dir
|
110
162
|
end
|
111
163
|
|
112
164
|
end
|
@@ -263,8 +263,9 @@ module Pindo
|
|
263
263
|
activities.each do |activity|
|
264
264
|
intent_filters = activity.xpath("intent-filter")
|
265
265
|
intent_filters.each do |intent_filter|
|
266
|
-
|
267
|
-
|
266
|
+
# 修复:移除命名空间后,应该使用 @name 而不是 @android:name
|
267
|
+
has_main = intent_filter.xpath("action[@name='android.intent.action.MAIN']").any?
|
268
|
+
has_launcher = intent_filter.xpath("category[@name='android.intent.category.LAUNCHER']").any?
|
268
269
|
|
269
270
|
if has_main && has_launcher
|
270
271
|
best_manifest = manifest_path
|
@@ -277,6 +278,7 @@ module Pindo
|
|
277
278
|
end
|
278
279
|
rescue => e
|
279
280
|
# 静默处理解析错误,继续尝试下一个文件
|
281
|
+
puts "解析 #{manifest_path} 时出错: #{e.message}" if ENV['PINDO_DEBUG']
|
280
282
|
end
|
281
283
|
|
282
284
|
break if best_activity
|
@@ -290,8 +292,8 @@ module Pindo
|
|
290
292
|
scheme_exists = false
|
291
293
|
existing_scheme = nil
|
292
294
|
|
293
|
-
# 首先检查完全一致的scheme
|
294
|
-
activity.xpath("intent-filter/data[
|
295
|
+
# 首先检查完全一致的scheme(修复:移除命名空间后使用 @scheme)
|
296
|
+
activity.xpath("intent-filter/data[@scheme='#{scheme_name}']").each do |node|
|
295
297
|
scheme_exists = true
|
296
298
|
existing_scheme = scheme_name
|
297
299
|
break
|
@@ -299,8 +301,8 @@ module Pindo
|
|
299
301
|
|
300
302
|
# 如果没有找到完全一致的,检查可能格式不同的scheme
|
301
303
|
if !scheme_exists
|
302
|
-
activity.xpath("intent-filter/data[
|
303
|
-
current_scheme = node["
|
304
|
+
activity.xpath("intent-filter/data[@scheme]").each do |node|
|
305
|
+
current_scheme = node["scheme"]
|
304
306
|
normalized_current = current_scheme.to_s.downcase.strip.gsub(/[\s\-_]/, '')
|
305
307
|
|
306
308
|
if normalized_current == scheme_name
|
@@ -389,7 +389,7 @@ module Pindo
|
|
389
389
|
additional_args = {}
|
390
390
|
additional_args[:platform] = platform if platform
|
391
391
|
additional_args[:buildtype] = 'library' if isLibrary
|
392
|
-
|
392
|
+
|
393
393
|
# 首先尝试使用GoodUnityBuild.BuildManager.BatchBuild
|
394
394
|
result = execute_unity_command(unity_exe_full_path, project_path, additional_args)
|
395
395
|
|
@@ -537,7 +537,6 @@ module Pindo
|
|
537
537
|
# 解析Unity进程信息
|
538
538
|
def parse_unity_processes(processes_output, unity_exe_full_path: nil, project_path: nil)
|
539
539
|
processes = []
|
540
|
-
current_pid = Process.pid.to_s
|
541
540
|
|
542
541
|
processes_output.lines.each do |line|
|
543
542
|
# 解析 ps aux 输出格式
|
@@ -546,14 +545,14 @@ module Pindo
|
|
546
545
|
pid = parts[1]
|
547
546
|
command = parts[10..-1].join(' ')
|
548
547
|
|
549
|
-
# 过滤掉grep
|
550
|
-
unless command.include?('grep') || command.include?('pindo')
|
548
|
+
# 过滤掉grep进程本身和pindo进程
|
549
|
+
unless command.include?('grep') || command.include?('pindo')
|
551
550
|
# 精确匹配Unity进程
|
552
551
|
is_relevant_unity_process = false
|
553
552
|
match_reasons = []
|
554
553
|
|
555
554
|
# 1. 必须是Unity Editor主进程(排除VS Code等其他进程)
|
556
|
-
is_unity_editor = command.match?(/Unity\.app.*\/Unity/i) || command.match?(/Unity\.exe
|
555
|
+
is_unity_editor = command.match?(/Unity\.app.*\/Unity/i) || command.match?(/Unity\.exe/i)
|
557
556
|
|
558
557
|
if is_unity_editor
|
559
558
|
# 2. 检查是否是打开了指定项目的Unity进程
|
@@ -108,7 +108,7 @@ module Pindo
|
|
108
108
|
# 检查缓存的 App Key
|
109
109
|
require_relative '../../base/pindocontext'
|
110
110
|
context = Pindo::PindoContext.instance
|
111
|
-
cached_app_key = context.get_selection(Pindo::PindoContext::SelectionKey::
|
111
|
+
cached_app_key = context.get_selection(Pindo::PindoContext::SelectionKey::PROJECT_NAME)
|
112
112
|
|
113
113
|
if cached_app_key && proj_name_array.include?(cached_app_key)
|
114
114
|
puts "\n使用之前选择的App代号: #{cached_app_key}"
|
@@ -135,7 +135,7 @@ module Pindo
|
|
135
135
|
|
136
136
|
# 保存选择到缓存(排除自定义输入选项)
|
137
137
|
if upload_proj_name && !upload_proj_name.include?("自定义输入")
|
138
|
-
context.set_selection(Pindo::PindoContext::SelectionKey::
|
138
|
+
context.set_selection(Pindo::PindoContext::SelectionKey::PROJECT_NAME, upload_proj_name)
|
139
139
|
end
|
140
140
|
end
|
141
141
|
|
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.4.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- wade
|
8
8
|
bindir: bin
|
9
9
|
cert_chain: []
|
10
|
-
date:
|
10
|
+
date: 2025-09-19 00:00:00.000000000 Z
|
11
11
|
dependencies:
|
12
12
|
- !ruby/object:Gem::Dependency
|
13
13
|
name: claide
|
@@ -457,7 +457,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
457
457
|
- !ruby/object:Gem::Version
|
458
458
|
version: '0'
|
459
459
|
requirements: []
|
460
|
-
rubygems_version: 3.6.
|
460
|
+
rubygems_version: 3.6.3
|
461
461
|
specification_version: 3
|
462
462
|
summary: easy work
|
463
463
|
test_files: []
|