travis 1.5.3 → 1.5.4
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 +4 -4
- data/README.md +27 -2
- data/Rakefile +4 -69
- data/completion/travis.sh +126 -1375
- data/completion/travis.sh.erb +60 -0
- data/lib/travis/cli.rb +0 -3
- data/lib/travis/cli/accounts.rb +4 -2
- data/lib/travis/cli/api_command.rb +19 -1
- data/lib/travis/cli/command.rb +4 -4
- data/lib/travis/cli/endpoint.rb +13 -1
- data/lib/travis/cli/init.rb +26 -2
- data/lib/travis/cli/login.rb +24 -12
- data/lib/travis/cli/monitor.rb +25 -2
- data/lib/travis/cli/repo_command.rb +4 -4
- data/lib/travis/cli/setup.rb +27 -122
- data/lib/travis/cli/setup/cloud_control.rb +21 -0
- data/lib/travis/cli/setup/cloud_foundry.rb +23 -0
- data/lib/travis/cli/setup/engine_yard.rb +24 -0
- data/lib/travis/cli/setup/heroku.rb +20 -0
- data/lib/travis/cli/setup/nodejitsu.rb +27 -0
- data/lib/travis/cli/setup/open_shift.rb +20 -0
- data/lib/travis/cli/setup/ruby_gems.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/client/repository.rb +1 -1
- data/lib/travis/client/session.rb +27 -5
- data/lib/travis/tools/notification.rb +69 -0
- data/lib/travis/tools/system.rb +38 -0
- data/lib/travis/version.rb +1 -1
- data/spec/cli/endpoint_spec.rb +5 -0
- data/spec/cli/init_spec.rb +21 -19
- data/spec/client/repository_spec.rb +1 -0
- data/spec/client/session_spec.rb +16 -0
- data/spec/support/fake_api.rb +2 -1
- data/travis.gemspec +28 -14
- metadata +46 -19
@@ -0,0 +1,60 @@
|
|
1
|
+
# implements tab completion for complete (bash), compsys (new zsh) and compctl (old zsh)
|
2
|
+
# this file is generated by `rake completion`
|
3
|
+
|
4
|
+
_travis_complete() {
|
5
|
+
case $1 in
|
6
|
+
1) _travis_commands;;
|
7
|
+
2)
|
8
|
+
case "$2" in
|
9
|
+
# commands with smart completions (in addition to command line flags)
|
10
|
+
help) _travis_commands;;
|
11
|
+
setup) _travis_setup;;
|
12
|
+
init) _travis_init;;
|
13
|
+
*) _travis_option;;
|
14
|
+
esac;;
|
15
|
+
*) _travis_option;;
|
16
|
+
esac
|
17
|
+
}
|
18
|
+
|
19
|
+
if type compdef 1>/dev/null 2>/dev/null; then
|
20
|
+
compdef _travis travis
|
21
|
+
_travis() { _travis_complete $((${#words} - 1)) "${words[2]}"; }
|
22
|
+
_travis_commands() { list=(<%= commands.map { |c| "%s:%p" % [c.command_name, c.description] }.join(" ") %>) _describe -t common-commands 'common commands' list; }
|
23
|
+
_travis_setup() { list=(<%= Travis::CLI::Setup.services.map { |s| "%s:%p" % [s.service_name, s.description] }.join(" ") %>) _describe -t common-commands 'common commands' list; }
|
24
|
+
_travis_init() { list=(<%= Travis::CLI::Init.languages.map { |l| "#{l}:'initialize #{l} project'" }.join(" ") %>) _describe -t common-commands 'common commands' list; }
|
25
|
+
_travis_option() {
|
26
|
+
case "${words[2]}" in
|
27
|
+
<% commands.each do |c| %>
|
28
|
+
<%= "#{c.command_name})".ljust(10) %> <%= c.new.parser.compsys(" ", c.command_name).gsub(/\s+\\\s+/, ' ')[/_arguments.*/] %>;;
|
29
|
+
<% end %>
|
30
|
+
esac
|
31
|
+
}
|
32
|
+
elif type compctl 1>/dev/null 2>/dev/null; then
|
33
|
+
compctl -K _travis travis
|
34
|
+
_travis() { read -cA words && _travis_complete $((${#words} - 1)) "${words[2]}"; }
|
35
|
+
_travis_commands() { reply=(<%= commands.map(&:command_name).map(&:inspect).join(" ") %>); }
|
36
|
+
_travis_setup() { reply=(<%= Travis::CLI::Setup.services.map(&:service_name).map(&:inspect).join(" ") %>); }
|
37
|
+
_travis_init() { reply=(<%= Travis::CLI::Init.languages.map(&:inspect).join(" ") %>); }
|
38
|
+
_travis_option() {
|
39
|
+
case "${words[2]}" in
|
40
|
+
<% commands.each do |c| %>
|
41
|
+
<%= "#{c.command_name})".ljust(10) %> reply=(<%= c.new.parser.candidate("-").flat_map { |o| [o.sub('[no-]', ''), o.sub('[no-]', 'no-')] }.uniq.map(&:inspect).join(" ") %>);;
|
42
|
+
<% end %>
|
43
|
+
esac
|
44
|
+
}
|
45
|
+
elif type complete 1>/dev/null 2>/dev/null; then
|
46
|
+
complete -F _travis travis
|
47
|
+
_travis() { _travis_complete "$COMP_CWORD" "${COMP_WORDS[1]}"; }
|
48
|
+
_travis_commands() { COMPREPLY=( $(compgen -W "<%= commands.map(&:command_name).join(" ") %>" -- "${COMP_WORDS[COMP_CWORD]}") ); }
|
49
|
+
_travis_setup() { COMPREPLY=( $(compgen -W "<%= Travis::CLI::Setup.services.map(&:service_name).join(" ") %>" -- "${COMP_WORDS[COMP_CWORD]}") ); }
|
50
|
+
_travis_init() { COMPREPLY=( $(compgen -W "<%= Travis::CLI::Init.languages.join(" ") %>" -- "${COMP_WORDS[COMP_CWORD]}") ); }
|
51
|
+
_travis_option() {
|
52
|
+
local options
|
53
|
+
case "${COMP_WORDS[1]}" in
|
54
|
+
<% commands.each do |c| %>
|
55
|
+
<%= "#{c.command_name})".ljust(10) %> options="<%= c.new.parser.candidate("-").flat_map { |o| [o.sub('[no-]', ''), o.sub('[no-]', 'no-')] }.uniq.join(" ") %>";;
|
56
|
+
<% end %>
|
57
|
+
esac
|
58
|
+
COMPREPLY=( $(compgen -W "$options" -- "${COMP_WORDS[COMP_CWORD]}") )
|
59
|
+
}
|
60
|
+
fi
|
data/lib/travis/cli.rb
CHANGED
data/lib/travis/cli/accounts.rb
CHANGED
@@ -11,12 +11,14 @@ module Travis
|
|
11
11
|
color = account.subscribed? ? :green : :info
|
12
12
|
say [
|
13
13
|
color(account.login, [color, :bold]),
|
14
|
-
color("(#{account.name}):", color),
|
14
|
+
color("(#{account.name || account.login.capitalize}):", color),
|
15
15
|
account.subscribed? ? "subscribed," : "not subscribed,",
|
16
16
|
account.repos_count == 1 ? "1 repository" : "#{account.repos_count} repositories"
|
17
17
|
].join(" ")
|
18
18
|
end
|
19
|
-
|
19
|
+
unless accounts.all?(&:subscribed?) or session.config['host'].nil?
|
20
|
+
say session.config['host'], "To set up a subscription, please visit %s."
|
21
|
+
end
|
20
22
|
end
|
21
23
|
end
|
22
24
|
end
|
@@ -31,7 +31,7 @@ module Travis
|
|
31
31
|
end
|
32
32
|
|
33
33
|
def initialize(*)
|
34
|
-
@session = Travis::Client.new
|
34
|
+
@session = Travis::Client.new(:agent_info => "command #{command_name}")
|
35
35
|
super
|
36
36
|
end
|
37
37
|
|
@@ -80,6 +80,24 @@ module Travis
|
|
80
80
|
|
81
81
|
private
|
82
82
|
|
83
|
+
def load_gh
|
84
|
+
return if defined? GH
|
85
|
+
require 'gh'
|
86
|
+
|
87
|
+
gh_config = session.config['github']
|
88
|
+
gh_config &&= gh_config.inject({}) { |h,(k,v)| h.update(k.to_sym => v) }
|
89
|
+
gh_config ||= {}
|
90
|
+
gh_config[:ssl] = Travis::Client::Session::SSL_OPTIONS
|
91
|
+
gh_config[:ssl] = { :verify => false } if gh_config[:api_url] and gh_config[:api_url] != "https://api.github.com"
|
92
|
+
|
93
|
+
GH.set(gh_config)
|
94
|
+
end
|
95
|
+
|
96
|
+
def github_endpoint
|
97
|
+
load_gh
|
98
|
+
GH.with({}).api_host
|
99
|
+
end
|
100
|
+
|
83
101
|
def listen(*args)
|
84
102
|
super(*args) do |listener|
|
85
103
|
on_signal { listener.disconnect }
|
data/lib/travis/cli/command.rb
CHANGED
@@ -171,9 +171,9 @@ module Travis
|
|
171
171
|
"Usage: " << color(usage, :command)
|
172
172
|
end
|
173
173
|
|
174
|
-
def help
|
174
|
+
def help(info = "")
|
175
175
|
parser.banner = usage
|
176
|
-
self.class.description.sub(/./) { |c| c.upcase } + ".\n" + parser.to_s
|
176
|
+
self.class.description.sub(/./) { |c| c.upcase } + ".\n" + info + parser.to_s
|
177
177
|
end
|
178
178
|
|
179
179
|
def say(data, format = nil, style = nil)
|
@@ -220,8 +220,8 @@ module Travis
|
|
220
220
|
end
|
221
221
|
|
222
222
|
def color(line, style)
|
223
|
-
return line unless interactive?
|
224
|
-
terminal.color(line, Array(style).map(&:to_sym))
|
223
|
+
return line.to_s unless interactive?
|
224
|
+
terminal.color(line || '???', Array(style).map(&:to_sym))
|
225
225
|
end
|
226
226
|
|
227
227
|
def interactive?(io = output)
|
data/lib/travis/cli/endpoint.rb
CHANGED
@@ -8,8 +8,16 @@ module Travis
|
|
8
8
|
skip :authenticate
|
9
9
|
on '--drop-default', 'delete stored default endpoint'
|
10
10
|
on '--set-default', 'store endpoint as global default'
|
11
|
+
on '--github', 'display github endpoint'
|
11
12
|
|
12
|
-
def
|
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
|
13
21
|
if drop_default? and was = config['default_endpoint']
|
14
22
|
config.delete('default_endpoint')
|
15
23
|
say was, "default API endpoint dropped (was %s)"
|
@@ -18,6 +26,10 @@ module Travis
|
|
18
26
|
say api_endpoint, "API endpoint: %s#{" (stored as default)" if set_default?}"
|
19
27
|
end
|
20
28
|
end
|
29
|
+
|
30
|
+
def run
|
31
|
+
github? ? run_github : run_travis
|
32
|
+
end
|
21
33
|
end
|
22
34
|
end
|
23
35
|
end
|
data/lib/travis/cli/init.rb
CHANGED
@@ -3,6 +3,15 @@ require 'travis/cli'
|
|
3
3
|
module Travis
|
4
4
|
module CLI
|
5
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
|
+
|
6
15
|
description "generates a .travis.yml and enables the project"
|
7
16
|
|
8
17
|
on('-f', '--force', 'override .travis.yml if it already exists')
|
@@ -24,6 +33,15 @@ module Travis
|
|
24
33
|
|
25
34
|
attr_writer :travis_config
|
26
35
|
|
36
|
+
def self.languages
|
37
|
+
pattern = File.expand_path("../init/*.yml", __FILE__)
|
38
|
+
Dir[pattern].map { |f| File.basename(f, '.yml') }.sort
|
39
|
+
end
|
40
|
+
|
41
|
+
def help
|
42
|
+
super("Available languages: #{self.class.languages.join(", ")}\n\n")
|
43
|
+
end
|
44
|
+
|
27
45
|
def run(language = nil, file = '.travis.yml')
|
28
46
|
error "#{file} already exists, use --force to override" if File.exist?(file) and not force? and not print_conf?
|
29
47
|
language ||= ask('Main programming language used: ') { |q| q.default = detect_language }
|
@@ -45,14 +63,20 @@ module Travis
|
|
45
63
|
|
46
64
|
private
|
47
65
|
|
66
|
+
def template_name(language)
|
67
|
+
File.expand_path("../init/#{language}.yml", __FILE__)
|
68
|
+
end
|
69
|
+
|
48
70
|
def template(language)
|
49
|
-
|
71
|
+
language = language.to_s.downcase
|
72
|
+
language = LANGUAGE_MAPPING[language] || language
|
73
|
+
file = template_name(language)
|
50
74
|
error "unknown language #{language}" unless File.exist? file
|
51
75
|
YAML.load_file(file)
|
52
76
|
end
|
53
77
|
|
54
78
|
def detect_language
|
55
|
-
|
79
|
+
repository.github_language || "Ruby"
|
56
80
|
end
|
57
81
|
end
|
58
82
|
end
|
data/lib/travis/cli/login.rb
CHANGED
@@ -6,17 +6,14 @@ module Travis
|
|
6
6
|
module CLI
|
7
7
|
class Login < ApiCommand
|
8
8
|
description "authenticates against the API and stores the token"
|
9
|
+
on '--github-token TOKEN', 'identify by GitHub token'
|
10
|
+
on '--auto', 'try to figure out who you are automatically (might send another apps token to Travis, token will not be stored)'
|
9
11
|
|
10
12
|
skip :authenticate
|
11
|
-
attr_accessor :github_login, :github_password, :github_token, :callback
|
12
|
-
|
13
|
-
on('--github-token TOKEN', 'identify by GitHub token')
|
14
|
-
|
15
|
-
on('--auto', 'try to figure out who you are automatically (might send another apps token to Travis, token will not be stored)') do |c|
|
16
|
-
c.github_token ||= Travis::Tools::TokenFinder.find(:explode => c.explode?)
|
17
|
-
end
|
13
|
+
attr_accessor :github_login, :github_password, :github_token, :github_otp, :callback
|
18
14
|
|
19
15
|
def run
|
16
|
+
self.github_token ||= Travis::Tools::TokenFinder.find(:explode => explode?, :github => github_endpoint.host) if auto?
|
20
17
|
generate_github_token unless github_token
|
21
18
|
endpoint_config['access_token'] = github_auth(github_token)
|
22
19
|
success("Successfully logged in!")
|
@@ -27,16 +24,25 @@ module Travis
|
|
27
24
|
private
|
28
25
|
|
29
26
|
def generate_github_token
|
27
|
+
load_gh
|
30
28
|
ask_info
|
31
29
|
|
32
|
-
|
30
|
+
options = { :username => github_login, :password => github_password }
|
31
|
+
options[:headers] = { "X-GitHub-OTP" => github_otp } if github_otp
|
32
|
+
gh = GH.with(options)
|
33
|
+
|
33
34
|
reply = gh.post('/authorizations', :scopes => github_scopes, :note => "temporary token to identify on #{api_endpoint}")
|
34
35
|
|
35
36
|
self.github_token = reply['token']
|
36
37
|
self.callback = proc { gh.delete reply['_links']['self']['href'] }
|
37
|
-
rescue GH::Error =>
|
38
|
-
|
39
|
-
|
38
|
+
rescue GH::Error => error
|
39
|
+
if error.info[:response_status] == 401
|
40
|
+
ask_2fa
|
41
|
+
generate_github_token
|
42
|
+
else
|
43
|
+
raise error if explode?
|
44
|
+
error(JSON.parse(error.info[:response_body])["message"])
|
45
|
+
end
|
40
46
|
end
|
41
47
|
|
42
48
|
def github_scopes
|
@@ -44,8 +50,9 @@ module Travis
|
|
44
50
|
end
|
45
51
|
|
46
52
|
def ask_info
|
53
|
+
return if !github_login.nil?
|
47
54
|
say "We need your #{color("GitHub login", :important)} to identify you."
|
48
|
-
say "This information will #{color("not be sent to Travis CI", :important)}, only to
|
55
|
+
say "This information will #{color("not be sent to Travis CI", :important)}, only to #{color(github_endpoint.host, :info)}."
|
49
56
|
say "The password will not be displayed."
|
50
57
|
empty_line
|
51
58
|
say "Try running with #{color("--github-token", :info)} or #{color("--auto", :info)} if you don't want to enter your password anyways."
|
@@ -54,6 +61,11 @@ module Travis
|
|
54
61
|
self.github_password = ask("Password: ") { |q| q.echo = "*" }
|
55
62
|
empty_line
|
56
63
|
end
|
64
|
+
|
65
|
+
def ask_2fa
|
66
|
+
self.github_otp = ask "Two-factor authentication code: "
|
67
|
+
empty_line
|
68
|
+
end
|
57
69
|
end
|
58
70
|
end
|
59
71
|
end
|
data/lib/travis/cli/monitor.rb
CHANGED
@@ -1,16 +1,22 @@
|
|
1
1
|
require 'travis/cli'
|
2
|
+
require 'travis/tools/notification'
|
2
3
|
|
3
4
|
module Travis
|
4
5
|
module CLI
|
5
6
|
class Monitor < ApiCommand
|
6
7
|
description "live monitor for what's going on"
|
7
|
-
|
8
8
|
on('-m', '--my-repos', 'Only monitor my own repositories')
|
9
|
+
|
9
10
|
on('-r', '--repo SLUG', 'monitor given repository (can be used more than once)') do |c, slug|
|
10
11
|
c.repos << slug
|
11
12
|
end
|
12
13
|
|
13
|
-
|
14
|
+
types = Tools::Notification::DEFAULT.map(&:to_s).join(", ")
|
15
|
+
on('-n', '--[no-]notify [TYPE]', "send out desktop notifications (optional type: #{types})") do |c, type|
|
16
|
+
c.setup_notification(type)
|
17
|
+
end
|
18
|
+
|
19
|
+
attr_reader :repos, :notification
|
14
20
|
|
15
21
|
def initialize(*)
|
16
22
|
@repos = []
|
@@ -21,6 +27,22 @@ module Travis
|
|
21
27
|
super
|
22
28
|
repos.map! { |r| repo(r) }
|
23
29
|
repos.concat(user.repositories) if my_repos?
|
30
|
+
setup_notification(repos.any? || :dummy) unless notification
|
31
|
+
end
|
32
|
+
|
33
|
+
def setup_notification(type = nil)
|
34
|
+
refuse = false
|
35
|
+
case type
|
36
|
+
when false then @notification = Tools::Notification.new(:dummy)
|
37
|
+
when nil, true then @notification = Tools::Notification.new
|
38
|
+
else
|
39
|
+
refuse = true
|
40
|
+
@notification = Tools::Notification.new(type)
|
41
|
+
end
|
42
|
+
rescue ArgumentError => e
|
43
|
+
@notification = Tools::Notification.new(:dummy)
|
44
|
+
error(e.message) if refuse
|
45
|
+
warn(e.message)
|
24
46
|
end
|
25
47
|
|
26
48
|
def description
|
@@ -42,6 +64,7 @@ module Travis
|
|
42
64
|
color(entity.inspect_info, [entity.color, :bold]),
|
43
65
|
color(entity.state, entity.color)
|
44
66
|
].join(" ")
|
67
|
+
notification.notify("Travis CI", "#{entity.inspect_info} #{entity.state}")
|
45
68
|
end
|
46
69
|
end
|
47
70
|
end
|
@@ -44,11 +44,10 @@ module Travis
|
|
44
44
|
end
|
45
45
|
|
46
46
|
def find_slug
|
47
|
-
git_head
|
48
|
-
git_remote = `git config --get branch.#{git_head}.remote 2
|
49
|
-
# Default to 'origin' if no tracking is set
|
47
|
+
git_head = `git name-rev --name-only HEAD 2>#{IO::NULL}`.chomp
|
48
|
+
git_remote = `git config --get branch.#{git_head}.remote 2>#{IO::NULL}`.chomp
|
50
49
|
git_remote = 'origin' if git_remote.empty?
|
51
|
-
git_info
|
50
|
+
git_info = `git config --get remote.#{git_remote}.url 2>#{IO::NULL}`.chomp
|
52
51
|
$1 if git_info =~ GIT_REGEX
|
53
52
|
end
|
54
53
|
|
@@ -64,6 +63,7 @@ module Travis
|
|
64
63
|
ENV['TRAVIS_ENDPOINT']
|
65
64
|
else
|
66
65
|
repo_config['endpoint'] ||= begin
|
66
|
+
load_gh
|
67
67
|
GH.head("/repos/#{slug}")
|
68
68
|
Travis::Client::ORG_URI
|
69
69
|
rescue GH::Error
|
data/lib/travis/cli/setup.rb
CHANGED
@@ -1,142 +1,47 @@
|
|
1
1
|
require 'travis/cli'
|
2
|
-
require 'json'
|
3
|
-
require 'yaml'
|
4
2
|
|
5
3
|
module Travis
|
6
4
|
module CLI
|
7
5
|
class Setup < RepoCommand
|
6
|
+
autoload :CloudControl, 'travis/cli/setup/cloud_control'
|
7
|
+
autoload :CloudFoundry, 'travis/cli/setup/cloud_foundry'
|
8
|
+
autoload :EngineYard, 'travis/cli/setup/engine_yard'
|
9
|
+
autoload :Heroku, 'travis/cli/setup/heroku'
|
10
|
+
autoload :Nodejitsu, 'travis/cli/setup/nodejitsu'
|
11
|
+
autoload :OpenShift, 'travis/cli/setup/open_shift'
|
12
|
+
autoload :RubyGems, 'travis/cli/setup/ruby_gems'
|
13
|
+
autoload :SauceConnect, 'travis/cli/setup/sauce_connect'
|
14
|
+
autoload :Service, 'travis/cli/setup/service'
|
15
|
+
|
8
16
|
description "sets up an addon or deploy target"
|
9
17
|
on('-f', '--force', 'override config section if it already exists')
|
10
18
|
|
11
|
-
def
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
def setup_heroku
|
17
|
-
configure 'deploy', 'provider' => 'heroku' do |config|
|
18
|
-
config['api_key'] = `heroku auth:token 2>/dev/null`.strip
|
19
|
-
config['api_key'] = ask("Heroku API token: ") { |q| q.echo = "*" }.to_s if config['api_key'].empty?
|
20
|
-
config['app'] = `heroku apps:info 2>/dev/null`.scan(/^=== (.+)$/).flatten.first
|
21
|
-
config['app'] = ask("Heroku application name: ") { |q| q.default = repository.name }.to_s if config['app'].nil?
|
22
|
-
config['on'] = { 'repo' => repository.slug } if agree("Deploy only from #{repository.slug}? ") { |q| q.default = 'yes' }
|
23
|
-
encrypt(config, 'api_key') if agree("Encrypt API key? ") { |q| q.default = 'yes' }
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
def setup_engineyard
|
28
|
-
configure 'deploy', 'provider' => 'engineyard' do |config|
|
29
|
-
eyrc = File.expand_path(".eyrc", Dir.home)
|
30
|
-
config['api_key'] = YAML.load_file(eyrc)["api_token"] if File.exists?(eyrc)
|
31
|
-
config['api_key'] = ask("API token: ") { |q| q.echo = "*" }.to_s unless config['api_key']
|
32
|
-
env = ask("Environment (optional): ").to_s
|
33
|
-
config['environment'] = env unless env.empty?
|
34
|
-
migrate = agree("Run migrations on deploy? ") { |q| q.default = 'yes' }
|
35
|
-
config['migrate'] = ask("Migration command: ") { |q| q.default = "rake db:migrate" } if migrate
|
36
|
-
config['on'] = { 'repo' => repository.slug } if agree("Deploy only from #{repository.slug}? ") { |q| q.default = 'yes' }
|
37
|
-
encrypt(config, 'api_key') if agree("Encrypt API key? ") { |q| q.default = 'yes' }
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
def setup_openshift
|
42
|
-
configure 'deploy', 'provider' => 'openshift' do |config|
|
43
|
-
config['user'] = ask("OpenShift user: ").to_s
|
44
|
-
config['password'] = ask("OpenShift password: ") { |q| q.echo = "*" }.to_s
|
45
|
-
config['app'] = ask("OpenShift application name: ") { |q| q.default = repository.name }.to_s
|
46
|
-
config['domain'] = ask("OpenShift domain: ").to_s
|
47
|
-
config['on'] = { 'repo' => repository.slug } if agree("Deploy only from #{repository.slug}? ") { |q| q.default = 'yes' }
|
48
|
-
encrypt(config, 'password') if agree("Encrypt password? ") { |q| q.default = 'yes' }
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
def setup_rubygems
|
53
|
-
configure 'deploy', 'provider' => 'rubygems' do |config|
|
54
|
-
authorization_file = File.expand_path('.rubygems/authorization', ENV['HOME'])
|
55
|
-
credentials_file = File.expand_path('.gem/credentials', ENV['HOME'])
|
56
|
-
|
57
|
-
config['api_key'] ||= File.read(authorization_file) if File.exist? authorization_file
|
58
|
-
config['api_key'] ||= YAML.load_file(credentials_file)[:rubygems_api_key] if File.exist? credentials_file
|
59
|
-
config['api_key'] ||= ask("RubyGems API token: ") { |q| q.echo = "*" }.to_s
|
60
|
-
config['gem'] ||= ask("Gem name: ") { |q| q.default = repository.name }.to_s
|
61
|
-
|
62
|
-
on("Release only from #{repository.slug}? ", config, 'repo' => repository.slug)
|
63
|
-
on("Release only tagged commits? ", config, 'tags' => true)
|
64
|
-
encrypt(config, 'api_key') if agree("Encrypt API key? ") { |q| q.default = 'yes' }
|
65
|
-
end
|
19
|
+
def self.service(name)
|
20
|
+
normal_name = Service.normalized_name(name)
|
21
|
+
const_name = constants(false).detect { |c| Service.normalized_name(c) == normal_name }
|
22
|
+
constant = const_get(const_name) if const_name
|
23
|
+
constant if constant and constant < Service and constant.known_as? name
|
66
24
|
end
|
67
25
|
|
68
|
-
def
|
69
|
-
|
70
|
-
jitsu_file = File.expand_path('.jitsuconf', ENV['HOME'])
|
71
|
-
|
72
|
-
if File.exist? jitsu_file
|
73
|
-
jitsu_conf = JSON.parse(File.read(jitsu_file))
|
74
|
-
config['user'] = jitsu_conf['username']
|
75
|
-
config['api_key'] = jitsu_conf['apiToken']
|
76
|
-
end
|
77
|
-
|
78
|
-
config['user'] ||= ask("Nodejitsu user: ").to_s
|
79
|
-
config['api_key'] ||= ask("Nodejitsu API token: ") { |q| q.echo = "*" }.to_s
|
80
|
-
config['on'] = { 'repo' => repository.slug } if agree("Deploy only from #{repository.slug}? ") { |q| q.default = 'yes' }
|
81
|
-
encrypt(config, 'api_key') if agree("Encrypt API key? ") { |q| q.default = 'yes' }
|
82
|
-
end
|
26
|
+
def self.services
|
27
|
+
constants(false).sort.map { |c| const_get(c) }.select { |c| c < Service }
|
83
28
|
end
|
84
29
|
|
85
|
-
def
|
86
|
-
|
87
|
-
|
88
|
-
config['username'] = ask("Sauce Labs user: ").to_s
|
89
|
-
config['access_key'] = ask("Sauce Labs access key: ") { |q| q.echo = "*" }.to_s
|
90
|
-
encrypt(config, 'access_key') if agree("Encrypt access key? ") { |q| q.default = 'yes' }
|
91
|
-
end
|
30
|
+
def help
|
31
|
+
services = self.class.services.map { |s| "\t" << color(s.service_name.ljust(20), :command) << color(s.description, :info) }.join("\n")
|
32
|
+
super("\nAvailable services:\n\n#{services}\n\n")
|
92
33
|
end
|
93
34
|
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
def setup_cloudcontrol
|
98
|
-
configure 'deploy', 'provider' => 'cloudcontrol' do |config|
|
99
|
-
config['email'] = ask("cloudControl email: ").to_s
|
100
|
-
config['password'] = ask("cloudControl password: ") { |q| q.echo = "*" }.to_s
|
101
|
-
app = ask("cloudControl application: ") { |q| q.default = repository.name }.to_s
|
102
|
-
dep = ask("cloudControl deployment: ") { |q| q.default = "default" }.to_s
|
103
|
-
config['deployment'] = "#{app}/#{dep}"
|
104
|
-
config['on'] = { 'repo' => repository.slug } if agree("Deploy only from #{repository.slug}? ") { |q| q.default = 'yes' }
|
105
|
-
encrypt(config, 'password') if agree("Encrypt password? ") { |q| q.default = 'yes' }
|
106
|
-
end
|
35
|
+
def run(service, file = travis_yaml)
|
36
|
+
service(service).run
|
37
|
+
save_travis_config(file)
|
107
38
|
end
|
108
39
|
|
109
|
-
def
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
config['password'] = ask("Cloud Foundry password: ") { |q| q.echo = "*" }.to_s
|
114
|
-
config['organization'] = ask("Cloud Foundry organization: ").to_s
|
115
|
-
config['space'] = ask("Cloud Foundry space: ").to_s
|
116
|
-
config['on'] = { 'repo' => repository.slug } if agree("Deploy only from #{repository.slug}? ") { |q| q.default = 'yes' }
|
117
|
-
encrypt(config, 'password') if agree("Encrypt password? ") { |q| q.default = 'yes' }
|
118
|
-
end
|
40
|
+
def service(name)
|
41
|
+
factory = self.class.service(name)
|
42
|
+
error("unknown service #{name}") unless factory
|
43
|
+
factory.new(self)
|
119
44
|
end
|
120
|
-
|
121
|
-
private
|
122
|
-
|
123
|
-
def on(question, config, condition)
|
124
|
-
return unless agree(question) { |q| q.default = 'yes' }
|
125
|
-
config['on'] ||= {}
|
126
|
-
config['on'].merge! condition
|
127
|
-
end
|
128
|
-
|
129
|
-
def encrypt(config, key)
|
130
|
-
encrypted = repository.encrypt(config.fetch(key))
|
131
|
-
config[key] = { 'secure' => encrypted }
|
132
|
-
end
|
133
|
-
|
134
|
-
def configure(key, value = {}, config = travis_config)
|
135
|
-
error "#{key} section already exists in .travis.yml, run with --force to override" if config.include? key and not force?
|
136
|
-
result = yield(config[key] = value)
|
137
|
-
save_travis_config
|
138
|
-
result
|
139
|
-
end
|
140
45
|
end
|
141
46
|
end
|
142
47
|
end
|