github_concern 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/MIT-LICENSE +20 -0
- data/README.markdown +78 -0
- data/Rakefile +23 -0
- data/app/assets/javascripts/github.js +2 -0
- data/app/assets/stylesheets/github.css +4 -0
- data/app/controllers/application_controller.rb +2 -0
- data/app/controllers/github_controller.rb +7 -0
- data/app/helpers/github_helper.rb +2 -0
- data/app/models/git_commit.rb +4 -0
- data/app/models/git_push.rb +56 -0
- data/app/models/github_concernable_git_push.rb +4 -0
- data/config/routes.rb +3 -0
- data/db/migrate/20111204031658_create_git_pushes.rb +9 -0
- data/db/migrate/20111204031730_create_git_commits.rb +10 -0
- data/db/migrate/20111204041743_add_user_id_to_git_push.rb +5 -0
- data/db/migrate/20111204055027_create_github_concernable_git_pushes.rb +11 -0
- data/lib/github_concern/engine.rb +50 -0
- data/lib/github_concern/version.rb +3 -0
- data/lib/github_concern.rb +15 -0
- data/lib/tasks/github_concern_tasks.rake +4 -0
- data/spec/controllers/github_controller_spec.rb +29 -0
- data/spec/internal/app/models/project.rb +2 -0
- data/spec/internal/app/models/ticket.rb +6 -0
- data/spec/internal/app/models/user.rb +2 -0
- data/spec/internal/config/application.rb +1 -0
- data/spec/internal/config/database.yml +3 -0
- data/spec/internal/config/initializers/github_concern.rb +11 -0
- data/spec/internal/config/routes.rb +3 -0
- data/spec/internal/db/combustion_test.sqlite +0 -0
- data/spec/internal/db/schema.rb +36 -0
- data/spec/internal/log/test.log +2387 -0
- data/spec/internal/public/favicon.ico +0 -0
- data/spec/models/git_push.rb +57 -0
- data/spec/spec_helper.rb +13 -0
- data/spec/support/github_payload.rb +3 -0
- metadata +158 -0
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2011 Adam Gamble
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.markdown
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
# Github Concern
|
2
|
+
|
3
|
+
Github Concern is a library to make integrating your application with github
|
4
|
+
braindead simple. It has the following useful features:
|
5
|
+
|
6
|
+
* Provides a controller to respond to github post-push service hooks.
|
7
|
+
* Provides models to store the information github sends you.
|
8
|
+
* Provides a DSL for easily specifying which objects in your system should be
|
9
|
+
associated with commits.
|
10
|
+
* Provides a DSL to specify actions in your system that should be taken as a
|
11
|
+
result of specific commits being seen. For instance, in a time tracking
|
12
|
+
system you might add something that responded to commits that had "\[HOURS:
|
13
|
+
3.5\]" in them by creating a WorkUnit in the system, associated with that
|
14
|
+
commit, for 3.5 hours.
|
15
|
+
|
16
|
+
## Installation
|
17
|
+
|
18
|
+
First, add github\_concern to your Gemfile:
|
19
|
+
|
20
|
+
```ruby
|
21
|
+
gem 'github_concern', :git => 'http://github.com/adamgamble/github_concern.git'
|
22
|
+
```
|
23
|
+
|
24
|
+
bundle install
|
25
|
+
|
26
|
+
Now github\_concern is available to your application. Next, add a service hook
|
27
|
+
to your github repo that posts to http://your\_url/github\_integration
|
28
|
+
|
29
|
+
Add this to config/initializers/github\_concern.rb:
|
30
|
+
|
31
|
+
```ruby
|
32
|
+
GithubConcern::Engine.config do |gc|
|
33
|
+
gc.user_lambda = lambda {|email| User.find_by_email email}
|
34
|
+
gc.user_class = User
|
35
|
+
end
|
36
|
+
```
|
37
|
+
|
38
|
+
You can adjust the lambda to fit your needs for determining a user.
|
39
|
+
|
40
|
+
You need to create tables to store the commits and pushes that the github web
|
41
|
+
hook is going to be sending you. Run this command to install the migrations:
|
42
|
+
|
43
|
+
rake github_concern_engine:install:migrations
|
44
|
+
|
45
|
+
You can configure whatever models you want to be associated with the git pushes:
|
46
|
+
|
47
|
+
```ruby
|
48
|
+
class SomeModel < ActiveRecord::Base
|
49
|
+
github_concern :repo => :github_repo, :branch => :github_branch
|
50
|
+
|
51
|
+
def github_concern_callback git_push
|
52
|
+
end
|
53
|
+
end
|
54
|
+
```
|
55
|
+
|
56
|
+
`:github_repo`, and `:github_branch` represent attributes on the model
|
57
|
+
|
58
|
+
Now when someone pushes to a repo that has the service hook, information about
|
59
|
+
that will be stored in the database and associated to whatever models specified.
|
60
|
+
It will also call the `github_concern_callback` method on the object if it
|
61
|
+
exists.
|
62
|
+
|
63
|
+
## Contributing
|
64
|
+
|
65
|
+
Fork our repo, make a feature branch, push to it. Send us a pull request.
|
66
|
+
We'll communicate back and forth via the github interface. All contributions
|
67
|
+
are welcome. Plase inform us of issues via the github issue tracker
|
68
|
+
|
69
|
+
## Authors
|
70
|
+
|
71
|
+
* Adam Gamble
|
72
|
+
* Josh Adams*
|
73
|
+
|
74
|
+
\* Hasn't actually commited any code yet
|
75
|
+
|
76
|
+
## License
|
77
|
+
|
78
|
+
See the MIT-LICENSE file for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
#!/usr/bin/env rake
|
2
|
+
begin
|
3
|
+
require 'bundler/setup'
|
4
|
+
rescue LoadError
|
5
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
6
|
+
end
|
7
|
+
begin
|
8
|
+
require 'rdoc/task'
|
9
|
+
rescue LoadError
|
10
|
+
require 'rdoc/rdoc'
|
11
|
+
require 'rake/rdoctask'
|
12
|
+
RDoc::Task = Rake::RDocTask
|
13
|
+
end
|
14
|
+
|
15
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
16
|
+
rdoc.rdoc_dir = 'rdoc'
|
17
|
+
rdoc.title = 'GithubConcern'
|
18
|
+
rdoc.options << '--line-numbers'
|
19
|
+
rdoc.rdoc_files.include('README.rdoc')
|
20
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
21
|
+
end
|
22
|
+
|
23
|
+
Bundler::GemHelper.install_tasks
|
@@ -0,0 +1,56 @@
|
|
1
|
+
class GitPush < ActiveRecord::Base
|
2
|
+
before_create :associate_user
|
3
|
+
after_create :associate_git_concernables, :build_commits
|
4
|
+
|
5
|
+
serialize :payload
|
6
|
+
belongs_to GithubConcern::Engine.user_class_symbol, :foreign_key => :user_id
|
7
|
+
has_many :github_concernable_git_pushes
|
8
|
+
has_many :github_concernables, :through => :github_concernable_git_pushes
|
9
|
+
has_many :git_commits
|
10
|
+
|
11
|
+
private
|
12
|
+
def associate_user
|
13
|
+
email = payload["pusher"]["email"]
|
14
|
+
user = GithubConcern::Engine.determine_user(email)
|
15
|
+
self.user_id = user.id if user
|
16
|
+
end
|
17
|
+
|
18
|
+
def build_commits
|
19
|
+
payload["commits"].each do |commit|
|
20
|
+
git_commits.create(:payload => commit)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def associate_git_concernables
|
25
|
+
GithubConcern::Engine.github_concerns.each_pair do |class_name, github_concern_hash|
|
26
|
+
bucket = class_name.constantize
|
27
|
+
github_concern_hash.each_pair do |github_concern_key, github_concern_method|
|
28
|
+
case github_concern_key
|
29
|
+
when :repo
|
30
|
+
git_variable = payload["repository"]["name"]
|
31
|
+
when :branch
|
32
|
+
git_variable = payload["ref"].gsub("refs/heads/","")
|
33
|
+
when :class_method
|
34
|
+
objects = bucket.send(github_concern_method,payload["repository"]["name"],payload["ref"].gsub("refs/heads/",""))
|
35
|
+
if objects.respond_to?(:each)
|
36
|
+
objects.each {|object| associate_to_object object }
|
37
|
+
else
|
38
|
+
associate_to_object objects
|
39
|
+
end
|
40
|
+
next
|
41
|
+
end
|
42
|
+
bucket = bucket.where(github_concern_method => git_variable)
|
43
|
+
end
|
44
|
+
bucket.all.each do |object|
|
45
|
+
associate_to_object object
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def associate_to_object object
|
51
|
+
github_concernable_git_push = self.github_concernable_git_pushes.new
|
52
|
+
github_concernable_git_push.github_concernable = object
|
53
|
+
github_concernable_git_push.save
|
54
|
+
object.github_concern_callback(self) if object.respond_to?(:github_concern_callback)
|
55
|
+
end
|
56
|
+
end
|
data/config/routes.rb
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
class CreateGithubConcernableGitPushes < ActiveRecord::Migration
|
2
|
+
def change
|
3
|
+
create_table :github_concernable_git_pushes do |t|
|
4
|
+
t.string :github_concernable_type
|
5
|
+
t.integer :github_concernable_id
|
6
|
+
t.integer :git_push_id
|
7
|
+
|
8
|
+
t.timestamps
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'rails/all'
|
2
|
+
module GithubConcern
|
3
|
+
class Engine < Rails::Engine
|
4
|
+
@@github_concerns = {}
|
5
|
+
def self.config
|
6
|
+
yield(self)
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.add_class(class_constant, options)
|
10
|
+
@@github_concerns[class_constant.to_s] = options
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.github_concerns
|
14
|
+
@@github_concerns
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.user_lambda= find_user_lambda
|
18
|
+
@@user_lambda = find_user_lambda
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.user_lambda
|
22
|
+
@@user_lambda
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.user_class= user_class_constant
|
26
|
+
@@user_class= user_class_constant
|
27
|
+
@@user_class.class_eval { has_many :git_pushes }
|
28
|
+
@@user_class
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.user_class
|
32
|
+
@@user_class
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.user_class_symbol
|
36
|
+
@@user_class.try(:to_s).try(:downcase).try(:to_sym)
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.determine_user(email)
|
40
|
+
@@user_lambda.call(email)
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.add_github_concernable_relationship_to_class(class_constant)
|
44
|
+
class_constant.class_eval {
|
45
|
+
has_many :github_concernables, :class_name => "GithubConcernableGitPush", :as => :github_concernable
|
46
|
+
has_many :git_pushes, :through => :github_concernables
|
47
|
+
}
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require "github_concern/engine"
|
2
|
+
|
3
|
+
module GithubConcern
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
included do
|
6
|
+
end
|
7
|
+
|
8
|
+
module ClassMethods
|
9
|
+
def github_concern(options = {})
|
10
|
+
GithubConcern::Engine.add_class(self, options)
|
11
|
+
GithubConcern::Engine.add_github_concernable_relationship_to_class(self)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
ActiveRecord::Base.send :include, GithubConcern
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe GithubController do
|
4
|
+
describe "POST payload" do
|
5
|
+
it "returns 500 when not sending a payload" do
|
6
|
+
post :payload
|
7
|
+
response.code.should == "500"
|
8
|
+
end
|
9
|
+
|
10
|
+
describe "when sending a valid payload" do
|
11
|
+
before(:each) do
|
12
|
+
payload = valid_payload_hash.to_json
|
13
|
+
post :payload, :payload => payload
|
14
|
+
end
|
15
|
+
|
16
|
+
it "returns 200 when sending a valid payload" do
|
17
|
+
response.should be_success
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should create a git push" do
|
21
|
+
GitPush.count.should == 1
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should set the payload of that git push to payload" do
|
25
|
+
GitPush.last.payload.should == valid_payload_hash
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'github_concern'
|
@@ -0,0 +1,11 @@
|
|
1
|
+
GithubConcern::Engine.config do |gc|
|
2
|
+
gc.user_lambda = lambda {|email| User.find_by_email email}
|
3
|
+
gc.user_class = User
|
4
|
+
end
|
5
|
+
|
6
|
+
Module.constants.select do |constant_name|
|
7
|
+
constant = constant_name.to_s.constantize
|
8
|
+
if not constant.nil? and constant.is_a? Class and constant.superclass == ActiveRecord::Base
|
9
|
+
constant.inspect
|
10
|
+
end
|
11
|
+
end
|
Binary file
|
@@ -0,0 +1,36 @@
|
|
1
|
+
ActiveRecord::Schema.define do
|
2
|
+
create_table(:users, :force => true) do |t|
|
3
|
+
t.string :email
|
4
|
+
t.timestamps
|
5
|
+
end
|
6
|
+
|
7
|
+
create_table(:projects, :force => true) do |t|
|
8
|
+
t.string :github_repo
|
9
|
+
t.timestamps
|
10
|
+
end
|
11
|
+
|
12
|
+
create_table(:tickets, :force => true) do |t|
|
13
|
+
t.string :github_repo
|
14
|
+
t.string :github_branch
|
15
|
+
t.timestamps
|
16
|
+
end
|
17
|
+
|
18
|
+
create_table(:git_pushes, :force => true) do |t|
|
19
|
+
t.text :payload
|
20
|
+
t.integer :user_id
|
21
|
+
t.timestamps
|
22
|
+
end
|
23
|
+
|
24
|
+
create_table(:git_commits, :force => true) do |t|
|
25
|
+
t.text :payload
|
26
|
+
t.integer :git_push_id
|
27
|
+
t.timestamps
|
28
|
+
end
|
29
|
+
|
30
|
+
create_table(:github_concernable_git_pushes, :force => true) do |t|
|
31
|
+
t.string :github_concernable_type
|
32
|
+
t.integer :github_concernable_id
|
33
|
+
t.integer :git_push_id
|
34
|
+
t.timestamps
|
35
|
+
end
|
36
|
+
end
|