lib/bundler.rb in bundler-2.1.0.pre.2 vs lib/bundler.rb in bundler-2.1.0.pre.3

- old
+ new

@@ -12,10 +12,29 @@ require_relative "bundler/version" require_relative "bundler/constants" require_relative "bundler/current_ruby" require_relative "bundler/build_metadata" +# Bundler provides a consistent environment for Ruby projects by +# tracking and installing the exact gems and versions that are needed. +# +# Since Ruby 2.6, Bundler is a part of Ruby's standard library. +# +# Bunder is used by creating _gemfiles_ listing all the project dependencies +# and (optionally) their versions and then using +# +# require 'bundler/setup' +# +# or Bundler.setup to setup environment where only specified gems and their +# specified versions could be used. +# +# See {Bundler website}[https://bundler.io/docs.html] for extensive documentation +# on gemfiles creation and Bundler usage. +# +# As a standard library inside project, Bundler could be used for introspection +# of loaded and required modules. +# module Bundler environment_preserver = EnvironmentPreserver.new(ENV, EnvironmentPreserver::BUNDLER_KEYS) ORIGINAL_ENV = environment_preserver.restore ENV.replace(environment_preserver.backup) SUDO_MUTEX = Mutex.new @@ -62,15 +81,15 @@ def configure @configured ||= configure_gem_home_and_path end def ui - (defined?(@ui) && @ui) || (self.ui = UI::Silent.new) + (defined?(@ui) && @ui) || (self.ui = UI::Shell.new) end def ui=(ui) - Bundler.rubygems.ui = ui ? UI::RGProxy.new(ui) : nil + Bundler.rubygems.ui = UI::RGProxy.new(ui) @ui = ui end # Returns absolute path of where gems are installed on the filesystem. def bundle_path @@ -89,10 +108,37 @@ SharedHelpers.filesystem_access(path) {|p| FileUtils.mkdir_p(p) } path end end + # Turns on the Bundler runtime. After +Bundler.setup+ call, all +load+ or + # +require+ of the gems would be allowed only if they are part of + # the Gemfile or Ruby's standard library. If the versions specified + # in Gemfile, only those versions would be loaded. + # + # Assuming Gemfile + # + # gem 'first_gem', '= 1.0' + # group :test do + # gem 'second_gem', '= 1.0' + # end + # + # The code using Bundler.setup works as follows: + # + # require 'third_gem' # allowed, required from global gems + # require 'first_gem' # allowed, loads the last installed version + # Bundler.setup + # require 'fourth_gem' # fails with LoadError + # require 'second_gem' # loads exactly version 1.0 + # + # +Bundler.setup+ can be called only once, all subsequent calls are no-op. + # + # If _groups_ list is provided, only gems from specified groups would + # be allowed (gems specified outside groups belong to special +:default+ group). + # + # To require all gems from Gemfile (or only some groups), see Bundler.require. + # def setup(*groups) # Return if all groups are already loaded return @setup if defined?(@setup) && @setup definition.validate_runtime! @@ -105,20 +151,38 @@ else load.setup(*groups) end end + # Setups Bundler environment (see Bundler.setup) if it is not already set, + # and loads all gems from groups specified. Unlike ::setup, can be called + # multiple times with different groups (if they were allowed by setup). + # + # Assuming Gemfile + # + # gem 'first_gem', '= 1.0' + # group :test do + # gem 'second_gem', '= 1.0' + # end + # + # The code will work as follows: + # + # Bundler.setup # allow all groups + # Bundler.require(:default) # requires only first_gem + # # ...later + # Bundler.require(:test) # requires second_gem + # def require(*groups) setup(*groups).require(*groups) end def load @load ||= Runtime.new(root, definition) end def environment - SharedHelpers.major_deprecation 2, "Bundler.environment has been removed in favor of Bundler.load" + SharedHelpers.major_deprecation 2, "Bundler.environment has been removed in favor of Bundler.load", :print_caller_location => true load end # Returns an instance of Bundler::Definition for given Gemfile and lockfile # @@ -165,35 +229,19 @@ elsif !File.writable?(home) && (!File.directory?(bundle_home) || !File.writable?(bundle_home)) "`#{home}` is not writable." end if warning - Kernel.send(:require, "etc") - user_home = tmp_home_path(Etc.getlogin, warning) + user_home = tmp_home_path(warning) Bundler.ui.warn "#{warning}\nBundler will use `#{user_home}' as your home directory temporarily.\n" user_home else Pathname.new(home) end end end - def tmp_home_path(login, warning) - login ||= "unknown" - Kernel.send(:require, "tmpdir") - path = Pathname.new(Dir.tmpdir).join("bundler", "home") - SharedHelpers.filesystem_access(path) do |tmp_home_path| - unless tmp_home_path.exist? - tmp_home_path.mkpath - tmp_home_path.chmod(0o777) - end - tmp_home_path.join(login).tap(&:mkpath) - end - rescue RuntimeError => e - raise e.exception("#{warning}\nBundler also failed to create a temporary home directory at `#{path}':\n#{e}") - end - def user_bundle_path(dir = "home") env_var, fallback = case dir when "home" ["BUNDLE_USER_HOME", proc { Pathname.new(user_home).join(".bundle") }] when "cache" @@ -280,11 +328,12 @@ # @deprecated Use `unbundled_env` instead def clean_env Bundler::SharedHelpers.major_deprecation( 2, "`Bundler.clean_env` has been deprecated in favor of `Bundler.unbundled_env`. " \ - "If you instead want the environment before bundler was originally loaded, use `Bundler.original_env`" + "If you instead want the environment before bundler was originally loaded, use `Bundler.original_env`", + :print_caller_location => true ) unbundled_env end @@ -319,11 +368,12 @@ # @deprecated Use `with_unbundled_env` instead def with_clean_env Bundler::SharedHelpers.major_deprecation( 2, "`Bundler.with_clean_env` has been deprecated in favor of `Bundler.with_unbundled_env`. " \ - "If you instead want the environment before bundler was originally loaded, use `Bundler.with_original_env`" + "If you instead want the environment before bundler was originally loaded, use `Bundler.with_original_env`", + :print_caller_location => true ) with_env(unbundled_env) { yield } end @@ -340,11 +390,12 @@ # @deprecated Use `unbundled_system` instead def clean_system(*args) Bundler::SharedHelpers.major_deprecation( 2, "`Bundler.clean_system` has been deprecated in favor of `Bundler.unbundled_system`. " \ - "If you instead want to run the command in the environment before bundler was originally loaded, use `Bundler.original_system`" + "If you instead want to run the command in the environment before bundler was originally loaded, use `Bundler.original_system`", + :print_caller_location => true ) with_env(unbundled_env) { Kernel.system(*args) } end @@ -361,11 +412,12 @@ # @deprecated Use `unbundled_exec` instead def clean_exec(*args) Bundler::SharedHelpers.major_deprecation( 2, "`Bundler.clean_exec` has been deprecated in favor of `Bundler.unbundled_exec`. " \ - "If you instead want to exec to a command in the environment before bundler was originally loaded, use `Bundler.original_exec`" + "If you instead want to exec to a command in the environment before bundler was originally loaded, use `Bundler.original_exec`", + :print_caller_location => true ) with_env(unbundled_env) { Kernel.exec(*args) } end @@ -604,9 +656,20 @@ end def configure_gem_home Bundler::SharedHelpers.set_env "GEM_HOME", File.expand_path(bundle_path, root) Bundler.rubygems.clear_paths + end + + def tmp_home_path(warning) + Kernel.send(:require, "tmpdir") + SharedHelpers.filesystem_access(Dir.tmpdir) do + path = Bundler.tmp + at_exit { Bundler.rm_rf(path) } + path + end + rescue RuntimeError => e + raise e.exception("#{warning}\nBundler also failed to create a temporary home directory':\n#{e}") end # @param env [Hash] def with_env(env) backup = ENV.to_hash