ey_rails_wizard 0.3.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +8 -0
- data/.rspec +2 -0
- data/.travis.yml +6 -0
- data/ChangeLog.md +23 -0
- data/Gemfile +3 -0
- data/MIT_LICENSE +20 -0
- data/README.md +78 -0
- data/Rakefile +45 -0
- data/autotest/discover.rb +1 -0
- data/bin/ey_rails_wizard +7 -0
- data/ey_rails_wizard.gemspec +28 -0
- data/lib/rails_wizard/command.rb +79 -0
- data/lib/rails_wizard/config.rb +86 -0
- data/lib/rails_wizard/recipe.rb +106 -0
- data/lib/rails_wizard/recipes.rb +38 -0
- data/lib/rails_wizard/template.rb +67 -0
- data/lib/rails_wizard.rb +10 -0
- data/recipes/active_admin.rb +18 -0
- data/recipes/activerecord.rb +69 -0
- data/recipes/cancan.rb +16 -0
- data/recipes/capybara.rb +34 -0
- data/recipes/carrierwave.rb +42 -0
- data/recipes/carrierwave_direct.rb +13 -0
- data/recipes/cartographer.rb +33 -0
- data/recipes/cucumber.rb +17 -0
- data/recipes/delayed_job.rb +16 -0
- data/recipes/devise.rb +52 -0
- data/recipes/devise_invitable.rb +23 -0
- data/recipes/env_yaml.rb +53 -0
- data/recipes/event_calendar.rb +12 -0
- data/recipes/eycloud.rb +30 -0
- data/recipes/eycloud_recipes_on_deploy.rb +20 -0
- data/recipes/factory_girl.rb +38 -0
- data/recipes/ffaker.rb +22 -0
- data/recipes/fixture_builder.rb +35 -0
- data/recipes/forgery.rb +15 -0
- data/recipes/git.rb +15 -0
- data/recipes/haml.rb +11 -0
- data/recipes/heroku.rb +58 -0
- data/recipes/hoptoad.rb +34 -0
- data/recipes/inherited_resources.rb +12 -0
- data/recipes/jammit.rb +43 -0
- data/recipes/jasmine.rb +12 -0
- data/recipes/jquery.rb +20 -0
- data/recipes/mini_magick.rb +13 -0
- data/recipes/mongo_mapper.rb +20 -0
- data/recipes/mongohq.rb +61 -0
- data/recipes/mongoid.rb +20 -0
- data/recipes/mootools.rb +23 -0
- data/recipes/mysql.rb +19 -0
- data/recipes/nifty_generators.rb +21 -0
- data/recipes/oa_oauth.rb +12 -0
- data/recipes/omniauth.rb +17 -0
- data/recipes/paper_trail.rb +17 -0
- data/recipes/pow.rb +12 -0
- data/recipes/prototype.rb +11 -0
- data/recipes/puma.rb +10 -0
- data/recipes/rails_admin.rb +21 -0
- data/recipes/rails_basics.rb +45 -0
- data/recipes/rails_dev_tweaks.rb +10 -0
- data/recipes/rails_erd.rb +9 -0
- data/recipes/rails_footnotes.rb +14 -0
- data/recipes/ransack.rb +32 -0
- data/recipes/redis.rb +15 -0
- data/recipes/resque.rb +37 -0
- data/recipes/rmagick.rb +13 -0
- data/recipes/rspec.rb +21 -0
- data/recipes/sass.rb +13 -0
- data/recipes/sequel.rb +13 -0
- data/recipes/settingslogic.rb +43 -0
- data/recipes/shoulda_matchers.rb +11 -0
- data/recipes/simple_form.rb +19 -0
- data/recipes/slim.rb +11 -0
- data/recipes/sqlite3.rb +10 -0
- data/recipes/test_unit.rb +11 -0
- data/recipes/thin.rb +10 -0
- data/recipes/thinking_sphinx.rb +14 -0
- data/recipes/twitter_bootstrap_rails.rb +142 -0
- data/recipes/unicorn.rb +10 -0
- data/sample.rb +77 -0
- data/spec/rails_wizard/config_spec.rb +99 -0
- data/spec/rails_wizard/recipe_spec.rb +103 -0
- data/spec/rails_wizard/recipes/sanity_spec.rb +30 -0
- data/spec/rails_wizard/recipes_spec.rb +24 -0
- data/spec/rails_wizard/template_spec.rb +48 -0
- data/spec/spec_helper.rb +11 -0
- data/spec/support/rails_directory.rb +17 -0
- data/spec/support/template_runner.rb +28 -0
- data/templates/helpers.erb +45 -0
- data/templates/layout.erb +45 -0
- data/templates/recipe.erb +10 -0
- data/version.rb +3 -0
- metadata +232 -0
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/ChangeLog.md
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# ChangeLog
|
2
|
+
|
3
|
+
## v0.3
|
4
|
+
|
5
|
+
* Engine Yard support - Resque
|
6
|
+
* Removed a bunch of recipes that didn't see useful/common
|
7
|
+
|
8
|
+
### v0.3.1
|
9
|
+
|
10
|
+
* Resque recipe works a treat.
|
11
|
+
|
12
|
+
Try this on EY Cloud! `ey_rails_wizard new demomysql -r sqlite3 mysql resque rails_basics git`
|
13
|
+
|
14
|
+
## v0.2
|
15
|
+
|
16
|
+
Merged lots of branches/forks
|
17
|
+
|
18
|
+
## v0.2.1
|
19
|
+
|
20
|
+
* Cleaned up many recipes
|
21
|
+
* Added :website attribute to recipes
|
22
|
+
* Convert all recipes to use supported categories
|
23
|
+
|
data/Gemfile
ADDED
data/MIT_LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2012 Dr Nic Williams and Engine Yard LLC
|
2
|
+
Copyright (c) 2010 Michael Bleigh and Intridea, Inc.
|
3
|
+
|
4
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
5
|
+
of this software and associated documentation files (the "Software"), to deal
|
6
|
+
in the Software without restriction, including without limitation the rights
|
7
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
8
|
+
copies of the Software, and to permit persons to whom the Software is
|
9
|
+
furnished to do so, subject to the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be included in
|
12
|
+
all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
15
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
16
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
17
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
18
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
19
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
20
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
# Engine Yard Rails Wizard Gem
|
2
|
+
|
3
|
+
The Engine Yard RailsWizard gem is both the official repository of recipes for [Engine Yard RailsWizard][1] as well as a stand-alone tool to generate rails templates from the command line. The website and the gem are kept in version sync, so any recipes released to the gem will be simultaneously available on the web builder.
|
4
|
+
|
5
|
+
This is a fork of the original [RailsWizard gem][4] specifically for Engine Yard Cloud customers. We are very thankful to Michael Bleigh and Intridea for creating Rails Wizard.
|
6
|
+
|
7
|
+
Generated applications may include EY Cloud recipes to setup/run required services.
|
8
|
+
|
9
|
+
## Installation
|
10
|
+
|
11
|
+
Installation is simple:
|
12
|
+
|
13
|
+
gem install ey_rails_wizard
|
14
|
+
|
15
|
+
## Usage
|
16
|
+
|
17
|
+
The primary usage of the `ey_rails_wizard` gem is to utilize its interactive terminal command to build a Rails template. To get started, you can simply run the command thusly:
|
18
|
+
|
19
|
+
ey_rails_wizard new APP_NAME
|
20
|
+
|
21
|
+
Where `APP_NAME` is the directory in which you wish to create the app (it mirrors the Rails creation syntax). You will then be guided through the recipe selection process and subsequently the Rails app generator will automatically run with the template and all appropriate command line options included.
|
22
|
+
|
23
|
+
### Specifying Recipes
|
24
|
+
|
25
|
+
If you wish to skip the interactive recipe selector, you may provide instead a list of recipes with the `-r` option:
|
26
|
+
|
27
|
+
ey_rails_wizard new APP_NAME -r jquery mongo_mapper sass
|
28
|
+
|
29
|
+
This will automatically generate a Rails template with the provided recipes and begin the app generator.
|
30
|
+
|
31
|
+
### Listing Recipes
|
32
|
+
|
33
|
+
You can also print out a simple list of recipes:
|
34
|
+
|
35
|
+
ey_rails_wizard list
|
36
|
+
|
37
|
+
Or print out a list of recipes for a specific category:
|
38
|
+
|
39
|
+
ey_rails_wizard list persistence
|
40
|
+
|
41
|
+
# EY Rails Wizard Recipes
|
42
|
+
|
43
|
+
The Engine Yard Rails Wizard recipe collection now live in this GitHub repository to make them fork-friendly and available for use with the command-line tool. You can see all of the recipes in the [recipes directory][2].
|
44
|
+
|
45
|
+
If you're looking for the web app source code, it now lives at [ey_rails_wizard.web][3].
|
46
|
+
|
47
|
+
## Submitting a Recipe
|
48
|
+
|
49
|
+
Submitting a recipe is actually a very straightforward process. Recipes are made of up **template code** and **YAML back-matter** stored in a ruby file. The `__END__` parsing convention is used so that each recipe is actually a valid, parseable Ruby file. The structure of a recipe looks something like this:
|
50
|
+
|
51
|
+
```ruby
|
52
|
+
gem 'supergem'
|
53
|
+
|
54
|
+
after_bundler do
|
55
|
+
generate "supergem:install"
|
56
|
+
end
|
57
|
+
|
58
|
+
__END__
|
59
|
+
|
60
|
+
category: templating
|
61
|
+
name: SuperGem
|
62
|
+
description: Installs SuperGem which is useful for things
|
63
|
+
author: mbleigh
|
64
|
+
```
|
65
|
+
|
66
|
+
It's really that simple. The gem has RSpec tests that automatically validate each recipe in the repository, so you should run `rake spec` as a basic sanity check before submitting a pull request. Note that these don't verify that your recipe code itself works, just that Engine Yard Rails Wizard could properly parse and understand your recipe file.
|
67
|
+
|
68
|
+
For more information on all available options for authoring recipes,
|
69
|
+
please see the
|
70
|
+
|
71
|
+
## License
|
72
|
+
|
73
|
+
Engine Yard Rails Wizard and its recipes are distributed under the MIT License.
|
74
|
+
|
75
|
+
[1]:http://railswizard.engineyard.com/
|
76
|
+
[2]:https://github.com/engineyard/ey_rails_wizard/tree/master/recipes
|
77
|
+
[3]:https://github.com/engineyard/ey_rails_wizard.web
|
78
|
+
[4]:https://github.com/intridea/rails_wizard
|
data/Rakefile
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
2
|
+
|
3
|
+
require 'rspec/core/rake_task'
|
4
|
+
|
5
|
+
desc "run specs"
|
6
|
+
RSpec::Core::RakeTask.new
|
7
|
+
|
8
|
+
task :default => :spec
|
9
|
+
|
10
|
+
|
11
|
+
desc "Remove the test_run Rails app (if it's there)"
|
12
|
+
task :clean do
|
13
|
+
system 'rm -rf test_run'
|
14
|
+
end
|
15
|
+
|
16
|
+
desc "Execute a test run with the specified recipes."
|
17
|
+
task :run => :clean do
|
18
|
+
recipes = ENV['RECIPES'].split(',')
|
19
|
+
|
20
|
+
require 'tempfile'
|
21
|
+
require 'rails_wizard'
|
22
|
+
|
23
|
+
template = RailsWizard::Template.new(recipes)
|
24
|
+
|
25
|
+
begin
|
26
|
+
dir = Dir.mktmpdir "rails_template"
|
27
|
+
Dir.chdir(dir) do
|
28
|
+
file = File.open('template.rb', 'w')
|
29
|
+
file.write template.compile
|
30
|
+
file.close
|
31
|
+
|
32
|
+
system "rails new test_run -m template.rb #{template.args.join(' ')}"
|
33
|
+
|
34
|
+
puts "\n\n cd #{dir} # look at the app"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
desc "Prints out a template from the provided recipes."
|
40
|
+
task :print do
|
41
|
+
require 'rails_wizard'
|
42
|
+
|
43
|
+
recipes = ENV['RECIPES'].split(',')
|
44
|
+
puts RailsWizard::Template.new(recipes).compile
|
45
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
Autotest.add_discovery { "rspec2" }
|
data/bin/ey_rails_wizard
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require File.dirname(__FILE__) + "/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "ey_rails_wizard"
|
7
|
+
s.version = RailsWizard::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["Michael Bleigh", "Dr Nic Williams"]
|
10
|
+
s.email = ["michael@intridea.com", "drnicwilliams@gmail.com"]
|
11
|
+
s.homepage = "http://railswizard.engineyard.com/"
|
12
|
+
s.summary = %q{A tool for quickly generating Rails applications for Engine Yard Cloud.}
|
13
|
+
s.description = %q{Quickly and easily create Rails application templates featuring dozens of popular libraries tuned for Engine Yard Cloud}
|
14
|
+
|
15
|
+
s.add_dependency "i18n"
|
16
|
+
s.add_dependency "activesupport", "~> 3.0"
|
17
|
+
s.add_dependency "thor"
|
18
|
+
s.add_development_dependency "rspec", "~> 2.5.0"
|
19
|
+
s.add_development_dependency "bundler", "~> 1.1.0"
|
20
|
+
s.add_development_dependency "rails", ">= 3.0.0"
|
21
|
+
s.add_development_dependency "ZenTest"
|
22
|
+
|
23
|
+
s.files = `git ls-files`.split("\n")
|
24
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
25
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
26
|
+
s.require_paths = ["lib"]
|
27
|
+
end
|
28
|
+
|
@@ -0,0 +1,79 @@
|
|
1
|
+
require 'rails_wizard'
|
2
|
+
require 'thor'
|
3
|
+
|
4
|
+
module RailsWizard
|
5
|
+
class Command < Thor
|
6
|
+
include Thor::Actions
|
7
|
+
desc "new APP_NAME", "create a new Rails app"
|
8
|
+
method_option :recipes, :type => :array, :aliases => "-r"
|
9
|
+
def new(name)
|
10
|
+
if options[:recipes]
|
11
|
+
run_template(name, options[:recipes])
|
12
|
+
else
|
13
|
+
@recipes = []
|
14
|
+
|
15
|
+
while recipe = ask("#{print_recipes}#{bold}Which recipe would you like to add? #{clear}#{yellow}(blank to finish)#{clear}")
|
16
|
+
if recipe == ''
|
17
|
+
run_template(name, @recipes)
|
18
|
+
break
|
19
|
+
elsif RailsWizard::Recipes.list.include?(recipe)
|
20
|
+
@recipes << recipe
|
21
|
+
puts
|
22
|
+
puts "> #{green}Added '#{recipe}' to template.#{clear}"
|
23
|
+
else
|
24
|
+
puts
|
25
|
+
puts "> #{red}Invalid recipe, please try again.#{clear}"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
desc "list [CATEGORY]", "list available recipes (optionally by category)"
|
32
|
+
def list(category = nil)
|
33
|
+
if category
|
34
|
+
recipes = RailsWizard::Recipes.for(category).map{|r| RailsWizard::Recipe.from_mongo(r) }
|
35
|
+
else
|
36
|
+
recipes = RailsWizard::Recipes.list_classes
|
37
|
+
end
|
38
|
+
|
39
|
+
recipes.each do |recipe|
|
40
|
+
puts recipe.key.ljust(15) + "# #{recipe.description}"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
no_tasks do
|
45
|
+
def cyan; "\033[36m" end
|
46
|
+
def clear; "\033[0m" end
|
47
|
+
def bold; "\033[1m" end
|
48
|
+
def red; "\033[31m" end
|
49
|
+
def green; "\033[32m" end
|
50
|
+
def yellow; "\033[33m" end
|
51
|
+
|
52
|
+
def print_recipes
|
53
|
+
puts
|
54
|
+
puts
|
55
|
+
puts
|
56
|
+
if @recipes && @recipes.any?
|
57
|
+
puts "#{green}#{bold}Your Recipes:#{clear} " + @recipes.join(", ")
|
58
|
+
puts
|
59
|
+
end
|
60
|
+
puts "#{bold}#{cyan}Available Recipes:#{clear} " + RailsWizard::Recipes.list.join(', ')
|
61
|
+
puts
|
62
|
+
end
|
63
|
+
|
64
|
+
def run_template(name, recipes)
|
65
|
+
puts
|
66
|
+
puts
|
67
|
+
puts "#{bold}Generating and Running Template..."
|
68
|
+
puts
|
69
|
+
file = Tempfile.new('template')
|
70
|
+
template = RailsWizard::Template.new(recipes)
|
71
|
+
file.write template.compile
|
72
|
+
file.close
|
73
|
+
system "rails new #{name} -m #{file.path} #{template.args.join(' ')}"
|
74
|
+
ensure
|
75
|
+
file.unlink
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
require 'active_support/ordered_hash'
|
2
|
+
|
3
|
+
module RailsWizard
|
4
|
+
class Config
|
5
|
+
attr_reader :questions
|
6
|
+
|
7
|
+
def initialize(schema)
|
8
|
+
@questions = ActiveSupport::OrderedHash.new
|
9
|
+
schema.each do |hash|
|
10
|
+
key = hash.keys.first
|
11
|
+
details = hash.values.first
|
12
|
+
|
13
|
+
kind = details['type']
|
14
|
+
raise ArgumentError, "Unrecognized question type, must be one of #{QUESTION_TYPES.keys.join(', ')}" unless QUESTION_TYPES.keys.include?(kind)
|
15
|
+
@questions[key] = QUESTION_TYPES[kind].new(details)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def compile(values = {})
|
20
|
+
result = []
|
21
|
+
result << "config = #{values.inspect}"
|
22
|
+
@questions.each_pair do |key, question|
|
23
|
+
result << "config['#{key}'] = #{question.compile} unless config.key?('#{key}')"
|
24
|
+
end
|
25
|
+
result.join("\n")
|
26
|
+
end
|
27
|
+
|
28
|
+
class Prompt
|
29
|
+
attr_reader :prompt, :details
|
30
|
+
def initialize(details)
|
31
|
+
@details = details
|
32
|
+
@prompt = details['prompt']
|
33
|
+
end
|
34
|
+
|
35
|
+
def compile
|
36
|
+
"#{question} if #{conditions}"
|
37
|
+
end
|
38
|
+
|
39
|
+
def question
|
40
|
+
"ask_wizard(#{prompt.inspect})"
|
41
|
+
end
|
42
|
+
|
43
|
+
def conditions
|
44
|
+
[config_conditions, recipe_conditions].join(' && ')
|
45
|
+
end
|
46
|
+
|
47
|
+
def config_conditions
|
48
|
+
if details['if']
|
49
|
+
"config['#{details['if']}']"
|
50
|
+
elsif details['unless']
|
51
|
+
"!config['#{details['unless']}']"
|
52
|
+
else
|
53
|
+
'true'
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def recipe_conditions
|
58
|
+
if details['if_recipe']
|
59
|
+
"recipe?('#{details['if_recipe']}')"
|
60
|
+
elsif details['unless_recipe']
|
61
|
+
"!recipe?('#{details['unless_recipe']}')"
|
62
|
+
else
|
63
|
+
'true'
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
class TrueFalse < Prompt
|
69
|
+
def question
|
70
|
+
"yes_wizard?(#{prompt.inspect})"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
class MultipleChoice < Prompt
|
75
|
+
def question
|
76
|
+
"multiple_choice(#{prompt.inspect}, #{@details['choices'].inspect})"
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
QUESTION_TYPES = {
|
81
|
+
'boolean' => TrueFalse,
|
82
|
+
'string' => Prompt,
|
83
|
+
'multiple_choice' => MultipleChoice
|
84
|
+
}
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
require 'rails_wizard/config'
|
2
|
+
|
3
|
+
require 'active_support/inflector'
|
4
|
+
require 'yaml'
|
5
|
+
require 'erb'
|
6
|
+
|
7
|
+
module RailsWizard
|
8
|
+
class Recipe
|
9
|
+
extend Comparable
|
10
|
+
|
11
|
+
def self.<=>(another)
|
12
|
+
return -1 if another.run_after.include?(self.key) || self.run_before.include?(another.key)
|
13
|
+
return 1 if another.run_before.include?(self.key) || self.run_after.include?(another.key)
|
14
|
+
self.key <=> another.key
|
15
|
+
end
|
16
|
+
|
17
|
+
ATTRIBUTES = %w(key args category name description template config exclusive tags run_before run_after requires website)
|
18
|
+
DEFAULT_ATTRIBUTES = {
|
19
|
+
:category => 'other',
|
20
|
+
:args => [],
|
21
|
+
:tags => [],
|
22
|
+
:run_after => [],
|
23
|
+
:run_before => [],
|
24
|
+
:requires => []
|
25
|
+
}
|
26
|
+
|
27
|
+
def self.generate(key, template_or_file, attributes = {})
|
28
|
+
if template_or_file.respond_to?(:read)
|
29
|
+
file = template_or_file.read
|
30
|
+
parts = file.split(/^__END__$/)
|
31
|
+
raise ArgumentError, "The recipe file must have YAML matter after an __END__" unless parts.size == 2
|
32
|
+
template = parts.first.strip
|
33
|
+
attributes = YAML.load(parts.last).inject({}) do |h,(k,v)|
|
34
|
+
h[k.to_sym] = v
|
35
|
+
h
|
36
|
+
end.merge!(attributes)
|
37
|
+
else
|
38
|
+
template = template_or_file
|
39
|
+
end
|
40
|
+
|
41
|
+
recipe_class = Class.new(RailsWizard::Recipe)
|
42
|
+
recipe_class.attributes = attributes
|
43
|
+
recipe_class.template = template
|
44
|
+
recipe_class.key = key
|
45
|
+
|
46
|
+
recipe_class
|
47
|
+
end
|
48
|
+
|
49
|
+
ATTRIBUTES.each do |setter|
|
50
|
+
class_eval <<-RUBY
|
51
|
+
def self.#{setter}
|
52
|
+
attributes[:#{setter}]
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.#{setter}=(val)
|
56
|
+
attributes[:#{setter}] = val
|
57
|
+
end
|
58
|
+
|
59
|
+
def #{setter}
|
60
|
+
self.class.#{setter}
|
61
|
+
end
|
62
|
+
RUBY
|
63
|
+
end
|
64
|
+
|
65
|
+
# The attributes hash containing any set values for
|
66
|
+
def self.attributes
|
67
|
+
@attributes ||= DEFAULT_ATTRIBUTES.dup
|
68
|
+
end
|
69
|
+
|
70
|
+
def self.attributes=(hash)
|
71
|
+
attributes.merge! hash
|
72
|
+
end
|
73
|
+
|
74
|
+
def self.config
|
75
|
+
return nil unless attributes[:config]
|
76
|
+
RailsWizard::Config.new(attributes[:config])
|
77
|
+
end
|
78
|
+
|
79
|
+
def attributes
|
80
|
+
self.class.attributes
|
81
|
+
end
|
82
|
+
|
83
|
+
def self.compile
|
84
|
+
"# >#{"[ #{name} ]".center(75,'-')}<\n\n# #{description}\nsay_recipe '#{name}'\n\n#{template}\n"
|
85
|
+
end
|
86
|
+
def compile; self.class.compile end
|
87
|
+
|
88
|
+
def self.to_mongo(value)
|
89
|
+
case value
|
90
|
+
when Class
|
91
|
+
value.key
|
92
|
+
when String
|
93
|
+
value
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def self.from_mongo(key)
|
98
|
+
return key if key.respond_to?(:superclass) && key.superclass == RailsWizard::Recipe
|
99
|
+
RailsWizard::Recipes[key]
|
100
|
+
end
|
101
|
+
|
102
|
+
def self.get_binding
|
103
|
+
binding
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module RailsWizard
|
2
|
+
module Recipes
|
3
|
+
@@categories = {}
|
4
|
+
@@list = {}
|
5
|
+
|
6
|
+
def self.add(recipe)
|
7
|
+
RailsWizard::Recipes.const_set ActiveSupport::Inflector.camelize(recipe.key), recipe
|
8
|
+
@@list[recipe.key] = recipe
|
9
|
+
(@@categories[recipe.category.to_s] ||= []) << recipe.key
|
10
|
+
@@categories[recipe.category.to_s].uniq!
|
11
|
+
recipe
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.[](key)
|
15
|
+
@@list[key.to_s]
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.list
|
19
|
+
@@list.keys.sort
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.list_classes
|
23
|
+
@@list.values.sort_by{|c| c.key}
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.categories
|
27
|
+
@@categories.keys.sort
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.for(category)
|
31
|
+
(@@categories[category.to_s] || []).sort
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.remove_from_category(category, recipe)
|
35
|
+
(@@categories[category.to_s] ||= []).delete(recipe.key)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
module RailsWizard
|
2
|
+
class Template
|
3
|
+
attr_reader :recipes, :unknown_recipe_names
|
4
|
+
|
5
|
+
def initialize(recipes)
|
6
|
+
@unknown_recipe_names = []
|
7
|
+
@recipes = recipes.inject([]) do |list, name|
|
8
|
+
recipe = RailsWizard::Recipe.from_mongo(name)
|
9
|
+
if recipe
|
10
|
+
list << recipe
|
11
|
+
else
|
12
|
+
@unknown_recipe_names << name
|
13
|
+
$stderr.puts "Unknown recipe '#{name}'. Skipping."
|
14
|
+
end
|
15
|
+
list
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.template_root
|
20
|
+
File.dirname(__FILE__) + '/../../templates'
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.render(template_name, binding = nil)
|
24
|
+
erb = ERB.new(File.open(template_root + '/' + template_name + '.erb').read)
|
25
|
+
erb.result(binding)
|
26
|
+
end
|
27
|
+
def render(template_name, binding = nil); self.class.render(template_name, binding) end
|
28
|
+
|
29
|
+
|
30
|
+
def resolve_recipes
|
31
|
+
@resolve_recipes ||= recipes_with_dependencies.sort
|
32
|
+
end
|
33
|
+
|
34
|
+
def recipe_classes
|
35
|
+
@recipe_classes ||= recipes.map { |name| RailsWizard::Recipe.from_mongo(name) }
|
36
|
+
end
|
37
|
+
|
38
|
+
def recipes_with_dependencies
|
39
|
+
@recipes_with_dependencies ||= recipe_classes
|
40
|
+
|
41
|
+
added_more = false
|
42
|
+
for recipe in recipe_classes
|
43
|
+
recipe.requires.each do |requirement|
|
44
|
+
requirement = RailsWizard::Recipe.from_mongo(requirement)
|
45
|
+
count = @recipes_with_dependencies.size
|
46
|
+
(@recipes_with_dependencies << requirement).uniq!
|
47
|
+
unless @recipes_with_dependencies.size == count
|
48
|
+
added_more = true
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
added_more ? recipes_with_dependencies : @recipes_with_dependencies
|
54
|
+
end
|
55
|
+
|
56
|
+
def compile
|
57
|
+
render 'layout', binding
|
58
|
+
end
|
59
|
+
|
60
|
+
def args
|
61
|
+
recipes.map(&:args).uniq
|
62
|
+
end
|
63
|
+
|
64
|
+
def custom_code?; false end
|
65
|
+
def custom_code; nil end
|
66
|
+
end
|
67
|
+
end
|
data/lib/rails_wizard.rb
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
require 'rails_wizard/recipes'
|
2
|
+
require 'rails_wizard/recipe'
|
3
|
+
require 'rails_wizard/config'
|
4
|
+
require 'rails_wizard/template'
|
5
|
+
|
6
|
+
Dir[File.dirname(__FILE__) + '/../recipes/*.rb'].each do |path|
|
7
|
+
key = File.basename(path, '.rb')
|
8
|
+
recipe = RailsWizard::Recipe.generate(key, File.open(path))
|
9
|
+
RailsWizard::Recipes.add(recipe)
|
10
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
#unless recipes.include? 'sass-rails'
|
2
|
+
# gem 'sass-rails'
|
3
|
+
#end
|
4
|
+
gem 'activeadmin'
|
5
|
+
|
6
|
+
after_everything do
|
7
|
+
generate "active_admin:install"
|
8
|
+
end
|
9
|
+
|
10
|
+
__END__
|
11
|
+
|
12
|
+
name: Active Admin
|
13
|
+
description: "The administration framework for Ruby on Rails applications"
|
14
|
+
author: jonochang
|
15
|
+
|
16
|
+
exclusive: administration
|
17
|
+
category: administration
|
18
|
+
tags: [administration]
|