Add the has_many_polymorphs plugin
[cs356-p2-videostore.git] / vendor / plugins / has_many_polymorphs / generators / tagging / tagging_generator.rb
diff --git a/vendor/plugins/has_many_polymorphs/generators/tagging/tagging_generator.rb b/vendor/plugins/has_many_polymorphs/generators/tagging/tagging_generator.rb
new file mode 100644 (file)
index 0000000..31fb088
--- /dev/null
@@ -0,0 +1,95 @@
+require 'ruby-debug' and Debugger.start if ENV['USER'] == 'eweaver'
+
+class TaggingGenerator < Rails::Generator::NamedBase
+  default_options :skip_migration => false
+  default_options :self_referential => false
+  attr_reader :parent_association_name
+  attr_reader :taggable_models
+
+  def initialize(runtime_args, runtime_options = {})
+    @parent_association_name = (runtime_args.include?("--self-referential") ? "tagger" : "tag")
+    @taggable_models = runtime_args.reject{|opt| opt =~ /^--/}.map do |taggable|
+      ":" + taggable.underscore.pluralize
+    end
+    @taggable_models += [":tags"] if runtime_args.include?("--self-referential") 
+    @taggable_models.uniq!
+        
+    verify @taggable_models
+    hacks     
+    runtime_args.unshift("placeholder")
+    super
+  end
+  
+  def verify models
+    puts "** Warning: only one taggable model specified; tests may not run properly." if models.size < 2
+    models.each do |model|
+      model = model[1..-1].classify
+      next if model == "Tag" # don't load ourselves when --self-referential is used
+      self.class.const_get(model) rescue puts "** Error: model #{model[1..-1].classify} could not be loaded." or exit
+    end
+  end
+  
+  def hacks    
+    # add the extension require in environment.rb
+    phrase = "require 'tagging_extensions'"
+    filename = "#{RAILS_ROOT}/config/environment.rb"
+    unless (open(filename) do |file|
+      file.grep(/#{Regexp.escape phrase}/).any?
+    end)
+      open(filename, 'a+') do |file|
+        file.puts "\n" + phrase + "\n"
+      end
+    end
+  end
+  
+  def manifest
+    record do |m|
+      m.class_collisions class_path, class_name, "#{class_name}Test"
+
+      m.directory File.join('app/models', class_path)
+      m.directory File.join('test/unit', class_path)
+      m.directory File.join('test/fixtures', class_path)
+      m.directory File.join('test/fixtures', class_path)
+      m.directory File.join('lib')
+
+      m.template 'tag.rb', File.join('app/models', class_path, "tag.rb")
+      m.template 'tag_test.rb', File.join('test/unit', class_path, "tag_test.rb")
+      m.template 'tags.yml', File.join('test/fixtures', class_path, "tags.yml")
+      
+      m.template 'tagging.rb', File.join('app/models', class_path, "tagging.rb")
+      m.template 'tagging_test.rb', File.join('test/unit', class_path, "tagging_test.rb")
+      m.template 'taggings.yml', File.join('test/fixtures', class_path, "taggings.yml")
+      
+      m.template 'tagging_extensions.rb', File.join('lib', 'tagging_extensions.rb')
+
+      unless options[:skip_migration]
+        m.migration_template 'migration.rb', 'db/migrate',
+          :migration_file_name => "create_tags_and_taggings"
+      end
+      
+    end
+  end
+
+  protected
+    def banner
+      "Usage: #{$0} generate tagging [TaggableModelA TaggableModelB ...]"
+    end
+
+    def add_options!(opt)
+      opt.separator ''
+      opt.separator 'Options:'
+      opt.on("--skip-migration", 
+             "Don't generate a migration file for this model") { |v| options[:skip_migration] = v }
+      opt.on("--self-referential",
+             "Allow tags to tag themselves.") { |v| options[:self_referential] = v }
+    end
+    
+    # Useful for generating tests/fixtures
+    def model_one
+      taggable_models[0][1..-1].classify
+    end
+    
+    def model_two
+      taggable_models[1][1..-1].classify rescue model_one
+    end
+end