travis-akerl 1.8.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (185) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +22 -0
  3. data/README.md +2512 -0
  4. data/Rakefile +64 -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 +5 -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/auto_login.rb +3 -0
  38. data/lib/travis/cli/accounts.rb +31 -0
  39. data/lib/travis/cli/api_command.rb +182 -0
  40. data/lib/travis/cli/branches.rb +25 -0
  41. data/lib/travis/cli/cache.rb +76 -0
  42. data/lib/travis/cli/cancel.rb +18 -0
  43. data/lib/travis/cli/command.rb +422 -0
  44. data/lib/travis/cli/console.rb +33 -0
  45. data/lib/travis/cli/disable.rb +15 -0
  46. data/lib/travis/cli/enable.rb +31 -0
  47. data/lib/travis/cli/encrypt.rb +115 -0
  48. data/lib/travis/cli/encrypt_file.rb +140 -0
  49. data/lib/travis/cli/endpoint.rb +35 -0
  50. data/lib/travis/cli/env.rb +66 -0
  51. data/lib/travis/cli/help.rb +23 -0
  52. data/lib/travis/cli/history.rb +49 -0
  53. data/lib/travis/cli/init.rb +82 -0
  54. data/lib/travis/cli/lint.rb +49 -0
  55. data/lib/travis/cli/login.rb +76 -0
  56. data/lib/travis/cli/logout.rb +14 -0
  57. data/lib/travis/cli/logs.rb +65 -0
  58. data/lib/travis/cli/monitor.rb +111 -0
  59. data/lib/travis/cli/open.rb +39 -0
  60. data/lib/travis/cli/parser.rb +43 -0
  61. data/lib/travis/cli/pubkey.rb +30 -0
  62. data/lib/travis/cli/raw.rb +20 -0
  63. data/lib/travis/cli/repo_command.rb +154 -0
  64. data/lib/travis/cli/report.rb +101 -0
  65. data/lib/travis/cli/repos.rb +53 -0
  66. data/lib/travis/cli/requests.rb +47 -0
  67. data/lib/travis/cli/restart.rb +18 -0
  68. data/lib/travis/cli/settings.rb +79 -0
  69. data/lib/travis/cli/setup/anynines.rb +21 -0
  70. data/lib/travis/cli/setup/appfog.rb +19 -0
  71. data/lib/travis/cli/setup/artifacts.rb +23 -0
  72. data/lib/travis/cli/setup/biicode.rb +19 -0
  73. data/lib/travis/cli/setup/cloud_66.rb +20 -0
  74. data/lib/travis/cli/setup/cloud_control.rb +21 -0
  75. data/lib/travis/cli/setup/cloud_files.rb +20 -0
  76. data/lib/travis/cli/setup/cloud_foundry.rb +23 -0
  77. data/lib/travis/cli/setup/code_deploy.rb +55 -0
  78. data/lib/travis/cli/setup/deis.rb +20 -0
  79. data/lib/travis/cli/setup/divshot.rb +18 -0
  80. data/lib/travis/cli/setup/elastic_beanstalk.rb +23 -0
  81. data/lib/travis/cli/setup/engine_yard.rb +24 -0
  82. data/lib/travis/cli/setup/gcs.rb +22 -0
  83. data/lib/travis/cli/setup/hackage.rb +18 -0
  84. data/lib/travis/cli/setup/heroku.rb +20 -0
  85. data/lib/travis/cli/setup/modulus.rb +18 -0
  86. data/lib/travis/cli/setup/ninefold.rb +20 -0
  87. data/lib/travis/cli/setup/nodejitsu.rb +27 -0
  88. data/lib/travis/cli/setup/npm.rb +20 -0
  89. data/lib/travis/cli/setup/open_shift.rb +20 -0
  90. data/lib/travis/cli/setup/opsworks.rb +22 -0
  91. data/lib/travis/cli/setup/pypi.rb +22 -0
  92. data/lib/travis/cli/setup/releases.rb +35 -0
  93. data/lib/travis/cli/setup/ruby_gems.rb +25 -0
  94. data/lib/travis/cli/setup/s3.rb +25 -0
  95. data/lib/travis/cli/setup/sauce_connect.rb +21 -0
  96. data/lib/travis/cli/setup/service.rb +73 -0
  97. data/lib/travis/cli/setup.rb +66 -0
  98. data/lib/travis/cli/show.rb +57 -0
  99. data/lib/travis/cli/sshkey.rb +118 -0
  100. data/lib/travis/cli/status.rb +19 -0
  101. data/lib/travis/cli/sync.rb +30 -0
  102. data/lib/travis/cli/token.rb +14 -0
  103. data/lib/travis/cli/version.rb +17 -0
  104. data/lib/travis/cli/whatsup.rb +30 -0
  105. data/lib/travis/cli/whoami.rb +15 -0
  106. data/lib/travis/cli.rb +126 -0
  107. data/lib/travis/client/account.rb +56 -0
  108. data/lib/travis/client/artifact.rb +88 -0
  109. data/lib/travis/client/auto_login.rb +45 -0
  110. data/lib/travis/client/broadcast.rb +14 -0
  111. data/lib/travis/client/build.rb +47 -0
  112. data/lib/travis/client/cache.rb +25 -0
  113. data/lib/travis/client/commit.rb +28 -0
  114. data/lib/travis/client/entity.rb +238 -0
  115. data/lib/travis/client/env_var.rb +102 -0
  116. data/lib/travis/client/error.rb +38 -0
  117. data/lib/travis/client/has_uuid.rb +13 -0
  118. data/lib/travis/client/job.rb +61 -0
  119. data/lib/travis/client/lint_result.rb +25 -0
  120. data/lib/travis/client/listener.rb +183 -0
  121. data/lib/travis/client/methods.rb +104 -0
  122. data/lib/travis/client/namespace.rb +85 -0
  123. data/lib/travis/client/not_loadable.rb +13 -0
  124. data/lib/travis/client/repository.rb +224 -0
  125. data/lib/travis/client/request.rb +36 -0
  126. data/lib/travis/client/restartable.rb +23 -0
  127. data/lib/travis/client/session.rb +339 -0
  128. data/lib/travis/client/settings.rb +25 -0
  129. data/lib/travis/client/singleton_setting.rb +36 -0
  130. data/lib/travis/client/ssh_key.rb +11 -0
  131. data/lib/travis/client/states.rb +98 -0
  132. data/lib/travis/client/user.rb +67 -0
  133. data/lib/travis/client/weak_entity.rb +26 -0
  134. data/lib/travis/client.rb +38 -0
  135. data/lib/travis/pro/auto_login.rb +3 -0
  136. data/lib/travis/pro.rb +5 -0
  137. data/lib/travis/tools/assets.rb +21 -0
  138. data/lib/travis/tools/completion.rb +54 -0
  139. data/lib/travis/tools/formatter.rb +50 -0
  140. data/lib/travis/tools/github.rb +293 -0
  141. data/lib/travis/tools/notification.rb +69 -0
  142. data/lib/travis/tools/safe_string.rb +22 -0
  143. data/lib/travis/tools/ssl_key.rb +48 -0
  144. data/lib/travis/tools/system.rb +88 -0
  145. data/lib/travis/version.rb +3 -0
  146. data/lib/travis.rb +8 -0
  147. data/spec/cli/api_command_spec.rb +38 -0
  148. data/spec/cli/cancel_spec.rb +15 -0
  149. data/spec/cli/encrypt_spec.rb +49 -0
  150. data/spec/cli/endpoint_spec.rb +39 -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 +227 -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/auto_login_spec.rb +25 -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 +731 -0
  180. data/spec/support/fake_github.rb +24 -0
  181. data/spec/support/fake_travis_config.yml +14 -0
  182. data/spec/support/helpers.rb +45 -0
  183. data/spec/travis_spec.rb +10 -0
  184. data/travis.gemspec +371 -0
  185. metadata +534 -0
@@ -0,0 +1,61 @@
1
+ require 'travis/client'
2
+
3
+ module Travis
4
+ module Client
5
+ class Job < Entity
6
+ include States, Restartable
7
+ preloadable
8
+
9
+ # @!parse attr_reader :repository_id, :build_id, :commit_id, :log_id, :number, :config, :state, :started_at, :finished_at, :queue, :allow_failure, :tags
10
+ attributes :repository_id, :build_id, :commit_id, :log_id, :number, :config, :state, :started_at, :finished_at, :queue, :allow_failure, :tags
11
+ time :started_at, :finished_at
12
+
13
+ alias allow_failure? allow_failure
14
+
15
+ # @!parse attr_reader :commit, :repository, :build
16
+ has :commit, :repository, :build, :log
17
+
18
+ one :job
19
+ many :jobs
20
+
21
+ def pull_request?
22
+ build.pull_request?
23
+ end
24
+
25
+ def push?
26
+ build.push?
27
+ end
28
+
29
+ def branch_info
30
+ build.branch_info
31
+ end
32
+
33
+ def allow_failures?
34
+ return false unless config.include? 'matrix' and config['matrix'].include? 'allow_failures'
35
+ config['matrix']['allow_failures'].any? do |allow|
36
+ allow.all? { |key, value| config[key] == value }
37
+ end
38
+ end
39
+
40
+ def duration
41
+ attributes['duration'] ||= begin
42
+ start = started_at || Time.now
43
+ finish = finished_at || Time.now
44
+ (finish - start).to_i
45
+ end
46
+ end
47
+
48
+ def delete_log(reason = {})
49
+ log.delete_body(reason)
50
+ end
51
+
52
+ def pusher_channels
53
+ build.pusher_channels + ["job-#{id}"]
54
+ end
55
+
56
+ def inspect_info
57
+ "#{repository.slug}##{number}"
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,25 @@
1
+ module Travis
2
+ module Client
3
+ class LintResult
4
+ Warning = Struct.new(:key, :message)
5
+ attr_accessor :warnings
6
+
7
+ def initialize(payload)
8
+ @warnings = []
9
+ payload = payload['lint'] if payload['lint']
10
+
11
+ Array(payload['warnings']).each do |warning|
12
+ @warnings << Warning.new(warning['key'], warning['message'])
13
+ end
14
+ end
15
+
16
+ def warnings?
17
+ warnings.any?
18
+ end
19
+
20
+ def ok?
21
+ !warnings?
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,183 @@
1
+ require 'travis/client'
2
+ require 'forwardable'
3
+ require 'json'
4
+
5
+ if require 'pusher-client'
6
+ # it's us that has been loading pusher-client
7
+ # so let's assume we can mess with it - yay for global state
8
+ PusherClient.logger.level = 5
9
+ end
10
+
11
+ module Travis
12
+ module Client
13
+ class Listener
14
+ class Socket < PusherClient::Socket
15
+ attr_accessor :session, :signatures
16
+ def initialize(application_key, options = {})
17
+ @session = options.fetch(:session)
18
+ @signatures = {}
19
+ super
20
+
21
+ bind('pusher:error') do |data|
22
+ handle_error(data)
23
+ end
24
+ end
25
+
26
+ def subscribe_all
27
+ # bulk auth on connect
28
+ fetch_auth(*channels.channels.keys)
29
+ super
30
+ end
31
+
32
+ def fetch_auth(*channels)
33
+ channels.select! { |c| signatures[c].nil? if c.start_with? 'private-' }
34
+ signatures.merge! session.post_raw('/pusher/auth', :channels => channels, :socket_id => socket_id)['channels'] if channels.any?
35
+ end
36
+
37
+ def get_private_auth(channel)
38
+ fetch_auth(channel.name)
39
+ signatures[channel.name]
40
+ end
41
+
42
+ def handle_error(data)
43
+ code, message = data["code"], data["message"] if data.is_a? Hash
44
+ message ||= data.inspect
45
+
46
+ case code
47
+ when 4100 then reconnect(1)
48
+ when 4200, 4201, 4202 then reconnect
49
+ else raise Travis::Client::Error, "Pusher error: %s (code: %p)" % [message, code]
50
+ end
51
+ end
52
+
53
+ def reconnect(delay = nil)
54
+ disconnect if connected
55
+ sleep delay if delay and delay > 0
56
+ connect
57
+ end
58
+ end
59
+
60
+ EVENTS = %w[
61
+ build:created build:started build:finished
62
+ job:created job:started job:log job:finished
63
+ ]
64
+
65
+ Event = Struct.new(:type, :repository, :build, :job, :payload)
66
+
67
+ class EntityListener
68
+ attr_reader :listener, :entities
69
+
70
+ extend Forwardable
71
+ def_delegators :listener, :disconnect, :on_connect, :subscribe
72
+
73
+ def initialize(listener, entities)
74
+ @listener, @entities = listener, Array(entities)
75
+ end
76
+
77
+ def on(*events)
78
+ listener.on(*events) { |e| yield(e) if dispatch?(e) }
79
+ end
80
+
81
+ private
82
+
83
+ def dispatch?(event)
84
+ entities.include? event.repository or
85
+ entities.include? event.build or
86
+ entities.include? event.job
87
+ end
88
+ end
89
+
90
+ attr_reader :session, :socket
91
+
92
+ def initialize(session)
93
+ @session = session
94
+ @socket = Socket.new(pusher_key, pusher_options)
95
+ @channels = []
96
+ @callbacks = []
97
+ end
98
+
99
+ def subscribe(*entities)
100
+ entities = entities.map do |entity|
101
+ entity = entity.pusher_entity while entity.respond_to? :pusher_entity
102
+ @channels.concat(entity.pusher_channels)
103
+ entity
104
+ end
105
+
106
+ yield entities.any? ? EntityListener.new(self, entities) : self if block_given?
107
+ end
108
+
109
+ def on(*events, &block)
110
+ events = events.flat_map { |e| e.respond_to?(:to_str) ? e.to_str : EVENTS.grep(e) }.uniq
111
+ events.each { |e| @callbacks << [e, block] }
112
+ end
113
+
114
+ def on_connect
115
+ socket.bind('pusher:connection_established') { yield }
116
+ end
117
+
118
+ def listen
119
+ @channels = default_channels if @channels.empty?
120
+ @channels.map! { |c| c.start_with?('private-') ? c : "private-#{c}" } if session.private_channels?
121
+ @channels.uniq.each { |c| socket.subscribe(c) }
122
+ @callbacks.each { |e,b| socket.bind(e) { |d| dispatch(e, d, &b) } }
123
+ socket.connect
124
+ end
125
+
126
+ def disconnect
127
+ socket.disconnect
128
+ end
129
+
130
+ private
131
+
132
+ def dispatch(type, json)
133
+ payload = JSON.parse(json)
134
+ entities = session.load format_payload(type, payload)
135
+ yield Event.new(type, entities['repository'], entities['build'], entities['job'], payload)
136
+ end
137
+
138
+ def format_payload(type, payload)
139
+ case type
140
+ when "job:log" then format_log(payload)
141
+ when /job:/ then format_job(payload)
142
+ else payload
143
+ end
144
+ end
145
+
146
+ def format_job(payload)
147
+ build = { "id" => payload["build_id"], "repository_id" => payload["repository_id"] }
148
+ repo = { "id" => payload["repository_id"], "slug" => payload["repository_slug"] }
149
+ build["number"] = payload["number"][/^[^\.]+/] if payload["number"]
150
+ { "job" => payload, "build" => build, "repository" => repo }
151
+ end
152
+
153
+ def format_log(payload)
154
+ job = session.job(payload['id'])
155
+ { "job" => { "id" => job.id }, "build" => { "id" => job.build.id }, "repository" => { "id" => job.repository.id } }
156
+ end
157
+
158
+ def default_channels
159
+ return ['common'] if session.access_token.nil?
160
+ session.user.channels
161
+ end
162
+
163
+ def pusher_options
164
+ pusher_options = session.config['pusher'] || {}
165
+ encrypted = pusher_options['scheme'] != 'http'
166
+ options = { :encrypted => encrypted, :session => session }
167
+ options[:ws_host] = pusher_options['host'] if pusher_options['host']
168
+ options[:wss_port] = pusher_options['port'] if encrypted and pusher_options['port']
169
+ options[:ws_port] = pusher_options['port'] if !encrypted and pusher_options['port']
170
+ options[:ws_path] = pusher_options['path'] if pusher_options['path']
171
+ options[:ws_path] = '/' << options[:ws_path] unless options[:ws_path].nil? or options[:ws_path].start_with? '/'
172
+ options[:ssl_verify] = session.ssl.fetch(:verify, true)
173
+ options
174
+ end
175
+
176
+ def pusher_key
177
+ session.config.fetch('pusher').fetch('key')
178
+ rescue IndexError
179
+ raise Travis::Client::Error, "#{session.api_endpoint} is missing pusher key"
180
+ end
181
+ end
182
+ end
183
+ end
@@ -0,0 +1,104 @@
1
+ require 'travis/client'
2
+ require 'yaml'
3
+
4
+ module Travis
5
+ module Client
6
+ module Methods
7
+ def access_token
8
+ session.access_token
9
+ end
10
+
11
+ def access_token=(token)
12
+ session.access_token = token
13
+ end
14
+
15
+ def api_endpoint
16
+ session.uri
17
+ end
18
+
19
+ def github_auth(github_token)
20
+ reply = session.post_raw("/auth/github", :github_token => github_token)
21
+ session.access_token = reply["access_token"]
22
+ end
23
+
24
+ def explicit_api_endpoint?
25
+ @explicit_api_endpoint ||= false
26
+ end
27
+
28
+ def api_endpoint=(uri)
29
+ @explicit_api_endpoint = true
30
+ session.uri = uri
31
+ end
32
+
33
+ def repos(params = {})
34
+ session.find_many(Repository, params)
35
+ end
36
+
37
+ def repo(id_or_slug)
38
+ session.find_one(Repository, id_or_slug)
39
+ end
40
+
41
+ def build(id)
42
+ session.find_one(Build, id)
43
+ end
44
+
45
+ def job(id)
46
+ session.find_one(Job, id)
47
+ end
48
+
49
+ def artifact(id)
50
+ session.find_one(Artifact, id)
51
+ end
52
+
53
+ alias log artifact
54
+
55
+ def user
56
+ session.find_one(User)
57
+ rescue NotFound
58
+ raise NotLoggedIn, 'currently not logged in'
59
+ end
60
+
61
+ def account(name)
62
+ session.find_one(Account, name)
63
+ end
64
+
65
+ def accounts
66
+ session.find_many(Account, :all => true)
67
+ end
68
+
69
+ def broadcasts
70
+ session.find_many(Broadcast)
71
+ end
72
+
73
+ def restart(entity)
74
+ # btw, internally we call this reset, not restart, as it resets the state machine
75
+ # but we thought that would be too confusing
76
+ raise Error, "cannot restart a #{entity.class.one}" unless entity.restartable?
77
+ session.post_raw('/requests', "#{entity.class.one}_id" => entity.id)
78
+ entity.reload
79
+ end
80
+
81
+ def cancel(entity)
82
+ raise Error, "cannot cancel a #{entity.class.one}" unless entity.cancelable?
83
+ session.post_raw("/#{entity.class.many}/#{entity.id}/cancel")
84
+ entity.reload
85
+ end
86
+
87
+ def listen(*entities, &block)
88
+ listener = Listener.new(session)
89
+ listener.subscribe(*entities, &block)
90
+ listener.listen
91
+ end
92
+
93
+ def lint(body)
94
+ body = body.to_yaml unless body.is_a? String
95
+ result = session.post_raw('/lint', 'content' => body)
96
+ LintResult.new(result)
97
+ end
98
+
99
+ def hooks
100
+ session.get('hooks')['hooks']
101
+ end
102
+ end
103
+ end
104
+ end
@@ -0,0 +1,85 @@
1
+ require 'travis/client'
2
+
3
+ module Travis
4
+ module Client
5
+ class Namespace < Module
6
+ class Curry < Module
7
+ attr_accessor :namespace, :type
8
+
9
+ def initialize(namespace, type)
10
+ @namespace, @type = namespace, type
11
+ end
12
+
13
+ def find_one(id = nil)
14
+ result = session.find_one(type, id)
15
+ result.curry = self
16
+ result
17
+ end
18
+
19
+ def current
20
+ result = session.find_one_or_many(type)
21
+ Array(result).each { |e| e.curry = self }
22
+ result
23
+ end
24
+
25
+ def find_many(params = {})
26
+ session.find_many(type, params).each do |entity|
27
+ entity.curry = self
28
+ end
29
+ end
30
+
31
+ alias find find_one
32
+ alias find_all find_many
33
+
34
+ def clear_cache
35
+ session.clear_cache
36
+ end
37
+
38
+ def clear_cache!
39
+ session.clear_cache!
40
+ end
41
+
42
+ private
43
+
44
+ def session
45
+ namespace.session
46
+ end
47
+ end
48
+
49
+ include Methods
50
+ attr_accessor :session
51
+
52
+ def initialize(session = nil)
53
+ session = Travis::Client.new(session || {}) unless session.is_a? Session
54
+ @session = session
55
+
56
+ Entity.subclasses.each do |subclass|
57
+ name = subclass.name[/[^:]+$/]
58
+ const_set(name, Curry.new(self, subclass))
59
+ end
60
+ end
61
+
62
+ def included(klass)
63
+ fix_names(klass)
64
+ delegate_session(klass)
65
+ end
66
+
67
+ private
68
+
69
+ def fix_names(klass)
70
+ constants.each do |name|
71
+ const = klass.const_get(name)
72
+ klass.const_set(name, const) if const == const_get(name)
73
+ end
74
+ end
75
+
76
+ def delegate_session(klass)
77
+ return if klass == Object or klass == Kernel
78
+ klass.extend(Methods)
79
+ namespace = self
80
+ klass.define_singleton_method(:session) { namespace.session }
81
+ klass.define_singleton_method(:session=) { |value| namespace.session = value }
82
+ end
83
+ end
84
+ end
85
+ end
@@ -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