appscrolls 0.7.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.
- data/.gitignore +8 -0
- data/.rspec +2 -0
- data/.travis.yml +6 -0
- data/ChangeLog.md +63 -0
- data/Gemfile +3 -0
- data/Guardfile +18 -0
- data/MIT_LICENSE +20 -0
- data/README.md +154 -0
- data/Rakefile +78 -0
- data/appscrolls.gemspec +32 -0
- data/bin/appscrolls +7 -0
- data/features/step_definitions/common_steps.rb +211 -0
- data/features/support/common.rb +51 -0
- data/features/support/env.rb +18 -0
- data/lib/appscrolls.rb +10 -0
- data/lib/appscrolls/command.rb +85 -0
- data/lib/appscrolls/config.rb +86 -0
- data/lib/appscrolls/scroll.rb +106 -0
- data/lib/appscrolls/scrolls.rb +38 -0
- data/lib/appscrolls/template.rb +67 -0
- data/lib/rails/generators/.DS_Store +0 -0
- data/lib/rails/generators/run_template/USAGE +13 -0
- data/lib/rails/generators/run_template/run_template_generator.rb +13 -0
- data/sample.rb +75 -0
- data/scrolls/active_admin.rb +19 -0
- data/scrolls/capybara.rb +34 -0
- data/scrolls/cucumber.rb +21 -0
- data/scrolls/delayed_job.rb +94 -0
- data/scrolls/env_yaml.rb +53 -0
- data/scrolls/eycloud.rb +72 -0
- data/scrolls/eycloud_recipes_on_deploy.rb +20 -0
- data/scrolls/git.rb +17 -0
- data/scrolls/github.rb +38 -0
- data/scrolls/guard.rb +75 -0
- data/scrolls/jquery.rb +11 -0
- data/scrolls/mysql.rb +51 -0
- data/scrolls/passenger.rb +11 -0
- data/scrolls/postgresql.rb +54 -0
- data/scrolls/prototype.rb +21 -0
- data/scrolls/puma.rb +11 -0
- data/scrolls/rails_basics.rb +54 -0
- data/scrolls/redis.rb +19 -0
- data/scrolls/resque.rb +59 -0
- data/scrolls/rspec.rb +21 -0
- data/scrolls/simple_form.rb +19 -0
- data/scrolls/split.rb +35 -0
- data/scrolls/spork.rb +19 -0
- data/scrolls/sqlite3.rb +10 -0
- data/scrolls/test_unit.rb +11 -0
- data/scrolls/thin.rb +10 -0
- data/scrolls/twitter_bootstrap.rb +41 -0
- data/scrolls/unicorn.rb +10 -0
- data/scrolls/zzz/activerecord.rb +69 -0
- data/scrolls/zzz/cancan.rb +16 -0
- data/scrolls/zzz/carrierwave.rb +42 -0
- data/scrolls/zzz/carrierwave_direct.rb +13 -0
- data/scrolls/zzz/cartographer.rb +33 -0
- data/scrolls/zzz/devise.rb +52 -0
- data/scrolls/zzz/devise_invitable.rb +23 -0
- data/scrolls/zzz/event_calendar.rb +12 -0
- data/scrolls/zzz/factory_girl.rb +38 -0
- data/scrolls/zzz/ffaker.rb +22 -0
- data/scrolls/zzz/fixture_builder.rb +35 -0
- data/scrolls/zzz/forgery.rb +15 -0
- data/scrolls/zzz/haml.rb +11 -0
- data/scrolls/zzz/heroku.rb +58 -0
- data/scrolls/zzz/hoptoad.rb +34 -0
- data/scrolls/zzz/inherited_resources.rb +12 -0
- data/scrolls/zzz/intercom.rb +35 -0
- data/scrolls/zzz/jammit.rb +43 -0
- data/scrolls/zzz/jasmine.rb +12 -0
- data/scrolls/zzz/mini_magick.rb +13 -0
- data/scrolls/zzz/mongo_mapper.rb +20 -0
- data/scrolls/zzz/mongohq.rb +61 -0
- data/scrolls/zzz/mongoid.rb +20 -0
- data/scrolls/zzz/mootools.rb +23 -0
- data/scrolls/zzz/newrelic.rb +11 -0
- data/scrolls/zzz/nifty_generators.rb +21 -0
- data/scrolls/zzz/oa_oauth.rb +12 -0
- data/scrolls/zzz/omniauth.rb +55 -0
- data/scrolls/zzz/paper_trail.rb +17 -0
- data/scrolls/zzz/pow.rb +12 -0
- data/scrolls/zzz/rails_admin.rb +22 -0
- data/scrolls/zzz/rails_dev_tweaks.rb +10 -0
- data/scrolls/zzz/rails_erd.rb +9 -0
- data/scrolls/zzz/rails_footnotes.rb +14 -0
- data/scrolls/zzz/ransack.rb +32 -0
- data/scrolls/zzz/rmagick.rb +13 -0
- data/scrolls/zzz/sass.rb +13 -0
- data/scrolls/zzz/sequel.rb +13 -0
- data/scrolls/zzz/settingslogic.rb +43 -0
- data/scrolls/zzz/shoulda_matchers.rb +11 -0
- data/scrolls/zzz/sidekiq.rb +23 -0
- data/scrolls/zzz/slim.rb +11 -0
- data/scrolls/zzz/thinking_sphinx.rb +14 -0
- data/scrolls/zzz/vanity.rb +35 -0
- data/spec/appscrolls/config_spec.rb +99 -0
- data/spec/appscrolls/scroll_spec.rb +103 -0
- data/spec/appscrolls/scrolls/sanity_spec.rb +30 -0
- data/spec/appscrolls/scrolls_spec.rb +24 -0
- data/spec/appscrolls/template_spec.rb +57 -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 +44 -0
- data/templates/new_scroll.erb +28 -0
- data/templates/scroll.erb +10 -0
- data/version.rb +3 -0
- metadata +297 -0
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
module CommonHelpers
|
|
2
|
+
def get_command_output
|
|
3
|
+
strip_color_codes(File.read(@stdout)).chomp
|
|
4
|
+
end
|
|
5
|
+
|
|
6
|
+
def strip_color_codes(text)
|
|
7
|
+
text.gsub(/\e\[\d+m/, '')
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def in_tmp_folder(&block)
|
|
11
|
+
FileUtils.chdir(@tmp_root, &block)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def in_project_folder(&block)
|
|
15
|
+
project_folder = @active_project_folder || @tmp_root
|
|
16
|
+
FileUtils.chdir(project_folder, &block)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def in_home_folder(&block)
|
|
20
|
+
FileUtils.chdir(@home_path, &block)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def force_local_lib_override(project_name = @project_name)
|
|
24
|
+
rakefile = File.read(File.join(project_name, 'Rakefile'))
|
|
25
|
+
File.open(File.join(project_name, 'Rakefile'), "w+") do |f|
|
|
26
|
+
f << "$:.unshift('#{@lib_path}')\n"
|
|
27
|
+
f << rakefile
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def setup_active_project_folder project_name
|
|
32
|
+
@active_project_folder = File.join(@tmp_root, project_name)
|
|
33
|
+
@project_name = project_name
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# capture both [stdout, stderr] as well as stdin
|
|
37
|
+
def capture_stdios(input = nil, &block)
|
|
38
|
+
require 'stringio'
|
|
39
|
+
org_stdin, $stdin = $stdin, StringIO.new(input) if input
|
|
40
|
+
org_stdout, $stdout = $stdout, StringIO.new
|
|
41
|
+
org_stderr, $stderr = $stdout, StringIO.new
|
|
42
|
+
yield
|
|
43
|
+
return [$stdout.string, $stderr.string]
|
|
44
|
+
ensure
|
|
45
|
+
$stderr = org_stderr
|
|
46
|
+
$stdout = org_stdout
|
|
47
|
+
$stdin = org_stdin
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
World(CommonHelpers)
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
$:.unshift(File.expand_path(File.dirname(__FILE__) + '/../../lib'))
|
|
2
|
+
require 'bundler/setup'
|
|
3
|
+
require 'appscrolls'
|
|
4
|
+
|
|
5
|
+
path = ENV['PATH']
|
|
6
|
+
|
|
7
|
+
Before do
|
|
8
|
+
@tmp_root = File.dirname(__FILE__) + "/../../tmp"
|
|
9
|
+
@active_project_folder = @tmp_root
|
|
10
|
+
@home_path = File.expand_path(File.join(@tmp_root, "home"))
|
|
11
|
+
@lib_path = File.expand_path(File.dirname(__FILE__) + "/../../lib")
|
|
12
|
+
@fixtures_path = File.expand_path(File.dirname(__FILE__) + "/../../fixtures")
|
|
13
|
+
FileUtils.rm_rf @tmp_root
|
|
14
|
+
FileUtils.mkdir_p @home_path
|
|
15
|
+
ENV['HOME'] = @home_path
|
|
16
|
+
fixture_bin_path = File.expand_path('../../../fixtures/bin', __FILE__)
|
|
17
|
+
ENV['PATH'] = fixture_bin_path + ":" + path
|
|
18
|
+
end
|
data/lib/appscrolls.rb
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
require 'appscrolls/scrolls'
|
|
2
|
+
require 'appscrolls/scroll'
|
|
3
|
+
require 'appscrolls/config'
|
|
4
|
+
require 'appscrolls/template'
|
|
5
|
+
|
|
6
|
+
Dir[File.dirname(__FILE__) + '/../scrolls/*.rb'].each do |path|
|
|
7
|
+
key = File.basename(path, '.rb')
|
|
8
|
+
scroll = AppScrollsScrolls::Scroll.generate(key, File.open(path))
|
|
9
|
+
AppScrollsScrolls::Scrolls.add(scroll)
|
|
10
|
+
end
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
require 'appscrolls'
|
|
2
|
+
require 'thor'
|
|
3
|
+
|
|
4
|
+
module AppScrollsScrolls
|
|
5
|
+
class Command < Thor
|
|
6
|
+
include Thor::Actions
|
|
7
|
+
desc "new APP_NAME", "create a new Rails app"
|
|
8
|
+
method_option :scrolls, :type => :array, :aliases => "-s", :desc => "List scrolls, e.g. -s resque rails_basics jquery"
|
|
9
|
+
method_option :template, :type => :boolean, :aliases => "-t", :desc => "Only display template that would be used"
|
|
10
|
+
def new(name)
|
|
11
|
+
if options[:scrolls]
|
|
12
|
+
run_template(name, options[:scrolls], options[:template])
|
|
13
|
+
else
|
|
14
|
+
@scrolls = []
|
|
15
|
+
|
|
16
|
+
while scroll = ask("#{print_scrolls}#{bold}Which scroll would you like to add? #{clear}#{yellow}(blank to finish)#{clear}")
|
|
17
|
+
if scroll == ''
|
|
18
|
+
run_template(name, @scrolls)
|
|
19
|
+
break
|
|
20
|
+
elsif AppScrollsScrolls::Scrolls.list.include?(scroll)
|
|
21
|
+
@scrolls << scroll
|
|
22
|
+
puts
|
|
23
|
+
puts "> #{green}Added '#{scroll}' to template.#{clear}"
|
|
24
|
+
else
|
|
25
|
+
puts
|
|
26
|
+
puts "> #{red}Invalid scroll, please try again.#{clear}"
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
desc "list [CATEGORY]", "list available scrolls (optionally by category)"
|
|
33
|
+
def list(category = nil)
|
|
34
|
+
if category
|
|
35
|
+
scrolls = AppScrollsScrolls::Scrolls.for(category).map{|r| AppScrollsScrolls::Scroll.from_mongo(r) }
|
|
36
|
+
else
|
|
37
|
+
scrolls = AppScrollsScrolls::Scrolls.list_classes
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
scrolls.each do |scroll|
|
|
41
|
+
puts scroll.key.ljust(15) + "# #{scroll.description}"
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
no_tasks do
|
|
46
|
+
def cyan; "\033[36m" end
|
|
47
|
+
def clear; "\033[0m" end
|
|
48
|
+
def bold; "\033[1m" end
|
|
49
|
+
def red; "\033[31m" end
|
|
50
|
+
def green; "\033[32m" end
|
|
51
|
+
def yellow; "\033[33m" end
|
|
52
|
+
|
|
53
|
+
def print_scrolls
|
|
54
|
+
puts
|
|
55
|
+
puts
|
|
56
|
+
puts
|
|
57
|
+
if @scrolls && @scrolls.any?
|
|
58
|
+
puts "#{green}#{bold}Your Scrolls:#{clear} " + @scrolls.join(", ")
|
|
59
|
+
puts
|
|
60
|
+
end
|
|
61
|
+
puts "#{bold}#{cyan}Available Scrolls:#{clear} " + AppScrollsScrolls::Scrolls.list.join(', ')
|
|
62
|
+
puts
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def run_template(name, scrolls, display_only = false)
|
|
66
|
+
puts
|
|
67
|
+
puts
|
|
68
|
+
puts "#{bold}Generating and Running Template..."
|
|
69
|
+
puts
|
|
70
|
+
file = Tempfile.new('template')
|
|
71
|
+
template = AppScrollsScrolls::Template.new(scrolls)
|
|
72
|
+
file.write template.compile
|
|
73
|
+
file.close
|
|
74
|
+
if display_only
|
|
75
|
+
puts "Template stored to #{file.path}"
|
|
76
|
+
puts File.read(file.path)
|
|
77
|
+
else
|
|
78
|
+
system "rails new #{name} -m #{file.path} #{template.args.join(' ')}"
|
|
79
|
+
end
|
|
80
|
+
ensure
|
|
81
|
+
file.unlink
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
require 'active_support/ordered_hash'
|
|
2
|
+
|
|
3
|
+
module AppScrollsScrolls
|
|
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, scroll_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 scroll_conditions
|
|
58
|
+
if details['if_scroll']
|
|
59
|
+
"scroll?('#{details['if_scroll']}')"
|
|
60
|
+
elsif details['unless_scroll']
|
|
61
|
+
"!scroll?('#{details['unless_scroll']}')"
|
|
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 'appscrolls/config'
|
|
2
|
+
|
|
3
|
+
require 'active_support/inflector'
|
|
4
|
+
require 'yaml'
|
|
5
|
+
require 'erb'
|
|
6
|
+
|
|
7
|
+
module AppScrollsScrolls
|
|
8
|
+
class Scroll
|
|
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 scroll 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
|
+
scroll_class = Class.new(AppScrollsScrolls::Scroll)
|
|
42
|
+
scroll_class.attributes = attributes
|
|
43
|
+
scroll_class.template = template
|
|
44
|
+
scroll_class.key = key
|
|
45
|
+
|
|
46
|
+
scroll_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
|
+
AppScrollsScrolls::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_scroll '#{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 == AppScrollsScrolls::Scroll
|
|
99
|
+
AppScrollsScrolls::Scrolls[key]
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def self.get_binding
|
|
103
|
+
binding
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
module AppScrollsScrolls
|
|
2
|
+
module Scrolls
|
|
3
|
+
@@categories = {}
|
|
4
|
+
@@list = {}
|
|
5
|
+
|
|
6
|
+
def self.add(scroll)
|
|
7
|
+
AppScrollsScrolls::Scrolls.const_set ActiveSupport::Inflector.camelize(scroll.key), scroll
|
|
8
|
+
@@list[scroll.key] = scroll
|
|
9
|
+
(@@categories[scroll.category.to_s] ||= []) << scroll.key
|
|
10
|
+
@@categories[scroll.category.to_s].uniq!
|
|
11
|
+
scroll
|
|
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, scroll)
|
|
35
|
+
(@@categories[category.to_s] ||= []).delete(scroll.key)
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
module AppScrollsScrolls
|
|
2
|
+
class Template
|
|
3
|
+
attr_reader :scrolls, :unknown_scroll_names
|
|
4
|
+
|
|
5
|
+
def initialize(scrolls)
|
|
6
|
+
@unknown_scroll_names = []
|
|
7
|
+
@scrolls = scrolls.inject([]) do |list, name|
|
|
8
|
+
scroll = AppScrollsScrolls::Scroll.from_mongo(name)
|
|
9
|
+
if scroll
|
|
10
|
+
list << scroll
|
|
11
|
+
else
|
|
12
|
+
@unknown_scroll_names << name
|
|
13
|
+
$stderr.puts "Unknown scroll '#{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_scrolls
|
|
31
|
+
@resolve_scrolls ||= scrolls_with_dependencies.sort
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def scroll_classes
|
|
35
|
+
@scroll_classes ||= scrolls.map { |name| AppScrollsScrolls::Scroll.from_mongo(name) }
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def scrolls_with_dependencies
|
|
39
|
+
@scrolls_with_dependencies ||= scroll_classes
|
|
40
|
+
|
|
41
|
+
added_more = false
|
|
42
|
+
for scroll in scroll_classes
|
|
43
|
+
scroll.requires.each do |requirement|
|
|
44
|
+
requirement = AppScrollsScrolls::Scroll.from_mongo(requirement)
|
|
45
|
+
count = @scrolls_with_dependencies.size
|
|
46
|
+
(@scrolls_with_dependencies << requirement).uniq!
|
|
47
|
+
unless @scrolls_with_dependencies.size == count
|
|
48
|
+
added_more = true
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
added_more ? scrolls_with_dependencies : @scrolls_with_dependencies
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def compile
|
|
57
|
+
render 'layout', binding
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def args
|
|
61
|
+
scrolls.map(&:args).uniq
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def custom_code?; false end
|
|
65
|
+
def custom_code; nil end
|
|
66
|
+
end
|
|
67
|
+
end
|