rails_product 0.5
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/CHANGELOG +619 -0
- data/MIT-LICENSE +21 -0
- data/README +195 -0
- data/Rakefile +413 -0
- data/bin/benchmarker +19 -0
- data/bin/breakpointer +3 -0
- data/bin/breakpointer_for_gem +4 -0
- data/bin/console +23 -0
- data/bin/console_sandbox +0 -0
- data/bin/destroy +7 -0
- data/bin/generate +7 -0
- data/bin/listener +86 -0
- data/bin/process/reaper +123 -0
- data/bin/process/spawner +54 -0
- data/bin/process/spinner +60 -0
- data/bin/profiler +34 -0
- data/bin/rails +17 -0
- data/bin/rails_product +17 -0
- data/bin/runner +28 -0
- data/bin/server +125 -0
- data/bin/tracker +69 -0
- data/bin/update +5 -0
- data/configs/apache/vhost.example.conf +42 -0
- data/configs/apache.conf +40 -0
- data/configs/database.yml +23 -0
- data/configs/empty.log +0 -0
- data/configs/routes.rb +19 -0
- data/dispatches/dispatch.fcgi +24 -0
- data/dispatches/dispatch.rb +10 -0
- data/dispatches/gateway.cgi +97 -0
- data/doc/README_FOR_APP +2 -0
- data/environments/development.rb +14 -0
- data/environments/environment.rb +101 -0
- data/environments/production.rb +8 -0
- data/environments/test.rb +17 -0
- data/fresh_rakefile +223 -0
- data/helpers/application.rb +4 -0
- data/helpers/application_helper.rb +3 -0
- data/helpers/test_helper.rb +26 -0
- data/html/404.html +8 -0
- data/html/500.html +8 -0
- data/html/favicon.ico +0 -0
- data/html/index.html +78 -0
- data/html/javascripts/controls.js +446 -0
- data/html/javascripts/dragdrop.js +537 -0
- data/html/javascripts/effects.js +612 -0
- data/html/javascripts/prototype.js +1038 -0
- data/html/robots.txt +1 -0
- data/lib/binding_of_caller.rb +83 -0
- data/lib/breakpoint.rb +523 -0
- data/lib/breakpoint_client.rb +196 -0
- data/lib/code_statistics.rb +104 -0
- data/lib/console_sandbox.rb +6 -0
- data/lib/dispatcher.rb +59 -0
- data/lib/fcgi_handler.rb +156 -0
- data/lib/productize.rb +116 -0
- data/lib/rails_generator/base.rb +203 -0
- data/lib/rails_generator/commands.rb +409 -0
- data/lib/rails_generator/generators/applications/app/USAGE +16 -0
- data/lib/rails_generator/generators/applications/app/app_generator.rb +126 -0
- data/lib/rails_generator/generators/applications/productized_app/USAGE +16 -0
- data/lib/rails_generator/generators/applications/productized_app/productized_app_generator.rb +133 -0
- data/lib/rails_generator/generators/components/controller/USAGE +30 -0
- data/lib/rails_generator/generators/components/controller/controller_generator.rb +38 -0
- data/lib/rails_generator/generators/components/controller/templates/controller.rb +10 -0
- data/lib/rails_generator/generators/components/controller/templates/functional_test.rb +18 -0
- data/lib/rails_generator/generators/components/controller/templates/helper.rb +2 -0
- data/lib/rails_generator/generators/components/controller/templates/view.rhtml +2 -0
- data/lib/rails_generator/generators/components/mailer/USAGE +19 -0
- data/lib/rails_generator/generators/components/mailer/mailer_generator.rb +32 -0
- data/lib/rails_generator/generators/components/mailer/templates/fixture.rhtml +3 -0
- data/lib/rails_generator/generators/components/mailer/templates/mailer.rb +13 -0
- data/lib/rails_generator/generators/components/mailer/templates/unit_test.rb +37 -0
- data/lib/rails_generator/generators/components/mailer/templates/view.rhtml +3 -0
- data/lib/rails_generator/generators/components/migration/USAGE +14 -0
- data/lib/rails_generator/generators/components/migration/migration_generator.rb +9 -0
- data/lib/rails_generator/generators/components/migration/templates/migration.rb +7 -0
- data/lib/rails_generator/generators/components/model/USAGE +17 -0
- data/lib/rails_generator/generators/components/model/model_generator.rb +18 -0
- data/lib/rails_generator/generators/components/model/templates/fixtures.yml +5 -0
- data/lib/rails_generator/generators/components/model/templates/model.rb +2 -0
- data/lib/rails_generator/generators/components/model/templates/unit_test.rb +14 -0
- data/lib/rails_generator/generators/components/scaffold/USAGE +32 -0
- data/lib/rails_generator/generators/components/scaffold/scaffold_generator.rb +178 -0
- data/lib/rails_generator/generators/components/scaffold/templates/controller.rb +54 -0
- data/lib/rails_generator/generators/components/scaffold/templates/form.rhtml +3 -0
- data/lib/rails_generator/generators/components/scaffold/templates/form_scaffolding.rhtml +1 -0
- data/lib/rails_generator/generators/components/scaffold/templates/functional_test.rb +98 -0
- data/lib/rails_generator/generators/components/scaffold/templates/helper.rb +2 -0
- data/lib/rails_generator/generators/components/scaffold/templates/layout.rhtml +13 -0
- data/lib/rails_generator/generators/components/scaffold/templates/style.css +74 -0
- data/lib/rails_generator/generators/components/scaffold/templates/view_edit.rhtml +9 -0
- data/lib/rails_generator/generators/components/scaffold/templates/view_list.rhtml +27 -0
- data/lib/rails_generator/generators/components/scaffold/templates/view_new.rhtml +8 -0
- data/lib/rails_generator/generators/components/scaffold/templates/view_show.rhtml +8 -0
- data/lib/rails_generator/generators/components/web_service/USAGE +28 -0
- data/lib/rails_generator/generators/components/web_service/templates/api_definition.rb +5 -0
- data/lib/rails_generator/generators/components/web_service/templates/controller.rb +8 -0
- data/lib/rails_generator/generators/components/web_service/templates/functional_test.rb +19 -0
- data/lib/rails_generator/generators/components/web_service/web_service_generator.rb +29 -0
- data/lib/rails_generator/lookup.rb +206 -0
- data/lib/rails_generator/manifest.rb +53 -0
- data/lib/rails_generator/options.rb +134 -0
- data/lib/rails_generator/scripts/destroy.rb +7 -0
- data/lib/rails_generator/scripts/generate.rb +7 -0
- data/lib/rails_generator/scripts/update.rb +12 -0
- data/lib/rails_generator/scripts.rb +83 -0
- data/lib/rails_generator/simple_logger.rb +46 -0
- data/lib/rails_generator/spec.rb +44 -0
- data/lib/rails_generator.rb +43 -0
- data/lib/rubyprof_ext.rb +35 -0
- data/lib/webrick_server.rb +148 -0
- data/sites/fresh_rakefile +176 -0
- metadata +250 -0
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
require File.dirname(__FILE__) + '/spec'
|
|
2
|
+
|
|
3
|
+
class Object
|
|
4
|
+
class << self
|
|
5
|
+
# Lookup missing generators using const_missing. This allows any
|
|
6
|
+
# generator to reference another without having to know its location:
|
|
7
|
+
# RubyGems, ~/.rails/generators, and RAILS_ROOT/generators.
|
|
8
|
+
def lookup_missing_generator(class_id)
|
|
9
|
+
if md = /(.+)Generator$/.match(class_id.to_s)
|
|
10
|
+
name = md.captures.first.demodulize.underscore
|
|
11
|
+
Rails::Generator::Base.lookup(name).klass
|
|
12
|
+
else
|
|
13
|
+
const_missing_before_generators(class_id)
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
unless respond_to?(:const_missing_before_generators)
|
|
18
|
+
alias_method :const_missing_before_generators, :const_missing
|
|
19
|
+
alias_method :const_missing, :lookup_missing_generator
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# User home directory lookup adapted from RubyGems.
|
|
25
|
+
def Dir.user_home
|
|
26
|
+
if ENV['HOME']
|
|
27
|
+
ENV['HOME']
|
|
28
|
+
elsif ENV['USERPROFILE']
|
|
29
|
+
ENV['USERPROFILE']
|
|
30
|
+
elsif ENV['HOMEDRIVE'] and ENV['HOMEPATH']
|
|
31
|
+
"#{ENV['HOMEDRIVE']}:#{ENV['HOMEPATH']}"
|
|
32
|
+
else
|
|
33
|
+
File.expand_path '~'
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
module Rails
|
|
39
|
+
module Generator
|
|
40
|
+
|
|
41
|
+
# Generator lookup is managed by a list of sources which return specs
|
|
42
|
+
# describing where to find and how to create generators. This module
|
|
43
|
+
# provides class methods for manipulating the source list and looking up
|
|
44
|
+
# generator specs, and an #instance wrapper for quickly instantiating
|
|
45
|
+
# generators by name.
|
|
46
|
+
#
|
|
47
|
+
# A spec is not a generator: it's a description of where to find
|
|
48
|
+
# the generator and how to create it. A source is anything that
|
|
49
|
+
# yields generators from #each. PathSource and GemSource are provided.
|
|
50
|
+
module Lookup
|
|
51
|
+
def self.append_features(base)
|
|
52
|
+
super
|
|
53
|
+
base.extend(ClassMethods)
|
|
54
|
+
base.use_component_sources!
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Convenience method to instantiate another generator.
|
|
58
|
+
def instance(generator_name, args, runtime_options = {})
|
|
59
|
+
self.class.instance(generator_name, args, runtime_options)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
module ClassMethods
|
|
63
|
+
# The list of sources where we look, in order, for generators.
|
|
64
|
+
def sources
|
|
65
|
+
read_inheritable_attribute(:sources) or use_component_sources!
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# Add a source to the end of the list.
|
|
69
|
+
def append_sources(*args)
|
|
70
|
+
sources.concat(args.flatten)
|
|
71
|
+
invalidate_cache!
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# Add a source to the beginning of the list.
|
|
75
|
+
def prepend_sources(*args)
|
|
76
|
+
write_inheritable_array(:sources, args.flatten + sources)
|
|
77
|
+
invalidate_cache!
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# Reset the source list.
|
|
81
|
+
def reset_sources
|
|
82
|
+
write_inheritable_attribute(:sources, [])
|
|
83
|
+
invalidate_cache!
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
# Use application generators (app, ?).
|
|
87
|
+
def use_application_sources!
|
|
88
|
+
reset_sources
|
|
89
|
+
sources << PathSource.new(:builtin, "#{File.dirname(__FILE__)}/generators/applications")
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
# Use component generators (model, controller, etc).
|
|
93
|
+
# 1. Rails application. If RAILS_ROOT is defined we know we're
|
|
94
|
+
# generating in the context of a Rails application, so search
|
|
95
|
+
# RAILS_ROOT/generators.
|
|
96
|
+
# 2. User home directory. Search ~/.rails/generators.
|
|
97
|
+
# 3. RubyGems. Search for gems named *_generator.
|
|
98
|
+
# 4. Builtins. Model, controller, mailer, scaffold.
|
|
99
|
+
def use_component_sources!
|
|
100
|
+
reset_sources
|
|
101
|
+
sources << PathSource.new(:app, "#{::RAILS_ROOT}/generators") if defined? ::RAILS_ROOT
|
|
102
|
+
sources << PathSource.new(:user, "#{Dir.user_home}/.rails/generators")
|
|
103
|
+
sources << GemSource.new if Object.const_defined?(:Gem)
|
|
104
|
+
sources << PathSource.new(:builtin, "#{File.dirname(__FILE__)}/generators/components")
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
# Lookup knows how to find generators' Specs from a list of Sources.
|
|
108
|
+
# Searches the sources, in order, for the first matching name.
|
|
109
|
+
def lookup(generator_name)
|
|
110
|
+
@found ||= {}
|
|
111
|
+
generator_name = generator_name.to_s.downcase
|
|
112
|
+
@found[generator_name] ||= cache.find { |spec| spec.name == generator_name }
|
|
113
|
+
unless @found[generator_name]
|
|
114
|
+
chars = generator_name.scan(/./).map{|c|"#{c}.*?"}
|
|
115
|
+
rx = /^#{chars}$/
|
|
116
|
+
gns = cache.select{|spec| spec.name =~ rx }
|
|
117
|
+
@found[generator_name] ||= gns.first if gns.length == 1
|
|
118
|
+
raise GeneratorError, "Pattern '#{generator_name}' matches more than one generator: #{gns.map{|sp|sp.name}.join(', ')}" if gns.length > 1
|
|
119
|
+
end
|
|
120
|
+
@found[generator_name] or raise GeneratorError, "Couldn't find '#{generator_name}' generator"
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
# Convenience method to lookup and instantiate a generator.
|
|
124
|
+
def instance(generator_name, args = [], runtime_options = {})
|
|
125
|
+
lookup(generator_name).klass.new(args, full_options(runtime_options))
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
private
|
|
129
|
+
# Lookup and cache every generator from the source list.
|
|
130
|
+
def cache
|
|
131
|
+
@cache ||= sources.inject([]) { |cache, source| cache + source.map }
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
# Clear the cache whenever the source list changes.
|
|
135
|
+
def invalidate_cache!
|
|
136
|
+
@cache = nil
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
# Sources enumerate (yield from #each) generator specs which describe
|
|
142
|
+
# where to find and how to create generators. Enumerable is mixed in so,
|
|
143
|
+
# for example, source.collect will retrieve every generator.
|
|
144
|
+
# Sources may be assigned a label to distinguish them.
|
|
145
|
+
class Source
|
|
146
|
+
include Enumerable
|
|
147
|
+
|
|
148
|
+
attr_reader :label
|
|
149
|
+
def initialize(label)
|
|
150
|
+
@label = label
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
# The each method must be implemented in subclasses.
|
|
154
|
+
# The base implementation raises an error.
|
|
155
|
+
def each
|
|
156
|
+
raise NotImplementedError
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
# Return a convenient sorted list of all generator names.
|
|
160
|
+
def names
|
|
161
|
+
map { |spec| spec.name }.sort
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
# PathSource looks for generators in a filesystem directory.
|
|
167
|
+
class PathSource < Source
|
|
168
|
+
attr_reader :path
|
|
169
|
+
|
|
170
|
+
def initialize(label, path)
|
|
171
|
+
super label
|
|
172
|
+
@path = path
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
# Yield each eligible subdirectory.
|
|
176
|
+
def each
|
|
177
|
+
Dir["#{path}/[a-z]*"].each do |dir|
|
|
178
|
+
if File.directory?(dir)
|
|
179
|
+
yield Spec.new(File.basename(dir), dir, label)
|
|
180
|
+
end
|
|
181
|
+
end
|
|
182
|
+
end
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
# GemSource hits the mines to quarry for generators. The latest versions
|
|
187
|
+
# of gems named *_generator are selected.
|
|
188
|
+
class GemSource < Source
|
|
189
|
+
def initialize
|
|
190
|
+
super :RubyGems
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
# Yield latest versions of generator gems.
|
|
194
|
+
def each
|
|
195
|
+
Gem::cache.search(/_generator$/).inject({}) { |latest, gem|
|
|
196
|
+
hem = latest[gem.name]
|
|
197
|
+
latest[gem.name] = gem if hem.nil? or gem.version > hem.version
|
|
198
|
+
latest
|
|
199
|
+
}.values.each { |gem|
|
|
200
|
+
yield Spec.new(gem.name.sub(/_generator$/, ''), gem.full_gem_path, label)
|
|
201
|
+
}
|
|
202
|
+
end
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
end
|
|
206
|
+
end
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
module Rails
|
|
2
|
+
module Generator
|
|
3
|
+
|
|
4
|
+
# Manifest captures the actions a generator performs. Instantiate
|
|
5
|
+
# a manifest with an optional target object, hammer it with actions,
|
|
6
|
+
# then replay or rewind on the object of your choice.
|
|
7
|
+
#
|
|
8
|
+
# Example:
|
|
9
|
+
# manifest = Manifest.new { |m|
|
|
10
|
+
# m.make_directory '/foo'
|
|
11
|
+
# m.create_file '/foo/bar.txt'
|
|
12
|
+
# }
|
|
13
|
+
# manifest.replay(creator)
|
|
14
|
+
# manifest.rewind(destroyer)
|
|
15
|
+
class Manifest
|
|
16
|
+
attr_reader :target
|
|
17
|
+
|
|
18
|
+
# Take a default action target. Yield self if block given.
|
|
19
|
+
def initialize(target = nil)
|
|
20
|
+
@target, @actions = target, []
|
|
21
|
+
yield self if block_given?
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Record an action.
|
|
25
|
+
def method_missing(action, *args, &block)
|
|
26
|
+
@actions << [action, args, block]
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Replay recorded actions.
|
|
30
|
+
def replay(target = nil)
|
|
31
|
+
send_actions(target || @target, @actions)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Rewind recorded actions.
|
|
35
|
+
def rewind(target = nil)
|
|
36
|
+
send_actions(target || @target, @actions.reverse)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Erase recorded actions.
|
|
40
|
+
def erase
|
|
41
|
+
@actions = []
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
private
|
|
45
|
+
def send_actions(target, actions)
|
|
46
|
+
actions.each do |method, args, block|
|
|
47
|
+
target.send(method, *args, &block)
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
end
|
|
53
|
+
end
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
require 'optparse'
|
|
2
|
+
|
|
3
|
+
module Rails
|
|
4
|
+
module Generator
|
|
5
|
+
module Options
|
|
6
|
+
def self.append_features(base)
|
|
7
|
+
super
|
|
8
|
+
base.extend(ClassMethods)
|
|
9
|
+
class << base
|
|
10
|
+
if respond_to?(:inherited)
|
|
11
|
+
alias_method :inherited_without_options, :inherited
|
|
12
|
+
end
|
|
13
|
+
alias_method :inherited, :inherited_with_options
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
module ClassMethods
|
|
18
|
+
def inherited_with_options(sub)
|
|
19
|
+
inherited_without_options(sub) if respond_to?(:inherited_without_options)
|
|
20
|
+
sub.extend(Rails::Generator::Options::ClassMethods)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def mandatory_options(options = nil)
|
|
24
|
+
if options
|
|
25
|
+
write_inheritable_attribute(:mandatory_options, options)
|
|
26
|
+
else
|
|
27
|
+
read_inheritable_attribute(:mandatory_options) or write_inheritable_attribute(:mandatory_options, {})
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def default_options(options = nil)
|
|
32
|
+
if options
|
|
33
|
+
write_inheritable_attribute(:default_options, options)
|
|
34
|
+
else
|
|
35
|
+
read_inheritable_attribute(:default_options) or write_inheritable_attribute(:default_options, {})
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Merge together our class options. In increasing precedence:
|
|
40
|
+
# default_options (class default options)
|
|
41
|
+
# runtime_options (provided as argument)
|
|
42
|
+
# mandatory_options (class mandatory options)
|
|
43
|
+
def full_options(runtime_options = {})
|
|
44
|
+
default_options.merge(runtime_options).merge(mandatory_options)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# Each instance has an options hash that's populated by #parse.
|
|
50
|
+
def options
|
|
51
|
+
@options ||= {}
|
|
52
|
+
end
|
|
53
|
+
attr_writer :options
|
|
54
|
+
|
|
55
|
+
protected
|
|
56
|
+
# Convenient access to class mandatory options.
|
|
57
|
+
def mandatory_options
|
|
58
|
+
self.class.mandatory_options
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# Convenient access to class default options.
|
|
62
|
+
def default_options
|
|
63
|
+
self.class.default_options
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# Merge together our instance options. In increasing precedence:
|
|
67
|
+
# default_options (class default options)
|
|
68
|
+
# options (instance options)
|
|
69
|
+
# runtime_options (provided as argument)
|
|
70
|
+
# mandatory_options (class mandatory options)
|
|
71
|
+
def full_options(runtime_options = {})
|
|
72
|
+
self.class.full_options(options.merge(runtime_options))
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# Parse arguments into the options hash. Classes may customize
|
|
76
|
+
# parsing behavior by overriding these methods:
|
|
77
|
+
# #banner Usage: ./script/generate [options]
|
|
78
|
+
# #add_options! Options:
|
|
79
|
+
# some options..
|
|
80
|
+
# #add_general_options! General Options:
|
|
81
|
+
# general options..
|
|
82
|
+
def parse!(args, runtime_options = {})
|
|
83
|
+
self.options = {}
|
|
84
|
+
|
|
85
|
+
@option_parser = OptionParser.new do |opt|
|
|
86
|
+
opt.banner = banner
|
|
87
|
+
add_options!(opt)
|
|
88
|
+
add_general_options!(opt)
|
|
89
|
+
opt.parse!(args)
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
return args
|
|
93
|
+
ensure
|
|
94
|
+
self.options = full_options(runtime_options)
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
# Raise a usage error. Override usage_message to provide a blurb
|
|
98
|
+
# after the option parser summary.
|
|
99
|
+
def usage
|
|
100
|
+
raise UsageError, "#{@option_parser}\n#{usage_message}"
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def usage_message
|
|
104
|
+
''
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
# Override with your own usage banner.
|
|
108
|
+
def banner
|
|
109
|
+
"Usage: #{$0} [options]"
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
# Override to add your options to the parser:
|
|
113
|
+
# def add_options!(opt)
|
|
114
|
+
# opt.on('-v', '--verbose') { |value| options[:verbose] = value }
|
|
115
|
+
# end
|
|
116
|
+
def add_options!(opt)
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
# Adds general options like -h and --quiet. Usually don't override.
|
|
120
|
+
def add_general_options!(opt)
|
|
121
|
+
opt.separator ''
|
|
122
|
+
opt.separator 'General Options:'
|
|
123
|
+
|
|
124
|
+
opt.on('-p', '--pretend', 'Run but do not make any changes.') { |options[:pretend]| }
|
|
125
|
+
opt.on('-f', '--force', 'Overwrite files that already exist.') { options[:collision] = :force }
|
|
126
|
+
opt.on('-s', '--skip', 'Skip files that already exist.') { options[:collision] = :skip }
|
|
127
|
+
opt.on('-q', '--quiet', 'Suppress normal output.') { |options[:quiet]| }
|
|
128
|
+
opt.on('-t', '--backtrace', 'Debugging: show backtrace on errors.') { |options[:backtrace]| }
|
|
129
|
+
opt.on('-h', '--help', 'Show this help message.') { |options[:help]| }
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
end
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
require File.dirname(__FILE__) + '/options'
|
|
2
|
+
|
|
3
|
+
module Rails
|
|
4
|
+
module Generator
|
|
5
|
+
module Scripts
|
|
6
|
+
|
|
7
|
+
# Generator scripts handle command-line invocation. Each script
|
|
8
|
+
# responds to an invoke! class method which handles option parsing
|
|
9
|
+
# and generator invocation.
|
|
10
|
+
class Base
|
|
11
|
+
include Options
|
|
12
|
+
default_options :collision => :ask, :quiet => false
|
|
13
|
+
|
|
14
|
+
# Run the generator script. Takes an array of unparsed arguments
|
|
15
|
+
# and a hash of parsed arguments, takes the generator as an option
|
|
16
|
+
# or first remaining argument, and invokes the requested command.
|
|
17
|
+
def run(args = [], runtime_options = {})
|
|
18
|
+
begin
|
|
19
|
+
parse!(args.dup, runtime_options)
|
|
20
|
+
rescue OptionParser::InvalidOption => e
|
|
21
|
+
# Don't cry, script. Generators want what you think is invalid.
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Generator name is the only required option.
|
|
25
|
+
unless options[:generator]
|
|
26
|
+
usage if args.empty?
|
|
27
|
+
options[:generator] ||= args.shift
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# Look up generator instance and invoke command on it.
|
|
31
|
+
Rails::Generator::Base.instance(options[:generator], args, options).command(options[:command]).invoke!
|
|
32
|
+
rescue => e
|
|
33
|
+
puts e
|
|
34
|
+
puts " #{e.backtrace.join("\n ")}\n" if options[:backtrace]
|
|
35
|
+
raise SystemExit
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
protected
|
|
39
|
+
# Override with your own script usage banner.
|
|
40
|
+
def banner
|
|
41
|
+
"Usage: #{$0} [options] generator [args]"
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def usage_message
|
|
45
|
+
usage = "\nInstalled Generators\n"
|
|
46
|
+
Rails::Generator::Base.sources.each do |source|
|
|
47
|
+
label = source.label.to_s.capitalize
|
|
48
|
+
names = source.names
|
|
49
|
+
usage << " #{label}: #{names.join(', ')}\n" unless names.empty?
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
usage << <<end_blurb
|
|
53
|
+
|
|
54
|
+
More are available at http://rubyonrails.org/show/Generators
|
|
55
|
+
1. Download, for example, login_generator.zip
|
|
56
|
+
2. Unzip to directory #{Dir.user_home}/.rails/generators/login
|
|
57
|
+
to use the generator with all your Rails apps
|
|
58
|
+
end_blurb
|
|
59
|
+
|
|
60
|
+
if Object.const_defined?(:RAILS_ROOT)
|
|
61
|
+
usage << <<end_blurb
|
|
62
|
+
or to #{File.expand_path(RAILS_ROOT)}/script/generators/login
|
|
63
|
+
to use with this app only.
|
|
64
|
+
end_blurb
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
usage << <<end_blurb
|
|
68
|
+
3. Run generate with no arguments for usage information
|
|
69
|
+
#{$0} login
|
|
70
|
+
|
|
71
|
+
Generator gems are also available:
|
|
72
|
+
1. gem list generator -s http://gems.rubyonrails.org
|
|
73
|
+
2. gem install login_generator -s http://gems.rubyonrails.org
|
|
74
|
+
3. #{$0} login
|
|
75
|
+
|
|
76
|
+
end_blurb
|
|
77
|
+
return usage
|
|
78
|
+
end
|
|
79
|
+
end # Base
|
|
80
|
+
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
module Rails
|
|
2
|
+
module Generator
|
|
3
|
+
class SimpleLogger # :nodoc:
|
|
4
|
+
attr_reader :out
|
|
5
|
+
attr_accessor :quiet
|
|
6
|
+
|
|
7
|
+
def initialize(out = $stdout)
|
|
8
|
+
@out = out
|
|
9
|
+
@quiet = false
|
|
10
|
+
@level = 0
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def log(status, message, &block)
|
|
14
|
+
@out.print("%12s %s%s\n" % [status, ' ' * @level, message]) unless quiet
|
|
15
|
+
indent(&block) if block_given?
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def indent(&block)
|
|
19
|
+
@level += 1
|
|
20
|
+
if block_given?
|
|
21
|
+
begin
|
|
22
|
+
block.call
|
|
23
|
+
ensure
|
|
24
|
+
outdent
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def outdent
|
|
30
|
+
@level -= 1
|
|
31
|
+
if block_given?
|
|
32
|
+
begin
|
|
33
|
+
block.call
|
|
34
|
+
ensure
|
|
35
|
+
indent
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
private
|
|
41
|
+
def method_missing(method, *args, &block)
|
|
42
|
+
log(method.to_s, args.first, &block)
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
module Rails
|
|
2
|
+
module Generator
|
|
3
|
+
# A spec knows where a generator was found and how to instantiate it.
|
|
4
|
+
# Metadata include the generator's name, its base path, and the source
|
|
5
|
+
# which yielded it (PathSource, GemSource, etc.)
|
|
6
|
+
class Spec
|
|
7
|
+
attr_reader :name, :path, :source
|
|
8
|
+
|
|
9
|
+
def initialize(name, path, source)
|
|
10
|
+
@name, @path, @source = name, path, source
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# Look up the generator class. Require its class file, find the class
|
|
14
|
+
# in ObjectSpace, tag it with this spec, and return.
|
|
15
|
+
def klass
|
|
16
|
+
unless @klass
|
|
17
|
+
require class_file
|
|
18
|
+
@klass = lookup_class
|
|
19
|
+
@klass.spec = self
|
|
20
|
+
end
|
|
21
|
+
@klass
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def class_file
|
|
25
|
+
"#{path}/#{name}_generator.rb"
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def class_name
|
|
29
|
+
"#{name.camelize}Generator"
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
private
|
|
33
|
+
# Search for the first Class descending from Rails::Generator::Base
|
|
34
|
+
# whose name matches the requested class name.
|
|
35
|
+
def lookup_class
|
|
36
|
+
ObjectSpace.each_object(Class) do |obj|
|
|
37
|
+
return obj if obj.ancestors.include?(Rails::Generator::Base) and
|
|
38
|
+
obj.name.split('::').last == class_name
|
|
39
|
+
end
|
|
40
|
+
raise NameError, "Missing #{class_name} class in #{class_file}"
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
#--
|
|
2
|
+
# Copyright (c) 2004 Jeremy Kemper
|
|
3
|
+
#
|
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
|
5
|
+
# a copy of this software and associated documentation files (the
|
|
6
|
+
# "Software"), to deal in the Software without restriction, including
|
|
7
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
|
8
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
|
9
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
|
10
|
+
# the following conditions:
|
|
11
|
+
#
|
|
12
|
+
# The above copyright notice and this permission notice shall be
|
|
13
|
+
# included in all copies or substantial portions of the Software.
|
|
14
|
+
#
|
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
16
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
17
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
18
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
19
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
20
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
21
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
22
|
+
#++
|
|
23
|
+
|
|
24
|
+
$:.unshift(File.dirname(__FILE__))
|
|
25
|
+
$:.unshift(File.dirname(__FILE__) + "/../../activesupport/lib")
|
|
26
|
+
|
|
27
|
+
begin
|
|
28
|
+
require 'active_support'
|
|
29
|
+
rescue LoadError
|
|
30
|
+
require 'rubygems'
|
|
31
|
+
require_gem 'activesupport'
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
require 'rails_generator/base'
|
|
35
|
+
require 'rails_generator/lookup'
|
|
36
|
+
require 'rails_generator/commands'
|
|
37
|
+
|
|
38
|
+
Rails::Generator::Base.send(:include, Rails::Generator::Lookup)
|
|
39
|
+
Rails::Generator::Base.send(:include, Rails::Generator::Commands)
|
|
40
|
+
|
|
41
|
+
# Set up a default logger for convenience.
|
|
42
|
+
require 'rails_generator/simple_logger'
|
|
43
|
+
Rails::Generator::Base.logger = Rails::Generator::SimpleLogger.new(STDOUT)
|
data/lib/rubyprof_ext.rb
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
require 'prof'
|
|
2
|
+
|
|
3
|
+
module Prof
|
|
4
|
+
# Adapted from Shugo Maeda's unprof.rb
|
|
5
|
+
def self.print_profile(results, io = $stderr)
|
|
6
|
+
total = results.detect { |i|
|
|
7
|
+
i.method_class.nil? && i.method_id == :"#toplevel"
|
|
8
|
+
}.total_time
|
|
9
|
+
total = 0.001 if total < 0.001
|
|
10
|
+
|
|
11
|
+
io.puts " %% cumulative self self total"
|
|
12
|
+
io.puts " time seconds seconds calls ms/call ms/call name"
|
|
13
|
+
|
|
14
|
+
sum = 0.0
|
|
15
|
+
for r in results
|
|
16
|
+
sum += r.self_time
|
|
17
|
+
|
|
18
|
+
name = if r.method_class.nil?
|
|
19
|
+
r.method_id.to_s
|
|
20
|
+
elsif r.method_class.is_a?(Class)
|
|
21
|
+
"#{r.method_class}##{r.method_id}"
|
|
22
|
+
else
|
|
23
|
+
"#{r.method_class}.#{r.method_id}"
|
|
24
|
+
end
|
|
25
|
+
io.printf "%6.2f %8.3f %8.3f %8d %8.2f %8.2f %s\n",
|
|
26
|
+
r.self_time / total * 100,
|
|
27
|
+
sum,
|
|
28
|
+
r.self_time,
|
|
29
|
+
r.count,
|
|
30
|
+
r.self_time * 1000 / r.count,
|
|
31
|
+
r.total_time * 1000 / r.count,
|
|
32
|
+
name
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|