juici 0.0.0.alpha1 → 0.0.0
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/Gemfile +1 -4
- data/Gemfile.lock +9 -19
- data/README.md +6 -45
- data/Rakefile +0 -24
- data/config/mongoid.yml.sample +5 -20
- data/juici.gemspec +3 -7
- data/lib/juici.rb +3 -8
- data/lib/juici/app.rb +23 -19
- data/lib/juici/build_environment.rb +1 -1
- data/lib/juici/build_logic.rb +1 -10
- data/lib/juici/build_queue.rb +3 -30
- data/lib/juici/callback.rb +5 -9
- data/lib/juici/config.rb +0 -4
- data/lib/juici/controllers/build_controller.rb +0 -0
- data/lib/juici/controllers/{trigger.rb → trigger_controller.rb} +5 -24
- data/lib/juici/database.rb +13 -19
- data/lib/juici/helpers/url_helpers.rb +0 -28
- data/lib/juici/models/build.rb +24 -81
- data/lib/juici/models/project.rb +1 -1
- data/lib/juici/server.rb +40 -103
- data/lib/juici/url_helpers.rb +15 -0
- data/lib/juici/views/README.markdown +6 -45
- data/lib/juici/views/about.erb +5 -5
- data/lib/juici/views/builds/list.erb +33 -26
- data/lib/juici/views/builds/new.erb +37 -42
- data/lib/juici/views/builds/show.erb +28 -4
- data/lib/juici/views/index.erb +13 -30
- data/lib/juici/views/layout.erb +13 -22
- data/lib/juici/views/partials/builds/debug.erb +18 -12
- data/lib/juici/watcher.rb +25 -33
- data/public/styles/builds.css +8 -59
- data/public/styles/juici.css +2 -226
- data/spec/build_callback_spec.rb +1 -46
- data/spec/build_process_spec.rb +5 -71
- data/spec/build_queue_spec.rb +1 -3
- data/spec/juici_app_spec.rb +15 -0
- data/spec/spec_helper.rb +0 -13
- metadata +12 -76
- data/.gitignore +0 -2
- data/bin/juicic +0 -54
- data/juici-interface.gemspec +0 -19
- data/lib/juici/controllers.rb +0 -6
- data/lib/juici/controllers/base.rb +0 -26
- data/lib/juici/controllers/build_queue.rb +0 -14
- data/lib/juici/controllers/builds.rb +0 -74
- data/lib/juici/controllers/index.rb +0 -20
- data/lib/juici/exceptions.rb +0 -2
- data/lib/juici/find_logic.rb +0 -11
- data/lib/juici/helpers/form_helpers.rb +0 -11
- data/lib/juici/helpers/html_helpers.rb +0 -4
- data/lib/juici/interface.rb +0 -13
- data/lib/juici/version.rb +0 -8
- data/lib/juici/views/builds/edit.erb +0 -23
- data/lib/juici/views/not_found.erb +0 -3
- data/lib/juici/views/partials/builds/output.erb +0 -1
- data/lib/juici/views/partials/builds/show.erb +0 -19
- data/lib/juici/views/partials/builds/sidebar.erb +0 -13
- data/lib/juici/views/partials/index/recently_built.erb +0 -19
- data/lib/juici/views/queue/list.erb +0 -6
- data/public/favicon.ico +0 -0
- data/public/images/black_denim.png +0 -0
- data/public/vendor/bootstrap.css +0 -6004
- data/public/vendor/bootstrap.js +0 -2036
- data/public/vendor/img/glyphicons-halflings-white.png +0 -0
- data/public/vendor/jquery.js +0 -9440
- data/script/cibuild +0 -10
- data/spec/controllers/builds_spec.rb +0 -68
- data/spec/controllers/index_spec.rb +0 -28
- data/spec/models/build_spec.rb +0 -54
@@ -0,0 +1,15 @@
|
|
1
|
+
# So this is pretty much just horrific, but at least an interestingish
|
2
|
+
# proof of concept
|
3
|
+
# XXX Deprecated
|
4
|
+
module Juici
|
5
|
+
def self.url_helpers(route)
|
6
|
+
Module.new do
|
7
|
+
@@route = route
|
8
|
+
|
9
|
+
def url_for(child)
|
10
|
+
"/#{@@route}/#{child}"
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -13,8 +13,8 @@ It's designed to work well with [agent99](https://github.com/99designs/agent99)
|
|
13
13
|
|
14
14
|
## Important but Miscellaneous
|
15
15
|
|
16
|
-
If you create child
|
17
|
-
disinterest or JuiCI will think they're builds and that would be bad
|
16
|
+
If you create child process in modules/plugins then you need to register your
|
17
|
+
disinterest or JuiCI will think they're builds and that would be bad
|
18
18
|
|
19
19
|
## Setup
|
20
20
|
|
@@ -27,26 +27,12 @@ bundle exec bin/juici
|
|
27
27
|
|
28
28
|
is all you need to have a working instance (provided that you have mongo installed)
|
29
29
|
|
30
|
-
### Gotchas
|
31
|
-
|
32
|
-
Make sure you don't do something innocuous like
|
33
|
-
|
34
|
-
```bash
|
35
|
-
bundle install --path .bundle
|
36
|
-
```
|
37
|
-
|
38
|
-
this might look sane (and it is, kinda) but owing to a quick in bundler, it
|
39
|
-
will break any ruby code you try to build.
|
40
|
-
|
41
|
-
I'm working on a workaround, but in the meantime the fix is to not do it!
|
42
|
-
|
43
30
|
## Usage
|
44
31
|
|
45
|
-
JuiCI
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
your test environment)
|
32
|
+
JuiCI chooses to be very "Mongo" (which is an adjective now), in that you don't
|
33
|
+
need to formally create a project. Just request a build; however this means
|
34
|
+
that on your first build you will need to send the commands to create your test
|
35
|
+
environment)
|
50
36
|
|
51
37
|
Example:
|
52
38
|
|
@@ -81,20 +67,6 @@ called with an (as yet unformalised) json body as the body if/when the build
|
|
81
67
|
reaches that state. Alternately you may specify "any" as the callback state and
|
82
68
|
it will be called on all state changes.
|
83
69
|
|
84
|
-
## Integration
|
85
|
-
|
86
|
-
Apps written in ruby wanting to interact with Juici can include the
|
87
|
-
`juici-interface` gem, which presently exposes a few constants to line up with
|
88
|
-
JuiCI's internal state.
|
89
|
-
Over time this will be expanded, but for now they are:
|
90
|
-
|
91
|
-
```ruby
|
92
|
-
Juici::BuildStatus::PASS
|
93
|
-
Juici::BuildStatus::FAIL
|
94
|
-
Juici::BuildStatus::START
|
95
|
-
Juici::BuildStatus::WAIT
|
96
|
-
```
|
97
|
-
|
98
70
|
## Security
|
99
71
|
|
100
72
|
JuiCI poses some interesting security conecerns. First off, it will allow
|
@@ -120,19 +92,8 @@ specifically implement it, your process won't see any of the signal handling
|
|
120
92
|
madness. The shell(`/bin/sh`) will see everything, and if killed, your
|
121
93
|
processes will become orphaned, but carry on.
|
122
94
|
|
123
|
-
## Authors
|
124
|
-
|
125
|
-
* [Richo Healey](https://github.com/rcho)
|
126
|
-
* [Alec Sloman](https://github.com/alecsloman)
|
127
|
-
|
128
95
|
## Contact
|
129
96
|
|
130
97
|
JuiCI's code lives on [Github](https://github.com/richo/juici)
|
131
98
|
and the [author](mailto:richo@psych0tik.net) can be contacted on
|
132
99
|
[Twitter](https://twitter.com/rich0H)
|
133
|
-
|
134
|
-
## Legalese
|
135
|
-
|
136
|
-
(c) Richo Healey 2012, richo@psych0tik.net
|
137
|
-
|
138
|
-
Released under the terms of the MIT license.
|
data/lib/juici/views/about.erb
CHANGED
@@ -1,12 +1,12 @@
|
|
1
|
-
<div class="row
|
2
|
-
<div class="
|
1
|
+
<div class="row">
|
2
|
+
<div class="span8">
|
3
3
|
<div>
|
4
|
-
<%=
|
4
|
+
<%= GitHub::Markdown.render(File.read("lib/juici/views/README.markdown")) %>
|
5
5
|
</div>
|
6
6
|
</div>
|
7
|
-
<div class="
|
7
|
+
<div class="span4">
|
8
8
|
<div>
|
9
|
-
<
|
9
|
+
<p>Quick Links</p>
|
10
10
|
<ul>
|
11
11
|
<li>richo on <a href="https://twitter.com/rich0H">twitter</a></li>
|
12
12
|
<li>richo on <a href="https://github.com/richo">github</a></li>
|
@@ -1,27 +1,34 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
$(
|
4
|
-
|
5
|
-
})
|
6
|
-
|
7
|
-
</
|
8
|
-
|
9
|
-
<div class="
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
<% end %>
|
15
|
-
</div>
|
16
|
-
<!-- Main contents -->
|
17
|
-
<div class="span11">
|
18
|
-
<!-- Create a new build -->
|
19
|
-
<h3 class="project-title"><a href="<%= build_url_for(project) %>"><%= project.name %></a><a class="btn pull-right" href="/builds/new?project=<%= project.name %>">New Build</a></h3>
|
20
|
-
<!-- Build history -->
|
21
|
-
<% builds.each_with_index do |build, idx| %>
|
22
|
-
<div class="accordion accordion-set-url" id="accordion<%= idx %>">
|
23
|
-
<%= erb(:"partials/builds/show", :locals => { :build => build, :idx => idx }) %>
|
1
|
+
<% if proj = ::Juici::Project.where(name: project).first %>
|
2
|
+
<script>
|
3
|
+
$(document).ready(function() {
|
4
|
+
$(".collapse").collapse();
|
5
|
+
});
|
6
|
+
</script>
|
7
|
+
<h3><em><%= proj.name %></em> - <a href="/builds/new?project=<%= proj.name %>"><em>New Build</em></a></h3>
|
8
|
+
<% ::Juici::Build.where(parent: proj.name).sort.reverse.each_with_index do |build, idx| %>
|
9
|
+
<div class="accordion" id="accordion<%= idx %>">
|
10
|
+
<div class="accordion-heading">
|
11
|
+
<a class="accordion-toggle <%= build.heading_color %>" data-toggle="collapse" data-parent="#accordion<%= idx+1 %>" href="#collapse_<%= idx %>">
|
12
|
+
<%= build.display_title %> <% build[:warnings].each do |warning| %><span class="label label-important"><%= warning %></span><% end %>
|
13
|
+
</a>
|
24
14
|
</div>
|
25
|
-
|
26
|
-
|
27
|
-
|
15
|
+
<div id="collapse_<%= idx %>" class="accordion-body collapse in">
|
16
|
+
<div class="row">
|
17
|
+
<div class="span8">
|
18
|
+
<div>
|
19
|
+
<a href="<%= build_url_for(build) %>">Link to this build</a>
|
20
|
+
</div>
|
21
|
+
<div class="accordion-inner build-output">
|
22
|
+
<%= build.output if build.respond_to? :output %>
|
23
|
+
</div>
|
24
|
+
</div>
|
25
|
+
<div class="span4">
|
26
|
+
<%= erb(:"partials/builds/debug", :locals => { :build => build }) %>
|
27
|
+
</div>
|
28
|
+
</div>
|
29
|
+
</div>
|
30
|
+
</div>
|
31
|
+
<% end %>
|
32
|
+
<% else %>
|
33
|
+
No such project.
|
34
|
+
<% end %>
|
@@ -1,43 +1,38 @@
|
|
1
|
-
<div class="row
|
2
|
-
|
3
|
-
<
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
<
|
10
|
-
<
|
11
|
-
<
|
12
|
-
<
|
13
|
-
|
14
|
-
<
|
15
|
-
|
16
|
-
<
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
</div>
|
39
|
-
|
40
|
-
</div>
|
41
|
-
</form>
|
42
|
-
</div>
|
1
|
+
<div class="row">
|
2
|
+
<div class="span6">
|
3
|
+
<form class="well" action="/builds/new" method="post">
|
4
|
+
<label>Project Name</label>
|
5
|
+
<input type="text" name="project" class="span3" value="<%= params[:project] %>" <%= "readonly" if params[:project] %>>
|
6
|
+
<label>Environment</label>
|
7
|
+
<input type="text" name="environment" class="span3" value="">
|
8
|
+
<span class="help-block">nb: Expects a valid json hash</span>
|
9
|
+
<label>Priority</label>
|
10
|
+
<input type="text" name="priority" class="span3" value="1">
|
11
|
+
<label>Command</label>
|
12
|
+
<textarea name="command" class="span3"></textarea>
|
13
|
+
<%# TODO -> When callbacks get implemented %>
|
14
|
+
<%# <label>Callback URL</label> %>
|
15
|
+
<%# <input type="text" name="callback" class="span3"> %>
|
16
|
+
<label><%# HACK %></label>
|
17
|
+
<button type="submit" class="btn">Submit</button>
|
18
|
+
</form>
|
19
|
+
</div>
|
20
|
+
<div class="span6">
|
21
|
+
<p>From here you can create a new build</p>
|
22
|
+
<p>Name is a unique identifier for the project. It doesn't need to already exist, but builds for a like project need to be named identically</p>
|
23
|
+
<p>Environment is a json hash of KEY - VALUE pairs, to be passed into the child environment</p>
|
24
|
+
<p>Command is where the magic happens. Often they'll be longwinded, but a reasonable boilerplate might look something like<p>
|
25
|
+
<pre class="prettyprint linenums">
|
26
|
+
if [ ! -d .git ]; then
|
27
|
+
git init .
|
28
|
+
git remote add origin git://github.com/$user/$project.git
|
29
|
+
fi
|
30
|
+
|
31
|
+
git fetch origin
|
32
|
+
git checkout -fq origin/master
|
33
|
+
|
34
|
+
bundle install --path .bundle
|
35
|
+
bundle exec rake spec
|
36
|
+
</pre>
|
37
|
+
</div>
|
43
38
|
</div>
|
@@ -1,4 +1,28 @@
|
|
1
|
-
|
2
|
-
<
|
3
|
-
|
4
|
-
|
1
|
+
<% if proj = ::Juici::Project.where(name: project).first %>
|
2
|
+
<h3><em><%= proj.name %></em> - <a href="/builds/new?project=<%= proj.name %>"><em>New Build</em></a></h3>
|
3
|
+
<% build =::Juici::Build.where(parent: proj.name, _id: id).first %>
|
4
|
+
<div class="accordion" id="accordion0">
|
5
|
+
<div class="accordion-heading">
|
6
|
+
<a class="accordion-toggle <%= build.heading_color %>" data-toggle="collapse" data-parent="#accordion0" href="#collapse_0">
|
7
|
+
<%= build.create_time %> <% build[:warnings].each do |warning| %><span class="label label-important"><%= warning %></span><% end %>
|
8
|
+
</a>
|
9
|
+
</div>
|
10
|
+
<div id="collapse_0" class="accordion-body collapse in">
|
11
|
+
<div class="row">
|
12
|
+
<div class="span8">
|
13
|
+
<div>
|
14
|
+
<a href="/builds/<%= proj.name %>/show/<%= build[:_id] %>">Link to this build</a>
|
15
|
+
</div>
|
16
|
+
<div class="accordion-inner build-output">
|
17
|
+
<%= build.output if build.respond_to? :output %>
|
18
|
+
</div>
|
19
|
+
</div>
|
20
|
+
<div class="span4">
|
21
|
+
<%= erb(:"partials/builds/debug", :locals => { :build => build }) %>
|
22
|
+
</div>
|
23
|
+
</div>
|
24
|
+
</div>
|
25
|
+
</div>
|
26
|
+
<% else %>
|
27
|
+
No such project.
|
28
|
+
<% end %>
|
data/lib/juici/views/index.erb
CHANGED
@@ -1,30 +1,13 @@
|
|
1
|
-
<
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
<li><a href="<%= build_url_for(p) %>"><%= p.name %></a></li>
|
15
|
-
<% end %>
|
16
|
-
</ul>
|
17
|
-
</div>
|
18
|
-
</div>
|
19
|
-
<div class="span4">
|
20
|
-
<h4 class="block-header builds-header">currently building</h4>
|
21
|
-
<ul class="builds">
|
22
|
-
<% $build_queue.currently_building.each do |build| %>
|
23
|
-
<li>
|
24
|
-
<a class="<%= build.heading_color %>" href="<%= build_url_for(build) %>"><%= build.link_title %></a>
|
25
|
-
</li>
|
26
|
-
<% end %>
|
27
|
-
</ul>
|
28
|
-
<%= erb(:"partials/index/recently_built") %>
|
29
|
-
</div>
|
30
|
-
</div>
|
1
|
+
<h1>JuiCI</h1>
|
2
|
+
<p>
|
3
|
+
JuiCI is a CI server, written at RailsCamp after Jenkins left me feeling a little dead inside. JuiCI aims to solve some of the issues with existing (and outstanding) CI solutions like <a href="http://jenkins-ci.org/">Jenkins</a> and <a href="http://travis-ci.org">Travis</a>, by not trying to be all things to all people.
|
4
|
+
</p>
|
5
|
+
<p>
|
6
|
+
JuiCI has a very thin wrapper around build triggers, is almost entirely API driven, and has a queuing system with a notion of priority, globally shared across all projects.
|
7
|
+
</p>
|
8
|
+
<p>
|
9
|
+
In the past, this instance of Juici has built code for:
|
10
|
+
<ul><% ::Juici::Project.all.each do |p| %>
|
11
|
+
<li><a href="<%= build_url_for(p) %>"><%= p.name %></a></li>
|
12
|
+
<% end %></ul>
|
13
|
+
</p>
|
data/lib/juici/views/layout.erb
CHANGED
@@ -1,43 +1,34 @@
|
|
1
1
|
<!doctype html>
|
2
2
|
<html>
|
3
3
|
<head>
|
4
|
-
<
|
5
|
-
<% if ::Juici.env == "development" %>
|
6
|
-
<link href="/vendor/bootstrap.css" rel="stylesheet">
|
7
|
-
<script src="/vendor/jquery.js"></script>
|
8
|
-
<script src="/vendor/bootstrap.js"></script>
|
9
|
-
<% else %>
|
10
|
-
<link href="//netdna.bootstrapcdn.com/twitter-bootstrap/2.2.1/css/bootstrap.min.css" rel="stylesheet">
|
11
|
-
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
|
12
|
-
<script src="//netdna.bootstrapcdn.com/twitter-bootstrap/2.2.1/js/bootstrap.min.js"></script>
|
13
|
-
<% end %>
|
4
|
+
<link href="//netdna.bootstrapcdn.com/twitter-bootstrap/2.1.1/css/bootstrap.min.css" rel="stylesheet">
|
14
5
|
<link href="/styles/juici.css" rel="stylesheet">
|
15
|
-
<%
|
16
|
-
<link href="/styles/<%=
|
17
|
-
<% end
|
6
|
+
<% if @page # This will 404 a ton of page XXX %>
|
7
|
+
<link href="/styles/<%= @page %>.css" rel="stylesheet">
|
8
|
+
<% end %>
|
9
|
+
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
|
10
|
+
<script src="//netdna.bootstrapcdn.com/twitter-bootstrap/2.1.1/js/bootstrap.min.js"></script>
|
18
11
|
<title>JuiCI</title>
|
19
12
|
<% if @redirect_to %>
|
20
|
-
<meta http-equiv="Refresh" content="0; url=<%= @redirect_to %>" />
|
13
|
+
<meta http-equiv="Refresh" content="0; url=<%= URI.escape(@redirect_to) %>" />
|
21
14
|
<% end %>
|
22
15
|
</head>
|
23
16
|
<body>
|
24
17
|
<div class="navbar navbar-fixed-top">
|
25
18
|
<div class="navbar-inner">
|
26
|
-
<div class="container
|
19
|
+
<div class="container">
|
27
20
|
<div class="nav-collapse">
|
28
21
|
<ul class="nav">
|
29
|
-
|
30
|
-
<li class="
|
31
|
-
<li class="<%= "active" if
|
32
|
-
<li class="<%= "active" if
|
33
|
-
<li class="<%= "active" if active == :support %>"><a href="/support">Support</a></li>
|
34
|
-
<li class="<%= "active" if active == :queue %>"><a href="/queue">Build Queue</a></li>
|
22
|
+
<li class="<%= "active" if @page == :index %>"><a class="brand" href="/">JuiCI</a></li>
|
23
|
+
<li class="<%= "active" if @page == :builds && @action == :new %>"><a href="/builds/new">New Build</a></li>
|
24
|
+
<li class="<%= "active" if @page == :about %>"><a href="/about">About</a></li>
|
25
|
+
<li class="<%= "active" if @page == :support %>"><a href="/support">Support</a></li>
|
35
26
|
</ul>
|
36
27
|
</div><!--/.nav-collapse -->
|
37
28
|
</div>
|
38
29
|
</div>
|
39
30
|
</div>
|
40
|
-
<div class="container
|
31
|
+
<div class="container">
|
41
32
|
<%= yield %>
|
42
33
|
</div>
|
43
34
|
</body>
|
@@ -1,22 +1,28 @@
|
|
1
|
-
|
1
|
+
<% if build[:environment] %>
|
2
|
+
<h3>Environment:</h3>
|
3
|
+
<pre class="prettyprint">
|
4
|
+
<% build[:environment].each do |k, v| %>
|
5
|
+
<%= "#{k}=#{v}" %>
|
6
|
+
<% end %>
|
7
|
+
</pre>
|
8
|
+
<% end %>
|
2
9
|
<% if build[:priority] %>
|
3
|
-
<h3
|
10
|
+
<h3>Priority:</h3>
|
11
|
+
<pre class="prettyprint">
|
4
12
|
<%= build[:priority] %>
|
13
|
+
</pre>
|
5
14
|
<% end %>
|
6
15
|
<% if build[:command] %>
|
7
|
-
<h3
|
16
|
+
<h3>Command:</h3>
|
17
|
+
<pre class="prettyprint">
|
8
18
|
<%= build[:command] %>
|
9
|
-
|
10
|
-
<% if build[:environment] %>
|
11
|
-
<h3 class="block-header">environment:</h3>
|
12
|
-
<% build[:environment].reject{|k, v| v.nil?}.each do |k, v| %>
|
13
|
-
<p><strong><%="#{k} = " %></strong><%="#{v}" %></p>
|
14
|
-
<% end %>
|
19
|
+
</pre>
|
15
20
|
<% end %>
|
16
21
|
<% if build[:callbacks] %>
|
17
|
-
<h3
|
22
|
+
<h3>Callbacks:</h3>
|
23
|
+
<pre class="prettyprint">
|
18
24
|
<% build[:callbacks].each do |callback| %>
|
19
|
-
|
25
|
+
<%= callback %>
|
20
26
|
<% end %>
|
27
|
+
</pre>
|
21
28
|
<% end %>
|
22
|
-
</div>
|
data/lib/juici/watcher.rb
CHANGED
@@ -1,47 +1,39 @@
|
|
1
1
|
module Juici
|
2
|
-
class Watcher
|
2
|
+
class Watcher < Thread
|
3
3
|
|
4
|
-
def self.
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
def initialize
|
9
|
-
@active = true
|
4
|
+
def self.start!
|
5
|
+
new do
|
6
|
+
self.mainloop
|
7
|
+
end
|
10
8
|
end
|
11
9
|
|
12
|
-
def
|
13
|
-
|
10
|
+
def self.mainloop
|
11
|
+
#XXX No classvariables ever!
|
12
|
+
loop do
|
14
13
|
begin
|
15
|
-
|
16
|
-
pid, status = Process.wait2(-1)
|
17
|
-
$build_queue.purge(:pid, OpenStruct.new(:pid => pid))
|
18
|
-
::Juici.dbgp "Trying to find pid: #{pid}"
|
19
|
-
handle(pid, status)
|
20
|
-
end
|
14
|
+
pid, status = catch_child
|
21
15
|
rescue Errno::ECHILD
|
22
|
-
|
16
|
+
# No children available, sleep for a while until some might exist
|
17
|
+
# TODO: It'd be a nice optimisation to actually die here, and
|
18
|
+
# optionally start a worker if we're the first child
|
19
|
+
sleep 5
|
20
|
+
next
|
23
21
|
end
|
24
|
-
|
25
|
-
|
26
|
-
end
|
22
|
+
next unless pid
|
23
|
+
build = $build_queue.get_build_by_pid(pid)
|
27
24
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
build.failure!
|
25
|
+
if status == 0
|
26
|
+
build.success!
|
27
|
+
else
|
28
|
+
build.failure!
|
29
|
+
end
|
30
|
+
$build_queue.bump! if $build_queue
|
35
31
|
end
|
36
|
-
$build_queue.bump! if $build_queue
|
37
|
-
end
|
38
|
-
|
39
|
-
def shutdown!
|
40
|
-
@active = false
|
41
32
|
end
|
42
33
|
|
43
|
-
|
44
|
-
|
34
|
+
# Hook for testing
|
35
|
+
def self.catch_child
|
36
|
+
Process.wait2(-1, Process::WNOHANG)
|
45
37
|
end
|
46
38
|
|
47
39
|
end
|