rubigen 1.4.0 → 1.5.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.autotest +13 -0
- data/History.txt +14 -1
- data/Manifest.txt +11 -7
- data/{README.txt → README.rdoc} +21 -7
- data/Rakefile +20 -3
- data/Todo.txt +4 -2
- data/bin/install_rubigen_scripts +0 -0
- data/bin/rubigen +10 -0
- data/bin/ruby_app +0 -0
- data/features/development.feature +13 -0
- data/features/help.feature +14 -0
- data/features/rubigen_cli.feature +10 -0
- data/features/steps/common.rb +195 -0
- data/features/steps/env.rb +6 -0
- data/lib/rubigen/base.rb +11 -1
- data/lib/rubigen/cli.rb +31 -0
- data/lib/rubigen/commands.rb +76 -80
- data/lib/rubigen/lookup.rb +5 -7
- data/lib/rubigen/options.rb +7 -0
- data/lib/rubigen/scripts/destroy.rb +3 -0
- data/lib/rubigen/scripts.rb +15 -8
- data/lib/rubigen.rb +6 -1
- data/rubygems_generators/application_generator/USAGE +2 -2
- data/rubygems_generators/application_generator/application_generator_generator.rb +1 -1
- data/rubygems_generators/application_generator/templates/generator.rb +1 -1
- data/rubygems_generators/application_generator/templates/readme +2 -2
- data/rubygems_generators/component_generator/USAGE +3 -4
- data/rubygems_generators/component_generator/component_generator_generator.rb +1 -5
- data/rubygems_generators/component_generator/templates/generator.rb +1 -1
- data/rubygems_generators/component_generator/templates/readme +1 -1
- data/script/console +10 -0
- data/script/destroy +1 -1
- data/script/generate +1 -1
- data/test/test_component_generator_generator.rb +0 -26
- data/test/test_generator_helper.rb +3 -1
- data/test/test_helper.rb +2 -0
- data/test/test_install_rubigen_scripts_generator.rb +1 -1
- data/test/test_rubigen_cli.rb +71 -0
- data/website/index.html +5 -5
- data/website/index.txt +5 -5
- metadata +34 -16
- data/config/hoe.rb +0 -74
- data/config/requirements.rb +0 -17
- data/setup.rb +0 -1585
- data/tasks/deployment.rake +0 -34
- data/tasks/environment.rake +0 -7
- data/tasks/website.rake +0 -17
data/lib/rubigen/commands.rb
CHANGED
@@ -39,6 +39,7 @@ module RubiGen
|
|
39
39
|
# Replay action manifest. RewindBase subclass rewinds manifest.
|
40
40
|
def invoke!
|
41
41
|
manifest.replay(self)
|
42
|
+
after_generate
|
42
43
|
end
|
43
44
|
|
44
45
|
def dependency(generator_name, args, runtime_options = {})
|
@@ -56,6 +57,17 @@ module RubiGen
|
|
56
57
|
end
|
57
58
|
|
58
59
|
protected
|
60
|
+
def current_migration_number
|
61
|
+
Dir.glob("#{RAILS_ROOT}/#{@migration_directory}/[0-9]*_*.rb").inject(0) do |max, file_path|
|
62
|
+
n = File.basename(file_path).split('_', 2).first.to_i
|
63
|
+
if n > max then n else max end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def next_migration_number
|
68
|
+
current_migration_number + 1
|
69
|
+
end
|
70
|
+
|
59
71
|
def migration_directory(relative_path)
|
60
72
|
directory(@migration_directory = relative_path)
|
61
73
|
end
|
@@ -68,19 +80,12 @@ module RubiGen
|
|
68
80
|
not existing_migrations(file_name).empty?
|
69
81
|
end
|
70
82
|
|
71
|
-
def current_migration_number
|
72
|
-
Dir.glob("#{@migration_directory}/[0-9]*.rb").inject(0) do |max, file_path|
|
73
|
-
n = File.basename(file_path).split('_', 2).first.to_i
|
74
|
-
if n > max then n else max end
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
def next_migration_number
|
79
|
-
current_migration_number + 1
|
80
|
-
end
|
81
|
-
|
82
83
|
def next_migration_string(padding = 3)
|
83
|
-
|
84
|
+
if ActiveRecord::Base.timestamped_migrations
|
85
|
+
Time.now.utc.strftime("%Y%m%d%H%M%S")
|
86
|
+
else
|
87
|
+
"%.#{padding}d" % next_migration_number
|
88
|
+
end
|
84
89
|
end
|
85
90
|
|
86
91
|
def gsub_file(relative_destination, regexp, *args, &block)
|
@@ -92,29 +97,39 @@ module RubiGen
|
|
92
97
|
private
|
93
98
|
# Ask the user interactively whether to force collision.
|
94
99
|
def force_file_collision?(destination, src, dst, file_options = {}, &block)
|
95
|
-
|
96
|
-
|
97
|
-
case $stdin.gets
|
98
|
-
when /
|
100
|
+
stdout.print "overwrite #{destination}? (enter \"h\" for help) [Ynaiqd] "
|
101
|
+
stdout.flush
|
102
|
+
case $stdin.gets.chomp
|
103
|
+
when /\Ad\z/i
|
99
104
|
Tempfile.open(File.basename(destination), File.dirname(dst)) do |temp|
|
100
105
|
temp.write render_file(src, file_options, &block)
|
101
106
|
temp.rewind
|
102
|
-
|
107
|
+
stdout.puts `#{diff_cmd} #{dst} #{temp.path}`
|
103
108
|
end
|
104
109
|
stdout.puts "retrying"
|
105
110
|
raise 'retry diff'
|
106
|
-
when /
|
107
|
-
|
111
|
+
when /\Aa\z/i
|
112
|
+
stdout.puts "forcing #{spec.name}"
|
108
113
|
options[:collision] = :force
|
109
|
-
when /i
|
110
|
-
|
114
|
+
when /\Ai\z/i
|
115
|
+
stdout.puts "ignoring #{spec.name}"
|
111
116
|
options[:collision] = :skip
|
112
|
-
when /
|
113
|
-
|
117
|
+
when /\Aq\z/i
|
118
|
+
stdout.puts "aborting #{spec.name}"
|
114
119
|
raise SystemExit
|
115
|
-
when /
|
116
|
-
when /
|
117
|
-
else
|
120
|
+
when /\An\z/i then :skip
|
121
|
+
when /\Ay\z/i then :force
|
122
|
+
else
|
123
|
+
$stdout.puts <<-HELP.gsub(/^ /, '')
|
124
|
+
Y - yes, overwrite
|
125
|
+
n - no, do not overwrite
|
126
|
+
a - all, overwrite this and all others
|
127
|
+
i - ignore, skip any conflicts
|
128
|
+
q - quit, abort
|
129
|
+
d - diff, show the differences between the old and the new
|
130
|
+
h - help, show this help
|
131
|
+
HELP
|
132
|
+
raise 'retry'
|
118
133
|
end
|
119
134
|
rescue
|
120
135
|
retry
|
@@ -201,7 +216,7 @@ module RubiGen
|
|
201
216
|
# Determine full paths for source and destination files.
|
202
217
|
source = source_path(relative_source)
|
203
218
|
destination = destination_path(relative_destination)
|
204
|
-
destination_exists = File.
|
219
|
+
destination_exists = File.exist?(destination)
|
205
220
|
|
206
221
|
# If source and destination are identical then we're done.
|
207
222
|
if destination_exists and identical?(source, destination, &block)
|
@@ -249,7 +264,7 @@ module RubiGen
|
|
249
264
|
FileUtils.chmod(file_options[:chmod], destination)
|
250
265
|
end
|
251
266
|
|
252
|
-
# Optionally add file to subversion
|
267
|
+
# Optionally add file to subversion or git
|
253
268
|
system("svn add #{destination}") if options[:svn]
|
254
269
|
end
|
255
270
|
|
@@ -267,6 +282,7 @@ module RubiGen
|
|
267
282
|
files.each do |file_name|
|
268
283
|
file "#{template_path}#{file_name}", "#{path}#{file_name}", options
|
269
284
|
end
|
285
|
+
system("git add -v #{relative_destination}") if options[:git]
|
270
286
|
end
|
271
287
|
|
272
288
|
# Checks if the source and the destination file are identical. If
|
@@ -280,7 +296,7 @@ module RubiGen
|
|
280
296
|
end
|
281
297
|
|
282
298
|
# Generate a file using an ERuby template.
|
283
|
-
# Looks up and
|
299
|
+
# Looks up and evaluates a template by name and writes the result.
|
284
300
|
#
|
285
301
|
# The ERB template uses explicit trim mode to best control the
|
286
302
|
# proliferation of whitespace in generated code. <%- trims leading
|
@@ -320,22 +336,24 @@ module RubiGen
|
|
320
336
|
end
|
321
337
|
|
322
338
|
# Create a directory including any missing parent directories.
|
323
|
-
# Always directories which exist.
|
339
|
+
# Always skips directories which exist.
|
324
340
|
def directory(relative_path)
|
325
341
|
path = destination_path(relative_path)
|
326
|
-
if File.
|
342
|
+
if File.exist?(path)
|
327
343
|
logger.exists relative_path
|
328
344
|
else
|
329
345
|
logger.create relative_path
|
330
346
|
unless options[:pretend]
|
331
347
|
FileUtils.mkdir_p(path)
|
348
|
+
# git doesn't require adding the paths, adding the files later will
|
349
|
+
# automatically do a path add.
|
332
350
|
|
333
351
|
# Subversion doesn't do path adds, so we need to add
|
334
352
|
# each directory individually.
|
335
353
|
# So stack up the directory tree and add the paths to
|
336
354
|
# subversion in order without recursion.
|
337
355
|
if options[:svn]
|
338
|
-
stack=[relative_path]
|
356
|
+
stack = [relative_path]
|
339
357
|
until File.dirname(stack.last) == stack.last # dirname('.') == '.'
|
340
358
|
stack.push File.dirname(stack.last)
|
341
359
|
end
|
@@ -356,45 +374,6 @@ module RubiGen
|
|
356
374
|
end
|
357
375
|
end
|
358
376
|
|
359
|
-
# Display a README.
|
360
|
-
def write_manifest(relative_destination)
|
361
|
-
files = ([relative_destination] + Dir["#{destination_root}/**/*"])
|
362
|
-
files.reject! { |file| File.directory?(file) }
|
363
|
-
files.map! { |path| path.sub("#{destination_root}/","") }
|
364
|
-
files = files.uniq.sort
|
365
|
-
|
366
|
-
|
367
|
-
destination = destination_path(relative_destination)
|
368
|
-
destination_exists = File.exists?(destination)
|
369
|
-
|
370
|
-
# Check for and resolve file collisions.
|
371
|
-
if destination_exists
|
372
|
-
# Always recreate the Manifest (perhaps we need to give the option... like normal files)
|
373
|
-
choice = :force
|
374
|
-
logger.force(relative_destination)
|
375
|
-
|
376
|
-
# File doesn't exist so log its unbesmirched creation.
|
377
|
-
else
|
378
|
-
logger.create relative_destination
|
379
|
-
end
|
380
|
-
|
381
|
-
# If we're pretending, back off now.
|
382
|
-
return if options[:pretend]
|
383
|
-
|
384
|
-
# Write destination file with optional shebang. Yield for content
|
385
|
-
# if block given so templaters may render the source file. If a
|
386
|
-
# shebang is requested, replace the existing shebang or insert a
|
387
|
-
# new one.
|
388
|
-
File.open(destination, 'wb') do |dest|
|
389
|
-
dest.write files.join("\n")
|
390
|
-
dest.write "\n"
|
391
|
-
end
|
392
|
-
|
393
|
-
# Optionally add file to subversion
|
394
|
-
system("svn add #{destination}") if options[:svn]
|
395
|
-
|
396
|
-
end
|
397
|
-
|
398
377
|
# When creating a migration, it knows to find the first available file in db/migrate and use the migration.rb template.
|
399
378
|
def migration_template(relative_source, relative_destination, template_options = {})
|
400
379
|
migration_directory relative_destination
|
@@ -436,18 +415,20 @@ module RubiGen
|
|
436
415
|
# Raise a usage error with an informative WordNet suggestion.
|
437
416
|
# Thanks to Florian Gross (flgr).
|
438
417
|
def raise_class_collision(class_name)
|
439
|
-
message =
|
440
|
-
The name '#{class_name}' is reserved.
|
418
|
+
message = <<-end_message
|
419
|
+
The name '#{class_name}' is either already used in your application or reserved.
|
441
420
|
Please choose an alternative and run this generator again.
|
442
421
|
end_message
|
443
422
|
if suggest = find_synonyms(class_name)
|
444
|
-
|
445
|
-
|
423
|
+
if suggest.any?
|
424
|
+
message << "\n Suggestions: \n\n"
|
425
|
+
message << suggest.join("\n")
|
426
|
+
end
|
446
427
|
end
|
447
428
|
raise UsageError, message
|
448
429
|
end
|
449
430
|
|
450
|
-
SYNONYM_LOOKUP_URI = "http://wordnet.princeton.edu/
|
431
|
+
SYNONYM_LOOKUP_URI = "http://wordnet.princeton.edu/perl/webwn?s=%s"
|
451
432
|
|
452
433
|
# Look up synonyms on WordNet. Thanks to Florian Gross (flgr).
|
453
434
|
def find_synonyms(word)
|
@@ -455,8 +436,8 @@ end_message
|
|
455
436
|
require 'timeout'
|
456
437
|
timeout(5) do
|
457
438
|
open(SYNONYM_LOOKUP_URI % word) do |stream|
|
458
|
-
|
459
|
-
data.scan(
|
439
|
+
# Grab words linked to dictionary entries as possible synonyms
|
440
|
+
data = stream.read.gsub(" ", " ").scan(/<a href="webwn.*?">([\w ]*?)<\/a>/s).uniq
|
460
441
|
end
|
461
442
|
end
|
462
443
|
rescue Exception
|
@@ -471,7 +452,7 @@ end_message
|
|
471
452
|
# Remove a file if it exists and is a file.
|
472
453
|
def file(relative_source, relative_destination, file_options = {})
|
473
454
|
destination = destination_path(relative_destination)
|
474
|
-
if File.
|
455
|
+
if File.exist?(destination)
|
475
456
|
logger.rm relative_destination
|
476
457
|
unless options[:pretend]
|
477
458
|
if options[:svn]
|
@@ -485,6 +466,19 @@ end_message
|
|
485
466
|
# has no modifications so we can simply remove it
|
486
467
|
system("svn rm #{destination}")
|
487
468
|
end
|
469
|
+
elsif options[:git]
|
470
|
+
if options[:git][:new][relative_destination]
|
471
|
+
# file has been added, but not committed
|
472
|
+
system("git reset HEAD #{relative_destination}")
|
473
|
+
FileUtils.rm(destination)
|
474
|
+
elsif options[:git][:modified][relative_destination]
|
475
|
+
# file is committed and modified
|
476
|
+
system("git rm -f #{relative_destination}")
|
477
|
+
else
|
478
|
+
# If the directory is not in the status list, it
|
479
|
+
# has no modifications so we can simply remove it
|
480
|
+
system("git rm #{relative_destination}")
|
481
|
+
end
|
488
482
|
else
|
489
483
|
FileUtils.rm(destination)
|
490
484
|
end
|
@@ -506,7 +500,7 @@ end_message
|
|
506
500
|
until parts.empty?
|
507
501
|
partial = File.join(parts)
|
508
502
|
path = destination_path(partial)
|
509
|
-
if File.
|
503
|
+
if File.exist?(path)
|
510
504
|
if Dir[File.join(path, '*')].empty?
|
511
505
|
logger.rmdir partial
|
512
506
|
unless options[:pretend]
|
@@ -521,6 +515,8 @@ end_message
|
|
521
515
|
# has no modifications so we can simply remove it
|
522
516
|
system("svn rm #{path}")
|
523
517
|
end
|
518
|
+
# I don't think git needs to remove directories?..
|
519
|
+
# or maybe they have special consideration...
|
524
520
|
else
|
525
521
|
FileUtils.rmdir(path)
|
526
522
|
end
|
data/lib/rubigen/lookup.rb
CHANGED
@@ -8,7 +8,7 @@ class Object
|
|
8
8
|
def lookup_missing_generator(class_id)
|
9
9
|
if md = /(.+)Generator$/.match(class_id.to_s)
|
10
10
|
name = md.captures.first.demodulize.underscore
|
11
|
-
RubiGen::Base.lookup(name).klass
|
11
|
+
RubiGen::Base.active.lookup(name).klass
|
12
12
|
else
|
13
13
|
const_missing_before_generators(class_id)
|
14
14
|
end
|
@@ -49,12 +49,12 @@ module RubiGen
|
|
49
49
|
module Lookup
|
50
50
|
def self.included(base)
|
51
51
|
base.extend(ClassMethods)
|
52
|
-
base.use_component_sources!
|
52
|
+
# base.use_component_sources! # TODO is this required since it has no scope/source context
|
53
53
|
end
|
54
54
|
|
55
55
|
# Convenience method to instantiate another generator.
|
56
56
|
def instance(generator_name, args, runtime_options = {})
|
57
|
-
self.class.instance(generator_name, args, runtime_options)
|
57
|
+
self.class.active.instance(generator_name, args, runtime_options)
|
58
58
|
end
|
59
59
|
|
60
60
|
module ClassMethods
|
@@ -71,7 +71,7 @@ module RubiGen
|
|
71
71
|
end
|
72
72
|
write_inheritable_attribute(:sources, diff)
|
73
73
|
end
|
74
|
-
use_component_sources! if read_inheritable_attribute(:sources).blank?
|
74
|
+
active.use_component_sources! if read_inheritable_attribute(:sources).blank?
|
75
75
|
end
|
76
76
|
read_inheritable_attribute(:sources)
|
77
77
|
end
|
@@ -162,7 +162,7 @@ module RubiGen
|
|
162
162
|
|
163
163
|
# Convenience method to lookup and instantiate a generator.
|
164
164
|
def instance(generator_name, args = [], runtime_options = {})
|
165
|
-
lookup(generator_name).klass.new(args, full_options(runtime_options))
|
165
|
+
active.lookup(generator_name).klass.new(args, full_options(runtime_options))
|
166
166
|
end
|
167
167
|
|
168
168
|
private
|
@@ -202,8 +202,6 @@ module RubiGen
|
|
202
202
|
case filter
|
203
203
|
when :visible
|
204
204
|
mem << spec.name if spec.visible?
|
205
|
-
else
|
206
|
-
usage_message
|
207
205
|
end
|
208
206
|
mem
|
209
207
|
end.sort
|
data/lib/rubigen/options.rb
CHANGED
@@ -130,6 +130,13 @@ module RubiGen
|
|
130
130
|
opt
|
131
131
|
end
|
132
132
|
end
|
133
|
+
opt.on('-g', '--git', 'Modify files with git. (Note: git must be in path)') do
|
134
|
+
options[:git] = `git status`.inject({:new => {}, :modified => {}}) do |opt, e|
|
135
|
+
opt[:new][e.chomp[14..-1]] = true if e =~ /new file:/
|
136
|
+
opt[:modified][e.chomp[14..-1]] = true if e =~ /modified:/
|
137
|
+
opt
|
138
|
+
end
|
139
|
+
end
|
133
140
|
end
|
134
141
|
|
135
142
|
end
|
@@ -13,6 +13,9 @@ module RubiGen::Scripts
|
|
13
13
|
usage << " #{label}: #{names.join(', ')}\n" unless names.empty?
|
14
14
|
end
|
15
15
|
|
16
|
+
# TODO - extensible blurbs for rails/newgem/adhearsion etc
|
17
|
+
# e.g. for rails script/destroy
|
18
|
+
# http://github.com/rails/rails/tree/daee6fd92ac16878f6806c3382a9e74592aa9656/railties/lib/rails_generator/scripts/destroy.rb
|
16
19
|
usage << <<-end_blurb
|
17
20
|
|
18
21
|
This script will destroy all files created by the corresponding
|
data/lib/rubigen/scripts.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require File.dirname(__FILE__) + '/options'
|
1
|
+
require File.dirname(__FILE__) + '/options' unless Object.const_defined?("RubiGen") && RubiGen.const_defined?("Base")
|
2
2
|
|
3
3
|
module RubiGen
|
4
4
|
module Scripts
|
@@ -9,11 +9,13 @@ module RubiGen
|
|
9
9
|
class Base
|
10
10
|
include Options
|
11
11
|
default_options :collision => :ask, :quiet => false
|
12
|
+
attr_reader :stdout
|
12
13
|
|
13
14
|
# Run the generator script. Takes an array of unparsed arguments
|
14
15
|
# and a hash of parsed arguments, takes the generator as an option
|
15
16
|
# or first remaining argument, and invokes the requested command.
|
16
17
|
def run(args = [], runtime_options = {})
|
18
|
+
@stdout = runtime_options[:stdout] || $stdout
|
17
19
|
begin
|
18
20
|
parse!(args.dup, runtime_options)
|
19
21
|
rescue OptionParser::InvalidOption => e
|
@@ -29,9 +31,9 @@ module RubiGen
|
|
29
31
|
# Look up generator instance and invoke command on it.
|
30
32
|
RubiGen::Base.instance(options[:generator], args, options).command(options[:command]).invoke!
|
31
33
|
rescue => e
|
32
|
-
puts e
|
33
|
-
puts " #{e.backtrace.join("\n ")}\n" if options[:backtrace]
|
34
|
-
raise SystemExit
|
34
|
+
stdout.puts e
|
35
|
+
stdout.puts " #{e.backtrace.join("\n ")}\n" if options[:backtrace]
|
36
|
+
raise SystemExit unless options[:no_exit]
|
35
37
|
end
|
36
38
|
|
37
39
|
protected
|
@@ -42,15 +44,20 @@ module RubiGen
|
|
42
44
|
|
43
45
|
def usage_message
|
44
46
|
usage = "\nInstalled Generators\n"
|
45
|
-
RubiGen::Base.sources.inject(
|
47
|
+
RubiGen::Base.sources.inject([]) do |mem, source|
|
48
|
+
# Using an association list instead of a hash to preserve order,
|
49
|
+
# for aesthetic reasons more than anything else.
|
46
50
|
label = source.label.to_s.capitalize
|
47
|
-
mem
|
48
|
-
mem[label]
|
51
|
+
pair = mem.assoc(label)
|
52
|
+
mem << (pair = [label, []]) if pair.nil?
|
53
|
+
pair[1] |= source.names(:visible)
|
49
54
|
mem
|
50
|
-
end.
|
55
|
+
end.each do |label, names|
|
51
56
|
usage << " #{label}: #{names.join(', ')}\n" unless names.empty?
|
52
57
|
end
|
53
58
|
|
59
|
+
# TODO - extensible blurbs for rails/newgem/adhearsion etc
|
60
|
+
# e.g. for rails http://github.com/rails/rails/tree/daee6fd92ac16878f6806c3382a9e74592aa9656/railties/lib/rails_generator/scripts.rb#L50-74
|
54
61
|
usage << <<-end_blurb
|
55
62
|
|
56
63
|
More are available at http://rubigen.rubyforge.org/
|
data/lib/rubigen.rb
CHANGED
@@ -10,7 +10,7 @@ rescue LoadError
|
|
10
10
|
end
|
11
11
|
|
12
12
|
module RubiGen
|
13
|
-
VERSION = '1.
|
13
|
+
VERSION = '1.5.0'
|
14
14
|
end
|
15
15
|
|
16
16
|
require 'rubigen/base'
|
@@ -24,3 +24,8 @@ RubiGen::Base.send(:include, RubiGen::Commands)
|
|
24
24
|
require 'rubigen/simple_logger'
|
25
25
|
RubiGen::Base.logger = RubiGen::SimpleLogger.new(STDOUT)
|
26
26
|
|
27
|
+
# Use self as default lookup algorithm
|
28
|
+
# If your framework needs to subclass RubiGen::Base, then
|
29
|
+
# assign it to #active after initialising rubigen and your code.
|
30
|
+
RubiGen::Base.active = RubiGen::Base
|
31
|
+
|
@@ -14,10 +14,10 @@ How to create an Application Generator
|
|
14
14
|
6. Run unit tests.
|
15
15
|
7. If your application generator uses other generators (m.dependency "gen-name", [arg1, arg2], :option1 => 'value')
|
16
16
|
then you must add this into the generated bin/foobar file.
|
17
|
-
For example, if you wanted to use a rubygems and/or
|
17
|
+
For example, if you wanted to use a rubygems and/or rails generator, then replace the use_application_sources!
|
18
18
|
call in bin/foobar:
|
19
19
|
|
20
|
-
RubiGen::Base.use_application_sources! :rubygems, :
|
20
|
+
RubiGen::Base.use_application_sources! :rubygems, :rails
|
21
21
|
|
22
22
|
Without this, RubiGen will not be able to find your dependent generators.
|
23
23
|
8. Update your Manifest.txt with the new files (if you are using Hoe; using newgem? it uses Hoe; so you need to do this)
|
@@ -54,7 +54,7 @@ EOS
|
|
54
54
|
# opts.separator 'Options:'
|
55
55
|
# opts.on("-a", "--author=\"Your Name\"", String,
|
56
56
|
# "Generated app file will include your name.",
|
57
|
-
# "Default: none") { |options[:author]
|
57
|
+
# "Default: none") { |o| options[:author] = o }
|
58
58
|
end
|
59
59
|
|
60
60
|
def extract_options
|
@@ -48,7 +48,7 @@ EOS
|
|
48
48
|
# at the top of the file next to "default_options"
|
49
49
|
# opts.on("-a", "--author=\"Your Name\"", String,
|
50
50
|
# "Some comment about this option",
|
51
|
-
# "Default: none") { |options[:author]
|
51
|
+
# "Default: none") { |o| options[:author] = o }
|
52
52
|
opts.on("-v", "--version", "Show the #{File.basename($0)} version number and quit.")
|
53
53
|
end
|
54
54
|
|
@@ -15,10 +15,10 @@ How to create a Generator (Application Generator)
|
|
15
15
|
6. If your application generator uses other generators (called 'dependencies')
|
16
16
|
e.g. (m.dependency "generator-from-rubygems", [arg1, arg2], options)
|
17
17
|
then you must add this generators' scope into the executable bin/myapp.
|
18
|
-
For example, if you wanted to use a rubygems and/or
|
18
|
+
For example, if you wanted to use a rubygems and/or rails generator, then
|
19
19
|
replace the use_application_sources! call in bin/myapp:
|
20
20
|
|
21
|
-
RubiGen::Base.use_application_sources! :rubygems, :
|
21
|
+
RubiGen::Base.use_application_sources! :rubygems, :rails
|
22
22
|
|
23
23
|
Without this, RubiGen will not be able to find your dependent generators.
|
24
24
|
7. Update your Manifest.txt with the new files (rake manifest:refresh)
|
@@ -4,8 +4,7 @@ How to create a Generator (aka Component Generator)
|
|
4
4
|
1. Run this generator: script/generate component_generator mygen scope
|
5
5
|
Where "mygen" is the name of the generator, and scope is scope restriction.
|
6
6
|
A scope of "rubygems" means this generator will only be available to RubyGems developers.
|
7
|
-
A scope of "
|
8
|
-
If you use "rails", then your generator is only accessible by Rails applications (v2.0+).
|
7
|
+
A scope of "rails" means the generator is only accessible to Rails applications
|
9
8
|
2. Using the generated test class, assert what directories, files, classes etc should
|
10
9
|
be generated.
|
11
10
|
3. Add these files into the scope_genearators/mygen/templates folder. Your files can use
|
@@ -18,8 +17,8 @@ How to create a Generator (aka Component Generator)
|
|
18
17
|
6. Add usage information in the USAGE file.
|
19
18
|
7. Update your Manifest.txt with the new files (if you are using Hoe)
|
20
19
|
8. Build and install your RubyGem locally. Run: rake install_gem
|
21
|
-
9. Go to a work area for your scope (e.g. go to the root folder of a
|
22
|
-
to use a "
|
20
|
+
9. Go to a work area for your scope (e.g. go to the root folder of a Rails application
|
21
|
+
to use a "rails" scoped generator)
|
23
22
|
10. Run "script/generate" and your generator should appear in the list of available generators.
|
24
23
|
11. Run "script/generate mygen" to see the options and usage information for your generator.
|
25
24
|
12. Run "script/generator mygen arguments" to execute the generator.
|
@@ -44,8 +44,6 @@ class ComponentGeneratorGenerator < RubiGen::Base
|
|
44
44
|
case (generator_type.to_sym rescue nil)
|
45
45
|
when :rails
|
46
46
|
"Rails::Generator::NamedBase"
|
47
|
-
when :merb
|
48
|
-
"Merb::GeneratorBase"
|
49
47
|
else
|
50
48
|
"RubiGen::Base"
|
51
49
|
end
|
@@ -55,8 +53,6 @@ class ComponentGeneratorGenerator < RubiGen::Base
|
|
55
53
|
case (generator_type.to_sym rescue nil)
|
56
54
|
when :rails
|
57
55
|
["rails_generator"]
|
58
|
-
when :merb
|
59
|
-
["merb-core", "merb-gen"]
|
60
56
|
else
|
61
57
|
[]
|
62
58
|
end
|
@@ -76,7 +72,7 @@ EOS
|
|
76
72
|
# opts.separator 'Options:'
|
77
73
|
# opts.on("-a", "--author=\"Your Name\"", String,
|
78
74
|
# "Generated app file will include your name.",
|
79
|
-
# "Default: none") { |options[:author]
|
75
|
+
# "Default: none") { |o| options[:author] = 0 }
|
80
76
|
end
|
81
77
|
|
82
78
|
def extract_options
|
@@ -42,7 +42,7 @@ EOS
|
|
42
42
|
# at the top of the file next to "default_options"
|
43
43
|
# opts.on("-a", "--author=\"Your Name\"", String,
|
44
44
|
# "Some comment about this option",
|
45
|
-
# "Default: none") { |options[:author]
|
45
|
+
# "Default: none") { |o| options[:author] = o }
|
46
46
|
# opts.on("-v", "--version", "Show the #{File.basename($0)} version number and quit.")
|
47
47
|
end
|
48
48
|
|
@@ -16,7 +16,7 @@ How to create a Generator (Component Generator)
|
|
16
16
|
7. Update your Manifest.txt with the new files (if you are using Hoe)
|
17
17
|
8. Build and install your RubyGem locally. Run: rake install_gem
|
18
18
|
9. Go to a work area whose script/generate for your scope (e.g. go to the root folder
|
19
|
-
of a
|
19
|
+
of a Rails application to use a 'rails' scoped generator.
|
20
20
|
10. Run "script/generate" and your new generator should appear in the list of available generators.
|
21
21
|
11. Run "script/generate mygen" to see the options and usage information for your generator.
|
22
22
|
12. Run "script/generator mygen arguments" to execute the generator.
|
data/script/console
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# File: script/console
|
3
|
+
irb = RUBY_PLATFORM =~ /(:?mswin|mingw)/ ? 'irb.bat' : 'irb'
|
4
|
+
|
5
|
+
libs = " -r irb/completion"
|
6
|
+
# Perhaps use a console_lib to store any extra methods I may want available in the cosole
|
7
|
+
# libs << " -r #{File.dirname(__FILE__) + '/../lib/console_lib/console_logger.rb'}"
|
8
|
+
libs << " -r #{File.dirname(__FILE__) + '/../lib/rubigen.rb'}"
|
9
|
+
puts "Loading rubigen gem"
|
10
|
+
exec "#{irb} #{libs} --simple-prompt"
|
data/script/destroy
CHANGED
@@ -10,5 +10,5 @@ end
|
|
10
10
|
require 'rubigen/scripts/destroy'
|
11
11
|
|
12
12
|
ARGV.shift if ['--help', '-h'].include?(ARGV[0])
|
13
|
-
RubiGen::Base.use_component_sources! [:rubygems
|
13
|
+
RubiGen::Base.use_component_sources! [:rubygems]
|
14
14
|
RubiGen::Scripts::Destroy.new.run(ARGV)
|
data/script/generate
CHANGED
@@ -10,5 +10,5 @@ end
|
|
10
10
|
require 'rubigen/scripts/generate'
|
11
11
|
|
12
12
|
ARGV.shift if ['--help', '-h'].include?(ARGV[0])
|
13
|
-
RubiGen::Base.use_component_sources! [:rubygems
|
13
|
+
RubiGen::Base.use_component_sources! [:rubygems]
|
14
14
|
RubiGen::Scripts::Generate.new.run(ARGV)
|
@@ -88,32 +88,6 @@ class TestGenerateComponentGenerator < Test::Unit::TestCase
|
|
88
88
|
end
|
89
89
|
end
|
90
90
|
|
91
|
-
def test_generator_with_merb_generator_type
|
92
|
-
name = "genname"
|
93
|
-
gen_type = "merb"
|
94
|
-
run_generator('component_generator', [name, gen_type], sources)
|
95
|
-
|
96
|
-
assert_generated_file "#{gen_type}_generators/#{name}/#{name}_generator.rb"
|
97
|
-
assert_generated_file "#{gen_type}_generators/#{name}/USAGE"
|
98
|
-
assert_generated_file "test/test_#{name}_generator.rb"
|
99
|
-
assert_generated_file "test/test_generator_helper.rb"
|
100
|
-
assert_directory_exists "#{gen_type}_generators/#{name}/templates"
|
101
|
-
assert_generated_class "#{gen_type}_generators/#{name}/#{name}_generator" do |body|
|
102
|
-
# assert_has_method body, "initialize" # as_has_m cannot pickup initialize(...) only initialize
|
103
|
-
assert_has_method body, "manifest"
|
104
|
-
gen_class, superclass = body.match(%r{class ([\w:_]+) < ([\w:_]+)})[1..2]
|
105
|
-
assert_equal("GennameGenerator", gen_class)
|
106
|
-
assert_equal("Merb::GeneratorBase", superclass)
|
107
|
-
end
|
108
|
-
assert_generated_class "test/test_#{name}_generator" do |body|
|
109
|
-
assert_has_method body, "setup"
|
110
|
-
assert_has_method body, "teardown"
|
111
|
-
assert_has_method body, "test_generator_without_options"
|
112
|
-
assert_has_method body, "sources"
|
113
|
-
assert_has_method body, "generator_path"
|
114
|
-
end
|
115
|
-
end
|
116
|
-
|
117
91
|
private
|
118
92
|
def sources
|
119
93
|
[RubiGen::PathSource.new(:test, File.join(File.dirname(__FILE__),"../#{generator_path}"))
|
@@ -2,7 +2,7 @@ require File.dirname(__FILE__) + '/test_helper'
|
|
2
2
|
require 'fileutils'
|
3
3
|
|
4
4
|
# Must set before requiring generator libs.
|
5
|
-
TMP_ROOT = File.dirname(__FILE__) + "
|
5
|
+
TMP_ROOT = File.expand_path(File.dirname(__FILE__) + "/../tmp") unless defined?(TMP_ROOT)
|
6
6
|
PROJECT_NAME = "myproject" unless defined?(PROJECT_NAME)
|
7
7
|
app_root = File.join(TMP_ROOT, PROJECT_NAME)
|
8
8
|
if defined?(APP_ROOT)
|
@@ -11,4 +11,6 @@ else
|
|
11
11
|
APP_ROOT = app_root
|
12
12
|
end
|
13
13
|
|
14
|
+
FileUtils.mkdir_p(APP_ROOT)
|
15
|
+
|
14
16
|
require 'rubigen/helpers/generator_test_helper'
|
data/test/test_helper.rb
CHANGED
@@ -26,7 +26,7 @@ class TestInstallRubigenScriptsGenerator < Test::Unit::TestCase
|
|
26
26
|
# bare_teardown - place this in teardown method to destroy the TMP_ROOT or APP_ROOT folder after each test
|
27
27
|
|
28
28
|
def test_install_rubigen_scripts_should_create_script_generate
|
29
|
-
run_generator('install_rubigen_scripts', [APP_ROOT] + %w(rubygems
|
29
|
+
run_generator('install_rubigen_scripts', [APP_ROOT] + %w(rubygems foobar), sources)
|
30
30
|
assert_directory_exists "script"
|
31
31
|
assert_generated_file "script/generate"
|
32
32
|
assert_generated_file "script/destroy"
|