require 'cli/kit' require 'fileutils' module CLI module Kit class Config XDG_CONFIG_HOME = 'XDG_CONFIG_HOME' def initialize(tool_name:) @tool_name = tool_name end # Returns the config corresponding to `name` from the config file # `false` is returned if it doesn't exist # # #### Parameters # `section` : the section of the config value you are looking for # `name` : the name of the config value you are looking for # # #### Returns # `value` : the value of the config variable (false if none) # # #### Example Usage # `config.get('name.of.config')` # def get(section, name) all_configs.dig("[#{section}]", name) || false end # Sets the config value in the config file # # #### Parameters # `section` : the section of the config you are setting # `name` : the name of the config you are setting # `value` : the value of the config you are setting # # #### Example Usage # `config.set('section', 'name.of.config', 'value')` # def set(section, name, value) all_configs["[#{section}]"] ||= {} all_configs["[#{section}]"][name] = value.nil? ? nil : value.to_s write_config end def get_section(section) (all_configs["[#{section}]"] || {}).dup end # Returns a path from config in expanded form # e.g. shopify corresponds to ~/src/shopify, but is expanded to /Users/name/src/shopify # # #### Example Usage # `config.get_path('srcpath', 'shopify')` # # #### Returns # `path` : the expanded path to the corrsponding value # def get_path(section, name = nil) v = get(section, name) false == v ? v : File.expand_path(v) end def to_s ini.to_s end # The path on disk at which the configuration is stored: # `$XDG_CONFIG_HOME//config` # if ENV['XDG_CONFIG_HOME'] is not set, we default to ~/.config, e.g.: # ~/.config/tool/config # def file config_home = ENV.fetch(XDG_CONFIG_HOME, '~/.config') File.expand_path(File.join(@tool_name, 'config'), config_home) end private def all_configs ini.ini end def ini @ini ||= CLI::Kit::Ini .new(file, default_section: "[global]", convert_types: false) .tap(&:parse) end def write_config all_configs.each do |section, sub_config| all_configs[section] = sub_config.reject { |_, value| value.nil? } all_configs.delete(section) if all_configs[section].empty? end FileUtils.mkdir_p(File.dirname(file)) File.write(file, to_s) end end end end