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,25 @@
|
|
|
1
|
+
require 'travis/cli/setup'
|
|
2
|
+
|
|
3
|
+
module Travis
|
|
4
|
+
module CLI
|
|
5
|
+
class Setup
|
|
6
|
+
class RubyGems < Service
|
|
7
|
+
description "automatic release to RubyGems"
|
|
8
|
+
|
|
9
|
+
def run
|
|
10
|
+
deploy 'rubygems', 'release' do |config|
|
|
11
|
+
authorization_file = File.expand_path('.rubygems/authorization', ENV['HOME'])
|
|
12
|
+
credentials_file = File.expand_path('.gem/credentials', ENV['HOME'])
|
|
13
|
+
|
|
14
|
+
config['api_key'] ||= File.read(authorization_file) if File.exist? authorization_file
|
|
15
|
+
config['api_key'] ||= YAML.load_file(credentials_file)[:rubygems_api_key] if File.exist? credentials_file
|
|
16
|
+
config['api_key'] ||= ask("RubyGems API token: ") { |q| q.echo = "*" }.to_s
|
|
17
|
+
config['gem'] ||= ask("Gem name: ") { |q| q.default = repository.name }.to_s
|
|
18
|
+
|
|
19
|
+
on("Release only tagged commits? ", config, 'tags' => true)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
require 'travis/cli/setup'
|
|
2
|
+
|
|
3
|
+
module Travis
|
|
4
|
+
module CLI
|
|
5
|
+
class Setup
|
|
6
|
+
class S3 < Service
|
|
7
|
+
description "automatic pushing to S3"
|
|
8
|
+
|
|
9
|
+
def run
|
|
10
|
+
deploy 's3', 'push' do |config|
|
|
11
|
+
config['access_key_id'] = ask("Access key ID: ").to_s
|
|
12
|
+
config['secret_access_key'] = ask("Secret access key: ") { |q| q.echo = "*" }.to_s
|
|
13
|
+
config['bucket'] = ask("Bucket: ").to_s
|
|
14
|
+
local_dir = ask("Local project directory to upload (Optional): ").to_s
|
|
15
|
+
config['local-dir'] = local_dir unless local_dir.empty?
|
|
16
|
+
upload_dir = ask("S3 upload directory (Optional): ").to_s
|
|
17
|
+
config['upload-dir'] = upload_dir unless upload_dir.empty?
|
|
18
|
+
config['acl'] = ask("S3 ACL Settings (private, public_read, public_read_write, authenticated_read, bucket_owner_read, bucket_owner_full_control): ").to_s { |q| q.default = 'private'}
|
|
19
|
+
encrypt(config, 'secret_access_key') if agree("Encrypt secret access key? ") { |q| q.default = 'yes' }
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
require 'travis/cli/setup'
|
|
2
|
+
|
|
3
|
+
module Travis
|
|
4
|
+
module CLI
|
|
5
|
+
class Setup
|
|
6
|
+
class SauceConnect < Service
|
|
7
|
+
description "Sauce Connet addon for Sauce Labs integration"
|
|
8
|
+
service_name "sauce_connect"
|
|
9
|
+
|
|
10
|
+
def run
|
|
11
|
+
travis_config['addons'] ||= {}
|
|
12
|
+
configure 'sauce_connect', {}, travis_config['addons'] do |config|
|
|
13
|
+
config['username'] = ask("Sauce Labs user: ").to_s
|
|
14
|
+
config['access_key'] = ask("Sauce Labs access key: ") { |q| q.echo = "*" }.to_s
|
|
15
|
+
encrypt(config, 'access_key') if agree("Encrypt access key? ") { |q| q.default = 'yes' }
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
require 'travis/cli/setup'
|
|
2
|
+
|
|
3
|
+
module Travis
|
|
4
|
+
module CLI
|
|
5
|
+
class Setup
|
|
6
|
+
class Service
|
|
7
|
+
def self.normalized_name(string)
|
|
8
|
+
string.to_s.downcase.gsub(/[^a-z\d]/, '')
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def self.description(description = nil)
|
|
12
|
+
@description ||= ""
|
|
13
|
+
@description = description if description
|
|
14
|
+
@description
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def self.service_name(service_name = nil)
|
|
18
|
+
@service_name ||= normalized_name(name[/[^:]+$/])
|
|
19
|
+
@service_name = service_name if service_name
|
|
20
|
+
@service_name
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def self.known_as?(name)
|
|
24
|
+
normalized_name(service_name) == normalized_name(name)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
attr_accessor :command
|
|
28
|
+
|
|
29
|
+
def initialize(command)
|
|
30
|
+
@command = command
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def method_missing(*args, &block)
|
|
34
|
+
@command.send(*args, &block)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
private
|
|
38
|
+
|
|
39
|
+
def on(question, config, condition)
|
|
40
|
+
return unless agree(question) { |q| q.default = 'yes' }
|
|
41
|
+
config['on'] ||= {}
|
|
42
|
+
config['on'].merge! condition
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def encrypt(config, key)
|
|
46
|
+
encrypted = repository.encrypt(config.fetch(key))
|
|
47
|
+
config[key] = { 'secure' => encrypted }
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def configure(key, value = {}, config = travis_config)
|
|
51
|
+
error "#{key} section already exists in .travis.yml, run with --force to override" if config.include? key and not force?
|
|
52
|
+
yield(config[key] = value)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def branch
|
|
56
|
+
@branch ||= `git rev-parse --symbolic-full-name --abbrev-ref HEAD`.chomp
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def deploy(provider, verb = "deploy")
|
|
60
|
+
configure('deploy', 'provider' => provider) do |config|
|
|
61
|
+
yield config
|
|
62
|
+
|
|
63
|
+
on("#{verb.capitalize} only from #{repository.slug}? ", config, 'repo' => repository.slug)
|
|
64
|
+
on("#{verb.capitalize} from #{branch} branch? ", config, 'branch' => branch) if branch != 'master' and branch != 'HEAD'
|
|
65
|
+
|
|
66
|
+
encrypt(config, 'password') if config['password'] and agree("Encrypt Password? ") { |q| q.default = 'yes' }
|
|
67
|
+
encrypt(config, 'api_key') if config['api_key'] and agree("Encrypt API key? ") { |q| q.default = 'yes' }
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
require 'travis/cli'
|
|
2
|
+
|
|
3
|
+
module Travis
|
|
4
|
+
module CLI
|
|
5
|
+
class Setup < RepoCommand
|
|
6
|
+
autoload :Anynines, 'travis/cli/setup/anynines'
|
|
7
|
+
autoload :Appfog, 'travis/cli/setup/appfog'
|
|
8
|
+
autoload :Artifacts, 'travis/cli/setup/artifacts'
|
|
9
|
+
autoload :Biicode, 'travis/cli/setup/biicode'
|
|
10
|
+
autoload :CloudControl, 'travis/cli/setup/cloud_control'
|
|
11
|
+
autoload :CloudFoundry, 'travis/cli/setup/cloud_foundry'
|
|
12
|
+
autoload :CodeDeploy, 'travis/cli/setup/code_deploy'
|
|
13
|
+
autoload :EngineYard, 'travis/cli/setup/engine_yard'
|
|
14
|
+
autoload :Heroku, 'travis/cli/setup/heroku'
|
|
15
|
+
autoload :Nodejitsu, 'travis/cli/setup/nodejitsu'
|
|
16
|
+
autoload :NPM, 'travis/cli/setup/npm'
|
|
17
|
+
autoload :OpenShift, 'travis/cli/setup/open_shift'
|
|
18
|
+
autoload :PyPI, 'travis/cli/setup/pypi'
|
|
19
|
+
autoload :RubyGems, 'travis/cli/setup/ruby_gems'
|
|
20
|
+
autoload :Ninefold, 'travis/cli/setup/ninefold'
|
|
21
|
+
autoload :S3, 'travis/cli/setup/s3'
|
|
22
|
+
autoload :CloudFiles, 'travis/cli/setup/cloud_files'
|
|
23
|
+
autoload :Divshot, 'travis/cli/setup/divshot'
|
|
24
|
+
autoload :Hackage, 'travis/cli/setup/hackage'
|
|
25
|
+
autoload :OpsWorks, 'travis/cli/setup/opsworks'
|
|
26
|
+
autoload :SauceConnect, 'travis/cli/setup/sauce_connect'
|
|
27
|
+
autoload :Modulus, 'travis/cli/setup/modulus'
|
|
28
|
+
autoload :Releases, 'travis/cli/setup/releases'
|
|
29
|
+
autoload :GCS, 'travis/cli/setup/gcs'
|
|
30
|
+
autoload :Cloud_66, 'travis/cli/setup/cloud_66'
|
|
31
|
+
autoload :ElasticBeanstalk, 'travis/cli/setup/elastic_beanstalk'
|
|
32
|
+
autoload :Deis, 'travis/cli/setup/deis'
|
|
33
|
+
autoload :Service, 'travis/cli/setup/service'
|
|
34
|
+
|
|
35
|
+
description "sets up an addon or deploy target"
|
|
36
|
+
on('-f', '--force', 'override config section if it already exists')
|
|
37
|
+
|
|
38
|
+
def self.service(name)
|
|
39
|
+
normal_name = Service.normalized_name(name)
|
|
40
|
+
const_name = constants(false).detect { |c| Service.normalized_name(c) == normal_name }
|
|
41
|
+
constant = const_get(const_name) if const_name
|
|
42
|
+
constant if constant and constant < Service and constant.known_as? name
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def self.services
|
|
46
|
+
constants(false).sort.map { |c| const_get(c) }.select { |c| c < Service }
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def help
|
|
50
|
+
services = self.class.services.map { |s| "\t" << color(s.service_name.ljust(20), :command) << color(s.description, :info) }.join("\n")
|
|
51
|
+
super("\nAvailable services:\n\n#{services}\n\n")
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def run(service, file = travis_yaml)
|
|
55
|
+
service(service).run
|
|
56
|
+
save_travis_config(file)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def service(name)
|
|
60
|
+
factory = self.class.service(name)
|
|
61
|
+
error("unknown service #{name}") unless factory
|
|
62
|
+
factory.new(self)
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
require 'travis/cli'
|
|
2
|
+
|
|
3
|
+
module Travis
|
|
4
|
+
module CLI
|
|
5
|
+
class Show < RepoCommand
|
|
6
|
+
description "displays a build or job"
|
|
7
|
+
|
|
8
|
+
def run(number = last_build.number)
|
|
9
|
+
number = repository.branch(number).number if number !~ /^\d+(\.\d+)?$/ and repository.branch(number)
|
|
10
|
+
entity = job(number) || build(number)
|
|
11
|
+
|
|
12
|
+
error "could not find job or build #{repository.slug}##{number}" unless entity
|
|
13
|
+
|
|
14
|
+
say template(__FILE__) % [
|
|
15
|
+
entity.class.one.capitalize,
|
|
16
|
+
entity.number,
|
|
17
|
+
entity.commit.subject,
|
|
18
|
+
entity.state,
|
|
19
|
+
entity.color,
|
|
20
|
+
entity.pull_request? ? "pull request" : "push",
|
|
21
|
+
entity.branch_info,
|
|
22
|
+
entity.commit.compare_url,
|
|
23
|
+
formatter.duration(entity.duration),
|
|
24
|
+
formatter.time(entity.started_at),
|
|
25
|
+
formatter.time(entity.finished_at)
|
|
26
|
+
]
|
|
27
|
+
|
|
28
|
+
if entity.respond_to? :jobs
|
|
29
|
+
empty_line
|
|
30
|
+
entity.jobs.each do |job|
|
|
31
|
+
say [
|
|
32
|
+
color("##{job.number} #{job.state}:".ljust(16), [job.color, :bold]),
|
|
33
|
+
formatter.duration(job.duration).ljust(14),
|
|
34
|
+
formatter.job_config(job.config),
|
|
35
|
+
(color("(failure allowed)", :info) if job.allow_failures?)
|
|
36
|
+
].compact.join(" ").rstrip
|
|
37
|
+
end
|
|
38
|
+
else
|
|
39
|
+
config = formatter.job_config(entity.config)
|
|
40
|
+
say color("Allow Failure: ", :info) + entity.allow_failures?.inspect
|
|
41
|
+
say color("Config: ", :info) + config unless config.empty?
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
__END__
|
|
49
|
+
|
|
50
|
+
<[[ color("%s #%s: ", :bold) ]]> <[[ color(%p, :bold) ]]>
|
|
51
|
+
<[[ color("State: ", :info) ]]><[[ color(%p, :%s) ]]>
|
|
52
|
+
<[[ color("Type: ", :info) ]]>%s
|
|
53
|
+
<[[ color("Branch: ", :info) ]]>%s
|
|
54
|
+
<[[ color("Compare URL: ", :info) ]]>%s
|
|
55
|
+
<[[ color("Duration: ", :info) ]]>%s
|
|
56
|
+
<[[ color("Started: ", :info) ]]>%s
|
|
57
|
+
<[[ color("Finished: ", :info) ]]>%s
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
require 'travis/cli'
|
|
2
|
+
require 'travis/tools/ssl_key'
|
|
3
|
+
require 'travis/tools/github'
|
|
4
|
+
|
|
5
|
+
module Travis
|
|
6
|
+
module CLI
|
|
7
|
+
class Sshkey < RepoCommand
|
|
8
|
+
description "checks, updates or deletes an SSH key"
|
|
9
|
+
on '-D', '--delete', 'remove SSH key'
|
|
10
|
+
on '-d', '--description DESCRIPTION', 'set description'
|
|
11
|
+
on '-u', '--upload FILE', 'upload key from given file'
|
|
12
|
+
on '-s', '--stdin', 'upload key read from stdin'
|
|
13
|
+
on '-c', '--check', 'set exit code depending on key existing'
|
|
14
|
+
on '-g', '--generate', 'generate SSH key and set up for given GitHub user'
|
|
15
|
+
on '-p', '--passphrase PASSPHRASE', 'pass phrase to decrypt with when using --upload'
|
|
16
|
+
|
|
17
|
+
def_delegators :repository, :ssh_key
|
|
18
|
+
|
|
19
|
+
def run
|
|
20
|
+
error "SSH keys are not available on #{color(session.config['host'], :bold)}" if org?
|
|
21
|
+
delete_key if delete?
|
|
22
|
+
update_key File.read(upload), upload if upload?
|
|
23
|
+
update_key $stdin.read, 'stdin' if stdin?
|
|
24
|
+
generate_key if generate?
|
|
25
|
+
display_key
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def display_key
|
|
29
|
+
say "Current SSH key: #{color(ssh_key.description, :info)}"
|
|
30
|
+
say "Finger print: #{color(ssh_key.fingerprint, :info)}"
|
|
31
|
+
rescue Travis::Client::NotFound
|
|
32
|
+
say "No custom SSH key installed."
|
|
33
|
+
exit 1 if check?
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def update_key(value, file)
|
|
37
|
+
error "#{file} does not look like a private key" unless value.lines.first =~ /PRIVATE KEY/
|
|
38
|
+
value = remove_passphrase(value)
|
|
39
|
+
self.description ||= ask("Key description: ") { |q| q.default = "Custom Key" } if interactive?
|
|
40
|
+
say "Updating ssh key for #{color slug, :info} with key from #{color file, :info}"
|
|
41
|
+
empty_line
|
|
42
|
+
ssh_key.update(:value => value, :description => description || file)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def delete_key
|
|
46
|
+
return if interactive? and not danger_zone? "Remove SSH key for #{color slug, :info}?"
|
|
47
|
+
say "Removing ssh key for #{color slug, :info}"
|
|
48
|
+
ssh_key.delete
|
|
49
|
+
rescue Travis::Client::NotFound
|
|
50
|
+
warn "no key found to remove"
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def generate_key
|
|
54
|
+
github.with_basic_auth do |gh|
|
|
55
|
+
login = gh['user']['login']
|
|
56
|
+
check_access(gh)
|
|
57
|
+
empty_line
|
|
58
|
+
|
|
59
|
+
say "Generating RSA key."
|
|
60
|
+
private_key = Tools::SSLKey.generate_rsa
|
|
61
|
+
self.description ||= "key for fetching dependencies for #{slug} via #{login}"
|
|
62
|
+
|
|
63
|
+
say "Uploading public key to GitHub."
|
|
64
|
+
gh.post("/user/keys", :title => "#{description} (Travis CI)", :key => Tools::SSLKey.rsa_ssh(private_key.public_key))
|
|
65
|
+
|
|
66
|
+
say "Uploading private key to Travis CI."
|
|
67
|
+
ssh_key.update(:value => private_key.to_s, :description => description)
|
|
68
|
+
|
|
69
|
+
empty_line
|
|
70
|
+
say "You can store the private key to reuse it for other repositories (travis sshkey --upload FILE)."
|
|
71
|
+
if agree("Store private key? ") { |q| q.default = "no" }
|
|
72
|
+
path = ask("Path: ") { |q| q.default = "id_travis_rsa" }
|
|
73
|
+
File.write(path, private_key.to_s)
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def remove_passphrase(value)
|
|
79
|
+
return value unless Tools::SSLKey.has_passphrase? value
|
|
80
|
+
return Tools::SSLKey.remove_passphrase(value, passphrase) || error("wrong pass phrase") if passphrase
|
|
81
|
+
error "Key is encrypted, but missing --passphrase option" unless interactive?
|
|
82
|
+
say "The private key is protected by a pass phrase."
|
|
83
|
+
result = Tools::SSLKey.remove_passphrase(value, ask("Enter pass phrase: ") { |q| q.echo = "*" }) until result
|
|
84
|
+
empty_line
|
|
85
|
+
result
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def check_access(gh)
|
|
89
|
+
gh["repos/#{slug}"]
|
|
90
|
+
rescue GH::Error
|
|
91
|
+
error "GitHub account has no read access to #{color slug, :bold}"
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def github
|
|
95
|
+
@github ||= begin
|
|
96
|
+
load_gh
|
|
97
|
+
Tools::Github.new(session.config['github']) do |g|
|
|
98
|
+
g.note = "token for fetching dependencies for #{slug} (Travis CI)"
|
|
99
|
+
g.explode = explode?
|
|
100
|
+
g.ask_login = proc { ask("Username: ") }
|
|
101
|
+
g.ask_password = proc { |user| ask("Password for #{user}: ") { |q| q.echo = "*" } }
|
|
102
|
+
g.ask_otp = proc { |user| ask("Two-factor authentication code for #{user}: ") }
|
|
103
|
+
g.login_header = proc { login_header }
|
|
104
|
+
g.debug = proc { |log| debug(log) }
|
|
105
|
+
g.after_tokens = proc { g.explode = true and error("no suitable github token found") }
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def login_header
|
|
111
|
+
say "We need the #{color("GitHub login", :important)} for the account you want to add the key to."
|
|
112
|
+
say "This information will #{color("not be sent to Travis CI", :important)}, only to #{color(github_endpoint.host, :info)}."
|
|
113
|
+
say "The password will not be displayed."
|
|
114
|
+
empty_line
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
require 'travis/cli'
|
|
2
|
+
|
|
3
|
+
module Travis
|
|
4
|
+
module CLI
|
|
5
|
+
class Status < RepoCommand
|
|
6
|
+
description "checks status of the latest build"
|
|
7
|
+
|
|
8
|
+
on '-x', '--[no-]exit-code', 'sets the exit code to 1 if the build failed'
|
|
9
|
+
on '-q', '--[no-]quiet', 'does not print anything'
|
|
10
|
+
on '-p', '--[no-]fail-pending', 'sets the status code to 1 if the build is pending'
|
|
11
|
+
|
|
12
|
+
def run
|
|
13
|
+
say color(last_build.state, last_build.color), "build ##{last_build.number} %s" unless quiet?
|
|
14
|
+
exit 1 if exit_code? and last_build.unsuccessful?
|
|
15
|
+
exit 1 if fail_pending? and last_build.pending?
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
require 'travis/cli'
|
|
2
|
+
|
|
3
|
+
module Travis
|
|
4
|
+
module CLI
|
|
5
|
+
class Sync < ApiCommand
|
|
6
|
+
description "triggers a new sync with GitHub"
|
|
7
|
+
|
|
8
|
+
on '-c', '--check', 'only check the sync status'
|
|
9
|
+
on '-b', '--background', 'will trigger sync but not block until sync is done'
|
|
10
|
+
on '-f', '--force', 'will force sync, even if one is already running'
|
|
11
|
+
|
|
12
|
+
def run
|
|
13
|
+
authenticate
|
|
14
|
+
|
|
15
|
+
if check?
|
|
16
|
+
say "#{"not " unless user.syncing?}syncing", "#{user.login} is currently %s"
|
|
17
|
+
elsif user.syncing? and not force?
|
|
18
|
+
error "user is already syncing"
|
|
19
|
+
elsif background?
|
|
20
|
+
say "starting synchronization"
|
|
21
|
+
sync(false)
|
|
22
|
+
else
|
|
23
|
+
say "synchronizing: "
|
|
24
|
+
sync
|
|
25
|
+
say color(" done", :success)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
require 'travis/cli'
|
|
2
|
+
|
|
3
|
+
module Travis
|
|
4
|
+
module CLI
|
|
5
|
+
class Whatsup < ApiCommand
|
|
6
|
+
description "lists most recent builds"
|
|
7
|
+
on('-m', '--my-repos', 'Only display my own repositories')
|
|
8
|
+
|
|
9
|
+
def run
|
|
10
|
+
say "nothing to show" if recent.empty?
|
|
11
|
+
|
|
12
|
+
recent.each do |repo|
|
|
13
|
+
say [
|
|
14
|
+
color(repo.slug, [:bold, repo.color]),
|
|
15
|
+
color("#{repo.last_build.state}: ##{repo.last_build.number}", repo.color)
|
|
16
|
+
].join(" ")
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
private
|
|
21
|
+
|
|
22
|
+
def recent
|
|
23
|
+
@recent ||= begin
|
|
24
|
+
recent = my_repos ? repos : repos(:member => user.login)
|
|
25
|
+
recent.select { |repo| repo.last_build }
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
require 'travis/cli'
|
|
2
|
+
|
|
3
|
+
module Travis
|
|
4
|
+
module CLI
|
|
5
|
+
class Whoami < ApiCommand
|
|
6
|
+
description "outputs the current user"
|
|
7
|
+
|
|
8
|
+
def run
|
|
9
|
+
authenticate
|
|
10
|
+
name = " (#{user.name})" unless user.name.to_s.empty?
|
|
11
|
+
say user.login, "You are %s" << name.to_s
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
data/lib/travis/cli.rb
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
begin
|
|
2
|
+
require 'travis/client'
|
|
3
|
+
rescue LoadError => e
|
|
4
|
+
if e.message == 'no such file to load -- json'
|
|
5
|
+
$stderr.puts "You should either run `gem install json` or upgrade your Ruby version!"
|
|
6
|
+
exit 1
|
|
7
|
+
else
|
|
8
|
+
raise e
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
require 'stringio'
|
|
13
|
+
|
|
14
|
+
module Travis
|
|
15
|
+
module CLI
|
|
16
|
+
autoload :Token, 'travis/cli/token'
|
|
17
|
+
autoload :ApiCommand, 'travis/cli/api_command'
|
|
18
|
+
autoload :Accounts, 'travis/cli/accounts'
|
|
19
|
+
autoload :Branches, 'travis/cli/branches'
|
|
20
|
+
autoload :Cache, 'travis/cli/cache'
|
|
21
|
+
autoload :Cancel, 'travis/cli/cancel'
|
|
22
|
+
autoload :Command, 'travis/cli/command'
|
|
23
|
+
autoload :Console, 'travis/cli/console'
|
|
24
|
+
autoload :Disable, 'travis/cli/disable'
|
|
25
|
+
autoload :Enable, 'travis/cli/enable'
|
|
26
|
+
autoload :Encrypt, 'travis/cli/encrypt'
|
|
27
|
+
autoload :EncryptFile, 'travis/cli/encrypt_file'
|
|
28
|
+
autoload :Endpoint, 'travis/cli/endpoint'
|
|
29
|
+
autoload :Env, 'travis/cli/env'
|
|
30
|
+
autoload :Help, 'travis/cli/help'
|
|
31
|
+
autoload :History, 'travis/cli/history'
|
|
32
|
+
autoload :Init, 'travis/cli/init'
|
|
33
|
+
autoload :Lint, 'travis/cli/lint'
|
|
34
|
+
autoload :Login, 'travis/cli/login'
|
|
35
|
+
autoload :Logout, 'travis/cli/logout'
|
|
36
|
+
autoload :Logs, 'travis/cli/logs'
|
|
37
|
+
autoload :Monitor, 'travis/cli/monitor'
|
|
38
|
+
autoload :Open, 'travis/cli/open'
|
|
39
|
+
autoload :Parser, 'travis/cli/parser'
|
|
40
|
+
autoload :Pubkey, 'travis/cli/pubkey'
|
|
41
|
+
autoload :Raw, 'travis/cli/raw'
|
|
42
|
+
autoload :RepoCommand, 'travis/cli/repo_command'
|
|
43
|
+
autoload :Report, 'travis/cli/report'
|
|
44
|
+
autoload :Repos, 'travis/cli/repos'
|
|
45
|
+
autoload :Restart, 'travis/cli/restart'
|
|
46
|
+
autoload :Requests, 'travis/cli/requests'
|
|
47
|
+
autoload :Settings, 'travis/cli/settings'
|
|
48
|
+
autoload :Setup, 'travis/cli/setup'
|
|
49
|
+
autoload :Show, 'travis/cli/show'
|
|
50
|
+
autoload :Sshkey, 'travis/cli/sshkey'
|
|
51
|
+
autoload :Status, 'travis/cli/status'
|
|
52
|
+
autoload :Sync, 'travis/cli/sync'
|
|
53
|
+
autoload :Version, 'travis/cli/version'
|
|
54
|
+
autoload :Whatsup, 'travis/cli/whatsup'
|
|
55
|
+
autoload :Whoami, 'travis/cli/whoami'
|
|
56
|
+
|
|
57
|
+
extend self
|
|
58
|
+
|
|
59
|
+
def run(*args)
|
|
60
|
+
args, opts = preparse(args)
|
|
61
|
+
name = args.shift unless args.empty?
|
|
62
|
+
command = command(name).new(opts)
|
|
63
|
+
command.parse(args)
|
|
64
|
+
command.execute
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def command(name)
|
|
68
|
+
const_name = command_name(name)
|
|
69
|
+
constant = CLI.const_get(const_name) if const_name =~ /^[A-Z][A-Za-z]+$/ and const_defined? const_name
|
|
70
|
+
if command? constant
|
|
71
|
+
constant
|
|
72
|
+
else
|
|
73
|
+
$stderr.puts "unknown command #{name}"
|
|
74
|
+
exit 1
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def commands
|
|
79
|
+
CLI.constants.map { |n| try_const_get(n) }.select { |c| command? c }
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def silent
|
|
83
|
+
stderr, $stderr = $stderr, dummy_io
|
|
84
|
+
stdout, $stdout = $stdout, dummy_io
|
|
85
|
+
yield
|
|
86
|
+
ensure
|
|
87
|
+
$stderr = stderr if stderr
|
|
88
|
+
$stdout = stdout if stdout
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
private
|
|
92
|
+
|
|
93
|
+
def try_const_get(name)
|
|
94
|
+
CLI.const_get(name)
|
|
95
|
+
rescue Exception
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def dummy_io
|
|
99
|
+
return StringIO.new unless defined? IO::NULL and IO::NULL
|
|
100
|
+
File.open(IO::NULL, 'w')
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def command?(constant)
|
|
104
|
+
constant.is_a? Class and constant < Command and not constant.abstract?
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def command_name(name)
|
|
108
|
+
case name
|
|
109
|
+
when nil, '-h', '-?' then 'Help'
|
|
110
|
+
when '-v' then 'Version'
|
|
111
|
+
when /^--/ then command_name(name[2..-1])
|
|
112
|
+
else name.split('-').map(&:capitalize).join
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
# can't use flatten as it will flatten hashes
|
|
117
|
+
def preparse(unparsed, args = [], opts = {})
|
|
118
|
+
case unparsed
|
|
119
|
+
when Hash then opts.merge! unparsed
|
|
120
|
+
when Array then unparsed.each { |e| preparse(e, args, opts) }
|
|
121
|
+
else args << unparsed.to_s
|
|
122
|
+
end
|
|
123
|
+
[args, opts]
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
end
|