integrity 0.1.9.3 → 0.1.10
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/AUTHORS +35 -0
- data/CHANGES +24 -0
- data/LICENSE +20 -0
- data/README.md +10 -52
- data/Rakefile +9 -8
- data/config/config.sample.yml +4 -0
- data/config/heroku/.gems +1 -1
- data/config/heroku/integrity-config.rb +1 -0
- data/integrity.gemspec +5 -4
- data/lib/integrity.rb +2 -0
- data/lib/integrity/app.rb +1 -1
- data/lib/integrity/helpers.rb +0 -1
- data/lib/integrity/helpers/rendering.rb +24 -0
- data/lib/integrity/helpers/urls.rb +3 -3
- data/lib/integrity/installer.rb +20 -11
- data/lib/integrity/migrations.rb +23 -2
- data/lib/integrity/notifier.rb +1 -1
- data/lib/integrity/notifier/base.rb +1 -1
- data/lib/integrity/notifier/test.rb +21 -28
- data/lib/integrity/project.rb +12 -17
- data/lib/integrity/project/notifiers.rb +20 -22
- data/lib/integrity/project/push.rb +32 -33
- data/lib/integrity/project_builder.rb +2 -2
- data/test/acceptance/build_notifications_test.rb +45 -2
- data/test/acceptance/error_page_test.rb +4 -1
- data/test/acceptance/installer_test.rb +3 -1
- data/test/acceptance/manual_build_project_test.rb +1 -1
- data/test/acceptance/not_found_page_test.rb +1 -1
- data/test/acceptance/notifier_test_test.rb +37 -0
- data/test/helpers.rb +1 -8
- data/test/helpers/acceptance.rb +5 -6
- data/test/helpers/acceptance/email_notifier.rb +0 -3
- data/test/unit/helpers_test.rb +7 -0
- data/test/unit/migrations_test.rb +7 -5
- data/test/unit/notifier_test.rb +1 -2
- data/test/unit/project_test.rb +12 -15
- data/views/project.haml +2 -3
- metadata +5 -4
- data/lib/integrity/helpers/forms.rb +0 -29
- data/test/unit/notifier/test_test.rb +0 -29
data/AUTHORS
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
Integrity is maintained by Nicolás Sanguinetti and Simon Rozet.
|
2
|
+
|
3
|
+
Thanks to the following people for their feedbacks, ideas and patches :
|
4
|
+
|
5
|
+
* Bodaniel Jeanes
|
6
|
+
* James Golick
|
7
|
+
* Wilson Bilkovich
|
8
|
+
* Mislav Marohnić
|
9
|
+
* Miles Z. Sterrett
|
10
|
+
* Kyle Hargraves
|
11
|
+
* Josh Nichols
|
12
|
+
* Jeremy Hinegardner
|
13
|
+
* Chris Wanstrath
|
14
|
+
* Will Leinweber
|
15
|
+
* Pier-Hugues Pellerin
|
16
|
+
* Justin Knowlden
|
17
|
+
* Elliott Cable
|
18
|
+
* dbr
|
19
|
+
* Scott Taylor
|
20
|
+
* Jeff Whitmire
|
21
|
+
* Diego Algorta
|
22
|
+
* Eric Mill
|
23
|
+
* Pat Nakajima
|
24
|
+
* Nick Quaranto
|
25
|
+
* Levent Ali
|
26
|
+
* Jeff Schoolcraft
|
27
|
+
* James Adam
|
28
|
+
* Harry Vangberg
|
29
|
+
* Guilherme Chapiewski
|
30
|
+
* David Dollar
|
31
|
+
* Corey Donohoe
|
32
|
+
* Christopher Redinger
|
33
|
+
* Alexander Lang
|
34
|
+
|
35
|
+
NOTE: Please let us know if your name is missing
|
data/CHANGES
CHANGED
@@ -1,3 +1,27 @@
|
|
1
|
+
0.1.10 / 2009-05-14
|
2
|
+
====================
|
3
|
+
|
4
|
+
* Bundle the NULL commit author/message fix as a migration
|
5
|
+
|
6
|
+
* Fix issue with stale notifier. See 693c95e for details
|
7
|
+
|
8
|
+
* Rename the "Build the last commit" button to "Fetch and build"
|
9
|
+
|
10
|
+
* Fix the rebuild button (Eric Mill)
|
11
|
+
|
12
|
+
* Various improvements to the Heroku install (Miles Z. Sterrett)
|
13
|
+
|
14
|
+
* Documentation to the default config.yml for the
|
15
|
+
:build_all_commits option. (Jeff Whitmire)
|
16
|
+
|
17
|
+
* `integrity launch` now saves the database into $HOME/.integrity.sqlite3
|
18
|
+
|
19
|
+
* Changed the Notifier::Test API. Notifiers tests are expected
|
20
|
+
to break. That API is still not defined and might change at
|
21
|
+
any time. See [#130] to discuss this.
|
22
|
+
|
23
|
+
* Send notifications to enabled notifiers only
|
24
|
+
|
1
25
|
0.1.9.3 / 2009-04-06
|
2
26
|
====================
|
3
27
|
|
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2008, 2009 Nicolás Sanguinetti <http://nicolassanguinetti.info>
|
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 NONINFRINGEMENT.
|
17
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
18
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
19
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
20
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
CHANGED
@@ -11,9 +11,9 @@ Integrity
|
|
11
11
|
Try it!
|
12
12
|
-------
|
13
13
|
|
14
|
-
$ git clone git://github.com/
|
14
|
+
$ git clone git://github.com/integrity/integrity.git
|
15
15
|
$ rake launch
|
16
|
-
|
16
|
+
$ open http://0.0.0.0:4567/
|
17
17
|
|
18
18
|
Run the test suite
|
19
19
|
------------------
|
@@ -24,59 +24,17 @@ Run the test suite
|
|
24
24
|
`gem build integrity.gemspec && gem install *.gem --development`.
|
25
25
|
3. Run the test suite: `rake test`
|
26
26
|
|
27
|
-
|
28
|
-
|
27
|
+
Why we don't `require "rubygems"`
|
28
|
+
---------------------------------
|
29
29
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
* [Elliott Cable][ec]
|
34
|
-
* [Corey Donohoe][atmos]
|
35
|
-
* [Kyle Hargraves][kyle]
|
36
|
-
* [Pier-Hugues Pellerin][ph]
|
37
|
-
* [Simon Rozet][sr]
|
38
|
-
* [Scott Taylor][scott]
|
39
|
-
|
40
|
-
License
|
41
|
-
-------
|
42
|
-
|
43
|
-
(The MIT License)
|
44
|
-
|
45
|
-
Copyright (c) 2008 [Nicolás Sanguinetti][foca], [entp][]
|
46
|
-
|
47
|
-
Permission is hereby granted, free of charge, to any person obtaining
|
48
|
-
a copy of this software and associated documentation files (the
|
49
|
-
'Software'), to deal in the Software without restriction, including
|
50
|
-
without limitation the rights to use, copy, modify, merge, publish,
|
51
|
-
distribute, sublicense, and/or sell copies of the Software, and to
|
52
|
-
permit persons to whom the Software is furnished to do so, subject to
|
53
|
-
the following conditions:
|
54
|
-
|
55
|
-
The above copyright notice and this permission notice shall be
|
56
|
-
included in all copies or substantial portions of the Software.
|
57
|
-
|
58
|
-
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
59
|
-
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
60
|
-
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
61
|
-
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
62
|
-
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
63
|
-
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
64
|
-
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
30
|
+
We decided to leave that choice up to the user. For more information, please
|
31
|
+
see [Why "require 'rubygems'" In Your Library/App/Tests Is Wrong][rubygems]
|
32
|
+
by [Ryan Tomayko][rtomayko].
|
65
33
|
|
66
34
|
[website]: http://integrityapp.com
|
67
35
|
[demo]: http://builder.integrityapp.com
|
68
|
-
[repo]: http://github.com/
|
36
|
+
[repo]: http://github.com/integrity/integrity
|
69
37
|
[lighthouse]: http://integrity.lighthouseapp.com/projects/14308-integrity
|
70
38
|
[irc-channel]: irc://irc.freenode.net/integrity
|
71
|
-
|
72
|
-
[
|
73
|
-
[entp]: http://entp.com
|
74
|
-
|
75
|
-
[james]: http://github.com/lazyatom
|
76
|
-
[ec]: http://github.com/elliotcabble
|
77
|
-
[atmos]: http://github.com/atmos
|
78
|
-
[kyle]: http://github.com/pd
|
79
|
-
[ph]: http://github.com/ph
|
80
|
-
[sr]: http://purl.org/net/sr/
|
81
|
-
[scott]: http://github.com/smtlaissezfaire
|
82
|
-
|
39
|
+
[rubygems]: http://gist.github.com/54177
|
40
|
+
[rtomayko]: http://tomayko.com/about
|
data/Rakefile
CHANGED
@@ -29,16 +29,10 @@ namespace :test do
|
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
|
-
begin
|
33
|
-
require "mg"
|
34
|
-
require "metric_fu"
|
35
|
-
|
36
|
-
MG.new("integrity.gemspec")
|
37
|
-
rescue LoadError
|
38
|
-
end
|
39
|
-
|
40
32
|
desc "Special task for running tests on <http://builder.integrityapp.com>"
|
41
33
|
task :ci do
|
34
|
+
require "metric_fu"
|
35
|
+
|
42
36
|
Rake::Task["test"].invoke
|
43
37
|
|
44
38
|
metrics = %w(flay flog:all reek roodi saikuro)
|
@@ -55,3 +49,10 @@ task :ci do
|
|
55
49
|
f.puts "</ul>"
|
56
50
|
}
|
57
51
|
end
|
52
|
+
|
53
|
+
begin
|
54
|
+
require "mg"
|
55
|
+
MG.new("integrity.gemspec")
|
56
|
+
rescue LoadError
|
57
|
+
end
|
58
|
+
|
data/config/config.sample.yml
CHANGED
@@ -23,6 +23,10 @@
|
|
23
23
|
# Path to the integrity log file
|
24
24
|
:log: /var/log/integrity.log
|
25
25
|
|
26
|
+
# If set to true integrity will do a build for each commit. Otherwise
|
27
|
+
# it will only do a build for each set of commits (i.e. each push)
|
28
|
+
:build_all_commits: true
|
29
|
+
|
26
30
|
# Enable or disable HTTP authentication for the app. BE AWARE that if you
|
27
31
|
# disable this anyone can delete and alter projects, so do it only if your
|
28
32
|
# app is running in a controlled environment (ie, behind your company's
|
data/config/heroku/.gems
CHANGED
@@ -1 +1 @@
|
|
1
|
-
integrity --version 0.1.9.
|
1
|
+
integrity --version 0.1.9.3
|
@@ -3,6 +3,7 @@ gem "integrity"
|
|
3
3
|
require "integrity"
|
4
4
|
|
5
5
|
Integrity.config = {
|
6
|
+
:base_uri => nil, # Edit this! Like :base_uri => 'http://awesome-subdomain-13.heroku.com'
|
6
7
|
:database_uri => ENV["DATABASE_URL"],
|
7
8
|
:export_directory => File.dirname(__FILE__) + "/tmp",
|
8
9
|
:log => File.dirname(__FILE__) + "/log/integrity.log",
|
data/integrity.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = "integrity"
|
3
|
-
s.version = "0.1.
|
3
|
+
s.version = "0.1.10"
|
4
4
|
s.date = "2009-04-06"
|
5
5
|
|
6
6
|
s.description = "Your Friendly Continuous Integration server. Easy, fun and painless!"
|
@@ -18,7 +18,7 @@ Gem::Specification.new do |s|
|
|
18
18
|
s.has_rdoc = false
|
19
19
|
s.rubygems_version = "1.3.1"
|
20
20
|
|
21
|
-
s.add_dependency "sinatra", ["
|
21
|
+
s.add_dependency "sinatra", ["= 0.9.1.1"]
|
22
22
|
s.add_dependency "sinatra-authorization"
|
23
23
|
s.add_dependency "haml", [">= 2.0.0"]
|
24
24
|
s.add_dependency "data_mapper", ["= 0.9.11"]
|
@@ -42,7 +42,9 @@ Gem::Specification.new do |s|
|
|
42
42
|
|
43
43
|
s.files = %w[
|
44
44
|
.gitignore
|
45
|
+
AUTHORS
|
45
46
|
CHANGES
|
47
|
+
LICENSE
|
46
48
|
README.md
|
47
49
|
Rakefile
|
48
50
|
bin/integrity
|
@@ -63,7 +65,6 @@ lib/integrity/core_ext/object.rb
|
|
63
65
|
lib/integrity/helpers.rb
|
64
66
|
lib/integrity/helpers/authorization.rb
|
65
67
|
lib/integrity/helpers/breadcrumbs.rb
|
66
|
-
lib/integrity/helpers/forms.rb
|
67
68
|
lib/integrity/helpers/pretty_output.rb
|
68
69
|
lib/integrity/helpers/rendering.rb
|
69
70
|
lib/integrity/helpers/resources.rb
|
@@ -96,6 +97,7 @@ test/acceptance/error_page_test.rb
|
|
96
97
|
test/acceptance/installer_test.rb
|
97
98
|
test/acceptance/manual_build_project_test.rb
|
98
99
|
test/acceptance/not_found_page_test.rb
|
100
|
+
test/acceptance/notifier_test_test.rb
|
99
101
|
test/acceptance/project_syndication_test.rb
|
100
102
|
test/acceptance/stylesheet_test.rb
|
101
103
|
test/acceptance/unauthorized_page_test.rb
|
@@ -117,7 +119,6 @@ test/unit/helpers_test.rb
|
|
117
119
|
test/unit/integrity_test.rb
|
118
120
|
test/unit/migrations_test.rb
|
119
121
|
test/unit/notifier/base_test.rb
|
120
|
-
test/unit/notifier/test_test.rb
|
121
122
|
test/unit/notifier_test.rb
|
122
123
|
test/unit/project_builder_test.rb
|
123
124
|
test/unit/project_test.rb
|
data/lib/integrity.rb
CHANGED
data/lib/integrity/app.rb
CHANGED
data/lib/integrity/helpers.rb
CHANGED
@@ -20,6 +20,30 @@ module Integrity
|
|
20
20
|
def partial(template, locals={})
|
21
21
|
haml("_#{template}".to_sym, :locals => locals, :layout => false)
|
22
22
|
end
|
23
|
+
|
24
|
+
def errors_on(object, field)
|
25
|
+
return "" unless errors = object.errors.on(field)
|
26
|
+
errors.map {|e| e.gsub(/#{field} /i, "") }.join(", ")
|
27
|
+
end
|
28
|
+
|
29
|
+
def error_class(object, field)
|
30
|
+
object.errors.on(field).nil? ? "" : "with_errors"
|
31
|
+
end
|
32
|
+
|
33
|
+
def checkbox(name, condition, extras={})
|
34
|
+
attrs = { :name => name, :type => "checkbox", :value => "1" }
|
35
|
+
attrs[:checked] = !!condition
|
36
|
+
attrs.update(extras)
|
37
|
+
end
|
38
|
+
|
39
|
+
def notifier_form
|
40
|
+
Notifier.available.each_pair { |name, klass|
|
41
|
+
haml_concat haml(klass.to_haml, :layout => :notifier, :locals => {
|
42
|
+
:notifier => name,
|
43
|
+
:enabled => current_project.notifies?(name),
|
44
|
+
:config => current_project.config_for(name) })
|
45
|
+
}
|
46
|
+
end
|
23
47
|
end
|
24
48
|
end
|
25
49
|
end
|
@@ -17,12 +17,12 @@ module Integrity
|
|
17
17
|
project_url(project, path).path
|
18
18
|
end
|
19
19
|
|
20
|
-
def commit_url(commit)
|
21
|
-
project_url(commit.project, "commits", commit.identifier)
|
20
|
+
def commit_url(commit, *path)
|
21
|
+
project_url(commit.project, ["commits", commit.identifier, *path].flatten)
|
22
22
|
end
|
23
23
|
|
24
24
|
def commit_path(commit, *path)
|
25
|
-
commit_url(commit).path
|
25
|
+
commit_url(commit, *path).path
|
26
26
|
end
|
27
27
|
|
28
28
|
def build_path(build, *path)
|
data/lib/integrity/installer.rb
CHANGED
@@ -5,6 +5,11 @@ module Integrity
|
|
5
5
|
class Installer < Thor
|
6
6
|
include FileUtils
|
7
7
|
|
8
|
+
def self.database_path
|
9
|
+
File.join(ENV["HOME"], ".integrity.sqlite3")
|
10
|
+
end
|
11
|
+
private_class_method :database_path
|
12
|
+
|
8
13
|
desc "install [PATH]",
|
9
14
|
"Copy template files to PATH for desired deployement strategy
|
10
15
|
(either Thin, Passenger or Heroku). Next, go there and edit them."
|
@@ -36,22 +41,25 @@ module Integrity
|
|
36
41
|
end
|
37
42
|
|
38
43
|
desc "launch [CONFIG]",
|
39
|
-
"Launch Integrity real quick."
|
40
|
-
method_options :config => :optional, :port =>
|
44
|
+
"Launch Integrity real quick. Database is saved in #{database_path}."
|
45
|
+
method_options :config => :optional, :port => :optional
|
41
46
|
def launch
|
42
47
|
require "thin"
|
43
48
|
require "do_sqlite3"
|
44
49
|
|
45
|
-
|
46
|
-
|
47
|
-
|
50
|
+
port = options[:port] || 4567
|
51
|
+
|
52
|
+
config = { :database_uri => "sqlite3://#{ENV["HOME"]}/.integrity.db",
|
53
|
+
:base_uri => "http://0.0.0.0:#{options[:port]}",
|
54
|
+
:export_directory => "/tmp/integrity-exports" }
|
55
|
+
config.merge!(YAML.load_file(options[:config])) if options[:config]
|
48
56
|
|
49
|
-
|
57
|
+
migrate_db(config)
|
50
58
|
|
51
|
-
Thin::Server.start("0.0.0.0",
|
59
|
+
Thin::Server.start("0.0.0.0", port, Integrity::App)
|
52
60
|
rescue LoadError => boom
|
53
|
-
|
54
|
-
|
61
|
+
$stderr << "Make sure thin and do_sqlite3 are insatalled\n\n"
|
62
|
+
raise
|
55
63
|
end
|
56
64
|
|
57
65
|
private
|
@@ -100,8 +108,9 @@ Your Integrity install is ready to be deployed onto Heroku. Next steps:
|
|
100
108
|
|
101
109
|
1. git init && git add . && git commit -am "Initial import"
|
102
110
|
2. heroku create
|
103
|
-
3.
|
104
|
-
4. heroku
|
111
|
+
3. Add heroku-given domain as :base_uri in integrity-config.rb
|
112
|
+
4. git push heroku master
|
113
|
+
5. heroku rake db:migrate
|
105
114
|
EOF
|
106
115
|
end
|
107
116
|
|
data/lib/integrity/migrations.rb
CHANGED
@@ -84,8 +84,8 @@ module Integrity
|
|
84
84
|
create_table :integrity_commits do
|
85
85
|
column :id, Integer, :serial => true
|
86
86
|
column :identifier, String, :nullable => false
|
87
|
-
column :message, String, :nullable =>
|
88
|
-
column :author, String, :nullable =>
|
87
|
+
column :message, String, :nullable => false, :length => 255
|
88
|
+
column :author, String, :nullable => false, :length => 255
|
89
89
|
column :committed_at, DateTime, :nullable => false
|
90
90
|
column :created_at, DateTime
|
91
91
|
column :updated_at, DateTime
|
@@ -147,5 +147,26 @@ module Integrity
|
|
147
147
|
# modify_table(:integrity_notifiers) { drop_column :enabled }
|
148
148
|
end
|
149
149
|
end
|
150
|
+
|
151
|
+
migration 4, :nil_commit_metadata do
|
152
|
+
up do
|
153
|
+
all_commits = Commit.all.collect { |c| c.dup }
|
154
|
+
drop_table :integrity_commits
|
155
|
+
|
156
|
+
create_table :integrity_commits do
|
157
|
+
column :id, Integer, :serial => true
|
158
|
+
column :identifier, String, :nullable => false
|
159
|
+
column :message, String, :nullable => true, :length => 255
|
160
|
+
column :author, String, :nullable => true, :length => 255
|
161
|
+
column :committed_at, DateTime, :nullable => false
|
162
|
+
column :created_at, DateTime
|
163
|
+
column :updated_at, DateTime
|
164
|
+
|
165
|
+
column :project_id, Integer
|
166
|
+
end
|
167
|
+
|
168
|
+
all_commits.each { |commit| Commit.create(commit.attributes) }
|
169
|
+
end
|
170
|
+
end
|
150
171
|
end
|
151
172
|
end
|
data/lib/integrity/notifier.rb
CHANGED
@@ -2,7 +2,7 @@ module Integrity
|
|
2
2
|
class Notifier
|
3
3
|
class Base
|
4
4
|
def self.notify_of_build(build, config)
|
5
|
-
Integrity.log "Notifying of build #{build.commit.short_identifier} using the #{
|
5
|
+
Integrity.log "Notifying of build #{build.commit.short_identifier} using the #{to_s} notifier"
|
6
6
|
Timeout.timeout(8) { new(build.commit, config).deliver! }
|
7
7
|
rescue Timeout::Error
|
8
8
|
Integrity.log "#{notifier.name} notifier timed out"
|
@@ -11,49 +11,42 @@ module Integrity
|
|
11
11
|
DataMapper.auto_migrate!
|
12
12
|
end
|
13
13
|
|
14
|
-
def
|
15
|
-
Integrity::
|
16
|
-
end
|
17
|
-
|
18
|
-
def notification(commit)
|
19
|
-
notifier_class.new(commit).full_message
|
20
|
-
end
|
21
|
-
|
22
|
-
def notification_successful
|
23
|
-
notification(Integrity::Commit.gen(:successful))
|
14
|
+
def build(state=:successful)
|
15
|
+
Integrity::Build.gen(state)
|
24
16
|
end
|
25
17
|
|
26
|
-
def
|
27
|
-
|
18
|
+
def notifier_class
|
19
|
+
Integrity::Notifier.const_get(notifier)
|
28
20
|
end
|
29
21
|
|
30
|
-
def
|
22
|
+
def provides_option?(option, value=nil)
|
31
23
|
selector = "input##{notifier.downcase}_notifier_#{option}"
|
32
24
|
selector << "[@name='notifiers[#{notifier}][#{option}]']"
|
33
25
|
selector << "[@value='#{value}']" if value
|
34
26
|
|
35
|
-
|
27
|
+
form_have_tag?(selector, option => value)
|
36
28
|
end
|
37
29
|
|
38
|
-
def
|
30
|
+
def provides_options(*options)
|
39
31
|
options.each { |option| assert_form_have_option(option) }
|
40
32
|
end
|
41
33
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
34
|
+
private
|
35
|
+
def form(config={})
|
36
|
+
Haml::Engine.new(notifier_class.to_haml).
|
37
|
+
render(OpenStruct.new(:config => config))
|
38
|
+
end
|
46
39
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
end
|
40
|
+
def form_have_tag?(selector, options={})
|
41
|
+
content = options.delete(:content)
|
42
|
+
have_tag?(form(options), selector, content)
|
43
|
+
end
|
52
44
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
45
|
+
def have_tag?(html, selector, content=nil)
|
46
|
+
matcher = HpricotMatcher.new(html)
|
47
|
+
assert_equal content, matcher.tag(selector) if content
|
48
|
+
matcher.tag(selector)
|
49
|
+
end
|
57
50
|
end
|
58
51
|
end
|
59
52
|
end
|
data/lib/integrity/project.rb
CHANGED
@@ -4,9 +4,7 @@ require "integrity/project/push"
|
|
4
4
|
module Integrity
|
5
5
|
class Project
|
6
6
|
include DataMapper::Resource
|
7
|
-
|
8
|
-
include Helpers::Notifiers
|
9
|
-
include Helpers::Push
|
7
|
+
include Notifiers, Push
|
10
8
|
|
11
9
|
property :id, Integer, :serial => true
|
12
10
|
property :name, String, :nullable => false
|
@@ -19,6 +17,8 @@ module Integrity
|
|
19
17
|
property :created_at, DateTime
|
20
18
|
property :updated_at, DateTime
|
21
19
|
|
20
|
+
default_scope(:default).update(:order => [:name.asc])
|
21
|
+
|
22
22
|
has n, :commits, :class_name => "Integrity::Commit"
|
23
23
|
has n, :notifiers, :class_name => "Integrity::Notifier"
|
24
24
|
|
@@ -27,17 +27,10 @@ module Integrity
|
|
27
27
|
|
28
28
|
validates_is_unique :name
|
29
29
|
|
30
|
-
def self.only_public_unless(condition)
|
31
|
-
if condition
|
32
|
-
all
|
33
|
-
else
|
34
|
-
all(:public => true)
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
30
|
def build(commit_identifier="HEAD")
|
39
31
|
commit_identifier = head_of_remote_repo if commit_identifier == "HEAD"
|
40
32
|
commit = find_or_create_commit_with_identifier(commit_identifier)
|
33
|
+
|
41
34
|
Build.queue(commit)
|
42
35
|
end
|
43
36
|
|
@@ -46,7 +39,8 @@ module Integrity
|
|
46
39
|
end
|
47
40
|
|
48
41
|
def previous_commits
|
49
|
-
commits.all(:project_id => id, :order => [:committed_at.desc]).
|
42
|
+
commits.all(:project_id => id, :order => [:committed_at.desc]).
|
43
|
+
tap {|commits| commits.shift }
|
50
44
|
end
|
51
45
|
|
52
46
|
def status
|
@@ -65,7 +59,7 @@ module Integrity
|
|
65
59
|
end
|
66
60
|
|
67
61
|
private
|
68
|
-
def find_or_create_commit_with_identifier(
|
62
|
+
def find_or_create_commit_with_identifier(identifier)
|
69
63
|
# We abuse +committed_at+ here setting it to Time.now because we use it
|
70
64
|
# to sort (for last_commit and previous_commits). I don't like this
|
71
65
|
# very much, but for now it's the only solution I can find.
|
@@ -75,7 +69,8 @@ module Integrity
|
|
75
69
|
#
|
76
70
|
# This might also make your commit listings a little jumpy, if some
|
77
71
|
# commits change place every time a build finishes =\
|
78
|
-
commits.first_or_create({
|
72
|
+
commits.first_or_create({:identifier => identifier, :project_id => id},
|
73
|
+
:committed_at => Time.now)
|
79
74
|
end
|
80
75
|
|
81
76
|
def head_of_remote_repo
|
@@ -83,15 +78,15 @@ module Integrity
|
|
83
78
|
end
|
84
79
|
|
85
80
|
def set_permalink
|
86
|
-
|
81
|
+
attribute_set(:permalink, (name || "").downcase.
|
87
82
|
gsub(/'s/, "s").
|
88
83
|
gsub(/&/, "and").
|
89
84
|
gsub(/[^a-z0-9]+/, "-").
|
90
|
-
gsub(/-*$/, "")
|
85
|
+
gsub(/-*$/, ""))
|
91
86
|
end
|
92
87
|
|
93
88
|
def delete_working_directory
|
94
|
-
commits.
|
89
|
+
commits.destroy!
|
95
90
|
ProjectBuilder.delete_working_directory(self)
|
96
91
|
rescue SCM::SCMUnknownError => error
|
97
92
|
Integrity.log "Problem while trying to deleting code: #{error}"
|
@@ -1,32 +1,30 @@
|
|
1
1
|
module Integrity
|
2
2
|
class Project
|
3
|
-
module
|
4
|
-
|
5
|
-
|
6
|
-
return false unless notifier = notifiers.first(:name => notifier)
|
3
|
+
module Notifiers
|
4
|
+
def notifies?(notifier)
|
5
|
+
return false unless notifier = notifiers.first(:name => notifier)
|
7
6
|
|
8
|
-
|
9
|
-
|
7
|
+
notifier.enabled?
|
8
|
+
end
|
10
9
|
|
11
|
-
|
12
|
-
|
13
|
-
|
10
|
+
def enabled_notifiers
|
11
|
+
notifiers.all(:enabled => true)
|
12
|
+
end
|
14
13
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
14
|
+
def config_for(notifier)
|
15
|
+
notifier = notifiers.first(:name => notifier)
|
16
|
+
notifier ? notifier.config : {}
|
17
|
+
end
|
19
18
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
19
|
+
def update_notifiers(to_enable, config)
|
20
|
+
config.each_pair { |name, config|
|
21
|
+
notifier = notifiers.first(:name => name)
|
22
|
+
notifier ||= notifiers.new(:name => name)
|
24
23
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
end
|
24
|
+
notifier.enabled = to_enable.include?(name)
|
25
|
+
notifier.config = config
|
26
|
+
notifier.save
|
27
|
+
}
|
30
28
|
end
|
31
29
|
end
|
32
30
|
end
|
@@ -1,44 +1,43 @@
|
|
1
1
|
module Integrity
|
2
2
|
class Project
|
3
|
-
module
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
raise ArgumentError unless valid_payload?(payload)
|
3
|
+
module Push
|
4
|
+
def push(payload)
|
5
|
+
payload = parse_payload(payload)
|
6
|
+
raise ArgumentError unless valid_payload?(payload)
|
8
7
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
end
|
15
|
-
|
16
|
-
commits.each do |commit_data|
|
17
|
-
create_commit_from(commit_data)
|
18
|
-
build(commit_data["id"])
|
8
|
+
commits =
|
9
|
+
if Integrity.config[:build_all_commits]
|
10
|
+
payload["commits"]
|
11
|
+
else
|
12
|
+
[ payload["commits"].first ]
|
19
13
|
end
|
20
|
-
end
|
21
14
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
end
|
15
|
+
commits.each { |commit_data|
|
16
|
+
commit = commit_from(commit_data)
|
17
|
+
commit.create
|
18
|
+
build(commit.identifier)
|
19
|
+
}
|
20
|
+
end
|
29
21
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
22
|
+
private
|
23
|
+
def commit_from(data)
|
24
|
+
commits.new(:identifier => data["id"],
|
25
|
+
:author => "#{data["author"]["name"]} <#{data["author"]["email"]}>",
|
26
|
+
:message => data["message"],
|
27
|
+
:committed_at => data["timestamp"])
|
28
|
+
end
|
35
29
|
|
36
|
-
|
37
|
-
|
38
|
-
|
30
|
+
def valid_payload?(payload)
|
31
|
+
payload && payload["ref"].to_s.include?(branch) &&
|
32
|
+
!payload["commits"].nil? &&
|
33
|
+
!payload["commits"].to_a.empty?
|
34
|
+
end
|
35
|
+
|
36
|
+
def parse_payload(payload)
|
37
|
+
JSON.parse(payload.to_s)
|
38
|
+
rescue JSON::ParserError
|
39
39
|
false
|
40
|
-
|
41
|
-
end
|
40
|
+
end
|
42
41
|
end
|
43
42
|
end
|
44
43
|
end
|
@@ -17,7 +17,7 @@ module Integrity
|
|
17
17
|
|
18
18
|
def initialize(project)
|
19
19
|
@project = project
|
20
|
-
@scm
|
20
|
+
@scm = SCM.new(uri, branch, export_directory)
|
21
21
|
end
|
22
22
|
|
23
23
|
def build(commit)
|
@@ -39,7 +39,7 @@ module Integrity
|
|
39
39
|
ensure
|
40
40
|
build.complete!
|
41
41
|
commit.update_attributes(scm.info(commit.identifier) || {})
|
42
|
-
project.
|
42
|
+
project.enabled_notifiers.each { |notifier| notifier.notify_of_build(build) }
|
43
43
|
end
|
44
44
|
|
45
45
|
def delete_code
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require File.dirname(__FILE__) + "/../helpers/acceptance"
|
2
2
|
require "helpers/acceptance/notifier_helper"
|
3
|
+
require "helpers/acceptance/email_notifier"
|
3
4
|
|
4
5
|
class BuildNotificationsTest < Test::Unit::AcceptanceTestCase
|
5
6
|
include NotifierHelper
|
@@ -12,9 +13,11 @@ class BuildNotificationsTest < Test::Unit::AcceptanceTestCase
|
|
12
13
|
|
13
14
|
before(:each) do
|
14
15
|
# This is needed before any available notifier is unset
|
15
|
-
# in the global #before
|
16
|
+
# in the global #before.
|
17
|
+
# But, we need the reload this one because we remove_const
|
18
|
+
# it in a test case. Sigh.
|
16
19
|
load "helpers/acceptance/textfile_notifier.rb"
|
17
|
-
|
20
|
+
|
18
21
|
Notifier.register(Integrity::Notifier::Textfile)
|
19
22
|
Notifier.register(Integrity::Notifier::Email)
|
20
23
|
end
|
@@ -46,6 +49,25 @@ class BuildNotificationsTest < Test::Unit::AcceptanceTestCase
|
|
46
49
|
notification.should =~ /Build Output:\n\nRunning tests...\n/
|
47
50
|
end
|
48
51
|
|
52
|
+
scenario "an admin sets up the Textfile notifier but do not enable it" do
|
53
|
+
git_repo(:my_test_project).add_successful_commit
|
54
|
+
Project.gen(:my_test_project, :uri => git_repo(:my_test_project).path)
|
55
|
+
rm_f "/tmp/textfile_notifications.txt"
|
56
|
+
|
57
|
+
login_as "admin", "test"
|
58
|
+
|
59
|
+
visit "/my-test-project"
|
60
|
+
|
61
|
+
click_link "Edit Project"
|
62
|
+
uncheck "enabled_notifiers_textfile"
|
63
|
+
fill_in "File", :with => "/tmp/textfile_notifications.txt"
|
64
|
+
click_button "Update Project"
|
65
|
+
|
66
|
+
click_button "manual build"
|
67
|
+
|
68
|
+
assert ! File.file?("/tmp/textfile_notifications.txt")
|
69
|
+
end
|
70
|
+
|
49
71
|
scenario "an admin can setup a notifier without enabling it" do
|
50
72
|
Project.gen(:integrity)
|
51
73
|
|
@@ -60,6 +82,27 @@ class BuildNotificationsTest < Test::Unit::AcceptanceTestCase
|
|
60
82
|
assert_have_email_notifier
|
61
83
|
end
|
62
84
|
|
85
|
+
scenario "an admin enables the Textfile notifier and get rid of it later" do
|
86
|
+
git_repo(:my_test_project).add_successful_commit
|
87
|
+
Project.gen(:my_test_project, :uri => git_repo(:my_test_project).path)
|
88
|
+
|
89
|
+
login_as "admin", "test"
|
90
|
+
visit "/my-test-project"
|
91
|
+
|
92
|
+
click_link "Edit Project"
|
93
|
+
check "enabled_notifiers_textfile"
|
94
|
+
fill_in "File", :with => "/tmp/textfile_notifications.txt"
|
95
|
+
click_button "Update Project"
|
96
|
+
|
97
|
+
Notifier.send(:remove_const, :Textfile)
|
98
|
+
Notifier.available.clear
|
99
|
+
rm_f "/tmp/textfile_notifications.txt"
|
100
|
+
|
101
|
+
click_button "manual build"
|
102
|
+
|
103
|
+
assert ! File.file?("/tmp/textfile_notifications.txt")
|
104
|
+
end
|
105
|
+
|
63
106
|
scenario "an admin configures various notifiers accros multiple projects" do
|
64
107
|
Project.first(:permalink => "integrity").should be_nil
|
65
108
|
|
@@ -7,8 +7,11 @@ class ErrorPageTest < Test::Unit::AcceptanceTestCase
|
|
7
7
|
So that I can understand what's going on
|
8
8
|
EOS
|
9
9
|
|
10
|
+
before { app.disable :raise_errors }
|
11
|
+
after { app.enable :raise_errors }
|
12
|
+
|
10
13
|
scenario "an error happen while I am browsing my Integrity install" do
|
11
|
-
stub(Project).
|
14
|
+
stub(Project).all { raise ArgumentError }
|
12
15
|
lambda { visit "/" }.should raise_error(Webrat::PageLoadError)
|
13
16
|
|
14
17
|
response_code.should == 500
|
@@ -53,6 +53,8 @@ class InstallerTest < Test::Unit::AcceptanceTestCase
|
|
53
53
|
|
54
54
|
assert root.join("public").directory?
|
55
55
|
assert root.join("tmp").directory?
|
56
|
+
|
57
|
+
assert ! root.join("thin.yml").file?
|
56
58
|
end
|
57
59
|
|
58
60
|
scenario "Installing Integrity for Thin" do
|
@@ -68,7 +70,7 @@ class InstallerTest < Test::Unit::AcceptanceTestCase
|
|
68
70
|
scenario "Installing Integrity for Heroku" do
|
69
71
|
message = install("--heroku")
|
70
72
|
|
71
|
-
assert_equal "integrity --version 0.1.9.
|
73
|
+
assert_equal "integrity --version 0.1.9.3", root.join(".gems").read.chomp
|
72
74
|
|
73
75
|
assert root.join("Rakefile").file?
|
74
76
|
assert root.join("integrity-config.rb").file?
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require File.dirname(__FILE__) + "/../helpers/acceptance"
|
2
|
+
require "helpers/acceptance/email_notifier"
|
3
|
+
require "helpers/acceptance/textfile_notifier"
|
4
|
+
|
5
|
+
require "integrity/notifier/test"
|
6
|
+
|
7
|
+
class NotifierTestTest < Test::Unit::TestCase
|
8
|
+
include Integrity::Notifier::Test
|
9
|
+
|
10
|
+
setup do
|
11
|
+
@notifier = Integrity::Notifier::Textfile
|
12
|
+
@config = {"file" => "/tmp/integrity.txt"}
|
13
|
+
|
14
|
+
FileUtils.rm @config["file"] if File.exists?(@config["file"])
|
15
|
+
end
|
16
|
+
|
17
|
+
def notifier
|
18
|
+
"Textfile"
|
19
|
+
end
|
20
|
+
|
21
|
+
test "it provides a formulary to configure options" do
|
22
|
+
assert provides_option?("file")
|
23
|
+
assert provides_option?("file", @config["file"])
|
24
|
+
end
|
25
|
+
|
26
|
+
test "it sends notification" do
|
27
|
+
build = build(:successful)
|
28
|
+
|
29
|
+
@notifier.notify_of_build(build, @config)
|
30
|
+
|
31
|
+
notification = File.read(@config["file"])
|
32
|
+
|
33
|
+
assert notification.start_with?("===")
|
34
|
+
assert notification.include?(build.commit.identifier)
|
35
|
+
assert notification.include?("successful")
|
36
|
+
end
|
37
|
+
end
|
data/test/helpers.rb
CHANGED
@@ -63,15 +63,8 @@ class Test::Unit::TestCase
|
|
63
63
|
end
|
64
64
|
|
65
65
|
before(:each) do
|
66
|
-
[Project, Build, Commit, Notifier].each
|
66
|
+
[Project, Build, Commit, Notifier].each{ |i| i.auto_migrate_down! }
|
67
67
|
capture_stdout { Integrity.migrate_db }
|
68
|
-
|
69
|
-
RR.reset
|
70
|
-
|
71
|
-
Notifier.available.each { |n|
|
72
|
-
Notifier.send(:remove_const, n.to_s.split(":").last.to_sym)
|
73
|
-
}
|
74
|
-
|
75
68
|
Notifier.available.clear
|
76
69
|
Integrity.instance_variable_set(:@config, nil)
|
77
70
|
end
|
data/test/helpers/acceptance.rb
CHANGED
@@ -56,14 +56,14 @@ class Test::Unit::AcceptanceTestCase < Test::Unit::TestCase
|
|
56
56
|
include Webrat::Matchers
|
57
57
|
include Webrat::HaveTagMatcher
|
58
58
|
|
59
|
-
# TODO: does this belongs in Webrat::SinatraSession?
|
60
59
|
Webrat::Methods.delegate_to_session :response_code
|
61
60
|
|
62
61
|
def app
|
63
|
-
Integrity::App
|
64
|
-
|
65
|
-
|
66
|
-
|
62
|
+
Integrity::App
|
63
|
+
end
|
64
|
+
|
65
|
+
before(:all) do
|
66
|
+
app.set(:environment, :test)
|
67
67
|
end
|
68
68
|
|
69
69
|
before(:each) do
|
@@ -79,5 +79,4 @@ class Test::Unit::AcceptanceTestCase < Test::Unit::TestCase
|
|
79
79
|
destroy_all_git_repos
|
80
80
|
rm_r export_directory if File.directory?(export_directory)
|
81
81
|
end
|
82
|
-
|
83
82
|
end
|
data/test/unit/helpers_test.rb
CHANGED
@@ -61,6 +61,13 @@ class BrowsePublicProjectsTest < Test::Unit::TestCase
|
|
61
61
|
}
|
62
62
|
end
|
63
63
|
|
64
|
+
test "build commit" do
|
65
|
+
assert_equal "/ci/foo-bar/commits/#{@commit.identifier}/builds",
|
66
|
+
@h.commit_path(@build.commit, :builds)
|
67
|
+
assert_equal "http://example.org/ci/foo-bar/commits/#{@commit.identifier}/builds",
|
68
|
+
@h.commit_url(@build.commit, :builds).to_s
|
69
|
+
end
|
70
|
+
|
64
71
|
test "compat" do
|
65
72
|
silence_warnings {
|
66
73
|
assert_equal @h.build_path(@build), @h.commit_path(@build.commit)
|
@@ -23,7 +23,7 @@ class MigrationsTest < Test::Unit::TestCase
|
|
23
23
|
end
|
24
24
|
|
25
25
|
before(:each) do
|
26
|
-
[Project, Build, Commit, Notifier].each
|
26
|
+
[Project, Build, Commit, Notifier].each{ |i| i.auto_migrate_down! }
|
27
27
|
database_adapter.execute("DROP TABLE migration_info")
|
28
28
|
assert !table_exists?("migration_info") # just to be sure
|
29
29
|
end
|
@@ -31,18 +31,20 @@ class MigrationsTest < Test::Unit::TestCase
|
|
31
31
|
test "upgrading a pre migration database" do
|
32
32
|
capture_stdout { Integrity.migrate_db }
|
33
33
|
|
34
|
-
current_migrations.should == ["initial", "add_commits",
|
34
|
+
current_migrations.should == ["initial", "add_commits",
|
35
|
+
"add_enabled_column", "nil_commit_metadata"]
|
35
36
|
assert table_exists?("integrity_projects")
|
36
37
|
assert table_exists?("integrity_builds")
|
37
38
|
assert table_exists?("integrity_notifiers")
|
38
39
|
assert table_exists?("integrity_commits")
|
39
40
|
end
|
40
41
|
|
41
|
-
test "migrating data from initial to
|
42
|
+
test "migrating data up from initial to the last migration" do
|
42
43
|
load_initial_migration_fixture
|
43
|
-
|
44
44
|
capture_stdout { Integrity.migrate_db }
|
45
|
-
|
45
|
+
|
46
|
+
current_migrations.should == ["initial", "add_commits",
|
47
|
+
"add_enabled_column", "nil_commit_metadata"]
|
46
48
|
|
47
49
|
sinatra = Project.first(:name => "Sinatra")
|
48
50
|
sinatra.should have(1).commits
|
data/test/unit/notifier_test.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require File.dirname(__FILE__) + "/../helpers"
|
2
|
+
require "helpers/acceptance/textfile_notifier"
|
2
3
|
|
3
4
|
class NotifierTest < Test::Unit::TestCase
|
4
5
|
specify "IRC fixture is valid and can be saved" do
|
@@ -68,8 +69,6 @@ class NotifierTest < Test::Unit::TestCase
|
|
68
69
|
|
69
70
|
describe "Registering a notifier" do
|
70
71
|
it "registers given notifier class" do
|
71
|
-
load "helpers/acceptance/textfile_notifier.rb"
|
72
|
-
|
73
72
|
Notifier.register(Integrity::Notifier::Textfile)
|
74
73
|
|
75
74
|
assert_equal Integrity::Notifier::Textfile,
|
data/test/unit/project_test.rb
CHANGED
@@ -145,22 +145,17 @@ class ProjectTest < Test::Unit::TestCase
|
|
145
145
|
end
|
146
146
|
end
|
147
147
|
|
148
|
-
describe "Finding
|
148
|
+
describe "Finding any project" do
|
149
149
|
before(:each) do
|
150
|
-
@
|
151
|
-
@
|
150
|
+
@rails = Project.gen(:name => "rails", :public => true)
|
151
|
+
@merb = Project.gen(:name => "merb", :public => true)
|
152
|
+
@sinatra = Project.gen(:name => "sinatra", :public => true)
|
153
|
+
@camping = Project.gen(:name => "camping", :public => false)
|
152
154
|
end
|
153
155
|
|
154
|
-
it "
|
155
|
-
|
156
|
-
|
157
|
-
projects.should include(@public_project)
|
158
|
-
end
|
159
|
-
|
160
|
-
it "finds both private and public projects if the condition passed is true" do
|
161
|
-
projects = Project.only_public_unless(true)
|
162
|
-
projects.should include(@private_project)
|
163
|
-
projects.should include(@public_project)
|
156
|
+
it "should always be ordered by name" do
|
157
|
+
Project.all.should == [@camping, @merb, @rails, @sinatra]
|
158
|
+
Project.all(:public => true).should == [@merb, @rails, @sinatra]
|
164
159
|
end
|
165
160
|
end
|
166
161
|
|
@@ -231,8 +226,10 @@ class ProjectTest < Test::Unit::TestCase
|
|
231
226
|
|
232
227
|
assert_equal 2, Notifier.count
|
233
228
|
assert_equal 2, project.enabled_notifiers.count
|
234
|
-
|
235
|
-
|
229
|
+
|
230
|
+
notifier_names = project.notifiers.map { |n| n.name }
|
231
|
+
assert notifier_names.include?("IRC")
|
232
|
+
assert notifier_names.include?("Twitter")
|
236
233
|
|
237
234
|
project.update_notifiers(["Twitter"],
|
238
235
|
{"IRC" => {"uri" => "irc://irc.freenode.net/integrity"},
|
data/views/project.haml
CHANGED
@@ -14,9 +14,8 @@
|
|
14
14
|
|
15
15
|
%form{ :action => project_path(@project, :builds), :method => :post }
|
16
16
|
%p.submit.manual-build
|
17
|
-
%button{ :type => :submit, :title => "Fetch the last commit and build it" }<
|
18
|
-
|
19
|
-
in the repository (or rebuild the latest)
|
17
|
+
%button{ :type => :submit, :title => "Fetch the last commit from the remote repository and build it" }<
|
18
|
+
Fetch and build
|
20
19
|
|
21
20
|
- unless @project.previous_commits.empty?
|
22
21
|
%h2 Previous builds
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: integrity
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.10
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- "Nicol\xC3\xA1s Sanguinetti"
|
@@ -19,7 +19,7 @@ dependencies:
|
|
19
19
|
version_requirement:
|
20
20
|
version_requirements: !ruby/object:Gem::Requirement
|
21
21
|
requirements:
|
22
|
-
- - "
|
22
|
+
- - "="
|
23
23
|
- !ruby/object:Gem::Version
|
24
24
|
version: 0.9.1.1
|
25
25
|
version:
|
@@ -203,7 +203,9 @@ extra_rdoc_files: []
|
|
203
203
|
|
204
204
|
files:
|
205
205
|
- .gitignore
|
206
|
+
- AUTHORS
|
206
207
|
- CHANGES
|
208
|
+
- LICENSE
|
207
209
|
- README.md
|
208
210
|
- Rakefile
|
209
211
|
- bin/integrity
|
@@ -224,7 +226,6 @@ files:
|
|
224
226
|
- lib/integrity/helpers.rb
|
225
227
|
- lib/integrity/helpers/authorization.rb
|
226
228
|
- lib/integrity/helpers/breadcrumbs.rb
|
227
|
-
- lib/integrity/helpers/forms.rb
|
228
229
|
- lib/integrity/helpers/pretty_output.rb
|
229
230
|
- lib/integrity/helpers/rendering.rb
|
230
231
|
- lib/integrity/helpers/resources.rb
|
@@ -257,6 +258,7 @@ files:
|
|
257
258
|
- test/acceptance/installer_test.rb
|
258
259
|
- test/acceptance/manual_build_project_test.rb
|
259
260
|
- test/acceptance/not_found_page_test.rb
|
261
|
+
- test/acceptance/notifier_test_test.rb
|
260
262
|
- test/acceptance/project_syndication_test.rb
|
261
263
|
- test/acceptance/stylesheet_test.rb
|
262
264
|
- test/acceptance/unauthorized_page_test.rb
|
@@ -278,7 +280,6 @@ files:
|
|
278
280
|
- test/unit/integrity_test.rb
|
279
281
|
- test/unit/migrations_test.rb
|
280
282
|
- test/unit/notifier/base_test.rb
|
281
|
-
- test/unit/notifier/test_test.rb
|
282
283
|
- test/unit/notifier_test.rb
|
283
284
|
- test/unit/project_builder_test.rb
|
284
285
|
- test/unit/project_test.rb
|
@@ -1,29 +0,0 @@
|
|
1
|
-
module Integrity
|
2
|
-
module Helpers
|
3
|
-
module Forms
|
4
|
-
def errors_on(object, field)
|
5
|
-
return "" unless errors = object.errors.on(field)
|
6
|
-
errors.map {|e| e.gsub(/#{field} /i, "") }.join(", ")
|
7
|
-
end
|
8
|
-
|
9
|
-
def error_class(object, field)
|
10
|
-
object.errors.on(field).nil? ? "" : "with_errors"
|
11
|
-
end
|
12
|
-
|
13
|
-
def checkbox(name, condition, extras={})
|
14
|
-
attrs = { :name => name, :type => "checkbox", :value => "1" }
|
15
|
-
attrs[:checked] = !!condition
|
16
|
-
attrs.update(extras)
|
17
|
-
end
|
18
|
-
|
19
|
-
def notifier_form
|
20
|
-
Notifier.available.each_pair { |name, klass|
|
21
|
-
haml_concat haml(klass.to_haml, :layout => :notifier, :locals => {
|
22
|
-
:notifier => name,
|
23
|
-
:enabled => current_project.notifies?(name),
|
24
|
-
:config => current_project.config_for(name) })
|
25
|
-
}
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
@@ -1,29 +0,0 @@
|
|
1
|
-
require File.dirname(__FILE__) + "/../../helpers"
|
2
|
-
require "helpers/acceptance/textfile_notifier"
|
3
|
-
|
4
|
-
require "integrity/notifier/test"
|
5
|
-
|
6
|
-
class NotifierTestTest < Test::Unit::TestCase
|
7
|
-
include Integrity::Notifier::Test
|
8
|
-
|
9
|
-
before(:each) do
|
10
|
-
# Because we unset every notifier in global setup
|
11
|
-
load "helpers/acceptance/textfile_notifier.rb"
|
12
|
-
end
|
13
|
-
|
14
|
-
def notifier
|
15
|
-
"Textfile"
|
16
|
-
end
|
17
|
-
|
18
|
-
test "it provides a formulary to configure options" do
|
19
|
-
assert_form_have_option("file")
|
20
|
-
end
|
21
|
-
|
22
|
-
test "it sends notification" do
|
23
|
-
commit = Integrity::Commit.gen(:build => Build.gen(:successful))
|
24
|
-
|
25
|
-
assert notification(commit).include?(commit.identifier)
|
26
|
-
assert notification_failed.include?("failed")
|
27
|
-
assert notification_successful.include?("was successful")
|
28
|
-
end
|
29
|
-
end
|