sr-bobette 0.0.2

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.
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2009 Simon Rozet <simon@rozet.name>
2
+
3
+ Permission is hereby granted, free of charge, to any person
4
+ obtaining a copy of this software and associated documentation
5
+ files (the "Software"), to deal in the Software without
6
+ restriction, including without limitation the rights to use,
7
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ copies of the Software, and to permit persons to whom the
9
+ Software is furnished to do so, subject to the following
10
+ conditions:
11
+
12
+ The above copyright notice and this permission notice shall be
13
+ included in all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22
+ OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,11 @@
1
+ # Bobette — Bob's sister
2
+
3
+ Bobette is a Rack app that, when `POST`-ed a [GitHub-like payload][gh-payload],
4
+ builds your code using [Bob][].
5
+
6
+ You probably don't care about this, though. I am just experimenting
7
+ with some ideas for [Integrity][].
8
+
9
+ [Integrity]: http://github.com/integrity/integrity
10
+ [Bob]: http://github.com/integrity/bob
11
+ [gh-payload]: http://github.com/guides/post-receive-hooks
data/Rakefile ADDED
@@ -0,0 +1,11 @@
1
+ require "rake/testtask"
2
+
3
+ Rake::TestTask.new(:default) do |t|
4
+ t.test_files = FileList["test/*_test.rb"]
5
+ end
6
+
7
+ begin
8
+ require "mg"
9
+ MG.new("bobette.gemspec")
10
+ rescue LoadError
11
+ end
@@ -0,0 +1,25 @@
1
+ require "integrity"
2
+ require "bobette"
3
+ require "bobette/github"
4
+
5
+ class Integrity::Project
6
+ def self.new(payload)
7
+ # Auto-create!
8
+ first_or_create(:kind => payload["kind"],
9
+ :uri => payload["uri"],
10
+ :branch => payload["master"]
11
+ )
12
+ end
13
+ end
14
+
15
+ map "/github" do
16
+ use Bobette::GitHub
17
+ run Bobette.new(Integrity::Project)
18
+ end
19
+
20
+ Integrity.new(:database_uri => "sqlite3:integrity.db")
21
+ DataMapper.auto_migrate!
22
+
23
+ map "/" do
24
+ run Integrity::App
25
+ end
@@ -0,0 +1,30 @@
1
+ require "json"
2
+
3
+ module Bobette
4
+ class GitHub
5
+ def initialize(app, &block)
6
+ @app = app
7
+ @head = block || Proc.new { false }
8
+ end
9
+
10
+ def call(env)
11
+ payload = Rack::Request.new(env).POST["payload"] || ""
12
+ payload = JSON.parse(payload)
13
+ payload["kind"] = "git"
14
+ payload["uri"] = uri(payload.delete("repository")["url"]).to_s
15
+ payload["branch"] = payload.delete("ref").split("/").last
16
+ if (head = payload.delete("after")) && @head.call
17
+ payload["commits"] = [{"id" => head}]
18
+ end
19
+ env["bobette.payload"] = payload
20
+
21
+ @app.call(env)
22
+ rescue JSON::JSONError
23
+ Rack::Response.new("Unparsable payload", 400).finish
24
+ end
25
+
26
+ def uri(url)
27
+ URI(url).tap { |u| u.scheme = "git" }
28
+ end
29
+ end
30
+ end
data/lib/bobette.rb ADDED
@@ -0,0 +1,23 @@
1
+ require "bob"
2
+
3
+ module Bobette
4
+ def self.new(buildable)
5
+ App.new(buildable)
6
+ end
7
+
8
+ class App
9
+ attr_reader :buildable
10
+
11
+ def initialize(buildable)
12
+ @buildable = buildable
13
+ end
14
+
15
+ def call(env)
16
+ payload = env["bobette.payload"]
17
+ commits = payload["commits"].collect { |c| c["id"] }
18
+ @buildable.from(payload).build(commits)
19
+
20
+ Rack::Response.new("OK", 200).finish
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,58 @@
1
+ require File.dirname(__FILE__) + "/helper"
2
+
3
+ require "bobette/github"
4
+
5
+ class BobetteGitHubTest < Bobette::TestCase
6
+ def app
7
+ Rack::Builder.new {
8
+ use Bobette::GitHub do
9
+ $head
10
+ end
11
+ use Rack::Lint
12
+ run lambda { |env|
13
+ Rack::Response.new(env["bobette.payload"].to_json, 200).finish
14
+ }
15
+ }
16
+ end
17
+
18
+ def setup
19
+ $head = false
20
+ end
21
+
22
+ def github_payload(repo, commits=[], branch="master")
23
+ { "ref" => "refs/heads/#{branch}",
24
+ "after" => commits.last["id"],
25
+ "commits" => commits,
26
+ "repository" => {"url" => "http://github.com/#{repo}"} }
27
+ end
28
+
29
+ def test_transform_payload
30
+ commits = %w(b926de8 737bf26 8ba250e 78bb2de).map { |c| {"id" => c} }
31
+
32
+ post("/", :payload => github_payload("integrity/bob", commits).to_json) { |response|
33
+ assert response.ok?
34
+
35
+ assert_equal(
36
+ { "uri" => "git://github.com/integrity/bob",
37
+ "kind" => "git",
38
+ "branch" => "master",
39
+ "commits" => commits }, JSON.parse(response.body))
40
+ }
41
+ end
42
+
43
+ def test_head_commit
44
+ $head = true
45
+ commits = %w(b926de8 737bf26 8ba250e 78bb2de).map { |c| {"id" => c} }
46
+
47
+ post("/", :payload => github_payload("integrity/bob", commits).to_json) { |response|
48
+ assert response.ok?
49
+
50
+ assert_equal [commits.last], JSON.parse(response.body)["commits"]
51
+ }
52
+ end
53
+
54
+ def test_invalid_payload
55
+ assert post("/").client_error?
56
+ assert post("/", {}, "bobette.payload" => "</3").client_error?
57
+ end
58
+ end
@@ -0,0 +1,55 @@
1
+ require File.dirname(__FILE__) + "/helper"
2
+
3
+ class BobetteTest < Bobette::TestCase
4
+ def app
5
+ @app ||= Rack::Builder.new {
6
+ use Rack::Lint
7
+ run Bobette.new(TestHelper::BuildableStub)
8
+ }
9
+ end
10
+
11
+ def setup
12
+ Bob.logger = Logger.new("/dev/null")
13
+ Bob.directory = "/tmp/bobette-builds"
14
+
15
+ @repo = GitRepo.new(:my_test_project)
16
+ @repo.create
17
+ 3.times { |i|
18
+ i.odd? ? @repo.add_successful_commit : @repo.add_failing_commit
19
+ }
20
+
21
+ @metadata = {}
22
+ @builds = {}
23
+
24
+ Beacon.watch(:start) { |commit_id, commit_info|
25
+ @metadata[commit_id] = commit_info
26
+ }
27
+
28
+ Beacon.watch(:finish) { |commit_id, status, output|
29
+ @builds[commit_id] = [status ? :successful : :failed, output]
30
+ }
31
+ end
32
+
33
+ def teardown
34
+ FileUtils.rm_rf(Bob.directory)
35
+ end
36
+
37
+ def test_valid_payload
38
+ assert post("/", {}, "bobette.payload" => payload(@repo)).ok?
39
+
40
+ assert_equal 4, @metadata.count
41
+ assert_equal 4, @builds.count
42
+
43
+ commit = @repo.head
44
+
45
+ assert_equal :failed, @builds[commit].first
46
+ assert_equal "Running tests...\n", @builds[commit].last
47
+ assert_equal "This commit will fail", @metadata[commit][:message]
48
+ end
49
+
50
+ def test_invalid_payload
51
+ # TODO
52
+ assert_raise(NoMethodError) { assert post("/") }
53
+ assert_raise(NoMethodError) { post("/", {}, "bobette.payload" => "</3") }
54
+ end
55
+ end
@@ -0,0 +1,20 @@
1
+ module TestHelper
2
+ class BuildableStub < Bob::Test::BuildableStub
3
+ def self.from(payload)
4
+ kind = payload["kind"]
5
+ uri = payload["uri"]
6
+ branch = payload["branch"]
7
+ build_script = "./test"
8
+
9
+ new(kind, uri, branch, build_script)
10
+ end
11
+
12
+ def start_building(commit_id, commit_info)
13
+ Beacon.fire(:start, commit_id, commit_info)
14
+ end
15
+
16
+ def finish_building(commit_id, status, output)
17
+ Beacon.fire(:finish, commit_id, status, output)
18
+ end
19
+ end
20
+ end
data/test/helper.rb ADDED
@@ -0,0 +1,44 @@
1
+ require "test/unit"
2
+ require "rack/test"
3
+ require "beacon"
4
+ require "bob/test"
5
+
6
+ begin
7
+ require "ruby-debug"
8
+ require "redgreen"
9
+ rescue LoadError
10
+ end
11
+
12
+ $LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) + "/../lib")
13
+ $LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__))
14
+
15
+ require "bobette"
16
+
17
+ class Test::Unit::TestSuite
18
+ def empty?
19
+ false
20
+ end
21
+ end
22
+
23
+ require "helper/buildable_stub"
24
+
25
+ class Bobette::TestCase < Test::Unit::TestCase
26
+ include Rack::Test::Methods
27
+ include TestHelper
28
+ include Bob::Test
29
+
30
+ def app
31
+ @app ||= Rack::Builder.new {
32
+ use Rack::Lint
33
+ run Bobette.new(TestHelper::BuildableStub)
34
+ }
35
+ end
36
+
37
+ def payload(repo, branch="master")
38
+ { "branch" => branch,
39
+ "commits" => repo.commits.map { |c| {"id" => c[:identifier]} },
40
+ "uri" => repo.path,
41
+ "kind" => "git" }
42
+ end
43
+ end
44
+
metadata ADDED
@@ -0,0 +1,122 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sr-bobette
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - "Nicol\xC3\xA1s Sanguinetti"
8
+ - Simon Rozet
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2009-06-03 00:00:00 -07:00
14
+ default_executable:
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: bob-the-builder
18
+ type: :runtime
19
+ version_requirement:
20
+ version_requirements: !ruby/object:Gem::Requirement
21
+ requirements:
22
+ - - ">="
23
+ - !ruby/object:Gem::Version
24
+ version: "0"
25
+ version:
26
+ - !ruby/object:Gem::Dependency
27
+ name: rack
28
+ type: :runtime
29
+ version_requirement:
30
+ version_requirements: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: "0"
35
+ version:
36
+ - !ruby/object:Gem::Dependency
37
+ name: rack-test
38
+ type: :development
39
+ version_requirement:
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ requirements:
42
+ - - ">="
43
+ - !ruby/object:Gem::Version
44
+ version: "0"
45
+ version:
46
+ - !ruby/object:Gem::Dependency
47
+ name: json
48
+ type: :development
49
+ version_requirement:
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: "0"
55
+ version:
56
+ - !ruby/object:Gem::Dependency
57
+ name: beacon
58
+ type: :development
59
+ version_requirement:
60
+ version_requirements: !ruby/object:Gem::Requirement
61
+ requirements:
62
+ - - ">="
63
+ - !ruby/object:Gem::Version
64
+ version: "0"
65
+ version:
66
+ - !ruby/object:Gem::Dependency
67
+ name: sr-bob-test
68
+ type: :development
69
+ version_requirement:
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: "0"
75
+ version:
76
+ description: Bob's sister
77
+ email: info@integrityapp.com
78
+ executables: []
79
+
80
+ extensions: []
81
+
82
+ extra_rdoc_files: []
83
+
84
+ files:
85
+ - LICENSE
86
+ - README.md
87
+ - Rakefile
88
+ - examples/integrity.ru
89
+ - lib/bobette.rb
90
+ - lib/bobette/github.rb
91
+ - test/bobette_github_test.rb
92
+ - test/bobette_test.rb
93
+ - test/helper.rb
94
+ - test/helper/buildable_stub.rb
95
+ has_rdoc: false
96
+ homepage: http://integrityapp.com
97
+ post_install_message:
98
+ rdoc_options: []
99
+
100
+ require_paths:
101
+ - lib
102
+ required_ruby_version: !ruby/object:Gem::Requirement
103
+ requirements:
104
+ - - ">="
105
+ - !ruby/object:Gem::Version
106
+ version: "0"
107
+ version:
108
+ required_rubygems_version: !ruby/object:Gem::Requirement
109
+ requirements:
110
+ - - ">="
111
+ - !ruby/object:Gem::Version
112
+ version: "0"
113
+ version:
114
+ requirements: []
115
+
116
+ rubyforge_project:
117
+ rubygems_version: 1.2.0
118
+ signing_key:
119
+ specification_version: 2
120
+ summary: Bob's sister
121
+ test_files: []
122
+