1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
|
require 'optparse'
module Rails
module Generator
module Options
def self.included(base)
base.extend(ClassMethods)
class << base
if respond_to?(:inherited)
alias_method :inherited_without_options, :inherited
end
alias_method :inherited, :inherited_with_options
end
end
module ClassMethods
def inherited_with_options(sub)
inherited_without_options(sub) if respond_to?(:inherited_without_options)
sub.extend(Rails::Generator::Options::ClassMethods)
end
def mandatory_options(options = nil)
if options
write_inheritable_attribute(:mandatory_options, options)
else
read_inheritable_attribute(:mandatory_options) or write_inheritable_attribute(:mandatory_options, {})
end
end
def default_options(options = nil)
if options
write_inheritable_attribute(:default_options, options)
else
read_inheritable_attribute(:default_options) or write_inheritable_attribute(:default_options, {})
end
end
# Merge together our class options. In increasing precedence:
# default_options (class default options)
# runtime_options (provided as argument)
# mandatory_options (class mandatory options)
def full_options(runtime_options = {})
default_options.merge(runtime_options).merge(mandatory_options)
end
end
# Each instance has an options hash that's populated by #parse.
def options
@options ||= {}
end
attr_writer :options
protected
# Convenient access to class mandatory options.
def mandatory_options
self.class.mandatory_options
end
# Convenient access to class default options.
def default_options
self.class.default_options
end
# Merge together our instance options. In increasing precedence:
# default_options (class default options)
# options (instance options)
# runtime_options (provided as argument)
# mandatory_options (class mandatory options)
def full_options(runtime_options = {})
self.class.full_options(options.merge(runtime_options))
end
# Parse arguments into the options hash. Classes may customize
# parsing behavior by overriding these methods:
# #banner Usage: ./script/generate [options]
# #add_options! Options:
# some options..
# #add_general_options! General Options:
# general options..
def parse!(args, runtime_options = {})
self.options = {}
@option_parser = OptionParser.new do |opt|
opt.banner = banner
add_options!(opt)
add_general_options!(opt)
opt.parse!(args)
end
return args
ensure
self.options = full_options(runtime_options)
end
# Raise a usage error. Override usage_message to provide a blurb
# after the option parser summary.
def usage(message = usage_message)
raise UsageError, "#{@option_parser}\n#{message}"
end
def usage_message
''
end
# Override with your own usage banner.
def banner
"Usage: #{$0} [options]"
end
# Override to add your options to the parser:
# def add_options!(opt)
# opt.on('-v', '--verbose') { |value| options[:verbose] = value }
# end
def add_options!(opt)
end
# Adds general options like -h and --quiet. Usually don't override.
def add_general_options!(opt)
opt.separator ''
opt.separator 'Rails Info:'
opt.on('-v', '--version', 'Show the Rails version number and quit.')
opt.on('-h', '--help', 'Show this help message and quit.') { |v| options[:help] = v }
opt.separator ''
opt.separator 'General Options:'
opt.on('-p', '--pretend', 'Run but do not make any changes.') { |v| options[:pretend] = v }
opt.on('-f', '--force', 'Overwrite files that already exist.') { options[:collision] = :force }
opt.on('-s', '--skip', 'Skip files that already exist.') { options[:collision] = :skip }
opt.on('-q', '--quiet', 'Suppress normal output.') { |v| options[:quiet] = v }
opt.on('-t', '--backtrace', 'Debugging: show backtrace on errors.') { |v| options[:backtrace] = v }
opt.on('-c', '--svn', 'Modify files with subversion. (Note: svn must be in path)') do
options[:svn] = `svn status`.inject({}) do |opt, e|
opt[e.chomp[7..-1]] = true
opt
end
end
opt.on('-g', '--git', 'Modify files with git. (Note: git must be in path)') do
options[:git] = `git status`.inject({:new => {}, :modified => {}}) do |opt, e|
opt[:new][e.chomp[14..-1]] = true if e =~ /new file:/
opt[:modified][e.chomp[14..-1]] = true if e =~ /modified:/
opt
end
end
end
end
end
end
|