Class: Travis::CLI::Command

Inherits:
Object
  • Object
show all
Extended by:
Forwardable, Parser, Tools::Assets
Includes:
Tools::Assets
Defined in:
lib/travis/cli/command.rb

Direct Known Subclasses

ApiCommand, Help, Version

Constant Summary collapse

MINUTE =
60
HOUR =
3600
DAY =
86400
WEEK =
604800

Constants included from Tools::Assets

Tools::Assets::BASE

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Tools::Assets

asset, asset_path

Methods included from Parser

new, on, on_initialize

Constructor Details

#initialize(options = {}) ⇒ Command

Returns a new instance of Command.



90
91
92
93
94
95
96
97
98
99
# File 'lib/travis/cli/command.rb', line 90

def initialize(options = {})
  @on_signal  = []
  @formatter  = Travis::Tools::Formatter.new
  self.output = $stdout
  self.input  = $stdin
  options.each do |key, value|
    public_send("#{key}=", value) if respond_to? "#{key}="
  end
  @arguments ||= []
end

Instance Attribute Details

#argumentsObject

Returns the value of attribute arguments.



86
87
88
# File 'lib/travis/cli/command.rb', line 86

def arguments
  @arguments
end

#configObject

Returns the value of attribute config.



86
87
88
# File 'lib/travis/cli/command.rb', line 86

def config
  @config
end

#debug(line) ⇒ Object

Returns the value of attribute debug.



86
87
88
# File 'lib/travis/cli/command.rb', line 86

def debug
  @debug
end

#force_interactiveObject

Returns the value of attribute force_interactive.



86
87
88
# File 'lib/travis/cli/command.rb', line 86

def force_interactive
  @force_interactive
end

#formatterObject

Returns the value of attribute formatter.



86
87
88
# File 'lib/travis/cli/command.rb', line 86

def formatter
  @formatter
end

#inputObject

Returns the value of attribute input.



87
88
89
# File 'lib/travis/cli/command.rb', line 87

def input
  @input
end

#outputObject

Returns the value of attribute output.



87
88
89
# File 'lib/travis/cli/command.rb', line 87

def output
  @output
end

Class Method Details

.abstractObject



58
59
60
# File 'lib/travis/cli/command.rb', line 58

def self.abstract
  @@abstract << self
end

.abstract?Boolean

Returns:

  • (Boolean)


54
55
56
# File 'lib/travis/cli/command.rb', line 54

def self.abstract?
  @@abstract.include? self
end

.command_nameObject



49
50
51
# File 'lib/travis/cli/command.rb', line 49

def self.command_name
  name[/[^:]*$/].split(/(?=[A-Z])/).map(&:downcase).join('-')
end

.description(description = nil) ⇒ Object



66
67
68
69
# File 'lib/travis/cli/command.rb', line 66

def self.description(description = nil)
  @description = description if description
  @description ||= ""
end

.skip(*names) ⇒ Object



62
63
64
# File 'lib/travis/cli/command.rb', line 62

def self.skip(*names)
  names.each { |n| define_method(n) {} }
end

.subcommands(*list) ⇒ Object



71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/travis/cli/command.rb', line 71

def self.subcommands(*list)
  return @subcommands ||= [] if list.empty?
  @subcommands = list

  define_method :run do |subcommand, *args|
    error "Unknown subcommand. Available: #{list.join(', ')}." unless list.include? subcommand.to_sym
    send(subcommand, *args)
  end

  define_method :usage do
    usages = list.map { |c| color(usage_for("#{command_name} #{c}", c), :command) }
    "\nUsage: #{usages.join("\n       ")}\n\n"
  end
end

Instance Method Details

#check_completionObject



170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
# File 'lib/travis/cli/command.rb', line 170

def check_completion
  return if skip_completion_check? or !interactive?

  if config['checked_completion']
    Tools::Completion.update_completion if config['completion_version'] != Travis::VERSION
  else
    write_to($stderr) do
      next Tools::Completion.update_completion if Tools::Completion.completion_installed?
      next unless agree('Shell completion not installed. Would you like to install it now? ') { |q| q.default = "y" }
      Tools::Completion.install_completion
    end
  end

  config['checked_completion'] = true
  config['completion_version'] = Travis::VERSION
end

#check_rubyObject



187
188
189
190
# File 'lib/travis/cli/command.rb', line 187

def check_ruby
  return if RUBY_VERSION > '1.9.2' or skip_version_check?
  warn "Your Ruby version is outdated, please consider upgrading, as we will drop support for #{RUBY_VERSION} soon!"
end

#check_versionObject



140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
# File 'lib/travis/cli/command.rb', line 140

def check_version
  last_check.clear if last_check['version'] != Travis::VERSION
  seconds_since = Time.now.to_i - last_check['at'].to_i

  return if skip_version_check?
  return if seconds_since < MINUTE

  case seconds_since
  when MINUTE .. HOUR then timeout = 0.5
  when HOUR   .. DAY  then timeout = 1.0
  when DAY    .. WEEK then timeout = 2.0
  else                     timeout = 10.0
  end

  Timeout.timeout(timeout) do
    response              = Faraday.get('https://rubygems.org/api/v1/gems/travis.json', {}, 'If-None-Match' => last_check['etag'].to_s)
    last_check['etag']    = response.headers['etag']
    last_check['version'] = JSON.parse(response.body)['version'] if response.status == 200
  end

  last_check['at'] = Time.now.to_i
  unless Tools::System.recent_version? Travis::VERSION, last_check['version']
    warn "Outdated CLI version, run `gem install travis`."
  end
rescue Timeout::Error, Faraday::ClientError => error
  debug "#{error.class}: #{error.message}"
rescue JSON::ParserError => error
  warn "Unable to determine the most recent travis gem version. http://rubygems.org may be down."
end

#command_nameObject



223
224
225
# File 'lib/travis/cli/command.rb', line 223

def command_name
  self.class.command_name
end

#debug?Object

Returns the value of attribute debug.



88
89
90
# File 'lib/travis/cli/command.rb', line 88

def debug
  @debug
end

#error(message, &block) ⇒ Object



289
290
291
292
# File 'lib/travis/cli/command.rb', line 289

def error(message, &block)
  warn(message, &block)
  exit 1
end

#executeObject



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
# File 'lib/travis/cli/command.rb', line 192

def execute
  setup_trap
  check_ruby
  check_arity(method(:run), *arguments)
  load_config
  check_version
  check_completion
  setup
  run(*arguments)
  clear_error
  store_config
rescue Travis::Client::NotLoggedIn => e
  raise(e) if explode?
  error "#{e.message} - try running #{command("login#{endpoint_option}")}"
rescue Travis::Client::RepositoryMigrated => e
  raise (e) if explode?
  error e.message
rescue Travis::Client::NotFound => e
  raise(e) if explode?
  error "resource not found (#{e.message})"
rescue Travis::Client::Error => e
  raise(e) if explode?
  error e.message
rescue StandardError => e
  raise(e) if explode?
  message = e.message
  message += color("\nfor a full error report, run #{command("report#{endpoint_option}")}", :error) if interactive?
  store_error(e)
  error(message)
end

#help(info = "") ⇒ Object



247
248
249
250
# File 'lib/travis/cli/command.rb', line 247

def help(info = "")
  parser.banner = usage
  self.class.description.sub(/./) { |c| c.upcase } + ".\n" + info + parser.to_s
end

#info(line) ⇒ Object



272
273
274
275
276
# File 'lib/travis/cli/command.rb', line 272

def info(line)
  write_to($stderr) do
    say color(line, :info)
  end
end

#last_checkObject



132
133
134
135
136
137
138
# File 'lib/travis/cli/command.rb', line 132

def last_check
  config['last_check'] ||= {
    # migrate from old values
    'at'   => config.delete('last_version_check'),
    'etag' => config.delete('etag')
  }
end

#on_signal(&block) ⇒ Object



278
279
280
# File 'lib/travis/cli/command.rb', line 278

def on_signal(&block)
  @on_signal << block
end

#parse(args) ⇒ Object



122
123
124
125
126
127
# File 'lib/travis/cli/command.rb', line 122

def parse(args)
  rest = parser.parse(args)
  arguments.concat(rest)
rescue OptionParser::ParseError => e
  error e.message
end

#say(data, format = nil, style = nil) ⇒ Object



252
253
254
# File 'lib/travis/cli/command.rb', line 252

def say(data, format = nil, style = nil)
  terminal.say format(data, format, style)
end

#setupObject



129
130
# File 'lib/travis/cli/command.rb', line 129

def setup
end

#terminalObject



101
102
103
# File 'lib/travis/cli/command.rb', line 101

def terminal
  @terminal ||= HighLine.new(input, output)
end

#time(info, callback = Proc.new) ⇒ Object



263
264
265
266
267
268
269
270
# File 'lib/travis/cli/command.rb', line 263

def time(info, callback = Proc.new)
  return callback.call unless debug?
  start = Time.now
  debug(info)
  callback.call
  duration = Time.now - start
  debug("  took %.2g seconds" % duration)
end

#usageObject



227
228
229
# File 'lib/travis/cli/command.rb', line 227

def usage
  "Usage: " << color(usage_for(command_name, :run), :command)
end

#usage_for(prefix, method) ⇒ Object



231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
# File 'lib/travis/cli/command.rb', line 231

def usage_for(prefix, method)
  usage = "travis #{prefix}"
  method = method(method)
  if method.respond_to? :parameters
    method.parameters.each do |type, name|
      name = name.upcase
      name = "[#{name}]"   if type == :opt
      name = "[#{name}..]" if type == :rest
      usage << " #{name}"
    end
  elsif method.arity != 0
    usage << " ..."
  end
  usage << " [OPTIONS]"
end

#warn(message) ⇒ Object



282
283
284
285
286
287
# File 'lib/travis/cli/command.rb', line 282

def warn(message)
  write_to($stderr) do
    say color(message, :error)
    yield if block_given?
  end
end

#write_to(io) ⇒ Object



115
116
117
118
119
120
# File 'lib/travis/cli/command.rb', line 115

def write_to(io)
  io_was, self.output = output, io
  yield
ensure
  self.output = io_was if io_was
end