playmo 0.0.18 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (34) hide show
  1. data/README.md +107 -10
  2. data/TODO.md +57 -33
  3. data/lib/playmo.rb +28 -29
  4. data/lib/playmo/action.rb +38 -0
  5. data/lib/playmo/answer.rb +17 -8
  6. data/lib/playmo/choice.rb +23 -22
  7. data/lib/playmo/cli.rb +31 -9
  8. data/lib/playmo/cookbook.rb +16 -17
  9. data/lib/playmo/question.rb +70 -37
  10. data/lib/playmo/recipe.rb +115 -32
  11. data/lib/playmo/recipes/application_controller_recipe.rb +12 -21
  12. data/lib/playmo/recipes/application_helper_recipe.rb +26 -37
  13. data/lib/playmo/recipes/assets_recipe.rb +8 -17
  14. data/lib/playmo/recipes/capistrano_recipe.rb +13 -24
  15. data/lib/playmo/recipes/compass_recipe.rb +7 -18
  16. data/lib/playmo/recipes/devise_recipe.rb +155 -168
  17. data/lib/playmo/recipes/forms_recipe.rb +16 -38
  18. data/lib/playmo/recipes/gemfile_recipe.rb +10 -0
  19. data/lib/playmo/recipes/git_recipe.rb +23 -29
  20. data/lib/playmo/recipes/home_controller_recipe.rb +60 -73
  21. data/lib/playmo/recipes/javascript_framework_recipe.rb +27 -42
  22. data/lib/playmo/recipes/layout_recipe.rb +9 -19
  23. data/lib/playmo/recipes/locale_recipe.rb +22 -0
  24. data/lib/playmo/recipes/markup_recipe.rb +15 -28
  25. data/lib/playmo/recipes/rails_recipe.rb +8 -0
  26. data/lib/playmo/recipes/rspec_recipe.rb +18 -35
  27. data/lib/playmo/recipes/rvm_recipe.rb +9 -16
  28. data/lib/playmo/recipes/setup_database_recipe.rb +10 -19
  29. data/lib/playmo/recipes/thinking_sphinx_recipe.rb +10 -25
  30. data/lib/playmo/recipes/unicorn_recipe.rb +8 -19
  31. data/lib/playmo/silent.rb +3 -13
  32. data/lib/playmo/version.rb +2 -2
  33. metadata +16 -13
  34. data/lib/playmo/recipes/congrats_recipe.rb +0 -20
@@ -1,18 +1,17 @@
1
+ require 'singleton'
2
+
1
3
  module Playmo
2
4
 
3
5
  # This class contains all registered recipes.
4
6
  # You can register own recipe in this class
5
7
  class Cookbook
6
8
  include Enumerable
7
- attr_accessor :recipes, :cooked_recipes
9
+ include Singleton
8
10
 
9
- def self.instance
10
- @@instance ||= Playmo::Cookbook.new
11
- end
11
+ attr_accessor :recipes
12
12
 
13
13
  def initialize
14
14
  @recipes = []
15
- @cooked_recipes = []
16
15
  end
17
16
 
18
17
  def each
@@ -35,11 +34,10 @@ module Playmo
35
34
  recipes.delete target
36
35
  end
37
36
 
38
- # Is recipe already cooked?
39
- def cooked?(recipe)
40
- @cooked_recipes.include?(recipe)
37
+ def delete_all
38
+ self.recipes = []
41
39
  end
42
-
40
+
43
41
  # Adds the new recipe before the specified existing recipe in the Cookbook stack.
44
42
  def insert(existing_recipe, new_recipe)
45
43
  index = assert_index(existing_recipe, :before)
@@ -59,17 +57,18 @@ module Playmo
59
57
  recipes.push(new_recipe)
60
58
  end
61
59
 
62
- def cook_recipes!(application_name)
63
- prepared_recipes = []
64
-
60
+ def cook_recipes!(application_name, options)
65
61
  recipes.each do |recipe|
66
- prepared_recipes << recipe.new
67
- end
68
-
69
- prepared_recipes.each do |recipe|
62
+ #puts recipe.name
70
63
  recipe.cook!(application_name)
71
- @cooked_recipes << recipe
72
64
  end
65
+
66
+ # Execute all actions
67
+ Playmo::Action.execute_all unless options['dry-run']
68
+ end
69
+
70
+ def find_recipe(recipe_symbol)
71
+ recipes.find { |recipe| recipe.name == recipe_symbol }
73
72
  end
74
73
 
75
74
  protected
@@ -1,59 +1,92 @@
1
+ require 'thor/shell/basic'
2
+ require 'thor/shell/color'
3
+
1
4
  module Playmo
2
- class Question < Thor::Shell::Basic
3
- attr_accessor :answers, :choice, :question_text, :caller
4
-
5
- def initialize(arg, &block)
6
- @question_text, method_name = arg, nil
7
- @answers ||= []
8
- @padding = 0
9
-
10
- # Question with no answers
11
- if arg.respond_to? :keys
12
- @question_text, method_name = arg.first.first, arg.first.last
13
- answer(nil => method_name)
14
- end
5
+ autoload :Answer
6
+ autoload :Choice
15
7
 
16
- # Multiple answers
17
- self.instance_eval(&block) if block_given?
18
- end
8
+ class Question
9
+ attr_accessor :question, :answers, :recipe, :action, :shell, :color, :options
19
10
 
20
- def set_caller(recipe)
21
- @caller = recipe
22
- end
11
+ def initialize(recipe, question, options, &block)
12
+ @question = question
13
+ @answers = []
14
+ @recipe = recipe
15
+ @options = options
16
+ @action = block
17
+ @shell = Thor::Shell::Basic.new
18
+ @color = Thor::Shell::Color.new
19
+
20
+ if @options[:type] == :question
21
+ instance_eval &block
22
+ elsif @options[:type] == :ask && block.arity == 0
23
+ answer(nil, nil, &block)
24
+ elsif @options[:type] == :ask && block.arity > 0
25
+ answer(nil, nil, &block)
26
+ end
27
+
28
+ # Do stuff with block
29
+ =begin
30
+ if block.arity > 0
31
+ # We have block with args
32
+ #answer(nil, nil, &block)
33
+ #@action = block
34
+ else
35
+ #instance_eval &block
36
+ raise block.methods.inspect
37
+ end
23
38
 
24
- def answer(arg)
25
- @answers << Playmo::Answer.new(arg.first.first, arg.first.last, @answers.size + 1)
39
+ # If block without answers was passed
40
+ unless has_answers?
41
+ answer(nil, nil, &block)
42
+ end
43
+ =end
26
44
  end
27
45
 
28
46
  def has_answers?
29
47
  @answers.size > 1
30
48
  end
31
49
 
32
- def ask_question!
33
- say render
50
+ def answer(answer, options = {}, &block)
51
+ @answers << Playmo::Answer.new(answer, options, @answers.size + 1, &block)
34
52
  end
35
53
 
36
- # Render question with answers
37
54
  def render
38
- result = "\n#{@question_text}"
39
-
55
+ shell.padding = 1
56
+ shell.say("\n")
57
+ shell.say(color.set_color(question, :green, true))
58
+ shell.say(color.set_color(recipe.description, :white, false))
59
+
40
60
  if has_answers?
41
- result += ":\n\n"
42
- num = 1
43
- @answers.each do |answer|
44
- result += answer.render
45
- num += 1
61
+ shell.say("\n")
62
+
63
+ answers.each do |answer|
64
+ shell.say("#{answer}")
46
65
  end
47
- else
48
- result += "\n"
49
66
  end
50
67
 
51
- # Create choice
52
- @choice = Playmo::Choice.new(self, @caller)
68
+ shell.say("\n")
53
69
 
54
- result
70
+ if options[:type] == :ask && action.arity > 0
71
+ response = shell.ask('Enter value:')
72
+
73
+ answer_action = action
74
+
75
+ x = Proc.new { answer_action.call(response) }
76
+ Playmo::Action.new(recipe, &x)
77
+ #Playmo::Action.new(recipe, &answer_action)# { action.call }#.call('en') }
78
+ else
79
+ choice = Playmo::Choice.new(self)
80
+ answer_action = choice.get_answer.action
81
+ Playmo::Action.new(recipe, &answer_action)
82
+ end
83
+ #if has_answers?
84
+ # Playmo::Action.new(recipe, &answer_action)
85
+ #else
86
+ # Playmo::Action.new(recipe, &action)
87
+ #end
55
88
  end
56
89
 
57
90
  alias :to_s :render
58
91
  end
59
- end
92
+ end
data/lib/playmo/recipe.rb CHANGED
@@ -1,50 +1,133 @@
1
1
  require 'rails/generators'
2
2
 
3
3
  module Playmo
4
- # Base class for all recipes
5
- class Recipe < Rails::Generators::Base
6
- attr_accessor :question_instance, :silents, :application_name
4
+ autoload :Action
5
+ autoload :Question
6
+ autoload :Silent
7
7
 
8
- # Приготовление рецепта
9
- def cook!(application_name)
10
- self.destination_root = application_name
11
- self.application_name = application_name
12
- setup
8
+ module Recipe
9
+ def recipe(name, options = {}, &block)
10
+ Dsl.new(name, options, &block)
11
+ end
13
12
 
14
- unless question_instance.nil?
15
- question_instance.set_caller(self)
13
+ # Переименовать этот класс в DSL, и сделать отдельный класс Recipe,
14
+ # который будет предком DSL и от которого можно наследоваться для создания complex recipes
15
+ # У класса DSL будут еще свои методы типма build (?)
16
+ class Recipe < Rails::Generators::Base
17
+ attr_accessor :actions, :application_name
18
+
19
+ def initialize
20
+ super
21
+
22
+ @actions = []
23
+ end
16
24
 
17
- # Ask question
18
- question_instance.ask_question!
25
+ def store(*args)
26
+ Options.instance.set(*args)
27
+ end
19
28
 
20
- # Ask for choice and make choice
21
- question_instance.choice.make_choice!
29
+ def retrieve(*args)
30
+ Options.instance.get(*args)
22
31
  end
23
32
 
24
- # Execute all silents
25
- unless silents.nil?
26
- silents.each do |silent|
27
- silent.set_caller(self)
28
- silent.execute!
33
+ # TODO: Move it into module
34
+ def after_install(&block)
35
+ Event.events.listen(:after_install) do
36
+ # TODO: DRY this
37
+ recipe_name = name
38
+
39
+ self.class.class_eval do
40
+ source_root File.expand_path("../recipes/templates/#{recipe_name}_recipe", __FILE__)
41
+ end
42
+
43
+ self.instance_eval &block
29
44
  end
30
45
  end
31
- end
32
46
 
33
- def question(arg, &block)
34
- @question_instance = Playmo::Question.new(arg, &block)
35
- end
47
+ def before_exit(&block)
48
+ Event.events.listen(:before_exit) do
49
+ # TODO: DRY this
50
+ recipe_name = name
36
51
 
37
- def silently(&block)
38
- @silents ||= []
39
- @silents << Playmo::Silent.new(&block)
40
- end
52
+ self.class.class_eval do
53
+ source_root File.expand_path("../recipes/templates/#{recipe_name}_recipe", __FILE__)
54
+ end
55
+
56
+ self.instance_eval &block
57
+ end
58
+ end
41
59
 
42
- def store(*args)
43
- Options.instance.set(*args)
60
+ def generate(*args)
61
+ after_install { super(*args) }
62
+ end
63
+
64
+ #def template(*args)
65
+ # after_install { super(*args) }
66
+ #end
67
+
68
+ def cook!(application_name)
69
+ self.destination_root = application_name
70
+ self.application_name = application_name
71
+
72
+ actions.each do |action|
73
+ action.call
74
+ end
75
+ end
76
+
77
+ def to_s
78
+ name
79
+ end
44
80
  end
45
81
 
46
- def retrieve(*args)
47
- Options.instance.get(*args)
82
+
83
+ class Dsl < Playmo::Recipe::Recipe
84
+ attr_accessor :description, :name, :options, :after
85
+
86
+ def initialize(name, options, &block)
87
+ super()
88
+
89
+ raise 'Recipe name not specified!' unless name
90
+
91
+ @name = name
92
+ @options = options
93
+ #@actions = []
94
+
95
+ instance_eval &block
96
+ end
97
+
98
+ def description(description = nil)
99
+ @description = description if description.present?
100
+ @description
101
+ end
102
+
103
+ # Если блок с агрументами - то поддерживается ввод данных пользователем
104
+ def question(question, &block)
105
+ actions << lambda { Playmo::Question.new(self, question, :type => :question, &block).to_s }
106
+ end
107
+
108
+ def ask(question, &block)
109
+ actions << lambda { Playmo::Question.new(self, question, :type => :ask, &block).to_s }
110
+ end
111
+
112
+ def silently(&block)
113
+ actions << lambda { Playmo::Silent.new(self, &block) }
114
+ end
115
+
116
+ # TODO: Сделать автолоадинг для зависимых рецептов
117
+ def after(after)
118
+ @after = after
119
+ after_recipe = Playmo::Cookbook.instance.find_recipe(@after)
120
+
121
+ if after_recipe.nil? && @after.present?
122
+ require "#{File.dirname(__FILE__)}/recipes/#{@after}_recipe.rb"
123
+ end
124
+
125
+ if after_recipe.nil?
126
+ Playmo::Cookbook.instance.use(self)
127
+ else
128
+ Playmo::Cookbook.instance.insert_after(after_recipe, self)
129
+ end
130
+ end
48
131
  end
49
132
  end
50
- end
133
+ end
@@ -1,24 +1,15 @@
1
- module Playmo
2
- module Recipes
3
- class ApplicationControllerRecipe < Playmo::Recipe
4
- source_root File.expand_path('../templates/application_controller_recipe', __FILE__)
1
+ recipe :application_controller do
2
+ description 'This will add ApplicationController with 404 and 500 errors handling'
3
+ after :assets
5
4
 
6
- def setup
7
- silently do
8
- remove_file 'app/controllers/application_controller.rb'
9
- copy_file 'application_controller.rb', 'app/controllers/application_controller.rb'
10
- empty_directory "app/views/application"
11
- copy_file "internal_error.html.erb", "app/views/application/internal_error.html.erb"
12
- copy_file "not_found.html.erb", "app/views/application/not_found.html.erb"
5
+ silently do
6
+ remove_file 'app/controllers/application_controller.rb', :verbose => true
7
+ copy_file 'application_controller.rb', 'app/controllers/application_controller.rb'
8
+ empty_directory "app/views/application"
9
+ copy_file "internal_error.html.erb", "app/views/application/internal_error.html.erb"
10
+ copy_file "not_found.html.erb", "app/views/application/not_found.html.erb"
13
11
 
14
- # To catch routing errors
15
- route 'match "*catch_all" => "application#not_found"'
16
- end
17
- end
18
- end
12
+ # To catch routing errors
13
+ route 'match "*catch_all" => "application#not_found"'
19
14
  end
20
- end
21
-
22
- # Write down this recipe to our Cookbook if it's available
23
- require File.dirname(__FILE__) + '/assets_recipe'
24
- Playmo::Cookbook.instance.insert_after(Playmo::Recipes::AssetsRecipe, Playmo::Recipes::ApplicationControllerRecipe) if defined?(Playmo::Cookbook)
15
+ end
@@ -1,42 +1,31 @@
1
- module Playmo
2
- module Recipes
3
- class ApplicationHelperRecipe < Playmo::Recipe
4
- source_root File.expand_path('../templates/application_helper_recipe', __FILE__)
1
+ recipe :application_helper do
2
+ description 'This will add helpers that used within generated layout and views'
3
+ after :home_controller
4
+
5
+ silently do
6
+ remove_file 'app/helpers/application_helper.rb'
7
+ copy_file 'application_helper.rb', 'app/helpers/application_helper.rb'
5
8
 
6
- def setup
7
- silently do
8
- remove_file 'app/helpers/application_helper.rb'
9
- copy_file 'application_helper.rb', 'app/helpers/application_helper.rb'
9
+ # TODO: Add version for prototype and Jquery
10
+ # TODO: Translate flash_messages.js to CoffeeScript
11
+ copy_file 'flash_messages.js', 'app/assets/javascripts/flash_messages.js'
10
12
 
11
- # TODO: Add version for prototype and Jquery
12
- # TODO: Translate flash_messages.js to CoffeeScript
13
- copy_file 'flash_messages.js', 'app/assets/javascripts/flash_messages.js'
14
-
15
- Event.events.listen(:after_install) do
16
- gsub_file 'app/assets/javascripts/application.js', '//= require_tree .' do
17
- <<-CONTENT.gsub(/^ {16}/, '')
18
- //= require flash_messages
19
- //= require_tree .
20
- CONTENT
21
- end
22
- end
13
+ gsub_file 'app/assets/javascripts/application.js', '//= require_tree .' do
14
+ <<-CONTENT.gsub(/^ {8}/, '')
15
+ //= require flash_messages
16
+ //= require_tree .
17
+ CONTENT
18
+ end
23
19
 
24
- gsub_file 'config/locales/en.yml', 'en:' do
25
- <<-CONTENT.gsub(/^ {14}/, '')
26
- en:
27
- helpers:
28
- application:
29
- link_to_delete:
30
- link_text: Delete?
31
- confirmation: Are you sure?
32
- CONTENT
33
- end
34
- end
35
- end
20
+ gsub_file 'config/locales/en.yml', 'en:' do
21
+ <<-CONTENT.gsub(/^ {8}/, '')
22
+ en:
23
+ helpers:
24
+ application:
25
+ link_to_delete:
26
+ link_text: Delete?
27
+ confirmation: Are you sure?
28
+ CONTENT
36
29
  end
37
30
  end
38
- end
39
-
40
- # Write down this recipe to our Cookbook if it's available
41
- require File.dirname(__FILE__) + '/home_controller_recipe'
42
- Playmo::Cookbook.instance.insert_after(Playmo::Recipes::HomeControllerRecipe, Playmo::Recipes::ApplicationHelperRecipe) if defined?(Playmo::Cookbook)
31
+ end