Allow plugins to specify a minimum `requires version`

This commit is contained in:
Robin Ward 2015-04-27 13:06:53 -04:00
parent 6af71bd601
commit de42c627c5
6 changed files with 85 additions and 11 deletions

View File

@ -1,6 +1,7 @@
require 'cache'
require_dependency 'plugin/instance'
require_dependency 'auth/default_current_user_provider'
require_dependency 'version'
module Discourse
@ -78,8 +79,18 @@ module Discourse
end
def self.activate_plugins!
@plugins = Plugin::Instance.find_all("#{Rails.root}/plugins")
@plugins.each { |plugin| plugin.activate! }
all_plugins = Plugin::Instance.find_all("#{Rails.root}/plugins")
@plugins = []
all_plugins.each do |p|
v = p.metadata.required_version || Discourse::VERSION::STRING
if Discourse.has_needed_version?(Discourse::VERSION::STRING, v)
p.activate!
@plugins << p
else
STDERR.puts "Could not activate #{p.metadata.name}, discourse does not meet required version (#{v})"
end
end
end
def self.disabled_plugin_names

View File

@ -31,13 +31,6 @@ class Plugin::Instance
def initialize(metadata=nil, path=nil)
@metadata = metadata
@path = path
if @path
# Automatically include all ES6 JS and hbs files
root_path = "#{File.dirname(@path)}/assets/javascripts"
DiscoursePluginRegistry.register_glob(root_path, 'js.es6')
DiscoursePluginRegistry.register_glob(root_path, 'hbs')
end
end
def add_admin_route(label, location)
@ -216,6 +209,14 @@ class Plugin::Instance
# this allows us to present information about a plugin in the UI
# prior to activations
def activate!
if @path
# Automatically include all ES6 JS and hbs files
root_path = "#{File.dirname(@path)}/assets/javascripts"
DiscoursePluginRegistry.register_glob(root_path, 'js.es6')
DiscoursePluginRegistry.register_glob(root_path, 'hbs')
end
self.instance_eval File.read(path), path
if auto_assets = generate_automatic_assets!
assets.concat auto_assets.map{|a| [a]}

View File

@ -2,7 +2,7 @@
module Plugin; end
class Plugin::Metadata
FIELDS ||= [:name, :about, :version, :authors, :url]
FIELDS ||= [:name, :about, :version, :authors, :url, :required_version]
attr_accessor *FIELDS
def self.parse(text)
@ -21,7 +21,7 @@ class Plugin::Metadata
attribute, *description = line[1..-1].split(":")
description = description.join(":")
attribute = attribute.strip.to_sym
attribute = attribute.strip.gsub(/ /, '_').to_sym
if FIELDS.include?(attribute)
self.send("#{attribute}=", description.strip)

View File

@ -10,4 +10,24 @@ module Discourse
STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
end
end
def self.has_needed_version?(current, needed)
current_split = current.split('.')
needed_split = needed.split('.')
(0..[current_split.size, needed_split.size].max).each do |idx|
current_str = current_split[idx] || ''
c0 = (needed_split[idx] || '').sub('beta', '').to_i
c1 = (current_str || '').sub('beta', '').to_i
# beta is less than stable
return false if current_str.include?('beta') && (c0 == 0) && (c1 > 0)
return true if c1 > c0
return false if c0 > c1
end
true
end
end

View File

@ -10,6 +10,7 @@ describe Plugin::Metadata do
# version: 0.1
# authors: Frank Zappa
# url: http://discourse.org
# required version: 1.3.0beta6+48
some_ruby
TEXT
@ -19,6 +20,7 @@ TEXT
expect(metadata.version).to eq("0.1")
expect(metadata.authors).to eq("Frank Zappa")
expect(metadata.url).to eq("http://discourse.org")
expect(metadata.required_version).to eq("1.3.0beta6+48")
end
end

View File

@ -0,0 +1,40 @@
require 'spec_helper'
require 'version'
describe Discourse::VERSION do
context "has_needed_version?" do
it "works for major comparisons" do
expect(Discourse.has_needed_version?('1.0.0', '1.0.0')).to eq(true)
expect(Discourse.has_needed_version?('2.0.0', '1.0.0')).to eq(true)
expect(Discourse.has_needed_version?('0.0.1', '1.0.0')).to eq(false)
end
it "works for minor comparisons" do
expect(Discourse.has_needed_version?('1.1.0', '1.1.0')).to eq(true)
expect(Discourse.has_needed_version?('1.2.0', '1.1.0')).to eq(true)
expect(Discourse.has_needed_version?('2.0.0', '1.1.0')).to eq(true)
expect(Discourse.has_needed_version?('0.1.0', '0.1.0')).to eq(true)
expect(Discourse.has_needed_version?('1.0.0', '1.1.0')).to eq(false)
expect(Discourse.has_needed_version?('0.0.1', '0.1.0')).to eq(false)
end
it "works for tiny comparisons" do
expect(Discourse.has_needed_version?('2.0.0', '2.0.0')).to eq(true)
expect(Discourse.has_needed_version?('2.0.1', '2.0.0')).to eq(true)
expect(Discourse.has_needed_version?('1.12.0', '2.0.0')).to eq(false)
expect(Discourse.has_needed_version?('1.12.0', '2.12.5')).to eq(false)
end
it "works for beta comparisons" do
expect(Discourse.has_needed_version?('1.3.0.beta3', '1.2.9')).to eq(true)
expect(Discourse.has_needed_version?('1.3.0.beta3', '1.3.0.beta1')).to eq(true)
expect(Discourse.has_needed_version?('1.3.0.beta3', '1.3.0.beta4')).to eq(false)
expect(Discourse.has_needed_version?('1.3.0.beta3', '1.3.0')).to eq(false)
end
end
end