shattered_ruby 0.5.0.2

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.
Files changed (60) hide show
  1. data/bin/console +4 -0
  2. data/bin/destroy +9 -0
  3. data/bin/generate +7 -0
  4. data/bin/runner +9 -0
  5. data/bin/shatter +22 -0
  6. data/lib/commands/console.rb +23 -0
  7. data/lib/game_loader.rb +118 -0
  8. data/lib/rails_generator/base.rb +203 -0
  9. data/lib/rails_generator/commands.rb +519 -0
  10. data/lib/rails_generator/generators/applications/shattered_app/USAGE +10 -0
  11. data/lib/rails_generator/generators/applications/shattered_app/shattered_app_generator.rb +103 -0
  12. data/lib/rails_generator/generators/components/actor/actor_generator.rb +22 -0
  13. data/lib/rails_generator/generators/components/actor/templates/actor.rb +0 -0
  14. data/lib/rails_generator/generators/components/model/USAGE +17 -0
  15. data/lib/rails_generator/generators/components/model/model_generator.rb +22 -0
  16. data/lib/rails_generator/generators/components/model/templates/fixtures.yml +5 -0
  17. data/lib/rails_generator/generators/components/model/templates/model.rb +2 -0
  18. data/lib/rails_generator/generators/components/model/templates/unit_test.rb +11 -0
  19. data/lib/rails_generator/generators/components/state/USAGE +30 -0
  20. data/lib/rails_generator/generators/components/state/state_generator.rb +19 -0
  21. data/lib/rails_generator/generators/components/state/templates/state.rb +31 -0
  22. data/lib/rails_generator/generators/components/view/USAGE +30 -0
  23. data/lib/rails_generator/generators/components/view/templates/material +4 -0
  24. data/lib/rails_generator/generators/components/view/templates/view.rb +9 -0
  25. data/lib/rails_generator/generators/components/view/view_generator.rb +28 -0
  26. data/lib/rails_generator/lookup.rb +209 -0
  27. data/lib/rails_generator/manifest.rb +53 -0
  28. data/lib/rails_generator/options.rb +143 -0
  29. data/lib/rails_generator/scripts/destroy.rb +7 -0
  30. data/lib/rails_generator/scripts/generate.rb +7 -0
  31. data/lib/rails_generator/scripts/update.rb +12 -0
  32. data/lib/rails_generator/scripts.rb +83 -0
  33. data/lib/rails_generator/simple_logger.rb +46 -0
  34. data/lib/rails_generator/spec.rb +44 -0
  35. data/lib/rails_generator.rb +43 -0
  36. data/lib/shatter.rb +7 -0
  37. data/lib/tasks/documentation.rake +46 -0
  38. data/lib/tasks/framework.rake +80 -0
  39. data/lib/tasks/log.rake +9 -0
  40. data/lib/tasks/misc.rake +4 -0
  41. data/lib/tasks/pre_namespace_aliases.rake +28 -0
  42. data/lib/tasks/shattered.rb +6 -0
  43. data/lib/tasks/statistics.rake +17 -0
  44. data/lib/tasks/testing.rake +102 -0
  45. data/lib/templates/MIT-LICENSE +20 -0
  46. data/lib/templates/README +35 -0
  47. data/lib/templates/Rakefile +11 -0
  48. data/lib/templates/configs/boot.rb +35 -0
  49. data/lib/templates/configs/empty.log +0 -0
  50. data/lib/templates/configs/ogre.cfg +4 -0
  51. data/lib/templates/configs/ogre_plugins.windows.cfg +14 -0
  52. data/lib/templates/configs/runner.rb +5 -0
  53. data/lib/templates/doc/README_FOR_APP +2 -0
  54. data/lib/templates/environments/environment.rb +10 -0
  55. data/lib/templates/media/basic.rmaterial +18 -0
  56. data/lib/templates/media/default.mesh +0 -0
  57. data/lib/templates/media/default.png +0 -0
  58. data/lib/templates/media/offset_map.rmaterial +117 -0
  59. data/lib/templates/test/test_helper.rb +5 -0
  60. metadata +153 -0
@@ -0,0 +1,519 @@
1
+ require 'delegate'
2
+ require 'optparse'
3
+ require 'fileutils'
4
+ require 'erb'
5
+
6
+ module Rails
7
+ module Generator
8
+ module Commands
9
+ # Here's a convenient way to get a handle on generator commands.
10
+ # Command.instance('destroy', my_generator) instantiates a Destroy
11
+ # delegate of my_generator ready to do your dirty work.
12
+ def self.instance(command, generator)
13
+ const_get(command.to_s.camelize).new(generator)
14
+ end
15
+
16
+ # Even more convenient access to commands. Include Commands in
17
+ # the generator Base class to get a nice #command instance method
18
+ # which returns a delegate for the requested command.
19
+ def self.included(base)
20
+ base.send(:define_method, :command) do |command|
21
+ Commands.instance(command, self)
22
+ end
23
+ end
24
+
25
+
26
+ # Generator commands delegate Rails::Generator::Base and implement
27
+ # a standard set of actions. Their behavior is defined by the way
28
+ # they respond to these actions: Create brings life; Destroy brings
29
+ # death; List passively observes.
30
+ #
31
+ # Commands are invoked by replaying (or rewinding) the generator's
32
+ # manifest of actions. See Rails::Generator::Manifest and
33
+ # Rails::Generator::Base#manifest method that generator subclasses
34
+ # are required to override.
35
+ #
36
+ # Commands allows generators to "plug in" invocation behavior, which
37
+ # corresponds to the GoF Strategy pattern.
38
+ class Base < DelegateClass(Rails::Generator::Base)
39
+ # Replay action manifest. RewindBase subclass rewinds manifest.
40
+ def invoke!
41
+ manifest.replay(self)
42
+ end
43
+
44
+ def dependency(generator_name, args, runtime_options = {})
45
+ logger.dependency(generator_name) do
46
+ self.class.new(instance(generator_name, args, full_options(runtime_options))).invoke!
47
+ end
48
+ end
49
+
50
+ # Does nothing for all commands except Create.
51
+ def class_collisions(*class_names)
52
+ end
53
+
54
+ # Does nothing for all commands except Create.
55
+ def readme(*args)
56
+ end
57
+
58
+ protected
59
+ def migration_directory(relative_path)
60
+ directory(@migration_directory = relative_path)
61
+ end
62
+
63
+ def existing_migrations(file_name)
64
+ Dir.glob("#{@migration_directory}/[0-9]*_*.rb").grep(/[0-9]+_#{file_name}.rb$/)
65
+ end
66
+
67
+ def migration_exists?(file_name)
68
+ not existing_migrations(file_name).empty?
69
+ end
70
+
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
+ def next_migration_string(padding = 3)
83
+ "%.#{padding}d" % next_migration_number
84
+ end
85
+
86
+ private
87
+ # Ask the user interactively whether to force collision.
88
+ def force_file_collision?(destination)
89
+ $stdout.print "overwrite #{destination}? [Ynaq] "
90
+ case $stdin.gets
91
+ when /a/i
92
+ $stdout.puts "forcing #{spec.name}"
93
+ options[:collision] = :force
94
+ when /q/i
95
+ $stdout.puts "aborting #{spec.name}"
96
+ raise SystemExit
97
+ when /n/i then :skip
98
+ else :force
99
+ end
100
+ rescue
101
+ retry
102
+ end
103
+
104
+ def render_template_part(template_options)
105
+ # Getting Sandbox to evaluate part template in it
106
+ part_binding = template_options[:sandbox].call.sandbox_binding
107
+ part_rel_path = template_options[:insert]
108
+ part_path = source_path(part_rel_path)
109
+
110
+ # Render inner template within Sandbox binding
111
+ rendered_part = ERB.new(File.readlines(part_path).join, nil, '-').result(part_binding)
112
+ begin_mark = template_part_mark(template_options[:begin_mark], template_options[:mark_id])
113
+ end_mark = template_part_mark(template_options[:end_mark], template_options[:mark_id])
114
+ begin_mark + rendered_part + end_mark
115
+ end
116
+
117
+ def template_part_mark(name, id)
118
+ "<!--[#{name}:#{id}]-->\n"
119
+ end
120
+ end
121
+
122
+ # Base class for commands which handle generator actions in reverse, such as Destroy.
123
+ class RewindBase < Base
124
+ # Rewind action manifest.
125
+ def invoke!
126
+ manifest.rewind(self)
127
+ end
128
+ end
129
+
130
+
131
+ # Create is the premier generator command. It copies files, creates
132
+ # directories, renders templates, and more.
133
+ class Create < Base
134
+
135
+ # Check whether the given class names are already taken by
136
+ # Ruby or Rails. In the future, expand to check other namespaces
137
+ # such as the rest of the user's app.
138
+ def class_collisions(*class_names)
139
+ class_names.flatten.each do |class_name|
140
+ # Convert to string to allow symbol arguments.
141
+ class_name = class_name.to_s
142
+
143
+ # Skip empty strings.
144
+ next if class_name.strip.empty?
145
+
146
+ # Split the class from its module nesting.
147
+ nesting = class_name.split('::')
148
+ name = nesting.pop
149
+
150
+ # Extract the last Module in the nesting.
151
+ last = nesting.inject(Object) { |last, nest|
152
+ break unless last.const_defined?(nest)
153
+ last.const_get(nest)
154
+ }
155
+
156
+ # If the last Module exists, check whether the given
157
+ # class exists and raise a collision if so.
158
+ if last and last.const_defined?(name.camelize)
159
+ raise_class_collision(class_name)
160
+ end
161
+ end
162
+ end
163
+
164
+ # Copy a file from source to destination with collision checking.
165
+ #
166
+ # The file_options hash accepts :chmod and :shebang and :collision options.
167
+ # :chmod sets the permissions of the destination file:
168
+ # file 'config/empty.log', 'log/test.log', :chmod => 0664
169
+ # :shebang sets the #!/usr/bin/ruby line for scripts
170
+ # file 'bin/generate.rb', 'script/generate', :chmod => 0755, :shebang => '/usr/bin/env ruby'
171
+ # :collision sets the collision option only for the destination file:
172
+ # file 'settings/server.yml', 'config/server.yml', :collision => :skip
173
+ #
174
+ # Collisions are handled by checking whether the destination file
175
+ # exists and either skipping the file, forcing overwrite, or asking
176
+ # the user what to do.
177
+ def file(relative_source, relative_destination, file_options = {}, &block)
178
+ # Determine full paths for source and destination files.
179
+ source = source_path(relative_source)
180
+ destination = destination_path(relative_destination)
181
+ destination_exists = File.exists?(destination)
182
+
183
+ # If source and destination are identical then we're done.
184
+ if destination_exists and identical?(source, destination, &block)
185
+ return logger.identical(relative_destination)
186
+ end
187
+
188
+ # Check for and resolve file collisions.
189
+ if destination_exists
190
+
191
+ # Make a choice whether to overwrite the file. :force and
192
+ # :skip already have their mind made up, but give :ask a shot.
193
+ choice = case (file_options[:collision] || options[:collision]).to_sym #|| :ask
194
+ when :ask then force_file_collision?(relative_destination)
195
+ when :force then :force
196
+ when :skip then :skip
197
+ else raise "Invalid collision option: #{options[:collision].inspect}"
198
+ end
199
+
200
+ # Take action based on our choice. Bail out if we chose to
201
+ # skip the file; otherwise, log our transgression and continue.
202
+ case choice
203
+ when :force then logger.force(relative_destination)
204
+ when :skip then return(logger.skip(relative_destination))
205
+ else raise "Invalid collision choice: #{choice}.inspect"
206
+ end
207
+
208
+ # File doesn't exist so log its unbesmirched creation.
209
+ else
210
+ logger.create relative_destination
211
+ end
212
+
213
+ # If we're pretending, back off now.
214
+ return if options[:pretend]
215
+
216
+ # Write destination file with optional shebang. Yield for content
217
+ # if block given so templaters may render the source file. If a
218
+ # shebang is requested, replace the existing shebang or insert a
219
+ # new one.
220
+ File.open(destination, 'wb') do |df|
221
+ File.open(source, 'rb') do |sf|
222
+ if block_given?
223
+ df.write(yield(sf))
224
+ else
225
+ if file_options[:shebang]
226
+ df.puts("#!#{file_options[:shebang]}")
227
+ if line = sf.gets
228
+ df.puts(line) if line !~ /^#!/
229
+ end
230
+ end
231
+ df.write(sf.read)
232
+ end
233
+ end
234
+ end
235
+
236
+ # Optionally change permissions.
237
+ if file_options[:chmod]
238
+ FileUtils.chmod(file_options[:chmod], destination)
239
+ end
240
+
241
+ # Optionally add file to subversion
242
+ system("svn add #{destination}") if options[:svn]
243
+ end
244
+
245
+ # Checks if the source and the destination file are identical. If
246
+ # passed a block then the source file is a template that needs to first
247
+ # be evaluated before being compared to the destination.
248
+ def identical?(source, destination, &block)
249
+ return false if File.directory? destination
250
+ source = block_given? ? File.open(source) {|sf| yield(sf)} : IO.read(source)
251
+ destination = IO.read(destination)
252
+ source == destination
253
+ end
254
+
255
+ # Generate a file for a Rails application using an ERuby template.
256
+ # Looks up and evalutes a template by name and writes the result.
257
+ #
258
+ # The ERB template uses explicit trim mode to best control the
259
+ # proliferation of whitespace in generated code. <%- trims leading
260
+ # whitespace; -%> trims trailing whitespace including one newline.
261
+ #
262
+ # A hash of template options may be passed as the last argument.
263
+ # The options accepted by the file are accepted as well as :assigns,
264
+ # a hash of variable bindings. Example:
265
+ # template 'foo', 'bar', :assigns => { :action => 'view' }
266
+ #
267
+ # Template is implemented in terms of file. It calls file with a
268
+ # block which takes a file handle and returns its rendered contents.
269
+ def template(relative_source, relative_destination, template_options = {})
270
+ file(relative_source, relative_destination, template_options) do |file|
271
+ # Evaluate any assignments in a temporary, throwaway binding.
272
+ vars = template_options[:assigns] || {}
273
+ b = binding
274
+ vars.each { |k,v| eval "#{k} = vars[:#{k}] || vars['#{k}']", b }
275
+
276
+ # Render the source file with the temporary binding.
277
+ ERB.new(file.read, nil, '-').result(b)
278
+ end
279
+ end
280
+
281
+ def complex_template(relative_source, relative_destination, template_options = {})
282
+ options = template_options.dup
283
+ options[:assigns] ||= {}
284
+ options[:assigns]['template_for_inclusion'] = render_template_part(template_options)
285
+ template(relative_source, relative_destination, options)
286
+ end
287
+
288
+ # Create a directory including any missing parent directories.
289
+ # Always directories which exist.
290
+ def directory(relative_path)
291
+ path = destination_path(relative_path)
292
+ if File.exists?(path)
293
+ logger.exists relative_path
294
+ else
295
+ logger.create relative_path
296
+ FileUtils.mkdir_p(path) unless options[:pretend]
297
+
298
+ # Optionally add file to subversion
299
+ system("svn add #{path}") if options[:svn]
300
+ end
301
+ end
302
+
303
+ # Display a README.
304
+ def readme(*relative_sources)
305
+ relative_sources.flatten.each do |relative_source|
306
+ logger.readme relative_source
307
+ puts File.read(source_path(relative_source)) unless options[:pretend]
308
+ end
309
+ end
310
+
311
+ # When creating a migration, it knows to find the first available file in db/migrate and use the migration.rb template.
312
+ def migration_template(relative_source, relative_destination, template_options = {})
313
+ migration_directory relative_destination
314
+ migration_file_name = template_options[:migration_file_name] || file_name
315
+ raise "Another migration is already named #{migration_file_name}: #{existing_migrations(migration_file_name).first}" if migration_exists?(migration_file_name)
316
+ template(relative_source, "#{relative_destination}/#{next_migration_string}_#{migration_file_name}.rb", template_options)
317
+ end
318
+
319
+ private
320
+ # Raise a usage error with an informative WordNet suggestion.
321
+ # Thanks to Florian Gross (flgr).
322
+ def raise_class_collision(class_name)
323
+ message = <<end_message
324
+ The name '#{class_name}' is reserved by Ruby on Rails.
325
+ Please choose an alternative and run this generator again.
326
+ end_message
327
+ if suggest = find_synonyms(class_name)
328
+ message << "\n Suggestions: \n\n"
329
+ message << suggest.join("\n")
330
+ end
331
+ raise UsageError, message
332
+ end
333
+
334
+ SYNONYM_LOOKUP_URI = "http://wordnet.princeton.edu/cgi-bin/webwn2.0?stage=2&word=%s&posnumber=1&searchtypenumber=2&senses=&showglosses=1"
335
+
336
+ # Look up synonyms on WordNet. Thanks to Florian Gross (flgr).
337
+ def find_synonyms(word)
338
+ require 'open-uri'
339
+ require 'timeout'
340
+ timeout(5) do
341
+ open(SYNONYM_LOOKUP_URI % word) do |stream|
342
+ data = stream.read.gsub("&nbsp;", " ").gsub("<BR>", "")
343
+ data.scan(/^Sense \d+\n.+?\n\n/m)
344
+ end
345
+ end
346
+ rescue Exception
347
+ return nil
348
+ end
349
+ end
350
+
351
+
352
+ # Undo the actions performed by a generator. Rewind the action
353
+ # manifest and attempt to completely erase the results of each action.
354
+ class Destroy < RewindBase
355
+ # Remove a file if it exists and is a file.
356
+ def file(relative_source, relative_destination, file_options = {})
357
+ destination = destination_path(relative_destination)
358
+ if File.exists?(destination)
359
+ logger.rm relative_destination
360
+ unless options[:pretend]
361
+ if options[:svn]
362
+ # If the file has been marked to be added
363
+ # but has not yet been checked in, revert and delete
364
+ if options[:svn][relative_destination]
365
+ system("svn revert #{destination}")
366
+ FileUtils.rm(destination)
367
+ else
368
+ # If the directory is not in the status list, it
369
+ # has no modifications so we can simply remove it
370
+ system("svn rm #{destination}")
371
+ end
372
+ else
373
+ FileUtils.rm(destination)
374
+ end
375
+ end
376
+ else
377
+ logger.missing relative_destination
378
+ return
379
+ end
380
+ end
381
+
382
+ # Templates are deleted just like files and the actions take the
383
+ # same parameters, so simply alias the file method.
384
+ alias_method :template, :file
385
+
386
+ # Remove each directory in the given path from right to left.
387
+ # Remove each subdirectory if it exists and is a directory.
388
+ def directory(relative_path)
389
+ parts = relative_path.split('/')
390
+ until parts.empty?
391
+ partial = File.join(parts)
392
+ path = destination_path(partial)
393
+ if File.exists?(path)
394
+ if Dir[File.join(path, '*')].empty?
395
+ logger.rmdir partial
396
+ unless options[:pretend]
397
+ if options[:svn]
398
+ # If the directory has been marked to be added
399
+ # but has not yet been checked in, revert and delete
400
+ if options[:svn][relative_path]
401
+ system("svn revert #{path}")
402
+ FileUtils.rmdir(path)
403
+ else
404
+ # If the directory is not in the status list, it
405
+ # has no modifications so we can simply remove it
406
+ system("svn rm #{path}")
407
+ end
408
+ else
409
+ FileUtils.rmdir(path)
410
+ end
411
+ end
412
+ else
413
+ logger.notempty partial
414
+ end
415
+ else
416
+ logger.missing partial
417
+ end
418
+ parts.pop
419
+ end
420
+ end
421
+
422
+ def complex_template(*args)
423
+ # nothing should be done here
424
+ end
425
+
426
+ # When deleting a migration, it knows to delete every file named "[0-9]*_#{file_name}".
427
+ def migration_template(relative_source, relative_destination, template_options = {})
428
+ migration_directory relative_destination
429
+
430
+ migration_file_name = template_options[:migration_file_name] || file_name
431
+ unless migration_exists?(migration_file_name)
432
+ puts "There is no migration named #{migration_file_name}"
433
+ return
434
+ end
435
+
436
+
437
+ existing_migrations(migration_file_name).each do |file_path|
438
+ file(relative_source, file_path, template_options)
439
+ end
440
+ end
441
+ end
442
+
443
+
444
+ # List a generator's action manifest.
445
+ class List < Base
446
+ def dependency(generator_name, args, options = {})
447
+ logger.dependency "#{generator_name}(#{args.join(', ')}, #{options.inspect})"
448
+ end
449
+
450
+ def class_collisions(*class_names)
451
+ logger.class_collisions class_names.join(', ')
452
+ end
453
+
454
+ def file(relative_source, relative_destination, options = {})
455
+ logger.file relative_destination
456
+ end
457
+
458
+ def template(relative_source, relative_destination, options = {})
459
+ logger.template relative_destination
460
+ end
461
+
462
+ def complex_template(relative_source, relative_destination, options = {})
463
+ logger.template "#{options[:insert]} inside #{relative_destination}"
464
+ end
465
+
466
+ def directory(relative_path)
467
+ logger.directory "#{destination_path(relative_path)}/"
468
+ end
469
+
470
+ def readme(*args)
471
+ logger.readme args.join(', ')
472
+ end
473
+
474
+ def migration_template(relative_source, relative_destination, options = {})
475
+ migration_directory relative_destination
476
+ logger.migration_template file_name
477
+ end
478
+ end
479
+
480
+ # Update generator's action manifest.
481
+ class Update < Create
482
+ def file(relative_source, relative_destination, options = {})
483
+ # logger.file relative_destination
484
+ end
485
+
486
+ def template(relative_source, relative_destination, options = {})
487
+ # logger.template relative_destination
488
+ end
489
+
490
+ def complex_template(relative_source, relative_destination, template_options = {})
491
+
492
+ begin
493
+ dest_file = destination_path(relative_destination)
494
+ source_to_update = File.readlines(dest_file).join
495
+ rescue Errno::ENOENT
496
+ logger.missing relative_destination
497
+ return
498
+ end
499
+
500
+ logger.refreshing "#{template_options[:insert].gsub(/\.rhtml/,'')} inside #{relative_destination}"
501
+
502
+ begin_mark = Regexp.quote(template_part_mark(template_options[:begin_mark], template_options[:mark_id]))
503
+ end_mark = Regexp.quote(template_part_mark(template_options[:end_mark], template_options[:mark_id]))
504
+
505
+ # Refreshing inner part of the template with freshly rendered part.
506
+ rendered_part = render_template_part(template_options)
507
+ source_to_update.gsub!(/#{begin_mark}.*?#{end_mark}/m, rendered_part)
508
+
509
+ File.open(dest_file, 'w') { |file| file.write(source_to_update) }
510
+ end
511
+
512
+ def directory(relative_path)
513
+ # logger.directory "#{destination_path(relative_path)}/"
514
+ end
515
+ end
516
+
517
+ end
518
+ end
519
+ end
@@ -0,0 +1,10 @@
1
+ Description:
2
+ The 'shatter' command creates a new Shattered application with a default
3
+ directory structure and configuration at the path you specify.
4
+
5
+ Example:
6
+ shatter ~/Code/Ruby/Quake15
7
+
8
+ This will create a skeletal Shattered application for the next version of
9
+ Quake. See the README in the newly created application to get going.
10
+
@@ -0,0 +1,103 @@
1
+ require 'rbconfig'
2
+
3
+ class ShatteredAppGenerator < Rails::Generator::Base #:nodoc:all
4
+ DEFAULT_SHEBANG = File.join(Config::CONFIG['bindir'],
5
+ Config::CONFIG['ruby_install_name'])
6
+
7
+ default_options :gem => true, :shebang => DEFAULT_SHEBANG
8
+ mandatory_options :source => "#{File.dirname(__FILE__)}/../../../.."
9
+
10
+ def initialize(runtime_args, runtime_options = {})
11
+ super
12
+ usage if args.empty?
13
+ @destination_root = args.shift
14
+ end
15
+
16
+ def manifest
17
+ script_options = { :chmod => 0755, :shebang => options[:shebang] }
18
+
19
+ record do |m|
20
+ # Root directory and all subdirectories.
21
+ m.directory ''
22
+ BASEDIRS.each { |path| m.directory path }
23
+
24
+ # Root
25
+ m.file "templates/Rakefile", "Rakefile"
26
+ m.file "templates/README", "README"
27
+
28
+ # ogre plugins and configuration
29
+ m.file "templates/configs/ogre_plugins.windows.cfg", "config/ogre_plugins.windows.cfg"
30
+ m.template "templates/configs/ogre.cfg", "config/ogre.cfg"
31
+ m.template "templates/configs/boot.rb", "config/boot.rb"
32
+
33
+ # Environments
34
+ m.file "templates/environments/environment.rb", "config/environment.rb"
35
+
36
+ # Testing
37
+ m.file "templates/test/test_helper.rb", "test/test_helper.rb"
38
+
39
+ # Mac OSX
40
+ # TODO: OSX support needs to be revisited.
41
+ #m.file "templates/configs/Mac/shattered.app/Contents/Info.plist", "config/Mac/shattered.app/Contents/Info.plist"
42
+ #m.file "templates/configs/Mac/shattered.app/Contents/MacOS/shattered_mac", "config/Mac/shattered.app/Contents/MacOS/shattered_mac"
43
+ #m.file "templates/configs/Mac/shattered.app/Contents/pbdevelopment.plist", "config/Mac/shattered.app/Contents/pbdevelopment.plist"
44
+ #m.file "templates/configs/Mac/shattered.app/Contents/PkgInfo", "config/Mac/shattered.app/Contents/PkgInfo"
45
+ #m.file "templates/configs/Mac/shattered.app/Contents/Resources/English.lproj/InfoPlist.strings", "config/Mac/shattered.app/Contents/Resources/English.lproj/InfoPlist.strings"
46
+ #m.file "templates/configs/Mac/shattered.app/Contents/Resources/English.lproj/MainMenu.nib/classes.nib", "config/Mac/shattered.app/Contents/Resources/English.lproj/MainMenu.nib/classes.nib"
47
+ #m.file "templates/configs/Mac/shattered.app/Contents/Resources/English.lproj/MainMenu.nib/info.nib", "config/Mac/shattered.app/Contents/Resources/English.lproj/MainMenu.nib/info.nib"
48
+ #m.file "templates/configs/Mac/shattered.app/Contents/Resources/English.lproj/MainMenu.nib/objects.nib", "config/Mac/shattered.app/Contents/Resources/English.lproj/MainMenu.nib/objects.nib"
49
+ #m.file "templates/configs/Mac/shattered.app/Contents/Resources/rb_main.rb", "config/Mac/shattered.app/Contents/Resources/rb_main.rb"
50
+
51
+ # Scripts
52
+ %w( generate runner console destroy ).each do |file|
53
+ m.file "../bin/#{file}", "script/#{file}", script_options
54
+ end
55
+
56
+ m.file "templates/configs/runner.rb", "script/runner.rb"
57
+
58
+ # Docs
59
+ m.file "templates/doc/README_FOR_APP", "doc/README_FOR_APP"
60
+
61
+ # Logs
62
+ %w(ogre shattered).each { |file|
63
+ m.file "templates/configs/empty.log", "log/#{file}.log", :chmod => 0666
64
+ }
65
+
66
+ # basic rmaterial
67
+ m.file "templates/media/basic.rmaterial", "app/media/common/templates/basic.rmaterial"
68
+ m.file "templates/media/offset_map.rmaterial", "app/media/common/templates/offset_map.rmaterial"
69
+ end
70
+ end
71
+
72
+ protected
73
+ def banner
74
+ "Usage: #{$0} /path/to/your/app [options]"
75
+ end
76
+
77
+ def add_options!(opt)
78
+ opt.separator ''
79
+ opt.separator 'Options:'
80
+ opt.on("--ruby [#{DEFAULT_SHEBANG}]",
81
+ "Path to the Ruby binary of your choice.") { |options[:shebang]| }
82
+ opt.on("--without-gems",
83
+ "Don't use the Shattered gems for your app.",
84
+ "This does not currently work.") { |options[:gem]| }
85
+ end
86
+
87
+
88
+ # Installation skeleton. Intermediate directories are automatically
89
+ # created so don't sweat their absence here.
90
+ BASEDIRS = %w(
91
+ app/models
92
+ app/views
93
+ app/media/common/programs
94
+ app/media/common/templates
95
+ doc
96
+ config
97
+ log
98
+ script
99
+ test/unit
100
+ vendor
101
+ vendor/plugins
102
+ )
103
+ end
@@ -0,0 +1,22 @@
1
+ # require File.dirname(__FILE__) + '/../config/environment'
2
+ # require 'rails_generator'
3
+ # require 'rails_generator/scripts/generate'
4
+
5
+ # ARGV.shift if ['--help', '-h'].include?(ARGV[0])
6
+ # Rails::Generator::Scripts::Generate.new.run(ARGV)
7
+ require File.dirname(__FILE__) + '/../model/model_generator'
8
+ require File.dirname(__FILE__) + '/../view/view_generator'
9
+
10
+ class ActorGenerator < Rails::Generator::NamedBase #:nodoc:
11
+ def manifest
12
+ generators = [ModelGenerator, ViewGenerator]
13
+ record do |m|
14
+ generators.each do |generator|
15
+ generator.check_collisions(m, class_path, class_name)
16
+ end
17
+ generators.each do |generator|
18
+ generator.generate(m, class_path, file_name)
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,17 @@
1
+ Description:
2
+ The model generator creates stubs for a new model.
3
+
4
+ The generator takes a model name as its argument. The model name may be
5
+ given in CamelCase or under_score and should not be suffixed with 'Model'.
6
+
7
+ The generator creates a model class in app/models, a test suite in
8
+ test/unit, and test fixtures in test/fixtures/singular_name.yml.
9
+
10
+ Example:
11
+ ./script/generate model Account
12
+
13
+ This will create an Account model:
14
+ Model: app/models/account.rb
15
+ Test: test/unit/account_test.rb
16
+ Fixtures: test/fixtures/accounts.yml
17
+