Class: GHTorrent::Command

Inherits:
Object
  • Object
show all
Includes:
Logging, Settings
Defined in:
lib/ghtorrent/command.rb

Overview

Base class for all GHTorrent command line utilities. Provides basic command line argument parsing and command bootstraping support. The order of initialization is the following: prepare_options validate go

Constant Summary

Constants included from Settings

Settings::CONFIGKEYS, Settings::DEFAULTS

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Logging

#debug, #error, #info, #loggerr, #warn

Methods included from Settings

#config, #merge, #merge_config_values, #settings

Methods included from Utils

included, #read_value, #user_type, #write_value

Class Method Details

.run(args = ARGV) ⇒ Object



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/ghtorrent/command.rb', line 24

def run(args = ARGV)
  attr_accessor :args
  attr_accessor :settings
  attr_accessor :name
  attr_accessor :options

  command = new()

  command.name = self.class.name
  command.args = args

  command.process_options
  command.validate

  command.settings = YAML::load_file command.options[:config]

  unless command.options[:addr].nil?
    command.settings = command.override_config(command.settings,
                                               :attach_ip,
                                               command.options[:addr])
  end

  unless command.options[:username].nil?
    command.settings = command.override_config(command.settings,
                                               :github_username,
                                               command.options[:username])
  end

  unless command.options[:password].nil?
    command.settings = command.override_config(command.settings,
                                               :github_passwd,
                                               command.options[:password])
  end

  unless command.options[:token].nil?
    command.settings = command.override_config(command.settings,
                                               :github_token,
                                               command.options[:token])
  end

  unless command.options[:req_limit].nil?
    command.settings = command.override_config(command.settings,
                                               :req_limit,
                                               command.options[:req_limit])
  end

  unless command.options[:uniq].nil?
    command.settings = command.override_config(command.settings,
                                               :logging_uniq,
                                               command.options[:uniq])
  end


  begin
    command.go
  rescue => e
    STDERR.puts e.message
    if command.options.verbose
      STDERR.puts e.backtrace.join("\n")
    else
      STDERR.puts e.backtrace[0]
    end
    exit 1
  end
end

Instance Method Details

#command_nameObject

Name of the command that is currently being executed.



156
157
158
# File 'lib/ghtorrent/command.rb', line 156

def command_name
  File.basename($0)
end

#goObject

The actual command code.



161
162
# File 'lib/ghtorrent/command.rb', line 161

def go
end

#override_config(config_file, setting, new_value) ⇒ Object



224
225
226
227
# File 'lib/ghtorrent/command.rb', line 224

def override_config(config_file, setting, new_value)
  puts "Overriding configuration #{setting}=#{config(setting)} with new value #{new_value}"
  super(config_file, setting, new_value)
end

#prepare_options(options) ⇒ Object

This method should be overriden by subclasses in order to specify, using trollop, the supported command line options



125
126
# File 'lib/ghtorrent/command.rb', line 125

def prepare_options(options)
end

#process_optionsObject

Specify and parse top-level command line options.



92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/ghtorrent/command.rb', line 92

def process_options
  command = self
  @options = Trollop::options(command.args) do

    command.prepare_options(self)

    banner <<-END
Standard options:
    END

    opt :config, 'config.yaml file location', :short => 'c',
        :default => 'config.yaml'
    opt :verbose, 'verbose mode', :short => 'v'
    opt :addr, 'IP address to use for performing requests', :short => 'a',
        :type => String
    opt :username, 'Username at Github', :short => 's', :type => String
    opt :password, 'Password at Github', :type => String
    opt :token, 'OAuth Github token (use instead of username/password)',
        :type => String, :short => 't'
    opt :req_limit, 'Request limit for provided account (in reqs/hour)',
        :type => Integer, :short => 'l'
    opt :uniq, 'Unique name for this command. Will appear in logs.',
        :type => String, :short => 'u'
  end
end

#queue_client(queue, ack = :after, block) ⇒ Object

Specify a handler to incoming messages from a connection to a queue.

Parameters:

  • queue (String)

    the queue name to bind to

  • ack (Symbol) (defaults to: :after)

    when should acks be send, :before or :after the block returns

  • block (Block)

    : A block accepting one argument (the message)



169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
# File 'lib/ghtorrent/command.rb', line 169

def queue_client(queue, ack = :after, block)

  stopped = false
  while not stopped
    begin
      conn = Bunny.new(:host => config(:amqp_host),
                       :port => config(:amqp_port),
                       :username => config(:amqp_username),
                       :password => config(:amqp_password))
      conn.start

      ch  = conn.create_channel
      debug "Setting prefetch to #{config(:amqp_prefetch)}"
      ch.prefetch(config(:amqp_prefetch))
      debug "Connection to #{config(:amqp_host)} succeded"

      x = ch.topic(config(:amqp_exchange), :durable => true,
                   :auto_delete => false)
      q   = ch.queue(queue, :durable => true)
      q.bind(x)

      q.subscribe(:block => true,
                  :ack => true) do |delivery_info, properties, msg|

        if ack == :before
          ch.acknowledge(delivery_info.delivery_tag)
        end

        begin
          block.call(msg)
        ensure
          ch.acknowledge(delivery_info.delivery_tag)
        end
      end

    rescue Bunny::TCPConnectionFailed => e
      warn "Connection to #{config(:amqp_host)} failed. Retrying in 1 sec"
      sleep(1)
    rescue Bunny::PossibleAuthenticationFailureError => e
      warn "Could not authenticate as #{conn.username}"
    rescue Bunny::NotFound, Bunny::AccessRefused, Bunny::PreconditionFailed => e
      warn "Channel error: #{e}. Retrying in 1 sec"
      sleep(1)
    rescue Interrupt => _
      stopped = true
    rescue StandardError => e
      raise e
    end
  end

  ch.close unless ch.nil?
  conn.close unless conn.nil?

end

#validateObject

Examine the validity of the provided options in the context of the executed command. Subclasses can also call super to also invoke the checks provided by this class.



131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
# File 'lib/ghtorrent/command.rb', line 131

def validate
  if options[:config].nil?
    unless (file_exists?("config.yaml"))
      Trollop::die "No config file in default location (#{Dir.pwd}). You
                    need to specify the #{:config} parameter. Read the
                    documentation on how to create a config.yaml file."
    end
  else
    Trollop::die "Cannot find file #{options[:config]}" \
      unless file_exists?(options[:config])
  end

  unless @options[:user].nil?
    if not Process.uid == 0
      Trollop::die "Option --user (-u) can only be specified by root"
    end
      begin
        Etc.getpwnam(@options[:user])
      rescue ArgumentError
        Trollop::die "No such user: #{@options[:user]}"
      end
  end
end

#versionObject

Get the version of the project



119
120
121
# File 'lib/ghtorrent/command.rb', line 119

def version
  IO.read(File.join(File.dirname(__FILE__), '..', '..', 'VERSION'))
end