travis-akerl 1.8.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/LICENSE +22 -0
- data/README.md +2512 -0
- data/Rakefile +64 -0
- data/assets/cacert.pem +69 -0
- data/assets/init/c.yml +4 -0
- data/assets/init/clojure.yml +1 -0
- data/assets/init/cpp.yml +4 -0
- data/assets/init/erlang.yml +3 -0
- data/assets/init/go.yml +4 -0
- data/assets/init/groovy.yml +1 -0
- data/assets/init/haskell.yml +1 -0
- data/assets/init/java.yml +4 -0
- data/assets/init/node_js.yml +5 -0
- data/assets/init/objective-c.yml +1 -0
- data/assets/init/perl.yml +4 -0
- data/assets/init/php.yml +4 -0
- data/assets/init/python.yml +5 -0
- data/assets/init/ruby.yml +6 -0
- data/assets/init/scala.yml +4 -0
- data/assets/notifications/Travis CI.app/Contents/Info.plist +52 -0
- data/assets/notifications/Travis CI.app/Contents/MacOS/Travis CI +0 -0
- data/assets/notifications/Travis CI.app/Contents/PkgInfo +1 -0
- data/assets/notifications/Travis CI.app/Contents/Resources/Travis CI.icns +0 -0
- data/assets/notifications/Travis CI.app/Contents/Resources/en.lproj/Credits.rtf +29 -0
- data/assets/notifications/Travis CI.app/Contents/Resources/en.lproj/InfoPlist.strings +0 -0
- data/assets/notifications/Travis CI.app/Contents/Resources/en.lproj/MainMenu.nib +0 -0
- data/assets/notifications/Travis CI.app/Contents/_CodeSignature/CodeResources +173 -0
- data/assets/notifications/Travis CI.app/Contents/embedded.provisionprofile +0 -0
- data/assets/notifications/icon.png +0 -0
- data/assets/travis.sh +163 -0
- data/assets/travis.sh.erb +64 -0
- data/bin/travis +18 -0
- data/examples/org_overview.rb +3 -0
- data/examples/pro_auth.rb +23 -0
- data/examples/stream.rb +6 -0
- data/lib/travis/auto_login.rb +3 -0
- data/lib/travis/cli/accounts.rb +31 -0
- data/lib/travis/cli/api_command.rb +182 -0
- data/lib/travis/cli/branches.rb +25 -0
- data/lib/travis/cli/cache.rb +76 -0
- data/lib/travis/cli/cancel.rb +18 -0
- data/lib/travis/cli/command.rb +422 -0
- data/lib/travis/cli/console.rb +33 -0
- data/lib/travis/cli/disable.rb +15 -0
- data/lib/travis/cli/enable.rb +31 -0
- data/lib/travis/cli/encrypt.rb +115 -0
- data/lib/travis/cli/encrypt_file.rb +140 -0
- data/lib/travis/cli/endpoint.rb +35 -0
- data/lib/travis/cli/env.rb +66 -0
- data/lib/travis/cli/help.rb +23 -0
- data/lib/travis/cli/history.rb +49 -0
- data/lib/travis/cli/init.rb +82 -0
- data/lib/travis/cli/lint.rb +49 -0
- data/lib/travis/cli/login.rb +76 -0
- data/lib/travis/cli/logout.rb +14 -0
- data/lib/travis/cli/logs.rb +65 -0
- data/lib/travis/cli/monitor.rb +111 -0
- data/lib/travis/cli/open.rb +39 -0
- data/lib/travis/cli/parser.rb +43 -0
- data/lib/travis/cli/pubkey.rb +30 -0
- data/lib/travis/cli/raw.rb +20 -0
- data/lib/travis/cli/repo_command.rb +154 -0
- data/lib/travis/cli/report.rb +101 -0
- data/lib/travis/cli/repos.rb +53 -0
- data/lib/travis/cli/requests.rb +47 -0
- data/lib/travis/cli/restart.rb +18 -0
- data/lib/travis/cli/settings.rb +79 -0
- data/lib/travis/cli/setup/anynines.rb +21 -0
- data/lib/travis/cli/setup/appfog.rb +19 -0
- data/lib/travis/cli/setup/artifacts.rb +23 -0
- data/lib/travis/cli/setup/biicode.rb +19 -0
- data/lib/travis/cli/setup/cloud_66.rb +20 -0
- data/lib/travis/cli/setup/cloud_control.rb +21 -0
- data/lib/travis/cli/setup/cloud_files.rb +20 -0
- data/lib/travis/cli/setup/cloud_foundry.rb +23 -0
- data/lib/travis/cli/setup/code_deploy.rb +55 -0
- data/lib/travis/cli/setup/deis.rb +20 -0
- data/lib/travis/cli/setup/divshot.rb +18 -0
- data/lib/travis/cli/setup/elastic_beanstalk.rb +23 -0
- data/lib/travis/cli/setup/engine_yard.rb +24 -0
- data/lib/travis/cli/setup/gcs.rb +22 -0
- data/lib/travis/cli/setup/hackage.rb +18 -0
- data/lib/travis/cli/setup/heroku.rb +20 -0
- data/lib/travis/cli/setup/modulus.rb +18 -0
- data/lib/travis/cli/setup/ninefold.rb +20 -0
- data/lib/travis/cli/setup/nodejitsu.rb +27 -0
- data/lib/travis/cli/setup/npm.rb +20 -0
- data/lib/travis/cli/setup/open_shift.rb +20 -0
- data/lib/travis/cli/setup/opsworks.rb +22 -0
- data/lib/travis/cli/setup/pypi.rb +22 -0
- data/lib/travis/cli/setup/releases.rb +35 -0
- data/lib/travis/cli/setup/ruby_gems.rb +25 -0
- data/lib/travis/cli/setup/s3.rb +25 -0
- data/lib/travis/cli/setup/sauce_connect.rb +21 -0
- data/lib/travis/cli/setup/service.rb +73 -0
- data/lib/travis/cli/setup.rb +66 -0
- data/lib/travis/cli/show.rb +57 -0
- data/lib/travis/cli/sshkey.rb +118 -0
- data/lib/travis/cli/status.rb +19 -0
- data/lib/travis/cli/sync.rb +30 -0
- data/lib/travis/cli/token.rb +14 -0
- data/lib/travis/cli/version.rb +17 -0
- data/lib/travis/cli/whatsup.rb +30 -0
- data/lib/travis/cli/whoami.rb +15 -0
- data/lib/travis/cli.rb +126 -0
- data/lib/travis/client/account.rb +56 -0
- data/lib/travis/client/artifact.rb +88 -0
- data/lib/travis/client/auto_login.rb +45 -0
- data/lib/travis/client/broadcast.rb +14 -0
- data/lib/travis/client/build.rb +47 -0
- data/lib/travis/client/cache.rb +25 -0
- data/lib/travis/client/commit.rb +28 -0
- data/lib/travis/client/entity.rb +238 -0
- data/lib/travis/client/env_var.rb +102 -0
- data/lib/travis/client/error.rb +38 -0
- data/lib/travis/client/has_uuid.rb +13 -0
- data/lib/travis/client/job.rb +61 -0
- data/lib/travis/client/lint_result.rb +25 -0
- data/lib/travis/client/listener.rb +183 -0
- data/lib/travis/client/methods.rb +104 -0
- data/lib/travis/client/namespace.rb +85 -0
- data/lib/travis/client/not_loadable.rb +13 -0
- data/lib/travis/client/repository.rb +224 -0
- data/lib/travis/client/request.rb +36 -0
- data/lib/travis/client/restartable.rb +23 -0
- data/lib/travis/client/session.rb +339 -0
- data/lib/travis/client/settings.rb +25 -0
- data/lib/travis/client/singleton_setting.rb +36 -0
- data/lib/travis/client/ssh_key.rb +11 -0
- data/lib/travis/client/states.rb +98 -0
- data/lib/travis/client/user.rb +67 -0
- data/lib/travis/client/weak_entity.rb +26 -0
- data/lib/travis/client.rb +38 -0
- data/lib/travis/pro/auto_login.rb +3 -0
- data/lib/travis/pro.rb +5 -0
- data/lib/travis/tools/assets.rb +21 -0
- data/lib/travis/tools/completion.rb +54 -0
- data/lib/travis/tools/formatter.rb +50 -0
- data/lib/travis/tools/github.rb +293 -0
- data/lib/travis/tools/notification.rb +69 -0
- data/lib/travis/tools/safe_string.rb +22 -0
- data/lib/travis/tools/ssl_key.rb +48 -0
- data/lib/travis/tools/system.rb +88 -0
- data/lib/travis/version.rb +3 -0
- data/lib/travis.rb +8 -0
- data/spec/cli/api_command_spec.rb +38 -0
- data/spec/cli/cancel_spec.rb +15 -0
- data/spec/cli/encrypt_spec.rb +49 -0
- data/spec/cli/endpoint_spec.rb +39 -0
- data/spec/cli/help_spec.rb +33 -0
- data/spec/cli/history_spec.rb +38 -0
- data/spec/cli/init_spec.rb +227 -0
- data/spec/cli/login_spec.rb +13 -0
- data/spec/cli/logs_spec.rb +8 -0
- data/spec/cli/open_spec.rb +33 -0
- data/spec/cli/repo_command_spec.rb +25 -0
- data/spec/cli/restart_spec.rb +15 -0
- data/spec/cli/setup_spec.rb +5 -0
- data/spec/cli/show_spec.rb +9 -0
- data/spec/cli/status_spec.rb +28 -0
- data/spec/cli/token_spec.rb +22 -0
- data/spec/cli/version_spec.rb +18 -0
- data/spec/cli/whoami_spec.rb +34 -0
- data/spec/client/account_spec.rb +32 -0
- data/spec/client/auto_login_spec.rb +25 -0
- data/spec/client/broadcast_spec.rb +10 -0
- data/spec/client/build_spec.rb +31 -0
- data/spec/client/commit_spec.rb +22 -0
- data/spec/client/job_spec.rb +30 -0
- data/spec/client/methods_spec.rb +15 -0
- data/spec/client/namespace_spec.rb +19 -0
- data/spec/client/repository_spec.rb +39 -0
- data/spec/client/session_spec.rb +165 -0
- data/spec/client/user_spec.rb +16 -0
- data/spec/client_spec.rb +17 -0
- data/spec/pro_spec.rb +10 -0
- data/spec/spec_helper.rb +29 -0
- data/spec/support/fake_api.rb +731 -0
- data/spec/support/fake_github.rb +24 -0
- data/spec/support/fake_travis_config.yml +14 -0
- data/spec/support/helpers.rb +45 -0
- data/spec/travis_spec.rb +10 -0
- data/travis.gemspec +371 -0
- metadata +534 -0
|
@@ -0,0 +1,422 @@
|
|
|
1
|
+
require 'travis/cli'
|
|
2
|
+
require 'travis/tools/system'
|
|
3
|
+
require 'travis/tools/formatter'
|
|
4
|
+
require 'travis/tools/assets'
|
|
5
|
+
require 'travis/tools/completion'
|
|
6
|
+
require 'travis/version'
|
|
7
|
+
|
|
8
|
+
require 'highline'
|
|
9
|
+
require 'forwardable'
|
|
10
|
+
require 'yaml'
|
|
11
|
+
require 'timeout'
|
|
12
|
+
|
|
13
|
+
module Travis
|
|
14
|
+
module CLI
|
|
15
|
+
class Command
|
|
16
|
+
MINUTE = 60
|
|
17
|
+
HOUR = 3600
|
|
18
|
+
DAY = 86400
|
|
19
|
+
WEEK = 604800
|
|
20
|
+
|
|
21
|
+
include Tools::Assets
|
|
22
|
+
extend Parser, Forwardable, Tools::Assets
|
|
23
|
+
def_delegators :terminal, :agree, :ask, :choose
|
|
24
|
+
|
|
25
|
+
HighLine.use_color = Tools::System.unix? && $stdout.tty?
|
|
26
|
+
HighLine.color_scheme = HighLine::ColorScheme.new do |cs|
|
|
27
|
+
cs[:command] = [ :bold ]
|
|
28
|
+
cs[:error] = [ :red ]
|
|
29
|
+
cs[:important] = [ :bold, :underline ]
|
|
30
|
+
cs[:success] = [ :green ]
|
|
31
|
+
cs[:info] = [ :yellow ]
|
|
32
|
+
cs[:debug] = [ :magenta ]
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
on('-h', '--help', 'Display help') do |c, _|
|
|
36
|
+
c.say c.help
|
|
37
|
+
exit
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
on('-i', '--[no-]interactive', "be interactive and colorful") do |c, v|
|
|
41
|
+
HighLine.use_color = v if Tools::System.unix?
|
|
42
|
+
c.force_interactive = v
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
on('-E', '--[no-]explode', "don't rescue exceptions")
|
|
46
|
+
on('--skip-version-check', "don't check if travis client is up to date")
|
|
47
|
+
on('--skip-completion-check', "don't check if auto-completion is set up")
|
|
48
|
+
|
|
49
|
+
def self.command_name
|
|
50
|
+
name[/[^:]*$/].split(/(?=[A-Z])/).map(&:downcase).join('-')
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
@@abstract ||= [Command] # ignore the man behind the courtains!
|
|
54
|
+
def self.abstract?
|
|
55
|
+
@@abstract.include? self
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def self.abstract
|
|
59
|
+
@@abstract << self
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def self.skip(*names)
|
|
63
|
+
names.each { |n| define_method(n) {} }
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def self.description(description = nil)
|
|
67
|
+
@description = description if description
|
|
68
|
+
@description ||= ""
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def self.subcommands(*list)
|
|
72
|
+
return @subcommands ||= [] if list.empty?
|
|
73
|
+
@subcommands = list
|
|
74
|
+
|
|
75
|
+
define_method :run do |subcommand, *args|
|
|
76
|
+
error "Unknown subcommand. Available: #{list.join(', ')}." unless list.include? subcommand.to_sym
|
|
77
|
+
send(subcommand, *args)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
define_method :usage do
|
|
81
|
+
usages = list.map { |c| color(usage_for("#{command_name} #{c}", c), :command) }
|
|
82
|
+
"\nUsage: #{usages.join("\n ")}\n\n"
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
attr_accessor :arguments, :config, :force_interactive, :formatter, :debug
|
|
87
|
+
attr_reader :input, :output
|
|
88
|
+
alias_method :debug?, :debug
|
|
89
|
+
|
|
90
|
+
def initialize(options = {})
|
|
91
|
+
@on_signal = []
|
|
92
|
+
@formatter = Travis::Tools::Formatter.new
|
|
93
|
+
self.output = $stdout
|
|
94
|
+
self.input = $stdin
|
|
95
|
+
options.each do |key, value|
|
|
96
|
+
public_send("#{key}=", value) if respond_to? "#{key}="
|
|
97
|
+
end
|
|
98
|
+
@arguments ||= []
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def terminal
|
|
102
|
+
@terminal ||= HighLine.new(input, output)
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def input=(io)
|
|
106
|
+
@terminal = nil
|
|
107
|
+
@input = io
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def output=(io)
|
|
111
|
+
@terminal = nil
|
|
112
|
+
@output = io
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def write_to(io)
|
|
116
|
+
io_was, self.output = output, io
|
|
117
|
+
yield
|
|
118
|
+
ensure
|
|
119
|
+
self.output = io_was if io_was
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def parse(args)
|
|
123
|
+
rest = parser.parse(args)
|
|
124
|
+
arguments.concat(rest)
|
|
125
|
+
rescue OptionParser::ParseError => e
|
|
126
|
+
error e.message
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
def setup
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def last_check
|
|
133
|
+
config['last_check'] ||= {
|
|
134
|
+
# migrate from old values
|
|
135
|
+
'at' => config.delete('last_version_check'),
|
|
136
|
+
'etag' => config.delete('etag')
|
|
137
|
+
}
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
def check_version
|
|
141
|
+
last_check.clear if last_check['version'] != Travis::VERSION
|
|
142
|
+
seconds_since = Time.now.to_i - last_check['at'].to_i
|
|
143
|
+
|
|
144
|
+
return if skip_version_check?
|
|
145
|
+
return if seconds_since < MINUTE
|
|
146
|
+
|
|
147
|
+
case seconds_since
|
|
148
|
+
when MINUTE .. HOUR then timeout = 0.5
|
|
149
|
+
when HOUR .. DAY then timeout = 1.0
|
|
150
|
+
when DAY .. WEEK then timeout = 2.0
|
|
151
|
+
else timeout = 10.0
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
Timeout.timeout(timeout) do
|
|
155
|
+
response = Faraday.get('https://rubygems.org/api/v1/gems/travis.json', {}, 'If-None-Match' => last_check['etag'].to_s)
|
|
156
|
+
last_check['etag'] = response.headers['etag']
|
|
157
|
+
last_check['version'] = JSON.parse(response.body)['version'] if response.status == 200
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
last_check['at'] = Time.now.to_i
|
|
161
|
+
unless Tools::System.recent_version? Travis::VERSION, last_check['version']
|
|
162
|
+
warn "Outdated CLI version, run `gem install travis`."
|
|
163
|
+
end
|
|
164
|
+
rescue Timeout::Error, Faraday::Error::ClientError => error
|
|
165
|
+
debug "#{error.class}: #{error.message}"
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
def check_completion
|
|
169
|
+
return if skip_completion_check? or !interactive?
|
|
170
|
+
|
|
171
|
+
if config['checked_completion']
|
|
172
|
+
Tools::Completion.update_completion if config['completion_version'] != Travis::VERSION
|
|
173
|
+
else
|
|
174
|
+
write_to($stderr) do
|
|
175
|
+
next Tools::Completion.update_completion if Tools::Completion.completion_installed?
|
|
176
|
+
next unless agree('Shell completion not installed. Would you like to install it now? ') { |q| q.default = "y" }
|
|
177
|
+
Tools::Completion.install_completion
|
|
178
|
+
end
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
config['checked_completion'] = true
|
|
182
|
+
config['completion_version'] = Travis::VERSION
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
def check_ruby
|
|
186
|
+
return if RUBY_VERSION > '1.9.2' or skip_version_check?
|
|
187
|
+
warn "Your Ruby version is outdated, please consider upgrading, as we will drop support for #{RUBY_VERSION} soon!"
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
def execute
|
|
191
|
+
setup_trap
|
|
192
|
+
check_ruby
|
|
193
|
+
check_arity(method(:run), *arguments)
|
|
194
|
+
load_config
|
|
195
|
+
check_version
|
|
196
|
+
check_completion
|
|
197
|
+
setup
|
|
198
|
+
run(*arguments)
|
|
199
|
+
clear_error
|
|
200
|
+
store_config
|
|
201
|
+
rescue Travis::Client::NotLoggedIn => e
|
|
202
|
+
raise(e) if explode?
|
|
203
|
+
error "#{e.message} - try running #{command("login#{endpoint_option}")}"
|
|
204
|
+
rescue Travis::Client::NotFound => e
|
|
205
|
+
raise(e) if explode?
|
|
206
|
+
error "resource not found (#{e.message})"
|
|
207
|
+
rescue Travis::Client::Error => e
|
|
208
|
+
raise(e) if explode?
|
|
209
|
+
error e.message
|
|
210
|
+
rescue StandardError => e
|
|
211
|
+
raise(e) if explode?
|
|
212
|
+
message = e.message
|
|
213
|
+
message += color("\nfor a full error report, run #{command("report#{endpoint_option}")}", :error) if interactive?
|
|
214
|
+
store_error(e)
|
|
215
|
+
error(message)
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
def command_name
|
|
219
|
+
self.class.command_name
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
def usage
|
|
223
|
+
"Usage: " << color(usage_for(command_name, :run), :command)
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
def usage_for(prefix, method)
|
|
227
|
+
usage = "travis #{prefix}"
|
|
228
|
+
method = method(method)
|
|
229
|
+
if method.respond_to? :parameters
|
|
230
|
+
method.parameters.each do |type, name|
|
|
231
|
+
name = name.upcase
|
|
232
|
+
name = "[#{name}]" if type == :opt
|
|
233
|
+
name = "[#{name}..]" if type == :rest
|
|
234
|
+
usage << " #{name}"
|
|
235
|
+
end
|
|
236
|
+
elsif method.arity != 0
|
|
237
|
+
usage << " ..."
|
|
238
|
+
end
|
|
239
|
+
usage << " [OPTIONS]"
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
def help(info = "")
|
|
243
|
+
parser.banner = usage
|
|
244
|
+
self.class.description.sub(/./) { |c| c.upcase } + ".\n" + info + parser.to_s
|
|
245
|
+
end
|
|
246
|
+
|
|
247
|
+
def say(data, format = nil, style = nil)
|
|
248
|
+
terminal.say format(data, format, style)
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
def debug(line)
|
|
252
|
+
return unless debug?
|
|
253
|
+
write_to($stderr) do
|
|
254
|
+
say color("** #{line}", :debug)
|
|
255
|
+
end
|
|
256
|
+
end
|
|
257
|
+
|
|
258
|
+
def time(info, callback = Proc.new)
|
|
259
|
+
return callback.call unless debug?
|
|
260
|
+
start = Time.now
|
|
261
|
+
debug(info)
|
|
262
|
+
callback.call
|
|
263
|
+
duration = Time.now - start
|
|
264
|
+
debug(" took %.2g seconds" % duration)
|
|
265
|
+
end
|
|
266
|
+
|
|
267
|
+
def info(line)
|
|
268
|
+
write_to($stderr) do
|
|
269
|
+
say color(line, :info)
|
|
270
|
+
end
|
|
271
|
+
end
|
|
272
|
+
|
|
273
|
+
def on_signal(&block)
|
|
274
|
+
@on_signal << block
|
|
275
|
+
end
|
|
276
|
+
|
|
277
|
+
private
|
|
278
|
+
|
|
279
|
+
def store_error(exception)
|
|
280
|
+
message = "An error occurred running `travis %s%s`:\n %p: %s\n" % [command_name, endpoint_option, exception.class, exception.message]
|
|
281
|
+
exception.backtrace.each { |l| message << " from #{l}\n" }
|
|
282
|
+
save_file("error.log", message)
|
|
283
|
+
end
|
|
284
|
+
|
|
285
|
+
def clear_error
|
|
286
|
+
delete_file("error.log")
|
|
287
|
+
end
|
|
288
|
+
|
|
289
|
+
def setup_trap
|
|
290
|
+
[:INT, :TERM].each do |signal|
|
|
291
|
+
trap signal do
|
|
292
|
+
@on_signal.each { |c| c.call }
|
|
293
|
+
exit 1
|
|
294
|
+
end
|
|
295
|
+
end
|
|
296
|
+
end
|
|
297
|
+
|
|
298
|
+
def format(data, format = nil, style = nil)
|
|
299
|
+
style ||= :important
|
|
300
|
+
data = format % color(data, style) if format and interactive?
|
|
301
|
+
data = data.gsub(/<\[\[/, '<%=').gsub(/\]\]>/, '%>')
|
|
302
|
+
data.encode! 'utf-8' if data.respond_to? :encode!
|
|
303
|
+
data
|
|
304
|
+
end
|
|
305
|
+
|
|
306
|
+
def template(*args)
|
|
307
|
+
File.read(*args).split('__END__', 2)[1].strip
|
|
308
|
+
end
|
|
309
|
+
|
|
310
|
+
def color(line, style)
|
|
311
|
+
return line.to_s unless interactive?
|
|
312
|
+
terminal.color(line || '???', Array(style).map(&:to_sym))
|
|
313
|
+
end
|
|
314
|
+
|
|
315
|
+
def interactive?(io = output)
|
|
316
|
+
return io.tty? if force_interactive.nil?
|
|
317
|
+
force_interactive
|
|
318
|
+
end
|
|
319
|
+
|
|
320
|
+
def empty_line
|
|
321
|
+
say "\n"
|
|
322
|
+
end
|
|
323
|
+
|
|
324
|
+
def warn(message)
|
|
325
|
+
write_to($stderr) do
|
|
326
|
+
say color(message, :error)
|
|
327
|
+
yield if block_given?
|
|
328
|
+
end
|
|
329
|
+
end
|
|
330
|
+
|
|
331
|
+
def error(message, &block)
|
|
332
|
+
warn(message, &block)
|
|
333
|
+
exit 1
|
|
334
|
+
end
|
|
335
|
+
|
|
336
|
+
def command(name)
|
|
337
|
+
color("#{File.basename($0)} #{name}", :command)
|
|
338
|
+
end
|
|
339
|
+
|
|
340
|
+
def success(line)
|
|
341
|
+
say color(line, :success) if interactive?
|
|
342
|
+
end
|
|
343
|
+
|
|
344
|
+
def config_path(name)
|
|
345
|
+
path = ENV.fetch('TRAVIS_CONFIG_PATH') { File.expand_path('.travis', Dir.home) }
|
|
346
|
+
Dir.mkdir(path, 0700) unless File.directory? path
|
|
347
|
+
File.join(path, name)
|
|
348
|
+
end
|
|
349
|
+
|
|
350
|
+
def load_file(name, default = nil)
|
|
351
|
+
return default unless path = config_path(name) and File.exist? path
|
|
352
|
+
debug "Loading %p" % path
|
|
353
|
+
File.read(path)
|
|
354
|
+
end
|
|
355
|
+
|
|
356
|
+
def delete_file(name)
|
|
357
|
+
return unless path = config_path(name) and File.exist? path
|
|
358
|
+
debug "Deleting %p" % path
|
|
359
|
+
File.delete(path)
|
|
360
|
+
end
|
|
361
|
+
|
|
362
|
+
def save_file(name, content, read_only = false)
|
|
363
|
+
path = config_path(name)
|
|
364
|
+
debug "Storing %p" % path
|
|
365
|
+
File.open(path, 'w') do |file|
|
|
366
|
+
file.write(content.to_s)
|
|
367
|
+
file.chmod(0600) if read_only
|
|
368
|
+
end
|
|
369
|
+
end
|
|
370
|
+
|
|
371
|
+
YAML_ERROR = defined?(Psych::SyntaxError) ? Psych::SyntaxError : ArgumentError
|
|
372
|
+
def load_config
|
|
373
|
+
@config = YAML.load load_file('config.yml', '{}')
|
|
374
|
+
@config ||= {}
|
|
375
|
+
@original_config = @config.dup
|
|
376
|
+
rescue YAML_ERROR => error
|
|
377
|
+
raise error if explode?
|
|
378
|
+
warn "Broken config file: #{color config_path('config.yml'), :bold}"
|
|
379
|
+
exit 1 unless interactive? and agree("Remove config file? ") { |q| q.default = "no" }
|
|
380
|
+
@original_config, @config = {}, {}
|
|
381
|
+
end
|
|
382
|
+
|
|
383
|
+
def store_config
|
|
384
|
+
save_file('config.yml', @config.to_yaml, true)
|
|
385
|
+
end
|
|
386
|
+
|
|
387
|
+
def check_arity(method, *args)
|
|
388
|
+
return unless method.respond_to? :parameters
|
|
389
|
+
method.parameters.each do |type, name|
|
|
390
|
+
return if type == :rest
|
|
391
|
+
wrong_args("few") unless args.shift or type == :opt or type == :block
|
|
392
|
+
end
|
|
393
|
+
wrong_args("many") if args.any?
|
|
394
|
+
end
|
|
395
|
+
|
|
396
|
+
def danger_zone?(message)
|
|
397
|
+
agree(color("DANGER ZONE: ", [:red, :bold]) << message << " ") { |q| q.default = "no" }
|
|
398
|
+
end
|
|
399
|
+
|
|
400
|
+
def write_file(file, content, force = false)
|
|
401
|
+
error "#{file} already exists" unless write_file?(file, force)
|
|
402
|
+
File.write(file, content)
|
|
403
|
+
end
|
|
404
|
+
|
|
405
|
+
def write_file?(file, force)
|
|
406
|
+
return true if force or not File.exist?(file)
|
|
407
|
+
return false unless interactive?
|
|
408
|
+
danger_zone? "Override existing #{color(file, :info)}?"
|
|
409
|
+
end
|
|
410
|
+
|
|
411
|
+
def wrong_args(quantity)
|
|
412
|
+
error "too #{quantity} arguments" do
|
|
413
|
+
say help
|
|
414
|
+
end
|
|
415
|
+
end
|
|
416
|
+
|
|
417
|
+
def endpoint_option
|
|
418
|
+
""
|
|
419
|
+
end
|
|
420
|
+
end
|
|
421
|
+
end
|
|
422
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
require 'travis/cli'
|
|
2
|
+
|
|
3
|
+
module Travis
|
|
4
|
+
module CLI
|
|
5
|
+
class Console < ApiCommand
|
|
6
|
+
description "interactive shell"
|
|
7
|
+
on '-x', '--eval LINE', 'run line of ruby' do |c, line|
|
|
8
|
+
c.instance_eval(line)
|
|
9
|
+
exit
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def run
|
|
13
|
+
return unless pry_installed?
|
|
14
|
+
|
|
15
|
+
Object.send(:include, Client::Namespace.new(session))
|
|
16
|
+
hooks = defined?(Pry::Hooks) ? Pry::Hooks.new : {}
|
|
17
|
+
binding.pry(:quiet => true, :prompt => Pry::SIMPLE_PROMPT, :output => $stdout, :hooks => hooks)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
private
|
|
21
|
+
|
|
22
|
+
def pry_installed?
|
|
23
|
+
require 'pry'
|
|
24
|
+
true
|
|
25
|
+
rescue LoadError
|
|
26
|
+
$stderr.puts 'You need to install pry to use Travis CLI console. Try'
|
|
27
|
+
$stderr.puts
|
|
28
|
+
$stderr.puts '$ (sudo) gem install pry'
|
|
29
|
+
false
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
require 'travis/cli'
|
|
2
|
+
|
|
3
|
+
module Travis
|
|
4
|
+
module CLI
|
|
5
|
+
class Enable < RepoCommand
|
|
6
|
+
description "enables a project"
|
|
7
|
+
on('-s', '--skip-sync', "don't trigger a sync if the repo is unknown")
|
|
8
|
+
|
|
9
|
+
def run
|
|
10
|
+
authenticate
|
|
11
|
+
error "not allowed to update service hook for #{color(repository.slug, :bold)}" unless repository.admin?
|
|
12
|
+
repository.enable
|
|
13
|
+
say "enabled", color("#{slug}: %s :)", :success)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
private
|
|
17
|
+
|
|
18
|
+
def repository
|
|
19
|
+
repo(slug)
|
|
20
|
+
rescue Travis::Client::NotFound
|
|
21
|
+
unless skip_sync?
|
|
22
|
+
say "repository not known to Travis CI (or no access?)"
|
|
23
|
+
say "triggering sync: "
|
|
24
|
+
sync
|
|
25
|
+
say " done"
|
|
26
|
+
end
|
|
27
|
+
super
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
require 'travis/cli'
|
|
3
|
+
|
|
4
|
+
module Travis
|
|
5
|
+
module CLI
|
|
6
|
+
class Encrypt < RepoCommand
|
|
7
|
+
description "encrypts values for the .travis.yml"
|
|
8
|
+
attr_accessor :config_key
|
|
9
|
+
|
|
10
|
+
on('-a', '--add [KEY]', 'adds it to .travis.yml under KEY (default: env.global)') do |c, value|
|
|
11
|
+
c.config_key = value || 'env.global'
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
on('-s', '--[no-]split', "treat each line as a separate input")
|
|
15
|
+
on('-p', '--append', "don't override existing values, instead treat as list")
|
|
16
|
+
on('-x', '--override', "override existing value")
|
|
17
|
+
|
|
18
|
+
def run(*args)
|
|
19
|
+
error "cannot combine --override and --append" if append? and override?
|
|
20
|
+
error "--append without --add makes no sense" if append? and not add?
|
|
21
|
+
error "--override without --add makes no sense" if override? and not add?
|
|
22
|
+
self.override |= !config_key.start_with?('env.') if add? and not append?
|
|
23
|
+
|
|
24
|
+
if args.first =~ %r{\w+/\w+} && !args.first.include?("=")
|
|
25
|
+
warn "WARNING: The name of the repository is now passed to the command with the -r option:"
|
|
26
|
+
warn " #{command("encrypt [...] -r #{args.first}")}"
|
|
27
|
+
warn " If you tried to pass the name of the repository as the first argument, you"
|
|
28
|
+
warn " probably won't get the results you wanted.\n"
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
data = args.join(" ")
|
|
32
|
+
|
|
33
|
+
if data.empty?
|
|
34
|
+
say color("Reading from stdin, press Ctrl+D when done", :info) if $stdin.tty?
|
|
35
|
+
data = $stdin.read
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
data = split? ? data.split("\n") : [data.strip]
|
|
39
|
+
warn_env_assignments(data)
|
|
40
|
+
encrypted = data.map { |data| repository.encrypt(data) }
|
|
41
|
+
|
|
42
|
+
if config_key
|
|
43
|
+
set_config encrypted.map { |e| { 'secure' => e } }
|
|
44
|
+
save_travis_config
|
|
45
|
+
else
|
|
46
|
+
list = encrypted.map { |data| format(data.inspect, " secure: %s") }
|
|
47
|
+
say(list.join("\n"), template(__FILE__), :none)
|
|
48
|
+
end
|
|
49
|
+
rescue OpenSSL::PKey::RSAError => error
|
|
50
|
+
error "#{error.message.sub(" for key size", "")} - consider using " <<
|
|
51
|
+
color("travis encrypt-file", [:red, :bold]) <<
|
|
52
|
+
color(" or ", :red) <<
|
|
53
|
+
color("travis env set", [:red, :bold])
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
private
|
|
57
|
+
|
|
58
|
+
def add?
|
|
59
|
+
!!config_key
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def set_config(result)
|
|
63
|
+
parent_config[last_key] = merge_config(result)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def merge_config(result)
|
|
67
|
+
case subconfig = (parent_config[last_key] unless override?)
|
|
68
|
+
when nil then result.size == 1 ? result.first : result
|
|
69
|
+
when Array then subconfig + result
|
|
70
|
+
else result.unshift(subconfig)
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def subconfig
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def key_chain
|
|
78
|
+
@key_chain ||= config_key.split('.')
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def last_key
|
|
82
|
+
key_chain.last
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def parent_config
|
|
86
|
+
@parent_config ||= traverse_config(travis_config, *key_chain[0..-2])
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def traverse_config(hash, key = nil, *rest)
|
|
90
|
+
return hash unless key
|
|
91
|
+
|
|
92
|
+
hash[key] = case value = hash[key]
|
|
93
|
+
when nil then {}
|
|
94
|
+
when Hash then value
|
|
95
|
+
else { 'matrix' => Array(value) }
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
traverse_config(hash[key], *rest)
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def warn_env_assignments(data)
|
|
102
|
+
if /env/.match(config_key) && data.find { |d| /=/.match(d).nil? }
|
|
103
|
+
warn "Environment variables in #{config_key} should be formatted as FOO=bar"
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
__END__
|
|
111
|
+
Please add the following to your <[[ color('.travis.yml', :info) ]]> file:
|
|
112
|
+
|
|
113
|
+
%s
|
|
114
|
+
|
|
115
|
+
Pro Tip: You can add it automatically by running with <[[ color('--add', :info) ]]>.
|