lib/playmo/recipe.rb in playmo-0.0.18 vs lib/playmo/recipe.rb in playmo-0.1.0
- old
+ new
@@ -1,50 +1,133 @@
require 'rails/generators'
module Playmo
- # Base class for all recipes
- class Recipe < Rails::Generators::Base
- attr_accessor :question_instance, :silents, :application_name
+ autoload :Action
+ autoload :Question
+ autoload :Silent
- # Приготовление рецепта
- def cook!(application_name)
- self.destination_root = application_name
- self.application_name = application_name
- setup
+ module Recipe
+ def recipe(name, options = {}, &block)
+ Dsl.new(name, options, &block)
+ end
- unless question_instance.nil?
- question_instance.set_caller(self)
+ # Переименовать этот класс в DSL, и сделать отдельный класс Recipe,
+ # который будет предком DSL и от которого можно наследоваться для создания complex recipes
+ # У класса DSL будут еще свои методы типма build (?)
+ class Recipe < Rails::Generators::Base
+ attr_accessor :actions, :application_name
+
+ def initialize
+ super
+
+ @actions = []
+ end
- # Ask question
- question_instance.ask_question!
+ def store(*args)
+ Options.instance.set(*args)
+ end
- # Ask for choice and make choice
- question_instance.choice.make_choice!
+ def retrieve(*args)
+ Options.instance.get(*args)
end
- # Execute all silents
- unless silents.nil?
- silents.each do |silent|
- silent.set_caller(self)
- silent.execute!
+ # TODO: Move it into module
+ def after_install(&block)
+ Event.events.listen(:after_install) do
+ # TODO: DRY this
+ recipe_name = name
+
+ self.class.class_eval do
+ source_root File.expand_path("../recipes/templates/#{recipe_name}_recipe", __FILE__)
+ end
+
+ self.instance_eval &block
end
end
- end
- def question(arg, &block)
- @question_instance = Playmo::Question.new(arg, &block)
- end
+ def before_exit(&block)
+ Event.events.listen(:before_exit) do
+ # TODO: DRY this
+ recipe_name = name
- def silently(&block)
- @silents ||= []
- @silents << Playmo::Silent.new(&block)
- end
+ self.class.class_eval do
+ source_root File.expand_path("../recipes/templates/#{recipe_name}_recipe", __FILE__)
+ end
+
+ self.instance_eval &block
+ end
+ end
- def store(*args)
- Options.instance.set(*args)
+ def generate(*args)
+ after_install { super(*args) }
+ end
+
+ #def template(*args)
+ # after_install { super(*args) }
+ #end
+
+ def cook!(application_name)
+ self.destination_root = application_name
+ self.application_name = application_name
+
+ actions.each do |action|
+ action.call
+ end
+ end
+
+ def to_s
+ name
+ end
end
- def retrieve(*args)
- Options.instance.get(*args)
+
+ class Dsl < Playmo::Recipe::Recipe
+ attr_accessor :description, :name, :options, :after
+
+ def initialize(name, options, &block)
+ super()
+
+ raise 'Recipe name not specified!' unless name
+
+ @name = name
+ @options = options
+ #@actions = []
+
+ instance_eval &block
+ end
+
+ def description(description = nil)
+ @description = description if description.present?
+ @description
+ end
+
+ # Если блок с агрументами - то поддерживается ввод данных пользователем
+ def question(question, &block)
+ actions << lambda { Playmo::Question.new(self, question, :type => :question, &block).to_s }
+ end
+
+ def ask(question, &block)
+ actions << lambda { Playmo::Question.new(self, question, :type => :ask, &block).to_s }
+ end
+
+ def silently(&block)
+ actions << lambda { Playmo::Silent.new(self, &block) }
+ end
+
+ # TODO: Сделать автолоадинг для зависимых рецептов
+ def after(after)
+ @after = after
+ after_recipe = Playmo::Cookbook.instance.find_recipe(@after)
+
+ if after_recipe.nil? && @after.present?
+ require "#{File.dirname(__FILE__)}/recipes/#{@after}_recipe.rb"
+ end
+
+ if after_recipe.nil?
+ Playmo::Cookbook.instance.use(self)
+ else
+ Playmo::Cookbook.instance.insert_after(after_recipe, self)
+ end
+ end
end
end
-end
+end
\ No newline at end of file