Class: Pindo::Options::GlobalOptionsState

Inherits:
Object
  • Object
show all
Includes:
Singleton
Defined in:
lib/pindo/options/core/global_options_state.rb

Overview

全局参数状态管理器(单例,简化版)职责:

  1. 管理当前命令的参数状态

  2. 管理文件缓存的加载、保存和应用

Constant Summary collapse

OPTION_GROUPS =

所有已知的 OptionGroup 模块(用于查找参数显示名称)

[
  -> { Pindo::Options::BuildOptions },
  -> { Pindo::Options::JPSOptions },
  -> { Pindo::Options::UnityOptions },
  -> { Pindo::Options::GitOptions }
].freeze
PARAM_DISPLAY_ORDER =

参数显示顺序(优先级从高到低)

[
  # 1. 核心标识参数
  :bundleid, :bundle_id, :bundle_name,
  # 2. 构建配置
  :build_type, :scheme,
  # 3. JPS 相关
  :proj, :upload, :send, :desc,
  # 4. Unity 相关
  :skipconfig, :skiplib, :skipyoo,
  # 5. Git 相关
  :ver_inc, :tag_type, :tag_pre, :release_branch
].freeze

Instance Method Summary collapse

Constructor Details

#initializeGlobalOptionsState

Returns a new instance of GlobalOptionsState.



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/pindo/options/core/global_options_state.rb', line 22

def initialize
  # 运行时状态(内存)
  @current_command = nil        # 当前命令名称
  @current_options = nil        # 当前参数配置对象
  @current_directory = nil      # 当前项目目录
  @cache_enabled = false        # 是否启用缓存

  # 缓存状态(文件)
  @cache_data = {}              # 缓存数据:{ 项目目录 => { 命令 => 参数Hash } }
  @cache_loaded = false         # 是否已加载缓存文件

  # 调试
  @verbose = ENV['PINDO_VERBOSE'] == '1'

  ensure_cache_dir
end

Instance Method Details

#[](key) ⇒ Any

访问当前参数值

Parameters:

  • key (Symbol)

    参数键名

Returns:

  • (Any)

    参数值



226
227
228
# File 'lib/pindo/options/core/global_options_state.rb', line 226

def [](key)
  @current_options ? @current_options[key] : nil
end

#[]=(key, value) ⇒ Object

设置当前参数值

Parameters:

  • key (Symbol)

    参数键名

  • value (Any)

    参数值



233
234
235
# File 'lib/pindo/options/core/global_options_state.rb', line 233

def []=(key, value)
  @current_options[key] = value if @current_options
end

#cache_dirObject

缓存目录



245
246
247
# File 'lib/pindo/options/core/global_options_state.rb', line 245

def cache_dir
  File.join(Dir.home, '.pindo', 'cache')
end

#cache_file_pathObject

缓存文件路径



240
241
242
# File 'lib/pindo/options/core/global_options_state.rb', line 240

def cache_file_path
  File.join(cache_dir, 'options_cache.json')
end

#clearObject

清除当前命令状态



213
214
215
216
217
218
219
220
221
# File 'lib/pindo/options/core/global_options_state.rb', line 213

def clear
  # 如果启用了缓存,保存当前参数
  save_cache_to_file if @cache_enabled && @current_options

  @current_command = nil
  @current_options = nil
  @current_directory = nil
  @cache_enabled = false
end

#clear_current_cacheObject

清除当前命令的缓存



180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
# File 'lib/pindo/options/core/global_options_state.rb', line 180

def clear_current_cache
  return unless @current_directory && @current_command

  if @cache_data[@current_directory.to_sym]
    @cache_data[@current_directory.to_sym].delete(@current_command.to_sym)

    # 如果项目目录下没有其他命令缓存了,删除整个项目目录
    if @cache_data[@current_directory.to_sym].empty?
      @cache_data.delete(@current_directory.to_sym)
    end

    # 立即保存到文件
    save_cache_to_file_immediate
  end
end

#display_cached_params(cached_params) ⇒ Object

显示缓存的参数



118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
# File 'lib/pindo/options/core/global_options_state.rb', line 118

def display_cached_params(cached_params)
  # 根据命令名显示友好的描述
  group_desc = case @current_command
               when 'ios:autobuild'
                 'iOS 构建'
               when 'and:autobuild', 'android:autobuild'
                 'Android 构建'
               when 'web:autobuild'
                 'Web 构建'
               else
                 @current_command
               end

  puts "\n检测到之前的参数 (#{group_desc}):"
  puts "────────────────────────────────────────"

  # 按照预定义顺序排序参数
  sorted_keys = cached_params.keys.sort_by do |key|
    order_index = PARAM_DISPLAY_ORDER.index(key.to_sym)
    order_index || PARAM_DISPLAY_ORDER.size  # 未定义的参数排在最后
  end

  sorted_keys.each do |key|
    value = cached_params[key]
    # 跳过内部字段
    next if key.to_s.start_with?('__')
    next if value.nil?
    next unless is_cacheable?(key)  # 跳过不可缓存的参数

    # 格式化显示参数
    key_name = format_param_name(key)
    puts "  #{key_name}: #{value}"
  end

  puts "────────────────────────────────────────"
end

#ensure_cache_dirObject

确保缓存目录存在



250
251
252
# File 'lib/pindo/options/core/global_options_state.rb', line 250

def ensure_cache_dir
  FileUtils.mkdir_p(cache_dir) unless Dir.exist?(cache_dir)
end

#format_param_name(key) ⇒ String

格式化参数名称(从 OptionItem 定义中查找显示名称)

Parameters:

  • key (Symbol, String)

    参数键名

Returns:

  • (String)

    显示名称



158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
# File 'lib/pindo/options/core/global_options_state.rb', line 158

def format_param_name(key)
  key_sym = key.to_sym

  # 遍历所有已知的 OptionGroup,查找匹配的 OptionItem
  OPTION_GROUPS.each do |group_proc|
    begin
      group = group_proc.call
      if group.respond_to?(:all_options)
        option_item = group.all_options[key_sym]
        return option_item.display_name if option_item
      end
    rescue NameError
      # 模块尚未加载,跳过
      next
    end
  end

  # 如果没有找到匹配的 OptionItem,返回 key 本身
  key.to_s
end

#is_cacheable?(key) ⇒ Boolean

判断参数是否可缓存

Parameters:

  • key (Symbol, String)

    参数键名

Returns:

  • (Boolean)

    是否可缓存



300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
# File 'lib/pindo/options/core/global_options_state.rb', line 300

def is_cacheable?(key)
  key_sym = key.to_sym

  # 遍历所有已知的 OptionGroup,查找匹配的 OptionItem
  OPTION_GROUPS.each do |group_proc|
    begin
      group = group_proc.call
      if group.respond_to?(:all_options)
        option_item = group.all_options[key_sym]
        return option_item.cacheable? if option_item
      end
    rescue NameError
      # 模块尚未加载,跳过
      next
    end
  end

  # 如果没有找到匹配的 OptionItem,默认可缓存
  true
end

#load_cache_from_fileObject

从文件加载缓存



255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
# File 'lib/pindo/options/core/global_options_state.rb', line 255

def load_cache_from_file
  return if @cache_loaded

  if File.exist?(cache_file_path)
    begin
      content = File.read(cache_file_path)
      @cache_data = JSON.parse(content, symbolize_names: true)
      log_verbose("加载缓存文件: #{cache_file_path}")
      log_verbose("缓存内容: #{@cache_data.inspect}")
    rescue StandardError => e
      log_verbose("加载缓存文件失败: #{e.message}")
      @cache_data = {}
    end
  else
    log_verbose("缓存文件不存在: #{cache_file_path}")
  end

  @cache_loaded = true
end

#load_cached_valuesHash

加载缓存的参数值(带用户确认)环境变量 PINDO_OPTIONS_CACHE 控制缓存行为:

- 1/true/force: 

Returns:

  • (Hash)

    缓存的参数值



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/pindo/options/core/global_options_state.rb', line 56

def load_cached_values
  return {} unless @current_directory && @current_command

  # 检查缓存控制环境变量
  cache_mode = ENV['PINDO_OPTIONS_CACHE']&.downcase

  # 禁用缓存模式: 0, false, disable
  if %w[0 false disable].include?(cache_mode)
    log_verbose("PINDO_OPTIONS_CACHE=#{cache_mode},跳过缓存")
    return {}
  end

  cached_params = @cache_data.dig(@current_directory.to_sym, @current_command.to_sym)

  # 没有缓存数据,直接返回空Hash
  unless cached_params && cached_params.is_a?(Hash) && cached_params.any?
    log_verbose("没有找到缓存参数: #{@current_directory} / #{@current_command}")
    return {}
  end

  # 强制使用缓存模式: 1, true, force
  if %w[1 true force].include?(cache_mode)
    puts "\n自动使用缓存的参数 (PINDO_OPTIONS_CACHE=#{cache_mode})"
    log_verbose("加载缓存参数: #{cached_params.inspect}")
    return cached_params
  end

  # 默认模式:显示缓存的参数并询问用户
  display_cached_params(cached_params)

  # 询问用户是否使用缓存
  require 'highline/import'
  cli = HighLine.new
  confirm = cli.agree("\n是否使用以上缓存的参数? (y/n) ")

  if confirm
    puts "使用缓存的参数\n"
    log_verbose("加载缓存参数: #{cached_params.inspect}")
    cached_params
  else
    puts "清除缓存,使用新参数\n"
    # 清除当前命令的缓存
    clear_current_cache
    {}
  end
end

#log_verbose(message) ⇒ Object

调试日志 ====================


333
334
335
# File 'lib/pindo/options/core/global_options_state.rb', line 333

def log_verbose(message)
  puts "[GlobalOptionsState] #{message}" if @verbose
end

#prepare_cache(command_name, directory) ⇒ Object

准备缓存(在创建 OptionConfiguration 之前调用)

Parameters:

  • command_name (String)

    命令名称

  • directory (String)

    项目目录



44
45
46
47
48
# File 'lib/pindo/options/core/global_options_state.rb', line 44

def prepare_cache(command_name, directory)
  @current_command = command_name
  @current_directory = directory
  load_cache_from_file
end

#save_cache_to_fileObject

保存当前参数到缓存文件



276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
# File 'lib/pindo/options/core/global_options_state.rb', line 276

def save_cache_to_file
  return unless @current_directory && @current_command && @current_options

  # 确保缓存数据结构存在
  @cache_data[@current_directory.to_sym] ||= {}

  # 提取当前参数值(排除 nil 值和不可缓存的参数)
  current_params = {}
  @current_options.instance_variable_get(:@values).each do |key, value|
    next if value.nil?
    next unless is_cacheable?(key)  # 过滤不可缓存的参数
    current_params[key] = value
  end

  # 保存到缓存
  @cache_data[@current_directory.to_sym][@current_command.to_sym] = current_params

  # 写入文件
  save_cache_to_file_immediate
end

#save_cache_to_file_immediateObject

立即保存缓存数据到文件(内部方法)



322
323
324
325
326
327
328
329
# File 'lib/pindo/options/core/global_options_state.rb', line 322

def save_cache_to_file_immediate
  begin
    File.write(cache_file_path, JSON.pretty_generate(@cache_data))
    log_verbose("保存缓存文件: #{cache_file_path}")
  rescue StandardError => e
    log_verbose("保存缓存文件失败: #{e.message}")
  end
end

#set_command(command_name, options, directory: nil, enable_cache: false) ⇒ Object

设置当前命令上下文

Parameters:

  • command_name (String)

    命令名称(如 “ios:autobuild”)

  • options (OptionConfiguration)

    参数配置对象

  • directory (String) (defaults to: nil)

    项目目录

  • enable_cache (Boolean) (defaults to: false)

    是否启用缓存



201
202
203
204
205
206
207
208
209
210
# File 'lib/pindo/options/core/global_options_state.rb', line 201

def set_command(command_name, options, directory: nil, enable_cache: false)
  @current_command = command_name
  @current_options = options
  @current_directory = directory || Dir.pwd
  @cache_enabled = enable_cache

  log_verbose("设置命令: #{command_name}")
  log_verbose("项目目录: #{@current_directory}")
  log_verbose("缓存启用: #{@cache_enabled}")
end