travis 1.11.0 → 1.12.0
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 +18 -4
- data/Rakefile +22 -20
- data/bin/travis +5 -3
- data/examples/org_overview.rb +2 -0
- data/examples/pro_auth.rb +3 -1
- data/examples/stream.rb +5 -3
- data/lib/travis/auto_login.rb +2 -0
- data/lib/travis/cli/accounts.rb +12 -9
- data/lib/travis/cli/api_command.rb +85 -81
- data/lib/travis/cli/branches.rb +8 -6
- data/lib/travis/cli/cache.rb +48 -44
- data/lib/travis/cli/cancel.rb +4 -2
- data/lib/travis/cli/command.rb +170 -142
- data/lib/travis/cli/console.rb +5 -5
- data/lib/travis/cli/disable.rb +4 -2
- data/lib/travis/cli/enable.rb +14 -12
- data/lib/travis/cli/encrypt.rb +57 -57
- data/lib/travis/cli/encrypt_file.rb +29 -18
- data/lib/travis/cli/endpoint.rb +9 -7
- data/lib/travis/cli/env.rb +13 -8
- data/lib/travis/cli/help.rb +10 -8
- data/lib/travis/cli/history.rb +19 -15
- data/lib/travis/cli/init.rb +27 -24
- data/lib/travis/cli/lint.rb +10 -8
- data/lib/travis/cli/login.rb +17 -11
- data/lib/travis/cli/logout.rb +4 -2
- data/lib/travis/cli/logs.rb +28 -19
- data/lib/travis/cli/monitor.rb +11 -8
- data/lib/travis/cli/open.rb +17 -14
- data/lib/travis/cli/parser.rb +2 -0
- data/lib/travis/cli/pubkey.rb +13 -11
- data/lib/travis/cli/raw.rb +4 -3
- data/lib/travis/cli/repo_command.rb +123 -112
- data/lib/travis/cli/report.rb +40 -33
- data/lib/travis/cli/repos.rb +14 -9
- data/lib/travis/cli/requests.rb +13 -12
- data/lib/travis/cli/restart.rb +4 -2
- data/lib/travis/cli/settings.rb +41 -35
- data/lib/travis/cli/setup/anynines.rb +7 -6
- data/lib/travis/cli/setup/appfog.rb +6 -4
- data/lib/travis/cli/setup/artifacts.rb +7 -5
- data/lib/travis/cli/setup/biicode.rb +6 -4
- data/lib/travis/cli/setup/cloud_66.rb +6 -4
- data/lib/travis/cli/setup/cloud_control.rb +8 -6
- data/lib/travis/cli/setup/cloud_files.rb +7 -5
- data/lib/travis/cli/setup/cloud_foundry.rb +9 -7
- data/lib/travis/cli/setup/code_deploy.rb +33 -29
- data/lib/travis/cli/setup/deis.rb +8 -6
- data/lib/travis/cli/setup/divshot.rb +20 -18
- data/lib/travis/cli/setup/elastic_beanstalk.rb +10 -8
- data/lib/travis/cli/setup/engine_yard.rb +9 -7
- data/lib/travis/cli/setup/gcs.rb +9 -7
- data/lib/travis/cli/setup/hackage.rb +6 -4
- data/lib/travis/cli/setup/heroku.rb +10 -4
- data/lib/travis/cli/setup/modulus.rb +5 -3
- data/lib/travis/cli/setup/ninefold.rb +7 -5
- data/lib/travis/cli/setup/nodejitsu.rb +6 -4
- data/lib/travis/cli/setup/npm.rb +6 -4
- data/lib/travis/cli/setup/open_shift.rb +8 -6
- data/lib/travis/cli/setup/opsworks.rb +24 -22
- data/lib/travis/cli/setup/pypi.rb +7 -5
- data/lib/travis/cli/setup/releases.rb +6 -6
- data/lib/travis/cli/setup/ruby_gems.rb +7 -5
- data/lib/travis/cli/setup/s3.rb +12 -8
- data/lib/travis/cli/setup/sauce_connect.rb +7 -5
- data/lib/travis/cli/setup/service.rb +36 -25
- data/lib/travis/cli/setup.rb +7 -3
- data/lib/travis/cli/show.rb +10 -8
- data/lib/travis/cli/sshkey.rb +31 -28
- data/lib/travis/cli/status.rb +5 -3
- data/lib/travis/cli/sync.rb +9 -7
- data/lib/travis/cli/token.rb +4 -2
- data/lib/travis/cli/version.rb +4 -3
- data/lib/travis/cli/whatsup.rb +10 -8
- data/lib/travis/cli/whoami.rb +2 -2
- data/lib/travis/cli.rb +39 -36
- data/lib/travis/client/account.rb +8 -6
- data/lib/travis/client/artifact.rb +16 -12
- data/lib/travis/client/auto_login.rb +7 -4
- data/lib/travis/client/broadcast.rb +2 -0
- data/lib/travis/client/build.rb +7 -3
- data/lib/travis/client/cache.rb +4 -2
- data/lib/travis/client/commit.rb +5 -2
- data/lib/travis/client/entity.rb +50 -46
- data/lib/travis/client/env_var.rb +13 -8
- data/lib/travis/client/error.rb +5 -3
- data/lib/travis/client/has_uuid.rb +3 -1
- data/lib/travis/client/job.rb +8 -3
- data/lib/travis/client/lint_result.rb +2 -0
- data/lib/travis/client/listener.rb +70 -55
- data/lib/travis/client/methods.rb +10 -5
- data/lib/travis/client/namespace.rb +20 -16
- data/lib/travis/client/not_loadable.rb +3 -1
- data/lib/travis/client/repository.rb +34 -22
- data/lib/travis/client/request.rb +5 -2
- data/lib/travis/client/restartable.rb +2 -0
- data/lib/travis/client/session.rb +118 -88
- data/lib/travis/client/settings.rb +8 -3
- data/lib/travis/client/singleton_setting.rb +2 -0
- data/lib/travis/client/ssh_key.rb +2 -0
- data/lib/travis/client/states.rb +8 -6
- data/lib/travis/client/user.rb +2 -0
- data/lib/travis/client/weak_entity.rb +6 -3
- data/lib/travis/client.rb +4 -1
- data/lib/travis/pro/auto_login.rb +2 -0
- data/lib/travis/pro.rb +2 -0
- data/lib/travis/tools/assets.rb +6 -3
- data/lib/travis/tools/completion.rb +10 -6
- data/lib/travis/tools/formatter.rb +20 -14
- data/lib/travis/tools/github.rb +59 -49
- data/lib/travis/tools/notification.rb +18 -13
- data/lib/travis/tools/safe_string.rb +4 -1
- data/lib/travis/tools/ssl_key.rb +5 -2
- data/lib/travis/tools/system.rb +11 -6
- data/lib/travis/version.rb +3 -1
- data/lib/travis.rb +3 -1
- data/spec/cli/api_command_spec.rb +11 -8
- data/spec/cli/cancel_spec.rb +2 -4
- data/spec/cli/encrypt_file_spec.rb +9 -7
- data/spec/cli/encrypt_spec.rb +19 -17
- data/spec/cli/endpoint_spec.rb +12 -10
- data/spec/cli/help_spec.rb +14 -12
- data/spec/cli/history_spec.rb +2 -0
- data/spec/cli/init_spec.rb +35 -33
- data/spec/cli/logs_spec.rb +2 -0
- data/spec/cli/open_spec.rb +6 -4
- data/spec/cli/repo_command_spec.rb +8 -4
- data/spec/cli/restart_spec.rb +2 -4
- data/spec/cli/setup/service_spec.rb +17 -18
- data/spec/cli/setup_spec.rb +2 -4
- data/spec/cli/show_spec.rb +4 -2
- data/spec/cli/status_spec.rb +7 -5
- data/spec/cli/token_spec.rb +7 -5
- data/spec/cli/version_spec.rb +2 -0
- data/spec/cli/whoami_spec.rb +9 -7
- data/spec/client/account_spec.rb +28 -20
- data/spec/client/auto_login_spec.rb +12 -9
- data/spec/client/broadcast_spec.rb +5 -3
- data/spec/client/build_spec.rb +28 -24
- data/spec/client/commit_spec.rb +17 -14
- data/spec/client/job_spec.rb +27 -23
- data/spec/client/methods_spec.rb +8 -4
- data/spec/client/namespace_spec.rb +8 -4
- data/spec/client/repository_spec.rb +33 -30
- data/spec/client/session_spec.rb +71 -67
- data/spec/client/user_spec.rb +13 -10
- data/spec/client_spec.rb +6 -4
- data/spec/pro_spec.rb +5 -3
- data/spec/spec_helper.rb +3 -1
- data/spec/support/fake_api.rb +662 -662
- data/spec/support/fake_github.rb +6 -3
- data/spec/support/helpers.rb +13 -8
- data/spec/travis_spec.rb +5 -3
- data/travis.gemspec +400 -399
- metadata +30 -50
data/lib/travis/cli/login.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'travis/cli'
|
2
4
|
require 'travis/tools/github'
|
3
5
|
require 'json'
|
@@ -7,16 +9,17 @@ module Travis
|
|
7
9
|
class Login < ApiCommand
|
8
10
|
skip :authenticate
|
9
11
|
|
10
|
-
description
|
12
|
+
description 'authenticates against the API and stores the token'
|
11
13
|
on('-g', '--github-token TOKEN', 'identify by GitHub token')
|
12
|
-
on('-T', '--auto-token',
|
14
|
+
on('-T', '--auto-token',
|
15
|
+
'try to figure out who you are automatically (might send another apps token to Travis, token will not be stored)')
|
13
16
|
on('--list-github-token', 'instead of actually logging in, list found GitHub tokens')
|
14
17
|
on('--skip-token-check', 'don\'t verify the token with github')
|
15
18
|
|
16
19
|
attr_accessor :user_login
|
17
20
|
|
18
21
|
def list_token
|
19
|
-
github.after_tokens = proc {
|
22
|
+
github.after_tokens = proc {}
|
20
23
|
github.each_token do |token|
|
21
24
|
say token
|
22
25
|
end
|
@@ -26,7 +29,10 @@ module Travis
|
|
26
29
|
session.access_token = nil
|
27
30
|
github.with_token do |token|
|
28
31
|
endpoint_config['access_token'] = github_auth(token)
|
29
|
-
|
32
|
+
if user_login && (user.login != user_login)
|
33
|
+
error(format('user mismatch: logged in as %p instead of %p', user.login,
|
34
|
+
user_login))
|
35
|
+
end
|
30
36
|
unless user.correct_scopes?
|
31
37
|
error(
|
32
38
|
"#{user.login} has not granted Travis CI the required permissions. " \
|
@@ -37,9 +43,9 @@ module Travis
|
|
37
43
|
success("Successfully logged in as #{user.login}!")
|
38
44
|
end
|
39
45
|
|
40
|
-
|
41
|
-
|
42
|
-
|
46
|
+
return if session.access_token
|
47
|
+
|
48
|
+
raise Travis::Client::GitHubLoginFailed, 'all GitHub tokens given were invalid'
|
43
49
|
end
|
44
50
|
|
45
51
|
def run
|
@@ -58,15 +64,15 @@ module Travis
|
|
58
64
|
g.drop_token = !list_github_token
|
59
65
|
g.login_header = proc { login_header }
|
60
66
|
g.debug = proc { |log| debug(log) }
|
61
|
-
g.after_tokens = proc { g.explode = true and error(
|
67
|
+
g.after_tokens = proc { g.explode = true and error('no suitable github token found') }
|
62
68
|
end
|
63
69
|
end
|
64
70
|
end
|
65
71
|
|
66
72
|
def login_header
|
67
|
-
say
|
68
|
-
say
|
69
|
-
say "Try running with #{color(
|
73
|
+
say 'GitHub deprecated its Authorizations API exchanging a password for a token.'
|
74
|
+
say 'Please visit https://github.blog/2020-07-30-token-authentication-requirements-for-api-and-git-operations for more information.'
|
75
|
+
say "Try running with #{color('--github-token', :info)} or #{color('--auto-token', :info)} ."
|
70
76
|
end
|
71
77
|
end
|
72
78
|
end
|
data/lib/travis/cli/logout.rb
CHANGED
@@ -1,14 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'travis/cli'
|
2
4
|
|
3
5
|
module Travis
|
4
6
|
module CLI
|
5
7
|
class Logout < ApiCommand
|
6
|
-
description
|
8
|
+
description 'deletes the stored API token'
|
7
9
|
|
8
10
|
def run
|
9
11
|
session.logout
|
10
12
|
endpoint_config.delete('access_token')
|
11
|
-
success(
|
13
|
+
success('Successfully logged out!')
|
12
14
|
end
|
13
15
|
end
|
14
16
|
end
|
data/lib/travis/cli/logs.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'travis/cli'
|
2
4
|
require 'travis/tools/safe_string'
|
3
5
|
require 'travis/tools/system'
|
@@ -6,8 +8,12 @@ module Travis
|
|
6
8
|
module CLI
|
7
9
|
class Logs < RepoCommand
|
8
10
|
attr_accessor :delete, :reason
|
9
|
-
|
10
|
-
|
11
|
+
|
12
|
+
description 'streams test logs'
|
13
|
+
on('-d', '--delete [REASON]', 'remove logs') do |c, reason|
|
14
|
+
c.delete = true
|
15
|
+
c.reason = reason
|
16
|
+
end
|
11
17
|
on('-f', '--force', 'do not ask user to confirm deleting the logs')
|
12
18
|
on('--[no-]stream', 'only print current logs, do not stream')
|
13
19
|
|
@@ -25,17 +31,19 @@ module Travis
|
|
25
31
|
|
26
32
|
def delete_log(job)
|
27
33
|
unless force?
|
28
|
-
error
|
29
|
-
error
|
34
|
+
error 'not deleting logs without --force' unless interactive?
|
35
|
+
error 'aborted' unless danger_zone? "Do you really want to delete the build log for #{color(job.inspect_info,
|
36
|
+
:underline)}?"
|
30
37
|
end
|
31
38
|
|
32
|
-
warn "deleting log for #{color(job.inspect_info, [
|
39
|
+
warn "deleting log for #{color(job.inspect_info, %i[bold info])}"
|
33
40
|
job.delete_log(reason || {})
|
34
41
|
end
|
35
42
|
|
36
43
|
def display_log(job)
|
37
|
-
info "displaying logs for #{color(job.inspect_info, [
|
44
|
+
info "displaying logs for #{color(job.inspect_info, %i[bold info])}"
|
38
45
|
return print_log(job.log.body) unless stream?
|
46
|
+
|
39
47
|
job.log.body { |part| print_log(part) }
|
40
48
|
ensure
|
41
49
|
print "\e[0m" if interactive?
|
@@ -47,19 +55,20 @@ module Travis
|
|
47
55
|
|
48
56
|
private
|
49
57
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
58
|
+
def job(number)
|
59
|
+
number = last_build.number + number if number.start_with? '.'
|
60
|
+
job = super(number) || build(number) || branch(number)
|
61
|
+
job = job.jobs.first if job.respond_to? :jobs
|
62
|
+
job
|
63
|
+
end
|
56
64
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
65
|
+
def check_websocket
|
66
|
+
require 'websocket-native' if stream?
|
67
|
+
rescue LoadError => e
|
68
|
+
raise e if e.respond_to?(:path) && (e.path != 'websocket-native')
|
69
|
+
|
70
|
+
info 'speed up log streaming by installing the websocket-native gem'
|
71
|
+
end
|
63
72
|
end
|
64
73
|
end
|
65
|
-
end
|
74
|
+
end
|
data/lib/travis/cli/monitor.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'travis/cli'
|
2
4
|
require 'travis/tools/notification'
|
3
5
|
|
@@ -9,10 +11,10 @@ module Travis
|
|
9
11
|
|
10
12
|
on('-r', '--repo SLUG', 'monitor given repository (can be used more than once)') do |c, slug|
|
11
13
|
c.repos << slug
|
12
|
-
c.send(:error,
|
14
|
+
c.send(:error, 'SLUG should be of the form OWNER/REPO') unless slug.split('/').compact.size == 2
|
13
15
|
end
|
14
16
|
|
15
|
-
types = Tools::Notification::DEFAULT.map(&:to_s).join(
|
17
|
+
types = Tools::Notification::DEFAULT.map(&:to_s).join(', ')
|
16
18
|
on('-n', '--[no-]notify [TYPE]', "send out desktop notifications (optional type: #{types})") do |c, type|
|
17
19
|
c.setup_notification(type)
|
18
20
|
end
|
@@ -75,6 +77,7 @@ module Travis
|
|
75
77
|
|
76
78
|
def monitor?(entity)
|
77
79
|
return true if all?
|
80
|
+
|
78
81
|
entity.pull_request? ? pull? : push?
|
79
82
|
end
|
80
83
|
|
@@ -84,26 +87,26 @@ module Travis
|
|
84
87
|
color(entity.inspect_info, [entity.color, :bold]),
|
85
88
|
color(entity.state, entity.color),
|
86
89
|
color(entity.commit.subject, entity.color)
|
87
|
-
].join(
|
90
|
+
].join(' ')
|
88
91
|
notification.notify(entity.repository.slug, [
|
89
92
|
entity.class.name[/[^:]+$/],
|
90
93
|
entity.number,
|
91
|
-
entity.state
|
94
|
+
"#{entity.state}:",
|
92
95
|
entity.commit.subject
|
93
|
-
].join(
|
96
|
+
].join(' '))
|
94
97
|
end
|
95
98
|
|
96
99
|
def handle_event(event)
|
97
100
|
entity = event.job || event.build
|
98
101
|
time = entity.finished_at || entity.started_at
|
99
102
|
display(entity, time) if monitor? entity
|
100
|
-
rescue Travis::Client::Error =>
|
101
|
-
raise
|
103
|
+
rescue Travis::Client::Error => e
|
104
|
+
raise e if explode?
|
102
105
|
end
|
103
106
|
|
104
107
|
def run
|
105
108
|
listen(*repos) do |listener|
|
106
|
-
listener.on_connect { say description, "Monitoring #{
|
109
|
+
listener.on_connect { say description, "Monitoring #{'builds for ' if builds?}%s:" }
|
107
110
|
listener.on(*events) { |e| handle_event(e) }
|
108
111
|
end
|
109
112
|
end
|
data/lib/travis/cli/open.rb
CHANGED
@@ -1,10 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'travis/cli'
|
2
4
|
require 'launchy'
|
3
5
|
|
4
6
|
module Travis
|
5
7
|
module CLI
|
6
8
|
class Open < RepoCommand
|
7
|
-
description
|
9
|
+
description 'opens a build or job in the browser'
|
8
10
|
|
9
11
|
on('-g', '--github', 'Open the corresponding project, compare view or pull request on GitHub')
|
10
12
|
on('-p', '--print', 'Print out the URL instead of opening it in a browser')
|
@@ -12,7 +14,7 @@ module Travis
|
|
12
14
|
def run(number = nil)
|
13
15
|
url = url_for(number)
|
14
16
|
if print?
|
15
|
-
say url,
|
17
|
+
say url, 'web view: %s'
|
16
18
|
else
|
17
19
|
Launchy.open(url)
|
18
20
|
end
|
@@ -20,20 +22,21 @@ module Travis
|
|
20
22
|
|
21
23
|
private
|
22
24
|
|
23
|
-
|
24
|
-
|
25
|
-
entity = job(number) || build(number)
|
26
|
-
error "could not find job or build #{repository.slug}##{number}" unless entity
|
27
|
-
github ? entity.commit.compare_url : "#{repo_url}/#{entity.class.many}/#{entity.id}"
|
28
|
-
end
|
25
|
+
def url_for(number)
|
26
|
+
return repo_url unless number
|
29
27
|
|
30
|
-
|
31
|
-
|
32
|
-
|
28
|
+
entity = job(number) || build(number)
|
29
|
+
error "could not find job or build #{repository.slug}##{number}" unless entity
|
30
|
+
github ? entity.commit.compare_url : "#{repo_url}/#{entity.class.many}/#{entity.id}"
|
31
|
+
end
|
33
32
|
|
34
|
-
|
35
|
-
|
36
|
-
|
33
|
+
def repo_url
|
34
|
+
"https://#{host}/#{slug}"
|
35
|
+
end
|
36
|
+
|
37
|
+
def host
|
38
|
+
github ? 'github.com' : session.config['host']
|
39
|
+
end
|
37
40
|
end
|
38
41
|
end
|
39
42
|
end
|
data/lib/travis/cli/parser.rb
CHANGED
data/lib/travis/cli/pubkey.rb
CHANGED
@@ -1,13 +1,15 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
2
3
|
require 'travis/cli'
|
3
4
|
|
4
5
|
module Travis
|
5
6
|
module CLI
|
6
7
|
class Pubkey < RepoCommand
|
7
8
|
attr_accessor :key_format
|
9
|
+
|
8
10
|
description "prints out a repository's public key"
|
9
|
-
on('-p', '--pem', 'encode in format used by pem') { |c,_| c.key_format = :pem }
|
10
|
-
on('-f', '--fingerprint', 'display fingerprint') { |c,_| c.key_format = :fingerprint }
|
11
|
+
on('-p', '--pem', 'encode in format used by pem') { |c, _| c.key_format = :pem }
|
12
|
+
on('-f', '--fingerprint', 'display fingerprint') { |c, _| c.key_format = :fingerprint }
|
11
13
|
|
12
14
|
def run
|
13
15
|
error "#{key_format} format not supported by #{api_endpoint}" unless key
|
@@ -16,15 +18,15 @@ module Travis
|
|
16
18
|
|
17
19
|
private
|
18
20
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
end
|
21
|
+
def key
|
22
|
+
key = repository.public_key
|
23
|
+
case self.key_format ||= :ssh
|
24
|
+
when :fingerprint then key.fingerprint
|
25
|
+
when :pem then key.to_s
|
26
|
+
when :ssh then key.to_ssh
|
27
|
+
else raise "unknown format #{key_format}"
|
27
28
|
end
|
29
|
+
end
|
28
30
|
end
|
29
31
|
end
|
30
32
|
end
|
data/lib/travis/cli/raw.rb
CHANGED
@@ -1,10 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'travis/cli'
|
2
|
-
require 'pp'
|
3
4
|
|
4
5
|
module Travis
|
5
6
|
module CLI
|
6
7
|
class Raw < ApiCommand
|
7
|
-
description
|
8
|
+
description 'makes an (authenticated) API call and prints out the result'
|
8
9
|
|
9
10
|
skip :authenticate
|
10
11
|
on('--[no-]json', 'display as json')
|
@@ -13,7 +14,7 @@ module Travis
|
|
13
14
|
reply = session.get_raw(resource)
|
14
15
|
json? ? say(reply.to_json) : pp(reply)
|
15
16
|
rescue Travis::Client::NotFound
|
16
|
-
error
|
17
|
+
error 'resource not found'
|
17
18
|
end
|
18
19
|
end
|
19
20
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'travis/cli'
|
2
4
|
require 'yaml'
|
3
5
|
|
@@ -9,7 +11,7 @@ module Travis
|
|
9
11
|
on('-g', '--github-token TOKEN', 'identify by GitHub token')
|
10
12
|
on('-r', '--repo SLUG', 'repository to use (will try to detect from current git clone)') do |c, slug|
|
11
13
|
c.slug = slug
|
12
|
-
c.error
|
14
|
+
c.error 'SLUG should be of the form OWNER/REPO' unless slug.split('/').compact.size == 2
|
13
15
|
end
|
14
16
|
on('-R', '--store-repo SLUG', 'like --repo, but remembers value for current directory') do |c, slug|
|
15
17
|
c.slug = slug
|
@@ -17,12 +19,15 @@ module Travis
|
|
17
19
|
end
|
18
20
|
|
19
21
|
attr_accessor :slug
|
22
|
+
|
20
23
|
abstract
|
21
24
|
|
22
25
|
def setup
|
23
26
|
setup_enterprise
|
24
|
-
|
25
|
-
|
27
|
+
unless self.slug ||= find_slug
|
28
|
+
error "Can't figure out GitHub repo name. Ensure you're in the repo directory, or specify the repo name via the -r option (e.g. travis <command> -r <owner>/<repo>)"
|
29
|
+
end
|
30
|
+
error "GitHub repo name is invalid, it should be of the form 'owner/repo'" unless self.slug.include?('/')
|
26
31
|
self.api_endpoint = detect_api_endpoint
|
27
32
|
super
|
28
33
|
repository.load # makes sure we actually have access to the repo
|
@@ -36,140 +41,146 @@ module Travis
|
|
36
41
|
|
37
42
|
private
|
38
43
|
|
39
|
-
|
40
|
-
|
41
|
-
repository.build(number_or_id)
|
42
|
-
end
|
44
|
+
def build(number_or_id)
|
45
|
+
return super if number_or_id.is_a? Integer
|
43
46
|
|
44
|
-
|
45
|
-
|
46
|
-
repository.job(number_or_id)
|
47
|
-
end
|
47
|
+
repository.build(number_or_id)
|
48
|
+
end
|
48
49
|
|
49
|
-
|
50
|
-
|
51
|
-
end
|
50
|
+
def job(number_or_id)
|
51
|
+
return super if number_or_id.is_a? Integer
|
52
52
|
|
53
|
-
|
54
|
-
|
55
|
-
end
|
53
|
+
repository.job(number_or_id)
|
54
|
+
end
|
56
55
|
|
57
|
-
|
58
|
-
|
59
|
-
|
56
|
+
def branch(name)
|
57
|
+
repository.branch(name)
|
58
|
+
end
|
60
59
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
60
|
+
def last_build
|
61
|
+
repository.last_build or error("no build yet for #{slug}")
|
62
|
+
end
|
63
|
+
|
64
|
+
def detected_endpoint?
|
65
|
+
!explicit_api_endpoint?
|
66
|
+
end
|
67
67
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
if parse_remote(git_info) =~ GIT_REGEX
|
75
|
-
detected_slug = $1
|
76
|
-
if interactive?
|
77
|
-
if agree("Detected repository as #{color(detected_slug, :info)}, is this correct? ") { |q| q.default = 'yes' }
|
78
|
-
detected_slug
|
79
|
-
else
|
80
|
-
ask("Repository slug (owner/name): ") { |q| q.default = detected_slug }
|
81
|
-
end
|
82
|
-
else
|
83
|
-
info "detected repository as #{color(detected_slug, :bold)}"
|
84
|
-
detected_slug
|
85
|
-
end
|
68
|
+
def find_slug
|
69
|
+
load_slug || begin
|
70
|
+
slug = detect_slug
|
71
|
+
if slug
|
72
|
+
interactive? ? store_slug(slug) : slug
|
86
73
|
end
|
87
74
|
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def detect_slug
|
78
|
+
git_head = `git name-rev --name-only HEAD 2>#{IO::NULL}`.chomp
|
79
|
+
git_remote = `git config --get branch.#{git_head}.remote 2>#{IO::NULL}`.chomp
|
80
|
+
git_remote = 'origin' if git_remote.empty?
|
81
|
+
git_info = `git ls-remote --get-url #{git_remote} 2>#{IO::NULL}`.chomp
|
82
|
+
|
83
|
+
return unless parse_remote(git_info) =~ GIT_REGEX
|
88
84
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
85
|
+
detected_slug = ::Regexp.last_match(1)
|
86
|
+
if interactive?
|
87
|
+
if agree("Detected repository as #{color(detected_slug, :info)}, is this correct? ") do |q|
|
88
|
+
q.default = 'yes'
|
89
|
+
end
|
90
|
+
detected_slug
|
94
91
|
else
|
95
|
-
|
92
|
+
ask('Repository slug (owner/name): ') { |q| q.default = detected_slug }
|
96
93
|
end
|
94
|
+
else
|
95
|
+
info "detected repository as #{color(detected_slug, :bold)}"
|
96
|
+
detected_slug
|
97
97
|
end
|
98
|
+
end
|
98
99
|
|
99
|
-
|
100
|
-
|
101
|
-
|
100
|
+
def parse_remote(url)
|
101
|
+
if url =~ /^git@[^:]+:/
|
102
|
+
path = url.split(':').last
|
103
|
+
path = "/#{path}" unless path.start_with?('/')
|
104
|
+
path
|
105
|
+
else
|
106
|
+
URI.parse(url).path
|
102
107
|
end
|
108
|
+
end
|
103
109
|
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
110
|
+
def load_slug
|
111
|
+
stored = `git config --get travis.slug`.chomp
|
112
|
+
stored unless stored.empty?
|
113
|
+
end
|
108
114
|
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
115
|
+
def store_slug(value)
|
116
|
+
`git config travis.slug #{value}` if value
|
117
|
+
value
|
118
|
+
end
|
113
119
|
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
ENV['TRAVIS_ENDPOINT']
|
119
|
-
elsif config['default_endpoint'] and config['default_endpoint'] !~ TRAVIS
|
120
|
-
repo_config['endpoint'] ||= config['default_endpoint']
|
121
|
-
else
|
122
|
-
repo_config['endpoint'] ||= begin
|
123
|
-
load_gh
|
124
|
-
GH.head("/repos/#{slug}")
|
125
|
-
Travis::Client::ORG_URI
|
126
|
-
rescue GH::Error
|
127
|
-
Travis::Client::COM_URI
|
128
|
-
end
|
129
|
-
end
|
130
|
-
end
|
120
|
+
def repo_config
|
121
|
+
config['repos'] ||= {}
|
122
|
+
config['repos'][slug] ||= {}
|
123
|
+
end
|
131
124
|
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
125
|
+
def detect_api_endpoint
|
126
|
+
if explicit_api_endpoint? || enterprise?
|
127
|
+
repo_config['endpoint'] = api_endpoint
|
128
|
+
elsif ENV['TRAVIS_ENDPOINT']
|
129
|
+
ENV['TRAVIS_ENDPOINT']
|
130
|
+
elsif config['default_endpoint'] && config['default_endpoint'] !~ (TRAVIS)
|
131
|
+
repo_config['endpoint'] ||= config['default_endpoint']
|
132
|
+
else
|
133
|
+
repo_config['endpoint'] ||= begin
|
134
|
+
load_gh
|
135
|
+
GH.head("/repos/#{slug}")
|
136
|
+
Travis::Client::ORG_URI
|
137
|
+
rescue GH::Error
|
138
|
+
Travis::Client::COM_URI
|
136
139
|
end
|
137
140
|
end
|
141
|
+
end
|
138
142
|
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
else
|
144
|
-
parent = File.expand_path('..', dir)
|
145
|
-
error "no .travis.yml found" if parent == dir
|
146
|
-
travis_yaml(parent)
|
147
|
-
end
|
143
|
+
def travis_config
|
144
|
+
@travis_config ||= begin
|
145
|
+
payload = YAML.load_file(travis_yaml)
|
146
|
+
payload.respond_to?(:to_hash) ? payload.to_hash : {}
|
148
147
|
end
|
148
|
+
end
|
149
149
|
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
].join("\n\n")
|
159
|
-
proceed = ans =~ /^y/i
|
160
|
-
else
|
161
|
-
proceed = true
|
162
|
-
end
|
163
|
-
|
164
|
-
save_travis_config if proceed
|
150
|
+
def travis_yaml(dir = Dir.pwd)
|
151
|
+
path = File.expand_path('.travis.yml', dir)
|
152
|
+
if File.exist? path
|
153
|
+
path
|
154
|
+
else
|
155
|
+
parent = File.expand_path('..', dir)
|
156
|
+
error 'no .travis.yml found' if parent == dir
|
157
|
+
travis_yaml(parent)
|
165
158
|
end
|
159
|
+
end
|
166
160
|
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
161
|
+
def confirm_and_save_travis_config(confirm = true, _file = travis_yaml)
|
162
|
+
if confirm
|
163
|
+
ans = ask [
|
164
|
+
nil,
|
165
|
+
color("Overwrite the config file #{travis_yaml} with the content below?", %i[info yellow]),
|
166
|
+
color('This reformats the existing file.', %i[info red]),
|
167
|
+
travis_config.to_yaml,
|
168
|
+
color('(y/N)', %i[info yellow])
|
169
|
+
].join("\n\n")
|
170
|
+
proceed = ans =~ /^y/i
|
171
|
+
else
|
172
|
+
proceed = true
|
173
|
+
end
|
174
|
+
|
175
|
+
save_travis_config if proceed
|
176
|
+
end
|
177
|
+
|
178
|
+
def save_travis_config(file = travis_yaml)
|
179
|
+
yaml = travis_config.to_yaml
|
180
|
+
yaml.gsub!(/^(\s+)('on'|true):/, '\\1on:')
|
181
|
+
yaml.gsub!(/\A---\s*\n/, '')
|
182
|
+
File.write(file, yaml)
|
183
|
+
end
|
173
184
|
end
|
174
185
|
end
|
175
186
|
end
|