Commit 14bd8cef authored by Yukihiro "Matz" Matsumoto's avatar Yukihiro "Matz" Matsumoto

Merge pull request #1241 from bovi/add-gem-dependency-check

[mrbgems] GEM Dependency Check
parents ea10d2d3 34f7dd53
...@@ -89,7 +89,7 @@ module MRuby ...@@ -89,7 +89,7 @@ module MRuby
def add_dependency(name, *requirements) def add_dependency(name, *requirements)
requirements = ['> 0.0.0'] if requirements.empty? requirements = ['> 0.0.0'] if requirements.empty?
requirements.flatten! requirements.flatten!
@dependencies << [:gem => name, :requirements => requirements] @dependencies << {:gem => name, :requirements => requirements}
end end
def self.bin=(bin) def self.bin=(bin)
...@@ -168,8 +168,82 @@ module MRuby ...@@ -168,8 +168,82 @@ module MRuby
f.puts %Q[#include "mruby/hash.h"] f.puts %Q[#include "mruby/hash.h"]
end 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 '~>'
Version.new(version).twiddle_wakka_ok?(Version.new(ver))
else
fail "Comparison not possible with '#{cmp}'"
end
end.all?
end
end # Specification 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 class List
include Enumerable include Enumerable
...@@ -192,6 +266,24 @@ module MRuby ...@@ -192,6 +266,24 @@ module MRuby
def empty? def empty?
@ary.empty? @ary.empty?
end 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 # List
end # Gem end # Gem
......
...@@ -5,6 +5,7 @@ MRuby.each_target do ...@@ -5,6 +5,7 @@ MRuby.each_target do
if enable_gems? if enable_gems?
# set up all gems # set up all gems
gems.each(&:setup) gems.each(&:setup)
gems.check
# loader all gems # loader all gems
self.libmruby << objfile("#{build_dir}/mrbgems/gem_init") self.libmruby << objfile("#{build_dir}/mrbgems/gem_init")
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment