playmo 0.0.18 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +107 -10
- data/TODO.md +57 -33
- data/lib/playmo.rb +28 -29
- data/lib/playmo/action.rb +38 -0
- data/lib/playmo/answer.rb +17 -8
- data/lib/playmo/choice.rb +23 -22
- data/lib/playmo/cli.rb +31 -9
- data/lib/playmo/cookbook.rb +16 -17
- data/lib/playmo/question.rb +70 -37
- data/lib/playmo/recipe.rb +115 -32
- data/lib/playmo/recipes/application_controller_recipe.rb +12 -21
- data/lib/playmo/recipes/application_helper_recipe.rb +26 -37
- data/lib/playmo/recipes/assets_recipe.rb +8 -17
- data/lib/playmo/recipes/capistrano_recipe.rb +13 -24
- data/lib/playmo/recipes/compass_recipe.rb +7 -18
- data/lib/playmo/recipes/devise_recipe.rb +155 -168
- data/lib/playmo/recipes/forms_recipe.rb +16 -38
- data/lib/playmo/recipes/gemfile_recipe.rb +10 -0
- data/lib/playmo/recipes/git_recipe.rb +23 -29
- data/lib/playmo/recipes/home_controller_recipe.rb +60 -73
- data/lib/playmo/recipes/javascript_framework_recipe.rb +27 -42
- data/lib/playmo/recipes/layout_recipe.rb +9 -19
- data/lib/playmo/recipes/locale_recipe.rb +22 -0
- data/lib/playmo/recipes/markup_recipe.rb +15 -28
- data/lib/playmo/recipes/rails_recipe.rb +8 -0
- data/lib/playmo/recipes/rspec_recipe.rb +18 -35
- data/lib/playmo/recipes/rvm_recipe.rb +9 -16
- data/lib/playmo/recipes/setup_database_recipe.rb +10 -19
- data/lib/playmo/recipes/thinking_sphinx_recipe.rb +10 -25
- data/lib/playmo/recipes/unicorn_recipe.rb +8 -19
- data/lib/playmo/silent.rb +3 -13
- data/lib/playmo/version.rb +2 -2
- metadata +16 -13
- data/lib/playmo/recipes/congrats_recipe.rb +0 -20
data/lib/playmo/cookbook.rb
CHANGED
@@ -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
|
-
|
9
|
+
include Singleton
|
8
10
|
|
9
|
-
|
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
|
-
|
39
|
-
|
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
|
-
|
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
|
data/lib/playmo/question.rb
CHANGED
@@ -1,59 +1,92 @@
|
|
1
|
+
require 'thor/shell/basic'
|
2
|
+
require 'thor/shell/color'
|
3
|
+
|
1
4
|
module Playmo
|
2
|
-
|
3
|
-
|
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
|
-
|
17
|
-
|
18
|
-
end
|
8
|
+
class Question
|
9
|
+
attr_accessor :question, :answers, :recipe, :action, :shell, :color, :options
|
19
10
|
|
20
|
-
def
|
21
|
-
|
22
|
-
|
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
|
-
|
25
|
-
|
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
|
33
|
-
|
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
|
-
|
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
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
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
|
-
|
52
|
-
@choice = Playmo::Choice.new(self, @caller)
|
68
|
+
shell.say("\n")
|
53
69
|
|
54
|
-
|
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
|
-
|
5
|
-
|
6
|
-
|
4
|
+
autoload :Action
|
5
|
+
autoload :Question
|
6
|
+
autoload :Silent
|
7
7
|
|
8
|
-
|
9
|
-
def
|
10
|
-
|
11
|
-
|
12
|
-
setup
|
8
|
+
module Recipe
|
9
|
+
def recipe(name, options = {}, &block)
|
10
|
+
Dsl.new(name, options, &block)
|
11
|
+
end
|
13
12
|
|
14
|
-
|
15
|
-
|
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
|
-
|
18
|
-
|
25
|
+
def store(*args)
|
26
|
+
Options.instance.set(*args)
|
27
|
+
end
|
19
28
|
|
20
|
-
|
21
|
-
|
29
|
+
def retrieve(*args)
|
30
|
+
Options.instance.get(*args)
|
22
31
|
end
|
23
32
|
|
24
|
-
#
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
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
|
-
|
34
|
-
|
35
|
-
|
47
|
+
def before_exit(&block)
|
48
|
+
Event.events.listen(:before_exit) do
|
49
|
+
# TODO: DRY this
|
50
|
+
recipe_name = name
|
36
51
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
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
|
-
|
43
|
-
|
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
|
-
|
47
|
-
|
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
|
-
|
2
|
-
|
3
|
-
|
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
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
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
|
-
|
15
|
-
|
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
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
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
|
-
|
7
|
-
|
8
|
-
|
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
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
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
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
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
|