magi 0.0.5 → 0.0.6

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 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