From a5a7c47e910f62abd49ab40691441f47a376031c Mon Sep 17 00:00:00 2001 From: Daniel Bovensiepen Date: Thu, 9 May 2013 01:47:24 +0800 Subject: Implement GEM dependency check --- tasks/mrbgem_spec.rake | 95 +++++++++++++++++++++++++++++++++++++++++++++++++- tasks/mrbgems.rake | 1 + 2 files changed, 95 insertions(+), 1 deletion(-) (limited to 'tasks') diff --git a/tasks/mrbgem_spec.rake b/tasks/mrbgem_spec.rake index d2dbc860c..0817531af 100644 --- a/tasks/mrbgem_spec.rake +++ b/tasks/mrbgem_spec.rake @@ -89,7 +89,7 @@ module MRuby def add_dependency(name, *requirements) requirements = ['> 0.0.0'] if requirements.empty? requirements.flatten! - @dependencies << [:gem => name, :requirements => requirements] + @dependencies << {:gem => name, :requirements => requirements} end def self.bin=(bin) @@ -168,8 +168,83 @@ module MRuby f.puts %Q[#include "mruby/hash.h"] end + def version_ok?(req_versions) + req_versions.map do |req| + cmp, ver = req.split + cmp_result = Version.new(version) <=> Version.new(ver) + case cmp + when '=' then cmp_result == 0 + when '!=' then cmp_result != 0 + when '>' then cmp_result == 1 + when '<' then cmp_result == -1 + when '>=' then cmp_result >= 0 + when '<=' then cmp_result <= 0 + when '~>' + # todo: implement twiddle-waka + Version.new(version).twiddle_wakka_ok?(Version.new(ver)) + else + fail "Comparison not possible with '#{cmp}'" + end + end.all? + end end # Specification + class Version + include Comparable + include Enumerable + + def <=>(other) + ret = 0 + own = to_enum + + other.each do |oth| + begin + ret = own.next <=> oth + rescue StopIteration + ret = 0 <=> oth + end + + break unless ret == 0 + end + + ret + end + + # ~> compare alghorithm + # + # Example: + # ~> 2.2 means >= 2.2.0 and < 3.0.0 + # ~> 2.2.0 means >= 2.2.0 and < 2.3.0 + def twiddle_wakka_ok?(other) + gr_or_eql = (self <=> other) >= 0 + still_minor = (self <=> other.skip_minor) < 0 + gr_or_eql and still_minor + end + + def skip_minor + a = @ary.dup + a.slice!(-1) + a[-1] = a[-1].succ + a + end + + def initialize(str) + @str = str + @ary = @str.split('.').map(&:to_i) + end + + def each(&block); @ary.each(&block); end + def [](index); @ary[index]; end + def []=(index, value) + @ary[index] = value + @str = @ary.join('.') + end + def slice!(index) + @ary.slice!(index) + @str = @ary.join('.') + end + end # Version + class List include Enumerable @@ -192,6 +267,24 @@ module MRuby def empty? @ary.empty? end + + def check + each do |g| + g.dependencies.each do |dep| + name = dep[:gem] + req_versions = dep[:requirements] + + # check each GEM dependency against all available GEMs + each do |dep_g| + if name == dep_g.name + unless dep_g.version_ok?(req_versions) + fail "#{name} version should be #{req_versions.join(' and ')} but was '#{dep_g.version}'" + end + end + end + end + end + end end # List end # Gem diff --git a/tasks/mrbgems.rake b/tasks/mrbgems.rake index c18a9a181..43435cf0b 100644 --- a/tasks/mrbgems.rake +++ b/tasks/mrbgems.rake @@ -5,6 +5,7 @@ MRuby.each_target do if enable_gems? # set up all gems gems.each(&:setup) + gems.check # loader all gems self.libmruby << objfile("#{build_dir}/mrbgems/gem_init") -- cgit v1.2.3 From 34f7dd539d6464af65c9e1dcc8b3d2fd214db8f8 Mon Sep 17 00:00:00 2001 From: Daniel Bovensiepen Date: Thu, 9 May 2013 01:49:53 +0800 Subject: Todo is actually already finished :-) --- tasks/mrbgem_spec.rake | 1 - 1 file changed, 1 deletion(-) (limited to 'tasks') diff --git a/tasks/mrbgem_spec.rake b/tasks/mrbgem_spec.rake index 0817531af..528542a03 100644 --- a/tasks/mrbgem_spec.rake +++ b/tasks/mrbgem_spec.rake @@ -180,7 +180,6 @@ module MRuby when '>=' then cmp_result >= 0 when '<=' then cmp_result <= 0 when '~>' - # todo: implement twiddle-waka Version.new(version).twiddle_wakka_ok?(Version.new(ver)) else fail "Comparison not possible with '#{cmp}'" -- cgit v1.2.3