diff options
author | Samuel Giddins <segiddins@segiddins.me> | 2016-06-05 18:52:58 -0500 |
---|---|---|
committer | Samuel Giddins <segiddins@segiddins.me> | 2016-06-10 01:42:17 -0500 |
commit | cfbe2b4b272242b404a6abb318edde030447707a (patch) | |
tree | d7562f75224cf57fad2b45b44495c63dad91621c | |
parent | 8c1b9e77b08b52018a7b1b38d51dcbcd168938f4 (diff) | |
download | bundler-cfbe2b4b272242b404a6abb318edde030447707a.tar.gz |
Add total bundler version trampolining via vendored postit
-rw-r--r-- | Rakefile | 11 | ||||
-rw-r--r-- | bundler.gemspec | 2 | ||||
-rwxr-xr-x | exe/bundle | 11 | ||||
-rw-r--r-- | lib/bundler/cli.rb | 2 | ||||
-rw-r--r-- | lib/bundler/cli/update.rb | 2 | ||||
-rw-r--r-- | lib/bundler/postit_trampoline.rb | 46 | ||||
-rw-r--r-- | lib/bundler/setup.rb | 1 | ||||
-rw-r--r-- | lib/bundler/shared_helpers.rb | 1 | ||||
-rw-r--r-- | lib/bundler/vendor/postit/lib/postit.rb | 15 | ||||
-rw-r--r-- | lib/bundler/vendor/postit/lib/postit/environment.rb | 44 | ||||
-rw-r--r-- | lib/bundler/vendor/postit/lib/postit/installer.rb | 17 | ||||
-rw-r--r-- | lib/bundler/vendor/postit/lib/postit/parser.rb | 21 | ||||
-rw-r--r-- | lib/bundler/vendor/postit/lib/postit/setup.rb | 12 | ||||
-rw-r--r-- | lib/bundler/vendor/postit/lib/postit/version.rb | 3 | ||||
-rw-r--r-- | spec/bundler/shared_helpers_spec.rb | 2 | ||||
-rw-r--r-- | spec/support/helpers.rb | 1 |
16 files changed, 183 insertions, 8 deletions
@@ -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 |