magi 0.0.6 → 0.0.7
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.
- checksums.yaml +4 -4
- data/Gemfile +7 -0
- data/README.md +0 -2
- data/app/controllers/builds_controller.rb +1 -1
- data/app/models/build.rb +1 -1
- data/app/models/job.rb +56 -22
- data/app/workers/job_enqueue_worker.rb +1 -1
- data/lib/magi/command.rb +10 -2
- data/lib/magi/plugin_manager.rb +13 -5
- data/lib/magi/proprietary.rb +20 -9
- data/lib/magi/version.rb +1 -1
- data/lib/magi/workspace.rb +26 -0
- data/lib/magi.rb +15 -2
- data/magi.gemspec +1 -1
- data/plugins/git/git.rb +84 -0
- data/script/clock.rb +1 -1
- data/spec/models/job_spec.rb +13 -11
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2db7f5dff13d75dd26fc1c8440bbb8cb68b51c92
|
4
|
+
data.tar.gz: 10ca4a6e4a4619df58bbc5a2f3c741c113cbf629
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a637eed71179f9ccda64cc6185d439f3ee432413da2e8448bd48b38bbe4e733191312368c934634316ba85d3128c390109af6eaa161a1646d7371b68f1c22aa4
|
7
|
+
data.tar.gz: 705a9126445b1f52b78b957718e3484937366b5d03f69c8dc7f5e316d1db4add2fc86ca4eca850a6acf1606738c9ca7c221acdc3100dbd51c6c0e232d08bfcda
|
data/Gemfile
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require "pathname"
|
2
|
+
|
1
3
|
source "https://rubygems.org"
|
2
4
|
|
3
5
|
gemspec
|
@@ -27,3 +29,8 @@ group :assets do
|
|
27
29
|
gem "coffee-rails", "~> 3.2.1"
|
28
30
|
gem "uglifier", ">= 1.0.3"
|
29
31
|
end
|
32
|
+
|
33
|
+
# Put Gemfile in plugins/:name/Gemfile to use arbitrary gems in your plugin.
|
34
|
+
Pathname.glob("plugins/*/Gemfile").each do |pathname|
|
35
|
+
eval(pathname.read)
|
36
|
+
end
|
data/README.md
CHANGED
data/app/models/build.rb
CHANGED
data/app/models/job.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
class Job < ActiveRecord::Base
|
2
|
-
|
2
|
+
include Magi::Proprietary
|
3
3
|
|
4
4
|
attr_accessible :name, :properties
|
5
5
|
|
@@ -20,24 +20,40 @@ class Job < ActiveRecord::Base
|
|
20
20
|
new.update_attributes_with_properties(params)
|
21
21
|
end
|
22
22
|
|
23
|
-
def
|
24
|
-
select(&:scheduled?)
|
23
|
+
def scheduled
|
24
|
+
select(&:scheduled?)
|
25
25
|
end
|
26
26
|
|
27
|
-
def
|
28
|
-
|
27
|
+
def before_enqueue(&block)
|
28
|
+
before_enqueues << block
|
29
29
|
end
|
30
30
|
|
31
|
-
def
|
32
|
-
@
|
31
|
+
def before_enqueues
|
32
|
+
@before_enqueues ||= []
|
33
33
|
end
|
34
34
|
|
35
|
-
def
|
36
|
-
|
35
|
+
def after_enqueue(&block)
|
36
|
+
after_enqueues << block
|
37
37
|
end
|
38
38
|
|
39
|
-
def
|
40
|
-
@
|
39
|
+
def after_enqueues
|
40
|
+
@after_enqueues ||= []
|
41
|
+
end
|
42
|
+
|
43
|
+
def before_execute(&block)
|
44
|
+
before_executes << block
|
45
|
+
end
|
46
|
+
|
47
|
+
def before_executes
|
48
|
+
@before_executes ||= []
|
49
|
+
end
|
50
|
+
|
51
|
+
def after_execute(&block)
|
52
|
+
after_executes << block
|
53
|
+
end
|
54
|
+
|
55
|
+
def after_executes
|
56
|
+
@after_executes ||= []
|
41
57
|
end
|
42
58
|
end
|
43
59
|
|
@@ -59,9 +75,19 @@ class Job < ActiveRecord::Base
|
|
59
75
|
builds.create.tap(&:enqueue)
|
60
76
|
end
|
61
77
|
|
62
|
-
def
|
63
|
-
|
78
|
+
def enqueue_with_before_enqueues
|
79
|
+
if self.class.before_enqueues.all? {|hook| instance_exec(&hook) != false }
|
80
|
+
enqueue_without_before_enqueues
|
81
|
+
end
|
64
82
|
end
|
83
|
+
alias_method_chain :enqueue, :before_enqueues
|
84
|
+
|
85
|
+
def enqueue_with_after_enqueues
|
86
|
+
enqueue_without_after_enqueues.tap do
|
87
|
+
self.class.after_enqueues.all? {|hook| instance_exec(&hook) != false }
|
88
|
+
end
|
89
|
+
end
|
90
|
+
alias_method_chain :enqueue, :after_enqueues
|
65
91
|
|
66
92
|
def status_name
|
67
93
|
last_finished_build.try(:status_name) || "unfinished"
|
@@ -82,24 +108,32 @@ class Job < ActiveRecord::Base
|
|
82
108
|
tap(&:save)
|
83
109
|
end
|
84
110
|
|
111
|
+
def workspace
|
112
|
+
@workspace ||= Magi::Workspace.new(workspace_path)
|
113
|
+
end
|
114
|
+
|
85
115
|
private
|
86
116
|
|
87
|
-
def
|
88
|
-
Magi
|
117
|
+
def workspace_path
|
118
|
+
Magi.workspace.path + "jobs/#{id}"
|
89
119
|
end
|
90
120
|
|
91
|
-
def
|
92
|
-
|
121
|
+
def execute
|
122
|
+
workspace.chdir { Magi::Executer.execute(script) }
|
93
123
|
end
|
94
|
-
alias_method_chain :execute, :after_hooks
|
95
124
|
|
96
|
-
def
|
97
|
-
self.class.
|
125
|
+
def execute_with_before_executes
|
126
|
+
self.class.before_executes.all? {|hook| instance_exec(&hook) != false }
|
127
|
+
execute_without_before_executes
|
98
128
|
end
|
129
|
+
alias_method_chain :execute, :before_executes
|
99
130
|
|
100
|
-
def
|
101
|
-
|
131
|
+
def execute_with_after_executes
|
132
|
+
execute_without_after_executes.tap do
|
133
|
+
self.class.after_executes.all? {|hook| instance_exec(&hook) != false }
|
134
|
+
end
|
102
135
|
end
|
136
|
+
alias_method_chain :execute, :after_executes
|
103
137
|
|
104
138
|
def raise_script_not_found
|
105
139
|
raise ScriptNotFound, 'You must set properties["script"]'
|
data/lib/magi/command.rb
CHANGED
@@ -8,7 +8,7 @@
|
|
8
8
|
# # Invokes "setup" command to set up your database.
|
9
9
|
# Magi::Command.call(["setup"])
|
10
10
|
#
|
11
|
-
# # Invokes "start" command to start
|
11
|
+
# # Invokes "start" command to start the processes.
|
12
12
|
# Magi::Command.call(["start"])
|
13
13
|
#
|
14
14
|
module Magi
|
@@ -43,11 +43,19 @@ module Magi
|
|
43
43
|
end
|
44
44
|
|
45
45
|
def start
|
46
|
-
system("cd #{root_path} && foreman start")
|
46
|
+
system(env, "cd #{root_path} && foreman start")
|
47
47
|
end
|
48
48
|
|
49
49
|
def root_path
|
50
50
|
File.expand_path("../../..", __FILE__)
|
51
51
|
end
|
52
|
+
|
53
|
+
def workspace_path
|
54
|
+
Dir.pwd
|
55
|
+
end
|
56
|
+
|
57
|
+
def env
|
58
|
+
{ "WORKSPACE_PATH" => workspace_path }
|
59
|
+
end
|
52
60
|
end
|
53
61
|
end
|
data/lib/magi/plugin_manager.rb
CHANGED
@@ -1,13 +1,21 @@
|
|
1
1
|
module Magi
|
2
2
|
class PluginManager
|
3
|
-
def
|
4
|
-
|
3
|
+
def plugins_directories
|
4
|
+
[Rails.root + "plugins", Pathname.pwd + "plugins"].uniq
|
5
5
|
end
|
6
6
|
|
7
7
|
def load_plugins
|
8
|
-
|
9
|
-
|
10
|
-
|
8
|
+
plugin_filepaths.each {|path| require path }
|
9
|
+
end
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def plugin_filepaths
|
14
|
+
Dir.glob("#{plugins_directories_pattern}/*/*.rb").sort
|
15
|
+
end
|
16
|
+
|
17
|
+
def plugins_directories_pattern
|
18
|
+
plugins_directories.join(",")
|
11
19
|
end
|
12
20
|
end
|
13
21
|
end
|
data/lib/magi/proprietary.rb
CHANGED
@@ -1,19 +1,30 @@
|
|
1
1
|
module Magi
|
2
2
|
module Proprietary
|
3
|
-
|
4
|
-
properties << name
|
3
|
+
extend ActiveSupport::Concern
|
5
4
|
|
6
|
-
|
7
|
-
|
5
|
+
def update_properties(properties)
|
6
|
+
properties.each do |key, value|
|
7
|
+
send("#{key}=", value)
|
8
8
|
end
|
9
|
+
save
|
10
|
+
end
|
11
|
+
|
12
|
+
module ClassMethods
|
13
|
+
def property(name)
|
14
|
+
properties << name
|
15
|
+
|
16
|
+
define_method(name) do
|
17
|
+
properties[name.to_s]
|
18
|
+
end
|
9
19
|
|
10
|
-
|
11
|
-
|
20
|
+
define_method("#{name}=") do |value|
|
21
|
+
properties[name.to_s] = value
|
22
|
+
end
|
12
23
|
end
|
13
|
-
end
|
14
24
|
|
15
|
-
|
16
|
-
|
25
|
+
def properties
|
26
|
+
@properties ||= []
|
27
|
+
end
|
17
28
|
end
|
18
29
|
end
|
19
30
|
end
|
data/lib/magi/version.rb
CHANGED
@@ -0,0 +1,26 @@
|
|
1
|
+
module Magi
|
2
|
+
class Workspace
|
3
|
+
attr_reader :path
|
4
|
+
|
5
|
+
def initialize(path)
|
6
|
+
@path = Pathname.new(path)
|
7
|
+
end
|
8
|
+
|
9
|
+
def chdir
|
10
|
+
mkpath_unless_exist
|
11
|
+
Dir.chdir(path) { yield }
|
12
|
+
end
|
13
|
+
|
14
|
+
def mkpath_unless_exist
|
15
|
+
mkpath unless exist?
|
16
|
+
end
|
17
|
+
|
18
|
+
def mkpath
|
19
|
+
path.mkpath
|
20
|
+
end
|
21
|
+
|
22
|
+
def exist?
|
23
|
+
path.exist?
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/lib/magi.rb
CHANGED
@@ -1,9 +1,22 @@
|
|
1
1
|
require "magi/command"
|
2
2
|
require "magi/plugin_manager"
|
3
3
|
require "magi/version"
|
4
|
+
require "magi/workspace"
|
4
5
|
|
5
6
|
module Magi
|
6
|
-
|
7
|
-
|
7
|
+
class << self
|
8
|
+
def workspace
|
9
|
+
@workspace ||= Magi::Workspace.new(workspace_path)
|
10
|
+
end
|
11
|
+
|
12
|
+
def plugin_manager
|
13
|
+
@plugin_manager ||= Magi::PluginManager.new
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def workspace_path
|
19
|
+
ENV["WORKSPACE_PATH"] || "."
|
20
|
+
end
|
8
21
|
end
|
9
22
|
end
|
data/magi.gemspec
CHANGED
@@ -12,7 +12,7 @@ Gem::Specification.new do |spec|
|
|
12
12
|
spec.homepage = "https://github.com/r7kamura/magi"
|
13
13
|
spec.license = "MIT"
|
14
14
|
|
15
|
-
spec.files = Dir["{app,bin,config,db,lib,public,script,spec}/**/*"]
|
15
|
+
spec.files = Dir["{app,bin,config,db,lib,plugins,public,script,spec}/**/*"]
|
16
16
|
spec.files += %w[
|
17
17
|
Gemfile
|
18
18
|
LICENSE.txt
|
data/plugins/git/git.rb
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
require "open3"
|
2
|
+
|
3
|
+
module Magi
|
4
|
+
class Repository
|
5
|
+
attr_reader :job
|
6
|
+
|
7
|
+
def initialize(job)
|
8
|
+
@job = job
|
9
|
+
end
|
10
|
+
|
11
|
+
def clone
|
12
|
+
validate_existence_of_git_url
|
13
|
+
command("git clone #{job.git_url} #{job.workspace.path}")
|
14
|
+
end
|
15
|
+
|
16
|
+
def update
|
17
|
+
command("cd #{job.workspace.path} && git pull")
|
18
|
+
end
|
19
|
+
|
20
|
+
def revision
|
21
|
+
command("cd #{job.workspace.path} && git rev-parse HEAD").rstrip
|
22
|
+
end
|
23
|
+
|
24
|
+
def updated?
|
25
|
+
revision != job.last_finished_build.try(:revision)
|
26
|
+
end
|
27
|
+
|
28
|
+
def cloned?
|
29
|
+
job.workspace.path.join(".git").exist?
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def command(script)
|
35
|
+
Open3.capture3(script)[0]
|
36
|
+
end
|
37
|
+
|
38
|
+
def validate_existence_of_git_url
|
39
|
+
raise GitUrlNotFound unless job.git_url
|
40
|
+
end
|
41
|
+
|
42
|
+
class GitUrlNotFound < StandardError
|
43
|
+
def message
|
44
|
+
"You must set `git_url`"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
Job.class_eval do
|
51
|
+
property(:git_url)
|
52
|
+
|
53
|
+
before_enqueue do
|
54
|
+
if git_url.present?
|
55
|
+
repository.clone unless repository.cloned?
|
56
|
+
repository.update
|
57
|
+
repository.updated?
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
before_execute do
|
62
|
+
if git_url.present?
|
63
|
+
repository.clone unless repository.cloned?
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
after_execute do
|
68
|
+
if git_url.present?
|
69
|
+
current_build.update_revision
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def repository
|
74
|
+
@repository ||= Magi::Repository.new(self)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
Build.class_eval do
|
79
|
+
property(:revision)
|
80
|
+
|
81
|
+
def update_revision
|
82
|
+
update_properties(revision: job.repository.revision)
|
83
|
+
end
|
84
|
+
end
|
data/script/clock.rb
CHANGED
data/spec/models/job_spec.rb
CHANGED
@@ -2,11 +2,15 @@ require "spec_helper"
|
|
2
2
|
|
3
3
|
describe Job do
|
4
4
|
let(:job) do
|
5
|
-
FactoryGirl.create(:job)
|
5
|
+
FactoryGirl.create(:job, properties: { "script" => "true" })
|
6
6
|
end
|
7
7
|
|
8
8
|
describe "#start" do
|
9
9
|
context "without script" do
|
10
|
+
before do
|
11
|
+
job.script = nil
|
12
|
+
end
|
13
|
+
|
10
14
|
it "raises Job::ScriptNotFound" do
|
11
15
|
expect { job.start }.to raise_error(Job::ScriptNotFound)
|
12
16
|
end
|
@@ -52,37 +56,35 @@ describe Job do
|
|
52
56
|
end
|
53
57
|
end
|
54
58
|
|
55
|
-
describe "#
|
59
|
+
describe "#enqueue" do
|
56
60
|
before do
|
57
|
-
Job.
|
61
|
+
Job.before_enqueues.clear
|
58
62
|
end
|
59
63
|
|
60
64
|
after do
|
61
|
-
Job.
|
65
|
+
Job.before_enqueues.clear
|
62
66
|
end
|
63
67
|
|
64
68
|
context "with successful hooks" do
|
65
69
|
before do
|
66
|
-
Job.
|
70
|
+
Job.before_enqueue { Job.hook_is_executed }
|
67
71
|
end
|
68
72
|
|
69
73
|
it "enqueues a new build" do
|
70
74
|
Job.should_receive(:hook_is_executed)
|
71
|
-
job.
|
72
|
-
job.enqueue_with_before_hooks
|
75
|
+
job.enqueue
|
73
76
|
end
|
74
77
|
end
|
75
78
|
|
76
79
|
context "with failed hooks" do
|
77
80
|
before do
|
78
|
-
Job.
|
79
|
-
Job.
|
81
|
+
Job.before_enqueue { false }
|
82
|
+
Job.before_enqueue { Job.hook_is_executed }
|
80
83
|
end
|
81
84
|
|
82
85
|
it "stops at failed hook" do
|
83
86
|
Job.should_not_receive(:hook_is_executed)
|
84
|
-
job.
|
85
|
-
job.enqueue_with_before_hooks
|
87
|
+
job.enqueue
|
86
88
|
end
|
87
89
|
end
|
88
90
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: magi
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryo Nakamura
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-06-
|
11
|
+
date: 2013-06-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: clockwork
|
@@ -308,8 +308,10 @@ files:
|
|
308
308
|
- lib/magi/proprietary.rb
|
309
309
|
- lib/magi/scheduler.rb
|
310
310
|
- lib/magi/version.rb
|
311
|
+
- lib/magi/workspace.rb
|
311
312
|
- lib/magi.rb
|
312
313
|
- lib/tasks/resque.rake
|
314
|
+
- plugins/git/git.rb
|
313
315
|
- public/404.html
|
314
316
|
- public/422.html
|
315
317
|
- public/500.html
|