gwooks 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ .DS_Store
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in gwooks.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Luca Ongaro
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,91 @@
1
+ # Gwooks
2
+
3
+ A DSL for quickly creating endpoints for [GitHub post-receive webhooks](https://help.github.com/articles/post-receive-hooks).
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'gwooks'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install gwooks
18
+
19
+ ## Usage
20
+
21
+ Extend the `Gwooks::Base` class and use the dsl to create you hooks:
22
+
23
+ ```ruby
24
+ class MyHooks < Gwooks::Base
25
+
26
+ repository_name "gwooks" do
27
+ # this block gets called when a post-receive webhook
28
+ # notifies a push to a repo named "gwooks"
29
+ end
30
+
31
+ commits_message /Bump new version v(\d+\.\d+\.\d+)/ do |matches|
32
+ # this block gets called when a post-receive webhook
33
+ # notifies a push with at least one commit message
34
+ # matching the Regexp. The block gets passed an array of
35
+ # MatchData objects, one for every match.
36
+ matches.each do |match|
37
+ # assuming a publish_tweet method was defined somewhere
38
+ # we can tweet about the new version released:
39
+ publish_tweet("New version released: #{match[1]}")
40
+ end
41
+ end
42
+
43
+ end
44
+ ```
45
+
46
+ Then set up an application providing an endpoint for the post-receive webhooks and make use of the class you created:
47
+
48
+ ```ruby
49
+ require "sinatra"
50
+
51
+ post "/webhook" do
52
+ MyHooks.call(params[:payload])
53
+ end
54
+ ```
55
+
56
+ Alternatively, you can use the sinatra application provided by the class `Gwooks::App`:
57
+
58
+ ```ruby
59
+ # In your config.ru
60
+
61
+ Gwooks::App.use_webhook MyHooks
62
+ use Gwooks::App
63
+ ```
64
+
65
+ ### Matcher methods
66
+
67
+ The full list of matcher methods is the following:
68
+ ```
69
+ after
70
+ before
71
+ commits_added
72
+ commits_author_email
73
+ commits_author_name
74
+ commits_id
75
+ commits_message
76
+ commits_modified
77
+ commits_removed
78
+ commits_timestamp
79
+ commits_url
80
+ ref
81
+ repository_description
82
+ repository_forks
83
+ repository_homepage
84
+ repository_name
85
+ repository_owner_email
86
+ repository_owner_name
87
+ repository_pledgie
88
+ repository_private
89
+ repository_url
90
+ repository_watchers
91
+ ```
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/gwooks.gemspec ADDED
@@ -0,0 +1,23 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'gwooks/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "gwooks"
8
+ gem.version = Gwooks::VERSION
9
+ gem.authors = ["Luca Ongaro"]
10
+ gem.email = ["lukeongaro@gmail.com"]
11
+ gem.description = "A DSL for quickly creating endpoints for GitHub post-receive webhooks."
12
+ gem.summary = "A DSL for quickly creating endpoints for GitHub post-receive webhooks. It provides methods for executing blocks of code when GitHub posts a payload matching some conditions in response to a code push."
13
+ gem.homepage = "https://github.com/lucaong/gwooks"
14
+
15
+ gem.files = `git ls-files`.split($/)
16
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ["lib"]
19
+ gem.add_dependency("json")
20
+ gem.add_dependency("sinatra")
21
+ gem.add_development_dependency("rspec")
22
+ gem.add_development_dependency("rack-test")
23
+ end
data/lib/gwooks/app.rb ADDED
@@ -0,0 +1,16 @@
1
+ require "sinatra/base"
2
+
3
+ module Gwooks
4
+ class App < Sinatra::Base
5
+
6
+ post "/" do
7
+ raise "No webhook specified." if settings.webhook.nil?
8
+ settings.webhook.call(params[:payload])
9
+ end
10
+
11
+ def self.use_webhook(hook)
12
+ set :webhook, hook
13
+ end
14
+
15
+ end
16
+ end
@@ -0,0 +1,112 @@
1
+ require "json"
2
+
3
+ module Gwooks
4
+ class Base
5
+
6
+ class << self
7
+ def call(payload)
8
+ new(payload).call
9
+ end
10
+
11
+ def hooks
12
+ @_hooks ||= []
13
+ end
14
+
15
+ def payload_matches(key, pattern, &block)
16
+ @_hooks ||= []
17
+ @_hooks << [key, pattern, block]
18
+ end
19
+
20
+ def ref(pattern, &block)
21
+ payload_matches("ref", pattern, &block)
22
+ end
23
+
24
+ method_names = %w(
25
+ after
26
+ before
27
+ commits_added
28
+ commits_author_email
29
+ commits_author_name
30
+ commits_id
31
+ commits_message
32
+ commits_modified
33
+ commits_removed
34
+ commits_timestamp
35
+ commits_url
36
+ ref
37
+ repository_description
38
+ repository_forks
39
+ repository_homepage
40
+ repository_name
41
+ repository_owner_email
42
+ repository_owner_name
43
+ repository_pledgie
44
+ repository_private
45
+ repository_url
46
+ repository_watchers
47
+ )
48
+
49
+ method_names.each do |method_name|
50
+ key = method_name.gsub("_", ".")
51
+
52
+ define_method(method_name.to_sym) do |pattern, &block|
53
+ payload_matches(key, pattern, &block)
54
+ end
55
+ end
56
+
57
+ end
58
+
59
+ attr_reader :payload
60
+ private :payload
61
+
62
+ def initialize(payload)
63
+ if payload.is_a? String
64
+ @payload = JSON.parse(payload)
65
+ else
66
+ @payload = payload
67
+ end
68
+ end
69
+
70
+ def call
71
+ self.class.hooks.each do |hook|
72
+ key, pattern, block = *hook
73
+ target = resolve_key(key)
74
+ if target.is_a? Array
75
+ match = target.map do |t|
76
+ match_pattern(t, pattern)
77
+ end.compact
78
+ matching = match.compact.size > 0
79
+ else
80
+ match = match_pattern(target, pattern)
81
+ matching = !match.nil?
82
+ end
83
+ instance_exec(match, &block) if matching
84
+ end
85
+ nil
86
+ end
87
+
88
+ private
89
+
90
+ def resolve_key(key)
91
+ key.split(".").inject(payload) do |obj, segment|
92
+ break nil if obj.nil?
93
+ if obj.is_a? Array
94
+ obj.map do |item|
95
+ item[segment]
96
+ end.flatten
97
+ else
98
+ obj[segment]
99
+ end
100
+ end
101
+ end
102
+
103
+ def match_pattern(target, pattern)
104
+ if pattern.is_a? Regexp
105
+ pattern.match(target)
106
+ else
107
+ target if target == pattern
108
+ end
109
+ end
110
+
111
+ end
112
+ end
@@ -0,0 +1,3 @@
1
+ module Gwooks
2
+ VERSION = "0.0.1"
3
+ end
data/lib/gwooks.rb ADDED
@@ -0,0 +1,3 @@
1
+ require "gwooks/version"
2
+ require "gwooks/base"
3
+ require "gwooks/app"
@@ -0,0 +1,41 @@
1
+ require File.expand_path("../spec_helper.rb", File.dirname(__FILE__))
2
+ require File.expand_path("../../lib/gwooks/app.rb", File.dirname(__FILE__))
3
+ require "rack/test"
4
+
5
+ Gwooks::App.instance_eval do
6
+ set :environment, :test
7
+ end
8
+
9
+ describe Gwooks::App do
10
+
11
+ include Rack::Test::Methods
12
+
13
+ def app
14
+ Gwooks::App
15
+ end
16
+
17
+ describe :use_webhook do
18
+ it "sets settings.webhook" do
19
+ Gwooks::App.should_receive(:set).with(:webhook, "foo")
20
+ Gwooks::App.use_webhook("foo")
21
+ end
22
+ end
23
+
24
+ describe "POST /" do
25
+ it "raises if settings.webhook is not set" do
26
+ Gwooks::App.stub(:webhook).and_return(nil)
27
+ expect {
28
+ post "/"
29
+ }.to raise_error(StandardError, /No webhook specified/)
30
+ end
31
+
32
+ it "invokes webhook.call() passing payload" do
33
+ webhook = Proc.new {}
34
+ Gwooks::App.stub(:webhook).and_return(webhook)
35
+ payload = "\{\}"
36
+ webhook.should_receive(:call).with(payload)
37
+ post "/", :payload => payload
38
+ end
39
+ end
40
+
41
+ end
@@ -0,0 +1,254 @@
1
+ require File.expand_path("../spec_helper.rb", File.dirname(__FILE__))
2
+ require File.expand_path("../../lib/gwooks/base.rb", File.dirname(__FILE__))
3
+
4
+ describe "subclass of Gwooks::Base" do
5
+
6
+ before(:each) do
7
+ Object.send(:remove_const, "GwooksBaseSub") if Object.const_defined?("GwooksBaseSub")
8
+ GwooksBaseSub = Class.new(Gwooks::Base)
9
+ end
10
+
11
+ describe :call do
12
+ it "creates a new instance passing payload and then invokes call()" do
13
+ gwooks = double GwooksBaseSub.new("{}")
14
+ GwooksBaseSub.should_receive(:new).with("{}").and_return(gwooks)
15
+ gwooks.should_receive(:call)
16
+ GwooksBaseSub.call("{}")
17
+ end
18
+ end
19
+
20
+ describe :payload_matches do
21
+ it "adds a new hook storing key, pattern and block" do
22
+ block = Proc.new {}
23
+ GwooksBaseSub.payload_matches "foo", "bar", &block
24
+ GwooksBaseSub.hooks.last.should == ["foo", "bar", block]
25
+ end
26
+ end
27
+
28
+ method_names = %w(
29
+ after
30
+ before
31
+ commits_added
32
+ commits_author_email
33
+ commits_author_name
34
+ commits_id
35
+ commits_message
36
+ commits_modified
37
+ commits_removed
38
+ commits_timestamp
39
+ commits_url
40
+ ref
41
+ repository_description
42
+ repository_forks
43
+ repository_homepage
44
+ repository_name
45
+ repository_owner_email
46
+ repository_owner_name
47
+ repository_pledgie
48
+ repository_private
49
+ repository_url
50
+ repository_watchers
51
+ )
52
+
53
+ method_names.each do |method_name|
54
+ key = method_name.gsub("_", ".")
55
+
56
+ describe method_name do
57
+ it "adds a new hook with key '#{key}'" do
58
+ block = Proc.new {}
59
+ GwooksBaseSub.send method_name.to_sym, "bar", &block
60
+ GwooksBaseSub.hooks.last.should == [key, "bar", block]
61
+ end
62
+ end
63
+ end
64
+
65
+ describe "instance" do
66
+
67
+ describe :new do
68
+ it "initializes payload parsing the argument as JSON if it is a string" do
69
+ gwooks = GwooksBaseSub.new("{\"foo\": \"bar\"}")
70
+ gwooks.send(:payload).should == {"foo" => "bar"}
71
+ end
72
+
73
+ it "initializes payload using the argument if it is not a string" do
74
+ gwooks = GwooksBaseSub.new({"foo" => "bar"})
75
+ gwooks.send(:payload).should == {"foo" => "bar"}
76
+ end
77
+ end
78
+
79
+ describe :call do
80
+ it "executes all matching hooks" do
81
+ probe = []
82
+ GwooksBaseSub.stub(:hooks).and_return([
83
+ ["repository.url", "foo/bar", Proc.new { probe << "baz" }],
84
+ ["repository.url", "foo/bar", Proc.new { probe << "qux" }]
85
+ ])
86
+ GwooksBaseSub.new(
87
+ "repository" => {
88
+ "url" => "foo/bar"
89
+ }
90
+ ).call()
91
+ probe.should include("baz", "qux")
92
+ end
93
+
94
+ it "does not execute non-matching hooks" do
95
+ probe = nil
96
+ GwooksBaseSub.stub(:hooks).and_return([
97
+ ["repository.url", "foo/bar", Proc.new { probe = "baz" }]
98
+ ])
99
+ GwooksBaseSub.new(
100
+ "repository" => {
101
+ "url" => "qux/quux"
102
+ }
103
+ ).call()
104
+ probe.should be_nil
105
+ end
106
+
107
+ it "execute hook if target is an array and any element matches" do
108
+ probe = nil
109
+ GwooksBaseSub.stub(:hooks).and_return([
110
+ ["commits.message", "foo", Proc.new { probe = "baz" }]
111
+ ])
112
+ GwooksBaseSub.new(
113
+ "commits" => [
114
+ { "message" => "foo" },
115
+ { "message" => "bar" }
116
+ ]
117
+ ).call()
118
+ probe.should == "baz"
119
+ end
120
+
121
+ it "supports regexp matching" do
122
+ probe = nil
123
+ GwooksBaseSub.stub(:hooks).and_return([
124
+ ["repository.url", /\b.oo/, Proc.new { probe = "baz" }]
125
+ ])
126
+ GwooksBaseSub.new(
127
+ "repository" => {
128
+ "url" => "foo/bar"
129
+ }
130
+ ).call()
131
+ probe.should == "baz"
132
+ end
133
+
134
+ it "executes block in the instance scope" do
135
+ probe = nil
136
+ GwooksBaseSub.stub(:hooks).and_return([
137
+ ["repository.url", /\b.oo/, Proc.new { probe = self }]
138
+ ])
139
+ gwooks = GwooksBaseSub.new(
140
+ "repository" => {
141
+ "url" => "foo/bar"
142
+ }
143
+ )
144
+ gwooks.call()
145
+ probe.should == gwooks
146
+ end
147
+
148
+ it "passes the matched string as argument to the block if string matching is used" do
149
+ probe = nil
150
+ GwooksBaseSub.stub(:hooks).and_return([
151
+ ["repository.url", "foo/bar", Proc.new {|url| probe = url }]
152
+ ])
153
+ GwooksBaseSub.new(
154
+ "repository" => {
155
+ "url" => "foo/bar"
156
+ }
157
+ ).call()
158
+ probe.should == "foo/bar"
159
+ end
160
+
161
+ it "passes the matchdata as argument to the block if regexp matching is used" do
162
+ probe = nil
163
+ GwooksBaseSub.stub(:hooks).and_return([
164
+ ["repository.url", /(\w+)\/(\w+)/, Proc.new {|match|
165
+ probe = "#{match[1]}#{match[2]}"
166
+ }]
167
+ ])
168
+ GwooksBaseSub.new(
169
+ "repository" => {
170
+ "url" => "foo/bar"
171
+ }
172
+ ).call()
173
+ probe.should == "foobar"
174
+ end
175
+
176
+ it "passes array of matches if target is an array and any element matches" do
177
+ probe = nil
178
+ GwooksBaseSub.stub(:hooks).and_return([
179
+ ["commits.message", /foo.*/, Proc.new {|matches|
180
+ probe = matches.map {|m| m[0] }
181
+ }]
182
+ ])
183
+ GwooksBaseSub.new(
184
+ "commits" => [
185
+ { "message" => "foo" },
186
+ { "message" => "bar" },
187
+ { "message" => "fooey" }
188
+ ]
189
+ ).call()
190
+ probe.should include("foo", "fooey")
191
+ end
192
+ end
193
+
194
+ describe :resolve_key do
195
+ it "returns nested object according to the key" do
196
+ GwooksBaseSub.new(
197
+ "foo" => {
198
+ "bar" => {
199
+ "baz" => "qux"
200
+ }
201
+ }
202
+ ).send(:resolve_key, "foo.bar.baz").should == "qux"
203
+ end
204
+
205
+ it "returns nil if nested object does not exist" do
206
+ GwooksBaseSub.new(
207
+ "foo" => {
208
+ "bar" => {}
209
+ }
210
+ ).send(:resolve_key, "foo.bar.baz").should == nil
211
+ end
212
+
213
+ it "returns nil if parent object does not exist" do
214
+ GwooksBaseSub.new(
215
+ "foo" => {}
216
+ ).send(:resolve_key, "foo.bar.baz").should == nil
217
+ end
218
+
219
+ it "returns all items in array when item is an array" do
220
+ GwooksBaseSub.new(
221
+ "foo" => ["a", "b", "c"]
222
+ ).send(:resolve_key, "foo").should == ["a", "b", "c"]
223
+ end
224
+
225
+ it "resolve key in array" do
226
+ GwooksBaseSub.new(
227
+ "foo" => [
228
+ { "bar" => 123 },
229
+ { "bar" => 321 }
230
+ ]
231
+ ).send(:resolve_key, "foo.bar").should == [123, 321]
232
+ end
233
+
234
+ it "resolve key in nested arrays" do
235
+ GwooksBaseSub.new(
236
+ "foo" => [
237
+ { "bar" => [
238
+ {"baz" => 123},
239
+ {"baz" => 321}
240
+ ]},
241
+ { "bar" => [
242
+ {"baz" => 312},
243
+ {"baz" => 132}
244
+ ]}
245
+ ]
246
+ ).send(:resolve_key, "foo.bar.baz").should == [123, 321, 312, 132]
247
+ end
248
+
249
+
250
+ end
251
+
252
+ end
253
+
254
+ end
@@ -0,0 +1,81 @@
1
+ require File.expand_path("../spec_helper.rb", File.dirname(__FILE__))
2
+ require File.expand_path("../../lib/gwooks/base.rb", File.dirname(__FILE__))
3
+ require File.expand_path("../../lib/gwooks/app.rb", File.dirname(__FILE__))
4
+ require "rack/test"
5
+
6
+ class IntegrationTestWebhook < Gwooks::Base
7
+ class << self
8
+ attr_accessor :probe
9
+ end
10
+
11
+ def initialize(payload)
12
+ self.class.probe = []
13
+ super payload
14
+ end
15
+
16
+ repository_url "foo/bar" do |url|
17
+ self.class.probe << "repository_url #{url}"
18
+ end
19
+
20
+ repository_owner_email "foo@bar.com" do |email|
21
+ self.class.probe << "repository_owner_email #{email}"
22
+ end
23
+
24
+ commits_message /\bv\d+\.\d+.\d+\b/ do |matches|
25
+ matches.each do |m|
26
+ self.class.probe << m[0]
27
+ end
28
+ end
29
+
30
+ repository_owner_name "qux" do |name|
31
+ self.class.probe << name
32
+ end
33
+ end
34
+
35
+ Gwooks::App.instance_eval do
36
+ set :environment, :test
37
+ use_webhook IntegrationTestWebhook
38
+ end
39
+
40
+ describe Gwooks::App do
41
+
42
+ include Rack::Test::Methods
43
+
44
+ def app
45
+ Gwooks::App
46
+ end
47
+
48
+ describe "when receiving a post-receive hook" do
49
+ let(:payload) do
50
+ <<-eos
51
+ {
52
+ "repository": {
53
+ "url": "foo/bar",
54
+ "owner": {
55
+ "name": "foo",
56
+ "email": "foo@bar.com"
57
+ }
58
+ },
59
+ "commits": [
60
+ { "message": "done some things" },
61
+ { "message": "v1.2.3"}
62
+ ]
63
+ }
64
+ eos
65
+ end
66
+
67
+ it "executes all matching hooks" do
68
+ post "/", :payload => payload
69
+ IntegrationTestWebhook.probe.should include(
70
+ "repository_url foo/bar",
71
+ "repository_owner_email foo@bar.com",
72
+ "v1.2.3"
73
+ )
74
+ end
75
+
76
+ it "does not execute non-matching hooks" do
77
+ post "/", :payload => payload
78
+ IntegrationTestWebhook.probe.should_not include("qux")
79
+ end
80
+ end
81
+ end
@@ -0,0 +1 @@
1
+ require "rspec"
metadata ADDED
@@ -0,0 +1,137 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: gwooks
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Luca Ongaro
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2013-01-13 00:00:00 Z
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ requirement: &id001 !ruby/object:Gem::Requirement
22
+ none: false
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ hash: 3
27
+ segments:
28
+ - 0
29
+ version: "0"
30
+ prerelease: false
31
+ type: :runtime
32
+ name: json
33
+ version_requirements: *id001
34
+ - !ruby/object:Gem::Dependency
35
+ requirement: &id002 !ruby/object:Gem::Requirement
36
+ none: false
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ hash: 3
41
+ segments:
42
+ - 0
43
+ version: "0"
44
+ prerelease: false
45
+ type: :runtime
46
+ name: sinatra
47
+ version_requirements: *id002
48
+ - !ruby/object:Gem::Dependency
49
+ requirement: &id003 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ hash: 3
55
+ segments:
56
+ - 0
57
+ version: "0"
58
+ prerelease: false
59
+ type: :development
60
+ name: rspec
61
+ version_requirements: *id003
62
+ - !ruby/object:Gem::Dependency
63
+ requirement: &id004 !ruby/object:Gem::Requirement
64
+ none: false
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ hash: 3
69
+ segments:
70
+ - 0
71
+ version: "0"
72
+ prerelease: false
73
+ type: :development
74
+ name: rack-test
75
+ version_requirements: *id004
76
+ description: A DSL for quickly creating endpoints for GitHub post-receive webhooks.
77
+ email:
78
+ - lukeongaro@gmail.com
79
+ executables: []
80
+
81
+ extensions: []
82
+
83
+ extra_rdoc_files: []
84
+
85
+ files:
86
+ - .gitignore
87
+ - Gemfile
88
+ - LICENSE.txt
89
+ - README.md
90
+ - Rakefile
91
+ - gwooks.gemspec
92
+ - lib/gwooks.rb
93
+ - lib/gwooks/app.rb
94
+ - lib/gwooks/base.rb
95
+ - lib/gwooks/version.rb
96
+ - spec/gwooks/app_spec.rb
97
+ - spec/gwooks/base_spec.rb
98
+ - spec/integration/integration_spec.rb
99
+ - spec/spec_helper.rb
100
+ homepage: https://github.com/lucaong/gwooks
101
+ licenses: []
102
+
103
+ post_install_message:
104
+ rdoc_options: []
105
+
106
+ require_paths:
107
+ - lib
108
+ required_ruby_version: !ruby/object:Gem::Requirement
109
+ none: false
110
+ requirements:
111
+ - - ">="
112
+ - !ruby/object:Gem::Version
113
+ hash: 3
114
+ segments:
115
+ - 0
116
+ version: "0"
117
+ required_rubygems_version: !ruby/object:Gem::Requirement
118
+ none: false
119
+ requirements:
120
+ - - ">="
121
+ - !ruby/object:Gem::Version
122
+ hash: 3
123
+ segments:
124
+ - 0
125
+ version: "0"
126
+ requirements: []
127
+
128
+ rubyforge_project:
129
+ rubygems_version: 1.8.24
130
+ signing_key:
131
+ specification_version: 3
132
+ summary: A DSL for quickly creating endpoints for GitHub post-receive webhooks. It provides methods for executing blocks of code when GitHub posts a payload matching some conditions in response to a code push.
133
+ test_files:
134
+ - spec/gwooks/app_spec.rb
135
+ - spec/gwooks/base_spec.rb
136
+ - spec/integration/integration_spec.rb
137
+ - spec/spec_helper.rb