Class: Aspera::Cli::PresetManager
- Inherits:
-
Object
- Object
- Aspera::Cli::PresetManager
- Defined in:
- lib/aspera/cli/preset_manager.rb
Overview
Manages the YAML config file and all preset-related operations. Extracted from Plugins::Config so it can be referenced independently via Context#presets without coupling to the plugin machinery.
Defined Under Namespace
Modules: Key
Constant Summary collapse
- GLOBAL_DEFAULT_KEYWORD =
'GLOBAL'- CONF_GLOBAL_SYM =
:config
Instance Attribute Summary collapse
-
#config_file ⇒ Object
readonly
Returns the value of attribute config_file.
-
#config_presets ⇒ Object
readonly
Returns the value of attribute config_presets.
-
#use_plugin_defaults ⇒ Object
Returns the value of attribute use_plugin_defaults.
Class Method Summary collapse
Instance Method Summary collapse
-
#by_name(config_name, include_path = []) ⇒ Object
Resolve and return a deep-cloned, extended copy of a named preset.
-
#checksum ⇒ String
SHA1 of current in-memory presets.
-
#defaults_set(plugin_name, preset_name, preset_values, option_default, option_override) ⇒ Object
Create / overwrite a preset and optionally set it as plugin default.
-
#global_default_preset ⇒ String
Name of the global default preset, creating it if needed.
-
#initialize(config_file:, use_plugin_defaults: true) ⇒ PresetManager
constructor
A new instance of PresetManager.
-
#lookup_preset(url:, username:) ⇒ Hash?
Find the first preset whose url+username match.
-
#plugin_default_name(plugin_name_sym) ⇒ String?
Name of the default preset for a plugin, or nil.
-
#read_config_file ⇒ Object
Read and validate the YAML config file.
-
#save_if_needed ⇒ Boolean
Save to disk only if content changed since last load/save.
-
#set_global_default(key, value) ⇒ Object
Set param in the global defaults preset.
-
#set_key(preset, param_name, param_value) ⇒ Object
Set a single key in a preset hash (creates the preset if absent).
Constructor Details
#initialize(config_file:, use_plugin_defaults: true) ⇒ PresetManager
Returns a new instance of PresetManager.
35 36 37 38 39 40 41 |
# File 'lib/aspera/cli/preset_manager.rb', line 35 def initialize(config_file:, use_plugin_defaults: true) @config_file = config_file @use_plugin_defaults = use_plugin_defaults @config_presets = {} @checksum_on_disk = nil read_config_file end |
Instance Attribute Details
#config_file ⇒ Object (readonly)
Returns the value of attribute config_file.
43 44 45 |
# File 'lib/aspera/cli/preset_manager.rb', line 43 def config_file @config_file end |
#config_presets ⇒ Object (readonly)
Returns the value of attribute config_presets.
43 44 45 |
# File 'lib/aspera/cli/preset_manager.rb', line 43 def config_presets @config_presets end |
#use_plugin_defaults ⇒ Object
Returns the value of attribute use_plugin_defaults.
43 44 45 |
# File 'lib/aspera/cli/preset_manager.rb', line 43 def use_plugin_defaults @use_plugin_defaults end |
Class Method Details
.deep_clone(val) ⇒ Object
209 210 211 |
# File 'lib/aspera/cli/preset_manager.rb', line 209 def deep_clone(val) Marshal.load(Marshal.dump(val)) end |
Instance Method Details
#by_name(config_name, include_path = []) ⇒ Object
Resolve and return a deep-cloned, extended copy of a named preset. Supports dot-notation (e.g. "outer.inner").
126 127 128 129 130 131 132 133 134 135 136 137 138 |
# File 'lib/aspera/cli/preset_manager.rb', line 126 def by_name(config_name, include_path = []) Aspera.assert(!include_path.include?(config_name), type: Cli::Error){'loop in include'} include_path = include_path.clone current = @config_presets config_name.split(PRESET_DIG_SEPARATOR).each do |name| Aspera.assert_type(current, Hash, type: Cli::Error){"sub key: #{include_path}"} include_path.push(name) current = current[name] Aspera.assert(!current.nil?, type: Cli::Error){"Unknown config preset: #{include_path}"} end current = self.class.deep_clone(current) unless current.is_a?(String) ExtendedValue.instance.evaluate(current, context: 'preset') end |
#checksum ⇒ String
Returns SHA1 of current in-memory presets.
51 52 53 |
# File 'lib/aspera/cli/preset_manager.rb', line 51 def checksum Digest::SHA1.hexdigest(JSON.generate(@config_presets)) end |
#defaults_set(plugin_name, preset_name, preset_values, option_default, option_override) ⇒ Object
Create / overwrite a preset and optionally set it as plugin default.
178 179 180 181 182 183 184 185 186 187 188 189 |
# File 'lib/aspera/cli/preset_manager.rb', line 178 def defaults_set(plugin_name, preset_name, preset_values, option_default, option_override) @config_presets[Key::DEFAULTS] ||= {} raise Cli::Error, "A default configuration already exists for plugin '#{plugin_name}' (use --override=yes or --default=no)" \ if !option_override && option_default && @config_presets[Key::DEFAULTS].key?(plugin_name) raise Cli::Error, "Preset already exists: #{preset_name} (use --override=yes or provide alternate name on command line)" \ if !option_override && @config_presets.key?(preset_name) if option_default Log.log.info("Setting config preset as default for #{plugin_name}") @config_presets[Key::DEFAULTS][plugin_name.to_s] = preset_name end @config_presets[preset_name] = preset_values end |
#global_default_preset ⇒ String
Returns name of the global default preset, creating it if needed.
163 164 165 166 167 168 169 170 |
# File 'lib/aspera/cli/preset_manager.rb', line 163 def global_default_preset result = plugin_default_name(CONF_GLOBAL_SYM) if result.nil? result = Key::GLOBAL set_key(Key::DEFAULTS, CONF_GLOBAL_SYM, result) end result end |
#lookup_preset(url:, username:) ⇒ Hash?
Find the first preset whose url+username match
193 194 195 196 197 198 199 200 201 202 |
# File 'lib/aspera/cli/preset_manager.rb', line 193 def lookup_preset(url:, username:) url = canonical_url(url) Log.log.debug{"Lookup preset for #{username}@#{url}"} @config_presets.each_value do |v| next unless v.is_a?(Hash) conf_url = v['url'].is_a?(String) ? canonical_url(v['url']) : nil return self.class.deep_clone(v) if conf_url.eql?(url) && v['username'].eql?(username) end nil end |
#plugin_default_name(plugin_name_sym) ⇒ String?
Returns name of the default preset for a plugin, or nil.
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
# File 'lib/aspera/cli/preset_manager.rb', line 102 def plugin_default_name(plugin_name_sym) Aspera.assert(!@config_presets.nil?, 'config_presets shall be defined') return unless @use_plugin_defaults return unless @config_presets.key?(Key::DEFAULTS) Aspera.assert_type(@config_presets[Key::DEFAULTS], Hash){'default section'} return unless @config_presets[Key::DEFAULTS].key?(plugin_name_sym.to_s) default_name = @config_presets[Key::DEFAULTS][plugin_name_sym.to_s] unless @config_presets.key?(default_name) Log.log.error do "Default config name [#{default_name}] specified for plugin [#{plugin_name_sym}], but it does not exist in config file.\n" \ "Please fix: either create preset:\n" \ "#{Info::CMD_NAME} config id #{default_name} init @json:'{}'\n" \ "or remove default:\n#{Info::CMD_NAME} config id default remove #{plugin_name_sym}" end raise Cli::Error, "No such preset: #{default_name}" end Aspera.assert_type(@config_presets[default_name], Hash, type: Cli::Error){'preset type'} default_name end |
#read_config_file ⇒ Object
Read and validate the YAML config file. Sets @config_presets and @checksum_on_disk.
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 |
# File 'lib/aspera/cli/preset_manager.rb', line 57 def read_config_file Log.log.debug{"config file is: #{@config_file}".red} if File.exist?(@config_file) Log.log.debug{"loading #{@config_file}"} @config_presets = Yaml.safe_load(File.read(@config_file)) @checksum_on_disk = checksum else Log.log.warn{"No config file found. New configuration file: #{@config_file}"} @config_presets = {Key::CONFIG => {Key::VERSION => 'new file'}} # @checksum_on_disk remains nil: will be saved on first write end validate_config_presets! rescue Psych::SyntaxError => e Log.log.error('YAML error in config file') raise e rescue StandardError => e Log.log.debug{"-> #{e.class.name} : #{e}"} if File.exist?(@config_file) new_name = "#{@config_file}.pre#{Cli::VERSION}.manual_conversion_needed" File.rename(@config_file, new_name) Log.log.warn{"Renamed config file to #{new_name}."} Log.log.warn('Manual Conversion is required. Next time, a new empty file will be created.') end raise Cli::Error, e.to_s end |
#save_if_needed ⇒ Boolean
Save to disk only if content changed since last load/save.
85 86 87 88 89 90 91 92 93 94 95 |
# File 'lib/aspera/cli/preset_manager.rb', line 85 def save_if_needed Aspera.assert(!@config_presets.nil?, type: Cli::Error){'no configuration loaded'} current = checksum return false if @checksum_on_disk.eql?(current) FileUtils.mkdir_p(File.dirname(@config_file)) Environment.restrict_file_access(File.dirname(@config_file)) Log.log.info{"Saving config file: #{@config_file}"} Environment.write_file_restricted(@config_file, force: true){@config_presets.to_yaml} @checksum_on_disk = current true end |
#set_global_default(key, value) ⇒ Object
Set param in the global defaults preset
173 174 175 |
# File 'lib/aspera/cli/preset_manager.rb', line 173 def set_global_default(key, value) set_key(global_default_preset, key, value) end |
#set_key(preset, param_name, param_value) ⇒ Object
Set a single key in a preset hash (creates the preset if absent).
141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 |
# File 'lib/aspera/cli/preset_manager.rb', line 141 def set_key(preset, param_name, param_value) Aspera.assert_type(param_name, String, Symbol){'parameter'} param_name = param_name.to_s selected = @config_presets[preset] if selected.nil? Log.log.debug{"Unknown preset name: #{preset}, initializing"} selected = @config_presets[preset] = {} end Aspera.assert_type(selected, Hash){"#{preset}.#{param_name}"} if selected.key?(param_name) if selected[param_name].eql?(param_value) Log.log.warn{"keeping same value for #{preset}: #{param_name}: #{param_value}"} return end Log.log.warn{"overwriting value for #{param_name}: #{selected[param_name]}"} end selected[param_name] = param_value Log.log.info("Updated: #{preset}: #{param_name} <- #{param_value}") nil end |