summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSamuel Giddins <segiddins@segiddins.me>2016-06-05 18:52:58 -0500
committerSamuel Giddins <segiddins@segiddins.me>2016-06-10 01:42:17 -0500
commitcfbe2b4b272242b404a6abb318edde030447707a (patch)
treed7562f75224cf57fad2b45b44495c63dad91621c
parent8c1b9e77b08b52018a7b1b38d51dcbcd168938f4 (diff)
downloadbundler-cfbe2b4b272242b404a6abb318edde030447707a.tar.gz
Add total bundler version trampolining via vendored postit
-rw-r--r--Rakefile11
-rw-r--r--bundler.gemspec2
-rwxr-xr-xexe/bundle11
-rw-r--r--lib/bundler/cli.rb2
-rw-r--r--lib/bundler/cli/update.rb2
-rw-r--r--lib/bundler/postit_trampoline.rb46
-rw-r--r--lib/bundler/setup.rb1
-rw-r--r--lib/bundler/shared_helpers.rb1
-rw-r--r--lib/bundler/vendor/postit/lib/postit.rb15
-rw-r--r--lib/bundler/vendor/postit/lib/postit/environment.rb44
-rw-r--r--lib/bundler/vendor/postit/lib/postit/installer.rb17
-rw-r--r--lib/bundler/vendor/postit/lib/postit/parser.rb21
-rw-r--r--lib/bundler/vendor/postit/lib/postit/setup.rb12
-rw-r--r--lib/bundler/vendor/postit/lib/postit/version.rb3
-rw-r--r--spec/bundler/shared_helpers_spec.rb2
-rw-r--r--spec/support/helpers.rb1
16 files changed, 183 insertions, 8 deletions
diff --git a/Rakefile b/Rakefile
index 43c5c58237..9bc34e4177 100644
--- a/Rakefile
+++ b/Rakefile
@@ -296,10 +296,21 @@ begin
lib.prefix = "Bundler"
lib.vendor_lib = "lib/bundler/vendor/thor"
end
+
+ Automatiek::RakeTask.new("postit") do |lib|
+ lib.download = { :github => "https://github.com/bundler/postit" }
+ lib.namespace = "PostIt"
+ lib.vendor_lib = "lib/bundler/vendor/postit"
+
+ def lib.namespace_files
+ process_files(namespace, "BundlerVendoredPostIt")
+ end
+ end
rescue LoadError
namespace :vendor do
task(:molinillo) { abort "Install the automatiek gem to be able to vendor gems." }
task(:thor) { abort "Install the automatiek gem to be able to vendor gems." }
+ task(:postit) { abort "Install the automatiek gem to be able to vendor gems." }
end
end
diff --git a/bundler.gemspec b/bundler.gemspec
index 27218d8b4e..0df67402b2 100644
--- a/bundler.gemspec
+++ b/bundler.gemspec
@@ -24,8 +24,6 @@ Gem::Specification.new do |s|
s.add_development_dependency "ronn", "~> 0.7.3"
s.add_development_dependency "rspec", "~> 3.0"
- s.add_runtime_dependency "postit", "~> 0.1.1"
-
s.files = `git ls-files -z`.split("\x0").reject {|f| f.match(%r{^(test|spec|features)/}) }
# we don't check in man pages, but we need to ship them because
# we use them to generate the long-form help for each command.
diff --git a/exe/bundle b/exe/bundle
index 0047906251..51a9035d97 100755
--- a/exe/bundle
+++ b/exe/bundle
@@ -4,6 +4,13 @@
# Exit cleanly from an early interrupt
Signal.trap("INT") { exit 1 }
+unless ENV["BUNDLE_DISABLE_POSTIT"]
+ update = "update".start_with?(ARGV.first || " ") && ARGV.find {|a| a.start_with?("--bundler") }
+ update &&= update =~ /--bundler(?:=(.+))?/ && $1 || "> 0.a"
+ ENV["BUNDLER_VERSION"] = update if update
+ require "bundler/postit_trampoline"
+end
+
require "bundler"
# Check if an older version of bundler is installed
$LOAD_PATH.each do |path|
@@ -17,10 +24,6 @@ end
require "bundler/friendly_errors"
Bundler.with_friendly_errors do
- if !"exec".start_with?(ARGV.first || " ") && postit = Gem.bin_path("postit", "postit")
- Kernel.exec(postit, *ARGV)
- end
-
require "bundler/cli"
# Allow any command to use --help flag to show help for that command
diff --git a/lib/bundler/cli.rb b/lib/bundler/cli.rb
index bb21e6f4e5..c255a59437 100644
--- a/lib/bundler/cli.rb
+++ b/lib/bundler/cli.rb
@@ -199,6 +199,8 @@ module Bundler
"Force downloading every gem."
method_option "ruby", :type => :boolean, :banner =>
"Update ruby specified in Gemfile.lock"
+ method_option "bundler", :type => :string, :lazy_default => "> 0.a", :banner =>
+ "Update the locked version of bundler"
def update(*gems)
require "bundler/cli/update"
Update.new(options, gems).run
diff --git a/lib/bundler/cli/update.rb b/lib/bundler/cli/update.rb
index 037da2915e..33b0557fec 100644
--- a/lib/bundler/cli/update.rb
+++ b/lib/bundler/cli/update.rb
@@ -13,7 +13,7 @@ module Bundler
sources = Array(options[:source])
groups = Array(options[:group]).map(&:to_sym)
- if gems.empty? && sources.empty? && groups.empty? && !options[:ruby]
+ if gems.empty? && sources.empty? && groups.empty? && !options[:ruby] && !options[:bundler]
# We're doing a full update
Bundler.definition(true)
else
diff --git a/lib/bundler/postit_trampoline.rb b/lib/bundler/postit_trampoline.rb
new file mode 100644
index 0000000000..f648832202
--- /dev/null
+++ b/lib/bundler/postit_trampoline.rb
@@ -0,0 +1,46 @@
+# frozen_string_literal: true
+
+postit_lib = File.expand_path("../vendor/postit/lib", __FILE__)
+$:.unshift(postit_lib)
+require "postit"
+require "rubygems"
+
+environment = BundlerVendoredPostIt::Environment.new([])
+version = Gem::Requirement.new(environment.bundler_version)
+
+installed_version =
+ if defined?(Bundler::VERSION)
+ Bundler::VERSION
+ else
+ File.read(File.expand_path("../version.rb", __FILE__)) =~ /VERSION = "(.+)"/
+ $1
+ end
+installed_version &&= Gem::Version.new(installed_version)
+
+if !version.satisfied_by?(installed_version)
+ installer = BundlerVendoredPostIt::Installer.new(version)
+ installer.install!
+
+ Gem.loaded_specs.delete("bundler") unless defined?(Bundler)
+ gem "bundler", version
+ $:.delete(File.expand_path("../..", __FILE__))
+else
+ begin
+ gem "bundler", version
+ rescue LoadError
+ $:.unshift(File.expand_path("../..", __FILE__))
+ end
+end
+
+running_version = begin
+ require "bundler/version"
+ Bundler::VERSION
+rescue LoadError, NameError
+ nil
+end
+
+if !Gem::Version.correct?(running_version.to_s) || !version.satisfied_by?(Gem::Version.create(running_version))
+ abort "The running bundler (#{running_version}) does not match the required `#{version}`"
+end
+
+$:.delete_at($:.find_index(postit_lib))
diff --git a/lib/bundler/setup.rb b/lib/bundler/setup.rb
index 9aae6478cd..c888dabf2c 100644
--- a/lib/bundler/setup.rb
+++ b/lib/bundler/setup.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+require "bundler/postit_trampoline" unless ENV["BUNDLE_DISABLE_POSTIT"]
require "bundler/shared_helpers"
if Bundler::SharedHelpers.in_bundle?
diff --git a/lib/bundler/shared_helpers.rb b/lib/bundler/shared_helpers.rb
index e21d616ecd..01f1118d7b 100644
--- a/lib/bundler/shared_helpers.rb
+++ b/lib/bundler/shared_helpers.rb
@@ -169,6 +169,7 @@ module Bundler
# Set BUNDLE_GEMFILE
ENV["BUNDLE_GEMFILE"] = find_gemfile.to_s
+ ENV["BUNDLER_VERSION"] = Bundler::VERSION
end
def set_path
diff --git a/lib/bundler/vendor/postit/lib/postit.rb b/lib/bundler/vendor/postit/lib/postit.rb
new file mode 100644
index 0000000000..4b3ff34d49
--- /dev/null
+++ b/lib/bundler/vendor/postit/lib/postit.rb
@@ -0,0 +1,15 @@
+require 'postit/environment'
+require 'postit/installer'
+require 'postit/parser'
+require 'postit/version'
+require 'rubygems'
+
+module BundlerVendoredPostIt
+ def self.setup
+ load File.expand_path('../postit/setup.rb', __FILE__)
+ end
+
+ def self.bundler_version
+ defined?(Bundler::VERSION) && Bundler::VERSION
+ end
+end
diff --git a/lib/bundler/vendor/postit/lib/postit/environment.rb b/lib/bundler/vendor/postit/lib/postit/environment.rb
new file mode 100644
index 0000000000..b758fa0ccb
--- /dev/null
+++ b/lib/bundler/vendor/postit/lib/postit/environment.rb
@@ -0,0 +1,44 @@
+require 'postit/parser'
+
+module BundlerVendoredPostIt
+ class Environment
+ def initialize(argv)
+ @argv = argv
+ end
+
+ def env_var_version
+ ENV['BUNDLER_VERSION']
+ end
+
+ def cli_arg_version
+ return unless str = @argv.first
+ str = str.dup.force_encoding('BINARY') if str.respond_to?(:force_encoding)
+ if Gem::Version.correct?(str)
+ @argv.shift
+ str
+ end
+ end
+
+ def gemfile
+ ENV['BUNDLE_GEMFILE'] || 'Gemfile'
+ end
+
+ def lockfile
+ File.expand_path case File.basename(gemfile)
+ when 'gems.rb' then gemfile.sub(/\.rb$/, gemfile)
+ else "#{gemfile}.lock"
+ end
+ end
+
+ def lockfile_version
+ BundlerVendoredPostIt::Parser.new(lockfile).parse
+ end
+
+ def bundler_version
+ @bundler_version ||= begin
+ env_var_version || cli_arg_version ||
+ lockfile_version || "#{Gem::Requirement.default}.a"
+ end
+ end
+ end
+end
diff --git a/lib/bundler/vendor/postit/lib/postit/installer.rb b/lib/bundler/vendor/postit/lib/postit/installer.rb
new file mode 100644
index 0000000000..9117a1ac35
--- /dev/null
+++ b/lib/bundler/vendor/postit/lib/postit/installer.rb
@@ -0,0 +1,17 @@
+module BundlerVendoredPostIt
+ class Installer
+ def initialize(bundler_version)
+ @bundler_version = bundler_version
+ end
+
+ def installed?
+ !Gem::Specification.find_by_name('bundler', @bundler_version).nil?
+ rescue Gem::MissingSpecVersionError
+ false
+ end
+
+ def install!
+ Gem.install('bundler', @bundler_version) unless installed?
+ end
+ end
+end
diff --git a/lib/bundler/vendor/postit/lib/postit/parser.rb b/lib/bundler/vendor/postit/lib/postit/parser.rb
new file mode 100644
index 0000000000..98c4a3578f
--- /dev/null
+++ b/lib/bundler/vendor/postit/lib/postit/parser.rb
@@ -0,0 +1,21 @@
+require 'rubygems'
+
+module BundlerVendoredPostIt
+ class Parser
+ def initialize(file)
+ @file = file
+ end
+
+ BUNDLED_WITH =
+ /\n\nBUNDLED WITH\n\s{2,}(#{Gem::Version::VERSION_PATTERN})\n/
+
+ def parse
+ return unless lockfile = File.file?(@file) && File.read(@file)
+ if lockfile =~ BUNDLED_WITH
+ Regexp.last_match(1)
+ else
+ '< 1.10'
+ end
+ end
+ end
+end
diff --git a/lib/bundler/vendor/postit/lib/postit/setup.rb b/lib/bundler/vendor/postit/lib/postit/setup.rb
new file mode 100644
index 0000000000..260edd559d
--- /dev/null
+++ b/lib/bundler/vendor/postit/lib/postit/setup.rb
@@ -0,0 +1,12 @@
+require 'postit/environment'
+require 'postit/installer'
+
+environment = BundlerVendoredPostIt::Environment.new(ARGV)
+version = environment.bundler_version
+
+installer = BundlerVendoredPostIt::Installer.new(version)
+installer.install!
+
+gem 'bundler', version
+
+require 'bundler/version'
diff --git a/lib/bundler/vendor/postit/lib/postit/version.rb b/lib/bundler/vendor/postit/lib/postit/version.rb
new file mode 100644
index 0000000000..1a16501024
--- /dev/null
+++ b/lib/bundler/vendor/postit/lib/postit/version.rb
@@ -0,0 +1,3 @@
+module BundlerVendoredPostIt
+ VERSION = '0.1.2'.freeze
+end
diff --git a/spec/bundler/shared_helpers_spec.rb b/spec/bundler/shared_helpers_spec.rb
index 98f7994f9f..2ad0c98dba 100644
--- a/spec/bundler/shared_helpers_spec.rb
+++ b/spec/bundler/shared_helpers_spec.rb
@@ -222,7 +222,7 @@ describe Bundler::SharedHelpers do
shared_examples_for "ENV['RUBYOPT'] gets set correctly" do
it "ensures -rbundler/setup is at the beginning of ENV['RUBYOPT']" do
subject.set_bundle_environment
- expect(ENV["RUBYOPT"].split(" ").first).to include("-rbundler/setup")
+ expect(ENV["RUBYOPT"].split(" ")).to start_with("-rbundler/setup")
end
end
diff --git a/spec/support/helpers.rb b/spec/support/helpers.rb
index 75ee592826..7e77c9f01a 100644
--- a/spec/support/helpers.rb
+++ b/spec/support/helpers.rb
@@ -12,6 +12,7 @@ module Spec
end
FileUtils.mkdir_p(tmp)
FileUtils.mkdir_p(home)
+ ENV["BUNDLE_DISABLE_POSTIT"] = "1"
Bundler.send(:remove_instance_variable, :@settings) if Bundler.send(:instance_variable_defined?, :@settings)
end