]> projects.mako.cc - selectricity/blob - vendor/plugins/engines/generators/engine/engine_generator.rb
ac66525dcc6bd76bb02afcec84f15e3d5909b2dd
[selectricity] / vendor / plugins / engines / generators / engine / engine_generator.rb
1 #  Copyright (c) 2005 Jonathan Lim <snowblink@gmail.com>
2 #  
3 #  The MIT License
4 #  
5 #  Permission is hereby granted, free of charge, to any person obtaining a copy
6 #  of this software and associated documentation files (the "Software"), to deal
7 #  in the Software without restriction, including without limitation the rights
8 #  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 #  copies of the Software, and to permit persons to whom the Software is
10 #  furnished to do so, subject to the following conditions:
11 #  
12 #  The above copyright notice and this permission notice shall be included in
13 #  all copies or substantial portions of the Software.
14 #  
15 #  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 #  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 #  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
18 #  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 #  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 #  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 #  THE SOFTWARE.
22
23
24 module Rails
25   module Generator
26     module Commands
27
28       class Create < Base
29         def complex_template(relative_source, relative_destination, template_options = {})
30           options = template_options.dup
31           options[:assigns] ||= {}
32           options[:assigns]['template_for_inclusion'] = render_template_part(template_options) if template_options[:mark_id]
33           options[:assigns]['license'] = render_license(template_options)
34           template(relative_source, relative_destination, options)
35         end
36
37         def render_license(template_options)
38           # Getting Sandbox to evaluate part template in it
39           part_binding = template_options[:sandbox].call.sandbox_binding
40           part_rel_path = template_options[:insert]
41           part_path = source_path(part_rel_path)
42
43           # Render inner template within Sandbox binding
44           template_file = File.readlines(part_path)
45           case template_options[:comment_style]
46           when :rb
47             template_file.map! {|x| x.sub(/^/, '#  ')}
48           end
49           rendered_part = ERB.new(template_file.join, nil, '-').result(part_binding)
50         end
51
52       end
53     end
54   end
55 end
56
57
58 class LicensingSandbox
59   include ActionView::Helpers::ActiveRecordHelper
60   attr_accessor :author
61
62   def sandbox_binding
63     binding
64   end
65
66 end
67
68 class Author
69   def initialize
70     set_name
71     set_email
72   end
73
74   def set_name
75     print "Please enter the author's name: "
76     @name = gets.chomp
77   end
78
79   def set_email
80     print "Please enter the author's email: "
81     @email = gets.chomp
82   end
83
84   def to_s
85     "#{@name} <#{@email}>"
86   end
87 end
88
89 class License
90   def initialize(source_root)
91     @source_root = source_root
92     select_license
93   end
94
95   def select_license
96     # list all the licenses in the licenses directory
97     licenses = Dir.entries(File.join(@source_root, 'licenses')).select { |name| name !~ /^\./ }
98     puts "We can generate the following licenses automatically for you:"
99     licenses.sort.each_with_index do |license, index|
100       puts "#{index}) #{licenses[index]}"
101     end
102     print "Please select a license: "
103     while choice = gets.chomp
104       if (choice !~ /^[0-9]+$/)
105         print "Hint - you want to be typing a number.\nPlease select a license: "
106         next
107       end
108       break if choice.to_i >=0 && choice.to_i <= licenses.length
109     end
110       
111     @license = licenses[choice.to_i]
112     puts "'#{@license}' selected"
113   end
114
115   def to_s
116     File.join('licenses', @license)
117   end
118
119 end
120
121 class EngineGenerator < Rails::Generator::NamedBase
122
123   attr_reader :engine_class_name, :engine_underscored_name, :engine_start_name, :author
124
125
126   def initialize(runtime_args, runtime_options = {})
127     super
128     @engine_class_name = runtime_args.shift
129     
130     # ensure that they've given us a valid class name
131     if @engine_class_name =~ /^[a-z]/
132       raise "'#{@engine_class_name}' should be a valid Ruby constant, e.g. 'MyEngine'; aborting generation..." 
133     end
134     
135     @engine_underscored_name = @engine_class_name.underscore
136     @engine_start_name = @engine_underscored_name.sub(/_engine$/, '')
137     @author = Author.new
138     @license = License.new(source_root)
139   end
140
141   def manifest
142     record do |m|
143       m.directory File.join('vendor', 'plugins')
144       m.directory File.join('vendor', 'plugins', @engine_underscored_name)
145       m.complex_template 'README',
146         File.join('vendor', 'plugins', @engine_underscored_name, 'README'),
147         :sandbox => lambda {create_sandbox},
148         :insert => @license.to_s
149
150       m.file 'install.erb', File.join('vendor', 'plugins', @engine_underscored_name, 'install.rb')
151       
152       m.complex_template 'init_engine.erb',
153         File.join('vendor', 'plugins', @engine_underscored_name, 'init_engine.rb'),
154         :sandbox => lambda {create_sandbox},
155         :insert => @license.to_s,
156         :comment_style => :rb
157
158       m.directory File.join('vendor', 'plugins', @engine_underscored_name, 'app')
159       m.directory File.join('vendor', 'plugins', @engine_underscored_name, 'app', 'models')
160       m.directory File.join('vendor', 'plugins', @engine_underscored_name, 'app', 'controllers')
161       m.directory File.join('vendor', 'plugins', @engine_underscored_name, 'app', 'helpers')
162       m.directory File.join('vendor', 'plugins', @engine_underscored_name, 'app', 'views')
163       m.directory File.join('vendor', 'plugins', @engine_underscored_name, 'db')
164       m.directory File.join('vendor', 'plugins', @engine_underscored_name, 'db', 'migrate')
165       m.directory File.join('vendor', 'plugins', @engine_underscored_name, 'lib')
166       m.complex_template File.join('lib', 'engine.erb'),
167         File.join('vendor', 'plugins', @engine_underscored_name, 'lib', "#{@engine_underscored_name}.rb"),
168         :sandbox => lambda {create_sandbox},
169         :insert => @license.to_s,
170         :comment_style => :rb
171
172       m.directory File.join('vendor', 'plugins', @engine_underscored_name, 'lib', @engine_underscored_name)
173       m.directory File.join('vendor', 'plugins', @engine_underscored_name, 'public')
174       m.directory File.join('vendor', 'plugins', @engine_underscored_name, 'public', 'javascripts')
175       m.template File.join('public', 'javascripts', 'engine.js'), File.join('vendor', 'plugins', @engine_underscored_name, 'public', 'javascripts', "#{@engine_underscored_name}.js")
176       m.directory File.join('vendor', 'plugins', @engine_underscored_name, 'public', 'stylesheets')
177       m.template File.join('public', 'stylesheets', 'engine.css'), File.join('vendor', 'plugins', @engine_underscored_name, 'public', 'stylesheets', "#{@engine_underscored_name}.css")
178       m.directory File.join('vendor', 'plugins', @engine_underscored_name, 'tasks')
179       m.template File.join('tasks', 'engine.rake'), File.join('vendor', 'plugins', @engine_underscored_name, 'tasks', "#{@engine_underscored_name}.rake")
180       m.directory File.join('vendor', 'plugins', @engine_underscored_name, 'test')
181       m.template File.join('test', 'test_helper.erb'), File.join('vendor', 'plugins', @engine_underscored_name, 'test', 'test_helper.rb')
182       m.directory File.join('vendor', 'plugins', @engine_underscored_name, 'test', 'fixtures')
183       m.directory File.join('vendor', 'plugins', @engine_underscored_name, 'test', 'functional')
184       m.directory File.join('vendor', 'plugins', @engine_underscored_name, 'test', 'unit')      
185     end
186   end
187
188 protected
189   def banner
190     "Usage: #{$0} #{spec.name} MyEngine [general options]"
191   end
192
193   def create_sandbox
194     sandbox = LicensingSandbox.new
195     sandbox.author = @author
196     sandbox
197   end
198
199 end

Benjamin Mako Hill || Want to submit a patch?