travis 1.11.1 → 1.12.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +9 -3
- 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 -27
- 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
|