travis-async-listener 1.8.3
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 +2486 -0
- data/Rakefile +63 -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 +4 -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.rb +8 -0
- data/lib/travis/auto_login.rb +3 -0
- data/lib/travis/cli.rb +126 -0
- data/lib/travis/cli/accounts.rb +31 -0
- data/lib/travis/cli/api_command.rb +180 -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 +31 -0
- data/lib/travis/cli/disable.rb +15 -0
- data/lib/travis/cli/enable.rb +31 -0
- data/lib/travis/cli/encrypt.rb +108 -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 +110 -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 +77 -0
- data/lib/travis/cli/setup.rb +66 -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/show.rb +69 -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/client.rb +39 -0
- data/lib/travis/client/account.rb +56 -0
- data/lib/travis/client/annotation.rb +21 -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 +184 -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/pro.rb +5 -0
- data/lib/travis/pro/auto_login.rb +3 -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 +279 -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/spec/cli/cancel_spec.rb +15 -0
- data/spec/cli/encrypt_spec.rb +43 -0
- data/spec/cli/endpoint_spec.rb +34 -0
- data/spec/cli/help_spec.rb +33 -0
- data/spec/cli/history_spec.rb +38 -0
- data/spec/cli/init_spec.rb +226 -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/annotation_spec.rb +14 -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 +738 -0
- data/spec/support/fake_github.rb +24 -0
- data/spec/support/helpers.rb +45 -0
- data/spec/travis_spec.rb +10 -0
- data/travis.gemspec +323 -0
- metadata +489 -0
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
require 'travis/client'
|
|
2
|
+
require 'travis/tools/ssl_key'
|
|
3
|
+
|
|
4
|
+
module Travis
|
|
5
|
+
module Client
|
|
6
|
+
class Repository < Entity
|
|
7
|
+
class Key
|
|
8
|
+
attr_reader :to_s, :fingerprint
|
|
9
|
+
|
|
10
|
+
def initialize(data, fingerprint)
|
|
11
|
+
@to_s = data
|
|
12
|
+
@fingerprint = fingerprint
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def encrypt(value)
|
|
16
|
+
encrypted = to_rsa.public_encrypt(value)
|
|
17
|
+
Base64.encode64(encrypted).gsub(/\s+/, "")
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def to_rsa
|
|
21
|
+
Tools::SSLKey.public_rsa_key(to_s)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def to_ssh
|
|
25
|
+
Tools::SSLKey.rsa_ssh(to_rsa)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def ==(other)
|
|
29
|
+
other.to_s == self
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
include States
|
|
34
|
+
preloadable
|
|
35
|
+
|
|
36
|
+
# @!parse attr_reader :slug, :description
|
|
37
|
+
attributes :slug, :active, :private, :admin, :description, :last_build_id, :last_build_number, :last_build_state, :last_build_duration, :last_build_started_at, :last_build_finished_at, :github_language
|
|
38
|
+
inspect_info :slug
|
|
39
|
+
|
|
40
|
+
time :last_build_finished_at, :last_build_started_at
|
|
41
|
+
|
|
42
|
+
one :repo
|
|
43
|
+
many :repos
|
|
44
|
+
aka :repository, :permissions, :admin, :pull, :push, :hooks
|
|
45
|
+
|
|
46
|
+
has_singleton :ssh_key
|
|
47
|
+
|
|
48
|
+
def initialize(*)
|
|
49
|
+
super
|
|
50
|
+
attributes['active'] = attributes['private'] = attributes['admin'] = nil
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def public_key
|
|
54
|
+
attributes["public_key"] ||= begin
|
|
55
|
+
payload = session.get_raw("/repos/#{id}/key")
|
|
56
|
+
Key.new(payload.fetch('key'), payload['fingerprint'])
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def name
|
|
61
|
+
slug[/[^\/]+$/]
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def public_key=(key)
|
|
65
|
+
# ignored
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
alias key public_key
|
|
69
|
+
alias key= public_key=
|
|
70
|
+
|
|
71
|
+
def encrypt(value)
|
|
72
|
+
key.encrypt(value)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# @!parse attr_reader :last_build
|
|
76
|
+
def last_build
|
|
77
|
+
return unless last_build_id
|
|
78
|
+
attributes['last_build'] ||= begin
|
|
79
|
+
last_build = session.find_one(Build, last_build_id)
|
|
80
|
+
last_build.number = last_build_number
|
|
81
|
+
last_build.state = last_build_state
|
|
82
|
+
last_build.duration = last_build_duration
|
|
83
|
+
last_build.started_at = last_build_started_at
|
|
84
|
+
last_build.finished_at = last_build_finished_at
|
|
85
|
+
last_build.repository_id = id
|
|
86
|
+
last_build
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def builds(params = nil)
|
|
91
|
+
return each_build unless params
|
|
92
|
+
session.find_many(Build, params.merge(:repository_id => id))
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def build(number)
|
|
96
|
+
builds(:number => number.to_s).first
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def recent_builds
|
|
100
|
+
builds({})
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def last_on_branch(name = nil)
|
|
104
|
+
return branch(name) if name
|
|
105
|
+
attributes['last_on_branch'] ||= session.get('branches', :repository_id => id)['branches']
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def branches
|
|
109
|
+
last_on_branch.map { |b| { b.commit.branch => b } }.inject(:merge)
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def branch(name)
|
|
113
|
+
attributes['branches'] ||= {}
|
|
114
|
+
attributes['branches'][name] ||= begin
|
|
115
|
+
build = attributes['last_on_branch'].detect { |b| b.commit.branch == name.to_s } if attributes['last_on_branch']
|
|
116
|
+
build || session.get("/repos/#{id}/branches/#{name}")['branch']
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def each_build(params = nil, &block)
|
|
121
|
+
return enum_for(__method__, params) unless block_given?
|
|
122
|
+
params ||= {}
|
|
123
|
+
chunk = builds(params)
|
|
124
|
+
until chunk.empty?
|
|
125
|
+
chunk.each(&block)
|
|
126
|
+
number = chunk.last.number
|
|
127
|
+
chunk = number == '1' ? [] : builds(params.merge(:after_number => number))
|
|
128
|
+
end
|
|
129
|
+
self
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def job(number)
|
|
133
|
+
build_number = number.to_s[/^\d+/] or return nil
|
|
134
|
+
build = build(build_number) or return nil
|
|
135
|
+
job = build.jobs.detect { |j| j.number == number } if number != build_number
|
|
136
|
+
job ||= build.jobs.first if build and build.jobs.size == 1
|
|
137
|
+
job
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
def set_hook(flag)
|
|
141
|
+
result = session.put_raw('/hooks/', :hook => { :id => id, :active => flag })
|
|
142
|
+
result['result']
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
def disable
|
|
146
|
+
set_hook(false)
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
def enable
|
|
150
|
+
set_hook(true)
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
def pusher_channels
|
|
154
|
+
attributes['pusher_channels'] ||= if session.private_channels?
|
|
155
|
+
["user-#{session.user.id}", "repo-#{id}"]
|
|
156
|
+
else
|
|
157
|
+
["common"]
|
|
158
|
+
end
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
def member?
|
|
162
|
+
session.user.repositories.include? self
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
def owner_name
|
|
166
|
+
slug[/^[^\/]+/]
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
def owner
|
|
170
|
+
session.account(owner_name)
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
def requests
|
|
174
|
+
attributes['requests'] ||= session.find_many(Request, :repository_id => id)
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
def settings
|
|
178
|
+
attributes['settings'] ||= begin
|
|
179
|
+
settings = session.get("/repos/#{id}/settings")['settings']
|
|
180
|
+
settings.repository = self
|
|
181
|
+
settings
|
|
182
|
+
end
|
|
183
|
+
rescue Travis::Client::NotFound
|
|
184
|
+
raise Travis::Client::Error, "not allowed to access settings"
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
def caches(params = {})
|
|
188
|
+
session.get("/repos/#{id}/caches", params)['caches']
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
def delete_caches(params = {})
|
|
192
|
+
session.delete("/repos/#{id}/caches", params)['caches']
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
def active?
|
|
196
|
+
# TODO remove once active is properly synced and exposed by api
|
|
197
|
+
return active unless active.nil?
|
|
198
|
+
last_build_id?
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
def admin?(user = session.user)
|
|
202
|
+
user.admin_access? self
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
def push?(user = session.user)
|
|
206
|
+
user.push_access? self
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
def pull?(user = session.user)
|
|
210
|
+
user.pull_access? self
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
def env_vars
|
|
214
|
+
attributes['env_vars'] ||= EnvVar::List.new(self)
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
private
|
|
218
|
+
|
|
219
|
+
def state
|
|
220
|
+
last_build_state
|
|
221
|
+
end
|
|
222
|
+
end
|
|
223
|
+
end
|
|
224
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
require 'travis/client/weak_entity'
|
|
2
|
+
|
|
3
|
+
module Travis
|
|
4
|
+
module Client
|
|
5
|
+
class Request < WeakEntity
|
|
6
|
+
# @!parse attr_reader :commit_id, :repository_id, :created_at, :owner_id, :owner_type, :event_type, :base_commit, :head_commit, :result, :message, :pull_request, :pull_request_number, :pull_request_title, :branch, :tag
|
|
7
|
+
attributes :commit_id, :repository_id, :created_at, :owner_id, :owner_type, :event_type, :base_commit, :head_commit, :result, :message, :pull_request, :pull_request_number, :pull_request_title, :branch, :tag
|
|
8
|
+
time :created_at
|
|
9
|
+
|
|
10
|
+
# @!parse attr_reader :repository
|
|
11
|
+
has :repository, :commit
|
|
12
|
+
|
|
13
|
+
one :request
|
|
14
|
+
many :requests
|
|
15
|
+
|
|
16
|
+
def owner
|
|
17
|
+
repository.owner
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def accepted?
|
|
21
|
+
result == 'accepted'
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def rejected?
|
|
25
|
+
result == 'rejected'
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def inspect_info
|
|
29
|
+
[
|
|
30
|
+
repository && repository.slug,
|
|
31
|
+
event_type, branch || pull_request_number, result
|
|
32
|
+
].compact.join(" ")
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
require 'travis/client'
|
|
2
|
+
|
|
3
|
+
module Travis
|
|
4
|
+
module Client
|
|
5
|
+
module Restartable
|
|
6
|
+
def restartable?
|
|
7
|
+
true
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def restart
|
|
11
|
+
session.restart(self)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def cancelable?
|
|
15
|
+
true
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def cancel
|
|
19
|
+
session.cancel(self)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,339 @@
|
|
|
1
|
+
require 'travis/client'
|
|
2
|
+
require 'travis/version'
|
|
3
|
+
|
|
4
|
+
require 'faraday'
|
|
5
|
+
require 'faraday_middleware'
|
|
6
|
+
require 'travis/tools/system'
|
|
7
|
+
require 'travis/tools/assets'
|
|
8
|
+
|
|
9
|
+
begin
|
|
10
|
+
require 'typhoeus/adapters/faraday' unless Travis::Tools::System.windows?
|
|
11
|
+
rescue LoadError
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
require 'json'
|
|
15
|
+
|
|
16
|
+
module Travis
|
|
17
|
+
module Client
|
|
18
|
+
class Session
|
|
19
|
+
PRIMITIVE = [nil, false, true]
|
|
20
|
+
SSL_OPTIONS = { :ca_file => Tools::Assets['cacert.pem'] }
|
|
21
|
+
|
|
22
|
+
include Methods
|
|
23
|
+
attr_reader :connection, :headers, :access_token, :instruments, :faraday_adapter, :agent_info, :ssl
|
|
24
|
+
attr_accessor :debug_http
|
|
25
|
+
|
|
26
|
+
def initialize(options = Travis::Client::ORG_URI)
|
|
27
|
+
@headers = {}
|
|
28
|
+
@cache = {}
|
|
29
|
+
@instruments = []
|
|
30
|
+
@agent_info = []
|
|
31
|
+
@config = nil
|
|
32
|
+
@faraday_adapter = defined?(Typhoeus) ? :typhoeus : :net_http
|
|
33
|
+
@ssl = SSL_OPTIONS
|
|
34
|
+
|
|
35
|
+
options = { :uri => options } unless options.respond_to? :each_pair
|
|
36
|
+
options.each_pair { |key, value| public_send("#{key}=", value) }
|
|
37
|
+
|
|
38
|
+
raise ArgumentError, "neither :uri nor :connection specified" unless connection
|
|
39
|
+
headers['Accept'] = 'application/vnd.travis-ci.2+json'
|
|
40
|
+
set_user_agent
|
|
41
|
+
check_ssl
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def uri
|
|
45
|
+
connection.url_prefix.to_s if connection
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def agent_info=(info)
|
|
49
|
+
@agent_info = [info].flatten.freeze
|
|
50
|
+
set_user_agent
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def ssl=(options)
|
|
54
|
+
@ssl = options.dup.freeze
|
|
55
|
+
self.uri = uri if uri
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def uri=(uri)
|
|
59
|
+
clear_cache!
|
|
60
|
+
self.connection = Faraday.new(:url => uri, :ssl => ssl) do |faraday|
|
|
61
|
+
faraday.request :url_encoded
|
|
62
|
+
faraday.response :logger if debug_http
|
|
63
|
+
faraday.adapter(*faraday_adapter)
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def faraday_adapter=(adapter)
|
|
68
|
+
@faraday_adapter = adapter
|
|
69
|
+
self.uri &&= uri
|
|
70
|
+
set_user_agent
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def access_token=(token)
|
|
74
|
+
clear_cache!
|
|
75
|
+
@access_token = token
|
|
76
|
+
headers['Authorization'] = "token #{token}"
|
|
77
|
+
headers.delete('Authorization') unless token
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def connection=(connection)
|
|
81
|
+
clear_cache!
|
|
82
|
+
connection.headers.merge! headers
|
|
83
|
+
@config = nil
|
|
84
|
+
@connection = connection
|
|
85
|
+
@headers = connection.headers
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def headers=(headers)
|
|
89
|
+
clear_cache!
|
|
90
|
+
connection.headers = headers if connection
|
|
91
|
+
@headers = headers
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def find_one(entity, id = nil)
|
|
95
|
+
raise Travis::Client::Error, "cannot fetch #{entity}" unless entity.respond_to?(:many) and entity.many
|
|
96
|
+
return create_entity(entity, entity.id_field => id) if entity.id? id
|
|
97
|
+
cached(entity, :by, id) { fetch_one(entity, id) }
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def find_many(entity, args = {})
|
|
101
|
+
raise Travis::Client::Error, "cannot fetch #{entity}" unless entity.respond_to?(:many) and entity.many
|
|
102
|
+
cached(entity, :many, args) { fetch_many(entity, args) }
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def find_one_or_many(entity, args = nil)
|
|
106
|
+
raise Travis::Client::Error, "cannot fetch #{entity}" unless entity.respond_to?(:many) and entity.many
|
|
107
|
+
cached(entity, :one_or_many, args) do
|
|
108
|
+
path = "/#{entity.many}"
|
|
109
|
+
path, args = "#{path}/#{args}", {} unless args.is_a? Hash
|
|
110
|
+
result = get(path, args)
|
|
111
|
+
one = result[entity.one]
|
|
112
|
+
|
|
113
|
+
if result.include? entity.many
|
|
114
|
+
Array(one) + Array(result[entity.many])
|
|
115
|
+
else
|
|
116
|
+
one
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def reset(entity)
|
|
122
|
+
entity.attributes.clear
|
|
123
|
+
entity
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def reload(entity)
|
|
127
|
+
reset(entity)
|
|
128
|
+
result = fetch_one(entity.class, entity.id)
|
|
129
|
+
entity.update_attributes(result.attributes) if result.attributes != entity.attributes
|
|
130
|
+
result
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
def config
|
|
134
|
+
@config ||= get_raw('/config')['config'] || {}
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
def load(data)
|
|
138
|
+
result = {}
|
|
139
|
+
(data || {}).each_pair do |key, value|
|
|
140
|
+
entity = load_entity(key, value)
|
|
141
|
+
result[key] = entity if entity
|
|
142
|
+
end
|
|
143
|
+
result
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
def load_entity(key, value)
|
|
147
|
+
type = Entity.subclass_for(key)
|
|
148
|
+
if value.respond_to? :to_ary
|
|
149
|
+
value.to_ary.map { |e| create_entity(type, e) }
|
|
150
|
+
else
|
|
151
|
+
create_entity(type, value)
|
|
152
|
+
end
|
|
153
|
+
rescue IndexError
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
def preload(list)
|
|
157
|
+
list.group_by(&:class).each do |type, instances|
|
|
158
|
+
next unless type.preloadable?
|
|
159
|
+
ids = instances.map { |e| e.id unless e.complete? }.compact
|
|
160
|
+
find_many(type, :ids => ids) if ids.any?
|
|
161
|
+
end
|
|
162
|
+
list
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
def get(*args)
|
|
166
|
+
load get_raw(*args)
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
def delete(*args)
|
|
170
|
+
load delete_raw(*args)
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
def patch(*args)
|
|
174
|
+
load patch_raw(*args)
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
def post(*args)
|
|
178
|
+
load post_raw(*args)
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
def put(*args)
|
|
182
|
+
load put_raw(*args)
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
def get_raw(*args)
|
|
186
|
+
raw(:get, *args)
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
def post_raw(*args)
|
|
190
|
+
raw(:post, *args)
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
def put_raw(*args)
|
|
194
|
+
raw(:put, *args)
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
def patch_raw(*args)
|
|
198
|
+
raw(:patch, *args)
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
def delete_raw(*args)
|
|
202
|
+
raw(:delete, *args)
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
def raw(verb, url, *args)
|
|
206
|
+
url = url.sub(/^\//, '')
|
|
207
|
+
result = instrumented(verb.to_s.upcase, url, *args) do
|
|
208
|
+
if url !~ /^https?:/ or url.start_with? api_endpoint
|
|
209
|
+
connection.public_send(verb, url, *args)
|
|
210
|
+
else
|
|
211
|
+
Faraday.public_send(verb, url, *args) { |r| r.headers.delete("Authorization") }
|
|
212
|
+
end
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
case result.status
|
|
216
|
+
when 0 then raise Travis::Client::SSLError, 'SSL error: could not verify peer'
|
|
217
|
+
when 200..299 then JSON.parse(result.body) rescue result.body
|
|
218
|
+
when 301, 303 then raw(:get, result.headers['Location'])
|
|
219
|
+
when 302, 307, 308 then raw(verb, result.headers['Location'])
|
|
220
|
+
when 401 then raise Travis::Client::NotLoggedIn, 'not logged in'
|
|
221
|
+
when 403 then raise Travis::Client::NotLoggedIn, 'invalid access token'
|
|
222
|
+
when 404 then raise Travis::Client::NotFound, result.body
|
|
223
|
+
when 422 then raise Travis::Client::ValidationFailed, result.body
|
|
224
|
+
when 400..499 then raise Travis::Client::Error, "%s: %p" % [result.status, result.body]
|
|
225
|
+
when 500..599 then raise Travis::Client::Error, "server error (%s: %p)" % [result.status, result.body]
|
|
226
|
+
else raise Travis::Client::Error, "unhandled status code #{result.status}"
|
|
227
|
+
end
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
def inspect
|
|
231
|
+
"#<#{self.class}: #{uri}>"
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
def clear_cache
|
|
235
|
+
reset_entities
|
|
236
|
+
clear_find_cache
|
|
237
|
+
self
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
def clear_cache!
|
|
241
|
+
reset_entities
|
|
242
|
+
@cache.clear
|
|
243
|
+
self
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
def session
|
|
247
|
+
self
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
def instrument(&block)
|
|
251
|
+
instruments << block
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
def private_channels?
|
|
255
|
+
!!config['pusher']['private']
|
|
256
|
+
end
|
|
257
|
+
|
|
258
|
+
private
|
|
259
|
+
|
|
260
|
+
def set_user_agent
|
|
261
|
+
adapter = Array === faraday_adapter ? faraday_adapter.first : faraday_adapter
|
|
262
|
+
adapter = adapter.to_s.capitalize.gsub(/_http_(.)/) { "::HTTP::#{$1.upcase}" }.gsub(/_http/, '::HTTP')
|
|
263
|
+
headers['User-Agent'] = "Travis/#{Travis::VERSION} (#{Travis::Tools::System.description(agent_info)}) Faraday/#{Faraday::VERSION} #{adapter}/#{adapter_version(adapter)}"
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
def adapter_version(adapter)
|
|
267
|
+
version = Object.const_get(adapter).const_get("VERSION")
|
|
268
|
+
[*version].join('.')
|
|
269
|
+
rescue Exception
|
|
270
|
+
"unknown"
|
|
271
|
+
end
|
|
272
|
+
|
|
273
|
+
def instrumented(name, *args)
|
|
274
|
+
name = [name, *args.map(&:inspect)].join(" ") if args.any?
|
|
275
|
+
result = nil
|
|
276
|
+
chain = instruments + [proc { |n,l| result = yield }]
|
|
277
|
+
lift = proc { chain.shift.call(name, lift) }
|
|
278
|
+
lift.call
|
|
279
|
+
result
|
|
280
|
+
end
|
|
281
|
+
|
|
282
|
+
def create_entity(type, data)
|
|
283
|
+
return data if primitive?(data)
|
|
284
|
+
data = { type.id_field => data } if type.id? data
|
|
285
|
+
id = type.cast_id(data.fetch(type.id_field)) unless type.weak?
|
|
286
|
+
entity = id ? cached(type, :id, id) { type.new(self, id) } : type.new(self, nil)
|
|
287
|
+
entity.update_attributes(data)
|
|
288
|
+
entity
|
|
289
|
+
end
|
|
290
|
+
|
|
291
|
+
def primitive?(data)
|
|
292
|
+
PRIMITIVE.include? data
|
|
293
|
+
end
|
|
294
|
+
|
|
295
|
+
def error_message(e)
|
|
296
|
+
message = e.response[:body].to_str rescue e.message
|
|
297
|
+
JSON.parse(message).fetch('error').fetch('message') rescue message
|
|
298
|
+
end
|
|
299
|
+
|
|
300
|
+
def reset_entities
|
|
301
|
+
subcaches do |subcache|
|
|
302
|
+
subcache[:id].each_value { |e| e.attributes.clear } if subcache.include? :id
|
|
303
|
+
end
|
|
304
|
+
end
|
|
305
|
+
|
|
306
|
+
def clear_find_cache
|
|
307
|
+
subcaches do |subcache|
|
|
308
|
+
subcache.delete_if { |k, v| k != :id }
|
|
309
|
+
end
|
|
310
|
+
end
|
|
311
|
+
|
|
312
|
+
def subcaches
|
|
313
|
+
@cache.each_value do |subcache|
|
|
314
|
+
yield subcache if subcache.is_a? Hash
|
|
315
|
+
end
|
|
316
|
+
end
|
|
317
|
+
|
|
318
|
+
def fetch_one(entity, id = nil)
|
|
319
|
+
get("/#{entity.base_path}/#{id}")[entity.one]
|
|
320
|
+
end
|
|
321
|
+
|
|
322
|
+
def fetch_many(entity, params = {})
|
|
323
|
+
get("/#{entity.base_path}/", params)[entity.many]
|
|
324
|
+
end
|
|
325
|
+
|
|
326
|
+
def cached(*keys)
|
|
327
|
+
last = keys.pop
|
|
328
|
+
cache = keys.inject(@cache) { |store, key| store[key] ||= {} }
|
|
329
|
+
cache[last] ||= yield
|
|
330
|
+
end
|
|
331
|
+
|
|
332
|
+
def check_ssl
|
|
333
|
+
raw(:head, '/') if ssl == SSL_OPTIONS
|
|
334
|
+
rescue SSLError => error
|
|
335
|
+
self.ssl = {}
|
|
336
|
+
end
|
|
337
|
+
end
|
|
338
|
+
end
|
|
339
|
+
end
|