require "colorize" require "yaml" class Baguette::Context # By default, just print everything. class_property verbosity = 4 end class Baguette::Configuration class Base include YAML::Serializable # Check for provided file first, # then $XDG_CONFIG_HOME/.yml, # then /etc/baguette/.yml. def self.get(file : String? = nil) filename = "/" + (self.name.downcase.gsub /baguette::configuration::/, "") + ".yml" directory = "/baguette" suffix = "#{directory}#{filename}" user_configuration = (ENV["XDG_CONFIG_HOME"]? || "~/.config") + suffix system_configuration = "/etc#{suffix}" if ! file.nil? && ! File.exists? file.not_nil! Baguette::Log.warning "Provided configuration file does not exist: #{file}" end if ! file.nil? && File.exists? file.not_nil! Baguette::Log.info "Using configuration file: #{file}" self.from_yaml File.read(file.not_nil!) elsif File.exists? user_configuration Baguette::Log.info "Using user configuration: #{user_configuration}" self.from_yaml File.read(user_configuration) elsif File.exists? user_configuration Baguette::Log.info "Using system configuration: #{system_configuration}" self.from_yaml File.read(system_configuration) else Baguette::Log.warning "No configuration found" nil end end end # Read options from the CLI. # We currently want to know: # - the program verbosity # - the configuration file to use # - if the configuration files should be ignored # - if this is just a simulation (used to print configuration then quit) def self.option_parser simulation = false no_configuration = false configuration_file = nil help = false OptionParser.parse do |parser| parser.banner = "usage: #{PROGRAM_NAME} [-ns][-c configuration-file]" parser.on "-s", "--simulation", "Print configuration then quit." do simulation = true end parser.on "-n", "--no-configuration", "No configuration file should be read." do no_configuration = true end parser.on "-v verbosity", "--verbosity level", "Verbosity level. From 0 to 3. Default: 1" do |v| Baguette::Context.verbosity = v.to_i end parser.on "-c file", "--configuration file", "Configuration file." do |file| configuration_file = file end parser.invalid_option do |arg| # Do not print anything: we only check for configuration file stuff. end parser.on "-h", "--help", "Show this help" do Baguette::Log.warning "for the first option parsing!" puts parser help = true end end # Options are removed once read from the ARGV array, but we want to propagate # this particular option to print the second set of options. ARGV.push "-h" if help return simulation, no_configuration, configuration_file end end class Baguette::Log # FIXME: Use log files. # FIXME: def log(), that puts stuff as-is in the logs. def self.debug(text) return unless Baguette::Context.verbosity > 2 STDERR.puts ":: #{text}".colorize(:cyan) STDERR.flush end def self.info(text) return unless Baguette::Context.verbosity > 1 STDOUT .<<(":: ".colorize(:blue)) .<<(text.colorize(:white)) .<<("\n") STDOUT.flush end def self.title(text) return unless Baguette::Context.verbosity > 1 STDOUT .<<("|> ".colorize(:blue).bright) .<<(text.colorize(:white).bright) .<<("\n") STDOUT.flush end def self.warning(text) return unless Baguette::Context.verbosity > 0 STDERR.puts ":: #{text}".colorize(:yellow) STDERR.flush end def self.error(text) return unless Baguette::Context.verbosity > 0 STDERR.puts "!! #{text}".colorize(:red) STDERR.flush end end