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_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.
34 35 36 37 38 39 40 |
# File 'lib/aspera/cli/preset_manager.rb', line 34 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_presets ⇒ Object (readonly)
Returns the value of attribute config_presets.
42 43 44 |
# File 'lib/aspera/cli/preset_manager.rb', line 42 def config_presets @config_presets end |
#use_plugin_defaults ⇒ Object
Returns the value of attribute use_plugin_defaults.
42 43 44 |
# File 'lib/aspera/cli/preset_manager.rb', line 42 def use_plugin_defaults @use_plugin_defaults end |
Class Method Details
.deep_clone(val) ⇒ Object
208 209 210 |
# File 'lib/aspera/cli/preset_manager.rb', line 208 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").
125 126 127 128 129 130 131 132 133 134 135 136 137 |
# File 'lib/aspera/cli/preset_manager.rb', line 125 def by_name(config_name, include_path = []) raise Cli::Error, 'loop in include' if include_path.include?(config_name) 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] raise Cli::Error, "Unknown config preset: #{include_path}" if current.nil? 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.
50 51 52 |
# File 'lib/aspera/cli/preset_manager.rb', line 50 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.
177 178 179 180 181 182 183 184 185 186 187 188 |
# File 'lib/aspera/cli/preset_manager.rb', line 177 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.
162 163 164 165 166 167 168 169 |
# File 'lib/aspera/cli/preset_manager.rb', line 162 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
192 193 194 195 196 197 198 199 200 201 |
# File 'lib/aspera/cli/preset_manager.rb', line 192 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.
101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 |
# File 'lib/aspera/cli/preset_manager.rb', line 101 def plugin_default_name(plugin_name_sym) Aspera.assert(!@config_presets.nil?, 'config_presets shall be defined') return nil unless @use_plugin_defaults return nil unless @config_presets.key?(Key::DEFAULTS) Aspera.assert_type(@config_presets[Key::DEFAULTS], Hash){'default section'} return nil 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.
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 |
# File 'lib/aspera/cli/preset_manager.rb', line 56 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.load_file(@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.
84 85 86 87 88 89 90 91 92 93 94 |
# File 'lib/aspera/cli/preset_manager.rb', line 84 def save_if_needed raise Cli::Error, 'no configuration loaded' if @config_presets.nil? 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
172 173 174 |
# File 'lib/aspera/cli/preset_manager.rb', line 172 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).
140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 |
# File 'lib/aspera/cli/preset_manager.rb', line 140 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 |