From 39b44b1cb94f68514bf9ce7ae76ee7228bf6ce07 Mon Sep 17 00:00:00 2001 From: Eric Davis Date: Wed, 16 Dec 2009 02:07:46 +0000 Subject: [PATCH] Adds a Plugin API to allow one plugin to depend on another. git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@3175 e93f8b46-1217-0410-a6f0-8f06a7374b81 --- lib/redmine/plugin.rb | 36 +++++++++++++++++++++++++ test/unit/lib/redmine/plugin_test.rb | 39 ++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+) diff --git a/lib/redmine/plugin.rb b/lib/redmine/plugin.rb index c04ba334c..2be8ac8aa 100644 --- a/lib/redmine/plugin.rb +++ b/lib/redmine/plugin.rb @@ -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' diff --git a/test/unit/lib/redmine/plugin_test.rb b/test/unit/lib/redmine/plugin_test.rb index 234da14ea..57e2b985e 100644 --- a/test/unit/lib/redmine/plugin_test.rb +++ b/test/unit/lib/redmine/plugin_test.rb @@ -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 -- 2.39.5