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.
Files changed (184) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +22 -0
  3. data/README.md +2486 -0
  4. data/Rakefile +63 -0
  5. data/assets/cacert.pem +69 -0
  6. data/assets/init/c.yml +4 -0
  7. data/assets/init/clojure.yml +1 -0
  8. data/assets/init/cpp.yml +4 -0
  9. data/assets/init/erlang.yml +3 -0
  10. data/assets/init/go.yml +4 -0
  11. data/assets/init/groovy.yml +1 -0
  12. data/assets/init/haskell.yml +1 -0
  13. data/assets/init/java.yml +4 -0
  14. data/assets/init/node_js.yml +4 -0
  15. data/assets/init/objective-c.yml +1 -0
  16. data/assets/init/perl.yml +4 -0
  17. data/assets/init/php.yml +4 -0
  18. data/assets/init/python.yml +5 -0
  19. data/assets/init/ruby.yml +6 -0
  20. data/assets/init/scala.yml +4 -0
  21. data/assets/notifications/Travis CI.app/Contents/Info.plist +52 -0
  22. data/assets/notifications/Travis CI.app/Contents/MacOS/Travis CI +0 -0
  23. data/assets/notifications/Travis CI.app/Contents/PkgInfo +1 -0
  24. data/assets/notifications/Travis CI.app/Contents/Resources/Travis CI.icns +0 -0
  25. data/assets/notifications/Travis CI.app/Contents/Resources/en.lproj/Credits.rtf +29 -0
  26. data/assets/notifications/Travis CI.app/Contents/Resources/en.lproj/InfoPlist.strings +0 -0
  27. data/assets/notifications/Travis CI.app/Contents/Resources/en.lproj/MainMenu.nib +0 -0
  28. data/assets/notifications/Travis CI.app/Contents/_CodeSignature/CodeResources +173 -0
  29. data/assets/notifications/Travis CI.app/Contents/embedded.provisionprofile +0 -0
  30. data/assets/notifications/icon.png +0 -0
  31. data/assets/travis.sh +163 -0
  32. data/assets/travis.sh.erb +64 -0
  33. data/bin/travis +18 -0
  34. data/examples/org_overview.rb +3 -0
  35. data/examples/pro_auth.rb +23 -0
  36. data/examples/stream.rb +6 -0
  37. data/lib/travis.rb +8 -0
  38. data/lib/travis/auto_login.rb +3 -0
  39. data/lib/travis/cli.rb +126 -0
  40. data/lib/travis/cli/accounts.rb +31 -0
  41. data/lib/travis/cli/api_command.rb +180 -0
  42. data/lib/travis/cli/branches.rb +25 -0
  43. data/lib/travis/cli/cache.rb +76 -0
  44. data/lib/travis/cli/cancel.rb +18 -0
  45. data/lib/travis/cli/command.rb +422 -0
  46. data/lib/travis/cli/console.rb +31 -0
  47. data/lib/travis/cli/disable.rb +15 -0
  48. data/lib/travis/cli/enable.rb +31 -0
  49. data/lib/travis/cli/encrypt.rb +108 -0
  50. data/lib/travis/cli/encrypt_file.rb +140 -0
  51. data/lib/travis/cli/endpoint.rb +35 -0
  52. data/lib/travis/cli/env.rb +66 -0
  53. data/lib/travis/cli/help.rb +23 -0
  54. data/lib/travis/cli/history.rb +49 -0
  55. data/lib/travis/cli/init.rb +82 -0
  56. data/lib/travis/cli/lint.rb +49 -0
  57. data/lib/travis/cli/login.rb +76 -0
  58. data/lib/travis/cli/logout.rb +14 -0
  59. data/lib/travis/cli/logs.rb +65 -0
  60. data/lib/travis/cli/monitor.rb +110 -0
  61. data/lib/travis/cli/open.rb +39 -0
  62. data/lib/travis/cli/parser.rb +43 -0
  63. data/lib/travis/cli/pubkey.rb +30 -0
  64. data/lib/travis/cli/raw.rb +20 -0
  65. data/lib/travis/cli/repo_command.rb +154 -0
  66. data/lib/travis/cli/report.rb +101 -0
  67. data/lib/travis/cli/repos.rb +53 -0
  68. data/lib/travis/cli/requests.rb +47 -0
  69. data/lib/travis/cli/restart.rb +18 -0
  70. data/lib/travis/cli/settings.rb +77 -0
  71. data/lib/travis/cli/setup.rb +66 -0
  72. data/lib/travis/cli/setup/anynines.rb +21 -0
  73. data/lib/travis/cli/setup/appfog.rb +19 -0
  74. data/lib/travis/cli/setup/artifacts.rb +23 -0
  75. data/lib/travis/cli/setup/biicode.rb +19 -0
  76. data/lib/travis/cli/setup/cloud_66.rb +20 -0
  77. data/lib/travis/cli/setup/cloud_control.rb +21 -0
  78. data/lib/travis/cli/setup/cloud_files.rb +20 -0
  79. data/lib/travis/cli/setup/cloud_foundry.rb +23 -0
  80. data/lib/travis/cli/setup/code_deploy.rb +55 -0
  81. data/lib/travis/cli/setup/deis.rb +20 -0
  82. data/lib/travis/cli/setup/divshot.rb +18 -0
  83. data/lib/travis/cli/setup/elastic_beanstalk.rb +23 -0
  84. data/lib/travis/cli/setup/engine_yard.rb +24 -0
  85. data/lib/travis/cli/setup/gcs.rb +22 -0
  86. data/lib/travis/cli/setup/hackage.rb +18 -0
  87. data/lib/travis/cli/setup/heroku.rb +20 -0
  88. data/lib/travis/cli/setup/modulus.rb +18 -0
  89. data/lib/travis/cli/setup/ninefold.rb +20 -0
  90. data/lib/travis/cli/setup/nodejitsu.rb +27 -0
  91. data/lib/travis/cli/setup/npm.rb +20 -0
  92. data/lib/travis/cli/setup/open_shift.rb +20 -0
  93. data/lib/travis/cli/setup/opsworks.rb +22 -0
  94. data/lib/travis/cli/setup/pypi.rb +22 -0
  95. data/lib/travis/cli/setup/releases.rb +35 -0
  96. data/lib/travis/cli/setup/ruby_gems.rb +25 -0
  97. data/lib/travis/cli/setup/s3.rb +25 -0
  98. data/lib/travis/cli/setup/sauce_connect.rb +21 -0
  99. data/lib/travis/cli/setup/service.rb +73 -0
  100. data/lib/travis/cli/show.rb +69 -0
  101. data/lib/travis/cli/sshkey.rb +118 -0
  102. data/lib/travis/cli/status.rb +19 -0
  103. data/lib/travis/cli/sync.rb +30 -0
  104. data/lib/travis/cli/token.rb +14 -0
  105. data/lib/travis/cli/version.rb +17 -0
  106. data/lib/travis/cli/whatsup.rb +30 -0
  107. data/lib/travis/cli/whoami.rb +15 -0
  108. data/lib/travis/client.rb +39 -0
  109. data/lib/travis/client/account.rb +56 -0
  110. data/lib/travis/client/annotation.rb +21 -0
  111. data/lib/travis/client/artifact.rb +88 -0
  112. data/lib/travis/client/auto_login.rb +45 -0
  113. data/lib/travis/client/broadcast.rb +14 -0
  114. data/lib/travis/client/build.rb +47 -0
  115. data/lib/travis/client/cache.rb +25 -0
  116. data/lib/travis/client/commit.rb +28 -0
  117. data/lib/travis/client/entity.rb +238 -0
  118. data/lib/travis/client/env_var.rb +102 -0
  119. data/lib/travis/client/error.rb +38 -0
  120. data/lib/travis/client/has_uuid.rb +13 -0
  121. data/lib/travis/client/job.rb +61 -0
  122. data/lib/travis/client/lint_result.rb +25 -0
  123. data/lib/travis/client/listener.rb +184 -0
  124. data/lib/travis/client/methods.rb +104 -0
  125. data/lib/travis/client/namespace.rb +85 -0
  126. data/lib/travis/client/not_loadable.rb +13 -0
  127. data/lib/travis/client/repository.rb +224 -0
  128. data/lib/travis/client/request.rb +36 -0
  129. data/lib/travis/client/restartable.rb +23 -0
  130. data/lib/travis/client/session.rb +339 -0
  131. data/lib/travis/client/settings.rb +25 -0
  132. data/lib/travis/client/singleton_setting.rb +36 -0
  133. data/lib/travis/client/ssh_key.rb +11 -0
  134. data/lib/travis/client/states.rb +98 -0
  135. data/lib/travis/client/user.rb +67 -0
  136. data/lib/travis/client/weak_entity.rb +26 -0
  137. data/lib/travis/pro.rb +5 -0
  138. data/lib/travis/pro/auto_login.rb +3 -0
  139. data/lib/travis/tools/assets.rb +21 -0
  140. data/lib/travis/tools/completion.rb +54 -0
  141. data/lib/travis/tools/formatter.rb +50 -0
  142. data/lib/travis/tools/github.rb +279 -0
  143. data/lib/travis/tools/notification.rb +69 -0
  144. data/lib/travis/tools/safe_string.rb +22 -0
  145. data/lib/travis/tools/ssl_key.rb +48 -0
  146. data/lib/travis/tools/system.rb +88 -0
  147. data/lib/travis/version.rb +3 -0
  148. data/spec/cli/cancel_spec.rb +15 -0
  149. data/spec/cli/encrypt_spec.rb +43 -0
  150. data/spec/cli/endpoint_spec.rb +34 -0
  151. data/spec/cli/help_spec.rb +33 -0
  152. data/spec/cli/history_spec.rb +38 -0
  153. data/spec/cli/init_spec.rb +226 -0
  154. data/spec/cli/login_spec.rb +13 -0
  155. data/spec/cli/logs_spec.rb +8 -0
  156. data/spec/cli/open_spec.rb +33 -0
  157. data/spec/cli/repo_command_spec.rb +25 -0
  158. data/spec/cli/restart_spec.rb +15 -0
  159. data/spec/cli/setup_spec.rb +5 -0
  160. data/spec/cli/show_spec.rb +9 -0
  161. data/spec/cli/status_spec.rb +28 -0
  162. data/spec/cli/token_spec.rb +22 -0
  163. data/spec/cli/version_spec.rb +18 -0
  164. data/spec/cli/whoami_spec.rb +34 -0
  165. data/spec/client/account_spec.rb +32 -0
  166. data/spec/client/annotation_spec.rb +14 -0
  167. data/spec/client/broadcast_spec.rb +10 -0
  168. data/spec/client/build_spec.rb +31 -0
  169. data/spec/client/commit_spec.rb +22 -0
  170. data/spec/client/job_spec.rb +30 -0
  171. data/spec/client/methods_spec.rb +15 -0
  172. data/spec/client/namespace_spec.rb +19 -0
  173. data/spec/client/repository_spec.rb +39 -0
  174. data/spec/client/session_spec.rb +165 -0
  175. data/spec/client/user_spec.rb +16 -0
  176. data/spec/client_spec.rb +17 -0
  177. data/spec/pro_spec.rb +10 -0
  178. data/spec/spec_helper.rb +29 -0
  179. data/spec/support/fake_api.rb +738 -0
  180. data/spec/support/fake_github.rb +24 -0
  181. data/spec/support/helpers.rb +45 -0
  182. data/spec/travis_spec.rb +10 -0
  183. data/travis.gemspec +323 -0
  184. metadata +489 -0
@@ -0,0 +1,13 @@
1
+ module Travis
2
+ module Client
3
+ module NotLoadable
4
+ def missing?(attribute)
5
+ false
6
+ end
7
+
8
+ def complete?
9
+ true
10
+ end
11
+ end
12
+ end
13
+ end
@@ -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