Class: Rufio::ScriptPathManager

Inherits:
Object
  • Object
show all
Defined in:
lib/rufio/script_path_manager.rb

Overview

スクリプトパスを管理するクラス設定ファイルからパスを読み込み、スクリプト名で解決する

Constant Summary collapse

SUPPORTED_EXTENSIONS =

サポートするスクリプト拡張子

%w[.sh .rb .py .pl .js .ts .ps1].freeze
MAX_HISTORY_SIZE =

履歴の最大サイズ

100

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(config_path = nil) ⇒ ScriptPathManager

Returns a new instance of ScriptPathManager.

Parameters:

  • config_path (String) (defaults to: nil)

    設定ファイルのパス(script_paths.yml または config.yml)



19
20
21
22
23
24
25
26
# File 'lib/rufio/script_path_manager.rb', line 19

def initialize(config_path = nil)
  @config_path = config_path || Config::SCRIPT_PATHS_YML
  @paths = load_paths_from_config
  @cache = {}
  @scripts_cache = nil
  @execution_history = []
  @execution_count = Hash.new(0)
end

Instance Attribute Details

#pathsObject (readonly)

Returns the value of attribute paths.



10
11
12
# File 'lib/rufio/script_path_manager.rb', line 10

def paths
  @paths
end

Instance Method Details

#add_path(path) ⇒ Boolean

パスを追加

Parameters:

  • path (String)

    追加するディレクトリパス

Returns:

  • (Boolean)

    追加成功した場合true、重複の場合false



99
100
101
102
103
104
105
106
107
# File 'lib/rufio/script_path_manager.rb', line 99

def add_path(path)
  expanded_path = File.expand_path(path)
  return false if @paths.include?(expanded_path)

  @paths << expanded_path
  save_config
  invalidate_cache
  true
end

#all_scriptsArray<String>

全スクリプト一覧を取得(タブ補完用)

Returns:

  • (Array<String>)

    スクリプト名(拡張子なし)の配列



71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/rufio/script_path_manager.rb', line 71

def all_scripts
  scripts = []
  seen = Set.new

  @paths.each do |path|
    next unless Dir.exist?(path)

    Dir.glob(File.join(path, '**', '*')).each do |file|
      next unless File.file?(file)

      basename = File.basename(file)
      next if basename.start_with?('.')
      next unless executable_script?(file)

      name = File.basename(file, '.*')
      next if seen.include?(name)

      seen.add(name)
      scripts << name
    end
  end

  scripts.sort
end

#complete(prefix) ⇒ Object

スクリプト名を補完



128
129
130
131
132
133
# File 'lib/rufio/script_path_manager.rb', line 128

def complete(prefix)
  scripts = all_scripts
  return scripts if prefix.empty?

  scripts.select { |name| name.downcase.start_with?(prefix.downcase) }
end

#executable?(path) ⇒ Boolean

ファイルが実行可能かどうかをチェック

Returns:

  • (Boolean)


192
193
194
195
196
# File 'lib/rufio/script_path_manager.rb', line 192

def executable?(path)
  return false unless File.exist?(path)

  File.executable?(path)
end

#execution_historyObject

実行履歴を取得



166
167
168
# File 'lib/rufio/script_path_manager.rb', line 166

def execution_history
  @execution_history.dup
end

#find_all_matches(command_name) ⇒ Object

すべてのマッチを取得(複数マッチ対応)



123
124
125
# File 'lib/rufio/script_path_manager.rb', line 123

def find_all_matches(command_name)
  find_scripts_all_paths(command_name)
end

#fix_permissions(path) ⇒ Object

ファイルに実行権限を付与



199
200
201
202
203
204
205
206
207
208
# File 'lib/rufio/script_path_manager.rb', line 199

def fix_permissions(path)
  return false unless File.exist?(path)

  current_mode = File.stat(path).mode
  new_mode = current_mode | 0111
  File.chmod(new_mode, path)
  true
rescue StandardError
  false
end

#fuzzy_match(query) ⇒ Object

fuzzy matchingで候補を取得



136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
# File 'lib/rufio/script_path_manager.rb', line 136

def fuzzy_match(query)
  return all_scripts if query.empty?

  scripts = all_scripts
  query_chars = query.downcase.chars

  scored = scripts.map do |name|
    score = fuzzy_score(name.downcase, query_chars)
    [name, score]
  end

  scored.select { |_, score| score > 0 }
        .sort_by { |_, score| -score }
        .map { |name, _| name }
end

#invalidate_cacheObject

キャッシュを無効化



153
154
155
156
# File 'lib/rufio/script_path_manager.rb', line 153

def invalidate_cache
  @cache.clear
  @scripts_cache = nil
end

#record_execution(script_name) ⇒ Object

実行を記録



159
160
161
162
163
# File 'lib/rufio/script_path_manager.rb', line 159

def record_execution(script_name)
  @execution_history.unshift(script_name)
  @execution_history = @execution_history.take(MAX_HISTORY_SIZE)
  @execution_count[script_name] += 1
end

#remove_path(path) ⇒ Boolean

パスを削除

Parameters:

  • path (String)

    削除するディレクトリパス

Returns:

  • (Boolean)

    削除成功した場合true



112
113
114
115
116
117
118
119
120
# File 'lib/rufio/script_path_manager.rb', line 112

def remove_path(path)
  expanded_path = File.expand_path(path)
  result = @paths.delete(expanded_path)
  if result
    save_config
    invalidate_cache
  end
  !!result
end

#resolve(command_name) ⇒ String?

スクリプト名で解決

Parameters:

  • command_name (String)

    スクリプト名(拡張子あり/なし)

Returns:

  • (String, nil)

    スクリプトのフルパス、見つからない場合はnil



54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/rufio/script_path_manager.rb', line 54

def resolve(command_name)
  return @cache[command_name] if @cache.key?(command_name)

  scripts = find_scripts(command_name)

  case scripts.size
  when 0
    nil
  when 1
    @cache[command_name] = scripts.first
  else
    @cache[command_name] = scripts.first
  end
end

#scripts_by_frequencyObject

実行頻度順にスクリプトを取得



171
172
173
174
# File 'lib/rufio/script_path_manager.rb', line 171

def scripts_by_frequency
  scripts = all_scripts
  scripts.sort_by { |name| -@execution_count[name] }
end

#suggest(query) ⇒ Object

類似スクリプトの候補を取得



177
178
179
180
181
182
183
184
185
186
187
188
189
# File 'lib/rufio/script_path_manager.rb', line 177

def suggest(query)
  scripts = all_scripts
  return [] if scripts.empty?

  scored = scripts.map do |name|
    distance = levenshtein_distance(query.downcase, name.downcase)
    [name, distance]
  end

  scored.select { |_, dist| dist <= 3 }
        .sort_by { |_, dist| dist }
        .map { |name, _| name }
end