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,140 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
require 'travis/cli'
|
|
3
|
+
require 'travis/tools/system'
|
|
4
|
+
|
|
5
|
+
require 'securerandom'
|
|
6
|
+
require 'openssl'
|
|
7
|
+
require 'digest'
|
|
8
|
+
require 'shellwords'
|
|
9
|
+
|
|
10
|
+
module Travis
|
|
11
|
+
module CLI
|
|
12
|
+
class EncryptFile < RepoCommand
|
|
13
|
+
attr_accessor :stage
|
|
14
|
+
description 'encrypts a file and adds decryption steps to .travis.yml'
|
|
15
|
+
on '-K', '--key KEY', 'encryption key to be used (randomly generated otherwise)'
|
|
16
|
+
on '--iv IV', 'encryption IV to be used (randomly generated otherwise)'
|
|
17
|
+
on '-d', '--decrypt', 'decrypt the file instead of encrypting it, requires key and iv'
|
|
18
|
+
on '-f', '--force', 'override output file if it exists'
|
|
19
|
+
on '-p', '--print-key', 'print (possibly generated) key and iv'
|
|
20
|
+
on '-w', '--decrypt-to PATH', 'where to write the decrypted file to on the Travis CI VM'
|
|
21
|
+
on '-a', '--add [STAGE]', 'automatically add command to .travis.yml (default stage is before_install)' do |c, stage|
|
|
22
|
+
c.stage = stage || 'before_install'
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def run(input_path, output_path = nil)
|
|
26
|
+
self.decrypt_to ||= decrypt_to_for(input_path)
|
|
27
|
+
output_path ||= File.basename(output_path_for(input_path))
|
|
28
|
+
self.output = $stdout.tty? ? StringIO.new : $stderr if output_path == '-'
|
|
29
|
+
result = transcode(input_path)
|
|
30
|
+
|
|
31
|
+
if output_path == '-'
|
|
32
|
+
$stdout.puts result
|
|
33
|
+
else
|
|
34
|
+
say "storing result as #{color(output_path, :info)}"
|
|
35
|
+
write_file(output_path, result, force)
|
|
36
|
+
return if decrypt?
|
|
37
|
+
|
|
38
|
+
error "requires --decrypt-to option when reading from stdin" unless decrypt_to?
|
|
39
|
+
|
|
40
|
+
set_env_vars
|
|
41
|
+
|
|
42
|
+
command = decrypt_command(output_path)
|
|
43
|
+
stage ? store_command(command) : print_command(command)
|
|
44
|
+
|
|
45
|
+
notes(input_path, output_path)
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def setup
|
|
50
|
+
super
|
|
51
|
+
self.key ||= SecureRandom.hex(32) unless decrypt?
|
|
52
|
+
self.iv ||= SecureRandom.hex(16) unless decrypt?
|
|
53
|
+
error "key must be 64 characters long and a valid hex number" unless key =~ /^[a-f0-9]{64}$/
|
|
54
|
+
error "iv must be 32 characters long and a valid hex number" unless iv =~ /^[a-f0-9]{32}$/
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def print_command(command)
|
|
58
|
+
empty_line
|
|
59
|
+
say command, template(__FILE__)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def store_command(command)
|
|
63
|
+
travis_config[stage] = Array(travis_config[stage])
|
|
64
|
+
travis_config[stage].delete(command)
|
|
65
|
+
travis_config[stage].unshift(command)
|
|
66
|
+
save_travis_config
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def decrypt_command(path)
|
|
70
|
+
"openssl aes-256-cbc -K $#{env_name(:key)} -iv $#{env_name(:iv)} -in #{escape_path(path)} -out #{escape_path(decrypt_to)} -d"
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def set_env_vars
|
|
74
|
+
say "storing secure env variables for decryption"
|
|
75
|
+
repository.env_vars.upsert env_name(:key), key, :public => false
|
|
76
|
+
repository.env_vars.upsert env_name(:iv), iv, :public => false
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def env_name(name)
|
|
80
|
+
@env_prefix ||= "encrypted_#{Digest.hexencode(Digest::SHA1.digest(Dir.pwd)[0..5])}"
|
|
81
|
+
"#{@env_prefix}_#{name}"
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def notes(input_path, output_path)
|
|
85
|
+
say "\nkey: #{color(key, :info)}\niv: #{color(iv, :info)}" if print_key?
|
|
86
|
+
empty_line
|
|
87
|
+
say "Make sure to add #{color(output_path, :info)} to the git repository."
|
|
88
|
+
say "Make sure #{color("not", :underline)} to add #{color(input_path, :info)} to the git repository." if input_path != '-'
|
|
89
|
+
say "Commit all changes to your #{color('.travis.yml', :info)}."
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def transcode(input_path)
|
|
93
|
+
description = "stdin#{' (waiting for input)' if $stdin.tty?}" if input_path == '-'
|
|
94
|
+
say "#{decrypt ? "de" : "en"}crypting #{color(description || input_path, :info)} for #{color(slug, :info)}"
|
|
95
|
+
|
|
96
|
+
data = input_path == '-' ? $stdin.read : File.binread(input_path)
|
|
97
|
+
aes = OpenSSL::Cipher.new('AES-256-CBC')
|
|
98
|
+
decrypt ? aes.decrypt : aes.encrypt
|
|
99
|
+
aes.key = [key].pack('H*')
|
|
100
|
+
aes.iv = [iv].pack('H*')
|
|
101
|
+
|
|
102
|
+
aes.update(data) + aes.final
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def decrypt_to_for(input_path)
|
|
106
|
+
return if input_path == '-'
|
|
107
|
+
if input_path.start_with? Dir.home
|
|
108
|
+
input_path.sub(Dir.home, '~')
|
|
109
|
+
else
|
|
110
|
+
input_path
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def escape_path(path)
|
|
115
|
+
Shellwords.escape(path).sub(/^\\~\//, '~\/')
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def output_path_for(input_path)
|
|
119
|
+
case input_path
|
|
120
|
+
when '-' then return '-'
|
|
121
|
+
when /^(.+)\.enc$/ then return $1 if decrypt?
|
|
122
|
+
when /^(.+)\.dec$/ then return $1 unless decrypt?
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
if interactive? and input_path =~ /(\.enc|\.dec)$/
|
|
126
|
+
exit 1 unless danger_zone? "File extension of input file is #{color($1, :info)}, are you sure that is correct?"
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
"#{input_path}.#{decrypt ? 'dec' : 'enc'}"
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
__END__
|
|
136
|
+
Please add the following to your build script (<[[ color('before_install', :info) ]]> stage in your <[[ color('.travis.yml', :info) ]]>, for instance):
|
|
137
|
+
|
|
138
|
+
%s
|
|
139
|
+
|
|
140
|
+
Pro Tip: You can add it automatically by running with <[[ color('--add', :info) ]]>.
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
require 'travis/cli'
|
|
2
|
+
|
|
3
|
+
module Travis
|
|
4
|
+
module CLI
|
|
5
|
+
class Endpoint < ApiCommand
|
|
6
|
+
description "displays or changes the API endpoint"
|
|
7
|
+
|
|
8
|
+
skip :authenticate
|
|
9
|
+
on '--drop-default', 'delete stored default endpoint'
|
|
10
|
+
on '--set-default', 'store endpoint as global default'
|
|
11
|
+
on '--github', 'display github endpoint'
|
|
12
|
+
|
|
13
|
+
def run_github
|
|
14
|
+
error "--github cannot be combined with --drop-default" if drop_default?
|
|
15
|
+
error "--github cannot be combined with --set-default" if set_default?
|
|
16
|
+
load_gh
|
|
17
|
+
say github_endpoint.to_s, "GitHub endpoint: %s"
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def run_travis
|
|
21
|
+
if drop_default? and was = config['default_endpoint']
|
|
22
|
+
config.delete('default_endpoint')
|
|
23
|
+
say was, "default API endpoint dropped (was %s)"
|
|
24
|
+
else
|
|
25
|
+
config['default_endpoint'] = api_endpoint if set_default?
|
|
26
|
+
say api_endpoint, "API endpoint: %s#{" (stored as default)" if set_default?}"
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def run
|
|
31
|
+
github? ? run_github : run_travis
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
require 'travis/cli'
|
|
2
|
+
require 'shellwords'
|
|
3
|
+
|
|
4
|
+
module Travis
|
|
5
|
+
module CLI
|
|
6
|
+
class Env < RepoCommand
|
|
7
|
+
on('-P', '--[no-]public', 'make new values public')
|
|
8
|
+
on('-p', '--[no-]private', 'make new values private') { |c,v| c.public = !v }
|
|
9
|
+
on('-u', '--[no-]unescape', 'do not escape values')
|
|
10
|
+
on('-f', '--force', 'do not ask for confirmation when clearing out all variables')
|
|
11
|
+
|
|
12
|
+
description "show or modify build environment variables"
|
|
13
|
+
subcommands :list, :set, :unset, :copy, :clear
|
|
14
|
+
|
|
15
|
+
def setup
|
|
16
|
+
super
|
|
17
|
+
authenticate
|
|
18
|
+
error "not allowed to access environment variables for #{color(repository.slug, :bold)}" unless repository.admin?
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def set(name, value)
|
|
22
|
+
options ||= { :public => public } if public != nil
|
|
23
|
+
say color('[+] ', [:green, :bold]) + "setting environment variable #{color "$#{name}", :info}"
|
|
24
|
+
value = Shellwords.escape(value) unless unescape?
|
|
25
|
+
env_vars.upsert(name, value, options || {})
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def copy(*names)
|
|
29
|
+
names.each do |name|
|
|
30
|
+
if ENV.include? name
|
|
31
|
+
set(name, ENV[name])
|
|
32
|
+
else
|
|
33
|
+
warn "missing in current environment: #{color "$#{name}", :bold}"
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def unset(*names)
|
|
39
|
+
remove_vars { |var| names.include? var.name }
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def clear
|
|
43
|
+
exit if env_vars.empty?
|
|
44
|
+
exit 1 if interactive? and not force? and not danger_zone? "Clear out all env variables for #{color(repository.slug, :bold)}?"
|
|
45
|
+
remove_vars
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def remove_vars
|
|
49
|
+
env_vars.each do |var|
|
|
50
|
+
next if block_given? and not yield(var)
|
|
51
|
+
say color('[x] ', [:red, :bold]) + "removing environment variable #{color "$#{var.name}", :info}"
|
|
52
|
+
var.delete
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def list
|
|
57
|
+
say color("# environment variables for #{color repository.slug, :bold}", :info)
|
|
58
|
+
env_vars.each { |v| say "#{v.name}=" << color(v.value || "[secure]", :bold) }
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def env_vars
|
|
62
|
+
repository.env_vars
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
require 'travis/cli'
|
|
2
|
+
|
|
3
|
+
module Travis
|
|
4
|
+
module CLI
|
|
5
|
+
class Help < Command
|
|
6
|
+
description "helps you out when in dire need of information"
|
|
7
|
+
|
|
8
|
+
def run(command = nil)
|
|
9
|
+
if command
|
|
10
|
+
say CLI.command(command).new.help
|
|
11
|
+
else
|
|
12
|
+
say "Usage: travis COMMAND ...\n\nAvailable commands:\n\n"
|
|
13
|
+
commands.each { |c| say "\t#{color(c.command_name, :command).ljust(22)} #{color(c.description, :info)}" }
|
|
14
|
+
say "\nrun `#$0 help COMMAND` for more infos"
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def commands
|
|
19
|
+
CLI.commands.sort_by { |c| c.command_name }
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
require 'travis/cli'
|
|
2
|
+
|
|
3
|
+
module Travis
|
|
4
|
+
module CLI
|
|
5
|
+
class History < RepoCommand
|
|
6
|
+
description "displays a projects build history"
|
|
7
|
+
|
|
8
|
+
on('-a', '--after BUILD', 'Only show history after a given build number')
|
|
9
|
+
on('-p', '--pull-request NUMBER', 'Only show history for the given Pull Request')
|
|
10
|
+
on('-b', '--branch BRANCH', 'Only show history for the given branch')
|
|
11
|
+
on('-l', '--limit LIMIT', 'Maximum number of history items')
|
|
12
|
+
on('-d', '--date', 'Include date in output')
|
|
13
|
+
on('-c', '--committer', 'Include committer in output')
|
|
14
|
+
on('--[no-]all', 'Display all history items')
|
|
15
|
+
|
|
16
|
+
def run
|
|
17
|
+
countdown = Integer(limit || 10) unless all?
|
|
18
|
+
params = { :after_number => after } if after
|
|
19
|
+
repository.each_build(params) do |build|
|
|
20
|
+
next unless display? build
|
|
21
|
+
display(build)
|
|
22
|
+
|
|
23
|
+
if countdown
|
|
24
|
+
countdown -= 1
|
|
25
|
+
break if countdown < 1
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
private
|
|
31
|
+
|
|
32
|
+
def display?(build)
|
|
33
|
+
return build.pr_number == pull_request if pull_request
|
|
34
|
+
return build.branch_info == branch if branch
|
|
35
|
+
true
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def display(build)
|
|
39
|
+
say [
|
|
40
|
+
date? && color(formatter.time(build.finished_at || build.started_at), build.color),
|
|
41
|
+
color("##{build.number} #{build.state}:".ljust(16), [build.color, :bold]),
|
|
42
|
+
color("#{build.branch_info}", :info),
|
|
43
|
+
committer? && build.commit.author_name.ljust(25),
|
|
44
|
+
build.commit.subject
|
|
45
|
+
].compact.join(" ").strip + "\n"
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
require 'travis/cli'
|
|
2
|
+
|
|
3
|
+
module Travis
|
|
4
|
+
module CLI
|
|
5
|
+
class Init < Enable
|
|
6
|
+
LANGUAGE_MAPPING = {
|
|
7
|
+
"node" => "node_js",
|
|
8
|
+
"node.js" => "node_js",
|
|
9
|
+
"javascript" => "node_js",
|
|
10
|
+
"coffeescript" => "node_js",
|
|
11
|
+
"c++" => "cpp",
|
|
12
|
+
"obj-c" => "objective-c"
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
description "generates a .travis.yml and enables the project"
|
|
16
|
+
|
|
17
|
+
on('-f', '--force', 'override .travis.yml if it already exists')
|
|
18
|
+
on('-k', '--skip-enable', 'do not enable project, only add .travis.yml')
|
|
19
|
+
on('-p', '--print-conf', 'print generated config instead of writing to file')
|
|
20
|
+
|
|
21
|
+
options = %w[
|
|
22
|
+
script before_script after_script after_success install before_install
|
|
23
|
+
compiler otp_release go jdk node_js perl php python rvm scala
|
|
24
|
+
env gemfile
|
|
25
|
+
]
|
|
26
|
+
|
|
27
|
+
options.each do |option|
|
|
28
|
+
on "--#{option.gsub('_', '-')} VALUE", "sets #{option} option in .travis.yml (can be used more than once)" do |c, value|
|
|
29
|
+
c.custom_config[option] &&= Array(c.custom_config[option]) << value
|
|
30
|
+
c.custom_config[option] ||= value
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
attr_writer :travis_config
|
|
35
|
+
|
|
36
|
+
def self.languages
|
|
37
|
+
Dir[asset_path('init/*.yml')].map { |f| File.basename(f, '.yml') }.sort
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def help
|
|
41
|
+
super("Available languages: #{self.class.languages.join(", ")}\n\n")
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def run(language = nil, file = '.travis.yml')
|
|
45
|
+
error "#{file} already exists, use --force to override" if File.exist?(file) and not force? and not print_conf?
|
|
46
|
+
language ||= ask('Main programming language used: ') { |q| q.default = detect_language }
|
|
47
|
+
self.travis_config = template(language).merge(custom_config)
|
|
48
|
+
|
|
49
|
+
if print_conf?
|
|
50
|
+
puts travis_config.to_yaml
|
|
51
|
+
else
|
|
52
|
+
save_travis_config(file)
|
|
53
|
+
say("#{file} file created!")
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
super() unless skip_enable?
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def custom_config
|
|
60
|
+
@custom_config ||= {}
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
private
|
|
64
|
+
|
|
65
|
+
def template_name(language)
|
|
66
|
+
asset_path "init/#{language}.yml"
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def template(language)
|
|
70
|
+
language = language.to_s.downcase
|
|
71
|
+
language = LANGUAGE_MAPPING[language] || language
|
|
72
|
+
file = template_name(language)
|
|
73
|
+
error "unknown language #{language}" unless File.exist? file
|
|
74
|
+
YAML.load_file(file)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def detect_language
|
|
78
|
+
repository.github_language || "Ruby"
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
require 'travis/cli'
|
|
2
|
+
|
|
3
|
+
module Travis
|
|
4
|
+
module CLI
|
|
5
|
+
class Lint < ApiCommand
|
|
6
|
+
description 'display warnings for a .travis.yml'
|
|
7
|
+
on '-q', '--[no-]quiet', 'does not print anything'
|
|
8
|
+
on '-x', '--[no-]exit-code', 'sets the exit code to 1 if there are warning'
|
|
9
|
+
|
|
10
|
+
def run(file = nil)
|
|
11
|
+
file ||= '.travis.yml' if $stdin.tty? or $stdin.eof?
|
|
12
|
+
|
|
13
|
+
if file and file != '-'
|
|
14
|
+
debug "reading #{file}"
|
|
15
|
+
error "file does not exist: #{color(file, :bold)}" unless File.exist? file
|
|
16
|
+
error "cannot read #{color(file, :bold)}" unless File.readable? file
|
|
17
|
+
content = File.read(file)
|
|
18
|
+
else
|
|
19
|
+
debug "reading stdin"
|
|
20
|
+
file = 'STDIN'
|
|
21
|
+
content = $stdin.read
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
lint = session.lint(content)
|
|
25
|
+
|
|
26
|
+
unless quiet?
|
|
27
|
+
if lint.ok?
|
|
28
|
+
say "valid", color("Hooray, #{file} looks %s :)", :success)
|
|
29
|
+
else
|
|
30
|
+
say "Warnings for #{color(file, :info)}:"
|
|
31
|
+
lint.warnings.each do |warning|
|
|
32
|
+
say color('[x]', [:red, :bold]) + " "
|
|
33
|
+
if warning.key.any?
|
|
34
|
+
say [
|
|
35
|
+
color('in ', :info),
|
|
36
|
+
color(warning.key.join('.'), [:info, :bold, :underline]),
|
|
37
|
+
color(' section:', :info), ' '
|
|
38
|
+
].join
|
|
39
|
+
end
|
|
40
|
+
say warning.message.gsub(/"(.*?)"/) { color($1, [:info, :important]) }
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
exit 1 if lint.warnings? and exit_code?
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
require 'travis/cli'
|
|
2
|
+
require 'travis/tools/github'
|
|
3
|
+
require 'json'
|
|
4
|
+
|
|
5
|
+
module Travis
|
|
6
|
+
module CLI
|
|
7
|
+
class Login < ApiCommand
|
|
8
|
+
skip :authenticate
|
|
9
|
+
|
|
10
|
+
description "authenticates against the API and stores the token"
|
|
11
|
+
on('-g', '--github-token TOKEN', 'identify by GitHub token')
|
|
12
|
+
on('-T', '--auto-token', 'try to figure out who you are automatically (might send another apps token to Travis, token will not be stored)')
|
|
13
|
+
on('-p', '--auto-password', 'try to load password from OSX keychain (will not be stored)')
|
|
14
|
+
on('-a', '--auto', 'shorthand for --auto-token --auto-password') { |c| c.auto_token = c.auto_password = true }
|
|
15
|
+
on('-u', '--user LOGIN', 'user to log in as') { |c,n| c.user_login = n }
|
|
16
|
+
on('-M', '--no-manual', 'do not use interactive login')
|
|
17
|
+
on('--list-github-token', 'instead of actually logging in, list found GitHub tokens')
|
|
18
|
+
on('--skip-token-check', 'don\'t verify the token with github')
|
|
19
|
+
|
|
20
|
+
attr_accessor :user_login
|
|
21
|
+
|
|
22
|
+
def list_token
|
|
23
|
+
github.after_tokens = proc { }
|
|
24
|
+
github.each_token do |token|
|
|
25
|
+
say token
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def login
|
|
30
|
+
session.access_token = nil
|
|
31
|
+
github.with_token do |token|
|
|
32
|
+
endpoint_config['access_token'] = github_auth(token)
|
|
33
|
+
error("user mismatch: logged in as %p instead of %p" % [user.login, user_login]) if user_login and user.login != user_login
|
|
34
|
+
error("#{user.login} has not granted Travis CI the required permissions, please log in via #{session.config['host']}") unless user.correct_scopes?
|
|
35
|
+
success("Successfully logged in as #{user.login}!")
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def run
|
|
40
|
+
list_github_token ? list_token : login
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def github
|
|
44
|
+
@github ||= begin
|
|
45
|
+
load_gh
|
|
46
|
+
Tools::Github.new(session.config['github']) do |g|
|
|
47
|
+
g.note = "temporary token to identify with the travis command line client against #{api_endpoint}"
|
|
48
|
+
g.manual_login = no_manual.nil?
|
|
49
|
+
g.explode = explode?
|
|
50
|
+
g.github_token = github_token
|
|
51
|
+
g.auto_token = auto_token
|
|
52
|
+
g.auto_password = auto_password
|
|
53
|
+
g.github_login = user_login
|
|
54
|
+
g.check_token = !skip_token_check?
|
|
55
|
+
g.drop_token = true
|
|
56
|
+
g.ask_login = proc { ask("Username: ") }
|
|
57
|
+
g.ask_password = proc { |user| ask("Password for #{user}: ") { |q| q.echo = "*" } }
|
|
58
|
+
g.ask_otp = proc { |user| ask("Two-factor authentication code for #{user}: ") }
|
|
59
|
+
g.login_header = proc { login_header }
|
|
60
|
+
g.debug = proc { |log| debug(log) }
|
|
61
|
+
g.after_tokens = proc { g.explode = true and error("no suitable github token found") }
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def login_header
|
|
67
|
+
say "We need your #{color("GitHub login", :important)} to identify you."
|
|
68
|
+
say "This information will #{color("not be sent to Travis CI", :important)}, only to #{color(github_endpoint.host, :info)}."
|
|
69
|
+
say "The password will not be displayed."
|
|
70
|
+
empty_line
|
|
71
|
+
say "Try running with #{color("--github-token", :info)} or #{color("--auto", :info)} if you don't want to enter your password anyway."
|
|
72
|
+
empty_line
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
require 'travis/cli'
|
|
2
|
+
require 'travis/tools/safe_string'
|
|
3
|
+
require 'travis/tools/system'
|
|
4
|
+
|
|
5
|
+
module Travis
|
|
6
|
+
module CLI
|
|
7
|
+
class Logs < RepoCommand
|
|
8
|
+
attr_accessor :delete, :reason
|
|
9
|
+
description "streams test logs"
|
|
10
|
+
on('-d', '--delete [REASON]', 'remove logs') { |c, reason| c.delete, c.reason = true, reason }
|
|
11
|
+
on('-f', '--force', 'do not ask user to confirm deleting the logs')
|
|
12
|
+
on('--[no-]stream', 'only print current logs, do not stream')
|
|
13
|
+
|
|
14
|
+
def setup
|
|
15
|
+
super
|
|
16
|
+
check_websocket
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
include Tools::SafeString
|
|
20
|
+
def run(number = last_build.number)
|
|
21
|
+
self.stream = true if stream.nil?
|
|
22
|
+
job ||= job(number) || error("no such job ##{number}")
|
|
23
|
+
delete ? delete_log(job) : display_log(job)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def delete_log(job)
|
|
27
|
+
unless force?
|
|
28
|
+
error "not deleting logs without --force" unless interactive?
|
|
29
|
+
error "aborted" unless danger_zone? "Do you really want to delete the build log for #{color(job.inspect_info, :underline)}?"
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
warn "deleting log for #{color(job.inspect_info, [:bold, :info])}"
|
|
33
|
+
job.delete_log(reason || {})
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def display_log(job)
|
|
37
|
+
info "displaying logs for #{color(job.inspect_info, [:bold, :info])}"
|
|
38
|
+
return print_log(job.log.body) unless stream?
|
|
39
|
+
job.log.body { |part| print_log(part) }
|
|
40
|
+
ensure
|
|
41
|
+
print "\e[0m" if interactive?
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def print_log(part)
|
|
45
|
+
print interactive? ? encoded(part) : clean(part)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
private
|
|
49
|
+
|
|
50
|
+
def job(number)
|
|
51
|
+
number = last_build.number + number if number.start_with? '.'
|
|
52
|
+
job = super(number) || build(number) || branch(number)
|
|
53
|
+
job = job.jobs.first if job.respond_to? :jobs
|
|
54
|
+
job
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def check_websocket
|
|
58
|
+
require 'websocket-native' if stream?
|
|
59
|
+
rescue LoadError => e
|
|
60
|
+
raise e if e.respond_to?(:path) and e.path != 'websocket-native'
|
|
61
|
+
info "speed up log streaming by installing the websocket-native gem"
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|