Permalink
Browse files

Combine GemResolver and Bundler into one library.

  • Loading branch information...
1 parent b21ade0 commit 09e58fa97b501547ad9f736aad45fd7c46cb1e49 Yehuda Katz + Carl Lerche committed Jul 8, 2009
Showing 505 changed files with 784 additions and 96 deletions.
View
@@ -0,0 +1 @@
+tmp
View
@@ -1,3 +0,0 @@
-[submodule "gem_resolver"]
- path = gem_resolver
- url = git@github.com:halorgium/gem_resolver.git
View
@@ -11,15 +11,15 @@ spec = Gem::Specification.new do |s|
s.email = "Your Email"
s.homepage = "http://example.com"
s.description = s.summary = "A gem that provides..."
-
+
s.platform = Gem::Platform::RUBY
s.has_rdoc = true
s.extra_rdoc_files = ["README", "LICENSE", 'TODO']
s.summary = ""
-
+
# Uncomment this to add a dependency
# s.add_dependency "foo"
-
+
s.require_path = 'lib'
s.files = %w(LICENSE README Rakefile TODO) + Dir.glob("{lib,spec}/**/*")
end
Submodule gem_resolver deleted from 7ea2dd
View
@@ -1,8 +1,15 @@
+require 'logger'
+require 'set'
+# Required elements of rubygems
require "rubygems/remote_fetcher"
require "rubygems/installer"
+
require "bundler/gem_bundle"
-require "bundler/finder"
require "bundler/environment"
+require "bundler/finder"
require "bundler/gem_specification"
+require "bundler/resolver"
-require File.expand_path(File.join(File.dirname(__FILE__), "..", "gem_resolver", "lib", "gem_resolver"))
+module Bundler
+ VERSION = "0.0.1"
+end
View
@@ -8,7 +8,7 @@ def initialize(*sources)
end
def resolve(*dependencies)
- resolved = GemResolver.resolve(dependencies, self)
+ resolved = Resolver.resolve(dependencies, self)
resolved && GemBundle.new(resolved.all_specs)
end
@@ -1,7 +1,7 @@
module Gem
class Specification
attribute :source
-
+
def source=(source)
@source = source.is_a?(URI) ? source : URI.parse(source)
raise ArgumentError, "The source must be an absolute URI" unless @source.absolute?
View
@@ -0,0 +1,19 @@
+require 'bundler/resolver/search'
+require 'bundler/resolver/engine'
+require 'bundler/resolver/inspects'
+require 'bundler/resolver/stack'
+require 'bundler/resolver/state'
+
+module Bundler
+ module Resolver
+ def self.resolve(deps, source_index = Gem.source_index, logger = nil)
+ unless logger
+ logger = Logger.new($stderr)
+ logger.datetime_format = ""
+ logger.level = ENV["GEM_RESOLVER_DEBUG"] ? Logger::DEBUG : Logger::ERROR
+ end
+
+ Engine.resolve(deps, source_index, logger)
+ end
+ end
+end
@@ -0,0 +1,61 @@
+module Bundler
+ module Resolver
+ module Builders
+ def build_index(&block)
+ index = Gem::SourceIndex.new
+ IndexBuilder.run(index, &block) if block_given?
+ index
+ end
+
+ def build_spec(name, version, &block)
+ spec = Gem::Specification.new
+ spec.instance_variable_set(:@name, name)
+ spec.instance_variable_set(:@version, Gem::Version.new(version))
+ DepBuilder.run(spec, &block) if block_given?
+ spec
+ end
+
+ def build_dep(name, requirements, type = :runtime)
+ Gem::Dependency.new(name, requirements, type)
+ end
+
+ class IndexBuilder
+ include Builders
+
+ def self.run(index, &block)
+ new(index).run(&block)
+ end
+
+ def initialize(index)
+ @index = index
+ end
+
+ def run(&block)
+ instance_eval(&block)
+ end
+
+ def add_spec(*args, &block)
+ @index.add_spec(build_spec(*args, &block))
+ end
+ end
+
+ class DepBuilder
+ def self.run(spec, &block)
+ new(spec).run(&block)
+ end
+
+ def initialize(spec)
+ @spec = spec
+ end
+
+ def run(&block)
+ instance_eval(&block)
+ end
+
+ def runtime(name, requirements)
+ @spec.add_runtime_dependency(name, requirements)
+ end
+ end
+ end
+ end
+end
@@ -0,0 +1,38 @@
+module Bundler
+ module Resolver
+ class ClosedSet < Set
+ end
+
+ class Engine
+ include Search
+
+ def self.resolve(deps, source_index, logger)
+ new(deps, source_index, logger).resolve
+ end
+
+ def initialize(deps, source_index, logger)
+ @deps, @source_index, @logger = deps, source_index, logger
+ logger.debug "searching for #{@deps.gem_resolver_inspect}"
+ end
+ attr_reader :deps, :source_index, :logger, :solution
+
+ def resolve
+ state = State.initial(self, [], Stack.new, Stack.new([[[], @deps.dup]]))
+ if solution = search(state)
+ logger.info "got the solution with #{solution.all_specs.size} specs"
+ solution.dump(Logger::INFO)
+ solution
+ end
+ end
+
+ def open
+ @open ||= []
+ end
+
+ def closed
+ @closed ||= ClosedSet.new
+ end
+ end
+ end
+
+end
@@ -0,0 +1,43 @@
+class Object
+ def gem_resolver_inspect
+ inspect
+ end
+end
+
+class Gem::Specification
+ def gem_resolver_inspect
+ "#<Spec: #{full_name}>"
+ end
+end
+
+class Gem::Dependency
+ def gem_resolver_inspect
+ "#<Dep: #{to_s}>"
+ end
+end
+
+class Array
+ def gem_resolver_inspect
+ '[' + map {|x| x.gem_resolver_inspect}.join(", ") + ']'
+ end
+end
+
+require 'set'
+class Set
+ def gem_resolver_inspect
+ to_a.gem_resolver_inspect
+ end
+end
+
+class Hash
+ def gem_resolver_inspect
+ '{' + map {|k,v| "#{k.gem_resolver_inspect} => #{v.gem_resolver_inspect}"}.join(", ") + '}'
+ end
+end
+
+class String
+ def gem_resolver_inspect
+ inspect
+ end
+end
+
@@ -0,0 +1,71 @@
+module Bundler
+ module Resolver
+ module Search
+ def search(initial, max_depth = (1.0 / 0.0))
+ if initial.goal_met?
+ return initial
+ end
+
+ open << initial
+
+ while open.any?
+ current = open.pop
+ closed << current
+
+ new = []
+ current.each_possibility do |attempt|
+ unless closed.include?(attempt)
+ if attempt.goal_met?
+ return attempt
+ elsif attempt.depth < max_depth
+ new << attempt
+ end
+ end
+ end
+ new.reverse.each do |state|
+ open << state
+ end
+ end
+
+ nil
+ end
+
+ def open
+ raise "implement #open in #{self.class}"
+ end
+
+ def closed
+ raise "implement #closed in #{self.class}"
+ end
+
+ module Node
+ def self.included(base)
+ base.extend(ClassMethods)
+ end
+
+ module ClassMethods
+ def initial(*data)
+ new(0, *data)
+ end
+ end
+
+ def initialize(depth)
+ @depth = depth
+ end
+ attr_reader :depth
+
+ def child(*data)
+ self.class.new(@depth + 1, *data)
+ end
+
+ def each_possibility
+ raise "implement #each_possibility on #{self.class}"
+ end
+
+ def goal_met?
+ raise "implement #goal_met? on #{self.class}"
+ end
+ end
+ end
+ end
+end
@@ -0,0 +1,72 @@
+module Bundler
+ module Resolver
+ class Stack
+ def initialize(initial = [])
+ @data = []
+ initial.each do |(path,value)|
+ self[path] = value
+ end
+ end
+
+ def last
+ @data.last
+ end
+
+ def []=(path, value)
+ raise ArgumentError, "#{path.inspect} already has a value" if key?(path)
+ @data << [path.dup, value]
+ end
+
+ def [](path)
+ if key?(path)
+ _, value = @data.find do |(k,v)|
+ k == path
+ end
+ value
+ else
+ raise "No value for #{path.inspect}"
+ end
+ end
+
+ def key?(path)
+ @data.any? do |(k,v)|
+ k == path
+ end
+ end
+
+ def each
+ @data.each do |(k,v)|
+ yield k, v
+ end
+ end
+
+ def map
+ @data.map do |(k,v)|
+ yield k, v
+ end
+ end
+
+ def each_value
+ @data.each do |(k,v)|
+ yield v
+ end
+ end
+
+ def dup
+ self.class.new(@data.dup)
+ end
+
+ def to_s
+ @data.to_s
+ end
+
+ def inspect
+ @data.inspect
+ end
+
+ def gem_resolver_inspect
+ @data.gem_resolver_inspect
+ end
+ end
+ end
+end
Oops, something went wrong.

0 comments on commit 09e58fa

Please sign in to comment.