foca-integrity 0.1.4 → 0.1.6
Sign up to get free protection for your applications and to get access to all the features.
- 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
|