Index: lib/tasks/redmine.rake =================================================================== --- lib/tasks/redmine.rake (révision 2280) +++ lib/tasks/redmine.rake (copie de travail) @@ -79,6 +79,31 @@ Rake::Task["db:schema:dump"].invoke end + desc 'Rollbacks installed plugins by 1 or many steps.' + task :rollback => :environment do + name = ENV['NAME'] + steps = nil + steps_string = ENV['STEP'] + + if name.nil? + abort "The VERSION argument requires a plugin NAME." + end + + begin + steps = Integer(steps_string) + rescue + abort "Invalid STEP #{steps_string} given." + end + + begin + Redmine::Plugin.rollback(name, steps) + rescue Redmine::PluginNotFound + abort "Plugin #{name} was not found." + end + + Rake::Task["db:schema:dump"].invoke + end + desc 'Copies plugins assets into the public directory.' task :assets => :environment do name = ENV['NAME'] Index: lib/redmine/plugin.rb =================================================================== --- lib/redmine/plugin.rb (révision 2280) +++ lib/redmine/plugin.rb (copie de travail) @@ -425,6 +425,12 @@ Redmine::Plugin::Migrator.migrate_plugin(self, version) end + # Rollback this plugin to the previous version + def rollback(steps=1) + puts "Rollback #{steps} migration#{ '(s)' if steps > 1 } before (#{name})..." + Redmine::Plugin::Migrator.rollback_plugin(self, steps) + end + # Migrates all plugins or a single plugin to a given version # Exemples: # Plugin.migrate @@ -441,6 +447,17 @@ end end + # Rollbacks a single plugin by one or more step + # Exemples: + # Plugin.rollback('sample_plugin') + # Plugin.rollback('sample_plugin', 2) + # + def self.rollback(name=nil, steps=nil) + if name.present? + find(name).rollback(steps) + end + end + class Migrator < ActiveRecord::Migrator # We need to be able to set the 'current' plugin being migrated. cattr_accessor :current_plugin @@ -452,7 +469,12 @@ return if current_version(plugin) == version migrate(plugin.migration_directory, version) end - + + def rollback_plugin(plugin, steps=1) + self.current_plugin = plugin + rollback(plugin.migration_directory, steps) + end + def current_version(plugin=current_plugin) # Delete migrations that don't match .. to_i will work because the number comes first ::ActiveRecord::Base.connection.select_values(