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
data/lib/juici/config.rb
CHANGED
File without changes
|
@@ -1,31 +1,15 @@
|
|
1
|
-
module Juici
|
2
|
-
class
|
1
|
+
module Juici
|
2
|
+
class TriggerController
|
3
3
|
|
4
4
|
attr_reader :project, :params
|
5
5
|
def initialize(project, params)
|
6
|
-
@project =
|
6
|
+
@project = Project.find_or_create_by(name: project)
|
7
7
|
@params = params
|
8
8
|
end
|
9
9
|
|
10
|
-
# Find an existing build, duplicate the sane parts of it.
|
11
|
-
def rebuild!
|
12
|
-
unless project = ::Juici::Project.where(name: params[:project]).first
|
13
|
-
not_found
|
14
|
-
end
|
15
|
-
unless build = ::Juici::Build.where(parent: project.name, _id: params[:id]).first
|
16
|
-
not_found
|
17
|
-
end
|
18
|
-
|
19
|
-
::Juici::Build.new_from(build).tap do |new_build|
|
20
|
-
new_build.save!
|
21
|
-
$build_queue << new_build
|
22
|
-
$build_queue.bump!
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
10
|
def build!
|
27
|
-
environment =
|
28
|
-
|
11
|
+
environment = BuildEnvironment.new
|
12
|
+
Build.new(parent: project.name).tap do |build|
|
29
13
|
# The seperation of concerns around this madness is horrifying
|
30
14
|
unless environment.load_json!(params['environment'])
|
31
15
|
build.warn!("Failed to parse environment")
|
@@ -52,9 +36,6 @@ module Juici::Controllers
|
|
52
36
|
# TODO Throw 422 not acceptable if missing
|
53
37
|
params['command'].tap do |c|
|
54
38
|
raise "No command given" if c.nil?
|
55
|
-
# TODO Detect that we've recieved this from a browser session and only
|
56
|
-
# do this replacement there, we can trust API supplied data.
|
57
|
-
c.gsub!(/\r\n/, "\n")
|
58
39
|
end
|
59
40
|
end
|
60
41
|
|
data/lib/juici/database.rb
CHANGED
@@ -1,25 +1,19 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
path = File.join("config", file)
|
8
|
-
return path if File.exist?(path)
|
9
|
-
end
|
10
|
-
raise "No database config file"
|
1
|
+
class Juici::Database
|
2
|
+
class << self
|
3
|
+
def mongoid_config_file
|
4
|
+
%w[mongoid.yml mongoid.yml.sample].each do |file|
|
5
|
+
path = File.join("config", file)
|
6
|
+
return path if File.exist?(path)
|
11
7
|
end
|
8
|
+
raise "No database config file"
|
9
|
+
end
|
12
10
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
end
|
17
|
-
if ENV['RACK_ENV'] == "development"
|
18
|
-
Mongoid.logger.level = Logger::INFO
|
19
|
-
end
|
20
|
-
|
21
|
-
Mongoid.load!(mongoid_config_file)
|
11
|
+
def initialize!
|
12
|
+
if ENV['RACK_ENV'] == "development"
|
13
|
+
Mongoid.logger.level = Logger::INFO
|
22
14
|
end
|
15
|
+
|
16
|
+
Mongoid.load!(mongoid_config_file)
|
23
17
|
end
|
24
18
|
end
|
25
19
|
end
|
@@ -8,31 +8,3 @@ def build_url_for(entity)
|
|
8
8
|
"/builds/#{entity[:parent]}/show/#{entity[:_id]}"
|
9
9
|
end
|
10
10
|
end
|
11
|
-
|
12
|
-
def rebuild_url_for(entity)
|
13
|
-
URI.escape case entity
|
14
|
-
when ::Juici::Build
|
15
|
-
"/builds/#{entity[:parent]}/rebuild/#{entity[:_id]}"
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
def kill_url_for(entity)
|
20
|
-
URI.escape case entity
|
21
|
-
when ::Juici::Build
|
22
|
-
"/builds/kill"
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
def cancel_url_for(entity)
|
27
|
-
URI.escape case entity
|
28
|
-
when ::Juici::Build
|
29
|
-
"/builds/cancel"
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
def edit_url_for(entity)
|
34
|
-
URI.escape case entity
|
35
|
-
when ::Juici::Build
|
36
|
-
"/builds/#{entity[:parent]}/edit/#{entity[:_id]}"
|
37
|
-
end
|
38
|
-
end
|
data/lib/juici/models/build.rb
CHANGED
@@ -1,43 +1,29 @@
|
|
1
1
|
require 'json'
|
2
|
-
|
2
|
+
# status enum
|
3
|
+
# :waiting
|
4
|
+
# :started
|
5
|
+
# :failed
|
6
|
+
# :success
|
7
|
+
#
|
8
|
+
# ???
|
9
|
+
# :profit!
|
10
|
+
#
|
3
11
|
module Juici
|
4
12
|
class Build
|
5
13
|
# A wrapper around the build process
|
6
14
|
|
7
15
|
include Mongoid::Document
|
16
|
+
include ::Juici.url_helpers("builds")
|
8
17
|
include BuildLogic
|
9
|
-
include BuildStatus
|
10
|
-
extend FindLogic
|
11
18
|
# TODO Builds should probably be children of projects in the URL?
|
12
19
|
|
13
|
-
# Finder classmethods
|
14
|
-
def self.get_recent(n, opts={})
|
15
|
-
self.where(opts).
|
16
|
-
limit(n).
|
17
|
-
desc(:_id)
|
18
|
-
end
|
19
|
-
|
20
|
-
CLONABLE_FIELDS = [:command, :priority, :environment, :callbacks, :title, :parent]
|
21
|
-
EDITABLE_ATTRIBUTES = {
|
22
|
-
:string => [:priority, :title],
|
23
|
-
:array => [:environment, :callbacks]
|
24
|
-
}
|
25
|
-
|
26
|
-
def self.new_from(other)
|
27
|
-
new.tap do |b|
|
28
|
-
CLONABLE_FIELDS.each do |prop|
|
29
|
-
b[prop] = other[prop]
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
20
|
field :parent, type: String
|
35
21
|
field :command, type: String
|
36
22
|
field :environment, type: Hash
|
37
23
|
field :create_time, type: Time, :default => Proc.new { Time.now }
|
38
24
|
field :start_time, type: Time, :default => nil
|
39
25
|
field :end_time, type: Time, :default => nil
|
40
|
-
field :status, type: Symbol, :default =>
|
26
|
+
field :status, type: Symbol, :default => :waiting
|
41
27
|
field :priority, type: Fixnum, :default => 1
|
42
28
|
field :pid, type: Fixnum
|
43
29
|
field :buffer, type: String
|
@@ -46,43 +32,37 @@ module Juici
|
|
46
32
|
field :title, type: String, :default => Proc.new { Time.now.to_s }
|
47
33
|
|
48
34
|
def set_status(value)
|
49
|
-
self
|
35
|
+
self[:status] = value
|
50
36
|
save!
|
51
37
|
end
|
52
38
|
|
53
39
|
def start!
|
54
40
|
self[:start_time] = Time.now
|
55
|
-
set_status
|
41
|
+
set_status :started
|
56
42
|
end
|
57
43
|
|
58
44
|
def success!
|
59
45
|
finish
|
60
|
-
set_status
|
46
|
+
set_status :success
|
61
47
|
process_callbacks
|
62
48
|
end
|
63
49
|
|
64
50
|
def failure!
|
65
51
|
finish
|
66
|
-
set_status
|
52
|
+
set_status :failed
|
67
53
|
process_callbacks
|
68
54
|
end
|
69
55
|
|
70
56
|
def finish
|
71
57
|
self[:end_time] = Time.now
|
72
58
|
self[:output] = get_output
|
73
|
-
$build_queue.purge(:pid, self)
|
74
|
-
end
|
75
|
-
|
76
|
-
def cancel
|
77
|
-
warn! "Cancelled"
|
78
|
-
set_status FAIL
|
79
|
-
$build_queue.delete(self[:_id]) if $build_queue
|
59
|
+
$build_queue.purge(:pid, self)
|
80
60
|
end
|
81
61
|
|
82
62
|
def build!
|
83
|
-
start!
|
84
63
|
case pid = spawn_build
|
85
64
|
when Fixnum
|
65
|
+
start!
|
86
66
|
Juici.dbgp "#{pid} away!"
|
87
67
|
self[:pid] = pid
|
88
68
|
self[:buffer] = @buffer.path
|
@@ -100,22 +80,18 @@ module Juici
|
|
100
80
|
|
101
81
|
def worktree
|
102
82
|
File.join(Config.workspace, parent)
|
103
|
-
rescue TypeError => e
|
104
|
-
warn! "Invalid workdir"
|
105
|
-
failure!
|
106
|
-
raise AbortBuild
|
107
83
|
end
|
108
84
|
|
109
85
|
# View helpers
|
110
86
|
def heading_color
|
111
87
|
case status
|
112
|
-
when
|
88
|
+
when :waiting
|
113
89
|
"build-heading-pending"
|
114
|
-
when
|
90
|
+
when :failed
|
115
91
|
"build-heading-failed"
|
116
|
-
when
|
92
|
+
when :success
|
117
93
|
"build-heading-success"
|
118
|
-
when
|
94
|
+
when :started
|
119
95
|
"build-heading-started"
|
120
96
|
end
|
121
97
|
end
|
@@ -133,20 +109,14 @@ module Juici
|
|
133
109
|
self[:title] || self[:create_time]
|
134
110
|
end
|
135
111
|
|
136
|
-
def link_title
|
137
|
-
"#{self[:parent]}/#{display_title}"
|
138
|
-
end
|
139
|
-
|
140
112
|
def warn!(msg)
|
141
113
|
warnings << msg
|
142
114
|
save!
|
143
115
|
end
|
144
116
|
|
145
117
|
def process_callbacks
|
146
|
-
callbacks.each do |callback_url|
|
147
|
-
|
148
|
-
c.payload = self.to_callback_json
|
149
|
-
c.process!
|
118
|
+
self[:callbacks].each do |callback_url|
|
119
|
+
Callback.new(self, callback_url).process!
|
150
120
|
end
|
151
121
|
end
|
152
122
|
|
@@ -155,36 +125,9 @@ module Juici
|
|
155
125
|
{
|
156
126
|
"project" => self[:parent],
|
157
127
|
"status" => self[:status],
|
158
|
-
"url" => build_url_for(self)
|
159
|
-
"time" => time_elapsed
|
128
|
+
"url" => build_url_for(self)
|
160
129
|
}.to_json
|
161
130
|
end
|
162
131
|
|
163
|
-
def callbacks
|
164
|
-
self[:callbacks] || []
|
165
|
-
end
|
166
|
-
|
167
|
-
def time_elapsed
|
168
|
-
if self[:end_time]
|
169
|
-
self[:end_time] - self[:start_time]
|
170
|
-
elsif self[:start_time]
|
171
|
-
Time.now - self[:start_time]
|
172
|
-
else
|
173
|
-
nil
|
174
|
-
end
|
175
|
-
rescue
|
176
|
-
-1 # Throw an obviously impossible build time.
|
177
|
-
# This will only occur as a result of old builds.
|
178
|
-
end
|
179
|
-
|
180
|
-
# Use symbols internally
|
181
|
-
def status
|
182
|
-
self[:status].to_s
|
183
|
-
end
|
184
|
-
|
185
|
-
def status=(s)
|
186
|
-
self[:status] = s.to_sym
|
187
|
-
end
|
188
|
-
|
189
132
|
end
|
190
133
|
end
|
data/lib/juici/models/project.rb
CHANGED
data/lib/juici/server.rb
CHANGED
@@ -11,8 +11,6 @@ module Juici
|
|
11
11
|
end
|
12
12
|
|
13
13
|
helpers do
|
14
|
-
include Ansible
|
15
|
-
|
16
14
|
Dir[File.dirname(__FILE__) + "/helpers/**/*.rb"].each do |file|
|
17
15
|
load file
|
18
16
|
end
|
@@ -21,16 +19,9 @@ module Juici
|
|
21
19
|
dir = File.dirname(File.expand_path(__FILE__))
|
22
20
|
|
23
21
|
def self.start(host, port)
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
trap(sig) do
|
28
|
-
$stderr.puts "Shutting down JuiCI"
|
29
|
-
App.shutdown
|
30
|
-
server.respond_to?(:stop!) ? server.stop! : server.stop
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
22
|
+
Database.initialize!
|
23
|
+
@@juici = App.new
|
24
|
+
Juici::Server.run! :host => host, :port => port
|
34
25
|
end
|
35
26
|
|
36
27
|
def self.rack_start(project_path)
|
@@ -42,130 +33,76 @@ module Juici
|
|
42
33
|
set :static, true
|
43
34
|
|
44
35
|
get '/' do
|
45
|
-
|
46
|
-
|
47
|
-
end
|
36
|
+
@page = :index
|
37
|
+
erb(:index, {}, :juici => juici)
|
48
38
|
end
|
49
39
|
|
50
40
|
get '/about' do
|
51
|
-
|
52
|
-
|
53
|
-
|
41
|
+
@page = :about
|
42
|
+
@action = :show
|
43
|
+
erb(:about)
|
54
44
|
end
|
55
45
|
|
56
46
|
get '/builds' do
|
57
|
-
|
58
|
-
|
59
|
-
|
47
|
+
@page = :builds
|
48
|
+
@action = :list
|
49
|
+
erb(:builds, {}, :juici => juici)
|
60
50
|
end
|
61
51
|
|
62
|
-
get '/
|
63
|
-
|
64
|
-
|
65
|
-
|
52
|
+
get '/builds/new' do
|
53
|
+
@page = :builds
|
54
|
+
@action = :new
|
55
|
+
erb(:"builds/new", :juici => juici)
|
66
56
|
end
|
67
57
|
|
68
58
|
post '/builds/new' do
|
69
|
-
|
70
|
-
@redirect_to = build_url_for(
|
71
|
-
erb(:redirect, {},
|
72
|
-
end
|
73
|
-
|
74
|
-
post '/builds/:project/rebuild/:id' do
|
75
|
-
build = Controllers::Trigger.new(params[:project], params).rebuild!
|
76
|
-
@redirect_to = build_url_for(build)
|
77
|
-
erb(:redirect, {}, {})
|
78
|
-
end
|
79
|
-
|
80
|
-
post '/builds/:user/:project/rebuild/:id' do
|
81
|
-
params[:project] = "#{params[:user]}/#{params[:project]}"
|
82
|
-
build = Controllers::Trigger.new(params[:project], params).rebuild!
|
83
|
-
@redirect_to = build_url_for(build)
|
84
|
-
erb(:redirect, {}, {})
|
59
|
+
TriggerController.new(params[:project], params).build!
|
60
|
+
@redirect_to = build_url_for(params[:project])
|
61
|
+
erb(:redirect, {}, :juici => juici)
|
85
62
|
end
|
86
63
|
|
87
|
-
|
88
|
-
|
89
|
-
@redirect_to = build_url_for(build)
|
90
|
-
erb(:redirect, {}, {})
|
91
|
-
end
|
92
|
-
|
93
|
-
post '/builds/cancel' do
|
94
|
-
build = Controllers::Builds.new(params).cancel
|
95
|
-
@redirect_to = build_url_for(build)
|
96
|
-
erb(:redirect, {}, {})
|
97
|
-
end
|
98
|
-
|
99
|
-
get ::Juici::Routes::NEW_BUILD do
|
100
|
-
Controllers::Builds.new(params).new do |template, opts|
|
101
|
-
erb(template, {}, opts)
|
102
|
-
end
|
64
|
+
def list_builds(params)
|
65
|
+
erb(:"builds/list", {}, :juici => juici, :project => params[:project])
|
103
66
|
end
|
104
67
|
|
105
68
|
get '/builds/:project/list' do
|
106
|
-
|
107
|
-
|
108
|
-
|
69
|
+
@page = :builds
|
70
|
+
@action = :list
|
71
|
+
list_builds(params)
|
109
72
|
end
|
110
73
|
|
111
74
|
get '/builds/:user/:project/list' do
|
75
|
+
@page = :builds
|
76
|
+
@action = :list
|
112
77
|
params[:project] = "#{params[:user]}/#{params[:project]}"
|
113
|
-
|
114
|
-
erb(template, {}, opts)
|
115
|
-
end
|
116
|
-
end
|
117
|
-
|
118
|
-
get '/builds/:project/edit/:id' do
|
119
|
-
Controllers::Builds.new(params).edit do |template, opts|
|
120
|
-
erb(template, {}, opts)
|
121
|
-
end
|
122
|
-
end
|
123
|
-
|
124
|
-
get '/builds/:user/:project/edit/:id' do
|
125
|
-
params[:project] = "#{params[:user]}/#{params[:project]}"
|
126
|
-
Controllers::Builds.new(params).edit do |template, opts|
|
127
|
-
erb(template, {}, opts)
|
128
|
-
end
|
129
|
-
end
|
130
|
-
|
131
|
-
post '/builds/:project/edit/:id' do
|
132
|
-
build = Controllers::Builds.new(params).update!
|
133
|
-
@redirect_to = build_url_for(build)
|
134
|
-
erb(:redirect, {}, {})
|
78
|
+
list_builds(params)
|
135
79
|
end
|
136
80
|
|
137
|
-
|
138
|
-
|
139
|
-
build = Controllers::Builds.new(params).update!
|
140
|
-
@redirect_to = build_url_for(build)
|
141
|
-
erb(:redirect, {}, {})
|
81
|
+
def show_build(params)
|
82
|
+
erb(:"builds/show", {}, :juici => juici, :project => params[:project], :id => params[:id])
|
142
83
|
end
|
143
84
|
|
144
85
|
get '/builds/:project/show/:id' do
|
145
|
-
|
146
|
-
|
147
|
-
|
86
|
+
@page = :builds
|
87
|
+
@action = :show
|
88
|
+
show_build(params)
|
148
89
|
end
|
149
90
|
|
150
91
|
get '/builds/:user/:project/show/:id' do
|
92
|
+
@page = :builds
|
93
|
+
@action = :show
|
151
94
|
params[:project] = "#{params[:user]}/#{params[:project]}"
|
152
|
-
|
153
|
-
erb(template, {}, opts)
|
154
|
-
end
|
95
|
+
show_build(params)
|
155
96
|
end
|
156
97
|
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
get '/queue' do
|
162
|
-
Controllers::BuildQueue.new(params).list do |template, opts|
|
163
|
-
erb(template, {}, opts)
|
164
|
-
end
|
98
|
+
get '/support' do
|
99
|
+
@page = :support
|
100
|
+
@action = :show
|
101
|
+
erb(:"support", {})
|
165
102
|
end
|
166
103
|
|
167
|
-
|
168
|
-
|
104
|
+
post '/trigger/:project' do
|
105
|
+
TriggerController.new(params[:project], params).build!
|
169
106
|
end
|
170
107
|
|
171
108
|
end
|