travis-core 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (138) hide show
  1. data/Gemfile +25 -0
  2. data/Gemfile.lock +203 -0
  3. data/LICENSE +21 -0
  4. data/README.md +1 -0
  5. data/Rakefile +12 -0
  6. data/lib/core_ext/active_record/base.rb +24 -0
  7. data/lib/core_ext/array/flatten_once.rb +6 -0
  8. data/lib/core_ext/hash/compact.rb +12 -0
  9. data/lib/core_ext/hash/deep_symbolize_keys.rb +15 -0
  10. data/lib/core_ext/ostruct/hash_access.rb +9 -0
  11. data/lib/devise/api_token_authenticatable.rb +10 -0
  12. data/lib/devise/models/api_token_authenticatable.rb +15 -0
  13. data/lib/devise/strategies/api_token_authenticatable.rb +46 -0
  14. data/lib/github.rb +170 -0
  15. data/lib/irc_client.rb +43 -0
  16. data/lib/travis.rb +29 -0
  17. data/lib/travis/amqp.rb +36 -0
  18. data/lib/travis/config.rb +44 -0
  19. data/lib/travis/database.rb +19 -0
  20. data/lib/travis/github_api.rb +32 -0
  21. data/lib/travis/logging.rb +42 -0
  22. data/lib/travis/mailer.rb +24 -0
  23. data/lib/travis/mailer/build.rb +25 -0
  24. data/lib/travis/mailer/helper/build.rb +59 -0
  25. data/lib/travis/mailer/locales/en.yml +12 -0
  26. data/lib/travis/mailer/views/build/finished_email.html.erb +37 -0
  27. data/lib/travis/mailer/views/build/finished_email.text.erb +16 -0
  28. data/lib/travis/mailer/views/layouts/build.html.erb +258 -0
  29. data/lib/travis/mailer/views/layouts/build.text.erb +8 -0
  30. data/lib/travis/model.rb +26 -0
  31. data/lib/travis/model/artifact.rb +7 -0
  32. data/lib/travis/model/artifact/log.rb +9 -0
  33. data/lib/travis/model/build.rb +88 -0
  34. data/lib/travis/model/build/denormalize.rb +22 -0
  35. data/lib/travis/model/build/matrix.rb +99 -0
  36. data/lib/travis/model/build/messages.rb +29 -0
  37. data/lib/travis/model/build/notifications.rb +107 -0
  38. data/lib/travis/model/build/states.rb +43 -0
  39. data/lib/travis/model/commit.rb +6 -0
  40. data/lib/travis/model/job.rb +43 -0
  41. data/lib/travis/model/job/cleanup.rb +44 -0
  42. data/lib/travis/model/job/configure.rb +7 -0
  43. data/lib/travis/model/job/configure/states.rb +40 -0
  44. data/lib/travis/model/job/states.rb +55 -0
  45. data/lib/travis/model/job/tagging.rb +20 -0
  46. data/lib/travis/model/job/test.rb +19 -0
  47. data/lib/travis/model/job/test/states.rb +44 -0
  48. data/lib/travis/model/repository.rb +66 -0
  49. data/lib/travis/model/repository/service_hook.rb +37 -0
  50. data/lib/travis/model/request.rb +48 -0
  51. data/lib/travis/model/request/branches.rb +32 -0
  52. data/lib/travis/model/request/payload.rb +5 -0
  53. data/lib/travis/model/request/payload/github.rb +34 -0
  54. data/lib/travis/model/request/states.rb +36 -0
  55. data/lib/travis/model/token.rb +17 -0
  56. data/lib/travis/model/user.rb +62 -0
  57. data/lib/travis/model/worker.rb +23 -0
  58. data/lib/travis/notifications.rb +49 -0
  59. data/lib/travis/notifications/email.rb +29 -0
  60. data/lib/travis/notifications/irc.rb +53 -0
  61. data/lib/travis/notifications/pusher.rb +74 -0
  62. data/lib/travis/notifications/pusher/payload.rb +33 -0
  63. data/lib/travis/notifications/pusher/views/v1/event/build/finished.rabl +15 -0
  64. data/lib/travis/notifications/pusher/views/v1/event/build/finished/test.rabl +10 -0
  65. data/lib/travis/notifications/pusher/views/v1/event/build/log.rabl +13 -0
  66. data/lib/travis/notifications/pusher/views/v1/event/build/queued.rabl +9 -0
  67. data/lib/travis/notifications/pusher/views/v1/event/build/removed.rabl +9 -0
  68. data/lib/travis/notifications/pusher/views/v1/event/build/started.rabl +23 -0
  69. data/lib/travis/notifications/pusher/views/v1/event/build/started/test.rabl +11 -0
  70. data/lib/travis/notifications/pusher/views/v1/event/job/test/started.rabl +21 -0
  71. data/lib/travis/notifications/webhook.rb +43 -0
  72. data/lib/travis/notifications/webhook/payload.rb +30 -0
  73. data/lib/travis/notifications/webhook/views/v1/webhook/build.rabl +19 -0
  74. data/lib/travis/notifications/webhook/views/v1/webhook/job/test.rabl +14 -0
  75. data/lib/travis/notifications/webhook/views/v1/webhook/repository.rabl +3 -0
  76. data/lib/travis/notifications/worker.rb +58 -0
  77. data/lib/travis/notifications/worker/payload.rb +33 -0
  78. data/lib/travis/notifications/worker/queue.rb +35 -0
  79. data/lib/travis/notifications/worker/views/v1/worker/job/configure.rabl +11 -0
  80. data/lib/travis/notifications/worker/views/v1/worker/job/test.rabl +13 -0
  81. data/lib/travis/renderer.rb +86 -0
  82. data/lib/travis_core/engine.rb +4 -0
  83. data/lib/travis_core/version.rb +3 -0
  84. data/spec/fixtures/github/api/v2/json/organizations/travis-ci/public_members.json +1 -0
  85. data/spec/fixtures/github/api/v2/json/repos/show/svenfuchs.json +1 -0
  86. data/spec/fixtures/github/api/v2/json/repos/show/svenfuchs/gem-release.json +1 -0
  87. data/spec/fixtures/github/api/v2/json/repos/show/svenfuchs/minimal.json +1 -0
  88. data/spec/fixtures/github/api/v2/json/repos/show/travis-ci/travis-ci.json +1 -0
  89. data/spec/fixtures/github/api/v2/json/user/show/LTe.json +1 -0
  90. data/spec/fixtures/github/api/v2/json/user/show/svenfuchs.json +1 -0
  91. data/spec/lib/core_ext/active_record_spec.rb +27 -0
  92. data/spec/lib/core_ext/array_spec.rb +9 -0
  93. data/spec/lib/core_ext/hash_spec.rb +19 -0
  94. data/spec/lib/github_spec.rb +74 -0
  95. data/spec/lib/irc_client_spec.rb +107 -0
  96. data/spec/spec_helper.rb +26 -0
  97. data/spec/support/active_record.rb +30 -0
  98. data/spec/support/factories.rb +77 -0
  99. data/spec/support/formats.rb +36 -0
  100. data/spec/support/matchers.rb +126 -0
  101. data/spec/support/mocks/irc.rb +42 -0
  102. data/spec/support/mocks/pusher.rb +22 -0
  103. data/spec/support/payloads.rb +191 -0
  104. data/spec/support/pusher.rb +17 -0
  105. data/spec/support/webmock.rb +67 -0
  106. data/spec/travis/config_spec.rb +70 -0
  107. data/spec/travis/github_api_spec.rb +5 -0
  108. data/spec/travis/mailer/build_spec.rb +96 -0
  109. data/spec/travis/mailer/helper/build_spec.rb +13 -0
  110. data/spec/travis/model/artifact/log_spec.rb +23 -0
  111. data/spec/travis/model/build/denormalize_spec.rb +43 -0
  112. data/spec/travis/model/build/matrix_spec.rb +295 -0
  113. data/spec/travis/model/build/notifications_spec.rb +177 -0
  114. data/spec/travis/model/build/states_spec.rb +79 -0
  115. data/spec/travis/model/build_spec.rb +133 -0
  116. data/spec/travis/model/job/cleanup_spec.rb +61 -0
  117. data/spec/travis/model/job/configure/states_spec.rb +86 -0
  118. data/spec/travis/model/job/tagging_spec.rb +38 -0
  119. data/spec/travis/model/job/test/states_spec.rb +107 -0
  120. data/spec/travis/model/job_spec.rb +35 -0
  121. data/spec/travis/model/repository/service_hook_spec.rb +32 -0
  122. data/spec/travis/model/repository_spec.rb +85 -0
  123. data/spec/travis/model/request/branches_spec.rb +75 -0
  124. data/spec/travis/model/request/payload/github_spec.rb +80 -0
  125. data/spec/travis/model/request/states_spec.rb +214 -0
  126. data/spec/travis/model/request_spec.rb +67 -0
  127. data/spec/travis/model/token_spec.rb +7 -0
  128. data/spec/travis/model/user_spec.rb +62 -0
  129. data/spec/travis/model/worker_spec.rb +15 -0
  130. data/spec/travis/notifications/email_spec.rb +12 -0
  131. data/spec/travis/notifications/irc_spec.rb +97 -0
  132. data/spec/travis/notifications/pusher_spec.rb +105 -0
  133. data/spec/travis/notifications/webhook_spec.rb +40 -0
  134. data/spec/travis/notifications/worker/payload_spec.rb +6 -0
  135. data/spec/travis/notifications/worker/queue_spec.rb +37 -0
  136. data/spec/travis/notifications/worker_spec.rb +88 -0
  137. data/spec/travis/renderer_spec.rb +54 -0
  138. metadata +424 -0
data/Gemfile ADDED
@@ -0,0 +1,25 @@
1
+ source :rubygems
2
+
3
+ gemspec
4
+
5
+ platform :mri do
6
+ gem 'pg', '~> 0.11.0'
7
+ gem 'silent-postgres', '~> 0.0.8'
8
+ end
9
+
10
+ platform :jruby do
11
+ gem 'jruby-openssl'
12
+ gem 'activerecord-jdbcpostgresql-adapter'
13
+ end
14
+
15
+ group :development do
16
+ gem 'standalone_migrations'
17
+ end
18
+
19
+ group :test do
20
+ gem 'rspec', '~> 2.7.0'
21
+ gem 'factory_girl', '~> 2.1.2'
22
+ gem 'database_cleaner', '~> 0.6.7'
23
+ gem 'mocha', '~> 0.10.0'
24
+ gem 'webmock', '~> 1.7.7'
25
+ end
@@ -0,0 +1,203 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ travis-core (0.0.1)
5
+ actionmailer (~> 3.1.1)
6
+ activerecord (~> 3.1.1)
7
+ amqp (~> 0.8.2)
8
+ data_migrations (~> 0.0.1)
9
+ devise (~> 1.4.2)
10
+ hashr (~> 0.0.16)
11
+ oa-oauth (~> 0.3.0)
12
+ octokit (~> 0.6.5)
13
+ pusher (~> 0.8.1)
14
+ rabl (~> 0.5.0)
15
+ rails (~> 3.1.1)
16
+ rake (~> 0.9.2)
17
+ simple_states (~> 0.0.10)
18
+ thor (~> 0.14.6)
19
+
20
+ GEM
21
+ remote: http://rubygems.org/
22
+ specs:
23
+ actionmailer (3.1.1)
24
+ actionpack (= 3.1.1)
25
+ mail (~> 2.3.0)
26
+ actionpack (3.1.1)
27
+ activemodel (= 3.1.1)
28
+ activesupport (= 3.1.1)
29
+ builder (~> 3.0.0)
30
+ erubis (~> 2.7.0)
31
+ i18n (~> 0.6)
32
+ rack (~> 1.3.2)
33
+ rack-cache (~> 1.1)
34
+ rack-mount (~> 0.8.2)
35
+ rack-test (~> 0.6.1)
36
+ sprockets (~> 2.0.2)
37
+ activemodel (3.1.1)
38
+ activesupport (= 3.1.1)
39
+ builder (~> 3.0.0)
40
+ i18n (~> 0.6)
41
+ activerecord (3.1.1)
42
+ activemodel (= 3.1.1)
43
+ activesupport (= 3.1.1)
44
+ arel (~> 2.2.1)
45
+ tzinfo (~> 0.3.29)
46
+ activeresource (3.1.1)
47
+ activemodel (= 3.1.1)
48
+ activesupport (= 3.1.1)
49
+ activesupport (3.1.1)
50
+ multi_json (~> 1.0)
51
+ addressable (2.2.6)
52
+ amq-client (0.8.5)
53
+ amq-protocol (>= 0.8.0)
54
+ eventmachine
55
+ amq-protocol (0.8.3)
56
+ amqp (0.8.2)
57
+ amq-client (~> 0.8.5)
58
+ amq-protocol (~> 0.8.3)
59
+ eventmachine
60
+ arel (2.2.1)
61
+ bcrypt-ruby (3.0.1)
62
+ builder (3.0.0)
63
+ crack (0.1.8)
64
+ data_migrations (0.0.1)
65
+ activerecord
66
+ rake
67
+ database_cleaner (0.6.7)
68
+ devise (1.4.9)
69
+ bcrypt-ruby (~> 3.0)
70
+ orm_adapter (~> 0.0.3)
71
+ warden (~> 1.0.3)
72
+ diff-lcs (1.1.3)
73
+ erubis (2.7.0)
74
+ eventmachine (0.12.10)
75
+ factory_girl (2.1.2)
76
+ activesupport
77
+ faraday (0.7.5)
78
+ addressable (~> 2.2.6)
79
+ multipart-post (~> 1.1.3)
80
+ rack (>= 1.1.0, < 2)
81
+ faraday_middleware (0.7.0)
82
+ faraday (~> 0.7.3)
83
+ hashie (1.2.0)
84
+ hashr (0.0.16)
85
+ hike (1.2.1)
86
+ i18n (0.6.0)
87
+ json (1.6.1)
88
+ mail (2.3.0)
89
+ i18n (>= 0.4.0)
90
+ mime-types (~> 1.16)
91
+ treetop (~> 1.4.8)
92
+ metaclass (0.0.1)
93
+ mime-types (1.17.2)
94
+ mocha (0.10.0)
95
+ metaclass (~> 0.0.1)
96
+ multi_json (1.0.3)
97
+ multi_xml (0.4.1)
98
+ multipart-post (1.1.3)
99
+ oa-core (0.3.2)
100
+ oa-oauth (0.3.2)
101
+ faraday (~> 0.7.3)
102
+ multi_json (~> 1.0.0)
103
+ multi_xml (~> 0.4.0)
104
+ oa-core (= 0.3.2)
105
+ oauth (~> 0.4.0)
106
+ oauth2 (~> 0.5.0)
107
+ oauth (0.4.5)
108
+ oauth2 (0.5.1)
109
+ faraday (~> 0.7.4)
110
+ multi_json (~> 1.0.3)
111
+ octokit (0.6.5)
112
+ addressable (~> 2.2.6)
113
+ faraday (~> 0.7.4)
114
+ faraday_middleware (~> 0.7.0)
115
+ hashie (~> 1.2.0)
116
+ multi_json (~> 1.0.2)
117
+ orm_adapter (0.0.5)
118
+ pg (0.11.0)
119
+ polyglot (0.3.2)
120
+ pusher (0.8.4)
121
+ crack (~> 0.1.0)
122
+ multi_json (~> 1.0)
123
+ ruby-hmac (~> 0.4.0)
124
+ signature (~> 0.1.2)
125
+ rabl (0.5.1)
126
+ activesupport (>= 2.3.14)
127
+ multi_json (~> 1.0.3)
128
+ rack (1.3.5)
129
+ rack-cache (1.1)
130
+ rack (>= 0.4)
131
+ rack-mount (0.8.3)
132
+ rack (>= 1.0.0)
133
+ rack-ssl (1.3.2)
134
+ rack
135
+ rack-test (0.6.1)
136
+ rack (>= 1.0)
137
+ rails (3.1.1)
138
+ actionmailer (= 3.1.1)
139
+ actionpack (= 3.1.1)
140
+ activerecord (= 3.1.1)
141
+ activeresource (= 3.1.1)
142
+ activesupport (= 3.1.1)
143
+ bundler (~> 1.0)
144
+ railties (= 3.1.1)
145
+ railties (3.1.1)
146
+ actionpack (= 3.1.1)
147
+ activesupport (= 3.1.1)
148
+ rack-ssl (~> 1.3.2)
149
+ rake (>= 0.8.7)
150
+ rdoc (~> 3.4)
151
+ thor (~> 0.14.6)
152
+ rake (0.9.2.2)
153
+ rdoc (3.11)
154
+ json (~> 1.4)
155
+ rspec (2.7.0)
156
+ rspec-core (~> 2.7.0)
157
+ rspec-expectations (~> 2.7.0)
158
+ rspec-mocks (~> 2.7.0)
159
+ rspec-core (2.7.1)
160
+ rspec-expectations (2.7.0)
161
+ diff-lcs (~> 1.1.2)
162
+ rspec-mocks (2.7.0)
163
+ ruby-hmac (0.4.0)
164
+ signature (0.1.2)
165
+ ruby-hmac
166
+ silent-postgres (0.0.8)
167
+ simple_states (0.0.10)
168
+ activesupport
169
+ hashr (~> 0.0.10)
170
+ sprockets (2.0.3)
171
+ hike (~> 1.2)
172
+ rack (~> 1.0)
173
+ tilt (~> 1.1, != 1.3.0)
174
+ standalone_migrations (1.0.4)
175
+ activerecord (>= 3)
176
+ rake
177
+ thor (0.14.6)
178
+ tilt (1.3.3)
179
+ treetop (1.4.10)
180
+ polyglot
181
+ polyglot (>= 0.3.1)
182
+ tzinfo (0.3.31)
183
+ warden (1.0.6)
184
+ rack (>= 1.0)
185
+ webmock (1.7.7)
186
+ addressable (~> 2.2, > 2.2.5)
187
+ crack (>= 0.1.7)
188
+
189
+ PLATFORMS
190
+ ruby
191
+
192
+ DEPENDENCIES
193
+ activerecord-jdbcpostgresql-adapter
194
+ database_cleaner (~> 0.6.7)
195
+ factory_girl (~> 2.1.2)
196
+ jruby-openssl
197
+ mocha (~> 0.10.0)
198
+ pg (~> 0.11.0)
199
+ rspec (~> 2.7.0)
200
+ silent-postgres (~> 0.0.8)
201
+ standalone_migrations
202
+ travis-core!
203
+ webmock (~> 1.7.7)
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT LICENSE
2
+
3
+ Copyright (c) Sven Fuchs <svenfuchs@artweb-design.de>
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1 @@
1
+ # travis-core
@@ -0,0 +1,12 @@
1
+ require 'rake'
2
+ require 'rspec/core/rake_task'
3
+ require 'tasks/standalone_migrations'
4
+
5
+ desc 'Run specs'
6
+ RSpec::Core::RakeTask.new do |t|
7
+ t.pattern = './spec/**/*_spec.rb'
8
+ end
9
+
10
+ task :default => :spec
11
+
12
+
@@ -0,0 +1,24 @@
1
+ require 'active_record'
2
+
3
+ class ActiveRecord::Base
4
+ SQL = {
5
+ :floor => {
6
+ 'postgresql' => 'floor(%s::float)',
7
+ 'mysql' => 'floor(%s)',
8
+ 'sqlite3' => 'round(%s - 0.5)'
9
+ }
10
+ }
11
+ class << self
12
+ def floor(field)
13
+ SQL[:floor][adapter] % field
14
+ end
15
+
16
+ # TODO extract this to somewhere else and use Travis.config.env instead
17
+ def adapter
18
+ env = defined?(Rails) ? Rails.env : ENV['RAILS_ENV'] || ENV['ENV'] || 'test'
19
+ adapter = configurations[env]['adapter']
20
+ adapter == 'jdbcpostgresql' ? 'postgresql' : adapter
21
+ end
22
+ end
23
+ end
24
+
@@ -0,0 +1,6 @@
1
+ class Array
2
+ def flatten_once
3
+ inject([]) { |result, element| result.push(*element) }
4
+ end unless method_defined?(:flatten_once)
5
+ end
6
+
@@ -0,0 +1,12 @@
1
+ class Hash
2
+ def compact
3
+ dup.compact!
4
+ end
5
+
6
+ def compact!
7
+ keys.each do |key|
8
+ delete(key) if self[key].nil?
9
+ end
10
+ self
11
+ end
12
+ end unless {}.respond_to?(:compact)
@@ -0,0 +1,15 @@
1
+ class Hash
2
+ def deep_symbolize_keys
3
+ inject({}) { |result, (key, value)|
4
+ result[(key.to_sym rescue key) || key] = case value
5
+ when Array
6
+ value.map { |value| value.is_a?(Hash) ? value.deep_symbolize_keys : value }
7
+ when Hash
8
+ value.deep_symbolize_keys
9
+ else
10
+ value
11
+ end
12
+ result
13
+ }
14
+ end unless Hash.method_defined?(:deep_symbolize_keys)
15
+ end
@@ -0,0 +1,9 @@
1
+ class OpenStruct
2
+ def [](name)
3
+ @table[name.to_sym]
4
+ end
5
+
6
+ def []=(name, value)
7
+ @table[name.to_sym] = value
8
+ end
9
+ end
@@ -0,0 +1,10 @@
1
+ require 'devise'
2
+ require 'devise/models/api_token_authenticatable'
3
+ require 'devise/strategies/api_token_authenticatable'
4
+
5
+ module Devise
6
+ add_module(:api_token_authenticatable, :strategy => true) # TODO somehow configure warden failure app to not use new_session_path
7
+
8
+ mattr_accessor :api_token_authentication_keys
9
+ self.api_token_authentication_keys = [:login, :token]
10
+ end
@@ -0,0 +1,15 @@
1
+ module Devise
2
+ module Models
3
+ module ApiTokenAuthenticatable
4
+ extend ActiveSupport::Concern
5
+
6
+ module ClassMethods
7
+ def find_for_api_token_authentication(conditions)
8
+ where(:login => conditions[:login]).joins(:tokens).where(Token.arel_table[:token].eq(conditions[:token])).first
9
+ end
10
+
11
+ ::Devise::Models.config(self, :api_token_authentication_keys)
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,46 @@
1
+ require 'devise/strategies/token_authenticatable'
2
+
3
+ module Devise
4
+ module Strategies
5
+ class ApiTokenAuthenticatable < TokenAuthenticatable
6
+ def store?
7
+ false
8
+ end
9
+
10
+ def authenticate!
11
+ resource = mapping.to.find_for_api_token_authentication(authentication_hash)
12
+
13
+ if validate(resource)
14
+ resource.after_api_token_authentication if resource.respond_to?(:after_api_token_authentication)
15
+ success!(resource)
16
+ else
17
+ fail(:invalid_token)
18
+ end
19
+ end
20
+
21
+ private
22
+ def valid_request?
23
+ request.post?
24
+ end
25
+
26
+ def remember_me?
27
+ false
28
+ end
29
+
30
+ def params_auth_hash
31
+ # params[scope] || params
32
+ {}
33
+ end
34
+
35
+ def http_auth_hash
36
+ Hash[*authentication_keys.zip(decode_credentials).flatten]
37
+ end
38
+
39
+ def authentication_keys
40
+ @authentication_keys ||= mapping.to.api_token_authentication_keys
41
+ end
42
+ end
43
+ end
44
+ end
45
+
46
+ Warden::Strategies.add(:api_token_authenticatable, Devise::Strategies::ApiTokenAuthenticatable)
@@ -0,0 +1,170 @@
1
+ require 'ostruct'
2
+ require 'active_support/core_ext/string/inflections'
3
+ require 'core_ext/ostruct/hash_access'
4
+ require 'active_support/json'
5
+
6
+ # TODO: either port this to Octokit or use Hashr instead of OpenStruct
7
+ module Github
8
+ module Api
9
+ class << self
10
+ def included(base)
11
+ base.extend(ClassMethods)
12
+ end
13
+ end
14
+
15
+ module ClassMethods
16
+ def fetch(data)
17
+ new(data).fetch
18
+ end
19
+ end
20
+
21
+ def fetch
22
+ uri = URI.parse("http://github.com/api/v2/json/#{path}")
23
+ response = Net::HTTP.get_response(uri)
24
+ data = ActiveSupport::JSON.decode(response.body)
25
+ key = self.class.name.demodulize.underscore
26
+ data.replace(data[key]) if data.key?(key)
27
+ self.class.new(data)
28
+ end
29
+ end
30
+
31
+ module ServiceHook
32
+ class Payload < OpenStruct
33
+ attr_reader :payload
34
+
35
+ def initialize(payload)
36
+ @payload = payload
37
+ payload = ActiveSupport::JSON.decode(payload) if payload.is_a?(String)
38
+ super(payload)
39
+ end
40
+
41
+ def repository
42
+ @repository ||= Repository.new(super)
43
+ end
44
+
45
+ def last_commit
46
+ commits.last
47
+ end
48
+
49
+ def commits
50
+ @commits ||= Array(self['commits']).map do |commit|
51
+ Commit.new(commit.merge('ref' => ref, 'compare_url' => compare_url), repository)
52
+ end
53
+ end
54
+
55
+ def compare_url
56
+ self['compare']
57
+ end
58
+ end
59
+ end
60
+
61
+ class Repository < OpenStruct
62
+ include Api
63
+
64
+ ATTR_NAMES = [:name, :url, :owner_name, :owner_email]
65
+
66
+ def to_hash
67
+ ATTR_NAMES.inject({}) { |result, name| result.merge(name => self.send(name)) }
68
+ end
69
+
70
+ def owner_name
71
+ owner.is_a?(Hash) ? owner['name'] : owner
72
+ end
73
+
74
+ def owner_email
75
+ if owner.is_a?(Hash) && email = owner['email']
76
+ return email if email
77
+ end
78
+
79
+ if organization
80
+ Organization.fetch(:name => organization).member_emails
81
+ else
82
+ User.fetch(:name => owner_name).email
83
+ end
84
+ end
85
+
86
+ def path
87
+ "repos/show/#{owner_name}/#{name}"
88
+ end
89
+
90
+ def private?
91
+ self['private']
92
+ end
93
+ end
94
+
95
+ class Commit < OpenStruct
96
+ ATTR_NAMES = [:commit, :message, :branch, :committed_at, :committer_name, :committer_email, :author_name, :author_email, :compare_url]
97
+
98
+ def initialize(data, repository)
99
+ data['author'] ||= {}
100
+ data['repository'] = repository
101
+ super(data)
102
+ end
103
+
104
+ def to_hash
105
+ ATTR_NAMES.inject({}) { |result, name| result.merge(name => self.send(name)) }
106
+ end
107
+
108
+ def commit
109
+ self['id']
110
+ end
111
+
112
+ def branch
113
+ (self['ref'] || '').split('/').last
114
+ end
115
+
116
+ def committed_at
117
+ self['timestamp']
118
+ end
119
+
120
+ def committer
121
+ self['committer'] || {}
122
+ end
123
+
124
+ def committer_name
125
+ committer['name']
126
+ end
127
+
128
+ def committer_email
129
+ committer['email']
130
+ end
131
+
132
+ def author
133
+ self['author'] || {}
134
+ end
135
+
136
+ def author_name
137
+ author['name']
138
+ end
139
+
140
+ def author_email
141
+ author['email']
142
+ end
143
+
144
+ def compare_url
145
+ self['compare_url']
146
+ end
147
+ end
148
+
149
+ class Organization < OpenStruct
150
+ include Api
151
+
152
+ def member_emails
153
+ users.map { |user| user['email'] }.select(&:present?).join(',')
154
+ end
155
+
156
+ def path
157
+ "organizations/#{name}/public_members"
158
+ end
159
+ end
160
+
161
+ class User < OpenStruct
162
+ include Api
163
+
164
+ def path
165
+ "user/show/#{name}"
166
+ end
167
+ end
168
+ end
169
+
170
+