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