foca-integrity 0.1.4 → 0.1.6
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/README.markdown +19 -106
- data/Rakefile +53 -25
- data/VERSION.yml +1 -1
- data/app.rb +24 -153
- data/bin/integrity +2 -80
- data/config/config.sample.ru +2 -1
- data/config/config.sample.yml +4 -0
- data/integrity.gemspec +16 -11
- data/lib/integrity/build.rb +10 -5
- data/lib/integrity/helpers/authorization.rb +33 -0
- data/lib/integrity/helpers/breadcrumbs.rb +20 -0
- data/lib/integrity/helpers/forms.rb +28 -0
- data/lib/integrity/helpers/pretty_output.rb +45 -0
- data/lib/integrity/helpers/rendering.rb +14 -0
- data/lib/integrity/helpers/resources.rb +13 -0
- data/lib/integrity/helpers/urls.rb +47 -0
- data/lib/integrity/helpers.rb +16 -0
- data/lib/integrity/installer.rb +133 -0
- data/lib/integrity/migrations.rb +50 -0
- data/lib/integrity/notifier/base.rb +1 -1
- data/lib/integrity/notifier.rb +2 -2
- data/lib/integrity/project.rb +40 -13
- data/lib/integrity/{builder.rb → project_builder.rb} +1 -3
- data/lib/integrity/scm/git.rb +4 -4
- data/lib/integrity/scm.rb +5 -8
- data/lib/integrity.rb +37 -26
- data/test/helpers/acceptance/git_helper.rb +99 -0
- data/test/helpers/acceptance/textfile_notifier.rb +26 -0
- data/test/helpers/acceptance.rb +126 -0
- data/test/helpers/expectations/be_a.rb +23 -0
- data/test/helpers/expectations/change.rb +90 -0
- data/test/helpers/expectations/have.rb +105 -0
- data/test/helpers/expectations/have_tag.rb +128 -0
- data/test/helpers/expectations/predicates.rb +37 -0
- data/test/helpers/expectations.rb +5 -0
- data/test/helpers/fixtures.rb +83 -0
- data/test/helpers.rb +48 -0
- data/views/_build_info.haml +18 -0
- data/views/build.haml +1 -1
- data/views/error.haml +10 -3
- data/views/home.haml +3 -2
- data/views/integrity.sass +1 -1
- data/views/layout.haml +3 -0
- data/views/new.haml +10 -13
- data/views/notifier.haml +1 -1
- data/views/project.builder +21 -0
- data/views/project.haml +9 -13
- metadata +38 -11
- data/lib/integrity/core_ext/time.rb +0 -13
- data/spec/form_field_matchers.rb +0 -91
- data/spec/spec_helper.rb +0 -135
- data/vendor/sinatra-hacks/lib/hacks.rb +0 -49
- data/views/build_info.haml +0 -22
data/README.markdown
CHANGED
@@ -1,93 +1,15 @@
|
|
1
1
|
Integrity
|
2
2
|
=========
|
3
3
|
|
4
|
-
Integrity is your friendly automated Continuous Integration server.
|
4
|
+
[Integrity][website] is your friendly automated Continuous Integration server.
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
It has been designed with ruby projects in mind, but any project that can be
|
12
|
-
tested in an unix-y fashion (with a command line tool that returns 0 on success
|
13
|
-
and non-zero on failure) works with it.
|
14
|
-
|
15
|
-
Getting Started
|
16
|
-
===============
|
17
|
-
|
18
|
-
Install the `integrity` gem from GitHub:
|
19
|
-
|
20
|
-
gem sources add http://gems.github.com
|
21
|
-
sudo gem install foca-integrity
|
22
|
-
|
23
|
-
In order to setup Integrity, run the following command:
|
24
|
-
|
25
|
-
integrity install /path/to/my/app
|
26
|
-
|
27
|
-
Then browse to /path/to/my/app and edit the config files at your convenience.
|
28
|
-
The default configuration should be "good enough" in most cases, so you should
|
29
|
-
be pretty much ready to rock.
|
30
|
-
|
31
|
-
For deployment, we recommend [Thin][]. Provided with Integrity comes a thin.yml
|
32
|
-
file, so all you need to do after running `integrity install` should be
|
33
|
-
|
34
|
-
thin -C /path/to/my/app/thin.yml -R /path/to/my/app/config.ru start
|
35
|
-
|
36
|
-
And you should be up and running.
|
37
|
-
|
38
|
-
If you want automatic commit processing, you currently need to be using
|
39
|
-
[GitHub][]. Click the edit link on your GitHub project, and add an integrity
|
40
|
-
link that looks like the following to the `Post-Receive URL` field:
|
41
|
-
|
42
|
-
http://integrity.domain.tld/projectname/push
|
43
|
-
|
44
|
-
Receiving Notifications
|
45
|
-
=======================
|
46
|
-
|
47
|
-
If you want to be notified after each build, you need to install our notifiers.
|
48
|
-
For example, in order to receive an email after each build, install:
|
49
|
-
|
50
|
-
sudo gem install foca-integrity-email
|
51
|
-
|
52
|
-
And then edit `/path/to/my/app/config.ru` and add:
|
53
|
-
|
54
|
-
require "notifier/email"
|
55
|
-
|
56
|
-
After all the `require` lines.
|
57
|
-
|
58
|
-
Available notifiers
|
59
|
-
-------------------
|
60
|
-
|
61
|
-
* [Mail](http://github.com/foca/integrity-email)
|
62
|
-
* [Jabber](http://github.com/ph/integrity-jabber)
|
63
|
-
* [Campfire](http://github.com/defunkt/integrity-campfire)
|
64
|
-
|
65
|
-
Resources
|
66
|
-
========
|
67
|
-
|
68
|
-
We have a [Lighthouse account][lighthouse] where you can submit patches or
|
69
|
-
feature requests. Also, someone is usually around [#integrity][irc-channel] on
|
70
|
-
Freenode, so don't hesitate to stop by for ideas, help, patches or something.
|
71
|
-
|
72
|
-
Future plans
|
73
|
-
============
|
74
|
-
|
75
|
-
* [Twitter][]/[IRC][]/etc bots
|
76
|
-
* A sample generic post-receive-hook so you can run this from any git repo
|
77
|
-
* Better integration with GitHub
|
78
|
-
|
79
|
-
Development
|
80
|
-
===========
|
81
|
-
|
82
|
-
The code is stored in [GitHub][repo]. Feel free to fork, play with it, and send
|
83
|
-
a pull request afterwards.
|
84
|
-
|
85
|
-
In order to run the test suite you'll need a few more gems: [rspec][], [rcov][]
|
86
|
-
and [hpricot][]. With that installed running `rake` will run the specs and
|
87
|
-
ensure the code coverage stays high.
|
6
|
+
* See our [website][] for documentation and a [live demo][demo]
|
7
|
+
* Report bugs and submit features request on our [Lighthouse account][lighthouse]
|
8
|
+
* Join us on [#integrity][irc-channel] for ideas, help, patches or something
|
9
|
+
* Get the code on [GitHub][repo]
|
88
10
|
|
89
11
|
Thanks
|
90
|
-
|
12
|
+
------
|
91
13
|
|
92
14
|
Thanks to the fellowing people for their feedbacks, ideas and patches :
|
93
15
|
|
@@ -99,16 +21,8 @@ Thanks to the fellowing people for their feedbacks, ideas and patches :
|
|
99
21
|
* [Simon Rozet][sr]
|
100
22
|
* [Scott Taylor][scott]
|
101
23
|
|
102
|
-
[james]: http://github.com/lazyatom
|
103
|
-
[ec]: http://github.com/elliotcabble
|
104
|
-
[atmos]: http://github.com/atmos
|
105
|
-
[kyle]: http://github.com/pd
|
106
|
-
[ph]: http://github.com/ph
|
107
|
-
[sr]: http://purl.org/net/sr/
|
108
|
-
[scott]: http://github.com/smtlaissezfaire
|
109
|
-
|
110
24
|
License
|
111
|
-
|
25
|
+
-------
|
112
26
|
|
113
27
|
(The MIT License)
|
114
28
|
|
@@ -133,21 +47,20 @@ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
133
47
|
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
134
48
|
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
135
49
|
|
136
|
-
[
|
137
|
-
[
|
138
|
-
[svn]: http://subversion.tigris.org
|
139
|
-
[Twitter]: http://twitter.com
|
140
|
-
[IRC]: http://wikipedia.org/wiki/IRC
|
141
|
-
[entp]: http://entp.com
|
142
|
-
[GitHub]: http://github.com
|
143
|
-
[Thin]: http://code.macournoyer.com/thin/
|
144
|
-
|
145
|
-
[rspec]: http://rspec.info
|
146
|
-
[rcov]: http://eigenclass.org/hiki.rb?rcov
|
147
|
-
[hpricot]: http://code.whytheluckystiff.net/hpricot
|
148
|
-
|
50
|
+
[website]: http://integrityapp.com
|
51
|
+
[demo]: http://builder.integrityapp.com
|
149
52
|
[repo]: http://github.com/foca/integrity
|
150
53
|
[lighthouse]: http://integrity.lighthouseapp.com/projects/14308-integrity
|
151
54
|
[irc-channel]: irc://irc.freenode.net/integrity
|
152
55
|
|
153
56
|
[foca]: http://nicolassanguinetti.info/
|
57
|
+
[entp]: http://entp.com
|
58
|
+
|
59
|
+
[james]: http://github.com/lazyatom
|
60
|
+
[ec]: http://github.com/elliotcabble
|
61
|
+
[atmos]: http://github.com/atmos
|
62
|
+
[kyle]: http://github.com/pd
|
63
|
+
[ph]: http://github.com/ph
|
64
|
+
[sr]: http://purl.org/net/sr/
|
65
|
+
[scott]: http://github.com/smtlaissezfaire
|
66
|
+
|
data/Rakefile
CHANGED
@@ -1,30 +1,58 @@
|
|
1
1
|
require File.dirname(__FILE__) + "/lib/integrity"
|
2
|
-
require
|
3
|
-
require
|
2
|
+
require "rake/testtask"
|
3
|
+
require "rcov/rcovtask"
|
4
4
|
|
5
|
-
|
5
|
+
desc "Run all tests and check test coverage"
|
6
|
+
task :default => "test:coverage:verify"
|
6
7
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
8
|
+
desc "Run tests"
|
9
|
+
task :test => %w(test:units test:acceptance)
|
10
|
+
|
11
|
+
namespace :test do
|
12
|
+
Rake::TestTask.new(:units) do |t|
|
13
|
+
t.test_files = FileList["test/unit/*_test.rb"]
|
14
|
+
end
|
13
15
|
|
14
|
-
|
15
|
-
|
16
|
-
t.spec_opts = ["--color", "--format", "progress"]
|
17
|
-
t.spec_files = Dir['spec/**/*_spec.rb'].sort
|
18
|
-
t.libs = ['lib']
|
19
|
-
t.rcov = true
|
20
|
-
t.rcov_opts = ['--exclude-only', '".*"', '--include-file', '^lib']
|
16
|
+
Rake::TestTask.new(:acceptance) do |t|
|
17
|
+
t.test_files = FileList["test/acceptance/*_test.rb"]
|
21
18
|
end
|
22
19
|
|
20
|
+
desc "Measure test coverage"
|
21
|
+
task :coverage => %w(test:coverage:units test:coverage:acceptance)
|
22
|
+
|
23
23
|
namespace :coverage do
|
24
|
-
|
25
|
-
|
26
|
-
|
24
|
+
desc "Measure test coverage of unit tests"
|
25
|
+
Rcov::RcovTask.new(:units) do |rcov|
|
26
|
+
rcov.pattern = "test/unit/*_test.rb"
|
27
|
+
rcov.rcov_opts = %w(--html --aggregate .aggregated_coverage_report)
|
28
|
+
rcov.rcov_opts << ENV["RCOV_OPTS"] if ENV["RCOV_OPTS"]
|
29
|
+
end
|
30
|
+
|
31
|
+
desc "Measure test coverage of acceptance tests"
|
32
|
+
Rcov::RcovTask.new(:acceptance) do |rcov|
|
33
|
+
rcov.pattern = "test/acceptance/*_test.rb"
|
34
|
+
rcov.rcov_opts = %w(--html --aggregate .aggregated_coverage_report)
|
35
|
+
rcov.rcov_opts << ENV["RCOV_OPTS"] if ENV["RCOV_OPTS"]
|
27
36
|
end
|
37
|
+
|
38
|
+
desc "Verify test coverage"
|
39
|
+
task :verify => "test:coverage" do
|
40
|
+
File.read("coverage/index.html") =~ /<tt class='coverage_total'>\s*(\d+\.\d+)%\s*<\/tt>/
|
41
|
+
coverage = $1.to_f
|
42
|
+
|
43
|
+
puts
|
44
|
+
if coverage == 100
|
45
|
+
puts "\e[32m100% coverage! Awesome!\e[0m"
|
46
|
+
else
|
47
|
+
puts "\e[31mOnly #{coverage}% code coverage. You can do better ;)\e[0m"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
desc "Install all gems on which the tests depend on"
|
53
|
+
task :install_dependencies do
|
54
|
+
system 'gem install redgreen rr mocha ruby-debug dm-sweatshop webrat'
|
55
|
+
system 'gem install -s http://gems.github.com jeremymcanally-context jeremymcanally-matchy jeremymcanally-pending foca-storyteller'
|
28
56
|
end
|
29
57
|
end
|
30
58
|
|
@@ -48,8 +76,7 @@ end
|
|
48
76
|
begin
|
49
77
|
require 'jeweler'
|
50
78
|
Jeweler::Tasks.new do |s|
|
51
|
-
files = `git ls-files`.split("\n").reject {|f| f =~ %r(^
|
52
|
-
files += %w(spec/spec_helper.rb spec/form_field_matchers.rb)
|
79
|
+
files = `git ls-files`.split("\n").reject {|f| f =~ %r(^test/acceptance) || f =~ %r(^test/unit) || f =~ /^\.git/ }
|
53
80
|
|
54
81
|
s.name = 'integrity'
|
55
82
|
s.summary = 'The easy and fun Continuous Integration server'
|
@@ -62,20 +89,21 @@ begin
|
|
62
89
|
s.executables = ['integrity']
|
63
90
|
s.post_install_message = 'Run `integrity help` for information on how to setup Integrity.'
|
64
91
|
|
65
|
-
s.add_dependency 'sinatra', ['>= 0.3
|
92
|
+
s.add_dependency 'sinatra', ['>= 0.9.0.3']
|
66
93
|
s.add_dependency 'haml' # ah, you evil monkey you
|
67
94
|
s.add_dependency 'dm-core', ['>= 0.9.5']
|
68
95
|
s.add_dependency 'dm-validations', ['>= 0.9.5']
|
69
96
|
s.add_dependency 'dm-types', ['>= 0.9.5']
|
70
97
|
s.add_dependency 'dm-timestamps', ['>= 0.9.5']
|
71
98
|
s.add_dependency 'dm-aggregates', ['>= 0.9.5']
|
99
|
+
s.add_dependency 'dm-migrations', ['>= 0.9.5']
|
72
100
|
s.add_dependency 'data_objects', ['>= 0.9.5']
|
73
|
-
s.add_dependency 'do_sqlite3', ['>= 0.9.5']
|
101
|
+
s.add_dependency 'do_sqlite3', ['>= 0.9.5']
|
74
102
|
s.add_dependency 'json'
|
75
103
|
s.add_dependency 'foca-sinatra-diddies', ['>= 0.0.2']
|
76
|
-
s.add_dependency 'rspec_hpricot_matchers'
|
77
104
|
s.add_dependency 'thor'
|
78
|
-
s.add_dependency '
|
105
|
+
s.add_dependency 'uuidtools' # required by dm-types
|
106
|
+
s.add_dependency 'bcrypt-ruby' # required by dm-types
|
79
107
|
end
|
80
108
|
rescue LoadError
|
81
109
|
end
|
data/VERSION.yml
CHANGED
data/app.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
|
-
require File.dirname(__FILE__) +
|
2
|
-
require
|
3
|
-
require
|
4
|
-
require 'hacks'
|
1
|
+
require File.dirname(__FILE__) + "/lib/integrity"
|
2
|
+
require "sinatra"
|
3
|
+
require "helpers"
|
5
4
|
|
6
5
|
set :root, Integrity.root
|
7
6
|
set :public, Integrity.root / "public"
|
@@ -39,14 +38,14 @@ before do
|
|
39
38
|
end
|
40
39
|
|
41
40
|
get "/" do
|
42
|
-
@projects = Project.
|
41
|
+
@projects = Project.only_public_unless(authorized?)
|
43
42
|
show :home, :title => "projects"
|
44
43
|
end
|
45
44
|
|
46
45
|
get "/login" do
|
47
46
|
login_required
|
48
47
|
session[:user] = current_user
|
49
|
-
redirect
|
48
|
+
redirect root_url
|
50
49
|
end
|
51
50
|
|
52
51
|
get "/new" do
|
@@ -58,7 +57,7 @@ end
|
|
58
57
|
|
59
58
|
post "/" do
|
60
59
|
login_required
|
61
|
-
|
60
|
+
|
62
61
|
@project = Project.new(params[:project_data])
|
63
62
|
if @project.save
|
64
63
|
@project.enable_notifiers(params["enabled_notifiers[]"], params["notifiers"])
|
@@ -70,14 +69,20 @@ end
|
|
70
69
|
|
71
70
|
get "/:project" do
|
72
71
|
login_required unless current_project.public?
|
73
|
-
show :project, :title => ["projects", current_project.
|
72
|
+
show :project, :title => ["projects", current_project.name]
|
73
|
+
end
|
74
|
+
|
75
|
+
get "/:project.atom" do
|
76
|
+
login_required unless current_project.public?
|
77
|
+
response["Content-Type"] = "application/rss+xml; charset=utf-8"
|
78
|
+
builder :project
|
74
79
|
end
|
75
80
|
|
76
81
|
put "/:project" do
|
77
82
|
login_required
|
78
|
-
|
83
|
+
|
79
84
|
if current_project.update_attributes(params[:project_data])
|
80
|
-
current_project.enable_notifiers(params["enabled_notifiers
|
85
|
+
current_project.enable_notifiers(params["enabled_notifiers"], params["notifiers"])
|
81
86
|
redirect project_url(current_project)
|
82
87
|
else
|
83
88
|
show :new, :title => ["projects", current_project.permalink, "edit"]
|
@@ -88,7 +93,7 @@ delete "/:project" do
|
|
88
93
|
login_required
|
89
94
|
|
90
95
|
current_project.destroy
|
91
|
-
redirect
|
96
|
+
redirect root_url
|
92
97
|
end
|
93
98
|
|
94
99
|
get "/:project/edit" do
|
@@ -99,23 +104,14 @@ end
|
|
99
104
|
|
100
105
|
post "/:project/push" do
|
101
106
|
login_required
|
102
|
-
|
103
|
-
content_type 'text/plain'
|
104
|
-
|
105
|
-
begin
|
106
|
-
payload = JSON.parse(params[:payload] || "")
|
107
107
|
|
108
|
-
|
109
|
-
payload['commits'].sort_by { |commit| Time.parse(commit['timestamp']) }.each do |commit|
|
110
|
-
current_project.build(commit['id']) if payload['ref'] =~ /#{current_project.branch}/
|
111
|
-
end
|
112
|
-
else
|
113
|
-
current_project.build(payload['after']) if payload['ref'] =~ /#{current_project.branch}/
|
114
|
-
end
|
108
|
+
content_type "text/plain"
|
115
109
|
|
116
|
-
|
110
|
+
begin
|
111
|
+
current_project.push(params[:payload])
|
112
|
+
"Thanks, build started."
|
117
113
|
rescue JSON::ParserError => exception
|
118
|
-
|
114
|
+
throw :halt, [422, exception.to_s]
|
119
115
|
end
|
120
116
|
end
|
121
117
|
|
@@ -126,141 +122,16 @@ post "/:project/builds" do
|
|
126
122
|
redirect project_url(@project)
|
127
123
|
end
|
128
124
|
|
129
|
-
get
|
125
|
+
get "/:project/builds/:build" do
|
130
126
|
login_required unless current_project.public?
|
131
127
|
show :build, :title => ["projects", current_project.permalink, current_build.short_commit_identifier]
|
132
128
|
end
|
133
129
|
|
134
130
|
get "/integrity.css" do
|
135
|
-
|
131
|
+
response["Content-Type"] = "text/css; charset=utf-8"
|
136
132
|
sass :integrity
|
137
133
|
end
|
138
134
|
|
139
135
|
helpers do
|
140
|
-
include
|
141
|
-
include Sinatra::Authorization
|
142
|
-
alias_method :h, :escape_html
|
143
|
-
|
144
|
-
def authorization_realm
|
145
|
-
"Integrity"
|
146
|
-
end
|
147
|
-
|
148
|
-
def authorized?
|
149
|
-
return true unless Integrity.config[:use_basic_auth]
|
150
|
-
!!request.env['REMOTE_USER']
|
151
|
-
end
|
152
|
-
|
153
|
-
def authorize(user, password)
|
154
|
-
if Integrity.config[:hash_admin_password]
|
155
|
-
password = Digest::SHA1.hexdigest(password)
|
156
|
-
end
|
157
|
-
|
158
|
-
!Integrity.config[:use_basic_auth] ||
|
159
|
-
(Integrity.config[:admin_username] == user &&
|
160
|
-
Integrity.config[:admin_password] == password)
|
161
|
-
end
|
162
|
-
|
163
|
-
def unauthorized!(realm=authorization_realm)
|
164
|
-
header 'WWW-Authenticate' => %(Basic realm="#{realm}")
|
165
|
-
throw :halt, [401, show(:unauthorized, :title => "incorrect credentials")]
|
166
|
-
end
|
167
|
-
|
168
|
-
def invalid_payload!(msg=nil)
|
169
|
-
throw :halt, [422, msg || 'No payload given']
|
170
|
-
end
|
171
|
-
|
172
|
-
def current_project
|
173
|
-
@project ||= Project.first(:permalink => params[:project]) or raise Sinatra::NotFound
|
174
|
-
end
|
175
|
-
|
176
|
-
def current_build
|
177
|
-
@build ||= current_project.builds.first(:commit_identifier => params[:build]) or raise Sinatra::NotFound
|
178
|
-
end
|
179
|
-
|
180
|
-
def show(view, options={})
|
181
|
-
@title = breadcrumbs(*options[:title])
|
182
|
-
haml view
|
183
|
-
end
|
184
|
-
|
185
|
-
def pages
|
186
|
-
@pages ||= [["projects", "/"], ["new project", "/new"]]
|
187
|
-
end
|
188
|
-
|
189
|
-
def breadcrumbs(*crumbs)
|
190
|
-
crumbs[0..-2].map do |crumb|
|
191
|
-
if page_data = pages.detect {|c| c.first == crumb }
|
192
|
-
%Q(<a href="#{page_data.last}">#{page_data.first}</a>)
|
193
|
-
elsif @project && @project.permalink == crumb
|
194
|
-
%Q(<a href="#{project_url(@project)}">#{@project.permalink}</a>)
|
195
|
-
end
|
196
|
-
end + [crumbs.last]
|
197
|
-
end
|
198
|
-
|
199
|
-
def cycle(*values)
|
200
|
-
@cycles ||= {}
|
201
|
-
@cycles[values] ||= -1 # first value returned is 0
|
202
|
-
next_value = @cycles[values] = (@cycles[values] + 1) % values.size
|
203
|
-
values[next_value]
|
204
|
-
end
|
205
|
-
|
206
|
-
def project_url(project, *path)
|
207
|
-
"/" << [project.permalink, *path].join("/")
|
208
|
-
end
|
209
|
-
|
210
|
-
def push_url_for(project)
|
211
|
-
Addressable::URI.parse(Integrity.config[:base_uri]).join("#{project_url(project)}/push").to_s
|
212
|
-
end
|
213
|
-
|
214
|
-
def build_url(build)
|
215
|
-
"/#{build.project.permalink}/builds/#{build.commit_identifier}"
|
216
|
-
end
|
217
|
-
|
218
|
-
def filter_attributes_of(model)
|
219
|
-
valid = model.properties.collect {|p| p.name.to_s }
|
220
|
-
Hash[*params.dup.select {|k,_| valid.include?(k) }.flatten]
|
221
|
-
end
|
222
|
-
|
223
|
-
def errors_on(object, field)
|
224
|
-
return "" unless errors = object.errors.on(field)
|
225
|
-
errors.map {|e| e.gsub(/#{field} /i, "") }.join(", ")
|
226
|
-
end
|
227
|
-
|
228
|
-
def error_class(object, field)
|
229
|
-
object.errors.on(field).nil? ? "" : "with_errors"
|
230
|
-
end
|
231
|
-
|
232
|
-
def checkbox(name, condition, extras={})
|
233
|
-
attrs = { :name => name, :type => "checkbox" }.merge(condition ? { :checked => "checked" } : {})
|
234
|
-
attrs.merge(extras)
|
235
|
-
end
|
236
|
-
|
237
|
-
def bash_color_codes(string)
|
238
|
-
string.gsub("\e[0m", '</span>').
|
239
|
-
gsub("\e[31m", '<span class="color31">').
|
240
|
-
gsub("\e[32m", '<span class="color32">').
|
241
|
-
gsub("\e[33m", '<span class="color33">').
|
242
|
-
gsub("\e[34m", '<span class="color34">').
|
243
|
-
gsub("\e[35m", '<span class="color35">').
|
244
|
-
gsub("\e[36m", '<span class="color36">').
|
245
|
-
gsub("\e[37m", '<span class="color37">')
|
246
|
-
end
|
247
|
-
|
248
|
-
def pretty_date(date_time)
|
249
|
-
today = Date.today
|
250
|
-
if date_time.day == today.day && date_time.month == today.month && date_time.year == today.year
|
251
|
-
"today"
|
252
|
-
elsif date_time.day == today.day - 1 && date_time.month == today.month && date_time.year == today.year
|
253
|
-
"yesterday"
|
254
|
-
else
|
255
|
-
date_time.strftime("on %b %d%o")
|
256
|
-
end
|
257
|
-
end
|
258
|
-
|
259
|
-
def notifier_form(notifier)
|
260
|
-
haml(notifier.to_haml, :layout => :notifier, :locals => {
|
261
|
-
:config => current_project.config_for(notifier),
|
262
|
-
:notifier => "#{notifier.to_s.split(/::/).last}",
|
263
|
-
:enabled => current_project.notifies?(notifier)
|
264
|
-
})
|
265
|
-
end
|
136
|
+
include Helpers
|
266
137
|
end
|
data/bin/integrity
CHANGED
@@ -1,82 +1,4 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
-
require "
|
3
|
-
require "thor"
|
2
|
+
require File.dirname(__FILE__) + "/../lib/integrity/installer"
|
4
3
|
|
5
|
-
|
6
|
-
|
7
|
-
class WithIntegrity < Thor
|
8
|
-
include FileUtils
|
9
|
-
|
10
|
-
desc "install [PATH]",
|
11
|
-
"Copy template files to PATH. Next, go there and edit them."
|
12
|
-
def install(path)
|
13
|
-
@root = File.expand_path(path)
|
14
|
-
|
15
|
-
create_dir_structure
|
16
|
-
copy_template_files
|
17
|
-
edit_template_files
|
18
|
-
create_db(root / "config.yml")
|
19
|
-
after_setup_message
|
20
|
-
end
|
21
|
-
|
22
|
-
desc "create_db [CONFIG]",
|
23
|
-
"Checks the `database_uri` in CONFIG and creates and bootstraps a database for integrity"
|
24
|
-
def create_db(config)
|
25
|
-
Integrity.new(config)
|
26
|
-
DataMapper.auto_migrate!
|
27
|
-
end
|
28
|
-
|
29
|
-
private
|
30
|
-
attr_reader :root
|
31
|
-
|
32
|
-
def create_dir_structure
|
33
|
-
mkdir_p root
|
34
|
-
mkdir_p root / "builds"
|
35
|
-
mkdir_p root / "log"
|
36
|
-
end
|
37
|
-
|
38
|
-
def copy_template_files
|
39
|
-
cp Integrity.root / "config" / "config.sample.ru", root / "config.ru"
|
40
|
-
cp Integrity.root / "config" / "config.sample.yml", root / "config.yml"
|
41
|
-
cp Integrity.root / "config" / "thin.sample.yml", root / "thin.yml"
|
42
|
-
end
|
43
|
-
|
44
|
-
def edit_template_files
|
45
|
-
edit_integrity_configuration
|
46
|
-
edit_thin_configuration
|
47
|
-
end
|
48
|
-
|
49
|
-
def edit_integrity_configuration
|
50
|
-
config = File.read(root / "config.yml")
|
51
|
-
config.gsub! %r(sqlite3:///var/integrity.db), "sqlite3://#{root}/integrity.db"
|
52
|
-
config.gsub! %r(/path/to/scm/exports), "#{root}/builds"
|
53
|
-
config.gsub! %r(/var/log), "#{root}/log"
|
54
|
-
File.open(root / "config.yml", "w") { |f| f.puts config }
|
55
|
-
end
|
56
|
-
|
57
|
-
def edit_thin_configuration
|
58
|
-
config = File.read(root / "thin.yml")
|
59
|
-
config.gsub! %r(/apps/integrity), root
|
60
|
-
File.open(root / "thin.yml", 'w') { |f| f.puts config }
|
61
|
-
end
|
62
|
-
|
63
|
-
def after_setup_message
|
64
|
-
puts
|
65
|
-
puts %Q(Awesome! Integrity was installed successfully!)
|
66
|
-
puts
|
67
|
-
puts %Q(If you want to enable notifiers, install the gems and then require them)
|
68
|
-
puts %Q(in #{root}/config.ru)
|
69
|
-
puts
|
70
|
-
puts %Q(For example:)
|
71
|
-
puts
|
72
|
-
puts %Q( sudo gem install -s http://gems.github.com foca-integrity-email)
|
73
|
-
puts
|
74
|
-
puts %Q(And then in #{root}/config.ru add:)
|
75
|
-
puts
|
76
|
-
puts %Q( require "notifier/email")
|
77
|
-
puts
|
78
|
-
puts %Q(Don't forget to tweak #{root / "config.yml"} to your needs.)
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
|
-
WithIntegrity.start
|
4
|
+
Integrity::Installer.start
|
data/config/config.sample.ru
CHANGED
data/config/config.sample.yml
CHANGED
@@ -16,6 +16,10 @@
|
|
16
16
|
# Path to the integrity log file
|
17
17
|
:log: /var/log/integrity.log
|
18
18
|
|
19
|
+
# Enable/Disable debug logging. Turning this on will log queries made to the
|
20
|
+
# database and web requests (if using the provided rackup file)
|
21
|
+
:log_debug_info: false
|
22
|
+
|
19
23
|
# Enable or disable HTTP authentication for the app. BE AWARE that if you
|
20
24
|
# disable this anyone can delete and alter projects, so do it only if your
|
21
25
|
# app is running in a controlled environment (ie, behind your company's
|