require "yaml" require "option_parser" require "colorize" # require "xdg_basedir" # require "completion" require "log" require "../lib/actions" require "../lib/types" require "../lib/models" require "../lib/version" module Arkisto class CtlCli property config : ConfigModel? property options : GlobalOptions? def initialize # @config = nil @options = nil end def self.parse_options(args) : GlobalOptions # default values action = NoneAction config_file = "arkisto.yml" verbose = true dry_run = false # parse OptionParser.parse(args) do |parser| parser.banner = "Usage: #{Version::PROGRAM_ARKISTOCTL} [options] [commands] [arguments]" parser.separator parser.separator "Options" parser.on "-c CONFIG_FILE", "--config=CONFIG_FILE", "Use the following config file" do |file| config_file = file end parser.on "-v", "--verbose", "Be verbose" do verbose = !verbose end parser.on "--dry-run", "Dry run (no real openstack command is executed" do dry_run = true end parser.on "--version", "Show version" do puts "version #{Version::VERSION}" exit 0 end parser.on "-h", "--help", "Show this help" do puts parser exit 0 end parser.on "--completion", "Provide autocompletion for bash" do # nothing here end parser.on "plan", "Display backup plan" do action = PlanAction end parser.on "apply", "Apply backup plan" do action = ApplyAction end parser.separator parser.missing_option do |flag| STDERR.puts parser STDERR.puts "ERROR: #{flag} requires an argument.".colorize(:red) exit(1) end parser.invalid_option do |flag| STDERR.puts parser STDERR.puts "ERROR: #{flag} is not a valid option.".colorize(:red) exit(1) end # complete_with Version::PROGRAM_ARKISTOCTL, parser end return { action: action, config_file: config_file, dry_run: dry_run, verbose: verbose, }.as(GlobalOptions) end def self.parse_config(options) config_file = options[:config_file] puts "Loading configuration... #{config_file}".colorize(:yellow) if options[:verbose] if ! File.exists? config_file STDERR.puts "ERROR: Unable to read configuration file '#{config_file}'".colorize(:red) exit 1 end yaml_str = File.read(config_file) config = ConfigModel.from_yaml(yaml_str) if config.nil? STDERR.puts "ERROR: Invalid YAML content in '#{config_file}'" exit 1 end return config end def self.run(args) app = CtlCli.new options = CtlCli.parse_options(args) config = CtlCli.parse_config(options) app.options = options app.config = config action = ActionFactory.build( options[:action], config, { dry_run: options[:dry_run], verbose: options[:verbose] } ) action.perform rescue ex : YAML::ParseException STDERR.puts "ERROR: #{ex.message}".colorize(:red) end end end Arkisto::CtlCli.run(ARGV)