Permalink
Browse files

Implement GEM dependency check

  • Loading branch information...
1 parent 8e45630 commit a5a7c47e910f62abd49ab40691441f47a376031c @bovi bovi committed May 8, 2013
Showing with 95 additions and 1 deletion.
  1. +94 −1 tasks/mrbgem_spec.rake
  2. +1 −0 tasks/mrbgems.rake
View
@@ -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
View
@@ -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")

0 comments on commit a5a7c47

Please sign in to comment.