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