OSDN Git Service

Change to production env.
[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       end
15       attr_reader :logger
16       
17       def parse_opt
18         opts = GetoptLong.new(
19           [ '--help', '-h', GetoptLong::NO_ARGUMENT ],
20           [ '--verbose', '-v', GetoptLong::NO_ARGUMENT ],
21           [ '--quiet', '-q', GetoptLong::NO_ARGUMENT ],
22         )
23         opts.ordering = GetoptLong::REQUIRE_ORDER
24         opts.each do |opt, arg|
25           case opt
26           when '--help'
27             help
28             exit 0
29           when '--verbose'
30             if logger.level == Logger::DEBUG
31               OSDNClient.configure do |config|
32                 config.debugging = true
33               end
34             end
35             logger.level > Logger::DEBUG and
36               logger.level -= 1
37           when '--quiet'
38             logger.level < Logger::UNKNOWN and
39               logger.level += 1
40           when '--help'
41             help
42             exit
43           end
44         end
45         logger.debug "Loglevel is #{logger.level}"
46       end
47
48       def get_command_class(command_name)
49         class_name = command_name.to_s.split('_').map(&:capitalize).join
50         begin
51           return self.class.const_get("OSDN::CLI::Command::#{class_name}")
52         rescue NameError => e
53           logger.fatal "Invalid command name '#{command_name}'. Use 'help' to list commands."
54           exit
55         end
56         false
57       end
58
59       def run
60         parse_opt
61
62         command_name = ARGV.shift
63         unless command_name
64           help
65           exit 1
66         end
67
68         if command_name == 'help'
69           help
70           exit
71         end
72         
73         command = get_command_class(command_name).new(logger)
74         logger.debug "Run command #{command_name}"
75         begin
76           command.run
77         rescue OSDNClient::ApiError => e
78           begin
79             err = JSON.parse(e.response_body)
80             if err["message"]
81               logger.fatal "#{err["status"]}: #{err["message"]}"
82             elsif err["error_description"]
83               logger.fatal err["error_description"]
84             else
85               logger.fatal "Command failed: #{e.inspect}"
86             end
87           rescue
88             logger.fatal "Command failed: #{e.inspect}"
89           end
90         end
91       end
92
93       def help
94         command_name = ARGV.shift
95         if command_name
96           get_command_class(command_name).new(logger).help
97         else
98           puts "#{$0} [global-options] <command> [command-options] [args]"
99           puts "#{$0} help <command>"
100           puts "Global Options:"
101           puts "  -h --help      Show help message. use 'help <command>' for specific command. "
102           puts "  -v --verbose   Increase log level (multiple)"
103           puts "  -q --quiet     Decrease log level (multiple)"
104           puts "Avaiable Commands:"
105           puts "  help"
106           OSDN::CLI::Command.constants.each do |c|
107             c = c.to_s.split(/(?=[A-Z])/).join('_').downcase
108             c == 'base' and next
109             puts "  %-14s %s" % [c, get_command_class(c).description]
110           end
111         end
112       end
113     end
114   end
115 end