]> source.dussan.org Git - redmine.git/commitdiff
Adds a Plugin API to allow one plugin to depend on another.
authorEric Davis <edavis@littlestreamsoftware.com>
Wed, 16 Dec 2009 02:07:46 +0000 (02:07 +0000)
committerEric Davis <edavis@littlestreamsoftware.com>
Wed, 16 Dec 2009 02:07:46 +0000 (02:07 +0000)
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@3175 e93f8b46-1217-0410-a6f0-8f06a7374b81

lib/redmine/plugin.rb
test/unit/lib/redmine/plugin_test.rb

index c04ba334c1f04b93f36de0a9905bd412d24f801b..2be8ac8aa3942973fa0c5b51a9115ae2c76791af 100644 (file)
@@ -132,6 +132,42 @@ module Redmine #:nodoc:
       true
     end
 
+    # Sets a requirement on a Redmine plugin version
+    # Raises a PluginRequirementError exception if the requirement is not met
+    #
+    # Examples
+    #   # Requires a plugin named :foo version 0.7.3 or higher
+    #   requires_redmine_plugin :foo, :version_or_higher => '0.7.3'
+    #   requires_redmine_plugin :foo, '0.7.3'
+    #
+    #   # Requires a specific version of a Redmine plugin
+    #   requires_redmine_plugin :foo, :version => '0.7.3'              # 0.7.3 only
+    #   requires_redmine_plugin :foo, :version => ['0.7.3', '0.8.0']   # 0.7.3 or 0.8.0
+    def requires_redmine_plugin(plugin_name, arg)
+      arg = { :version_or_higher => arg } unless arg.is_a?(Hash)
+      arg.assert_valid_keys(:version, :version_or_higher)
+
+      plugin = Plugin.find(plugin_name)
+      current = plugin.version.split('.').collect(&:to_i)
+
+      arg.each do |k, v|
+        v = [] << v unless v.is_a?(Array)
+        versions = v.collect {|s| s.split('.').collect(&:to_i)}
+        case k
+        when :version_or_higher
+          raise ArgumentError.new("wrong number of versions (#{versions.size} for 1)") unless versions.size == 1
+          unless (current <=> versions.first) >= 0
+            raise PluginRequirementError.new("#{id} plugin requires the #{plugin_name} plugin #{v} or higher but current is #{current.join('.')}")
+          end
+        when :version
+          unless versions.include?(current.slice(0,3))
+            raise PluginRequirementError.new("#{id} plugin requires one the following versions of #{plugin_name}: #{v.join(', ')} but current is #{current.join('.')}")
+          end
+        end
+      end
+      true
+    end
+
     # Adds an item to the given +menu+.
     # The +id+ parameter (equals to the project id) is automatically added to the url.
     #   menu :project_menu, :plugin_example, { :controller => 'example', :action => 'say_hello' }, :caption => 'Sample'
index 234da14ea6d0e0fa2dddae8f7b43a126390720b4..57e2b985e93e02344ba5220ad887d1e2d1adc50f 100644 (file)
@@ -75,4 +75,43 @@ class Redmine::PluginTest < ActiveSupport::TestCase
       end
     end
   end
+
+  def test_requires_redmine_plugin
+    test = self
+    other_version = '0.5.0'
+    
+    @klass.register :other do
+      name 'Other'
+      version other_version
+    end
+    
+    @klass.register :foo do
+      test.assert requires_redmine_plugin(:other, :version_or_higher => '0.1.0')
+      test.assert requires_redmine_plugin(:other, :version_or_higher => other_version)
+      test.assert requires_redmine_plugin(:other, other_version)
+      test.assert_raise Redmine::PluginRequirementError do
+        requires_redmine_plugin(:other, :version_or_higher => '99.0.0')
+      end
+      
+      test.assert requires_redmine_plugin(:other, :version => other_version)
+      test.assert requires_redmine_plugin(:other, :version => [other_version, '99.0.0'])
+      test.assert_raise Redmine::PluginRequirementError do
+        requires_redmine_plugin(:other, :version => '99.0.0')
+      end
+      test.assert_raise Redmine::PluginRequirementError do
+        requires_redmine_plugin(:other, :version => ['98.0.0', '99.0.0'])
+      end
+      # Missing plugin
+      test.assert_raise Redmine::PluginNotFound do
+        requires_redmine_plugin(:missing, :version_or_higher => '0.1.0')
+      end
+      test.assert_raise Redmine::PluginNotFound do
+        requires_redmine_plugin(:missing, '0.1.0')
+      end
+      test.assert_raise Redmine::PluginNotFound do
+        requires_redmine_plugin(:missing, :version => '0.1.0')
+      end
+      
+    end
+  end
 end