Skip to content
Browse files

Removing all the code

  • Loading branch information...
1 parent 2ba4a35 commit e42b04da3585e01d3f28937d59e17c71309dee15 Carl Lerche committed Feb 3, 2010
Showing with 0 additions and 5,486 deletions.
  1. +0 −20 LICENSE
  2. +0 −284 README.markdown
  3. +0 −81 Rakefile
  4. +0 −28 bundler.gemspec
  5. +0 −49 lib/bundler.rb
  6. +0 −314 lib/bundler/bundle.rb
  7. +0 −89 lib/bundler/cli.rb
  8. +0 −83 lib/bundler/commands/bundle_command.rb
  9. +0 −36 lib/bundler/commands/exec_command.rb
  10. +0 −62 lib/bundler/dependency.rb
  11. +0 −182 lib/bundler/dsl.rb
  12. +0 −87 lib/bundler/environment.rb
  13. +0 −51 lib/bundler/finder.rb
  14. +0 −11 lib/bundler/gem_bundle.rb
  15. +0 −34 lib/bundler/gem_ext.rb
  16. +0 −53 lib/bundler/remote_specification.rb
  17. +0 −250 lib/bundler/resolver.rb
  18. +0 −2 lib/bundler/runtime.rb
  19. +0 −365 lib/bundler/source.rb
  20. +0 −72 lib/bundler/templates/Gemfile
  21. +0 −3 lib/bundler/templates/app_script.erb
  22. +0 −156 lib/bundler/templates/environment.erb
  23. +0 −4 lib/bundler/templates/environment_picker.erb
  24. +0 −6 lib/rubygems_plugin.rb
  25. +0 −2 spec/.gitignore
  26. +0 −589 spec/bundler/cli_spec.rb
  27. +0 −255 spec/bundler/directory_spec.rb
  28. +0 −126 spec/bundler/dsl_spec.rb
  29. +0 −138 spec/bundler/fetcher_spec.rb
  30. +0 −266 spec/bundler/git_spec.rb
  31. +0 −155 spec/bundler/installer_spec.rb
  32. +0 −105 spec/bundler/manifest_file_spec.rb
  33. +0 −257 spec/bundler/manifest_spec.rb
  34. +0 −141 spec/bundler/runtime_spec.rb
  35. +0 −42 spec/bundler/system_gems_spec.rb
  36. +0 −57 spec/quality_spec.rb
  37. +0 −112 spec/resolver/engine_spec.rb
  38. +0 −50 spec/resolver/error_spec.rb
  39. +0 −43 spec/resolver/fake_source_index_spec.rb
  40. +0 −113 spec/resolver/prerelease_spec.rb
  41. +0 −46 spec/spec_helper.rb
  42. +0 −257 spec/support/builders.rb
  43. +0 −18 spec/support/core_ext.rb
  44. +0 −128 spec/support/helpers.rb
  45. +0 −201 spec/support/matchers.rb
  46. +0 −63 spec/support/path_utils.rb
View
20 LICENSE
@@ -1,20 +0,0 @@
-Copyright (c) 2009 Engine Yard
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
View
284 README.markdown
@@ -1,284 +0,0 @@
-## Bundler : A gem to bundle gems
-
- Github: http://github.com/wycats/bundler
- Mailing list: http://groups.google.com/group/ruby-bundler
- IRC: #carlhuda on freenode
-
-## Intro
-
-Bundler is a tool that manages gem dependencies for your ruby application. It
-takes a gem manifest file and is able to fetch, download, and install the gems
-and all child dependencies specified in this manifest. It can manage any update
-to the gem manifest file and update the bundled gems accordingly. It also lets
-you run any ruby code in context of the bundled gem environment.
-
-## Installation
-
-Bundler has no dependencies. Just clone the git repository and install the gem
-with the following rake task:
-
- rake install
-
-You can also install the gem with
-
- gem install bundler
-
-## Usage
-
-Bundler requires a gem manifest file to be created. This should be a file named
-`Gemfile` located in the root directory of your application. After the manifest
-has been created, in your shell, cd into your application's directory and run
-`gem bundle`. This will start the bundling process.
-
-### Manifest file
-
-This is where you specify all of your application's dependencies. By default
-this should be in a file named `Gemfile` located in your application's root
-directory. The following is an example of a potential `Gemfile`. For more
-information, please refer to Bundler::ManifestBuilder.
-
- # Specify a dependency on rails. When the bundler downloads gems,
- # it will download rails as well as all of rails' dependencies (such as
- # activerecord, actionpack, etc...)
- #
- # At least one dependency must be specified
- gem "rails"
-
- # Specify a dependency on rack v.1.0.0. The version is optional. If present,
- # it can be specified the same way as with rubygems' #gem method.
- gem "rack", "1.0.0"
-
- # Specify a dependency rspec, but only require that gem in the "testing"
- # environment. :except is also a valid option to specify environment
- # restrictions.
- gem "rspec", :only => :testing
-
- # Specify a dependency, but specify that it is already present and expanded
- # at vendor/rspec. Bundler will treat rspec as though it was the rspec gem
- # for the purpose of gem resolution: if another gem depends on a version
- # of rspec satisfied by "1.1.6", it will be used.
- #
- # If a gemspec is found in the directory, it will be used to specify load
- # paths and supply additional dependencies.
- #
- # Bundler will also recursively search for *.gemspec, and assume that
- # gemspecs it finds represent gems that are rooted in the same directory
- # the gemspec is found in.
- gem "rspec", "1.1.6", :vendored_at => "vendor/rspec"
-
- # You can also control what will happen when you run Bundler.require_env
- # by using the :require_as option, as per the next two examples.
-
- # Don't auto-require this gem.
- gem "rspec-rails", "1.2.9", :require_as => nil
-
- # Require something other than the default.
- gem "yajl-ruby", "0.6.7", :require_as => "yajl/json_gem"
-
- # Works exactly like :vendored_at, but first downloads the repo from
- # git and handles stashing the files for you. As with :vendored_at,
- # Bundler will automatically use *.gemspec files in the root or anywhere
- # in the repository.
- gem "rails", "3.0.pre", :git => "git://github.com/rails/rails.git"
-
- # Add http://gems.github.com as a source that the bundler will use
- # to find gems listed in the manifest. By default,
- # http://gems.rubyforge.org is already added to the list.
- #
- # This is an optional setting.
- source "http://gems.github.com"
-
- # Specify where the bundled gems should be stashed. This directory will
- # be a gem repository where all gems are downloaded to and installed to.
- #
- # This is an optional setting.
- # The default is: vendor/gems
- bundle_path "my/bundled/gems"
-
- # Specify where gem executables should be copied to.
- #
- # This is an optional setting.
- # The default is: bin
- bin_path "my/executables"
-
- # Specify that rubygems should be completely disabled. This means that it
- # will be impossible to require it and that available gems will be
- # limited exclusively to gems that have been bundled.
- #
- # The default is to automatically require rubygems. There is also a
- # `disable_system_gems` option that will limit available rubygems to
- # the ones that have been bundled.
- disable_rubygems
-
-### Gem Resolution
-
-One of the most important things that the bundler does is do a
-dependency resolution on the full list of gems that you specify, all
-at once. This differs from the one-at-a-time dependency resolution that
-Rubygems does, which can result in the following problem:
-
- # On my system:
- # activesupport 3.0.pre
- # activesupport 2.3.4
- # activemerchant 1.4.2
- # rails 2.3.4
- #
- # activemerchant 1.4.2 depends on activesupport >= 2.3.2
-
- gem "activemerchant", "1.4.2"
- # results in activating activemerchant, as well as
- # activesupport 3.0.pre, since it is >= 2.3.2
-
- gem "rails", "2.3.4"
- # results in:
- # can't activate activesupport (= 2.3.4, runtime)
- # for ["rails-2.3.4"], already activated
- # activesupport-3.0.pre for ["activemerchant-1.4.2"]
-
-This is because activemerchant has a broader dependency, which results
-in the activation of a version of activesupport that does not satisfy
-a more narrow dependency.
-
-Bundler solves this problem by evaluating all dependencies at once,
-so it can detect that all gems *together* require activesupport "2.3.4".
-
-### Running Bundler
-
-Once a manifest file has been created, the only thing that needs to be done
-is to run the `gem bundle` command anywhere in your application. The script
-will load the manifest file, resolve all the dependencies, download all
-needed gems, and install them into the specified directory.
-
-Every time an update is made to the manifest file, run `gem bundle` again to
-get the changes installed. This will only check the remote sources if your
-currently installed gems do not satisfy the `Gemfile`. If you want to force
-checking for updates on the remote sources, use the `--update` option.
-
-### Remote deploys
-
-When you run `gem bundle`, the following steps occur:
-
-1. Gemfile is read in
-2. The gems specified in the Gemfile are resolved against the gems
- already in your bundle. If the dependencies resolve, skip to step 5.
-3. If the dependencies in your Gemfile cannot be fully resolved
- against the gems already in the bundle, the metadata for each
- source is fetched.
-4. The gems in the Gemfile are resolved against the full list of
- available gems in all sources, and the resulting gems are downloaded
-5. Each gem that has been downloaded but not yet expanded is expanded
- into the local directory. This expansion process also installs
- native gems.
-
-As you can see, if you run gem bundle twice in a row, it will do nothing the
-second time, since the gems obviously resolve against the installed gems,
-and they are all expanded.
-
-This also means that if you run `gem bundle`, and .gitignore the expanded
-copies, leaving only the cached `.gem` files, you can run `gem bundle` again
-on the remote system, and it will only expand out the gems (but not
-resolve or download `.gem` files). This also means that native gems
-will be compiled for the target platform without requiring that the
-`.gem` file itself be downloaded from a remote gem server.
-
-Assuming a Rails app with Bundler's standard setup, add something like
-this to your top-level `.gitignore` to only keep the cache:
-
- bin/*
- vendor/gems/*
- !vendor/gems/cache/
-
-Make sure that you explicitly `git add vendor/gems/cache` before you commit.
-
-### Gems with compile-time options
-
-Some gems require you to pass compile-time options to the gem install command.
-For instance, to install mysql, you might do:
-
- gem install mysql -- --with-mysql-config=/usr/local/lib/mysql
-
-You can pass these options to the bundler by creating a YAML file containing
-the options in question:
-
- mysql:
- mysql-config: /usr/local/lib/mysql
-
-You can then point the bundler at the file:
-
- gem bundle --build-options build_options.yml
-
-In general, you will want to keep the build options YAML out of version control,
-and provide the appropriate options for the system in question.
-
-### Running your application
-
-The easiest way to run your application is to start it with an executable
-copied to the specified bin directory (by default, simply bin). For example,
-if the application in question is a rack app, start it with `bin/rackup`.
-This will automatically set the gem environment correctly.
-
-Another way to run arbitrary ruby code in context of the bundled gems is to
-run it with the `gem exec` command. For example:
-
- gem exec ruby my_ruby_script.rb
-
-You can use `gem exec bash` to enter a shell that will run all binaries in
-the current context.
-
-Yet another way is to manually require the environment file first. This is
-located in `[bundle_path]/gems/environment.rb`. For example:
-
- ruby -r vendor/gems/environment.rb my_ruby_script.rb
-
-### Using Bundler with Rails today
-
-It should be possible to use Bundler with Rails today. Here are the steps
-to follow.
-
-* In your rails app, create a Gemfile and specify the gems that your
- application depends on. Make sure to specify rails as well:
-
- gem "rails", "2.1.2"
- gem "will_paginate"
-
- # Optionally, you can disable system gems all together and only
- # use bundled gems.
- disable_system_gems
-
-* Run `gem bundle`
-
-* You can now use rails if you prepend `gem exec` to every call to `script/*`
- but that isn't fun.
-
-* At the top of `config/preinitializer.rb`, add the following line:
-
- require "#{RAILS_ROOT}/vendor/gems/environment"
-
-In theory, this should be enough to get going.
-
-## To require rubygems or not
-
-Ideally, no gem would assume the presence of rubygems at runtime. Rubygems provides
-enough features so that this isn't necessary. However, there are a number of gems
-that require specific rubygems features.
-
-If the `disable_rubygems` option is used, Bundler will stub out the most common
-of these features, but it is possible that things will not go as intended quite
-yet. So, if you are brave, try your code without rubygems at runtime.
-
-This is different from the `disable_system_gems` option, which uses the rubygems
-library, but prevents system gems from being loaded; only gems that are bundled
-will be available to your application. This option guarantees that dependencies
-of your application will be available to a remote system.
-
-## Known Issues
-
-* When a gem points to a git repository, the git repository will be cloned
- every time Bundler does a gem dependency resolve.
-
-## Reporting bugs
-
-Please report all bugs on the github issue tracker for the project located
-at:
-
- http://github.com/wycats/bundler/issues/
View
81 Rakefile
@@ -1,81 +0,0 @@
-$:.unshift File.join(File.dirname(__FILE__), 'lib')
-require 'rubygems' unless ENV['NO_RUBYGEMS']
-require 'rubygems/specification'
-require 'bundler'
-require 'date'
-
-spec = Gem::Specification.new do |s|
- s.name = "bundler"
- s.version = Bundler::VERSION
- s.authors = ["Yehuda Katz", "Carl Lerche"]
- s.email = ["wycats@gmail.com", "clerche@engineyard.com"]
- s.homepage = "http://github.com/wycats/bundler"
- s.description = s.summary = "An easy way to vendor gem dependencies"
-
- s.platform = Gem::Platform::RUBY
- s.has_rdoc = true
- s.extra_rdoc_files = ["README.markdown", "LICENSE"]
-
- s.required_rubygems_version = ">= 1.3.5"
-
- s.require_path = 'lib'
- s.files = %w(LICENSE README.markdown Rakefile) + Dir.glob("lib/**/*")
-end
-
-task :default => :spec
-
-begin
- require 'spec/rake/spectask'
-rescue LoadError
- task(:spec) { $stderr.puts '`gem install rspec` to run specs' }
-else
- desc "Run specs"
- Spec::Rake::SpecTask.new do |t|
- t.spec_files = FileList['spec/**/*_spec.rb'] - FileList['spec/fixtures/**/*_spec.rb']
- t.spec_opts = %w(-fs --color)
- t.warning = true
- end
-end
-
-namespace :spec do
- file "tmp/rg_deps" do
- repo = File.dirname(__FILE__) + '/tmp/rg_deps'
- FileUtils.mkdir_p(repo)
- p repo
- ENV['GEM_HOME'], ENV['GEM_PATH'] = repo, repo
- system "gem install builder --no-rdoc --no-ri"
- end
-
- desc "Do all setup needed to run the specs"
- task :setup => "tmp/rg_deps"
-
- desc "Mount a ramdisk at ./tmp for faster specs"
- task :ramdisk do
- sh 'diskutil erasevolume HFS+ "tmpbundler" `hdiutil attach -nomount ram://116543`'
- File.symlink "/Volumes/tmpbundler", File.expand_path('../tmp', __FILE__)
- end
-end
-
-spec_file = "#{spec.name}.gemspec"
-desc "Create #{spec_file}"
-file spec_file => "Rakefile" do
- File.open(spec_file, "w") do |file|
- file.puts spec.to_ruby
- end
-end
-
-begin
- require 'rake/gempackagetask'
-rescue LoadError
- task(:gem) { $stderr.puts '`gem install rake` to package gems' }
-else
- Rake::GemPackageTask.new(spec) do |pkg|
- pkg.gem_spec = spec
- end
- task :gem => spec_file
-end
-
-desc "install the gem locally"
-task :install => :package do
- sh %{gem install pkg/#{spec.name}-#{spec.version}}
-end
View
28 bundler.gemspec
@@ -1,28 +0,0 @@
-# -*- encoding: utf-8 -*-
-
-Gem::Specification.new do |s|
- s.name = %q{bundler}
- s.version = "0.8.0"
-
- s.required_rubygems_version = Gem::Requirement.new(">= 1.3.5") if s.respond_to? :required_rubygems_version=
- s.authors = ["Yehuda Katz", "Carl Lerche"]
- s.date = %q{2010-01-04}
- s.description = %q{An easy way to vendor gem dependencies}
- s.email = ["wycats@gmail.com", "clerche@engineyard.com"]
- s.extra_rdoc_files = ["README.markdown", "LICENSE"]
- s.files = ["LICENSE", "README.markdown", "Rakefile", "lib/bundler/bundle.rb", "lib/bundler/cli.rb", "lib/bundler/commands/bundle_command.rb", "lib/bundler/commands/exec_command.rb", "lib/bundler/dependency.rb", "lib/bundler/dsl.rb", "lib/bundler/environment.rb", "lib/bundler/finder.rb", "lib/bundler/gem_bundle.rb", "lib/bundler/gem_ext.rb", "lib/bundler/remote_specification.rb", "lib/bundler/resolver.rb", "lib/bundler/runtime.rb", "lib/bundler/source.rb", "lib/bundler/templates/app_script.erb", "lib/bundler/templates/environment.erb", "lib/bundler/templates/environment_picker.erb", "lib/bundler.rb", "lib/rubygems_plugin.rb"]
- s.homepage = %q{http://github.com/wycats/bundler}
- s.require_paths = ["lib"]
- s.rubygems_version = %q{1.3.5}
- s.summary = %q{An easy way to vendor gem dependencies}
-
- if s.respond_to? :specification_version then
- current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
- s.specification_version = 3
-
- if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
- else
- end
- else
- end
-end
View
49 lib/bundler.rb
@@ -1,49 +0,0 @@
-require 'pathname'
-require 'logger'
-require 'set'
-require 'erb'
-# Required elements of rubygems
-require "rubygems/remote_fetcher"
-require "rubygems/installer"
-
-require "bundler/gem_bundle"
-require "bundler/source"
-require "bundler/finder"
-require "bundler/gem_ext"
-require "bundler/resolver"
-require "bundler/environment"
-require "bundler/dsl"
-require "bundler/cli"
-require "bundler/bundle"
-require "bundler/dependency"
-require "bundler/remote_specification"
-
-module Bundler
- VERSION = "0.8.1"
-
- class << self
- attr_writer :logger, :mode
-
- def logger
- @logger ||= begin
- logger = Logger.new(STDOUT, Logger::INFO)
- logger.formatter = proc {|_,_,_,msg| "#{msg}\n" }
- logger
- end
- end
-
- def local?
- @mode == :local
- end
-
- def writable?
- @mode != :readonly
- end
-
- def remote?
- @mode == :readwrite
- end
- end
-
- self.mode = :readonly
-end
View
314 lib/bundler/bundle.rb
@@ -1,314 +0,0 @@
-module Bundler
- class InvalidRepository < StandardError ; end
-
- class Bundle
- attr_reader :gemfile, :environment
-
- def self.load(gemfile = nil)
- gemfile = Pathname.new(gemfile || default_gemfile).expand_path
-
- unless gemfile.file?
- raise ManifestFileNotFound, "Manifest file not found: #{gemfile.to_s.inspect}"
- end
-
- new(gemfile)
- end
-
- def self.default_gemfile
- current = Pathname.new(Dir.pwd)
-
- until current.root?
- filename = current.join("Gemfile")
- return filename if filename.exist?
- current = current.parent
- end
-
- raise DefaultManifestNotFound
- end
-
- # TODO: passing in the filename is not good
- def initialize(gemfile)
- @gemfile = gemfile
- @environment = Environment.new(self)
- Dsl.evaluate(gemfile, self, @environment)
-
- # path = env.gem_path
-
- FileUtils.mkdir_p(gem_path)
-
- @cache_path = gem_path.join('cache')
- @cache = GemDirectorySource.new(self, :location => @cache_path)
-
- @specs_path = gem_path.join('specifications')
- @gems_path = gem_path.join('gems')
- end
-
- def root
- gemfile.parent
- end
-
- def path
- @path ||= root.join("vendor/gems")
- end
-
- def path=(path)
- @path = (path.relative? ? root.join(path) : path).expand_path
- end
-
- def gem_path
- path.join("#{Gem.ruby_engine}/#{Gem::ConfigMap[:ruby_version]}")
- end
-
- def bindir
- @bindir ||= root.join("bin")
- end
-
- def bindir=(path)
- @bindir = (path.relative? ? root.join(path) : path).expand_path
- end
-
- def install(options = {})
- dependencies = @environment.dependencies
- sources = @environment.sources
-
- # ========== from env
- if only_envs = options[:only]
- dependencies.reject! { |d| !only_envs.any? {|env| d.in?(env) } }
- end
- # ==========
-
- # Check to see whether the existing cache meets all the requirements
- begin
- valid = nil
- # valid = Resolver.resolve(dependencies, [source_index], source_requirements)
- rescue Bundler::GemNotFound
- end
-
- sources = only_local(sources) if options[:cached]
-
- # Check the remote sources if the existing cache does not meet the requirements
- # or the user passed --update
- if options[:update] || !valid
- Bundler.logger.info "Calculating dependencies..."
- bundle = Resolver.resolve(dependencies, [@cache] + sources)
- download(bundle, options)
- do_install(bundle, options)
- valid = bundle
- end
-
- generate_bins(valid, options)
- cleanup(valid, options)
- configure(valid, options)
-
- Bundler.logger.info "Done."
- end
-
- def cache(*gemfiles)
- FileUtils.mkdir_p(@cache_path)
- gemfiles.each do |gemfile|
- Bundler.logger.info "Caching: #{File.basename(gemfile)}"
- FileUtils.cp(gemfile, @cache_path)
- end
- end
-
- def list_outdated(options={})
- outdated_gems = source_index.outdated.sort
-
- if outdated_gems.empty?
- Bundler.logger.info "All gems are up to date."
- else
- Bundler.logger.info "Outdated gems:"
- outdated_gems.each do |name|
- Bundler.logger.info " * #{name}"
- end
- end
- end
-
- def prune(options = {})
- dependencies, sources = @environment.dependencies, @environment.sources
-
- sources = only_local(sources)
- bundle = Resolver.resolve(dependencies, [@cache] + sources)
- @cache.gems.each do |name, specs|
- specs.each do |spec|
- unless bundle.any? { |s| s.name == spec.name && s.version == spec.version }
- Bundler.logger.info "Pruning #{spec.name} (#{spec.version}) from the cache"
- FileUtils.rm @cache_path.join("#{spec.full_name}.gem")
- end
- end
- end
- end
-
- def list(options = {})
- Bundler.logger.info "Currently bundled gems:"
- gems.each do |spec|
- Bundler.logger.info " * #{spec.name} (#{spec.version})"
- end
- end
-
- def gems
- source_index.gems.values
- end
-
- def source_index
- index = Gem::SourceIndex.from_gems_in(@specs_path)
- index.each { |n, spec| spec.loaded_from = @specs_path.join("#{spec.full_name}.gemspec") }
- index
- end
-
- def download_path_for(type)
- @repos[type].download_path_for
- end
-
- def setup_environment
- unless @environment.system_gems
- ENV["GEM_HOME"] = gem_path
- ENV["GEM_PATH"] = gem_path
- end
- ENV["PATH"] = "#{bindir}:#{ENV["PATH"]}"
- ENV["RUBYOPT"] = "-r#{gem_path}/environment #{ENV["RUBYOPT"]}"
- end
-
- private
-
- def only_local(sources)
- sources.select { |s| s.local? }
- end
-
- def download(bundle, options)
- bundle.sort_by {|s| s.full_name.downcase }.each do |spec|
- next if spec.no_bundle?
- spec.source.download(spec)
- end
- end
-
- def do_install(bundle, options)
- bundle.each do |spec|
- next if spec.no_bundle?
- spec.loaded_from = @specs_path.join("#{spec.full_name}.gemspec")
- # Do nothing if the gem is already expanded
- next if @gems_path.join(spec.full_name).directory?
-
- case spec.source
- when GemSource, GemDirectorySource, SystemGemSource
- expand_gemfile(spec, options)
- else
- expand_vendored_gem(spec, options)
- end
- end
- end
-
- def generate_bins(bundle, options)
- bundle.each do |spec|
- next if spec.no_bundle?
- # HAX -- Generate the bin
- bin_dir = bindir
- path = gem_path
- gems_path = @gems_path
- installer = Gem::Installer.allocate
- installer.instance_eval do
- @spec = spec
- @bin_dir = bin_dir
- @gem_dir = gems_path.join(spec.full_name)
- @gem_home = path
- @wrappers = true
- @format_executable = false
- @env_shebang = false
- end
- installer.generate_bin
- end
- end
-
- def expand_gemfile(spec, options)
- Bundler.logger.info "Installing #{spec.name} (#{spec.version})"
-
- gemfile = @cache_path.join("#{spec.full_name}.gem").to_s
-
- if build_args = options[:build_options] && options[:build_options][spec.name]
- Gem::Command.build_args = build_args.map {|k,v| "--with-#{k}=#{v}"}
- end
-
- installer = Gem::Installer.new(gemfile, options.merge(
- :install_dir => gem_path,
- :ignore_dependencies => true,
- :env_shebang => true,
- :wrappers => true,
- :bin_dir => bindir
- ))
- installer.install
- rescue Gem::InstallError
- cleanup_spec(spec)
- raise
- ensure
- Gem::Command.build_args = []
- end
-
- def expand_vendored_gem(spec, options)
- add_spec(spec)
- FileUtils.mkdir_p(@gems_path)
- File.symlink(spec.location, @gems_path.join(spec.full_name))
- end
-
- def add_spec(spec)
- destination = @specs_path
- destination.mkdir unless destination.exist?
-
- File.open(destination.join("#{spec.full_name}.gemspec"), 'w') do |f|
- f.puts spec.to_ruby
- end
- end
-
- def cleanup(valid, options)
- to_delete = gems
- to_delete.delete_if do |spec|
- valid.any? { |other| spec.name == other.name && spec.version == other.version }
- end
-
- valid_executables = valid.map { |s| s.executables }.flatten.compact
-
- to_delete.each do |spec|
- Bundler.logger.info "Deleting gem: #{spec.name} (#{spec.version})"
- cleanup_spec(spec)
- # Cleanup the bin directory
- spec.executables.each do |bin|
- next if valid_executables.include?(bin)
- Bundler.logger.info "Deleting bin file: #{bin}"
- FileUtils.rm_rf(bindir.join(bin))
- end
- end
- end
-
- def cleanup_spec(spec)
- FileUtils.rm_rf(@specs_path.join("#{spec.full_name}.gemspec"))
- FileUtils.rm_rf(@gems_path.join(spec.full_name))
- end
-
- def expand(options)
- each_repo do |repo|
- repo.expand(options)
- end
- end
-
- def configure(specs, options)
- FileUtils.mkdir_p(gem_path)
-
- File.open(gem_path.join("environment.rb"), "w") do |file|
- file.puts @environment.environment_rb(specs, options)
- end
-
- generate_environment_picker
- end
-
- def generate_environment_picker
- FileUtils.cp("#{File.dirname(__FILE__)}/templates/environment_picker.erb", path.join("environment.rb"))
- end
-
- def require_code(file, dep)
- constraint = case
- when dep.only then %{ if #{dep.only.inspect}.include?(env)}
- when dep.except then %{ unless #{dep.except.inspect}.include?(env)}
- end
- "require #{file.inspect}#{constraint}"
- end
- end
-end
View
89 lib/bundler/cli.rb
@@ -1,89 +0,0 @@
-require "optparse"
-
-module Bundler
- class CLI
- def self.run(command, options = {})
- new(options).run(command)
- rescue DefaultManifestNotFound => e
- Bundler.logger.error "Could not find a Gemfile to use"
- exit 3
- rescue InvalidEnvironmentName => e
- Bundler.logger.error "Gemfile error: #{e.message}"
- exit 4
- rescue InvalidRepository => e
- Bundler.logger.error e.message
- exit 5
- rescue VersionConflict => e
- Bundler.logger.error e.message
- exit 6
- rescue GemNotFound => e
- Bundler.logger.error e.message
- exit 7
- rescue InvalidCacheArgument => e
- Bundler.logger.error e.message
- exit 8
- rescue SourceNotCached => e
- Bundler.logger.error e.message
- exit 9
- rescue ManifestFileNotFound => e
- Bundler.logger.error e.message
- exit 10
- end
-
- def initialize(options)
- Bundler.mode = options[:cached] ? :local : :readwrite
- @options = options
- @bundle = Bundle.load(@options[:manifest])
- end
-
- def bundle
- @bundle.install(@options)
- end
-
- def cache
- gemfile = @options[:cache]
-
- if File.extname(gemfile) == ".gem"
- if !File.exist?(gemfile)
- raise InvalidCacheArgument, "'#{gemfile}' does not exist."
- end
- @bundle.cache(gemfile)
- elsif File.directory?(gemfile) || gemfile.include?('/')
- if !File.directory?(gemfile)
- raise InvalidCacheArgument, "'#{gemfile}' does not exist."
- end
- gemfiles = Dir["#{gemfile}/*.gem"]
- if gemfiles.empty?
- raise InvalidCacheArgument, "'#{gemfile}' contains no gemfiles"
- end
- @bundle.cache(*gemfiles)
- else
- raise InvalidCacheArgument, "w0t? '#{gemfile}' means nothing to me."
- end
- end
-
- def prune
- Bundler.mode = :local
- @bundle.prune(@options)
- end
-
- def list
- @bundle.list(@options)
- end
-
- def list_outdated
- @bundle.list_outdated(@options)
- end
-
- def exec
- @bundle.setup_environment
- # w0t?
- super(*$command)
- end
-
- def run(command)
- send(command)
- end
-
- end
-end
View
83 lib/bundler/commands/bundle_command.rb
@@ -1,83 +0,0 @@
-class Gem::Commands::BundleCommand < Gem::Command
-
- def initialize
- super('bundle', 'Create a gem bundle based on your Gemfile', {:manifest => nil, :update => false})
-
- add_option('-i', '--init',"Create a Gemfile") do
- options[:init] = true
- end
-
- add_option('-m', '--manifest MANIFEST', "Specify the path to the manifest file") do |manifest, options|
- options[:manifest] = manifest
- end
-
- add_option('-u', '--update', "Force a remote check for newer gems") do
- options[:update] = true
- end
-
- add_option('--cached', "Only use cached gems when expanding the bundle") do
- options[:cached] = true
- end
-
- add_option('--cache GEM', "Specify a path to a .gem file to add to the bundled gem cache") do |gem, options|
- options[:cache] = gem
- end
-
- add_option('--prune-cache', "Removes all .gem files that are not a part of the bundle from the cache") do
- options[:prune] = true
- end
-
- add_option('--list', "List all gems that are part of the active bundle") do
- options[:list] = true
- end
-
- add_option('--list-outdated', "List all outdated gems that are part of the active bundle") do
- options[:list_outdated] = true
- end
-
- add_option('-b', '--build-options OPTION_FILE', "Specify a path to a yml file with build options for binary gems") do |option_file, options|
- if File.exist?(option_file)
- options[:build_options] = YAML.load_file(option_file)
- end
- end
-
- add_option('--only ENV', "Only expand the given environment. To specify multiple environments, use --only multiple times.") do |env, options|
- options[:only] ||= []
- options[:only] << env
- end
- end
-
- def usage
- "#{program_name}"
- end
-
- def description # :nodoc:
- <<-EOF
-Bundle stuff
- EOF
- end
-
- def execute
- # Prevent the bundler from getting required unless it is actually being used
- require 'bundler'
- if options[:cache]
- Bundler::CLI.run(:cache, options)
- elsif options[:prune]
- Bundler::CLI.run(:prune, options)
- elsif options[:list]
- Bundler::CLI.run(:list, options)
- elsif options[:list_outdated]
- Bundler::CLI.run(:list_outdated, options)
- elsif options[:init]
- if File.exists?("Gemfile")
- Bundler.logger.error "The Gemfile already exists"
- else
- FileUtils.cp File.expand_path("../../templates/Gemfile", __FILE__), "Gemfile"
- Bundler.logger.info "Initialized Gemfile in #{Dir.pwd}"
- end
- else
- Bundler::CLI.run(:bundle, options)
- end
- end
-
-end
View
36 lib/bundler/commands/exec_command.rb
@@ -1,36 +0,0 @@
-if exec = ARGV.index("exec")
- $command = ARGV[(exec + 1)..-1]
- ARGV.replace ARGV[0..exec]
-end
-
-class Gem::Commands::ExecCommand < Gem::Command
-
- def initialize
- super('exec', 'Run a command in context of a gem bundle', {:manifest => nil})
-
- add_option('-m', '--manifest MANIFEST', "Specify the path to the manifest file") do |manifest, options|
- options[:manifest] = manifest
- end
- end
-
- def usage
- "#{program_name} COMMAND"
- end
-
- def arguments # :nodoc:
- "COMMAND command to run in context of the gem bundle"
- end
-
- def description # :nodoc:
- <<-EOF.gsub(' ', '')
- Run in context of a bundle
- EOF
- end
-
- def execute
- # Prevent the bundler from getting required unless it is actually being used
- require 'bundler'
- Bundler::CLI.run(:exec, options)
- end
-
-end
View
62 lib/bundler/dependency.rb
@@ -1,62 +0,0 @@
-module Bundler
- class InvalidEnvironmentName < StandardError; end
-
- class Dependency < Gem::Dependency
- attr_reader :name, :version, :require_as, :only, :except
- attr_accessor :source
-
- def initialize(name, options = {}, &block)
- options.each do |k, v|
- options[k.to_s] = v
- end
-
- super(name, options["version"] || ">= 0")
-
- @require_as = options["require_as"]
- @only = options["only"]
- @except = options["except"]
- @source = options["source"]
- @block = block
-
- if (@only && @only.include?("rubygems")) || (@except && @except.include?("rubygems"))
- raise InvalidEnvironmentName, "'rubygems' is not a valid environment name"
- end
- end
-
- def in?(environment)
- environment = environment.to_s
-
- return false unless !@only || @only.include?(environment)
- return false if @except && @except.include?(environment)
- true
- end
-
- def require_env(environment)
- return unless in?(environment)
-
- if @require_as
- Array(@require_as).each { |file| require file }
- else
- begin
- require name
- rescue LoadError
- # Do nothing
- end
- end
-
- @block.call if @block
- end
-
- def no_bundle?
- source == SystemGemSource.instance
- end
-
- def ==(o)
- [name, version, require_as, only, except] ==
- [o.name, o.version, o.require_as, o.only, o.except]
- end
-
- alias version version_requirements
-
- end
-end
View
182 lib/bundler/dsl.rb
@@ -1,182 +0,0 @@
-module Bundler
- class ManifestFileNotFound < StandardError; end
- class InvalidKey < StandardError; end
- class DefaultManifestNotFound < StandardError; end
-
- class Dsl
- def self.evaluate(file, bundle, environment)
- builder = new(bundle, environment)
- builder.instance_eval(File.read(file.to_s), file.to_s, 1)
- environment
- end
-
- def initialize(bundle, environment)
- @bundle = bundle
- @environment = environment
- @directory_sources = []
- @git_sources = {}
- @only, @except, @directory, @git = nil, nil, nil, nil
- end
-
- def bundle_path(path)
- @bundle.path = Pathname.new(path)
- end
-
- def bin_path(path)
- @bundle.bindir = Pathname.new(path)
- end
-
- def disable_rubygems
- @environment.rubygems = false
- end
-
- def disable_system_gems
- @environment.system_gems = false
- end
-
- def source(source)
- source = GemSource.new(@bundle, :uri => source)
- unless @environment.sources.include?(source)
- @environment.add_source(source)
- end
- end
-
- def only(*env)
- old, @only = @only, _combine_only(env)
- yield
- @only = old
- end
-
- def except(*env)
- old, @except = @except, _combine_except(env)
- yield
- @except = old
- end
-
- def directory(path, options = {})
- raise DirectorySourceError, "cannot nest calls to directory or git" if @directory || @git
- @directory = DirectorySource.new(@bundle, options.merge(:location => path))
- @directory_sources << @directory
- @environment.add_priority_source(@directory)
- retval = yield if block_given?
- @directory = nil
- retval
- end
-
- def git(uri, options = {})
- raise DirectorySourceError, "cannot nest calls to directory or git" if @directory || @git
- @git = GitSource.new(@bundle, options.merge(:uri => uri))
- @git_sources[uri] = @git
- @environment.add_priority_source(@git)
- retval = yield if block_given?
- @git = nil
- retval
- end
-
- def clear_sources
- @environment.clear_sources
- end
-
- def gem(name, *args)
- options = args.last.is_a?(Hash) ? args.pop : {}
- version = args.last
-
- keys = :vendored_at, :path, :only, :except, :git, :path, :bundle, :require_as, :tag, :branch, :ref
- unless (invalid = options.keys - keys).empty?
- raise InvalidKey, "Only #{keys.join(", ")} are valid options to #gem. You used #{invalid.join(", ")}"
- end
-
- if path = options.delete(:vendored_at)
- options[:path] = path
- warn "The :vendored_at option is deprecated. Use :path instead.\nFrom #{caller[0]}"
- end
-
- options[:only] = _combine_only(options[:only] || options["only"])
- options[:except] = _combine_except(options[:except] || options["except"])
-
- dep = Dependency.new(name, options.merge(:version => version))
-
- if options.key?(:bundle) && !options[:bundle]
- dep.source = SystemGemSource.new(@bundle)
- elsif @git || options[:git]
- dep.source = _handle_git_option(name, version, options)
- elsif @directory || options[:path]
- dep.source = _handle_vendored_option(name, version, options)
- end
-
- @environment.dependencies << dep
- end
-
- private
-
- def _version?(version)
- version && Gem::Version.new(version) rescue false
- end
-
- def _handle_vendored_option(name, version, options)
- dir, path = _find_directory_source(options[:path])
-
- if dir
- dir.required_specs << name
- dir.add_spec(path, name, version) if _version?(version)
- dir
- else
- directory options[:path] do
- _handle_vendored_option(name, version, {})
- end
- end
- end
-
- def _find_directory_source(path)
- if @directory
- return @directory, Pathname.new(path || '')
- end
-
- path = @bundle.gemfile.dirname.join(path)
-
- @directory_sources.each do |s|
- if s.location.expand_path.to_s < path.expand_path.to_s
- return s, path.relative_path_from(s.location)
- end
- end
-
- nil
- end
-
- def _handle_git_option(name, version, options)
- git = options[:git].to_s
- ref = options[:ref] || options[:tag]
- branch = options[:branch]
-
- if source = @git || @git_sources[git]
- if ref && source.ref != ref
- raise GitSourceError, "'#{git}' already specified with ref: #{source.ref}"
- elsif branch && source.branch != branch
- raise GitSourceError, "'#{git}' already specified with branch: #{source.branch}"
- end
-
- source.required_specs << name
- source.add_spec(Pathname.new(options[:path] || '.'), name, version) if _version?(version)
- source
- else
- git(git, :ref => ref, :branch => branch) do
- _handle_git_option(name, version, options)
- end
- end
- end
-
- def _combine_only(only)
- return @only unless only
- only = Array(only).compact.uniq.map { |o| o.to_s }
- only &= @only if @only
- only
- end
-
- def _combine_except(except)
- return @except unless except
- except = Array(except).compact.uniq.map { |o| o.to_s }
- except |= @except if @except
- except
- end
- end
-end
View
87 lib/bundler/environment.rb
@@ -1,87 +0,0 @@
-require "rubygems/source_index"
-
-module Bundler
- class InvalidCacheArgument < StandardError; end
- class SourceNotCached < StandardError; end
-
- class Environment
- attr_reader :dependencies
- attr_accessor :rubygems, :system_gems
-
- def initialize(bundle)
- @bundle = bundle # TODO: remove this
- @default_sources = default_sources
- @sources = []
- @priority_sources = []
- @dependencies = []
- @rubygems = true
- @system_gems = true
- end
-
- def environment_rb(specs, options)
- load_paths = load_paths_for_specs(specs, options)
- bindir = @bundle.bindir.relative_path_from(@bundle.gem_path).to_s
- filename = @bundle.gemfile.relative_path_from(@bundle.gem_path).to_s
-
- template = File.read(File.join(File.dirname(__FILE__), "templates", "environment.erb"))
- erb = ERB.new(template, nil, '-')
- erb.result(binding)
- end
-
- def require_env(env = nil)
- dependencies.each { |d| d.require_env(env) }
- end
-
- def sources
- sources = @priority_sources + [SystemGemSource.new(@bundle)] + @sources + @default_sources
- sources.reject! {|s| !s.local? } if Bundler.local?
- sources
- end
-
- def add_source(source)
- @sources << source
- end
-
- def add_priority_source(source)
- @priority_sources << source
- end
-
- def clear_sources
- @sources.clear
- @default_sources.clear
- end
-
- alias rubygems? rubygems
- alias system_gems? system_gems
-
- private
-
- def default_sources
- [GemSource.new(@bundle, :uri => "http://gems.rubyforge.org")]
- end
-
- def load_paths_for_specs(specs, options)
- load_paths = []
- specs.each do |spec|
- next if spec.no_bundle?
- full_gem_path = Pathname.new(spec.full_gem_path)
-
- if spec.bindir && full_gem_path.join(spec.bindir).exist?
- load_paths << load_path_for(full_gem_path, spec.bindir)
- end
- spec.require_paths.each do |path|
- load_paths << load_path_for(full_gem_path, path)
- end
- end
- load_paths
- end
-
- def load_path_for(gem_path, path)
- gem_path.join(path).relative_path_from(@bundle.gem_path).to_s
- end
-
- def spec_file_for(spec)
- spec.loaded_from.relative_path_from(@bundle.gem_path).to_s
- end
- end
-end
View
51 lib/bundler/finder.rb
@@ -1,51 +0,0 @@
-module Bundler
- # Finder behaves like a rubygems source index in that it responds
- # to #search. It also resolves a list of dependencies finding the
- # best possible configuration of gems that satisifes all requirements
- # without causing any gem activation errors.
- class Finder
-
- # Takes an array of gem sources and fetches the full index of
- # gems from each one. It then combines the indexes together keeping
- # track of the original source so that any resolved gem can be
- # fetched from the correct source.
- #
- # ==== Parameters
- # *sources<String>:: URI pointing to the gem repository
- def initialize(*sources)
- @cache = {}
- @index = {}
- @sources = sources
- end
-
- # Searches for a gem that matches the dependency
- #
- # ==== Parameters
- # dependency<Gem::Dependency>:: The gem dependency to search for
- #
- # ==== Returns
- # [Gem::Specification]:: A collection of gem specifications
- # matching the search
- def search(dependency)
- @cache[dependency.hash] ||= begin
- find_by_name(dependency.name).select do |spec|
- dependency =~ spec
- end.sort_by {|s| s.version }
- end
- end
-
- private
-
- def find_by_name(name)
- matches = @index[name] ||= begin
- versions = {}
- @sources.reverse_each do |source|
- versions.merge! source.specs[name] || {}
- end
- versions
- end
- matches.values
- end
-
- end
-end
View
11 lib/bundler/gem_bundle.rb
@@ -1,11 +0,0 @@
-module Bundler
- class GemBundle < Array
- def download
- sort_by {|s| s.full_name.downcase }.each do |spec|
- spec.source.download(spec)
- end
-
- self
- end
- end
-end
View
34 lib/bundler/gem_ext.rb
@@ -1,34 +0,0 @@
-module Gem
- class Installer
- remove_method(:app_script_text) if method_defined?(:app_script_text)
-
- def app_script_text(bin_file_name)
- path = @gem_home
- template = File.read(File.join(File.dirname(__FILE__), "templates", "app_script.erb"))
- erb = ERB.new(template, nil, '-')
- erb.result(binding)
- end
- end
-
- class Specification
- attr_accessor :source, :location, :no_bundle
-
- alias no_bundle? no_bundle
-
- remove_method(:specification_version) if method_defined?(:specification_version)
-
- # Hack to fix github's strange marshal file
- def specification_version
- @specification_version && @specification_version.to_i
- end
-
- alias full_gem_path_without_location full_gem_path
- def full_gem_path
- if defined?(@location) && @location
- @location
- else
- full_gem_path_without_location
- end
- end
- end
-end
View
53 lib/bundler/remote_specification.rb
@@ -1,53 +0,0 @@
-module Bundler
- # Represents a lazily loaded gem specification, where the full specification
- # is on the source server in rubygems' "quick" index. The proxy object is to
- # be seeded with what we're given from the source's abbreviated index - the
- # full specification will only be fetched when necesary.
- class RemoteSpecification
- attr_reader :name, :version, :platform
- attr_accessor :source
-
- def initialize(name, version, platform, source_uri)
- @name = name
- @version = version
- @platform = platform
- @source_uri = source_uri
- end
-
- def full_name
- if platform == Gem::Platform::RUBY or platform.nil? then
- "#{@name}-#{@version}"
- else
- "#{@name}-#{@version}-#{platform}"
- end
- end
-
- # Because Rubyforge cannot be trusted to provide valid specifications
- # once the remote gem is donwloaded, the backend specification will
- # be swapped out.
- def __swap__(spec)
- @specification = spec
- end
-
- private
-
- def _remote_uri
- # "#{@source_uri}/quick/Marshal.4.8/#{@name}-#{@version}.gemspec.rz"
- tuple = [@name, @version, @platform]
- tuple = tuple - [nil, 'ruby', '']
- "#{@source_uri}/quick/Marshal.4.8/#{tuple.join("-")}.gemspec.rz"
- end
-
- def _remote_specification
- @specification ||= begin
- deflated = Gem::RemoteFetcher.fetcher.fetch_path(_remote_uri)
- inflated = Gem.inflate(deflated)
- Marshal.load(inflated)
- end
- end
-
- def method_missing(method, *args, &blk)
- _remote_specification.send(method, *args, &blk)
- end
- end
-end
View
250 lib/bundler/resolver.rb
@@ -1,250 +0,0 @@
-# This is the latest iteration of the gem dependency resolving algorithm. As of now,
-# it can resolve (as a success of failure) any set of gem dependencies we throw at it
-# in a reasonable amount of time. The most iterations I've seen it take is about 150.
-# The actual implementation of the algorithm is not as good as it could be yet, but that
-# can come later.
-
-# Extending Gem classes to add necessary tracking information
-module Gem
- class Dependency
- def required_by
- @required_by ||= []
- end
- end
- class Specification
- def required_by
- @required_by ||= []
- end
- end
-end
-
-module Bundler
- class GemNotFound < StandardError; end
- class VersionConflict < StandardError; end
-
- class Resolver
-
- attr_reader :errors
-
- # Figures out the best possible configuration of gems that satisfies
- # the list of passed dependencies and any child dependencies without
- # causing any gem activation errors.
- #
- # ==== Parameters
- # *dependencies<Gem::Dependency>:: The list of dependencies to resolve
- #
- # ==== Returns
- # <GemBundle>,nil:: If the list of dependencies can be resolved, a
- # collection of gemspecs is returned. Otherwise, nil is returned.
- def self.resolve(requirements, sources)
- source_requirements = {}
-
- requirements.each do |r|
- next unless r.source
- source_requirements[r.name] = r.source
- end
-
- resolver = new(sources, source_requirements)
- result = catch(:success) do
- resolver.resolve(requirements, {})
- output = resolver.errors.inject("") do |o, (conflict, (origin, requirement))|
- o << " Conflict on: #{conflict.inspect}:\n"
- o << " * #{conflict} (#{origin.version}) activated by #{origin.required_by.first}\n"
- o << " * #{requirement} required by #{requirement.required_by.first}\n"
- o << " All possible versions of origin requirements conflict."
- end
- raise VersionConflict, "No compatible versions could be found for required dependencies:\n #{output}"
- nil
- end
- if result
- # Order gems in order of dependencies. Every gem's dependency is at
- # a smaller index in the array.
- ordered = []
- result.values.each do |spec1|
- spec1.no_bundle = true if source_requirements[spec1.name] == SystemGemSource.instance
- index = nil
- place = ordered.detect do |spec2|
- spec1.dependencies.any? { |d| d.name == spec2.name }
- end
- place ?
- ordered.insert(ordered.index(place), spec1) :
- ordered << spec1
- end
- ordered.reverse
- end
- end
-
- def initialize(sources, source_requirements)
- @errors = {}
- @stack = []
- @specs = Hash.new { |h,k| h[k] = [] }
- @by_gem = source_requirements
- @cache = {}
- @index = {}
-
- sources.each do |source|
- source.gems.each do |name, specs|
- # Hack to work with a regular Gem::SourceIndex
- specs = [specs] unless specs.is_a?(Array)
- specs.compact.each do |spec|
- next if @specs[spec.name].any? { |s| s.version == spec.version && s.platform == spec.platform }
- @specs[spec.name] << spec
- end
- end
- end
- end
-
- def debug
- puts yield if defined?($debug) && $debug
- end
-
- def resolve(reqs, activated)
- # If the requirements are empty, then we are in a success state. Aka, all
- # gem dependencies have been resolved.
- throw :success, activated if reqs.empty?
-
- debug { STDIN.gets ; print "\e[2J\e[f" ; "==== Iterating ====\n\n" }
-
- # Sort dependencies so that the ones that are easiest to resolve are first.
- # Easiest to resolve is defined by:
- # 1) Is this gem already activated?
- # 2) Do the version requirements include prereleased gems?
- # 3) Sort by number of gems available in the source.
- reqs = reqs.sort_by do |a|
- [ activated[a.name] ? 0 : 1,
- a.version_requirements.prerelease? ? 0 : 1,
- @errors[a.name] ? 0 : 1,
- activated[a.name] ? 0 : search(a).size ]
- end
-
- debug { "Activated:\n" + activated.values.map { |a| " #{a.name} (#{a.version})" }.join("\n") }
- debug { "Requirements:\n" + reqs.map { |r| " #{r.name} (#{r.version_requirements})"}.join("\n") }
-
- activated = activated.dup
- # Pull off the first requirement so that we can resolve it
- current = reqs.shift
-
- debug { "Attempting:\n #{current.name} (#{current.version_requirements})"}
-
- # Check if the gem has already been activated, if it has, we will make sure
- # that the currently activated gem satisfies the requirement.
- if existing = activated[current.name]
- if current.version_requirements.satisfied_by?(existing.version)
- debug { " * [SUCCESS] Already activated" }
- @errors.delete(existing.name)
- # Since the current requirement is satisfied, we can continue resolving
- # the remaining requirements.
- resolve(reqs, activated)
- else
- debug { " * [FAIL] Already activated" }
- @errors[existing.name] = [existing, current]
- debug { current.required_by.map {|d| " * #{d.name} (#{d.version_requirements})" }.join("\n") }
- # debug { " * All current conflicts:\n" + @errors.keys.map { |c| " - #{c}" }.join("\n") }
- # Since the current requirement conflicts with an activated gem, we need
- # to backtrack to the current requirement's parent and try another version
- # of it (maybe the current requirement won't be present anymore). If the
- # current requirement is a root level requirement, we need to jump back to
- # where the conflicting gem was activated.
- parent = current.required_by.last || existing.required_by.last
- # We track the spot where the current gem was activated because we need
- # to keep a list of every spot a failure happened.
- debug { " -> Jumping to: #{parent.name}" }
- throw parent.name, existing.required_by.last.name
- end
- else
- # There are no activated gems for the current requirement, so we are going
- # to find all gems that match the current requirement and try them in decending
- # order. We also need to keep a set of all conflicts that happen while trying
- # this gem. This is so that if no versions work, we can figure out the best
- # place to backtrack to.
- conflicts = Set.new
-
- # Fetch all gem versions matching the requirement
- #
- # TODO: Warn / error when no matching versions are found.
- matching_versions = search(current)
-
- if matching_versions.empty?
- if current.required_by.empty?
- location = @by_gem[current.name] ? @by_gem[current.name] : "any of the sources"
- raise GemNotFound, "Could not find gem '#{current}' in #{location}"
- end
- Bundler.logger.warn "Could not find gem '#{current}' (required by '#{current.required_by.last}') in any of the sources"
- end
-
- matching_versions.reverse_each do |spec|
- conflict = resolve_requirement(spec, current, reqs.dup, activated.dup)
- conflicts << conflict if conflict
- end
- # If the current requirement is a root level gem and we have conflicts, we
- # can figure out the best spot to backtrack to.
- if current.required_by.empty? && !conflicts.empty?
- # Check the current "catch" stack for the first one that is included in the
- # conflicts set. That is where the parent of the conflicting gem was required.
- # By jumping back to this spot, we can try other version of the parent of
- # the conflicting gem, hopefully finding a combination that activates correctly.
- @stack.reverse_each do |savepoint|
- if conflicts.include?(savepoint)
- debug { " -> Jumping to: #{savepoint}" }
- throw savepoint
- end
- end
- end
- end
- end
-
- def resolve_requirement(spec, requirement, reqs, activated)
- # We are going to try activating the spec. We need to keep track of stack of
- # requirements that got us to the point of activating this gem.
- spec.required_by.replace requirement.required_by
- spec.required_by << requirement
-
- activated[spec.name] = spec
- debug { " Activating: #{spec.name} (#{spec.version})" }
- debug { spec.required_by.map { |d| " * #{d.name} (#{d.version_requirements})" }.join("\n") }
-
- # Now, we have to loop through all child dependencies and add them to our
- # array of requirements.
- debug { " Dependencies"}
- spec.dependencies.each do |dep|
- next if dep.type == :development
- debug { " * #{dep.name} (#{dep.version_requirements})" }
- dep.required_by.replace(requirement.required_by)
- dep.required_by << requirement
- reqs << dep
- end
-
- # We create a savepoint and mark it by the name of the requirement that caused
- # the gem to be activated. If the activated gem ever conflicts, we are able to
- # jump back to this point and try another version of the gem.
- length = @stack.length
- @stack << requirement.name
- retval = catch(requirement.name) do
- resolve(reqs, activated)
- end
- # Since we're doing a lot of throw / catches. A push does not necessarily match
- # up to a pop. So, we simply slice the stack back to what it was before the catch
- # block.
- @stack.slice!(length..-1)
- retval
- end
-
- def search(dependency)
- @cache[dependency.hash] ||= begin
- pinned = @by_gem[dependency.name].gems if @by_gem[dependency.name]
- specs = (pinned || @specs)[dependency.name]
-
- wants_prerelease = dependency.version_requirements.prerelease?
- only_prerelease = specs.all? {|spec| spec.version.prerelease? }
-
- found = specs.select { |spec| dependency =~ spec }
-
- unless wants_prerelease || (pinned && only_prerelease)
- found.reject! { |spec| spec.version.prerelease? }
- end
-
- found.sort_by {|s| [s.version, s.platform.to_s == 'ruby' ? "\0" : s.platform.to_s] }
- end
- end
- end
-end
View
2 lib/bundler/runtime.rb
@@ -1,2 +0,0 @@
-require File.join(File.dirname(__FILE__), "runtime", "dsl")
-require File.join(File.dirname(__FILE__), "runtime", "dependency")
View
365 lib/bundler/source.rb
@@ -1,365 +0,0 @@
-module Bundler
- class DirectorySourceError < StandardError; end
- class GitSourceError < StandardError ; end
- # Represents a source of rubygems. Initially, this is only gem repositories, but
- # eventually, this will be git, svn, HTTP
- class Source
- attr_reader :bundle
-
- def initialize(bundle, options)
- @bundle = bundle
- end
-
- private
-
- def process_source_gems(gems)
- new_gems = Hash.new { |h,k| h[k] = [] }
- gems.values.each do |spec|
- spec.source = self
- new_gems[spec.name] << spec
- end
- new_gems
- end
- end
-
- class GemSource < Source
- attr_reader :uri
-
- def initialize(bundle, options)
- super
- @uri = options[:uri]
- @uri = URI.parse(@uri) unless @uri.is_a?(URI)
- raise ArgumentError, "The source must be an absolute URI" unless @uri.absolute?
- end
-
- def local?
- false
- end
-
- def gems
- @specs ||= fetch_specs
- end
-
- def ==(other)
- uri == other.uri
- end
-
- def to_s
- @uri.to_s
- end
-
- class RubygemsRetardation < StandardError; end
-
- def download(spec)
- Bundler.logger.info "Downloading #{spec.full_name}.gem"
-
- destination = bundle.gem_path
-
- unless destination.writable?
- raise RubygemsRetardation, "destination: #{destination} is not writable"
- end
-
- # Download the gem
- Gem::RemoteFetcher.fetcher.download(spec, uri, destination)
-
- # Re-read the gemspec from the downloaded gem to correct
- # any errors that were present in the Rubyforge specification.
- new_spec = Gem::Format.from_file_by_path(destination.join('cache', "#{spec.full_name}.gem")).spec
- spec.__swap__(new_spec)
- end
-
- private
-
- def fetch_specs
- Bundler.logger.info "Updating source: #{to_s}"
- build_gem_index(fetch_main_specs + fetch_prerelease_specs)
- end
-
- def build_gem_index(index)
- gems = Hash.new { |h,k| h[k] = [] }
- index.each do |name, version, platform|
- spec = RemoteSpecification.new(name, version, platform, @uri)
- spec.source = self
- gems[spec.name] << spec if Gem::Platform.match(spec.platform)
- end
- gems
- end
-
- def fetch_main_specs
- Marshal.load(Gem::RemoteFetcher.fetcher.fetch_path("#{uri}/specs.4.8.gz"))
- rescue Gem::RemoteFetcher::FetchError => e
- raise ArgumentError, "#{to_s} is not a valid source: #{e.message}"
- end
-
- def fetch_prerelease_specs
- Marshal.load(Gem::RemoteFetcher.fetcher.fetch_path("#{uri}/prerelease_specs.4.8.gz"))
- rescue Gem::RemoteFetcher::FetchError
- Bundler.logger.warn "Source '#{uri}' does not support prerelease gems"
- []
- end
- end
-
- class SystemGemSource < Source
-
- def self.instance
- @instance
- end
-
- def self.new(*args)
- @instance ||= super
- end
-
- def initialize(bundle, options = {})
- super
- @source = Gem::SourceIndex.from_installed_gems
- end
-
- def local?
- false
- end
-
- def gems
- @gems ||= process_source_gems(@source.gems)
- end
-
- def ==(other)
- other.is_a?(SystemGemSource)
- end
-
- def to_s
- "system"
- end
-
- def download(spec)
- gemfile = Pathname.new(spec.loaded_from)
- gemfile = gemfile.dirname.join('..', 'cache', "#{spec.full_name}.gem")
- bundle.cache(gemfile)
- end
-
- private
-
- end
-
- class GemDirectorySource < Source
- attr_reader :location
-
- def initialize(bundle, options)
- super
- @location = options[:location]
- end
-
- def local?
- true
- end
-
- def gems
- @specs ||= fetch_specs
- end
-
- def ==(other)
- location == other.location
- end
-
- def to_s
- location.to_s
- end
-
- def download(spec)
- # raise NotImplementedError
- end
-
- private
-
- def fetch_specs
- specs = Hash.new { |h,k| h[k] = [] }
-
- Dir["#{@location}/*.gem"].each do |gemfile|
- spec = Gem::Format.from_file_by_path(gemfile).spec
- spec.source = self
- specs[spec.name] << spec
- end
-
- specs
- end
- end
-
- class DirectorySource < Source
- attr_reader :location, :specs, :required_specs
-
- def initialize(bundle, options)
- super
- if options[:location]
- @location = Pathname.new(options[:location]).expand_path
- end
- @glob = options[:glob] || "**/*.gemspec"
- @specs = {}
- @required_specs = []
- end
-
- def add_spec(path, name, version, require_paths = %w(lib))
- raise DirectorySourceError, "already have a gem defined for '#{path}'" if @specs[path.to_s]
- @specs[path.to_s] = Gem::Specification.new do |s|
- s.name = name
- s.version = Gem::Version.new(version)
- end
- end
-
- def local?
- true
- end
-
- def gems
- @gems ||= begin
- # Locate all gemspecs from the directory
- specs = locate_gemspecs
- specs = merge_defined_specs(specs)
-
- required_specs.each do |required|
- unless specs.any? {|k,v| v.name == required }
- raise DirectorySourceError, "No gemspec for '#{required}' was found in" \
- " '#{location}'. Please explicitly specify a version."
- end
- end
-
- process_source_gems(specs)
- end
- end
-
- def locate_gemspecs
- Dir["#{location}/#{@glob}"].inject({}) do |specs, file|
- file = Pathname.new(file)
- if spec = eval(File.read(file)) # and validate_gemspec(file.dirname, spec)
- spec.location = file.dirname.expand_path
- specs[spec.full_name] = spec
- end
- specs
- end
- end
-
- def merge_defined_specs(specs)
- @specs.each do |path, spec|
- # Set the spec location
- spec.location = "#{location}/#{path}"
-
- if existing = specs.values.find { |s| s.name == spec.name }
- if existing.version != spec.version
- raise DirectorySourceError, "The version you specified for #{spec.name}" \
- " is #{spec.version}. The gemspec is #{existing.version}."
- # Not sure if this is needed
- # ====
- # elsif File.expand_path(existing.location) != File.expand_path(spec.location)
- # raise DirectorySourceError, "The location you specified for #{spec.name}" \
- # " is '#{spec.location}'. The gemspec was found at '#{existing.location}'."
- end
- # elsif !validate_gemspec(spec.location, spec)
- # raise "Your gem definition is not valid: #{spec}"
- else
- specs[spec.full_name] = spec
- end
- end
- specs
- end
-
- def validate_gemspec(path, spec)
- path = Pathname.new(path)
- msg = "Gemspec for #{spec.name} (#{spec.version}) is invalid:"
- # Check the require_paths
- (spec.require_paths || []).each do |require_path|
- unless path.join(require_path).directory?
- Bundler.logger.warn "#{msg} Missing require path: '#{require_path}'"
- return false
- end
- end
-
- # Check the executables
- (spec.executables || []).each do |exec|
- unless path.join(spec.bindir, exec).file?
- Bundler.logger.warn "#{msg} Missing executable: '#{File.join(spec.bindir, exec)}'"
- return false
- end
- end
-
- true
- end
-
- def ==(other)
- # TMP HAX
- other.is_a?(DirectorySource)
- end
-
- def to_s
- "directory: '#{location}'"
- end
-
- def download(spec)
- # Nothing needed here
- end
- end
-
- class GitSource < DirectorySource
- attr_reader :ref, :uri, :branch
-
- def initialize(bundle, options)
- super
- @uri = options[:uri]
- @branch = options[:branch] || 'master'
- @ref = options[:ref] || "origin/#{@branch}"
- end
-
- def local?
- raise SourceNotCached, "Git repository '#{@uri}' has not been cloned yet" unless location.directory?
- super
- end
-
- def location
- # TMP HAX to get the *.gemspec reading to work
- bundle.gem_path.join('dirs', File.basename(@uri, '.git'))
- end
-
- def gems
- update if Bundler.remote?
- checkout if Bundler.writable?
- super
- end
-
- def download(spec)
- # Nothing needed here
- end
-
- def to_s
- "git: #{uri}"
- end
-
- private
- def update
- if location.directory?
- fetch if current_revision != revision_for_ref
- else
- clone
- end
- end
-
- def fetch
- Bundler.logger.info "Fetching git repository at: #{@uri}"
- Dir.chdir(location) { `git fetch origin` }
- end
-
- def clone
- Bundler.logger.info "Cloning git repository at: #{@uri}"
- FileUtils.mkdir_p(location.dirname)
- `git clone #{@uri} #{location} --no-hardlinks`
- end
-
- def current_revision
- Dir.chdir(location) { `git rev-parse HEAD`.strip }
- end
-
- def revision_for_ref
- Dir.chdir(location) { `git rev-parse #{@ref}`.strip }
- end
-
- def checkout
- Dir.chdir(location) { `git checkout --quiet #{@ref}` }
- end
- end
-end
View
72 lib/bundler/templates/Gemfile
@@ -1,72 +0,0 @@
-# Specify a dependency on rails. When the bundler downloads gems,
-# it will download rails as well as all of rails' dependencies (such as
-# activerecord, actionpack, etc...)
-#
-# At least one dependency must be specified
-#gem "rails"
-
-# Specify a dependency on rack v.1.0.0. The version is optional. If present,
-# it can be specified the same way as with rubygems' #gem method.
-#gem "rack", "1.0.0"
-
-# Specify a dependency rspec, but only require that gem in the "testing"
-# environment. :except is also a valid option to specify environment
-# restrictions.
-#gem "rspec", :only => :testing
-
-# Specify a dependency, but specify that it is already present and expanded
-# at vendor/rspec. Bundler will treat rspec as though it was the rspec gem
-# for the purpose of gem resolution: if another gem depends on a version
-# of rspec satisfied by "1.1.6", it will be used.
-#
-# If a gemspec is found in the directory, it will be used to specify load
-# paths and supply additional dependencies.
-#
-# Bundler will also recursively search for *.gemspec, and assume that
-# gemspecs it finds represent gems that are rooted in the same directory
-# the gemspec is found in.
-#gem "rspec", "1.1.6", :vendored_at => "vendor/rspec"
-
-# You can also control what will happen when you run Bundler.require_env
-# by using the :require_as option, as per the next two examples.
-
-# Don't auto-require this gem.
-#gem "rspec-rails", "1.2.9", :require_as => nil
-
-# Require something other than the default.
-#gem "yajl-ruby", "0.6.7", :require_as => "yajl/json_gem"
-
-# Works exactly like :vendored_at, but first downloads the repo from
-# git and handles stashing the files for you. As with :vendored_at,
-# Bundler will automatically use *.gemspec files in the root or anywhere
-# in the repository.
-#gem "rails", "3.0.pre", :git => "git://github.com/rails/rails.git"
-
-# Add http://gems.github.com as a source that the bundler will use
-# to find gems listed in the manifest. By default,
-# http://gems.rubyforge.org is already added to the list.
-#
-# This is an optional setting.
-#source "http://gems.github.com"
-
-# Specify where the bundled gems should be stashed. This directory will
-# be a gem repository where all gems are downloaded to and installed to.
-#
-# This is an optional setting.
-# The default is: vendor/gems
-#bundle_path "my/bundled/gems"
-
-# Specify where gem executables should be copied to.
-#
-# This is an optional setting.
-# The default is: bin
-#bin_path "my/executables"
-
-# Specify that rubygems should be completely disabled. This means that it
-# will be impossible to require it and that available gems will be
-# limited exclusively to gems that have been bundled.
-#
-# The default is to automatically require rubygems. There is also a
-# `disable_system_gems` option that will limit available rubygems to
-# the ones that have been bundled.
-#disable_rubygems
View
3 lib/bundler/templates/app_script.erb
@@ -1,3 +0,0 @@
-<%= shebang bin_file_name %>
-require File.expand_path(File.join(File.dirname(__FILE__), "<%= path.join("environment").relative_path_from(Pathname.new(bin_dir)) %>"))
-load File.expand_path(File.join(File.dirname(__FILE__), "<%= path.join("gems", @spec.full_name, @spec.bindir, bin_file_name).relative_path_from(Pathname.new(bin_dir)) %>"))
View
156 lib/bundler/templates/environment.erb
@@ -1,156 +0,0 @@
-# DO NOT MODIFY THIS FILE
-module Bundler
- file = File.expand_path(__FILE__)
- dir = File.dirname(file)
-
-<% unless system_gems? -%>
- ENV["GEM_HOME"] = dir
- ENV["GEM_PATH"] = dir
-
- # handle 1.9 where system gems are always on the load path
- if defined?(::Gem)
- $LOAD_PATH.reject! do |p|
- p != File.dirname(__FILE__) &&
- Gem.path.any? { |gp| p.include?(gp) }
- end
- end
-
-<% end -%>
- ENV["PATH"] = "#{dir}/<%= bindir %><%= File::PATH_SEPARATOR %>#{ENV["PATH"]}"
- ENV["RUBYOPT"] = "-r#{file} #{ENV["RUBYOPT"]}"
-
-<% load_paths.each do |load_path| -%>
- $LOAD_PATH.unshift File.expand_path("#{dir}/<%= load_path %>")
-<% end -%>
-
- @gemfile = "#{dir}/<%= filename %>"
-
-<% if rubygems? -%>
- require "rubygems" unless respond_to?(:gem) # 1.9 already has RubyGems loaded
-
- @bundled_specs = {}
-<% specs.each do |spec| -%>
-<% if spec.no_bundle? -%>
- gem "<%= spec.name %>", "<%= spec.version %>"
-<% else -%>
-<% path = spec_file_for(spec) -%>
- @bundled_specs["<%= spec.name %>"] = eval(File.read("#{dir}/<%= path %>"))
- @bundled_specs["<%= spec.name %>"].loaded_from = "#{dir}/<%= path %>"
-<% end -%>
-<% end -%>
-
- def self.add_specs_to_loaded_specs
- Gem.loaded_specs.merge! @bundled_specs
- end
-
- def self.add_specs_to_index
- @bundled_specs.each do |name, spec|
- Gem.source_index.add_spec spec
- end
- end
-
- add_specs_to_loaded_specs
- add_specs_to_index
-<% end -%>
-
- def self.require_env(env = nil)
- context = Class.new do
- def initialize(env) @env = env && env.to_s ; end
- def method_missing(*) ; yield if block_given? ; end
- def only(*env)
- old, @only = @only, _combine_only(env.flatten)
- yield
- @only = old
- end
- def except(*env)
- old, @except = @except, _combine_except(env.flatten)
- yield
- @except = old
- end
- def gem(name, *args)
- opt = args.last.is_a?(Hash) ? args.pop : {}
- only = _combine_only(opt[:only] || opt["only"])
- except = _combine_except(opt[:except] || opt["except"])
- files = opt[:require_as] || opt["require_as"] || name
- files = [files] unless files.respond_to?(:each)
-
- return unless !only || only.any? {|e| e == @env }
- return if except && except.any? {|e| e == @env }
-
- if files = opt[:require_as] || opt["require_as"]
- files = Array(files)
- files.each { |f| require f }
- else
- begin
- require name
- rescue LoadError
- # Do nothing
- end
- end
- yield if block_given?
- true
- end
- private
- def _combine_only(only)
- return @only unless only
- only = [only].flatten.compact.uniq.map { |o| o.to_s }
- only &= @only if @only
- only
- end
- def _combine_except(except)
- return @except unless except
- except = [except].flatten.compact.uniq.map { |o| o.to_s }
- except |= @except if @except
- except
- end
- end
- context.new(env && env.to_s).instance_eval(File.read(@gemfile), @gemfile, 1)
- end
-end
-
-<% if rubygems? -%>
-module Gem
- @loaded_stacks = Hash.new { |h,k| h[k] = [] }
-
- def source_index.refresh!
- super
- Bundler.add_sp