magi 0.0.5 → 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: fd8670d413c9cc9a48fc8ab40a8a61bf7644df09
4
- data.tar.gz: bdcde50c3ccb2bb39de71b4d706d36ceb59980a4
3
+ metadata.gz: 7b4d28573a8ed0497572635a79c1430e27e61e50
4
+ data.tar.gz: 108e5eca7dd38c7edde9527ebb4cd7efda53412c
5
5
  SHA512:
6
- metadata.gz: 9d816fdc2a44c697af5bad160e83fc1e1dcf56eaee8b4270f560cc621372ed8d45966c874f19514563b36482533b8fbbe78ddd3eb6aeced1cf98f7cce5712878
7
- data.tar.gz: 9fe5724e18f3063c5a800dedc4c6f3f5e076b40f6a82597d091351ca8768bebce04cb7095160062d509b81141bdc9a0fa18075938f0d7144ea2051d6254333f1
6
+ metadata.gz: ff4eca110f647870737e4ec032819f0b2919e7f70551f92f17f279e78ea312b203da5e5927caedbd582ccdf10e8e362b7b949cb4d4ccb09978312a9c1dbc7fe7
7
+ data.tar.gz: 5080f4adeae11f1bb33e8e31d7a9910b62e1de6d787d07ce7ff581993f8d45bdabd3cdb7d94c6bb95c72e724b53901b0ade57cdeb90c437c8d7cafa51f1b86f9
@@ -16,7 +16,7 @@ class BuildsController < ApplicationController
16
16
  end
17
17
 
18
18
  def create
19
- resource = @job.queue
19
+ resource = @job.enqueue
20
20
  respond_with resource, location: [@job, resource]
21
21
  end
22
22
 
@@ -4,12 +4,10 @@ class JobsController < ApplicationController
4
4
 
5
5
  validates :create do
6
6
  string :name, required: true
7
- hash :config
8
7
  end
9
8
 
10
9
  validates :update do
11
10
  string :name
12
- hash :config
13
11
  end
14
12
 
15
13
  def index
@@ -25,11 +23,11 @@ class JobsController < ApplicationController
25
23
  end
26
24
 
27
25
  def create
28
- respond_with @resource = scope.create_with_properties(params.slice(:config, :name))
26
+ respond_with @resource = scope.create_with_properties(params)
29
27
  end
30
28
 
31
29
  def update
32
- respond_with @resource.update_attributes_with_properties(params.slice(:config, :name))
30
+ respond_with @resource.update_attributes_with_properties(params)
33
31
  end
34
32
 
35
33
  def destroy
data/app/models/build.rb CHANGED
@@ -1,5 +1,9 @@
1
1
  class Build < ActiveRecord::Base
2
- attr_accessible :finished_at, :started_at, :output, :status
2
+ extend Magi::Proprietary
3
+
4
+ attr_accessible :finished_at, :started_at, :output, :properties, :status
5
+
6
+ serialize :properties, Hash
3
7
 
4
8
  validates :job_id, presence: true
5
9
 
@@ -9,8 +13,18 @@ class Build < ActiveRecord::Base
9
13
 
10
14
  scope :finished, -> { where("finished_at IS NOT NULL") }
11
15
 
16
+ scope :unfinished, -> { where("finished_at IS NULL") }
17
+
18
+ scope :started, -> { where("started_at IS NOT NULL") }
19
+
20
+ scope :running, -> { started.unfinished }
21
+
22
+ def self.latest
23
+ recent.first
24
+ end
25
+
12
26
  # Pushes this build to worker's queue.
13
- def queue
27
+ def enqueue
14
28
  BuildWorker.perform_async(id)
15
29
  end
16
30
 
@@ -18,7 +32,7 @@ class Build < ActiveRecord::Base
18
32
  def start
19
33
  update_attributes!(started_at: Time.now)
20
34
  result = job.start
21
- update_attributes!(finished_at: Time.now, status: result[:status], output: result[:output])
35
+ reload.update_attributes!(finished_at: Time.now, status: result[:status], output: result[:output])
22
36
  end
23
37
 
24
38
  # Returns elapsed sec as a Float or nil.
data/app/models/job.rb CHANGED
@@ -1,7 +1,9 @@
1
1
  class Job < ActiveRecord::Base
2
- attr_accessible :name, :config
2
+ extend Magi::Proprietary
3
3
 
4
- serialize :config, Hash
4
+ attr_accessible :name, :properties
5
+
6
+ serialize :properties, Hash
5
7
 
6
8
  validates :name, presence: true
7
9
 
@@ -11,31 +13,31 @@ class Job < ActiveRecord::Base
11
13
 
12
14
  delegate :status, :status_name, :status_icon_css_class, to: :last_finished_build, allow_nil: true
13
15
 
16
+ delegate :scheduled?, to: :scheduler, allow_nil: true
17
+
14
18
  class << self
15
- def create_with_properties(properties)
16
- job = new
17
- properties.each {|key, value| job.send("#{key}=", value) }
18
- job.tap(&:save)
19
+ def create_with_properties(params)
20
+ new.update_attributes_with_properties(params)
19
21
  end
20
22
 
21
- def queue
22
- select(&:scheduled?).each(&:queue)
23
+ def enqueue_with_before_hooks
24
+ select(&:scheduled?).each(&:enqueue_with_before_hooks)
23
25
  end
24
26
 
25
- def property(name)
26
- properties << name
27
+ def before_hook(&block)
28
+ before_hooks << block
29
+ end
27
30
 
28
- define_method(name) do
29
- config[name.to_s]
30
- end
31
+ def before_hooks
32
+ @before_hooks ||= []
33
+ end
31
34
 
32
- define_method("#{name}=") do |value|
33
- config[name.to_s] = value
34
- end
35
+ def after_hook(&block)
36
+ after_hooks << block
35
37
  end
36
38
 
37
- def properties
38
- @properties ||= []
39
+ def after_hooks
40
+ @after_hooks ||= []
39
41
  end
40
42
  end
41
43
 
@@ -50,27 +52,33 @@ class Job < ActiveRecord::Base
50
52
  end
51
53
 
52
54
  def scheduler
53
- Magi::Scheduler.new(schedule)
55
+ Magi::Scheduler.new(schedule) if schedule
54
56
  end
55
57
 
56
- def scheduled?
57
- schedule && scheduler.scheduled?
58
+ def enqueue
59
+ builds.create.tap(&:enqueue)
58
60
  end
59
61
 
60
- def queue
61
- builds.create.tap(&:queue)
62
+ def enqueue_with_before_hooks
63
+ enqueue if execute_before_hooks
62
64
  end
63
65
 
64
66
  def status_name
65
67
  last_finished_build.try(:status_name) || "unfinished"
66
68
  end
67
69
 
70
+ def current_build
71
+ builds.running.latest
72
+ end
73
+
68
74
  def last_finished_build
69
75
  builds.finished.order(:finished_at).last
70
76
  end
71
77
 
72
- def update_attributes_with_properties(properties)
73
- properties.each {|key, value| send("#{key}=", value) }
78
+ def update_attributes_with_properties(params)
79
+ params.slice(:name, *self.class.properties).each do |key, value|
80
+ send("#{key}=", value)
81
+ end
74
82
  tap(&:save)
75
83
  end
76
84
 
@@ -80,8 +88,21 @@ class Job < ActiveRecord::Base
80
88
  Magi::Executer.execute(script)
81
89
  end
82
90
 
91
+ def execute_with_after_hooks
92
+ execute_without_after_hooks.tap { execute_after_hooks }
93
+ end
94
+ alias_method_chain :execute, :after_hooks
95
+
96
+ def execute_before_hooks
97
+ self.class.before_hooks.all? {|hook| instance_exec(&hook) != false }
98
+ end
99
+
100
+ def execute_after_hooks
101
+ self.class.after_hooks.all? {|hook| instance_exec(&hook) != false }
102
+ end
103
+
83
104
  def raise_script_not_found
84
- raise ScriptNotFound, 'You must set script["config"]'
105
+ raise ScriptNotFound, 'You must set properties["script"]'
85
106
  end
86
107
 
87
108
  class ScriptNotFound < StandardError; end
@@ -1,7 +1,7 @@
1
1
  section.job_settings
2
2
  h1 Settings
3
3
 
4
- = form_for resource do |f|
4
+ = form_for resource, as: "" do |f|
5
5
  .field
6
6
  p= f.label :name
7
7
  p= f.text_field :name, placeholder: "required"
@@ -0,0 +1,13 @@
1
+ class JobEnqueueWorker
2
+ @queue = name
3
+
4
+ class << self
5
+ def perform(id)
6
+ Job.find(id).enqueue_with_before_hooks
7
+ end
8
+
9
+ def perform_async(id)
10
+ Resque.enqueue(self, id)
11
+ end
12
+ end
13
+ end
@@ -0,0 +1 @@
1
+ Magi.plugin_manager.load_plugins
@@ -0,0 +1,9 @@
1
+ class ChangeJobColumnNameFromConfigToProperties < ActiveRecord::Migration
2
+ def up
3
+ rename_column :jobs, :config, :properties
4
+ end
5
+
6
+ def down
7
+ rename_column :jobs, :properties, :config
8
+ end
9
+ end
@@ -0,0 +1,5 @@
1
+ class AddColumnPropertiesToBuilds < ActiveRecord::Migration
2
+ def change
3
+ add_column :builds, :properties, :text
4
+ end
5
+ end
data/db/schema.rb CHANGED
@@ -11,7 +11,7 @@
11
11
  #
12
12
  # It's strongly recommended to check this file into your version control system.
13
13
 
14
- ActiveRecord::Schema.define(:version => 20130531155155) do
14
+ ActiveRecord::Schema.define(:version => 20130608153655) do
15
15
 
16
16
  create_table "builds", :force => true do |t|
17
17
  t.boolean "status"
@@ -21,13 +21,14 @@ ActiveRecord::Schema.define(:version => 20130531155155) do
21
21
  t.text "output"
22
22
  t.datetime "created_at", :null => false
23
23
  t.datetime "updated_at", :null => false
24
+ t.text "properties"
24
25
  end
25
26
 
26
27
  add_index "builds", ["job_id"], :name => "index_builds_on_job_id"
27
28
 
28
29
  create_table "jobs", :force => true do |t|
29
30
  t.string "name"
30
- t.text "config"
31
+ t.text "properties"
31
32
  t.datetime "created_at", :null => false
32
33
  t.datetime "updated_at", :null => false
33
34
  end
data/lib/magi/executer.rb CHANGED
@@ -13,8 +13,21 @@ module Magi
13
13
  end
14
14
 
15
15
  def execute
16
- output, status = Open3.capture2e(script)
17
16
  { output: output, status: status.success? }
18
17
  end
18
+
19
+ private
20
+
21
+ def output
22
+ result[0]
23
+ end
24
+
25
+ def status
26
+ result[1]
27
+ end
28
+
29
+ def result
30
+ @result ||= Open3.capture2e(script)
31
+ end
19
32
  end
20
33
  end
@@ -0,0 +1,13 @@
1
+ module Magi
2
+ class PluginManager
3
+ def plugins_directory
4
+ @plugins_directory ||= Rails.root + "plugins"
5
+ end
6
+
7
+ def load_plugins
8
+ Dir.glob("#{plugins_directory}/*/*.rb").sort.each do |path|
9
+ require path
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,19 @@
1
+ module Magi
2
+ module Proprietary
3
+ def property(name)
4
+ properties << name
5
+
6
+ define_method(name) do
7
+ properties[name.to_s]
8
+ end
9
+
10
+ define_method("#{name}=") do |value|
11
+ properties[name.to_s] = value
12
+ end
13
+ end
14
+
15
+ def properties
16
+ @properties ||= []
17
+ end
18
+ end
19
+ end
data/lib/magi/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Magi
2
- VERSION = "0.0.5"
2
+ VERSION = "0.0.6"
3
3
  end
data/lib/magi.rb CHANGED
@@ -1,2 +1,9 @@
1
1
  require "magi/command"
2
+ require "magi/plugin_manager"
2
3
  require "magi/version"
4
+
5
+ module Magi
6
+ def self.plugin_manager
7
+ @plugin_manager ||= Magi::PluginManager.new
8
+ end
9
+ end
data/magi.gemspec CHANGED
@@ -39,7 +39,7 @@ Gem::Specification.new do |spec|
39
39
  spec.add_dependency "sass-rails", "~> 3.2.3"
40
40
  spec.add_dependency "slim"
41
41
  spec.add_dependency "uglifier", ">= 1.0.3"
42
- spec.add_dependency "weak_parameters", ">= 0.0.2"
42
+ spec.add_dependency "weak_parameters", ">= 0.0.3"
43
43
  spec.add_development_dependency "bundler", "~> 1.3"
44
44
  spec.add_development_dependency "pry-rails"
45
45
  spec.add_development_dependency "thin"
data/script/clock.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  require File.expand_path("../../config/environment.rb", __FILE__)
2
2
 
3
- Clockwork.every(1.minute, "Job.queue") do
4
- Job.queue
3
+ Clockwork.every(1.minute, "JobEnqueueWorker") do
4
+ Job.enqueue_with_before_hooks
5
5
  end
@@ -6,7 +6,7 @@ describe Build do
6
6
  end
7
7
 
8
8
  let(:job) do
9
- FactoryGirl.create(:job, config: { "script" => "true" })
9
+ FactoryGirl.create(:job, properties: { "script" => "true" })
10
10
  end
11
11
 
12
12
  describe "#start" do
@@ -21,7 +21,7 @@ describe Build do
21
21
 
22
22
  context "with failure" do
23
23
  before do
24
- build.job.config["script"] = "false"
24
+ build.job.script = "false"
25
25
  end
26
26
 
27
27
  it "starts its job and sets status with false" do
@@ -33,7 +33,7 @@ describe Job do
33
33
 
34
34
  context "with matched schedule" do
35
35
  before do
36
- job.config["schedule"] = "* * * * *"
36
+ job.schedule = "* * * * *"
37
37
  end
38
38
 
39
39
  it "returns true" do
@@ -43,7 +43,7 @@ describe Job do
43
43
 
44
44
  context "without matched schedule" do
45
45
  before do
46
- job.config["schedule"] = "0 0 0 0 0"
46
+ job.schedule = "0 0 0 0 0"
47
47
  end
48
48
 
49
49
  it "returns false" do
@@ -51,4 +51,39 @@ describe Job do
51
51
  end
52
52
  end
53
53
  end
54
+
55
+ describe "#enqueue_with_before_hooks" do
56
+ before do
57
+ Job.before_hooks.clear
58
+ end
59
+
60
+ after do
61
+ Job.before_hooks.clear
62
+ end
63
+
64
+ context "with successful hooks" do
65
+ before do
66
+ Job.before_hook { Job.hook_is_executed }
67
+ end
68
+
69
+ it "enqueues a new build" do
70
+ Job.should_receive(:hook_is_executed)
71
+ job.should_receive(:enqueue)
72
+ job.enqueue_with_before_hooks
73
+ end
74
+ end
75
+
76
+ context "with failed hooks" do
77
+ before do
78
+ Job.before_hook { false }
79
+ Job.before_hook { Job.hook_is_executed }
80
+ end
81
+
82
+ it "stops at failed hook" do
83
+ Job.should_not_receive(:hook_is_executed)
84
+ job.should_not_receive(:enqueue)
85
+ job.enqueue_with_before_hooks
86
+ end
87
+ end
88
+ end
54
89
  end
@@ -10,7 +10,7 @@ describe "Builds" do
10
10
  end
11
11
 
12
12
  let(:job) do
13
- FactoryGirl.create(:job, config: { "script" => "true" })
13
+ FactoryGirl.create(:job, properties: { "script" => "true" })
14
14
  end
15
15
 
16
16
  let(:build) do
@@ -36,6 +36,7 @@ describe "Jobs" do
36
36
  describe "POST /jobs" do
37
37
  before do
38
38
  params[:name] = "name"
39
+ params[:description] = "description"
39
40
  end
40
41
 
41
42
  context "with invalid params" do
@@ -53,7 +54,9 @@ describe "Jobs" do
53
54
  it "creates a new job", :autodoc do
54
55
  post "/jobs", params, env
55
56
  response.status.should == 201
56
- Job.should have(1).job
57
+ job = Job.first
58
+ job.name.should == "name"
59
+ job.description.should == "description"
57
60
  end
58
61
  end
59
62
  end
@@ -61,24 +64,16 @@ describe "Jobs" do
61
64
  describe "PUT /jobs/:id" do
62
65
  before do
63
66
  params[:name] = "name"
64
- end
65
-
66
- context "with invalid params" do
67
- before do
68
- params[:config] = "invalid"
69
- end
70
-
71
- it "returns 400" do
72
- put "/jobs/#{job.id}", params, env
73
- response.status.should == 400
74
- end
67
+ params[:description] = "description"
75
68
  end
76
69
 
77
70
  context "with valid condition" do
78
71
  it "updates the job", :autodoc do
79
72
  put "/jobs/#{job.id}", params, env
80
73
  response.status.should == 204
81
- job.reload.name.should == "name"
74
+ job.reload
75
+ job.name.should == "name"
76
+ job.description.should == "description"
82
77
  end
83
78
  end
84
79
  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.5
4
+ version: 0.0.6
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-08 00:00:00.000000000 Z
11
+ date: 2013-06-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: clockwork
@@ -198,14 +198,14 @@ dependencies:
198
198
  requirements:
199
199
  - - '>='
200
200
  - !ruby/object:Gem::Version
201
- version: 0.0.2
201
+ version: 0.0.3
202
202
  type: :runtime
203
203
  prerelease: false
204
204
  version_requirements: !ruby/object:Gem::Requirement
205
205
  requirements:
206
206
  - - '>='
207
207
  - !ruby/object:Gem::Version
208
- version: 0.0.2
208
+ version: 0.0.3
209
209
  - !ruby/object:Gem::Dependency
210
210
  name: bundler
211
211
  requirement: !ruby/object:Gem::Requirement
@@ -278,6 +278,7 @@ files:
278
278
  - app/views/jobs/show.html.slim
279
279
  - app/views/layouts/application.html.slim
280
280
  - app/workers/build_worker.rb
281
+ - app/workers/job_enqueue_worker.rb
281
282
  - bin/magi
282
283
  - config/application.rb
283
284
  - config/boot.rb
@@ -288,6 +289,7 @@ files:
288
289
  - config/environments/test.rb
289
290
  - config/initializers/backtrace_silencers.rb
290
291
  - config/initializers/inflections.rb
292
+ - config/initializers/load_plugins.rb
291
293
  - config/initializers/mime_types.rb
292
294
  - config/initializers/secret_token.rb
293
295
  - config/initializers/session_store.rb
@@ -296,10 +298,14 @@ files:
296
298
  - config/routes.rb
297
299
  - db/migrate/20130531143239_create_jobs.rb
298
300
  - db/migrate/20130531155155_create_builds.rb
301
+ - db/migrate/20130608153135_change_job_column_name_from_config_to_properties.rb
302
+ - db/migrate/20130608153655_add_column_properties_to_builds.rb
299
303
  - db/schema.rb
300
304
  - db/seeds.rb
301
305
  - lib/magi/command.rb
302
306
  - lib/magi/executer.rb
307
+ - lib/magi/plugin_manager.rb
308
+ - lib/magi/proprietary.rb
303
309
  - lib/magi/scheduler.rb
304
310
  - lib/magi/version.rb
305
311
  - lib/magi.rb