OSDN Git Service

Tune general error message.
[osdn-codes/osdn-cli.git] / lib / osdn / cli / runner.rb
1 require 'getoptlong'
2 require 'logger'
3 require 'pp'
4
5 module OSDN
6   module CLI
7     class Runner
8       def initialize
9         @logger = Logger.new(STDERR)
10         @logger.level = Logger::WARN
11         @logger.formatter = proc { |severity, time, progname, msg|
12           "[%s] %s\n" % [severity, msg]
13         }
14         OSDNClient.configure do |config|
15           ENV['OSDN_API_OVERRIDE_HOST'] and
16             config.host = ENV['OSDN_API_OVERRIDE_HOST']
17           ENV['OSDN_API_SKIP_SSL_VERIFY'].to_s =~ /^(1|t(rue)?|y(es)?)$/ and
18             config.verify_ssl = false
19         end
20       end
21       attr_reader :logger
22       
23       def parse_opt
24         opts = GetoptLong.new(
25           [ '--help', '-h', GetoptLong::NO_ARGUMENT ],
26           [ '--verbose', '-v', GetoptLong::NO_ARGUMENT ],
27           [ '--quiet', '-q', GetoptLong::NO_ARGUMENT ],
28         )
29         opts.ordering = GetoptLong::REQUIRE_ORDER
30         opts.each do |opt, arg|
31           case opt
32           when '--help'
33             help
34             exit 0
35           when '--verbose'
36             if logger.level == Logger::DEBUG
37               OSDNClient.configure do |config|
38                 config.debugging = true
39               end
40             end
41             logger.level > Logger::DEBUG and
42               logger.level -= 1
43           when '--quiet'
44             logger.level < Logger::UNKNOWN and
45               logger.level += 1
46           when '--help'
47             help
48             exit
49           end
50         end
51         logger.debug "Loglevel is #{logger.level}"
52       end
53
54       def get_command_class(command_name)
55         class_name = command_name.to_s.split('_').map(&:capitalize).join
56         begin
57           return self.class.const_get("OSDN::CLI::Command::#{class_name}")
58         rescue NameError => e
59           logger.fatal "Invalid command name '#{command_name}'. Use 'help' to list commands."
60           exit
61         end
62         false
63       end
64
65       def run
66         parse_opt
67
68         command_name = ARGV.shift
69         unless command_name
70           help
71           exit 1
72         end
73
74         if command_name == 'help'
75           help
76           exit
77         end
78         
79         command = get_command_class(command_name).new(logger)
80         logger.debug "Run command #{command_name}"
81         begin
82           command.run
83         rescue OSDNClient::ApiError => e
84           begin
85             err = JSON.parse(e.response_body)
86             if err["message"]
87               logger.fatal "#{err["status"]}: #{err["message"]}"
88             elsif err["error_description"]
89               logger.fatal err["error_description"]
90             else
91               logger.fatal "Command failed by ApiError: #{e.response_body}"
92             end
93           rescue => e
94             logger.fatal "Command failed: #{e.inspect}"
95           end
96         end
97       end
98
99       def help
100         command_name = ARGV.shift
101         if command_name
102           get_command_class(command_name).new(logger).help
103         else
104           puts "#{$0} [global-options] <command> [command-options] [args]"
105           puts "#{$0} help <command>"
106           puts "Global Options:"
107           puts "  -h --help      Show help message. use 'help <command>' for specific command. "
108           puts "  -v --verbose   Increase log level (multiple)"
109           puts "  -q --quiet     Decrease log level (multiple)"
110           puts "Avaiable Commands:"
111           puts "  help"
112           OSDN::CLI::Command.constants.each do |c|
113             c = c.to_s.split(/(?=[A-Z])/).join('_').downcase
114             c == 'base' and next
115             puts "  %-14s %s" % [c, get_command_class(c).description]
116           end
117         end
118       end
119     end
120   end
121 end