rufio 0.61.0 → 0.62.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.
data/lib/rufio/config.rb CHANGED
@@ -1,11 +1,24 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'yaml'
4
+ require 'fileutils'
5
+
3
6
  module Rufio
4
7
  class Config
5
8
  # Default language settings
6
9
  DEFAULT_LANGUAGE = 'en'
7
10
  AVAILABLE_LANGUAGES = %w[en ja].freeze
8
11
 
12
+ # 設定ディレクトリとファイルパス
13
+ CONFIG_DIR = File.expand_path('~/.config/rufio').freeze
14
+ CONFIG_RB_PATH = File.join(CONFIG_DIR, 'config.rb').freeze
15
+ SCRIPT_PATHS_YML = File.join(CONFIG_DIR, 'script_paths.yml').freeze
16
+ BOOKMARKS_YML = File.join(CONFIG_DIR, 'bookmarks.yml').freeze
17
+
18
+ # 後方互換性のためのパス(非推奨)
19
+ YAML_CONFIG_PATH = File.join(CONFIG_DIR, 'config.yml').freeze
20
+ LOCAL_YAML_PATH = './rufio.yml'
21
+
9
22
  # Multi-language message definitions
10
23
  MESSAGES = {
11
24
  'en' => {
@@ -179,8 +192,209 @@ module Rufio
179
192
  @current_language = nil
180
193
  end
181
194
 
195
+ # YAML設定を取得(キャッシュあり)
196
+ # @return [Hash] YAML設定
197
+ def yaml_config
198
+ @yaml_config ||= load_yaml_config(YAML_CONFIG_PATH)
199
+ end
200
+
201
+ # YAML設定をリロード
202
+ def reload_yaml_config!
203
+ @yaml_config = nil
204
+ end
205
+
206
+ # 全設定をリセット
207
+ def reset_config!
208
+ @yaml_config = nil
209
+ @script_paths = nil
210
+ @bookmarks = nil
211
+ end
212
+
213
+ # ========================================
214
+ # script_paths.yml の操作
215
+ # ========================================
216
+
217
+ # スクリプトパスを読み込む
218
+ # @param path [String] YAMLファイルのパス
219
+ # @return [Array<String>] 展開済みのパス配列
220
+ def load_script_paths(path = SCRIPT_PATHS_YML)
221
+ return [] unless File.exist?(path)
222
+
223
+ yaml = YAML.safe_load(File.read(path))
224
+ return [] unless yaml.is_a?(Array)
225
+
226
+ yaml.map { |p| File.expand_path(p) }
227
+ rescue StandardError => e
228
+ warn "Failed to load script paths: #{e.message}"
229
+ []
230
+ end
231
+
232
+ # スクリプトパスを保存
233
+ # @param path [String] YAMLファイルのパス
234
+ # @param paths [Array<String>] パス配列
235
+ def save_script_paths(path, paths)
236
+ ensure_config_directory(path)
237
+ File.write(path, YAML.dump(paths))
238
+ end
239
+
240
+ # スクリプトパスを追加
241
+ # @param path [String] YAMLファイルのパス
242
+ # @param new_path [String] 追加するパス
243
+ def add_script_path(path, new_path)
244
+ paths = load_script_paths(path)
245
+ expanded = File.expand_path(new_path)
246
+ return if paths.include?(expanded)
247
+
248
+ paths << expanded
249
+ save_script_paths(path, paths)
250
+ end
251
+
252
+ # スクリプトパスを削除
253
+ # @param path [String] YAMLファイルのパス
254
+ # @param remove_path [String] 削除するパス
255
+ def remove_script_path(path, remove_path)
256
+ paths = load_script_paths(path)
257
+ expanded = File.expand_path(remove_path)
258
+ paths.delete(expanded)
259
+ save_script_paths(path, paths)
260
+ end
261
+
262
+ # ========================================
263
+ # bookmarks.yml の操作
264
+ # ========================================
265
+
266
+ # ブックマークを読み込む
267
+ # @param path [String] YAMLファイルのパス
268
+ # @return [Array<Hash>] ブックマーク配列
269
+ def load_bookmarks_from_yml(path = BOOKMARKS_YML)
270
+ return [] unless File.exist?(path)
271
+
272
+ yaml = YAML.safe_load(File.read(path), symbolize_names: true)
273
+ return [] unless yaml.is_a?(Array)
274
+
275
+ yaml.select { |b| b.is_a?(Hash) && b[:path] && b[:name] }
276
+ rescue StandardError => e
277
+ warn "Failed to load bookmarks: #{e.message}"
278
+ []
279
+ end
280
+
281
+ # ブックマークを保存
282
+ # @param path [String] YAMLファイルのパス
283
+ # @param bookmarks [Array<Hash>] ブックマーク配列
284
+ def save_bookmarks_to_yml(path, bookmarks)
285
+ ensure_config_directory(path)
286
+ data = bookmarks.map { |b| { 'path' => b[:path], 'name' => b[:name] } }
287
+ File.write(path, YAML.dump(data))
288
+ end
289
+
290
+ # ブックマークを追加
291
+ # @param path [String] YAMLファイルのパス
292
+ # @param bookmark_path [String] ブックマークするパス
293
+ # @param name [String] ブックマーク名
294
+ def add_bookmark(path, bookmark_path, name)
295
+ bookmarks = load_bookmarks_from_yml(path)
296
+ bookmarks << { path: bookmark_path, name: name }
297
+ save_bookmarks_to_yml(path, bookmarks)
298
+ end
299
+
300
+ # ブックマークを削除
301
+ # @param path [String] YAMLファイルのパス
302
+ # @param name [String] 削除するブックマーク名
303
+ def remove_bookmark(path, name)
304
+ bookmarks = load_bookmarks_from_yml(path)
305
+ bookmarks.reject! { |b| b[:name] == name }
306
+ save_bookmarks_to_yml(path, bookmarks)
307
+ end
308
+
309
+ # ========================================
310
+ # config.rb (DSL) の操作
311
+ # ========================================
312
+
313
+ # config.rb を読み込む
314
+ # @param path [String] config.rb のパス
315
+ def load_config_rb(path = CONFIG_RB_PATH)
316
+ return unless File.exist?(path)
317
+
318
+ load path
319
+ rescue StandardError => e
320
+ warn "Failed to load config.rb: #{e.message}"
321
+ end
322
+
323
+ # ========================================
324
+ # マイグレーション
325
+ # ========================================
326
+
327
+ # 古い config.yml から新形式にマイグレーション
328
+ # @param old_config_yml [String] 古い config.yml のパス
329
+ # @param script_paths_yml [String] 新しい script_paths.yml のパス
330
+ # @param bookmarks_yml [String] 新しい bookmarks.yml のパス
331
+ def migrate_from_config_yml(old_config_yml, script_paths_yml, bookmarks_yml)
332
+ return unless File.exist?(old_config_yml)
333
+
334
+ old_config = load_yaml_config(old_config_yml)
335
+
336
+ # script_paths のマイグレーション
337
+ if old_config[:script_paths].is_a?(Array) && !old_config[:script_paths].empty?
338
+ save_script_paths(script_paths_yml, old_config[:script_paths])
339
+ end
340
+
341
+ # bookmarks のマイグレーション
342
+ if old_config[:bookmarks].is_a?(Array) && !old_config[:bookmarks].empty?
343
+ save_bookmarks_to_yml(bookmarks_yml, old_config[:bookmarks])
344
+ end
345
+ end
346
+
347
+ # YAML設定ファイルを読み込む
348
+ # @param path [String] 設定ファイルのパス
349
+ # @return [Hash] 設定内容(シンボルキー)
350
+ def load_yaml_config(path)
351
+ return {} unless File.exist?(path)
352
+
353
+ yaml = YAML.safe_load(File.read(path), symbolize_names: true)
354
+ yaml || {}
355
+ rescue StandardError => e
356
+ warn "Failed to load YAML config: #{e.message}"
357
+ {}
358
+ end
359
+
360
+ # YAML設定ファイルにセクションを保存
361
+ # @param path [String] 設定ファイルのパス
362
+ # @param key [Symbol, String] 保存するキー
363
+ # @param value [Object] 保存する値
364
+ def save_yaml_config(path, key, value)
365
+ ensure_config_directory(path)
366
+
367
+ existing = if File.exist?(path)
368
+ YAML.safe_load(File.read(path), symbolize_names: true) || {}
369
+ else
370
+ {}
371
+ end
372
+
373
+ existing[key.to_sym] = value
374
+ File.write(path, YAML.dump(stringify_keys(existing)))
375
+ reload_yaml_config! if path == YAML_CONFIG_PATH
376
+ end
377
+
182
378
  private
183
379
 
380
+ def ensure_config_directory(path)
381
+ dir = File.dirname(path)
382
+ FileUtils.mkdir_p(dir) unless Dir.exist?(dir)
383
+ end
384
+
385
+ def stringify_keys(hash)
386
+ hash.transform_keys(&:to_s).transform_values do |value|
387
+ case value
388
+ when Hash
389
+ stringify_keys(value)
390
+ when Array
391
+ value.map { |v| v.is_a?(Hash) ? stringify_keys(v) : v }
392
+ else
393
+ value
394
+ end
395
+ end
396
+ end
397
+
184
398
  def detect_language
185
399
  # Only BENIYA_LANG environment variable takes precedence
186
400
  # This ensures English is default unless explicitly requested
@@ -1,14 +1,19 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'yaml'
4
+ require 'json'
4
5
  require_relative 'config'
5
- require_relative 'bookmark_storage'
6
6
 
7
7
  module Rufio
8
8
  class ConfigLoader
9
- CONFIG_PATH = File.expand_path('~/.config/rufio/config.rb').freeze
10
- YAML_CONFIG_PATH = File.expand_path('~/.config/rufio/config.yml').freeze
11
- JSON_BOOKMARKS_PATH = File.expand_path('~/.config/rufio/bookmarks.json').freeze
9
+ # 新しいパス定数(Configから取得)
10
+ CONFIG_PATH = Config::CONFIG_RB_PATH
11
+ SCRIPT_PATHS_YML = Config::SCRIPT_PATHS_YML
12
+ BOOKMARKS_YML = Config::BOOKMARKS_YML
13
+
14
+ # 後方互換性のためのパス(非推奨)
15
+ YAML_CONFIG_PATH = Config::YAML_CONFIG_PATH
16
+ LOCAL_YAML_PATH = Config::LOCAL_YAML_PATH
12
17
 
13
18
  class << self
14
19
  def load_config
@@ -21,6 +26,7 @@ module Rufio
21
26
 
22
27
  def reload_config!
23
28
  @config = nil
29
+ @script_paths = nil
24
30
  load_config
25
31
  end
26
32
 
@@ -42,7 +48,6 @@ module Rufio
42
48
 
43
49
  def set_language(lang)
44
50
  Config.current_language = lang
45
- # Update config if it's user-defined
46
51
  if @config
47
52
  @config[:language] = lang
48
53
  end
@@ -64,12 +69,10 @@ module Rufio
64
69
  load_config[:command_history_size] || 1000
65
70
  end
66
71
 
67
- # スクリプトパスの配列を取得
72
+ # スクリプトパスの配列を取得(ローカル > ユーザー設定の優先順位でマージ)
68
73
  # @return [Array<String>] 展開済みのスクリプトパス
69
74
  def script_paths
70
- yaml_config = load_yaml_config
71
- paths = yaml_config[:script_paths] || default_script_paths
72
- expand_script_paths(paths)
75
+ @script_paths ||= load_merged_script_paths
73
76
  end
74
77
 
75
78
  # デフォルトのスクリプトパス
@@ -85,58 +88,159 @@ module Rufio
85
88
  paths.map { |p| File.expand_path(p) }
86
89
  end
87
90
 
88
- # YAML設定ファイルを読み込む
91
+ # スクリプトパスを追加
92
+ # @param path [String] 追加するパス
93
+ # @return [Boolean] 追加成功したか
94
+ def add_script_path(path)
95
+ expanded = File.expand_path(path)
96
+ current = script_paths
97
+ return false if current.include?(expanded)
98
+
99
+ save_script_paths_to_yaml(current + [expanded])
100
+ @script_paths = nil
101
+ true
102
+ end
103
+
104
+ # スクリプトパスを削除
105
+ # @param path [String] 削除するパス
106
+ # @return [Boolean] 削除成功したか
107
+ def remove_script_path(path)
108
+ expanded = File.expand_path(path)
109
+ current = script_paths
110
+ return false unless current.include?(expanded)
111
+
112
+ save_script_paths_to_yaml(current - [expanded])
113
+ @script_paths = nil
114
+ true
115
+ end
116
+
117
+ # YAML設定ファイルを読み込む(Config経由)
89
118
  # @param path [String, nil] 設定ファイルのパス(nilの場合はデフォルト)
90
119
  # @return [Hash] 設定内容
91
120
  def load_yaml_config(path = nil)
92
121
  config_path = path || YAML_CONFIG_PATH
93
- return {} unless File.exist?(config_path)
122
+ Config.load_yaml_config(config_path)
123
+ end
124
+
125
+ # ブックマークを読み込む(新形式: bookmarks.yml)
126
+ # @return [Array<Hash>] ブックマークの配列
127
+ def load_bookmarks
128
+ # 新形式を優先
129
+ bookmarks = Config.load_bookmarks_from_yml(BOOKMARKS_YML)
130
+ return bookmarks unless bookmarks.empty?
94
131
 
95
- yaml = YAML.safe_load(File.read(config_path), symbolize_names: true)
96
- yaml || {}
132
+ # 後方互換: 古いconfig.ymlから読み込み
133
+ yaml_config = load_yaml_config
134
+ filter_valid_bookmarks(yaml_config[:bookmarks] || [])
135
+ end
136
+
137
+ # ブックマークを保存(新形式: bookmarks.yml)
138
+ # @param bookmarks [Array<Hash>] ブックマークの配列
139
+ # @return [Boolean] 保存成功したか
140
+ def save_bookmarks(bookmarks)
141
+ Config.save_bookmarks_to_yml(BOOKMARKS_YML, bookmarks)
142
+ true
97
143
  rescue StandardError => e
98
- warn "Failed to load YAML config: #{e.message}"
99
- {}
144
+ warn "Failed to save bookmarks: #{e.message}"
145
+ false
100
146
  end
101
147
 
102
- # ブックマーク用のYAMLストレージを取得
103
- # @return [YamlBookmarkStorage] ストレージインスタンス
148
+ # ブックマークストレージを取得
149
+ # @return [YamlBookmarkStorage] ブックマークストレージ
104
150
  def bookmark_storage
105
- YamlBookmarkStorage.new(YAML_CONFIG_PATH)
151
+ @bookmark_storage ||= YamlBookmarkStorage.new(BOOKMARKS_YML)
106
152
  end
107
153
 
108
- # 必要に応じてブックマークをJSONからYAMLに移行
109
- # @param json_path [String] JSONファイルパス
110
- # @param yaml_path [String] YAMLファイルパス
111
- # @return [Boolean] 移行が実行されたかどうか
112
- def migrate_bookmarks_if_needed(json_path = JSON_BOOKMARKS_PATH, yaml_path = YAML_CONFIG_PATH)
113
- BookmarkMigrator.migrate(json_path, yaml_path)
154
+ # 古いconfig.ymlからのマイグレーション
155
+ def migrate_bookmarks_if_needed
156
+ # 新形式が存在する場合はスキップ
157
+ return if File.exist?(BOOKMARKS_YML)
158
+ return unless File.exist?(YAML_CONFIG_PATH)
159
+
160
+ Config.migrate_from_config_yml(YAML_CONFIG_PATH, SCRIPT_PATHS_YML, BOOKMARKS_YML)
114
161
  end
115
162
 
116
163
  private
117
164
 
165
+ # マージされたスクリプトパスを読み込む
166
+ # @return [Array<String>] マージされたスクリプトパス
167
+ def load_merged_script_paths
168
+ paths = []
169
+ seen = Set.new
170
+
171
+ # ローカル設定(優先)
172
+ if File.exist?(LOCAL_YAML_PATH)
173
+ local_config = load_yaml_config(LOCAL_YAML_PATH)
174
+ local_paths = local_config[:script_paths] || []
175
+ add_unique_paths(paths, seen, expand_script_paths(local_paths))
176
+ end
177
+
178
+ # 新形式: script_paths.yml から読み込み
179
+ script_paths_from_yml = Config.load_script_paths(SCRIPT_PATHS_YML)
180
+ add_unique_paths(paths, seen, script_paths_from_yml)
181
+
182
+ # 後方互換: 古いconfig.ymlから読み込み
183
+ if paths.empty?
184
+ user_config = load_yaml_config
185
+ user_paths = user_config[:script_paths] || []
186
+ add_unique_paths(paths, seen, expand_script_paths(user_paths))
187
+ end
188
+
189
+ # デフォルトパス(何も設定されていない場合)
190
+ if paths.empty?
191
+ add_unique_paths(paths, seen, default_script_paths)
192
+ end
193
+
194
+ paths
195
+ end
196
+
197
+ # ユニークなパスを追加
198
+ def add_unique_paths(paths, seen, new_paths)
199
+ new_paths.each do |path|
200
+ expanded = File.expand_path(path)
201
+ next if seen.include?(expanded)
202
+
203
+ seen.add(expanded)
204
+ paths << expanded
205
+ end
206
+ end
207
+
208
+ # スクリプトパスをYAMLに保存(新形式: script_paths.yml)
209
+ def save_script_paths_to_yaml(paths)
210
+ Config.save_script_paths(SCRIPT_PATHS_YML, paths)
211
+ end
212
+
213
+ # YAMLファイルにセクションを保存(Config経由)
214
+ def save_to_yaml(key, value)
215
+ Config.save_yaml_config(YAML_CONFIG_PATH, key, value)
216
+ end
217
+
218
+ def filter_valid_bookmarks(bookmarks)
219
+ return [] unless bookmarks.is_a?(Array)
220
+
221
+ bookmarks.select do |b|
222
+ b.is_a?(Hash) && b[:path] && b[:name]
223
+ end
224
+ end
225
+
118
226
  def load_config_file
119
- # 設定ファイルを実行してグローバル定数を定義
120
227
  load CONFIG_PATH
121
228
  config = {
122
- applications: Object.const_get(:APPLICATIONS),
123
- colors: Object.const_get(:COLORS),
124
- keybinds: Object.const_get(:KEYBINDS)
229
+ applications: safe_const_get(:APPLICATIONS, default_config[:applications]),
230
+ colors: safe_const_get(:COLORS, default_config[:colors]),
231
+ keybinds: safe_const_get(:KEYBINDS, default_config[:keybinds])
125
232
  }
126
233
 
127
- # Load language setting if defined
128
234
  if Object.const_defined?(:LANGUAGE)
129
235
  language = Object.const_get(:LANGUAGE)
130
236
  config[:language] = language
131
237
  Config.current_language = language if Config.available_languages.include?(language.to_s)
132
238
  end
133
239
 
134
- # Load scripts directory if defined
135
240
  if Object.const_defined?(:SCRIPTS_DIR)
136
241
  config[:scripts_dir] = Object.const_get(:SCRIPTS_DIR)
137
242
  end
138
243
 
139
- # Load command history size if defined
140
244
  if Object.const_defined?(:COMMAND_HISTORY_SIZE)
141
245
  config[:command_history_size] = Object.const_get(:COMMAND_HISTORY_SIZE)
142
246
  end
@@ -148,6 +252,10 @@ module Rufio
148
252
  default_config
149
253
  end
150
254
 
255
+ def safe_const_get(name, default)
256
+ Object.const_defined?(name) ? Object.const_get(name) : default
257
+ end
258
+
151
259
  def default_config
152
260
  {
153
261
  applications: {
@@ -159,11 +267,11 @@ module Rufio
159
267
  :default => 'open'
160
268
  },
161
269
  colors: {
162
- directory: { hsl: [220, 80, 60] }, # Blue
163
- file: { hsl: [0, 0, 90] }, # Light gray
164
- executable: { hsl: [120, 70, 50] }, # Green
165
- selected: { hsl: [50, 90, 70] }, # Yellow
166
- preview: { hsl: [180, 60, 65] } # Cyan
270
+ directory: { hsl: [220, 80, 60] },
271
+ file: { hsl: [0, 0, 90] },
272
+ executable: { hsl: [120, 70, 50] },
273
+ selected: { hsl: [50, 90, 70] },
274
+ preview: { hsl: [180, 60, 65] }
167
275
  },
168
276
  keybinds: {
169
277
  quit: %w[q ESC],
@@ -182,4 +290,3 @@ module Rufio
182
290
  end
183
291
  end
184
292
  end
185
-
@@ -51,7 +51,7 @@ module Rufio
51
51
  # Log viewer mode
52
52
  @in_log_viewer_mode = false
53
53
  @pre_log_viewer_directory = nil
54
- @log_dir = File.join(Dir.home, '.config', 'rufio', 'log')
54
+ @log_dir = File.join(Dir.home, '.config', 'rufio', 'logs')
55
55
 
56
56
  # Preview pane focus and scroll
57
57
  @preview_focused = false
@@ -62,9 +62,8 @@ module Rufio
62
62
  @job_manager = JobManager.new(notification_manager: @notification_manager)
63
63
  @job_mode = JobMode.new(job_manager: @job_manager)
64
64
 
65
- # Script path manager
66
- config_file = File.expand_path('~/.config/rufio/config.yml')
67
- @script_path_manager = File.exist?(config_file) ? ScriptPathManager.new(config_file) : nil
65
+ # Script path manager (新形式: script_paths.yml)
66
+ @script_path_manager = ScriptPathManager.new(Config::SCRIPT_PATHS_YML)
68
67
  end
69
68
 
70
69
  def set_directory_listing(directory_listing)
@@ -1446,8 +1445,16 @@ module Rufio
1446
1445
  when '3'
1447
1446
  show_script_paths_manager
1448
1447
  when '4'
1449
- # ブックマーク一覧表示(既存機能)
1448
+ # ブックマーク一覧表示
1449
+ selected_bookmark = @bookmark_manager.list_interactive
1450
1450
  @terminal_ui&.refresh_display
1451
+ if selected_bookmark
1452
+ if @bookmark_manager.path_exists?(selected_bookmark)
1453
+ navigate_to_directory(selected_bookmark[:path])
1454
+ else
1455
+ show_error_and_wait('bookmark.path_not_exist', selected_bookmark[:path])
1456
+ end
1457
+ end
1451
1458
  else
1452
1459
  @terminal_ui&.refresh_display
1453
1460
  end
@@ -1460,10 +1467,8 @@ module Rufio
1460
1467
  current_path = @directory_listing&.current_path || Dir.pwd
1461
1468
 
1462
1469
  unless @script_path_manager
1463
- # ScriptPathManagerがない場合は作成
1464
- config_file = File.expand_path('~/.config/rufio/config.yml')
1465
- FileUtils.mkdir_p(File.dirname(config_file))
1466
- @script_path_manager = ScriptPathManager.new(config_file)
1470
+ # ScriptPathManagerがない場合は作成(新形式: script_paths.yml)
1471
+ @script_path_manager = ScriptPathManager.new(Config::SCRIPT_PATHS_YML)
1467
1472
  end
1468
1473
 
1469
1474
  if @script_path_manager.paths.include?(current_path)
@@ -1,15 +1,16 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'yaml'
4
+ require_relative 'config'
4
5
 
5
6
  module Rufio
6
7
  # 複数の設定ファイルからscript_pathsをロード・マージするクラス
7
8
  # 優先順位: ローカル > ユーザー > システム
8
9
  class ScriptConfigLoader
9
- # デフォルトの設定ファイルパス
10
- DEFAULT_LOCAL_PATH = './rufio.yml'
11
- DEFAULT_USER_PATH = File.expand_path('~/.config/rufio/config.yml')
12
- DEFAULT_SYSTEM_PATH = '/etc/rufio/config.yml'
10
+ # デフォルトの設定ファイルパス(新形式: script_paths.yml)
11
+ DEFAULT_LOCAL_PATH = Config::LOCAL_YAML_PATH
12
+ DEFAULT_USER_PATH = Config::SCRIPT_PATHS_YML
13
+ DEFAULT_SYSTEM_PATH = '/etc/rufio/script_paths.yml'
13
14
 
14
15
  # @param local_path [String, nil] ローカル設定ファイルのパス
15
16
  # @param user_path [String, nil] ユーザー設定ファイルのパス
@@ -63,25 +64,39 @@ module Rufio
63
64
 
64
65
  private
65
66
 
66
- # 設定ファイルからscript_pathsを読み込む
67
+ # 設定ファイルからscript_pathsを読み込む(新形式対応)
67
68
  # @param path [String] 設定ファイルのパス
68
69
  # @return [Array<String>] パスの配列
69
70
  def load_paths_from_file(path)
71
+ # 新形式: script_paths.yml(リスト形式)
72
+ if path.end_with?('script_paths.yml')
73
+ return Config.load_script_paths(path)
74
+ end
75
+
76
+ # 後方互換: 古いconfig.yml形式(ハッシュ形式)
70
77
  config = load_config(path)
71
78
  config['script_paths'] || []
72
79
  end
73
80
 
74
- # 設定ファイルを読み込む
81
+ # 設定ファイルを読み込む(後方互換用)
75
82
  # @param path [String] 設定ファイルのパス
76
83
  # @return [Hash] 設定内容
77
84
  def load_config(path)
78
- return {} unless File.exist?(path)
85
+ config = Config.load_yaml_config(path)
86
+ stringify_keys(config)
87
+ end
79
88
 
80
- yaml = YAML.safe_load(File.read(path), symbolize_names: false)
81
- yaml || {}
82
- rescue StandardError => e
83
- warn "Warning: Failed to load config #{path}: #{e.message}"
84
- {}
89
+ def stringify_keys(hash)
90
+ hash.transform_keys(&:to_s).transform_values do |value|
91
+ case value
92
+ when Hash
93
+ stringify_keys(value)
94
+ when Array
95
+ value.map { |v| v.is_a?(Hash) ? stringify_keys(v) : v }
96
+ else
97
+ value
98
+ end
99
+ end
85
100
  end
86
101
 
87
102
  # ハッシュを深くマージ