OSDN Git Service

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