Refactor and simplify recipe DSL evaluation usages:
Remove most of recipe evaluation code in Recipe class, and rely on Recipe::DSL to get evaluated recipes. * Remove Recipe#evaluate call from CLI, rely on Recipe.evaluate_from_file to get the evaluated recipe; * Implement Recipe.evaluate_from_file(filepath, env); * Implement Recipe::DSL.evaluate(code, env); * Remove code and filepath accessor on Recipe; * Remove Recipe.from_file and Recipe#evaluate methods; * Move task evaluations in Recipe::DSL#evaluate; * Modify Recipe constructor so that it accepts tasks as argument.
This commit is contained in:
parent
7c5d5b0417
commit
f0e144cebd
@ -12,7 +12,6 @@ module Producer
|
|||||||
|
|
||||||
def run!
|
def run!
|
||||||
check_arguments!
|
check_arguments!
|
||||||
recipe.evaluate(env)
|
|
||||||
worker.process recipe.tasks
|
worker.process recipe.tasks
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -25,7 +24,7 @@ module Producer
|
|||||||
end
|
end
|
||||||
|
|
||||||
def recipe
|
def recipe
|
||||||
@recipe ||= Recipe.from_file(@arguments.first)
|
@recipe ||= Recipe.evaluate_from_file(@arguments.first, env)
|
||||||
end
|
end
|
||||||
|
|
||||||
def worker
|
def worker
|
||||||
|
@ -1,22 +1,14 @@
|
|||||||
module Producer
|
module Producer
|
||||||
module Core
|
module Core
|
||||||
class Recipe
|
class Recipe
|
||||||
attr_reader :code, :filepath, :tasks
|
attr_accessor :tasks
|
||||||
|
|
||||||
def self.from_file(filepath)
|
def self.evaluate_from_file(filepath, env)
|
||||||
new(File.read(filepath), filepath)
|
DSL.evaluate(File.read(filepath), env)
|
||||||
end
|
end
|
||||||
|
|
||||||
def initialize(code, filepath = nil)
|
def initialize(tasks = [])
|
||||||
@code = code
|
@tasks = tasks
|
||||||
@filepath = filepath
|
|
||||||
@tasks = []
|
|
||||||
end
|
|
||||||
|
|
||||||
def evaluate(env)
|
|
||||||
dsl = DSL.new(@code).evaluate(env)
|
|
||||||
dsl.tasks.map { |e| e.evaluate env }
|
|
||||||
@tasks = dsl.tasks
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -4,6 +4,11 @@ module Producer
|
|||||||
class DSL
|
class DSL
|
||||||
attr_reader :tasks
|
attr_reader :tasks
|
||||||
|
|
||||||
|
def self.evaluate(code, env)
|
||||||
|
dsl = new(code).evaluate(env)
|
||||||
|
Recipe.new(dsl.tasks)
|
||||||
|
end
|
||||||
|
|
||||||
def initialize(code = nil, &block)
|
def initialize(code = nil, &block)
|
||||||
@code = code
|
@code = code
|
||||||
@block = block
|
@block = block
|
||||||
@ -17,6 +22,7 @@ module Producer
|
|||||||
else
|
else
|
||||||
instance_eval &@block
|
instance_eval &@block
|
||||||
end
|
end
|
||||||
|
@tasks.each { |e| e.evaluate env }
|
||||||
self
|
self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -27,11 +27,6 @@ module Producer::Core
|
|||||||
cli.run!
|
cli.run!
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'evaluates the recipe with the environment' do
|
|
||||||
expect(cli.recipe).to receive(:evaluate).with(cli.env)
|
|
||||||
cli.run!
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'processes the tasks with the worker' do
|
it 'processes the tasks with the worker' do
|
||||||
allow(cli.recipe).to receive(:tasks) { [:some_task] }
|
allow(cli.recipe).to receive(:tasks) { [:some_task] }
|
||||||
expect(cli.worker).to receive(:process).with([:some_task])
|
expect(cli.worker).to receive(:process).with([:some_task])
|
||||||
@ -80,12 +75,12 @@ module Producer::Core
|
|||||||
describe '#recipe' do
|
describe '#recipe' do
|
||||||
it 'builds a recipe' do
|
it 'builds a recipe' do
|
||||||
expect(Recipe)
|
expect(Recipe)
|
||||||
.to receive(:from_file).with(recipe_file)
|
.to receive(:evaluate_from_file).with(recipe_file, cli.env)
|
||||||
cli.recipe
|
cli.recipe
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'returns the recipe' do
|
it 'returns the recipe' do
|
||||||
recipe = double('recipe')
|
recipe = double('recipe').as_null_object
|
||||||
allow(Recipe).to receive(:new) { recipe }
|
allow(Recipe).to receive(:new) { recipe }
|
||||||
expect(cli.recipe).to be recipe
|
expect(cli.recipe).to be recipe
|
||||||
end
|
end
|
||||||
|
@ -8,6 +8,35 @@ module Producer::Core
|
|||||||
let(:env) { double('env').as_null_object }
|
let(:env) { double('env').as_null_object }
|
||||||
subject(:dsl) { Recipe::DSL.new &code }
|
subject(:dsl) { Recipe::DSL.new &code }
|
||||||
|
|
||||||
|
describe '.evaluate' do
|
||||||
|
let(:code) { 'nil' }
|
||||||
|
|
||||||
|
it 'builds a new DSL sandbox with given code' do
|
||||||
|
expect(Recipe::DSL).to receive(:new).once.with(code).and_call_original
|
||||||
|
Recipe::DSL.evaluate(code, env)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'evaluates the DSL sandbox code with given environment' do
|
||||||
|
dsl = double('dsl').as_null_object
|
||||||
|
allow(Recipe::DSL).to receive(:new) { dsl }
|
||||||
|
expect(dsl).to receive(:evaluate).with(env)
|
||||||
|
Recipe::DSL.evaluate(code, env)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'builds a recipe with evaluated tasks' do
|
||||||
|
dsl = Recipe::DSL.new('task(:some_task) { }')
|
||||||
|
allow(Recipe::DSL).to receive(:new) { dsl }
|
||||||
|
expect(Recipe).to receive(:new).with(dsl.tasks)
|
||||||
|
Recipe::DSL.evaluate(code, env)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'returns the recipe' do
|
||||||
|
recipe = double('recipe').as_null_object
|
||||||
|
allow(Recipe).to receive(:new) { recipe }
|
||||||
|
expect(Recipe::DSL.evaluate(code, env)).to be recipe
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe '#initialize' do
|
describe '#initialize' do
|
||||||
it 'assigns no task' do
|
it 'assigns no task' do
|
||||||
expect(dsl.instance_eval { @tasks }).to be_empty
|
expect(dsl.instance_eval { @tasks }).to be_empty
|
||||||
@ -30,7 +59,7 @@ module Producer::Core
|
|||||||
end
|
end
|
||||||
|
|
||||||
describe '#tasks' do
|
describe '#tasks' do
|
||||||
let(:code) { proc { task(:some_task) } }
|
let(:code) { proc { task(:some_task) { } } }
|
||||||
|
|
||||||
it 'returns registered tasks' do
|
it 'returns registered tasks' do
|
||||||
dsl.evaluate(env)
|
dsl.evaluate(env)
|
||||||
@ -44,6 +73,14 @@ module Producer::Core
|
|||||||
expect { dsl.evaluate(env) }.to throw_symbol :recipe_code
|
expect { dsl.evaluate(env) }.to throw_symbol :recipe_code
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it 'evaluates the registered tasks' do
|
||||||
|
task = double('task')
|
||||||
|
allow(Task).to receive(:new) { task }
|
||||||
|
dsl = Recipe::DSL.new { task(:some_task) }
|
||||||
|
expect(task).to receive(:evaluate).with(env)
|
||||||
|
dsl.evaluate(env)
|
||||||
|
end
|
||||||
|
|
||||||
it 'returns itself' do
|
it 'returns itself' do
|
||||||
expect(dsl.evaluate(env)).to eq dsl
|
expect(dsl.evaluate(env)).to eq dsl
|
||||||
end
|
end
|
||||||
@ -81,11 +118,11 @@ module Producer::Core
|
|||||||
end
|
end
|
||||||
|
|
||||||
describe '#task' do
|
describe '#task' do
|
||||||
let(:code) { proc { task(:first) { throw :first_task }; task(:last) } }
|
let(:code) { proc { task(:first) { :some_value }; task(:last) { } } }
|
||||||
|
|
||||||
it 'register a task with its code' do
|
it 'register a task with its code' do
|
||||||
expect(dsl.tasks.first.name).to eq :first
|
expect(dsl.tasks.first.instance_eval { @block.call })
|
||||||
expect { dsl.tasks.first.evaluate(env) }.to throw_symbol :first_task
|
.to eq :some_value
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'registers tasks in declaration order' do
|
it 'registers tasks in declaration order' do
|
||||||
|
@ -4,76 +4,39 @@ module Producer::Core
|
|||||||
describe Recipe do
|
describe Recipe do
|
||||||
include FixturesHelpers
|
include FixturesHelpers
|
||||||
|
|
||||||
let(:code) { 'nil' }
|
subject(:recipe) { Recipe.new }
|
||||||
subject(:recipe) { Recipe.new(code) }
|
|
||||||
|
|
||||||
describe '.from_file' do
|
describe '.evaluate_from_file' do
|
||||||
let(:filepath) { fixture_path_for 'recipes/empty.rb' }
|
let(:env) { double('env') }
|
||||||
subject(:recipe) { Recipe.from_file(filepath) }
|
let(:filepath) { fixture_path_for 'recipes/empty.rb' }
|
||||||
|
|
||||||
it 'builds a recipe whose code is read from given file path' do
|
it 'delegates to DSL.evaluate with the recipe file content' do
|
||||||
expect(recipe.code).to eq File.read(filepath)
|
expect(Recipe::DSL)
|
||||||
|
.to receive(:evaluate).with(File.read(filepath), env)
|
||||||
|
Recipe.evaluate_from_file(filepath, env)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'builds a recipe whose file path is set from given file path' do
|
it 'returns the evaluated recipe' do
|
||||||
expect(recipe.filepath).to eq filepath
|
recipe = double('recipe')
|
||||||
|
allow(Recipe::DSL).to receive(:evaluate) { recipe }
|
||||||
|
expect(Recipe.evaluate_from_file(filepath, env)).to be recipe
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe '#initialize' do
|
describe '#initialize' do
|
||||||
it 'assigns nil as a default filepath' do
|
context 'without arguments' do
|
||||||
expect(recipe.filepath).to be nil
|
it 'assigns no task' do
|
||||||
|
expect(recipe.tasks).to be_empty
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'has no task' do
|
context 'when tasks are given as argument' do
|
||||||
expect(recipe.tasks).to be_empty
|
let(:tasks) { [Task.new(:some_task)] }
|
||||||
end
|
let(:recipe) { Recipe.new(tasks) }
|
||||||
end
|
|
||||||
|
|
||||||
describe '#code' do
|
it 'assigns the tasks' do
|
||||||
it 'returns the assigned code' do
|
expect(recipe.tasks).to eq tasks
|
||||||
expect(recipe.code).to be code
|
end
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe '#filepath' do
|
|
||||||
let(:filepath) { 'some_file_path' }
|
|
||||||
let(:recipe) { Recipe.new(code, filepath) }
|
|
||||||
|
|
||||||
it 'returns the assigned file path' do
|
|
||||||
expect(recipe.filepath).to eq filepath
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe '#evaluate' do
|
|
||||||
let(:env) { double('env').as_null_object }
|
|
||||||
|
|
||||||
it 'builds a recipe DSL sandbox' do
|
|
||||||
expect(Recipe::DSL).to receive(:new).once.with(code).and_call_original
|
|
||||||
recipe.evaluate(env)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'evaluates the DSL sandbox with the environment given as argument' do
|
|
||||||
dsl = double('dsl').as_null_object
|
|
||||||
allow(Recipe::DSL).to receive(:new) { dsl }
|
|
||||||
expect(dsl).to receive(:evaluate)
|
|
||||||
recipe.evaluate(env)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'evaluates the DSL sandbox tasks' do
|
|
||||||
task = double('task')
|
|
||||||
allow(Task).to receive(:new) { task }
|
|
||||||
dsl = Recipe::DSL.new { task(:some_task) }
|
|
||||||
allow(Recipe::DSL).to receive(:new) { dsl }
|
|
||||||
expect(task).to receive(:evaluate).with(env)
|
|
||||||
recipe.evaluate(env)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'assigns the evaluated tasks' do
|
|
||||||
dsl = Recipe::DSL.new { task(:some_task) { } }
|
|
||||||
allow(Recipe::DSL).to receive(:new) { dsl }
|
|
||||||
recipe.evaluate(env)
|
|
||||||
expect(recipe.tasks.first.name).to eq :some_task
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
Loading…
x
Reference in New Issue
Block a user