Skip to content
This repository has been archived by the owner on Apr 14, 2021. It is now read-only.

Commit

Permalink
Merge branch 'flexicle'
Browse files Browse the repository at this point in the history
  • Loading branch information
Carlhuda committed Apr 22, 2010
2 parents 6adcba4 + 9cf95d1 commit 2c996b1
Show file tree
Hide file tree
Showing 32 changed files with 692 additions and 297 deletions.
75 changes: 75 additions & 0 deletions EXAMPLE_LOCKFILE
@@ -0,0 +1,75 @@
sources:
gem: http://rubygems.org/
path: /Users/carlhuda/Developer/Source/bundler

dependencies:
rails:
groups: default
git: git://github.com/rails/rails.git ref:"d03196c"

specs:
abstract (1.0.0)
actionmailer (3.0.0.beta3):
actionpack (= 3.0.0.beta3)
mail (~> 2.2.0)
text-format (~> 1.0.0)
actionpack (3.0.0.beta3):
activemodel (= 3.0.0.beta3)
activesupport (= 3.0.0.beta3)
erubis (~> 2.6.5)
rack (~> 1.1.0)
rack-mount (~> 0.6.3)
rack-test (~> 0.5.0)
activemodel (3.0.0.beta3):
activesupport (= 3.0.0.beta3)
activerecord (3.0.0.beta3):
activemodel (= 3.0.0.beta3)
activesupport (= 3.0.0.beta3)
arel (~> 0.3.3)
activeresource (3.0.0.beta3):
activemodel (= 3.0.0.beta3)
activesupport (= 3.0.0.beta3)
activesupport (3.0.0.beta3):
builder (~> 2.1.2)
i18n (~> 0.3.6)
memcache-client (>= 1.7.5)
tzinfo (~> 0.3.16)
arel (0.3.3):
activesupport (>= 3.0.0.beta)
builder (2.1.2)
bundler (0.9.21):
erubis (2.6.5):
abstract (>= 1.0.0)
i18n (0.3.7)
mail (2.2.0):
activesupport (>= 2.3.4)
mime-types
treetop (>= 1.4.5)
memcache-client (1.8.2)
mime-types (1.16):
polyglot (0.3.1):
rack (1.1.0):
rack-mount (0.6.3)
rack-test (0.5.3):
rack (>= 1.0)
rails (3.0.0.beta3):
actionmailer (= 3.0.0.beta3)
actionpack (= 3.0.0.beta3)
activerecord (= 3.0.0.beta3)
activeresource (= 3.0.0.beta3)
activesupport (= 3.0.0.beta3)
bundler (>= 0.9.19)
railties (= 3.0.0.beta3)
railties (3.0.0.beta3):
actionpack (= 3.0.0.beta3)
activesupport (= 3.0.0.beta3)
rake (>= 0.8.3)
thor (~> 0.13.4)
rake (0.8.7)
text-format (1.0.0):
text-hyphen (~> 1.0.0)
text-hyphen (1.0.0)
thor (0.13.4)
treetop (1.4.5):
polyglot (>= 0.3.1)
tzinfo (0.3.20)
15 changes: 3 additions & 12 deletions lib/bundler.rb
Expand Up @@ -13,6 +13,8 @@ module Bundler
autoload :Environment, 'bundler/environment'
autoload :Index, 'bundler/index'
autoload :Installer, 'bundler/installer'
autoload :LazySpecification, 'bundler/lazy_specification'
autoload :LockfileParser, 'bundler/lockfile_parser'
autoload :RemoteSpecification, 'bundler/remote_specification'
autoload :Resolver, 'bundler/resolver'
autoload :Runtime, 'bundler/runtime'
Expand Down Expand Up @@ -114,18 +116,7 @@ def runtime
def definition
configure
lockfile = root.join("Gemfile.lock")
if lockfile.exist?
Definition.from_lock(lockfile)
else
Definition.from_gemfile(default_gemfile)
end
end

# TODO: obvious
def flexdef
configure
lockfile = root.join("Gemfile.lock")
Definition.flexdef(default_gemfile, lockfile)
Definition.build(default_gemfile, lockfile)
end

def home
Expand Down
36 changes: 1 addition & 35 deletions lib/bundler/cli.rb
Expand Up @@ -69,7 +69,6 @@ def check

desc "install", "Install the current environment to the system"
method_option "without", :type => :array, :banner => "Exclude gems that are part of the specified named group."
method_option "relock", :type => :boolean, :banner => "Unlock, install the gems, and relock."
method_option "disable-shared-gems", :type => :boolean, :banner => "Do not use any shared gems, such as the system gem repository."
method_option "gemfile", :type => :string, :banner => "Use the specified gemfile instead of Gemfile"
def install(path = nil)
Expand All @@ -83,40 +82,7 @@ def install(path = nil)
Bundler.settings[:disable_shared_gems] = '1' if options["disable-shared-gems"] || path
Bundler.settings.without = opts[:without]

remove_lockfiles if options[:relock]

begin
Installer.install(Bundler.root, Bundler.definition, opts)
rescue GemfileChanged
raise GemfileChanged, "You changed your Gemfile after locking. Please run `bundle install --relock`."
end

lock if options[:relock] || options[:flex]
cache if Bundler.root.join("vendor/cache").exist?
rescue GemNotFound => e
if Bundler.definition.sources.empty?
Bundler.ui.warn "Your Gemfile doesn't have any sources. You can add one with a line like 'source :gemcutter'"
end
raise e
end

desc "flex_install", "Temporary command for the 0.10 install as it is being built"
method_option "without", :type => :array, :banner => "Exclude gems that are part of the specified named group."
method_option "relock", :type => :boolean, :banner => "Unlock, install the gems, and relock."
method_option "disable-shared-gems", :type => :boolean, :banner => "Do not use any shared gems, such as the system gem repository."
method_option "gemfile", :type => :string, :banner => "Use the specified gemfile instead of Gemfile"
def flex_install(path = nil)
opts = options.dup
opts[:without] ||= []
opts[:without].map! { |g| g.to_sym }

# Can't use Bundler.settings for this because settings needs gemfile.dirname
ENV['BUNDLE_GEMFILE'] = opts[:gemfile] if opts[:gemfile]
Bundler.settings[:path] = path if path
Bundler.settings[:disable_shared_gems] = '1' if options["disable-shared-gems"] || path
Bundler.settings.without = opts[:without]

Installer.install(Bundler.root, Bundler.flexdef, opts).lock
Installer.install(Bundler.root, Bundler.definition, opts)
cache if Bundler.root.join("vendor/cache").exist?
rescue GemNotFound => e
if Bundler.definition.sources.empty?
Expand Down
140 changes: 43 additions & 97 deletions lib/bundler/definition.rb
Expand Up @@ -3,123 +3,69 @@
# TODO: In the 0.10 release, there shouldn't be a locked subclass of Definition
module Bundler
class Definition
def self.from_gemfile(gemfile)
attr_reader :dependencies, :sources, :locked_specs

def self.build(gemfile, lockfile)
gemfile = Pathname.new(gemfile).expand_path

unless gemfile.file?
raise GemfileNotFound, "#{gemfile} not found"
end

Dsl.evaluate(gemfile)
# TODO: move this back into DSL
builder = Dsl.new
builder.instance_eval(File.read(gemfile.to_s), gemfile.to_s, 1)
builder.to_definition(lockfile)
end

def self.from_lock(lockfile, check = true)
return nil unless lockfile.exist?

locked_definition = Locked.new(YAML.load_file(lockfile))

if check
hash = Digest::SHA1.hexdigest(File.read("#{Bundler.root}/Gemfile"))
unless locked_definition.hash == hash
raise GemfileChanged, "You changed your Gemfile after locking. Please relock using `bundle lock`"
end
def initialize(lockfile, dependencies, sources)
@dependencies, @sources = dependencies, sources

if lockfile && File.exists?(lockfile)
locked = LockfileParser.new(File.read(lockfile))
@locked_deps = locked.dependencies
@locked_specs = SpecSet.new(locked.specs)
@sources = locked.sources
else
@locked_deps = []
@locked_specs = SpecSet.new([])
end

locked_definition
end

def self.flexdef(gemfile, lockfile)
Flex.new(from_gemfile(gemfile), from_lock(lockfile, false))
end

attr_reader :dependencies, :sources

alias resolved_dependencies dependencies

def initialize(dependencies, sources)
@dependencies = dependencies
@sources = sources
# TODO: OMG LOL
def resolved_dependencies
deps = locked_specs_as_deps
dependencies.each do |dep|
deps << dep unless deps.any? { |d| d.name == dep.name }
end
deps
end

def groups
dependencies.map { |d| d.groups }.flatten.uniq
end

class Flex
def initialize(gemfile, lockfile)
@gemfile = gemfile
@lockfile = lockfile
end

def dependencies
@gemfile.dependencies
end

def sources
@gemfile.sources
end

def groups
dependencies.map { |d| d.groups }.flatten.uniq
end

def resolved_dependencies
@resolved_dependencies ||= begin
if @lockfile
# Build a list of gems that have been removed from the gemfile
# but are still listed in the lockfile
removed_deps = @lockfile.dependencies.select do |d|
dependencies.all? { |d2| d2.name != d.name }
end

# Take the lockfile, remove the gems that are in the previously
# built list of removed gems, and keep what's left over
new_deps = @lockfile.resolved_dependencies.reject do |d|
removed_deps.any? { |d2| d.name == d2.name }
end

# Add gems that have been added to the gemfile
dependencies.each do |d|
next if new_deps.any? {|new_dep| new_dep.name == d.name }
new_deps << d
end

new_deps
else
dependencies
end
end
end
end

class Locked < Definition
def initialize(details)
@details = details
end

def hash
@details["hash"]
end

def sources
@sources ||= @details["sources"].map do |args|
name, options = args.to_a.flatten
Bundler::Source.const_get(name).new(options)
end
end

def resolved_dependencies
@resolved_dependencies ||= @details["specs"].map do |args|
name, details = args.to_a.flatten
details["source"] = sources[details["source"]] if details.include?("source")
Bundler::Dependency.new(name, details.delete("version"), details)
end
# We have the dependencies from Gemfile.lock and the dependencies from the
# Gemfile. Here, we are finding a list of all dependencies that were
# originally present in the Gemfile that still satisfy the requirements
# of the dependencies in the Gemfile.lock
#
# This allows us to add on the *new* requirements in the Gemfile and make
# sure that the changes result in a conservative update to the Gemfile.lock.
def locked_specs_as_deps
deps = @dependencies & @locked_deps

@dependencies.each do |dep|
next if deps.include?(dep)
deps << dep if @locked_specs.any? { |s| s.satisfies?(dep) }
end

def dependencies
@dependencies ||= @details["dependencies"].map do |opts|
Bundler::Dependency.new(opts.delete("name"), opts.delete("version"), opts)
meta_deps = @locked_specs.for(deps).map do |s|
dep = Gem::Dependency.new(s.name, s.version)
@locked_deps.each do |d|
dep.source = d.source if d.name == dep.name
end
dep
end
end
end
Expand Down
13 changes: 13 additions & 0 deletions lib/bundler/dependency.rb
Expand Up @@ -16,5 +16,18 @@ def initialize(name, version, options = {}, &blk)
@autorequire = Array(options['require'] || [])
end
end

def to_lock
out = " #{name}"
unless requirement == Gem::Requirement.default
out << " (#{requirement.to_s})"
end

if @source
out << ":\n #{@source.to_lock}\n"
else
out << "\n"
end
end
end
end
4 changes: 2 additions & 2 deletions lib/bundler/dsl.rb
Expand Up @@ -55,8 +55,8 @@ def git(uri, options = {}, source_options = {}, &blk)
source Source::Git.new(_normalize_hash(options).merge("uri" => uri)), source_options, &blk
end

def to_definition
Definition.new(@dependencies, @sources)
def to_definition(lockfile)
Definition.new(lockfile, @dependencies, @sources)
end

def group(*args, &blk)
Expand Down

0 comments on commit 2c996b1

Please sign in to comment.