travis 1.5.3 → 1.5.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
@@ -9,9 +9,6 @@ rescue LoadError => e
9
9
  end
10
10
  end
11
11
 
12
- require 'gh'
13
- GH.set(:ssl => Travis::Client::Session::SSL_OPTIONS)
14
-
15
12
  require 'stringio'
16
13
 
17
14
  module Travis
@@ -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
- say session.config['host'], "To set up a subscription, please visit %s." unless accounts.all?(&:subscribed?)
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 }
@@ -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)
@@ -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 run
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
@@ -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
- file = File.expand_path("../init/#{language}.yml", __FILE__)
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
- 'ruby'
79
+ repository.github_language || "Ruby"
56
80
  end
57
81
  end
58
82
  end
@@ -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
- gh = GH.with(:username => github_login, :password => github_password)
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 => e
38
- raise e if explode?
39
- error JSON.parse(e.info[:response_body])["message"]
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 GitHub."
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
@@ -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
- attr_reader :repos
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 = `git name-rev --name-only HEAD 2>&1`.chomp
48
- git_remote = `git config --get branch.#{git_head}.remote 2>&1`.chomp
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 = `git config --get remote.#{git_remote}.url 2>&1`.chomp
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
@@ -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 run(service)
12
- error "unknown service #{service}" unless respond_to? "setup_#{service}"
13
- public_send "setup_#{service}"
14
- end
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 setup_nodejitsu
69
- configure 'deploy', 'provider' => 'nodejitsu' do |config|
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 setup_sauce_connect
86
- travis_config['addons'] ||= {}
87
- configure 'sauce_connect', {}, travis_config['addons'] do |config|
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
- alias setup_sauce_labs setup_sauce_connect
95
- alias setup_sauce setup_sauce_connect
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 setup_cloudfoundry
110
- configure 'deploy', 'provider' => 'cloudfoundry' do |config|
111
- config['target'] = ask("Cloud Foundry target: ").to_s
112
- config['username'] = ask("Cloud Foundry user name: ").to_s
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