module NSWTopo::Config
def self.method_missing(symbol, *args, &block)
def self.method_missing(symbol, *args, &block) extend(self).init singleton_class.remove_method :method_missing send symbol, *args, &block end
def delete(*entries, key)
def delete(*entries, key) delete_recursive @config, *entries, key end
def delete_recursive(config, *entries, key)
def delete_recursive(config, *entries, key) case when entry = entries.shift raise "no such entry: %s" % entry unless Hash === config[entry] delete_recursive config[entry], *entries, key config.delete entry if config[entry].empty? when config.key?(key) config.delete key else raise "no such entry: %s" % key end end
def init
def init candidates = [] %w[XDG_CONFIG_HOME APPDATA].each do |key| candidates << [ENV.fetch(key), "nswtopo"] rescue KeyError end candidates << [Dir.home, "Library", "Application Support", "com.nswtopo"] candidates << [Dir.home, ".config", "nswtopo"] candidates << [Dir.home, ".nswtopo"] @path = candidates.map do |base, *parts| Pathname(base).join(*parts) end.first do |dir| dir.parent.directory? end.join("nswtopo.cfg") @config, extra = [@path, @extra_path].map do |path| next Hash[] unless path&.file? config = YAML.load(path.read) Hash === config ? config : raise rescue YAML::Exception, RuntimeError log_warn "couldn't parse #{path} - ignoring" Hash[] end @merged = @config.deep_merge extra end
def save
def save @path.parent.mkpath @path.write @config.to_yaml end
def store(*entries, key, value)
def store(*entries, key, value) entries.inject(@config) do |config, entry| config[entry] ||= {} Hash === config[entry] ? config[entry] : raise("entry already taken: %s" % entry) end.store key, value end