Class: Fusuma::Config

Inherits:
Object
  • Object
show all
Includes:
Singleton
Defined in:
lib/fusuma/config.rb,
lib/fusuma/config/index.rb,
lib/fusuma/config/searcher.rb,
lib/fusuma/config/yaml_duplication_checker.rb

Overview

read keymap from yaml file

Defined Under Namespace

Modules: YAMLDuplicationChecker Classes: Index, InvalidFileError, NotFoundError, Searcher

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeConfig

: () -> void



41
42
43
44
45
# File 'lib/fusuma/config.rb', line 41

def initialize
  @searcher = Searcher.new
  @custom_path = nil
  @keymap = nil
end

Instance Attribute Details

#custom_pathObject

Returns the value of attribute custom_path.



38
39
40
# File 'lib/fusuma/config.rb', line 38

def custom_path
  @custom_path
end

#searcherObject (readonly)

Returns the value of attribute searcher.



38
39
40
# File 'lib/fusuma/config.rb', line 38

def searcher
  @searcher
end

Class Method Details

.custom_path=(new_path) ⇒ Object

: (String?) -> Fusuma::Config



33
34
35
# File 'lib/fusuma/config.rb', line 33

def custom_path=(new_path)
  instance.custom_path = new_path
end

.find_execute_key(index) ⇒ Object



28
29
30
# File 'lib/fusuma/config.rb', line 28

def find_execute_key(index)
  instance.find_execute_key(index)
end

.search(index) ⇒ Object

: (Fusuma::Config::Index) -> (String | Hash[untyped, untyped] | Integer | Float)?



24
25
26
# File 'lib/fusuma/config.rb', line 24

def search(index)
  instance.search(index)
end

Instance Method Details

#fetch_config_params(key, base) ⇒ Hash

: (Symbol?, Fusuma::Config::Index) -> (String | Hash[untyped, untyped] | Float | Integer | bool)?

Parameters:

Returns:



86
87
88
89
90
91
92
93
94
95
96
# File 'lib/fusuma/config.rb', line 86

def fetch_config_params(key, base)
  request_context = {plugin_defaults: base.keys.last.symbol.to_s}
  fallbacks = [:no_context, :plugin_default_context]
  Config::Searcher.find_context(request_context, fallbacks) do
    ret = Config.search(base)
    if ret&.key?(key)
      return ret
    end
  end
  {}
end

#find_execute_key(index) ⇒ Object

Returns Symbol.

Parameters:

Returns:

  • Symbol



128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
# File 'lib/fusuma/config.rb', line 128

def find_execute_key(index)
  @execute_keys ||= Plugin::Executors::Executor.plugins.map do |executor|
    executor.new.execute_keys
  end.flatten

  @cache_execute_keys ||= {} #: Hash[String, untyped]

  cache_key = [index.cache_key, Searcher.context].join

  return @cache_execute_keys[cache_key] if @cache_execute_keys.has_key?(cache_key)

  @cache_execute_keys[cache_key] =
    @execute_keys.find do |execute_key|
      new_index = Config::Index.new(index.keys | [execute_key])
      search(new_index)
    end
end

#keymapObject

: () -> Array?



54
55
56
57
# File 'lib/fusuma/config.rb', line 54

def keymap
  # FIXME: @keymap is not initialized when called from outside Fusuma::Runner like fusuma-senkey
  @keymap || reload.keymap
end

#reloadObject

: () -> Fusuma::Config



60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/fusuma/config.rb', line 60

def reload
  plugin_defaults = plugin_defaults_paths.map do |default_yml|
    {
      context: {plugin_defaults: default_yml.split("/").last.delete_suffix(".yml")},
      **validate(default_yml)[0]
    }
  end

  config_path = find_config_filepath
  @keymap = validate(config_path) | plugin_defaults
  MultiLogger.info "reload config: #{config_path}"

  # reset searcher cache
  @searcher = Searcher.new
  @cache_execute_keys = nil

  self
rescue InvalidFileError => e
  MultiLogger.error e.message
  exit 1
end

#search(index) ⇒ Object

: (Fusuma::Config::Index) -> (String | Hash[untyped, untyped] | Integer | Float)?

Parameters:



121
122
123
124
# File 'lib/fusuma/config.rb', line 121

def search(index)
  return nil if index.nil? || index.keys.empty?
  @searcher.search_with_cache(index, location: keymap)
end

#validate(path) ⇒ Hash

: (String) -> Array[Hash[Symbol, untyped]]

Returns:

  • (Hash)

    If check passes

Raises:



101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/fusuma/config.rb', line 101

def validate(path)
  duplicates = []
  YAMLDuplicationChecker.check(File.read(path), path) do |ignored, duplicate| # steep:ignore UnexpectedBlockGiven
    MultiLogger.error "#{path}: #{ignored.value} is duplicated"
    duplicates << duplicate.value
  end
  raise InvalidFileError, "Detect duplicate keys #{duplicates}" unless duplicates.empty?

  yamls = YAML.load_stream(File.read(path)).compact # steep:ignore NoMethod
  yamls.map do |yaml|
    raise InvalidFileError, "Invalid config.yml: #{path}" unless yaml.is_a? Hash

    yaml.deep_symbolize_keys
  end
rescue Psych::SyntaxError => e
  raise InvalidFileError, "Invalid syntax: #{path} #{e.message}"
end