github_concern 0.0.1

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 (36) hide show
  1. data/MIT-LICENSE +20 -0
  2. data/README.markdown +78 -0
  3. data/Rakefile +23 -0
  4. data/app/assets/javascripts/github.js +2 -0
  5. data/app/assets/stylesheets/github.css +4 -0
  6. data/app/controllers/application_controller.rb +2 -0
  7. data/app/controllers/github_controller.rb +7 -0
  8. data/app/helpers/github_helper.rb +2 -0
  9. data/app/models/git_commit.rb +4 -0
  10. data/app/models/git_push.rb +56 -0
  11. data/app/models/github_concernable_git_push.rb +4 -0
  12. data/config/routes.rb +3 -0
  13. data/db/migrate/20111204031658_create_git_pushes.rb +9 -0
  14. data/db/migrate/20111204031730_create_git_commits.rb +10 -0
  15. data/db/migrate/20111204041743_add_user_id_to_git_push.rb +5 -0
  16. data/db/migrate/20111204055027_create_github_concernable_git_pushes.rb +11 -0
  17. data/lib/github_concern/engine.rb +50 -0
  18. data/lib/github_concern/version.rb +3 -0
  19. data/lib/github_concern.rb +15 -0
  20. data/lib/tasks/github_concern_tasks.rake +4 -0
  21. data/spec/controllers/github_controller_spec.rb +29 -0
  22. data/spec/internal/app/models/project.rb +2 -0
  23. data/spec/internal/app/models/ticket.rb +6 -0
  24. data/spec/internal/app/models/user.rb +2 -0
  25. data/spec/internal/config/application.rb +1 -0
  26. data/spec/internal/config/database.yml +3 -0
  27. data/spec/internal/config/initializers/github_concern.rb +11 -0
  28. data/spec/internal/config/routes.rb +3 -0
  29. data/spec/internal/db/combustion_test.sqlite +0 -0
  30. data/spec/internal/db/schema.rb +36 -0
  31. data/spec/internal/log/test.log +2387 -0
  32. data/spec/internal/public/favicon.ico +0 -0
  33. data/spec/models/git_push.rb +57 -0
  34. data/spec/spec_helper.rb +13 -0
  35. data/spec/support/github_payload.rb +3 -0
  36. 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,2 @@
1
+ // Place all the behaviors and hooks related to the matching controller here.
2
+ // All this logic will automatically be available in application.js.
@@ -0,0 +1,4 @@
1
+ /*
2
+ Place all the styles related to the matching controller here.
3
+ They will automatically be included in application.css.
4
+ */
@@ -0,0 +1,2 @@
1
+ class ApplicationController < ActionController::Base
2
+ end
@@ -0,0 +1,7 @@
1
+ class GithubController < ApplicationController
2
+ def payload
3
+ render :nothing => true, :status => 500 and return unless params["payload"]
4
+ GitPush.create(:payload => JSON.parse(params["payload"]))
5
+ render :nothing => true, :status => 200
6
+ end
7
+ end
@@ -0,0 +1,2 @@
1
+ module GithubHelper
2
+ end
@@ -0,0 +1,4 @@
1
+ class GitCommit < ActiveRecord::Base
2
+ belongs_to :git_push
3
+ serialize :payload
4
+ end
@@ -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
@@ -0,0 +1,4 @@
1
+ class GithubConcernableGitPush < ActiveRecord::Base
2
+ belongs_to :github_concernable, :polymorphic => true
3
+ belongs_to :git_push
4
+ end
data/config/routes.rb ADDED
@@ -0,0 +1,3 @@
1
+ Rails.application.routes.draw do
2
+ post "/github_integration", :to => "github#payload"
3
+ end
@@ -0,0 +1,9 @@
1
+ class CreateGitPushes < ActiveRecord::Migration
2
+ def change
3
+ create_table :git_pushes do |t|
4
+ t.text :payload
5
+
6
+ t.timestamps
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,10 @@
1
+ class CreateGitCommits < ActiveRecord::Migration
2
+ def change
3
+ create_table :git_commits do |t|
4
+ t.text :payload
5
+ t.integer :git_push_id
6
+
7
+ t.timestamps
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,5 @@
1
+ class AddUserIdToGitPush < ActiveRecord::Migration
2
+ def change
3
+ add_column :git_push, :user_id, :integer
4
+ end
5
+ end
@@ -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,3 @@
1
+ module GithubConcern
2
+ VERSION = "0.0.1"
3
+ 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,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :github_concern do
3
+ # # Task goes here
4
+ # end
@@ -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,2 @@
1
+ class Project < ActiveRecord::Base
2
+ end
@@ -0,0 +1,6 @@
1
+ class Ticket < ActiveRecord::Base
2
+
3
+ def self.github_concern_class_method repo, branch
4
+
5
+ end
6
+ end
@@ -0,0 +1,2 @@
1
+ class User < ActiveRecord::Base
2
+ end
@@ -0,0 +1 @@
1
+ require 'github_concern'
@@ -0,0 +1,3 @@
1
+ test:
2
+ adapter: sqlite3
3
+ database: db/combustion_test.sqlite
@@ -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
@@ -0,0 +1,3 @@
1
+ Rails.application.routes.draw do
2
+ #
3
+ end
@@ -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