diff .svn/pristine/5d/5dc200a9880b49ee8adf93752f95bd14fc23a33e.svn-base @ 909:cbb26bc654de redmine-1.3

Update to Redmine 1.3-stable branch (Redmine SVN rev 8964)
author Chris Cannam
date Fri, 24 Feb 2012 19:09:32 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.svn/pristine/5d/5dc200a9880b49ee8adf93752f95bd14fc23a33e.svn-base	Fri Feb 24 19:09:32 2012 +0000
@@ -0,0 +1,98 @@
+# Generates a migration which migrates all plugins to their latest versions
+# within the database.
+class PluginMigrationGenerator < Rails::Generator::Base
+  
+  # 255 characters max for Windows NTFS (http://en.wikipedia.org/wiki/Filename)
+  # minus 14 for timestamp, minus some extra chars for dot, underscore, file 
+  # extension. So let's have 230.
+  MAX_FILENAME_LENGTH = 230
+    
+  def initialize(runtime_args, runtime_options={})
+    super
+    @options = {:assigns => {}}
+    ensure_schema_table_exists    
+    get_plugins_to_migrate(runtime_args)
+    
+    if @plugins_to_migrate.empty?
+      puts "All plugins are migrated to their latest versions"
+      exit(0)
+    end
+
+    @options[:migration_file_name] = build_migration_name
+    @options[:assigns][:class_name] = build_migration_name.classify
+  end
+  
+  def manifest
+    record do |m|
+      m.migration_template 'plugin_migration.erb', 'db/migrate', @options
+    end
+  end
+  
+  protected
+
+    # Create the schema table if it doesn't already exist.
+    def ensure_schema_table_exists
+      ActiveRecord::Base.connection.initialize_schema_migrations_table
+    end
+
+    # Determine all the plugins which have migrations that aren't present
+    # according to the plugin schema information from the database.
+    def get_plugins_to_migrate(plugin_names)
+
+      # First, grab all the plugins which exist and have migrations
+      @plugins_to_migrate = if plugin_names.empty?
+        Engines.plugins
+      else
+        plugin_names.map do |name| 
+          Engines.plugins[name] ? Engines.plugins[name] : raise("Cannot find the plugin '#{name}'")
+        end
+      end
+      
+      @plugins_to_migrate.reject! { |p| !p.respond_to?(:latest_migration) || p.latest_migration.nil? }
+      
+      # Then find the current versions from the database    
+      @current_versions = {}
+      @plugins_to_migrate.each do |plugin|
+        @current_versions[plugin.name] = Engines::Plugin::Migrator.current_version(plugin)
+      end
+
+      # Then find the latest versions from their migration directories
+      @new_versions = {}      
+      @plugins_to_migrate.each do |plugin|
+        @new_versions[plugin.name] = plugin.latest_migration
+      end
+      
+      # Remove any plugins that don't need migration
+      @plugins_to_migrate.map { |p| p.name }.each do |name|
+        @plugins_to_migrate.delete(Engines.plugins[name]) if @current_versions[name] == @new_versions[name]
+      end
+      
+      @options[:assigns][:plugins] = @plugins_to_migrate
+      @options[:assigns][:new_versions] = @new_versions
+      @options[:assigns][:current_versions] = @current_versions
+    end
+
+    # Returns a migration name. If the descriptive migration name based on the 
+    # plugin names involved is shorter than 230 characters that one will be
+    # used. Otherwise a shorter name will be returned.
+    def build_migration_name
+      descriptive_migration_name.tap do |name|        
+        name.replace short_migration_name if name.length > MAX_FILENAME_LENGTH
+      end
+    end
+
+    # Construct a unique migration name based on the plugins involved and the
+    # versions they should reach after this migration is run. The name constructed
+    # needs to be lowercase
+    def descriptive_migration_name
+      @plugins_to_migrate.map do |plugin| 
+        "#{plugin.name}_to_version_#{@new_versions[plugin.name]}" 
+      end.join("_and_").downcase
+    end
+
+    # Short migration name that will be used if the descriptive_migration_name
+    # exceeds 230 characters
+    def short_migration_name
+      'plugin_migrations'
+    end
+end
\ No newline at end of file