ey_rails_wizard 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (93) hide show
  1. data/.gitignore +8 -0
  2. data/.rspec +2 -0
  3. data/.travis.yml +6 -0
  4. data/ChangeLog.md +23 -0
  5. data/Gemfile +3 -0
  6. data/MIT_LICENSE +20 -0
  7. data/README.md +78 -0
  8. data/Rakefile +45 -0
  9. data/autotest/discover.rb +1 -0
  10. data/bin/ey_rails_wizard +7 -0
  11. data/ey_rails_wizard.gemspec +28 -0
  12. data/lib/rails_wizard/command.rb +79 -0
  13. data/lib/rails_wizard/config.rb +86 -0
  14. data/lib/rails_wizard/recipe.rb +106 -0
  15. data/lib/rails_wizard/recipes.rb +38 -0
  16. data/lib/rails_wizard/template.rb +67 -0
  17. data/lib/rails_wizard.rb +10 -0
  18. data/recipes/active_admin.rb +18 -0
  19. data/recipes/activerecord.rb +69 -0
  20. data/recipes/cancan.rb +16 -0
  21. data/recipes/capybara.rb +34 -0
  22. data/recipes/carrierwave.rb +42 -0
  23. data/recipes/carrierwave_direct.rb +13 -0
  24. data/recipes/cartographer.rb +33 -0
  25. data/recipes/cucumber.rb +17 -0
  26. data/recipes/delayed_job.rb +16 -0
  27. data/recipes/devise.rb +52 -0
  28. data/recipes/devise_invitable.rb +23 -0
  29. data/recipes/env_yaml.rb +53 -0
  30. data/recipes/event_calendar.rb +12 -0
  31. data/recipes/eycloud.rb +30 -0
  32. data/recipes/eycloud_recipes_on_deploy.rb +20 -0
  33. data/recipes/factory_girl.rb +38 -0
  34. data/recipes/ffaker.rb +22 -0
  35. data/recipes/fixture_builder.rb +35 -0
  36. data/recipes/forgery.rb +15 -0
  37. data/recipes/git.rb +15 -0
  38. data/recipes/haml.rb +11 -0
  39. data/recipes/heroku.rb +58 -0
  40. data/recipes/hoptoad.rb +34 -0
  41. data/recipes/inherited_resources.rb +12 -0
  42. data/recipes/jammit.rb +43 -0
  43. data/recipes/jasmine.rb +12 -0
  44. data/recipes/jquery.rb +20 -0
  45. data/recipes/mini_magick.rb +13 -0
  46. data/recipes/mongo_mapper.rb +20 -0
  47. data/recipes/mongohq.rb +61 -0
  48. data/recipes/mongoid.rb +20 -0
  49. data/recipes/mootools.rb +23 -0
  50. data/recipes/mysql.rb +19 -0
  51. data/recipes/nifty_generators.rb +21 -0
  52. data/recipes/oa_oauth.rb +12 -0
  53. data/recipes/omniauth.rb +17 -0
  54. data/recipes/paper_trail.rb +17 -0
  55. data/recipes/pow.rb +12 -0
  56. data/recipes/prototype.rb +11 -0
  57. data/recipes/puma.rb +10 -0
  58. data/recipes/rails_admin.rb +21 -0
  59. data/recipes/rails_basics.rb +45 -0
  60. data/recipes/rails_dev_tweaks.rb +10 -0
  61. data/recipes/rails_erd.rb +9 -0
  62. data/recipes/rails_footnotes.rb +14 -0
  63. data/recipes/ransack.rb +32 -0
  64. data/recipes/redis.rb +15 -0
  65. data/recipes/resque.rb +37 -0
  66. data/recipes/rmagick.rb +13 -0
  67. data/recipes/rspec.rb +21 -0
  68. data/recipes/sass.rb +13 -0
  69. data/recipes/sequel.rb +13 -0
  70. data/recipes/settingslogic.rb +43 -0
  71. data/recipes/shoulda_matchers.rb +11 -0
  72. data/recipes/simple_form.rb +19 -0
  73. data/recipes/slim.rb +11 -0
  74. data/recipes/sqlite3.rb +10 -0
  75. data/recipes/test_unit.rb +11 -0
  76. data/recipes/thin.rb +10 -0
  77. data/recipes/thinking_sphinx.rb +14 -0
  78. data/recipes/twitter_bootstrap_rails.rb +142 -0
  79. data/recipes/unicorn.rb +10 -0
  80. data/sample.rb +77 -0
  81. data/spec/rails_wizard/config_spec.rb +99 -0
  82. data/spec/rails_wizard/recipe_spec.rb +103 -0
  83. data/spec/rails_wizard/recipes/sanity_spec.rb +30 -0
  84. data/spec/rails_wizard/recipes_spec.rb +24 -0
  85. data/spec/rails_wizard/template_spec.rb +48 -0
  86. data/spec/spec_helper.rb +11 -0
  87. data/spec/support/rails_directory.rb +17 -0
  88. data/spec/support/template_runner.rb +28 -0
  89. data/templates/helpers.erb +45 -0
  90. data/templates/layout.erb +45 -0
  91. data/templates/recipe.erb +10 -0
  92. data/version.rb +3 -0
  93. metadata +232 -0
data/.gitignore ADDED
@@ -0,0 +1,8 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ ./test_run
5
+ dist/*
6
+ .idea
7
+ .rvmrc
8
+
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format=progress
2
+ --colour
data/.travis.yml ADDED
@@ -0,0 +1,6 @@
1
+ rvm:
2
+ - 1.8.7
3
+ - 1.9.2
4
+ - jruby
5
+ - rbx
6
+ - ree
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
@@ -0,0 +1,3 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec
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" }
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+ $:.push File.dirname(__FILE__) + '/../lib'
3
+
4
+ require 'rubygems'
5
+ require 'rails_wizard/command'
6
+
7
+ RailsWizard::Command.start
@@ -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
@@ -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]