view .svn/pristine/5d/5dc200a9880b49ee8adf93752f95bd14fc23a33e.svn-base @ 1082:997f6d7738f7 bug_531

In repo controller entry action, show the page for the file even if it's binary (so user still has access to history etc links). This makes it possible to use the entry action as the default when a file is clicked on
author Chris Cannam <chris.cannam@soundsoftware.ac.uk>
date Thu, 22 Nov 2012 18:04:17 +0000
parents cbb26bc654de
children
line wrap: on
line source
# 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