Merge Recipe::DSL into Recipe
This commit is contained in:
parent
4c0077d14d
commit
166dae681c
@ -33,7 +33,7 @@ require 'producer/core/errors'
|
|||||||
require 'producer/core/logger_formatter'
|
require 'producer/core/logger_formatter'
|
||||||
require 'producer/core/prompter'
|
require 'producer/core/prompter'
|
||||||
require 'producer/core/recipe'
|
require 'producer/core/recipe'
|
||||||
require 'producer/core/recipe/dsl'
|
require 'producer/core/recipe/file_evaluator'
|
||||||
require 'producer/core/remote'
|
require 'producer/core/remote'
|
||||||
require 'producer/core/remote/environment'
|
require 'producer/core/remote/environment'
|
||||||
require 'producer/core/remote/fs'
|
require 'producer/core/remote/fs'
|
||||||
|
@ -58,7 +58,7 @@ module Producer
|
|||||||
end
|
end
|
||||||
|
|
||||||
def recipe
|
def recipe
|
||||||
@recipe ||= Recipe.evaluate_from_file(@arguments.first, env)
|
@recipe ||= Recipe::FileEvaluator.evaluate(@arguments.first, env)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -2,16 +2,46 @@ module Producer
|
|||||||
module Core
|
module Core
|
||||||
class Recipe
|
class Recipe
|
||||||
class << self
|
class << self
|
||||||
def evaluate_from_file(filepath, env)
|
def define_macro(name, block)
|
||||||
dsl = DSL.new(env, File.read(filepath)).evaluate
|
define_method(name) { |*args| task name, *args, &block }
|
||||||
Recipe.new(dsl.tasks)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
attr_accessor :tasks
|
attr_reader :env, :tasks
|
||||||
|
|
||||||
def initialize(tasks = [])
|
def initialize(env)
|
||||||
@tasks = tasks
|
@env = env
|
||||||
|
@tasks = []
|
||||||
|
end
|
||||||
|
|
||||||
|
def source(filepath)
|
||||||
|
instance_eval File.read("./#{filepath}.rb"), "#{filepath}.rb"
|
||||||
|
end
|
||||||
|
|
||||||
|
def target(hostname)
|
||||||
|
env.target ||= hostname
|
||||||
|
end
|
||||||
|
|
||||||
|
def task(name, *args, &block)
|
||||||
|
@tasks << Task.evaluate(name, env, *args, &block)
|
||||||
|
end
|
||||||
|
|
||||||
|
def macro(name, &block)
|
||||||
|
define_singleton_method(name) do |*args|
|
||||||
|
task("#{name}", *args, &block)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_macro(name, dsl: Condition::DSL, &block)
|
||||||
|
dsl.define_test(name, block)
|
||||||
|
end
|
||||||
|
|
||||||
|
def set(key, value)
|
||||||
|
env[key] = value
|
||||||
|
end
|
||||||
|
|
||||||
|
def get(key)
|
||||||
|
env[key]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -1,61 +0,0 @@
|
|||||||
module Producer
|
|
||||||
module Core
|
|
||||||
class Recipe
|
|
||||||
class DSL
|
|
||||||
class << self
|
|
||||||
def define_macro(name, block)
|
|
||||||
define_method(name) { |*args| task name, *args, &block }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
attr_reader :env, :code, :block, :tasks
|
|
||||||
|
|
||||||
def initialize(env, code = nil, &block)
|
|
||||||
@env = env
|
|
||||||
@code = code
|
|
||||||
@block = block
|
|
||||||
@tasks = []
|
|
||||||
end
|
|
||||||
|
|
||||||
def evaluate
|
|
||||||
if @code
|
|
||||||
instance_eval @code
|
|
||||||
else
|
|
||||||
instance_eval &@block
|
|
||||||
end
|
|
||||||
self
|
|
||||||
end
|
|
||||||
|
|
||||||
def source(filepath)
|
|
||||||
instance_eval File.read("./#{filepath}.rb"), "#{filepath}.rb"
|
|
||||||
end
|
|
||||||
|
|
||||||
def target(hostname)
|
|
||||||
env.target ||= hostname
|
|
||||||
end
|
|
||||||
|
|
||||||
def task(name, *args, &block)
|
|
||||||
@tasks << Task.evaluate(name, env, *args, &block)
|
|
||||||
end
|
|
||||||
|
|
||||||
def macro(name, &block)
|
|
||||||
define_singleton_method(name) do |*args|
|
|
||||||
task("#{name}", *args, &block)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_macro(name, dsl: Condition::DSL, &block)
|
|
||||||
dsl.define_test(name, block)
|
|
||||||
end
|
|
||||||
|
|
||||||
def set(key, value)
|
|
||||||
env[key] = value
|
|
||||||
end
|
|
||||||
|
|
||||||
def get(key)
|
|
||||||
env[key]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
14
lib/producer/core/recipe/file_evaluator.rb
Normal file
14
lib/producer/core/recipe/file_evaluator.rb
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
module Producer
|
||||||
|
module Core
|
||||||
|
class Recipe
|
||||||
|
class FileEvaluator
|
||||||
|
class << self
|
||||||
|
def evaluate(file_path, env)
|
||||||
|
content = File.read(file_path)
|
||||||
|
Recipe.new(env).tap { |o| o.instance_eval content, file_path }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
@ -1,140 +0,0 @@
|
|||||||
require 'spec_helper'
|
|
||||||
|
|
||||||
module Producer::Core
|
|
||||||
class Recipe
|
|
||||||
describe DSL do
|
|
||||||
include FixturesHelpers
|
|
||||||
|
|
||||||
let(:code) { proc { :some_recipe_code } }
|
|
||||||
let(:env) { Env.new }
|
|
||||||
subject(:dsl) { DSL.new(env, &code) }
|
|
||||||
|
|
||||||
describe '#initialize' do
|
|
||||||
it 'assigns the given env' do
|
|
||||||
expect(dsl.env).to be env
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'assigns no task' do
|
|
||||||
expect(dsl.tasks).to be_empty
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'when a string of code is given as argument' do
|
|
||||||
let(:code) { 'some_code' }
|
|
||||||
subject(:dsl) { described_class.new(env, code) }
|
|
||||||
|
|
||||||
it 'assigns the string of code' do
|
|
||||||
expect(dsl.code).to eq code
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'when a code block is given as argument' do
|
|
||||||
it 'assigns the code block' do
|
|
||||||
expect(dsl.block).to be code
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe '#tasks' do
|
|
||||||
let(:code) { proc { task(:some_task) {} } }
|
|
||||||
|
|
||||||
it 'returns registered tasks' do
|
|
||||||
dsl.evaluate
|
|
||||||
expect(dsl.tasks[0].name).to eq :some_task
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe '#evaluate' do
|
|
||||||
it 'evaluates its code' do
|
|
||||||
dsl = described_class.new(env) { throw :recipe_code }
|
|
||||||
expect { dsl.evaluate }.to throw_symbol :recipe_code
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'returns itself' do
|
|
||||||
expect(dsl.evaluate).to eq dsl
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe '#source' do
|
|
||||||
let(:filepath) { fixture_path_for 'recipes/throw' }
|
|
||||||
|
|
||||||
it 'sources the recipe given as argument' do
|
|
||||||
expect { dsl.source filepath }.to throw_symbol :recipe_code
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe '#target' do
|
|
||||||
let(:host) { 'some_host.example' }
|
|
||||||
|
|
||||||
context 'when env has no assigned target' do
|
|
||||||
it 'registers the target host in the env' do
|
|
||||||
dsl.target host
|
|
||||||
expect(env.target).to eq host
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'when env has an assigned target' do
|
|
||||||
before { env.target = 'already_assigned_host.example' }
|
|
||||||
|
|
||||||
it 'does not change env target' do
|
|
||||||
expect { dsl.target host }.not_to change { env.target }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe '#task' do
|
|
||||||
it 'registers a new evaluated task' do
|
|
||||||
expect { dsl.task(:some_task) { :some_task_code } }
|
|
||||||
.to change { dsl.tasks.count }.by 1
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe '#macro' do
|
|
||||||
it 'defines the new recipe keyword' do
|
|
||||||
dsl.macro :hello
|
|
||||||
expect(dsl).to respond_to(:hello)
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'when a defined macro is called' do
|
|
||||||
before { dsl.macro(:hello) { :some_macro_code } }
|
|
||||||
|
|
||||||
it 'registers the new task' do
|
|
||||||
expect { dsl.hello }.to change { dsl.tasks.count }.by 1
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'when a defined macro is called with arguments' do
|
|
||||||
before { dsl.macro(:hello) { |a, b| echo a, b } }
|
|
||||||
|
|
||||||
it 'evaluates task code with arguments' do
|
|
||||||
dsl.hello :some, :args
|
|
||||||
expect(dsl.tasks.first.actions.first.arguments).to eq [:some, :args]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe '#test_macro' do
|
|
||||||
it 'defines the new test' do
|
|
||||||
condition_dsl = double 'condition dsl'
|
|
||||||
test_block = proc {}
|
|
||||||
expect(condition_dsl)
|
|
||||||
.to receive(:define_test).with(:some_test, test_block)
|
|
||||||
dsl.test_macro(:some_test, dsl: condition_dsl, &test_block)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe '#set' do
|
|
||||||
it 'registers a key/value pair in env registry' do
|
|
||||||
dsl.set :some_key, :some_value
|
|
||||||
expect(env[:some_key]).to eq :some_value
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe '#get' do
|
|
||||||
it 'fetches a value from the registry at given index' do
|
|
||||||
dsl.set :some_key, :some_value
|
|
||||||
expect(dsl.get :some_key).to eq :some_value
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
22
spec/producer/core/recipe/file_evaluator_spec.rb
Normal file
22
spec/producer/core/recipe/file_evaluator_spec.rb
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
module Producer::Core
|
||||||
|
class Recipe
|
||||||
|
describe FileEvaluator do
|
||||||
|
include FixturesHelpers
|
||||||
|
|
||||||
|
describe '.evaluate' do
|
||||||
|
let(:env) { Env.new }
|
||||||
|
let(:file_path) { fixture_path_for 'recipes/some_recipe.rb' }
|
||||||
|
subject(:recipe) { described_class.evaluate(file_path, env) }
|
||||||
|
|
||||||
|
it 'returns an evaluated recipe' do
|
||||||
|
expect(recipe.tasks).to match [
|
||||||
|
an_object_having_attributes(name: :some_task),
|
||||||
|
an_object_having_attributes(name: :another_task)
|
||||||
|
]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
@ -4,33 +4,92 @@ module Producer::Core
|
|||||||
describe Recipe do
|
describe Recipe do
|
||||||
include FixturesHelpers
|
include FixturesHelpers
|
||||||
|
|
||||||
subject(:recipe) { Recipe.new }
|
let(:env) { Env.new }
|
||||||
|
subject(:recipe) { described_class.new(env) }
|
||||||
|
|
||||||
describe '.evaluate_from_file' do
|
describe '#initialize' do
|
||||||
let(:env) { double 'env' }
|
it 'assigns no task' do
|
||||||
let(:filepath) { fixture_path_for 'recipes/some_recipe.rb' }
|
expect(recipe.tasks).to be_empty
|
||||||
subject(:recipe) { Recipe.evaluate_from_file(filepath, env) }
|
|
||||||
|
|
||||||
it 'returns an evaluated recipe' do
|
|
||||||
expect(recipe.tasks.map(&:name)).to eq [:some_task, :another_task]
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe '#initialize' do
|
describe '#source' do
|
||||||
context 'without arguments' do
|
let(:filepath) { fixture_path_for 'recipes/throw' }
|
||||||
it 'assigns no task' do
|
|
||||||
expect(recipe.tasks).to be_empty
|
it 'sources the recipe given as argument' do
|
||||||
|
expect { recipe.source filepath }.to throw_symbol :recipe_code
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#target' do
|
||||||
|
let(:host) { 'some_host.example' }
|
||||||
|
|
||||||
|
context 'when env has no assigned target' do
|
||||||
|
it 'registers the target host in the env' do
|
||||||
|
recipe.target host
|
||||||
|
expect(env.target).to eq host
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when tasks are given as argument' do
|
context 'when env has an assigned target' do
|
||||||
let(:tasks) { [double('task')] }
|
before { env.target = 'already_assigned_host.example' }
|
||||||
subject(:recipe) { Recipe.new(tasks) }
|
|
||||||
|
|
||||||
it 'assigns the tasks' do
|
it 'does not change env target' do
|
||||||
expect(recipe.tasks).to eq tasks
|
expect { recipe.target host }.not_to change { env.target }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe '#task' do
|
||||||
|
it 'registers a new evaluated task' do
|
||||||
|
expect { recipe.task(:some_task) { :some_task_code } }
|
||||||
|
.to change { recipe.tasks.count }.by 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#macro' do
|
||||||
|
it 'defines the new recipe keyword' do
|
||||||
|
recipe.macro :hello
|
||||||
|
expect(recipe).to respond_to(:hello)
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when a defined macro is called' do
|
||||||
|
before { recipe.macro(:hello) { :some_macro_code } }
|
||||||
|
|
||||||
|
it 'registers the new task' do
|
||||||
|
expect { recipe.hello }.to change { recipe.tasks.count }.by 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when a defined macro is called with arguments' do
|
||||||
|
before { recipe.macro(:hello) { |a, b| echo a, b } }
|
||||||
|
|
||||||
|
it 'evaluates task code with given arguments' do
|
||||||
|
recipe.hello :foo, :bar
|
||||||
|
expect(recipe.tasks.first.actions.first.arguments).to eq %i[foo bar]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#test_macro' do
|
||||||
|
it 'defines the new test' do
|
||||||
|
recipe.test_macro(:some_test) { }
|
||||||
|
expect(Condition::DSL.new(env)).to respond_to :some_test
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#set' do
|
||||||
|
it 'registers a key/value pair in env registry' do
|
||||||
|
recipe.set :some_key, :some_value
|
||||||
|
expect(env[:some_key]).to eq :some_value
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#get' do
|
||||||
|
it 'fetches a value from the registry at given index' do
|
||||||
|
recipe.set :some_key, :some_value
|
||||||
|
expect(recipe.get :some_key).to eq :some_value
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
Loading…
x
Reference in New Issue
Block a user