playmo 0.0.18 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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