1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

Merge Bundler 2.1.0.pre.1 as developed version from upstream.

a53709556b

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67539 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
hsbt 2019-04-14 06:01:35 +00:00
parent d636809c05
commit 68ddd4d300
290 changed files with 5820 additions and 6161 deletions

View file

@ -5,7 +5,6 @@ require "bundler/compatibility_guard"
require "bundler/vendored_fileutils"
require "pathname"
require "rbconfig"
require "thread"
require "bundler/errors"
require "bundler/environment_preserver"
@ -119,7 +118,7 @@ module Bundler
end
def environment
SharedHelpers.major_deprecation 3, "Bundler.environment has been removed in favor of Bundler.load"
SharedHelpers.major_deprecation 2, "Bundler.environment has been removed in favor of Bundler.load"
load
end
@ -280,10 +279,19 @@ EOF
ORIGINAL_ENV.clone
end
# @deprecated Use `original_env` instead
# @return [Hash] Environment with all bundler-related variables removed
# @deprecated Use `unbundled_env` instead
def clean_env
Bundler::SharedHelpers.major_deprecation(3, "`Bundler.clean_env` has weird edge cases, use `.original_env` instead")
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`"
)
unbundled_env
end
# @return [Hash] Environment with all bundler-related variables removed
def unbundled_env
env = original_env
if env.key?("BUNDLER_ORIG_MANPATH")
@ -305,20 +313,67 @@ EOF
env
end
# Run block with environment present before Bundler was activated
def with_original_env
with_env(original_env) { yield }
end
# @deprecated Use `with_unbundled_env` instead
def with_clean_env
with_env(clean_env) { yield }
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`"
)
with_env(unbundled_env) { yield }
end
# Run block with all bundler-related variables removed
def with_unbundled_env
with_env(unbundled_env) { yield }
end
# Run subcommand with the environment present before Bundler was activated
def original_system(*args)
with_original_env { Kernel.system(*args) }
end
# @deprecated Use `unbundled_system` instead
def clean_system(*args)
with_clean_env { Kernel.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`"
)
with_env(unbundled_env) { Kernel.system(*args) }
end
# Run subcommand in an environment with all bundler related variables removed
def unbundled_system(*args)
with_unbundled_env { Kernel.system(*args) }
end
# Run a `Kernel.exec` to a subcommand with the environment present before Bundler was activated
def original_exec(*args)
with_original_env { Kernel.exec(*args) }
end
# @deprecated Use `unbundled_exec` instead
def clean_exec(*args)
with_clean_env { Kernel.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`"
)
with_env(unbundled_env) { Kernel.exec(*args) }
end
# Run a `Kernel.exec` to a subcommand in an environment with all bundler related variables removed
def unbundled_exec(*args)
with_env(unbundled_env) { Kernel.exec(*args) }
end
def local_platform
@ -343,7 +398,7 @@ EOF
# system binaries. If you put '-n foo' in your .gemrc, RubyGems will
# install binstubs there instead. Unfortunately, RubyGems doesn't expose
# that directory at all, so rather than parse .gemrc ourselves, we allow
# the directory to be set as well, via `bundle config bindir foo`.
# the directory to be set as well, via `bundle config set bindir foo`.
Bundler.settings[:system_bindir] || Bundler.rubygems.gem_bindir
end
@ -523,7 +578,7 @@ EOF
rescue ScriptError, StandardError => e
msg = "There was an error while loading `#{path.basename}`: #{e.message}"
if e.is_a?(LoadError) && RUBY_VERSION >= "1.9"
if e.is_a?(LoadError)
msg += "\nDoes it try to require a relative path? That's been removed in Ruby 1.9"
end

View file

@ -1,4 +1,3 @@
# coding: utf-8
# frozen_string_literal: true
begin
@ -19,16 +18,16 @@ Gem::Specification.new do |s|
"Yehuda Katz"
]
s.email = ["team@bundler.io"]
s.homepage = "http://bundler.io"
s.homepage = "https://bundler.io"
s.summary = "The best way to manage your application's dependencies"
s.description = "Bundler manages an application's dependencies through its entire life, across many machines, systematically and repeatably"
if s.respond_to?(:metadata=)
s.metadata = {
"bug_tracker_uri" => "http://github.com/bundler/bundler/issues",
"bug_tracker_uri" => "https://github.com/bundler/bundler/issues",
"changelog_uri" => "https://github.com/bundler/bundler/blob/master/CHANGELOG.md",
"homepage_uri" => "https://bundler.io/",
"source_code_uri" => "http://github.com/bundler/bundler/",
"source_code_uri" => "https://github.com/bundler/bundler/",
}
end
@ -41,14 +40,12 @@ Gem::Specification.new do |s|
end
s.add_development_dependency "automatiek", "~> 0.1.0"
s.add_development_dependency "mustache", "0.99.6"
s.add_development_dependency "rake", "~> 10.0"
s.add_development_dependency "rdiscount", "~> 2.2"
s.add_development_dependency "rake", "~> 12.0"
s.add_development_dependency "ronn", "~> 0.7.3"
s.add_development_dependency "rspec", "~> 3.6"
s.add_development_dependency "rubocop", "= 0.65.0"
# base_dir = File.dirname(__FILE__).gsub(%r{([^A-Za-z0-9_\-.,:\/@\n])}, "\\\\\\1")
# s.files = IO.popen("git -C #{base_dir} ls-files -z", &:read).split("\x0").select {|f| f.match(%r{^(lib|exe)/}) }
# s.files = Dir.glob("{lib,exe}/**/*", File::FNM_DOTMATCH).reject {|f| File.directory?(f) }
# 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.

View file

@ -1,7 +1,7 @@
# frozen_string_literal: true
require "bundler/shared_helpers"
Bundler::SharedHelpers.major_deprecation 3,
Bundler::SharedHelpers.major_deprecation 2,
"The Bundler task for Capistrano. Please use http://github.com/capistrano/bundler"
# Capistrano task for Bundler.

View file

@ -16,7 +16,7 @@ module Bundler
def self.start(*)
super
rescue Exception => e
rescue Exception => e # rubocop:disable Lint/RescueException
Bundler.ui = UI::Shell.new
raise e
ensure
@ -61,11 +61,6 @@ module Bundler
end
end
def self.deprecated_option(*args, &blk)
return if Bundler.feature_flag.forget_cli_options?
method_option(*args, &blk)
end
check_unknown_options!(:except => [:config, :exec])
stop_on_unknown_option! :exec
@ -142,7 +137,7 @@ module Bundler
Gemfile to a gem with a gemspec, the --gemspec option will automatically add each
dependency listed in the gemspec file to the newly created Gemfile.
D
deprecated_option "gemspec", :type => :string, :banner => "Use the specified .gemspec to create the Gemfile"
method_option "gemspec", :type => :string, :banner => "Use the specified .gemspec to create the Gemfile"
def init
require "bundler/cli/init"
Init.new(options.dup).run
@ -188,13 +183,13 @@ module Bundler
If the bundle has already been installed, bundler will tell you so and then exit.
D
deprecated_option "binstubs", :type => :string, :lazy_default => "bin", :banner =>
method_option "binstubs", :type => :string, :lazy_default => "bin", :banner =>
"Generate bin stubs for bundled gems to ./bin"
deprecated_option "clean", :type => :boolean, :banner =>
method_option "clean", :type => :boolean, :banner =>
"Run bundle clean automatically after install"
deprecated_option "deployment", :type => :boolean, :banner =>
method_option "deployment", :type => :boolean, :banner =>
"Install using defaults tuned for deployment environments"
deprecated_option "frozen", :type => :boolean, :banner =>
method_option "frozen", :type => :boolean, :banner =>
"Do not allow the Gemfile.lock to be updated after this install"
method_option "full-index", :type => :boolean, :banner =>
"Fall back to using the single-file index of all gems"
@ -204,32 +199,37 @@ module Bundler
"Specify the number of jobs to run in parallel"
method_option "local", :type => :boolean, :banner =>
"Do not attempt to fetch gems remotely and use the gem cache instead"
deprecated_option "no-cache", :type => :boolean, :banner =>
method_option "no-cache", :type => :boolean, :banner =>
"Don't update the existing gem cache."
method_option "redownload", :type => :boolean, :aliases => "--force", :banner =>
"Force downloading every gem."
deprecated_option "no-prune", :type => :boolean, :banner =>
method_option "no-prune", :type => :boolean, :banner =>
"Don't remove stale gems from the cache."
deprecated_option "path", :type => :string, :banner =>
method_option "path", :type => :string, :banner =>
"Specify a different path than the system default ($BUNDLE_PATH or $GEM_HOME). Bundler will remember this value for future installs on this machine"
method_option "quiet", :type => :boolean, :banner =>
"Only output warnings and errors."
deprecated_option "shebang", :type => :string, :banner =>
method_option "shebang", :type => :string, :banner =>
"Specify a different shebang executable name than the default (usually 'ruby')"
method_option "standalone", :type => :array, :lazy_default => [], :banner =>
"Make a bundle that can work without the Bundler runtime"
deprecated_option "system", :type => :boolean, :banner =>
method_option "system", :type => :boolean, :banner =>
"Install to the system location ($BUNDLE_PATH or $GEM_HOME) even if the bundle was previously installed somewhere else for this application"
method_option "trust-policy", :alias => "P", :type => :string, :banner =>
"Gem trust policy (like gem install -P). Must be one of " +
Bundler.rubygems.security_policy_keys.join("|")
deprecated_option "without", :type => :array, :banner =>
method_option "without", :type => :array, :banner =>
"Exclude gems that are part of the specified named group."
deprecated_option "with", :type => :array, :banner =>
method_option "with", :type => :array, :banner =>
"Include gems that are part of the specified named group."
map "i" => "install"
def install
SharedHelpers.major_deprecation(3, "The `--force` option has been renamed to `--redownload`") if ARGV.include?("--force")
SharedHelpers.major_deprecation(2, "The `--force` option has been renamed to `--redownload`") if ARGV.include?("--force")
%w[clean deployment frozen no-cache no-prune path shebang system without with].each do |option|
remembered_flag_deprecation(option)
end
require "bundler/cli/install"
Bundler.settings.temporary(:no_install => false) do
Install.new(options.dup).run
@ -275,57 +275,60 @@ module Bundler
method_option "all", :type => :boolean, :banner =>
"Update everything."
def update(*gems)
SharedHelpers.major_deprecation(3, "The `--force` option has been renamed to `--redownload`") if ARGV.include?("--force")
SharedHelpers.major_deprecation(2, "The `--force` option has been renamed to `--redownload`") if ARGV.include?("--force")
require "bundler/cli/update"
Update.new(options, gems).run
Bundler.settings.temporary(:no_install => false) do
Update.new(options, gems).run
end
end
desc "show GEM [OPTIONS]", "Shows all gems that are part of the bundle, or the path to a given gem"
long_desc <<-D
Show lists the names and versions of all gems that are required by your Gemfile.
Calling show with [GEM] will list the exact location of that gem on your machine.
D
method_option "paths", :type => :boolean,
:banner => "List the paths of all gems that are required by your Gemfile."
method_option "outdated", :type => :boolean,
:banner => "Show verbose output including whether gems are outdated."
def show(gem_name = nil)
if ARGV[0] == "show"
rest = ARGV[1..-1]
unless Bundler.feature_flag.bundler_3_mode?
desc "show GEM [OPTIONS]", "Shows all gems that are part of the bundle, or the path to a given gem"
long_desc <<-D
Show lists the names and versions of all gems that are required by your Gemfile.
Calling show with [GEM] will list the exact location of that gem on your machine.
D
method_option "paths", :type => :boolean,
:banner => "List the paths of all gems that are required by your Gemfile."
method_option "outdated", :type => :boolean,
:banner => "Show verbose output including whether gems are outdated."
def show(gem_name = nil)
if ARGV[0] == "show"
rest = ARGV[1..-1]
new_command = rest.find {|arg| !arg.start_with?("--") } ? "info" : "list"
if flag = rest.find{|arg| ["--verbose", "--outdated"].include?(arg) }
Bundler::SharedHelpers.major_deprecation(2, "the `#{flag}` flag to `bundle show` was undocumented and will be removed without replacement")
else
new_command = rest.find {|arg| !arg.start_with?("--") } ? "info" : "list"
new_arguments = rest.map do |arg|
next arg if arg != "--paths"
next "--path" if new_command == "info"
new_arguments = rest.map do |arg|
next arg if arg != "--paths"
next "--path" if new_command == "info"
end
old_argv = ARGV.join(" ")
new_argv = [new_command, *new_arguments.compact].join(" ")
Bundler::SharedHelpers.major_deprecation(2, "use `bundle #{new_argv}` instead of `bundle #{old_argv}`")
end
end
old_argv = ARGV.join(" ")
new_argv = [new_command, *new_arguments.compact].join(" ")
Bundler::SharedHelpers.major_deprecation(3, "use `bundle #{new_argv}` instead of `bundle #{old_argv}`")
require "bundler/cli/show"
Show.new(options, gem_name).run
end
require "bundler/cli/show"
Show.new(options, gem_name).run
end
# TODO: 2.0 remove `bundle show`
if Bundler.feature_flag.list_command?
desc "list", "List all gems in the bundle"
method_option "name-only", :type => :boolean, :banner => "print only the gem names"
method_option "only-group", :type => :string, :banner => "print gems from a particular group"
method_option "without-group", :type => :string, :banner => "print all gems expect from a group"
method_option "paths", :type => :boolean, :banner => "print the path to each gem in the bundle"
def list
require "bundler/cli/list"
List.new(options).run
end
map %w[ls] => "list"
else
map %w[list] => "show"
desc "list", "List all gems in the bundle"
method_option "name-only", :type => :boolean, :banner => "print only the gem names"
method_option "only-group", :type => :string, :banner => "print gems from a particular group"
method_option "without-group", :type => :string, :banner => "print all gems except from a group"
method_option "paths", :type => :boolean, :banner => "print the path to each gem in the bundle"
def list
require "bundler/cli/list"
List.new(options).run
end
map %w[ls] => "list"
desc "info GEM [OPTIONS]", "Show information for the given gem"
method_option "path", :type => :boolean, :banner => "Print full path to gem"
def info(gem_name)
@ -386,9 +389,10 @@ module Bundler
"Do not attempt to fetch gems remotely and use the gem cache instead"
method_option "pre", :type => :boolean, :banner => "Check for newer pre-release gems"
method_option "source", :type => :array, :banner => "Check against a specific source"
method_option "strict", :type => :boolean, :banner =>
strict_is_update = Bundler.feature_flag.forget_cli_options?
method_option "filter-strict", :type => :boolean, :aliases => strict_is_update ? [] : %w[--strict], :banner =>
"Only list newer versions allowed by your Gemfile requirements"
method_option "update-strict", :type => :boolean, :banner =>
method_option "update-strict", :type => :boolean, :aliases => strict_is_update ? %w[--strict] : [], :banner =>
"Strict conservative resolution, do not allow any gem to be updated past latest --patch | --minor | --major"
method_option "minor", :type => :boolean, :banner => "Prefer updating only to next minor version"
method_option "major", :type => :boolean, :banner => "Prefer updating to next major version (default)"
@ -475,11 +479,8 @@ module Bundler
will show the current value, as well as any superceded values and
where they were specified.
D
method_option "parseable", :type => :boolean, :banner => "Use minimal formatting for more parseable output"
def config(*args)
require "bundler/cli/config"
Config.new(options, args, self).run
end
require "bundler/cli/config"
subcommand "config", Config
desc "open GEM", "Opens the source directory of the given bundled gem"
def open(name)
@ -487,7 +488,7 @@ module Bundler
Open.new(options, name).run
end
if Bundler.feature_flag.console_command?
unless Bundler.feature_flag.bundler_3_mode?
desc "console [GROUP]", "Opens an IRB session with the bundle pre-loaded"
def console(group = nil)
require "bundler/cli/console"
@ -524,7 +525,7 @@ module Bundler
end
end
if Bundler.feature_flag.viz_command?
unless Bundler.feature_flag.bundler_3_mode?
desc "viz [OPTIONS]", "Generates a visual dependency graph", :hide => true
long_desc <<-D
Viz generates a PNG file of the current Gemfile as a dependency graph.
@ -537,7 +538,7 @@ module Bundler
method_option :version, :type => :boolean, :default => false, :aliases => "-v", :desc => "Set to show each gem version."
method_option :without, :type => :array, :default => [], :aliases => "-W", :banner => "GROUP[ GROUP...]", :desc => "Exclude gems that are part of the specified named group."
def viz
SharedHelpers.major_deprecation 3, "The `viz` command has been moved to the `bundle-viz` gem, see https://github.com/bundler/bundler-viz"
SharedHelpers.major_deprecation 2, "The `viz` command has been moved to the `bundle-viz` gem, see https://github.com/bundler/bundler-viz"
require "bundler/cli/viz"
Viz.new(options.dup).run
end
@ -547,14 +548,14 @@ module Bundler
desc "gem NAME [OPTIONS]", "Creates a skeleton for creating a rubygem"
method_option :exe, :type => :boolean, :default => false, :aliases => ["--bin", "-b"], :desc => "Generate a binary executable for your library."
method_option :coc, :type => :boolean, :desc => "Generate a code of conduct file. Set a default with `bundle config gem.coc true`."
method_option :coc, :type => :boolean, :desc => "Generate a code of conduct file. Set a default with `bundle config set gem.coc true`."
method_option :edit, :type => :string, :aliases => "-e", :required => false, :banner => "EDITOR",
:lazy_default => [ENV["BUNDLER_EDITOR"], ENV["VISUAL"], ENV["EDITOR"]].find {|e| !e.nil? && !e.empty? },
:desc => "Open generated gemspec in the specified editor (defaults to $EDITOR or $BUNDLER_EDITOR)"
method_option :ext, :type => :boolean, :default => false, :desc => "Generate the boilerplate for C extension code"
method_option :mit, :type => :boolean, :desc => "Generate an MIT license file. Set a default with `bundle config gem.mit true`."
method_option :mit, :type => :boolean, :desc => "Generate an MIT license file. Set a default with `bundle config set gem.mit true`."
method_option :test, :type => :string, :lazy_default => "rspec", :aliases => "-t", :banner => "rspec",
:desc => "Generate a test directory for your library, either rspec or minitest. Set a default with `bundle config gem.test rspec`."
:desc => "Generate a test directory for your library, either rspec or minitest. Set a default with `bundle config set gem.test rspec`."
def gem(name)
end
@ -608,7 +609,7 @@ module Bundler
method_option "group", :type => :string, :banner =>
"Install gem into a bundler group"
def inject(name, version)
SharedHelpers.major_deprecation 3, "The `inject` command has been replaced by the `add` command"
SharedHelpers.major_deprecation 2, "The `inject` command has been replaced by the `add` command"
require "bundler/cli/inject"
Inject.new(options.dup, name, version).run
end
@ -620,6 +621,8 @@ module Bundler
"do not attempt to fetch remote gemspecs and use the local gem cache only"
method_option "print", :type => :boolean, :default => false, :banner =>
"print the lockfile to STDOUT instead of writing to the file system"
method_option "gemfile", :type => :string, :banner =>
"Use the specified gemfile instead of Gemfile"
method_option "lockfile", :type => :string, :default => nil, :banner =>
"the path the lockfile should be written to"
method_option "full-index", :type => :boolean, :default => false, :banner =>
@ -714,7 +717,7 @@ module Bundler
# Automatically invoke `bundle install` and resume if
# Bundler.settings[:auto_install] exists. This is set through config cmd
# `bundle config auto_install 1`.
# `bundle config set auto_install 1`.
#
# Note that this method `nil`s out the global Definition object, so it
# should be called first, before you instantiate anything like an
@ -786,5 +789,22 @@ module Bundler
rescue RuntimeError
nil
end
def remembered_flag_deprecation(name)
option = current_command.options[name]
flag_name = option.switch_name
name_index = ARGV.find {|arg| flag_name == arg }
return unless name_index
value = options[name]
value = value.join(" ").to_s if option.type == :array
Bundler::SharedHelpers.major_deprecation 2,\
"The `#{flag_name}` flag is deprecated because it relies on being " \
"remembered accross bundler invokations, which bundler will no longer " \
"do in future versions. Instead please use `bundle config #{name} " \
"'#{value}'`, and stop using this flag"
end
end
end

View file

@ -29,7 +29,7 @@ module Bundler
if Bundler.definition.has_local_dependencies? && !Bundler.feature_flag.cache_all?
Bundler.ui.warn "Your Gemfile contains path and git dependencies. If you want " \
"to package them as well, please pass the --all flag. This will be the default " \
"on Bundler 2.0."
"on Bundler 3.0."
end
end
end

View file

@ -23,7 +23,7 @@ module Bundler
groups = Bundler.settings[:without]
group_list = [groups[0...-1].join(", "), groups[-1..-1]].
reject {|s| s.to_s.empty? }.join(" and ")
group_str = (groups.size == 1) ? "group" : "groups"
group_str = groups.size == 1 ? "group" : "groups"
"Gems in the #{group_str} #{group_list} were not installed."
end
@ -49,10 +49,6 @@ module Bundler
end
def self.ask_for_spec_from(specs)
if !$stdout.tty? && ENV["BUNDLE_SPEC_RUN"].nil?
raise GemNotFound, gem_not_found_message(name, Bundler.definition.dependencies)
end
specs.each_with_index do |spec, index|
Bundler.ui.info "#{index.succ} : #{spec.name}", true
end
@ -72,7 +68,7 @@ module Bundler
end
def self.ensure_all_gems_in_lockfile!(names, locked_gems = Bundler.locked_gems)
locked_names = locked_gems.specs.map(&:name)
locked_names = locked_gems.specs.map(&:name).uniq
names.-(locked_names).each do |g|
raise GemNotFound, gem_not_found_message(g, locked_names)
end
@ -80,10 +76,12 @@ module Bundler
def self.configure_gem_version_promoter(definition, options)
patch_level = patch_level_options(options)
patch_level << :patch if patch_level.empty? && Bundler.settings[:prefer_patch]
raise InvalidOption, "Provide only one of the following options: #{patch_level.join(", ")}" unless patch_level.length <= 1
definition.gem_version_promoter.tap do |gvp|
gvp.level = patch_level.first || :major
gvp.strict = options[:strict] || options["update-strict"]
gvp.strict = options[:strict] || options["update-strict"] || options["filter-strict"]
end
end

View file

@ -1,119 +1,194 @@
# frozen_string_literal: true
module Bundler
class CLI::Config
attr_reader :name, :options, :scope, :thor
attr_accessor :args
class CLI::Config < Thor
class_option :parseable, :type => :boolean, :banner => "Use minimal formatting for more parseable output"
def initialize(options, args, thor)
@options = options
@args = args
@thor = thor
@name = peek = args.shift
@scope = "global"
return unless peek && peek.start_with?("--")
@name = args.shift
@scope = peek[2..-1]
def self.scope_options
method_option :global, :type => :boolean, :banner => "Only change the global config"
method_option :local, :type => :boolean, :banner => "Only change the local config"
end
private_class_method :scope_options
desc "base NAME [VALUE]", "The Bundler 1 config interface", :hide => true
scope_options
method_option :delete, :type => :boolean, :banner => "delete"
def base(name = nil, *value)
new_args =
if ARGV.size == 1
["config", "list"]
elsif ARGV.include?("--delete")
ARGV.map {|arg| arg == "--delete" ? "unset" : arg }
elsif ARGV.include?("--global") || ARGV.include?("--local") || ARGV.size == 3
["config", "set", *ARGV[1..-1]]
else
["config", "get", ARGV[1]]
end
SharedHelpers.major_deprecation 2,
"Using the `config` command without a subcommand [list, get, set, unset] is deprecated and will be removed in the future. Use `bundle #{new_args.join(" ")}` instead."
Base.new(options, name, value, self).run
end
def run
unless name
confirm_all
return
desc "list", "List out all configured settings"
def list
Base.new(options, nil, nil, self).run
end
desc "get NAME", "Returns the value for the given key"
def get(name)
Base.new(options, name, nil, self).run
end
desc "set NAME VALUE", "Sets the given value for the given key"
scope_options
def set(name, value, *value_)
Base.new(options, name, value_.unshift(value), self).run
end
desc "unset NAME", "Unsets the value for the given key"
scope_options
def unset(name)
options[:delete] = true
Base.new(options, name, nil, self).run
end
default_task :base
class Base
attr_reader :name, :value, :options, :scope, :thor
def initialize(options, name, value, thor)
@options = options
@name = name
value = Array(value)
@value = value.empty? ? nil : value.join(" ")
@thor = thor
validate_scope!
end
unless valid_scope?(scope)
Bundler.ui.error "Invalid scope --#{scope} given. Please use --local or --global."
exit 1
end
def run
unless name
warn_unused_scope "Ignoring --#{scope}"
confirm_all
return
end
if scope == "delete"
Bundler.settings.set_local(name, nil)
Bundler.settings.set_global(name, nil)
return
end
if args.empty?
if options[:parseable]
if value = Bundler.settings[name]
Bundler.ui.info("#{name}=#{value}")
if options[:delete]
if !explicit_scope? || scope != "global"
Bundler.settings.set_local(name, nil)
end
if !explicit_scope? || scope != "local"
Bundler.settings.set_global(name, nil)
end
return
end
confirm(name)
return
if value.nil?
warn_unused_scope "Ignoring --#{scope} since no value to set was given"
if options[:parseable]
if value = Bundler.settings[name]
Bundler.ui.info("#{name}=#{value}")
end
return
end
confirm(name)
return
end
Bundler.ui.info(message) if message
Bundler.settings.send("set_#{scope}", name, new_value)
end
Bundler.ui.info(message) if message
Bundler.settings.send("set_#{scope}", name, new_value)
end
private
def confirm_all
if @options[:parseable]
thor.with_padding do
def confirm_all
if @options[:parseable]
thor.with_padding do
Bundler.settings.all.each do |setting|
val = Bundler.settings[setting]
Bundler.ui.info "#{setting}=#{val}"
end
end
else
Bundler.ui.confirm "Settings are listed in order of priority. The top value will be used.\n"
Bundler.settings.all.each do |setting|
val = Bundler.settings[setting]
Bundler.ui.info "#{setting}=#{val}"
Bundler.ui.confirm "#{setting}"
show_pretty_values_for(setting)
Bundler.ui.confirm ""
end
end
else
Bundler.ui.confirm "Settings are listed in order of priority. The top value will be used.\n"
Bundler.settings.all.each do |setting|
Bundler.ui.confirm "#{setting}"
show_pretty_values_for(setting)
Bundler.ui.confirm ""
end
def confirm(name)
Bundler.ui.confirm "Settings for `#{name}` in order of priority. The top value will be used"
show_pretty_values_for(name)
end
def new_value
pathname = Pathname.new(value)
if name.start_with?("local.") && pathname.directory?
pathname.expand_path.to_s
else
value
end
end
end
def confirm(name)
Bundler.ui.confirm "Settings for `#{name}` in order of priority. The top value will be used"
show_pretty_values_for(name)
end
def new_value
pathname = Pathname.new(args.join(" "))
if name.start_with?("local.") && pathname.directory?
pathname.expand_path.to_s
else
args.join(" ")
end
end
def message
locations = Bundler.settings.locations(name)
if @options[:parseable]
"#{name}=#{new_value}" if new_value
elsif scope == "global"
if locations[:local]
"Your application has set #{name} to #{locations[:local].inspect}. " \
"This will override the global value you are currently setting"
elsif locations[:env]
"You have a bundler environment variable for #{name} set to " \
"#{locations[:env].inspect}. This will take precedence over the global value you are setting"
elsif locations[:global] && locations[:global] != args.join(" ")
"You are replacing the current global value of #{name}, which is currently " \
"#{locations[:global].inspect}"
end
elsif scope == "local" && locations[:local] != args.join(" ")
"You are replacing the current local value of #{name}, which is currently " \
"#{locations[:local].inspect}"
end
end
def show_pretty_values_for(setting)
thor.with_padding do
Bundler.settings.pretty_values_for(setting).each do |line|
Bundler.ui.info line
def message
locations = Bundler.settings.locations(name)
if @options[:parseable]
"#{name}=#{new_value}" if new_value
elsif scope == "global"
if !locations[:local].nil?
"Your application has set #{name} to #{locations[:local].inspect}. " \
"This will override the global value you are currently setting"
elsif locations[:env]
"You have a bundler environment variable for #{name} set to " \
"#{locations[:env].inspect}. This will take precedence over the global value you are setting"
elsif !locations[:global].nil? && locations[:global] != value
"You are replacing the current global value of #{name}, which is currently " \
"#{locations[:global].inspect}"
end
elsif scope == "local" && !locations[:local].nil? && locations[:local] != value
"You are replacing the current local value of #{name}, which is currently " \
"#{locations[:local].inspect}"
end
end
end
def valid_scope?(scope)
%w[delete local global].include?(scope)
def show_pretty_values_for(setting)
thor.with_padding do
Bundler.settings.pretty_values_for(setting).each do |line|
Bundler.ui.info line
end
end
end
def explicit_scope?
@explicit_scope
end
def warn_unused_scope(msg)
return unless explicit_scope?
return if options[:parseable]
Bundler.ui.warn(msg)
end
def validate_scope!
@explicit_scope = true
scopes = %w[global local].select {|s| options[s] }
case scopes.size
when 0
@scope = "global"
@explicit_scope = false
when 1
@scope = scopes.first
else
raise InvalidOption,
"The options #{scopes.join " and "} were specified. Please only use one of the switches at a time."
end
end
end
end
end

View file

@ -9,10 +9,10 @@ module Bundler
end
def run
Bundler::SharedHelpers.major_deprecation 3, "bundle console will be replaced " \
Bundler::SharedHelpers.major_deprecation 2, "bundle console will be replaced " \
"by `bin/console` generated by `bundle gem <name>`"
group ? Bundler.require(:default, *(group.split.map!(&:to_sym))) : Bundler.require
group ? Bundler.require(:default, *group.split.map!(&:to_sym)) : Bundler.require
ARGV.clear
console = get_console(Bundler.settings[:console] || "irb")

View file

@ -4,8 +4,8 @@ require "rbconfig"
module Bundler
class CLI::Doctor
DARWIN_REGEX = /\s+(.+) \(compatibility /
LDD_REGEX = /\t\S+ => (\S+) \(\S+\)/
DARWIN_REGEX = /\s+(.+) \(compatibility /.freeze
LDD_REGEX = /\t\S+ => (\S+) \(\S+\)/.freeze
attr_reader :options

View file

@ -11,7 +11,7 @@ module Bundler
class CLI::Gem
TEST_FRAMEWORK_VERSIONS = {
"rspec" => "3.0",
"minitest" => "5.0"
"minitest" => "5.0",
}.freeze
attr_reader :options, :gem_name, :thor, :name, :target
@ -57,7 +57,7 @@ module Bundler
:ext => options[:ext],
:exe => options[:exe],
:bundler_version => bundler_dependency_version,
:github_username => github_username.empty? ? "[USERNAME]" : github_username
:github_username => github_username.empty? ? "[USERNAME]" : github_username,
}
ensure_safe_gem_name(name, constant_array)
@ -69,7 +69,7 @@ module Bundler
"Rakefile.tt" => "Rakefile",
"README.md.tt" => "README.md",
"bin/console.tt" => "bin/console",
"bin/setup.tt" => "bin/setup"
"bin/setup.tt" => "bin/setup",
}
executables = %w[

View file

@ -9,18 +9,24 @@ module Bundler
end
def run
Bundler.ui.silence do
Bundler.definition.validate_runtime!
Bundler.load.lock
end
spec = spec_for_gem(gem_name)
spec_not_found(gem_name) unless spec
return print_gem_path(spec) if @options[:path]
print_gem_info(spec)
if spec
return print_gem_path(spec) if @options[:path]
print_gem_info(spec)
end
end
private
def spec_for_gem(gem_name)
spec = Bundler.definition.specs.find {|s| s.name == gem_name }
spec || default_gem_spec(gem_name)
spec || default_gem_spec(gem_name) || Bundler::CLI::Common.select_spec(gem_name, :regex_match)
end
def default_gem_spec(gem_name)
@ -34,7 +40,13 @@ module Bundler
end
def print_gem_path(spec)
Bundler.ui.info spec.full_gem_path
path = if spec.name == "bundler"
File.expand_path("../../../..", __FILE__)
else
spec.full_gem_path
end
Bundler.ui.info path
end
def print_gem_info(spec)

View file

@ -41,7 +41,7 @@ module Bundler
private
def gemfile
@gemfile ||= Bundler.feature_flag.init_gems_rb? ? "gems.rb" : "Gemfile"
@gemfile ||= Bundler.settings[:init_gems_rb] ? "gems.rb" : "Gemfile"
end
end
end

View file

@ -53,7 +53,7 @@ module Bundler
Bundler::Fetcher.disable_endpoint = options["full-index"]
if options["binstubs"]
Bundler::SharedHelpers.major_deprecation 3,
Bundler::SharedHelpers.major_deprecation 2,
"The --binstubs option will be removed in favor of `bundle binstubs`"
end
@ -202,15 +202,16 @@ module Bundler
end
def warn_ambiguous_gems
# TODO: remove this when we drop Bundler 1.x support
Installer.ambiguous_gems.to_a.each do |name, installed_from_uri, *also_found_in_uris|
Bundler.ui.error "Warning: the gem '#{name}' was found in multiple sources."
Bundler.ui.error "Installed from: #{installed_from_uri}"
Bundler.ui.error "Also found in:"
also_found_in_uris.each {|uri| Bundler.ui.error " * #{uri}" }
Bundler.ui.error "You should add a source requirement to restrict this gem to your preferred source."
Bundler.ui.error "For example:"
Bundler.ui.error " gem '#{name}', :source => '#{installed_from_uri}'"
Bundler.ui.error "Then uninstall the gem '#{name}' (or delete all bundled gems) and then install again."
Bundler.ui.warn "Warning: the gem '#{name}' was found in multiple sources."
Bundler.ui.warn "Installed from: #{installed_from_uri}"
Bundler.ui.warn "Also found in:"
also_found_in_uris.each {|uri| Bundler.ui.warn " * #{uri}" }
Bundler.ui.warn "You should add a source requirement to restrict this gem to your preferred source."
Bundler.ui.warn "For example:"
Bundler.ui.warn " gem '#{name}', :source => '#{installed_from_uri}'"
Bundler.ui.warn "Then uninstall the gem '#{name}' (or delete all bundled gems) and then install again."
end
end
end

View file

@ -13,10 +13,10 @@ module Bundler
https://github.com/bundler/bundler/blob/master/doc/TROUBLESHOOTING.md
2. Instructions for common Bundler uses can be found on the documentation
site: http://bundler.io/
site: https://bundler.io/
3. Information about each Bundler command can be found in the Bundler
man pages: http://bundler.io/man/bundle.1.html
man pages: https://bundler.io/man/bundle.1.html
Hopefully the troubleshooting steps above resolved your problem! If things
still aren't working the way you expect them to, please let us know so

View file

@ -41,7 +41,7 @@ module Bundler
# the patch level options imply strict is also true. It wouldn't make
# sense otherwise.
strict = options[:strict] ||
strict = options["filter-strict"] ||
Bundler::CLI::Common.patch_level_options(options).any?
filter_options_patch = options.keys &
@ -124,7 +124,7 @@ module Bundler
[nil, ordered_groups].flatten.each do |groups|
gems = outdated_gems_by_groups[groups]
contains_group = if groups
groups.split(",").include?(options[:group])
groups.split(", ").include?(options[:group])
else
options[:group] == "group"
end
@ -221,9 +221,9 @@ module Bundler
def check_for_deployment_mode
return unless Bundler.frozen_bundle?
suggested_command = if Bundler.settings.locations("frozen")[:global]
"bundle config --delete frozen"
"bundle config unset frozen"
elsif Bundler.settings.locations("deployment").keys.&([:global, :local]).any?
"bundle config --delete deployment"
"bundle config unset deployment"
else
"bundle install --no-deployment"
end

View file

@ -42,7 +42,7 @@ module Bundler
if Bundler.definition.has_local_dependencies? && !Bundler.feature_flag.cache_all?
Bundler.ui.warn "Your Gemfile contains path and git dependencies. If you want " \
"to package them as well, please pass the --all flag. This will be the default " \
"on Bundler 2.0."
"on Bundler 3.0."
end
end
end

View file

@ -5,7 +5,7 @@ module Bundler
class CLI::Plugin < Thor
desc "install PLUGINS", "Install the plugin from the source"
long_desc <<-D
Install plugins either from the rubygems source provided (with --source option) or from a git source provided with (--git option). If no sources are provided, it uses Gem.sources
Install plugins either from the rubygems source provided (with --source option) or from a git source provided with --git (for remote repos) or --local_git (for local repos). If no sources are provided, it uses Gem.sources
D
method_option "source", :type => :string, :default => nil, :banner =>
"URL of the RubyGems source to fetch the plugin from"
@ -13,6 +13,8 @@ module Bundler
"The version of the plugin to fetch"
method_option "git", :type => :string, :default => nil, :banner =>
"URL of the git repo to fetch from"
method_option "local_git", :type => :string, :default => nil, :banner =>
"Path of the local git repo to fetch from"
method_option "branch", :type => :string, :default => nil, :banner =>
"The git branch to checkout"
method_option "ref", :type => :string, :default => nil, :banner =>
@ -20,5 +22,10 @@ module Bundler
def install(*plugins)
Bundler::Plugin.install(plugins, options)
end
desc "list", "List the installed plugins and available commands"
def list
Bundler::Plugin.list
end
end
end

View file

@ -33,7 +33,7 @@ module Bundler
if extension_cache_path = source.extension_cache_path(spec)
FileUtils.rm_rf extension_cache_path
end
FileUtils.rm_rf spec.extension_dir if spec.respond_to?(:extension_dir)
FileUtils.rm_rf spec.extension_dir
FileUtils.rm_rf spec.full_gem_path
else
Bundler.ui.warn("Cannot pristine #{gem_name}. Gem is sourced from local path.")

View file

@ -24,7 +24,7 @@ module Bundler
return unless spec
path = spec.full_gem_path
unless File.directory?(path)
Bundler.ui.warn "The gem #{gem_name} has been deleted. It was installed at:"
return Bundler.ui.warn "The gem #{gem_name} has been deleted. It was installed at: #{path}"
end
end
return Bundler.ui.info(path)

View file

@ -22,7 +22,7 @@ module Bundler
if Bundler.feature_flag.update_requires_all_flag?
raise InvalidOption, "To update everything, pass the `--all` flag."
end
SharedHelpers.major_deprecation 3, "Pass --all to `bundle update` to update everything"
SharedHelpers.major_deprecation 2, "Pass --all to `bundle update` to update everything"
elsif !full_update && options[:all]
raise InvalidOption, "Cannot specify --all along with specific options."
end

View file

@ -18,11 +18,6 @@ module Bundler
attr_reader :directory
# @return [Lambda] A lambda that takes an array of inputs and a block, and
# maps the inputs with the block in parallel.
#
attr_accessor :in_parallel
def initialize(directory, fetcher)
@directory = Pathname.new(directory)
@updater = Updater.new(fetcher)
@ -31,7 +26,28 @@ module Bundler
@info_checksums_by_name = {}
@parsed_checksums = false
@mutex = Mutex.new
@in_parallel = lambda do |inputs, &blk|
end
def execution_mode=(block)
Bundler::CompactIndexClient.debug { "execution_mode=" }
@endpoints = Set.new
@execution_mode = block
end
# @return [Lambda] A lambda that takes an array of inputs and a block, and
# maps the inputs with the block in parallel.
#
def execution_mode
@execution_mode || sequentially
end
def sequential_execution_mode!
self.execution_mode = sequentially
end
def sequentially
@sequentially ||= lambda do |inputs, &blk|
inputs.map(&blk)
end
end
@ -51,7 +67,7 @@ module Bundler
def dependencies(names)
Bundler::CompactIndexClient.debug { "dependencies(#{names})" }
in_parallel.call(names) do |name|
execution_mode.call(names) do |name|
update_info(name)
@cache.dependencies(name).map {|d| d.unshift(name) }
end.flatten(1)

View file

@ -95,11 +95,7 @@ module Bundler
end
def slice_body(body, range)
if body.respond_to?(:byteslice)
body.byteslice(range)
else # pre-1.9.3
body.unpack("@#{range.first}a#{range.end + 1}").first
end
body.byteslice(range)
end
def checksum_for_file(path)

View file

@ -1,14 +1,9 @@
# frozen_string_literal: false
require "rubygems"
require "bundler/version"
if Bundler::VERSION.split(".").first.to_i >= 2
if Gem::Version.new(Object::RUBY_VERSION.dup) < Gem::Version.new("2.3")
abort "Bundler 2 requires Ruby 2.3 or later. Either install bundler 1 or update to a supported Ruby version."
end
if Gem::Version.new(Gem::VERSION.dup) < Gem::Version.new("2.5")
abort "Bundler 2 requires RubyGems 2.5 or later. Either install bundler 1 or update to a supported RubyGems version."
end
end

View file

@ -331,7 +331,7 @@ module Bundler
# i.e., Windows with `git config core.autocrlf=true`
contents.gsub!(/\n/, "\r\n") if @lockfile_contents.match("\r\n")
if @locked_bundler_version && Bundler.feature_flag.lockfile_upgrade_warning?
if @locked_bundler_version
locked_major = @locked_bundler_version.segments.first
current_major = Gem::Version.create(Bundler::VERSION).segments.first
@ -397,9 +397,9 @@ module Bundler
unless explicit_flag
suggested_command = if Bundler.settings.locations("frozen")[:global]
"bundle config --delete frozen"
"bundle config unset frozen"
elsif Bundler.settings.locations("deployment").keys.&([:global, :local]).any?
"bundle config --delete deployment"
"bundle config unset deployment"
else
"bundle install --no-deployment"
end
@ -643,7 +643,7 @@ module Bundler
end
def converge_rubygems_sources
return false if Bundler.feature_flag.lockfile_uses_separate_rubygems_sources?
return false if Bundler.feature_flag.disable_multisource?
changes = false
@ -855,8 +855,8 @@ module Bundler
concat_ruby_version_requirements(locked_ruby_version_object) unless @unlock[:ruby]
end
[
Dependency.new("ruby\0", ruby_versions),
Dependency.new("rubygems\0", Gem::VERSION),
Dependency.new("Ruby\0", ruby_versions),
Dependency.new("RubyGems\0", Gem::VERSION),
]
end
end
@ -915,7 +915,7 @@ module Bundler
# look for that gemspec (or its dependencies)
default = sources.default_source
source_requirements = { :default => default }
default = nil unless Bundler.feature_flag.lockfile_uses_separate_rubygems_sources?
default = nil unless Bundler.feature_flag.disable_multisource?
dependencies.each do |dep|
next unless source = dep.source || default
source_requirements[dep.name] = source
@ -929,7 +929,7 @@ module Bundler
def pinned_spec_names(skip = nil)
pinned_names = []
default = Bundler.feature_flag.lockfile_uses_separate_rubygems_sources? && sources.default_source
default = Bundler.feature_flag.disable_multisource? && sources.default_source
@dependencies.each do |dep|
next unless dep_source = dep.source || default
next if dep_source == skip
@ -977,7 +977,9 @@ module Bundler
dependencies_by_name = dependencies.inject({}) {|memo, dep| memo.update(dep.name => dep) }
@locked_gems.specs.reduce({}) do |requirements, locked_spec|
name = locked_spec.name
next requirements if @locked_gems.dependencies[name] != dependencies_by_name[name]
dependency = dependencies_by_name[name]
next requirements if @locked_gems.dependencies[name] != dependency
next requirements if dependency && dependency.source.is_a?(Source::Path)
dep = Gem::Dependency.new(name, ">= #{locked_spec.version}")
requirements[name] = DepProxy.new(dep, locked_spec.platform)
requirements

View file

@ -1,7 +1,7 @@
# frozen_string_literal: true
require "bundler/shared_helpers"
Bundler::SharedHelpers.major_deprecation 3, "Bundler no longer integrates with " \
Bundler::SharedHelpers.major_deprecation 2, "Bundler no longer integrates with " \
"Capistrano, but Capistrano provides its own integration with " \
"Bundler via the capistrano-bundler gem. Use it instead."

View file

@ -45,7 +45,7 @@ module Bundler
@gemfiles << expanded_gemfile_path
contents ||= Bundler.read_file(@gemfile.to_s)
instance_eval(contents.dup.untaint, gemfile.to_s, 1)
rescue Exception => e
rescue Exception => e # rubocop:disable Lint/RescueException
message = "There was an error " \
"#{e.is_a?(GemfileEvalError) ? "evaluating" : "parsing"} " \
"`#{File.basename gemfile.to_s}`: #{e.message}"
@ -194,7 +194,7 @@ module Bundler
" end\n\n"
raise DeprecatedError, msg if Bundler.feature_flag.disable_multisource?
SharedHelpers.major_deprecation(3, msg.strip)
SharedHelpers.major_deprecation(2, msg.strip)
end
source_options = normalize_hash(options).merge(
@ -290,37 +290,21 @@ module Bundler
warn_deprecated_git_source(:github, <<-'RUBY'.strip, 'Change any "reponame" :github sources to "username/reponame".')
"https://github.com/#{repo_name}.git"
RUBY
# It would be better to use https instead of the git protocol, but this
# can break deployment of existing locked bundles when switching between
# different versions of Bundler. The change will be made in 2.0, which
# does not guarantee compatibility with the 1.x series.
#
# See https://github.com/bundler/bundler/pull/2569 for discussion
#
# This can be overridden by adding this code to your Gemfiles:
#
# git_source(:github) do |repo_name|
# repo_name = "#{repo_name}/#{repo_name}" unless repo_name.include?("/")
# "https://github.com/#{repo_name}.git"
# end
repo_name = "#{repo_name}/#{repo_name}" unless repo_name.include?("/")
# TODO: 2.0 upgrade this setting to the default
if Bundler.settings["github.https"]
Bundler::SharedHelpers.major_deprecation 3, "The `github.https` setting will be removed"
if Bundler.feature_flag.github_https?
"https://github.com/#{repo_name}.git"
else
Bundler::SharedHelpers.major_deprecation 2, "Setting `github.https` to false is deprecated and won't be supported in the future."
"git://github.com/#{repo_name}.git"
end
end
# TODO: 2.0 remove this deprecated git source
git_source(:gist) do |repo_name|
warn_deprecated_git_source(:gist, '"https://gist.github.com/#{repo_name}.git"')
"https://gist.github.com/#{repo_name}.git"
end
# TODO: 2.0 remove this deprecated git source
git_source(:bitbucket) do |repo_name|
warn_deprecated_git_source(:bitbucket, <<-'RUBY'.strip)
user_name, repo_name = repo_name.split("/")
@ -363,9 +347,7 @@ repo_name ||= user_name
if name =~ /\s/
raise GemfileError, %('#{name}' is not a valid gem name because it contains whitespace)
end
if name.empty?
raise GemfileError, %(an empty gem name is not valid)
end
raise GemfileError, %(an empty gem name is not valid) if name.empty?
normalize_hash(opts)
@ -443,10 +425,10 @@ repo_name ||= user_name
message = String.new
message << "You passed #{invalid_keys.map {|k| ":" + k }.join(", ")} "
message << if invalid_keys.size > 1
"as options for #{command}, but they are invalid."
else
"as an option for #{command}, but it is invalid."
end
"as options for #{command}, but they are invalid."
else
"as an option for #{command}, but it is invalid."
end
message << " Valid options are: #{valid_keys.join(", ")}."
message << " You may be able to resolve this by upgrading Bundler to the newest version."
@ -456,7 +438,7 @@ repo_name ||= user_name
def normalize_source(source)
case source
when :gemcutter, :rubygems, :rubyforge
Bundler::SharedHelpers.major_deprecation 3, "The source :#{source} is deprecated because HTTP " \
Bundler::SharedHelpers.major_deprecation 2, "The source :#{source} is deprecated because HTTP " \
"requests are insecure.\nPlease change your source to 'https://" \
"rubygems.org' if possible, or 'http://rubygems.org' if not."
"http://rubygems.org"
@ -474,23 +456,22 @@ repo_name ||= user_name
msg = "This Gemfile contains multiple primary sources. " \
"Each source after the first must include a block to indicate which gems " \
"should come from that source"
unless Bundler.feature_flag.bundler_3_mode?
unless Bundler.feature_flag.bundler_2_mode?
msg += ". To downgrade this error to a warning, run " \
"`bundle config --delete disable_multisource`"
"`bundle config unset disable_multisource`"
end
raise GemfileEvalError, msg
else
Bundler::SharedHelpers.major_deprecation 3, "Your Gemfile contains multiple primary sources. " \
Bundler::SharedHelpers.major_deprecation 2, "Your Gemfile contains multiple primary sources. " \
"Using `source` more than once without a block is a security risk, and " \
"may result in installing unexpected gems. To resolve this warning, use " \
"a block to indicate which gems should come from the secondary source. " \
"To upgrade this warning to an error, run `bundle config " \
"To upgrade this warning to an error, run `bundle config set " \
"disable_multisource true`."
end
end
def warn_deprecated_git_source(name, replacement, additional_message = nil)
# TODO: 2.0 remove deprecation
additional_message &&= " #{additional_message}"
replacement = if replacement.count("\n").zero?
"{|repo_name| #{replacement} }"
@ -499,7 +480,7 @@ repo_name ||= user_name
end
Bundler::SharedHelpers.major_deprecation 3, <<-EOS
The :#{name} git source is deprecated, and will be removed in Bundler 3.0.#{additional_message} Add this code to the top of your Gemfile to ensure it continues to work:
The :#{name} git source is deprecated, and will be removed in the future.#{additional_message} Add this code to the top of your Gemfile to ensure it continues to work:
git_source(:#{name}) #{replacement}
@ -601,7 +582,7 @@ The :#{name} git source is deprecated, and will be removed in Bundler 3.0.#{addi
description = self.description
if dsl_path && description =~ /((#{Regexp.quote File.expand_path(dsl_path)}|#{Regexp.quote dsl_path.to_s}):\d+)/
trace_line = Regexp.last_match[1]
description = description.sub(/#{Regexp.quote trace_line}:\s*/, "").sub("\n", " - ")
description = description.sub(/\n.*\n(\.\.\.)? *\^~+$/, "").sub(/#{Regexp.quote trace_line}:\s*/, "").sub("\n", " - ")
end
[trace_line, description]
end

View file

@ -70,14 +70,8 @@ module Bundler
def self.ruby_version
str = String.new("#{RUBY_VERSION}")
if RUBY_VERSION < "1.9"
str << " (#{RUBY_RELEASE_DATE}"
str << " patchlevel #{RUBY_PATCHLEVEL}" if defined? RUBY_PATCHLEVEL
str << ") [#{RUBY_PLATFORM}]"
else
str << "p#{RUBY_PATCHLEVEL}" if defined? RUBY_PATCHLEVEL
str << " (#{RUBY_RELEASE_DATE} revision #{RUBY_REVISION}) [#{RUBY_PLATFORM}]"
end
str << "p#{RUBY_PATCHLEVEL}" if defined? RUBY_PATCHLEVEL
str << " (#{RUBY_RELEASE_DATE} revision #{RUBY_REVISION}) [#{RUBY_PLATFORM}]"
end
def self.git_version

View file

@ -19,7 +19,7 @@ module Bundler
def self.settings_method(name, key, &default)
define_method(name) do
value = Bundler.settings[key]
value = instance_eval(&default) if value.nil? && !default.nil?
value = instance_eval(&default) if value.nil?
value
end
end
@ -33,7 +33,6 @@ module Bundler
settings_flag(:auto_config_jobs) { bundler_3_mode? }
settings_flag(:cache_all) { bundler_3_mode? }
settings_flag(:cache_command_is_package) { bundler_3_mode? }
settings_flag(:console_command) { !bundler_3_mode? }
settings_flag(:default_install_uses_path) { bundler_3_mode? }
settings_flag(:deployment_means_frozen) { bundler_3_mode? }
settings_flag(:disable_multisource) { bundler_3_mode? }
@ -41,23 +40,17 @@ module Bundler
settings_flag(:forget_cli_options) { bundler_3_mode? }
settings_flag(:global_path_appends_ruby_scope) { bundler_3_mode? }
settings_flag(:global_gem_cache) { bundler_3_mode? }
settings_flag(:init_gems_rb) { bundler_3_mode? }
settings_flag(:list_command) { bundler_3_mode? }
settings_flag(:lockfile_uses_separate_rubygems_sources) { bundler_3_mode? }
settings_flag(:lockfile_upgrade_warning) { bundler_3_mode? }
settings_flag(:only_update_to_newer_versions) { bundler_3_mode? }
settings_flag(:path_relative_to_cwd) { bundler_3_mode? }
settings_flag(:plugins) { @bundler_version >= Gem::Version.new("1.14") }
settings_flag(:prefer_gems_rb) { bundler_3_mode? }
settings_flag(:print_only_version_number) { bundler_3_mode? }
settings_flag(:setup_makes_kernel_gem_public) { !bundler_3_mode? }
settings_flag(:skip_default_git_sources) { bundler_3_mode? }
settings_flag(:skip_default_git_sources) { bundler_4_mode? }
settings_flag(:specific_platform) { bundler_3_mode? }
settings_flag(:suppress_install_using_messages) { bundler_3_mode? }
settings_flag(:unlock_source_unlocks_spec) { !bundler_3_mode? }
settings_flag(:update_requires_all_flag) { bundler_3_mode? }
settings_flag(:use_gem_version_promoter_for_major_updates) { bundler_3_mode? }
settings_flag(:viz_command) { !bundler_3_mode? }
settings_option(:default_cli_command) { bundler_3_mode? ? :cli_help : :install }

View file

@ -4,6 +4,7 @@ require "bundler/vendored_persistent"
require "cgi"
require "securerandom"
require "zlib"
require "rubygems/request"
module Bundler
# Handles all the fetching with the rubygems server
@ -15,6 +16,8 @@ module Bundler
# This error is raised when it looks like the network is down
class NetworkDownError < HTTPError; end
# This error is raised if we should rate limit our requests to the API
class TooManyRequestsError < HTTPError; end
# This error is raised if the API returns a 413 (only printed in verbose)
class FallbackError < HTTPError; end
# This is the error raised if OpenSSL fails the cert verification
@ -44,7 +47,7 @@ module Bundler
remote_uri = filter_uri(remote_uri)
super "Authentication is required for #{remote_uri}.\n" \
"Please supply credentials for this source. You can do this by running:\n" \
" bundle config #{remote_uri} username:password"
" bundle config set #{remote_uri} username:password"
end
end
# This error is raised if HTTP authentication is provided, but incorrect.
@ -226,7 +229,7 @@ module Bundler
"GO_SERVER_URL" => "go",
"SNAP_CI" => "snap",
"CI_NAME" => ENV["CI_NAME"],
"CI" => "ci"
"CI" => "ci",
}
env_cis.find_all {|env, _| ENV[env] }.map {|_, ci| ci }
end
@ -293,8 +296,7 @@ module Bundler
end
else
store.set_default_paths
certs = File.expand_path("../ssl_certs/*/*.pem", __FILE__)
Dir.glob(certs).each {|c| store.add_file c }
Gem::Request.get_cert_files.each {|c| store.add_file c }
end
store
end

View file

@ -39,7 +39,13 @@ module Bundler
until remaining_gems.empty?
log_specs "Looking up gems #{remaining_gems.inspect}"
deps = compact_index_client.dependencies(remaining_gems)
deps = begin
parallel_compact_index_client.dependencies(remaining_gems)
rescue TooManyRequestsError
@bundle_worker.stop if @bundle_worker
@bundle_worker = nil # reset it. Not sure if necessary
serial_compact_index_client.dependencies(remaining_gems)
end
next_gems = deps.map {|d| d[3].map(&:first).flatten(1) }.flatten(1).uniq
deps.each {|dep| gem_info << dep }
complete_gems.concat(deps.map(&:first)).uniq!
@ -80,18 +86,26 @@ module Bundler
private
def compact_index_client
@compact_index_client ||= begin
@compact_index_client ||=
SharedHelpers.filesystem_access(cache_path) do
CompactIndexClient.new(cache_path, client_fetcher)
end.tap do |client|
client.in_parallel = lambda do |inputs, &blk|
func = lambda {|object, _index| blk.call(object) }
worker = bundle_worker(func)
inputs.each {|input| worker.enq(input) }
inputs.map { worker.deq }
end
end
end
def parallel_compact_index_client
compact_index_client.execution_mode = lambda do |inputs, &blk|
func = lambda {|object, _index| blk.call(object) }
worker = bundle_worker(func)
inputs.each {|input| worker.enq(input) }
inputs.map { worker.deq }
end
compact_index_client
end
def serial_compact_index_client
compact_index_client.sequential_execution_mode!
compact_index_client
end
def bundle_worker(func = nil)

View file

@ -34,10 +34,12 @@ module Bundler
fetch(uri, new_headers)
when Net::HTTPRequestEntityTooLarge
raise FallbackError, response.body
when Net::HTTPTooManyRequests
raise TooManyRequestsError, response.body
when Net::HTTPUnauthorized
raise AuthenticationRequiredError, uri.host
when Net::HTTPNotFound
raise FallbackError, "Net::HTTPNotFound"
raise FallbackError, "Net::HTTPNotFound: #{URICredentialsFilter.credential_filtered_uri(uri)}"
else
raise HTTPError, "#{response.class}#{": #{response.body}" unless response.body.empty?}"
end

View file

@ -1,4 +1,3 @@
# encoding: utf-8
# frozen_string_literal: true
require "cgi"
@ -45,7 +44,7 @@ module Bundler
"Alternatively, you can increase the amount of memory the JVM is able to use by running Bundler with jruby -J-Xmx1024m -S bundle (JRuby defaults to 500MB)."
else request_issue_report_for(error)
end
rescue
rescue StandardError
raise error
end
@ -124,7 +123,7 @@ module Bundler
yield
rescue SignalException
raise
rescue Exception => e
rescue Exception => e # rubocop:disable Lint/RescueException
FriendlyErrors.log_error(e)
exit FriendlyErrors.exit_status(e)
end

View file

@ -2,6 +2,7 @@
require "bundler/vendored_thor" unless defined?(Thor)
require "bundler"
require "shellwords"
module Bundler
class GemHelper
@ -75,7 +76,7 @@ module Bundler
def build_gem
file_name = nil
gem = ENV["BUNDLE_GEM"] ? ENV["BUNDLE_GEM"] : "gem"
sh("#{gem} build -V '#{spec_path}'") do
sh(%W[#{gem} build -V #{spec_path}]) do
file_name = File.basename(built_gem_path)
SharedHelpers.filesystem_access(File.join(base, "pkg")) {|p| FileUtils.mkdir_p(p) }
FileUtils.mv(built_gem_path, "pkg")
@ -87,17 +88,21 @@ module Bundler
def install_gem(built_gem_path = nil, local = false)
built_gem_path ||= build_gem
gem = ENV["BUNDLE_GEM"] ? ENV["BUNDLE_GEM"] : "gem"
out, _ = sh_with_code("#{gem} install '#{built_gem_path}'#{" --local" if local}")
raise "Couldn't install gem, run `gem install #{built_gem_path}' for more detailed output" unless out[/Successfully installed/]
cmd = %W[#{gem} install #{built_gem_path}]
cmd << "--local" if local
out, status = sh_with_status(cmd)
unless status.success? && out[/Successfully installed/]
raise "Couldn't install gem, run `gem install #{built_gem_path}' for more detailed output"
end
Bundler.ui.confirm "#{name} (#{version}) installed."
end
protected
def rubygem_push(path)
gem_command = "gem push '#{path}'"
gem_command += " --key #{gem_key}" if gem_key
gem_command += " --host #{allowed_push_host}" if allowed_push_host
gem_command = %W[gem push #{path}]
gem_command << "--key" << gem_key if gem_key
gem_command << "--host" << allowed_push_host if allowed_push_host
unless allowed_push_host || Bundler.user_home.join(".gem/credentials").file?
raise "Your rubygems.org credentials aren't set. Run `gem push` to set them."
end
@ -129,12 +134,14 @@ module Bundler
def perform_git_push(options = "")
cmd = "git push #{options}"
out, code = sh_with_code(cmd)
raise "Couldn't git push. `#{cmd}' failed with the following output:\n\n#{out}\n" unless code == 0
out, status = sh_with_status(cmd)
return if status.success?
cmd = cmd.shelljoin if cmd.respond_to?(:shelljoin)
raise "Couldn't git push. `#{cmd}' failed with the following output:\n\n#{out}\n"
end
def already_tagged?
return false unless sh("git tag").split(/\n/).include?(version_tag)
return false unless sh(%w[git tag]).split(/\n/).include?(version_tag)
Bundler.ui.confirm "Tag #{version_tag} has already been created."
true
end
@ -144,20 +151,20 @@ module Bundler
end
def clean?
sh_with_code("git diff --exit-code")[1] == 0
sh_with_status(%w[git diff --exit-code])[1].success?
end
def committed?
sh_with_code("git diff-index --quiet --cached HEAD")[1] == 0
sh_with_status(%w[git diff-index --quiet --cached HEAD])[1].success?
end
def tag_version
sh "git tag -m \"Version #{version}\" #{version_tag}"
sh %W[git tag -m Version\ #{version} #{version_tag}]
Bundler.ui.confirm "Tagged #{version_tag}."
yield if block_given?
rescue RuntimeError
Bundler.ui.error "Untagging #{version_tag} due to error."
sh_with_code "git tag -d #{version_tag}"
sh_with_status %W[git tag -d #{version_tag}]
raise
end
@ -174,21 +181,20 @@ module Bundler
end
def sh(cmd, &block)
out, code = sh_with_code(cmd, &block)
unless code.zero?
out, status = sh_with_status(cmd, &block)
unless status.success?
cmd = cmd.shelljoin if cmd.respond_to?(:shelljoin)
raise(out.empty? ? "Running `#{cmd}` failed. Run this command directly for more detailed output." : out)
end
out
end
def sh_with_code(cmd, &block)
cmd += " 2>&1"
outbuf = String.new
def sh_with_status(cmd, &block)
Bundler.ui.debug(cmd)
SharedHelpers.chdir(base) do
outbuf = `#{cmd}`
status = $?.exitstatus
block.call(outbuf) if status.zero? && block
outbuf = IO.popen(cmd, :err => [:child, :out], &:read)
status = $?
block.call(outbuf) if status.success? && block
[outbuf, status]
end
end

View file

@ -10,7 +10,7 @@ module Bundler
[Gem::Platform.new("universal-mingw32"), Gem::Platform.new("universal-mingw32")],
[Gem::Platform.new("x64-mingw32"), Gem::Platform.new("x64-mingw32")],
[Gem::Platform.new("x86_64-mingw32"), Gem::Platform.new("x64-mingw32")],
[Gem::Platform.new("mingw32"), Gem::Platform.new("x86-mingw32")]
[Gem::Platform.new("mingw32"), Gem::Platform.new("x86-mingw32")],
].freeze
def generic(p)

View file

@ -109,7 +109,7 @@ module Bundler
must_match = minor? ? [0] : [0, 1]
matches = must_match.map {|idx| gsv.segments[idx] == lsv.segments[idx] }
(matches.uniq == [true]) ? (gsv >= lsv) : false
matches.uniq == [true] ? (gsv >= lsv) : false
else
true
end

View file

@ -117,7 +117,7 @@ module Bundler
:style => "filled",
:fillcolor => "#B9B9D5",
:shape => "box3d",
:fontsize => 16
:fontsize => 16,
}.merge(@node_options[group])
)
end
@ -142,7 +142,7 @@ module Bundler
g.output @output_format.to_sym => "#{@output_file}.#{@output_format}"
Bundler.ui.info "#{@output_file}.#{@output_format}"
rescue ArgumentError => e
$stderr.puts "Unsupported output format. See Ruby-Graphviz/lib/graphviz/constants.rb"
warn "Unsupported output format. See Ruby-Graphviz/lib/graphviz/constants.rb"
raise e
end
end

View file

@ -123,7 +123,7 @@ module Bundler
end
end
# evalutes a gemfile to remove the specified gem
# evaluates a gemfile to remove the specified gem
# from it.
def remove_deps(gemfile_path)
initial_gemfile = IO.readlines(gemfile_path)
@ -136,8 +136,8 @@ module Bundler
removed_deps = remove_gems_from_dependencies(builder, @deps, gemfile_path)
# abort the opertion if no gems were removed
# no need to operate on gemfile furthur
# abort the operation if no gems were removed
# no need to operate on gemfile further
return [] if removed_deps.empty?
cleaned_gemfile = remove_gems_from_gemfile(@deps, gemfile_path)
@ -153,8 +153,8 @@ module Bundler
# @param [Dsl] builder Dsl object of current Gemfile.
# @param [Array] gems Array of names of gems to be removed.
# @param [Pathname] path of the Gemfile
# @return [Array] removed_deps Array of removed dependencies.
# @param [Pathname] gemfile_path Path of the Gemfile.
# @return [Array] Array of removed dependencies.
def remove_gems_from_dependencies(builder, gems, gemfile_path)
removed_deps = []
@ -206,7 +206,7 @@ module Bundler
nested_blocks -= 1
gemfile.each_with_index do |line, index|
next unless !line.nil? && line.include?(block_name)
next unless !line.nil? && line.strip.start_with?(block_name)
if gemfile[index + 1] =~ /^\s*end\s*$/
gemfile[index] = nil
gemfile[index + 1] = nil
@ -222,7 +222,7 @@ module Bundler
# @param [Array] removed_deps Array of removed dependencies.
# @param [Array] initial_gemfile Contents of original Gemfile before any operation.
def cross_check_for_errors(gemfile_path, original_deps, removed_deps, initial_gemfile)
# evalute the new gemfile to look for any failure cases
# evaluate the new gemfile to look for any failure cases
builder = Dsl.new
builder.eval_gemfile(gemfile_path)

View file

@ -36,6 +36,7 @@ def gemfile(install = false, options = {}, &gemfile)
opts = options.dup
ui = opts.delete(:ui) { Bundler::UI::Shell.new }
ui.level = "silent" if opts.delete(:quiet)
raise ArgumentError, "Unknown options: #{opts.keys.join(", ")}" unless opts.empty?
old_root = Bundler.method(:root)

View file

@ -221,7 +221,7 @@ module Bundler
def processor_count
require "etc"
Etc.nprocessors
rescue
rescue StandardError
1
end
@ -275,14 +275,7 @@ module Bundler
end
def can_install_in_parallel?
if Bundler.rubygems.provides?(">= 2.1.0")
true
else
Bundler.ui.warn "RubyGems #{Gem::VERSION} is not threadsafe, so your "\
"gems will be installed one at a time. Upgrade to RubyGems 2.1.0 " \
"or higher to enable parallel gem installation."
false
end
true
end
def install_in_parallel(size, standalone, force = false)

View file

@ -1,5 +1,7 @@
# frozen_string_literal: true
require "shellwords"
module Bundler
class GemInstaller
attr_reader :spec, :standalone, :worker, :force, :installer
@ -56,7 +58,9 @@ module Bundler
def spec_settings
# Fetch the build settings, if there are any
Bundler.settings["build.#{spec.name}"]
if settings = Bundler.settings["build.#{spec.name}"]
Shellwords.shellsplit(settings)
end
end
def install

View file

@ -91,10 +91,6 @@ module Bundler
end
def call
# Since `autoload` has the potential for threading issues on 1.8.7
# TODO: remove in bundler 2.0
require "bundler/gem_remote_fetcher" if RUBY_VERSION < "1.9"
check_for_corrupt_lockfile
if @size > 1
@ -115,7 +111,7 @@ module Bundler
s,
s.missing_lockfile_dependencies(@specs.map(&:name)),
]
end.reject { |a| a.last.empty? }
end.reject {|a| a.last.empty? }
return if missing_dependencies.empty?
warning = []
@ -150,7 +146,7 @@ module Bundler
end
def worker_pool
@worker_pool ||= Bundler::Worker.new @size, "Parallel Installer", lambda { |spec_install, worker_num|
@worker_pool ||= Bundler::Worker.new @size, "Parallel Installer", lambda {|spec_install, worker_num|
do_install(spec_install, worker_num)
}
end

View file

@ -77,7 +77,7 @@ module Bundler
if search && Gem::Platform.new(search.platform) != Gem::Platform.new(platform) && !search.runtime_dependencies.-(dependencies.reject {|d| d.type == :development }).empty?
Bundler.ui.warn "Unable to use the platform-specific (#{search.platform}) version of #{name} (#{version}) " \
"because it has different dependencies from the #{platform} version. " \
"To use the platform-specific version of the gem, run `bundle config specific_platform true` and install again."
"To use the platform-specific version of the gem, run `bundle config set specific_platform true` and install again."
search = source.specs.search(self).last
end
search.dependencies = dependencies if search && (search.is_a?(RemoteSpecification) || search.is_a?(EndpointSpecification))

View file

@ -23,16 +23,14 @@ module Bundler
PATH = "PATH".freeze
PLUGIN = "PLUGIN SOURCE".freeze
SPECS = " specs:".freeze
OPTIONS = /^ ([a-z]+): (.*)$/i
OPTIONS = /^ ([a-z]+): (.*)$/i.freeze
SOURCE = [GIT, GEM, PATH, PLUGIN].freeze
SECTIONS_BY_VERSION_INTRODUCED = {
# The strings have to be dup'ed for old RG on Ruby 2.3+
# TODO: remove dup in Bundler 2.0
Gem::Version.create("1.0".dup) => [DEPENDENCIES, PLATFORMS, GIT, GEM, PATH].freeze,
Gem::Version.create("1.10".dup) => [BUNDLED].freeze,
Gem::Version.create("1.12".dup) => [RUBY].freeze,
Gem::Version.create("1.13".dup) => [PLUGIN].freeze,
Gem::Version.create("1.0") => [DEPENDENCIES, PLATFORMS, GIT, GEM, PATH].freeze,
Gem::Version.create("1.10") => [BUNDLED].freeze,
Gem::Version.create("1.12") => [RUBY].freeze,
Gem::Version.create("1.13") => [PLUGIN].freeze,
}.freeze
KNOWN_SECTIONS = SECTIONS_BY_VERSION_INTRODUCED.values.flatten.freeze
@ -90,7 +88,7 @@ module Bundler
send("parse_#{@state}", line)
end
end
@sources << @rubygems_aggregate unless Bundler.feature_flag.lockfile_uses_separate_rubygems_sources?
@sources << @rubygems_aggregate unless Bundler.feature_flag.disable_multisource?
@specs = @specs.values.sort_by(&:identifier)
warn_for_outdated_bundler_version
rescue ArgumentError => e
@ -109,9 +107,9 @@ module Bundler
when 0
if current_version < bundler_version
Bundler.ui.warn "Warning: the running version of Bundler (#{current_version}) is older " \
"than the version that created the lockfile (#{bundler_version}). We suggest you " \
"upgrade to the latest version of Bundler by running `gem " \
"install bundler#{prerelease_text}`.\n"
"than the version that created the lockfile (#{bundler_version}). We suggest you to " \
"upgrade to the version that created the lockfile by running `gem install " \
"bundler:#{bundler_version}#{prerelease_text}`.\n"
end
end
end
@ -141,7 +139,7 @@ module Bundler
@sources << @current_source
end
when GEM
if Bundler.feature_flag.lockfile_uses_separate_rubygems_sources?
if Bundler.feature_flag.disable_multisource?
@opts["remotes"] = @opts.delete("remote")
@current_source = TYPES[@type].from_lock(@opts)
@sources << @current_source
@ -185,7 +183,7 @@ module Bundler
(?:-(.*))?\))? # Optional platform
(!)? # Optional pinned marker
$ # Line end
/xo
/xo.freeze
def parse_dependency(line)
return unless line =~ NAME_VERSION

View file

@ -47,26 +47,48 @@ module Bundler
Bundler.ui.error "Failed to install plugin #{name}: #{e.message}\n #{e.backtrace.join("\n ")}"
end
# List installed plugins and commands
#
def list
installed_plugins = index.installed_plugins
if installed_plugins.any?
output = String.new
installed_plugins.each do |plugin|
output << "#{plugin}\n"
output << "-----\n"
index.plugin_commands(plugin).each do |command|
output << " #{command}\n"
end
output << "\n"
end
else
output = "No plugins installed"
end
Bundler.ui.info output
end
# Evaluates the Gemfile with a limited DSL and installs the plugins
# specified by plugin method
#
# @param [Pathname] gemfile path
# @param [Proc] block that can be evaluated for (inline) Gemfile
def gemfile_install(gemfile = nil, &inline)
builder = DSL.new
if block_given?
builder.instance_eval(&inline)
else
builder.eval_gemfile(gemfile)
Bundler.settings.temporary(:frozen => false, :deployment => false) do
builder = DSL.new
if block_given?
builder.instance_eval(&inline)
else
builder.eval_gemfile(gemfile)
end
definition = builder.to_definition(nil, true)
return if definition.dependencies.empty?
plugins = definition.dependencies.map(&:name).reject {|p| index.installed? p }
installed_specs = Installer.new.install_definition(definition)
save_plugins plugins, installed_specs, builder.inferred_plugins
end
definition = builder.to_definition(nil, true)
return if definition.dependencies.empty?
plugins = definition.dependencies.map(&:name).reject {|p| index.installed? p }
installed_specs = Installer.new.install_definition(definition)
save_plugins plugins, installed_specs, builder.inferred_plugins
rescue RuntimeError => e
unless e.is_a?(GemfileError)
Bundler.ui.error "Failed to install plugin: #{e.message}\n #{e.backtrace[0]}"

View file

@ -37,7 +37,7 @@ module Bundler
#
# @!attribute [rw] dependency_names
# @return [Array<String>] Names of dependencies that the source should
# try to resolve. It is not necessary to use this list intenally. This
# try to resolve. It is not necessary to use this list internally. This
# is present to be compatible with `Definition` and is used by
# rubygems source.
module Source

View file

@ -58,7 +58,10 @@ module Bundler
raise SourceConflict.new(name, common) unless common.empty?
sources.each {|k| @sources[k] = name }
hooks.each {|e| (@hooks[e] ||= []) << name }
hooks.each do |event|
event_hooks = (@hooks[event] ||= []) << name
event_hooks.uniq!
end
@plugin_paths[name] = path
@load_paths[name] = load_paths
@ -100,6 +103,14 @@ module Bundler
@plugin_paths[name]
end
def installed_plugins
@plugin_paths.keys
end
def plugin_commands(plugin)
@commands.find_all {|_, n| n == plugin }.map(&:first)
end
def source?(source)
@sources.key? source
end

View file

@ -12,10 +12,15 @@ module Bundler
autoload :Git, "bundler/plugin/installer/git"
def install(names, options)
check_sources_consistency!(options)
version = options[:version] || [">= 0"]
Bundler.settings.temporary(:lockfile_uses_separate_rubygems_sources => false, :disable_multisource => false) do
Bundler.settings.temporary(:disable_multisource => false) do
if options[:git]
install_git(names, version, options)
elsif options[:local_git]
install_local_git(names, version, options)
else
sources = options[:source] || Bundler.rubygems.sources
install_rubygems(names, version, sources)
@ -38,22 +43,24 @@ module Bundler
private
def check_sources_consistency!(options)
if options.key?(:git) && options.key?(:local_git)
raise InvalidOption, "Remote and local plugin git sources can't be both specified"
end
end
def install_git(names, version, options)
uri = options.delete(:git)
options["uri"] = uri
source_list = SourceList.new
source_list.add_git_source(options)
install_all_sources(names, version, options, options[:source])
end
# To support both sources
if options[:source]
source_list.add_rubygems_source("remotes" => options[:source])
end
def install_local_git(names, version, options)
uri = options.delete(:local_git)
options["uri"] = uri
deps = names.map {|name| Dependency.new name, version }
definition = Definition.new(nil, deps, source_list, true)
install_definition(definition)
install_all_sources(names, version, options, options[:source])
end
# Installs the plugin from rubygems source and returns the path where the
@ -65,10 +72,16 @@ module Bundler
#
# @return [Hash] map of names to the specs of plugins installed
def install_rubygems(names, version, sources)
deps = names.map {|name| Dependency.new name, version }
install_all_sources(names, version, nil, sources)
end
def install_all_sources(names, version, git_source_options, rubygems_source)
source_list = SourceList.new
source_list.add_rubygems_source("remotes" => sources)
source_list.add_git_source(git_source_options) if git_source_options
source_list.add_rubygems_source("remotes" => rubygems_source) if rubygems_source
deps = names.map {|name| Dependency.new name, version }
definition = Definition.new(nil, deps, source_list, true)
install_definition(definition)

View file

@ -38,8 +38,8 @@ module Bundler
@platforms = platforms
@gem_version_promoter = gem_version_promoter
@allow_bundler_dependency_conflicts = Bundler.feature_flag.allow_bundler_dependency_conflicts?
@lockfile_uses_separate_rubygems_sources = Bundler.feature_flag.lockfile_uses_separate_rubygems_sources?
@use_gvp = Bundler.feature_flag.use_gem_version_promoter_for_major_updates? || !@gem_version_promoter.major?
@lockfile_uses_separate_rubygems_sources = Bundler.feature_flag.disable_multisource?
end
def start(requirements)
@ -48,9 +48,12 @@ module Bundler
verify_gemfile_dependencies_are_found!(requirements)
dg = @resolver.resolve(requirements, @base_dg)
dg.map(&:payload).
dg.
tap {|resolved| validate_resolved_specs!(resolved) }.
map(&:payload).
reject {|sg| sg.name.end_with?("\0") }.
map(&:to_specs).flatten
map(&:to_specs).
flatten
rescue Molinillo::VersionConflict => e
message = version_conflict_message(e)
raise VersionConflict.new(e.conflicts.keys.uniq, message)
@ -169,13 +172,13 @@ module Bundler
def name_for_explicit_dependency_source
Bundler.default_gemfile.basename.to_s
rescue
rescue StandardError
"Gemfile"
end
def name_for_locking_dependency_source
Bundler.default_lockfile.basename.to_s
rescue
rescue StandardError
"Gemfile.lock"
end
@ -276,10 +279,10 @@ module Bundler
versions_with_platforms = specs.map {|s| [s.version, s.platform] }
message = String.new("Could not find gem '#{SharedHelpers.pretty_dependency(requirement)}' in #{source}#{cache_message}.\n")
message << if versions_with_platforms.any?
"The source contains '#{name}' at: #{formatted_versions_with_platforms(versions_with_platforms)}"
else
"The source does not contain any versions of '#{name}'"
end
"The source contains '#{name}' at: #{formatted_versions_with_platforms(versions_with_platforms)}"
else
"The source does not contain any versions of '#{name}'"
end
else
message = "Could not find gem '#{requirement}' in any of the gem sources " \
"listed in your Gemfile#{cache_message}."
@ -300,9 +303,19 @@ module Bundler
end
def version_conflict_message(e)
# only show essential conflicts, if possible
conflicts = e.conflicts.dup
conflicts.delete_if do |_name, conflict|
deps = conflict.requirement_trees.map(&:last).flatten(1)
!Bundler::VersionRanges.empty?(*Bundler::VersionRanges.for_many(deps.map(&:requirement)))
end
e = Molinillo::VersionConflict.new(conflicts, e.specification_provider) unless conflicts.empty?
solver_name = "Bundler"
possibility_type = "gem"
e.message_with_trees(
:solver_name => "Bundler",
:possibility_type => "gem",
:solver_name => solver_name,
:possibility_type => possibility_type,
:reduce_trees => lambda do |trees|
# called first, because we want to reduce the amount of work required to find maximal empty sets
trees = trees.uniq {|t| t.flatten.map {|dep| [dep.name, dep.requirement] } }
@ -314,10 +327,8 @@ module Bundler
end.flatten(1).select do |deps|
Bundler::VersionRanges.empty?(*Bundler::VersionRanges.for_many(deps.map(&:requirement)))
end.min_by(&:size)
trees.reject! {|t| !maximal.include?(t.last) } if maximal
trees = trees.sort_by {|t| t.flatten.map(&:to_s) }
trees.uniq! {|t| t.flatten.map {|dep| [dep.name, dep.requirement] } }
trees.reject! {|t| !maximal.include?(t.last) } if maximal
trees.sort_by {|t| t.reverse.map(&:name) }
end,
@ -325,7 +336,7 @@ module Bundler
:additional_message_for_conflict => lambda do |o, name, conflict|
if name == "bundler"
o << %(\n Current Bundler version:\n bundler (#{Bundler::VERSION}))
other_bundler_required = !conflict.requirement.requirement.satisfied_by?(Gem::Version.new Bundler::VERSION)
other_bundler_required = !conflict.requirement.requirement.satisfied_by?(Gem::Version.new(Bundler::VERSION))
end
if name == "bundler" && other_bundler_required
@ -352,7 +363,11 @@ module Bundler
[]
end.compact.map(&:to_s).uniq.sort
o << "Could not find gem '#{SharedHelpers.pretty_dependency(conflict.requirement)}'"
metadata_requirement = name.end_with?("\0")
o << "Could not find gem '" unless metadata_requirement
o << SharedHelpers.pretty_dependency(conflict.requirement)
o << "'" unless metadata_requirement
if conflict.requirement_trees.first.size > 1
o << ", which is required by "
o << "gem '#{SharedHelpers.pretty_dependency(conflict.requirement_trees.first[-2])}',"
@ -360,14 +375,47 @@ module Bundler
o << " "
o << if relevant_sources.empty?
"in any of the sources.\n"
else
"in any of the relevant sources:\n #{relevant_sources * "\n "}\n"
end
"in any of the sources.\n"
elsif metadata_requirement
"is not available in #{relevant_sources.join(" or ")}"
else
"in any of the relevant sources:\n #{relevant_sources * "\n "}\n"
end
end
end,
:version_for_spec => lambda {|spec| spec.version }
:version_for_spec => lambda {|spec| spec.version },
:incompatible_version_message_for_conflict => lambda do |name, _conflict|
if name.end_with?("\0")
%(#{solver_name} found conflicting requirements for the #{name} version:)
else
%(#{solver_name} could not find compatible versions for #{possibility_type} "#{name}":)
end
end
)
end
def validate_resolved_specs!(resolved_specs)
resolved_specs.each do |v|
name = v.name
next unless sources = relevant_sources_for_vertex(v)
sources.compact!
if default_index = sources.index(@source_requirements[:default])
sources.delete_at(default_index)
end
sources.reject! {|s| s.specs[name].empty? }
sources.uniq!
next if sources.size <= 1
multisource_disabled = Bundler.feature_flag.disable_multisource?
msg = ["The gem '#{name}' was found in multiple relevant sources."]
msg.concat sources.map {|s| " * #{s}" }.sort
msg << "You #{multisource_disabled ? :must : :should} add this gem to the source block for the source you wish it to be installed from."
msg = msg.join("\n")
raise SecurityError, msg if multisource_disabled
Bundler.ui.warn "Warning: #{msg}"
end
end
end
end

View file

@ -94,10 +94,10 @@ module Bundler
return [] if !spec.is_a?(EndpointSpecification) && !spec.is_a?(Gem::Specification)
dependencies = []
if !spec.required_ruby_version.nil? && !spec.required_ruby_version.none?
dependencies << DepProxy.new(Gem::Dependency.new("ruby\0", spec.required_ruby_version), platform)
dependencies << DepProxy.new(Gem::Dependency.new("Ruby\0", spec.required_ruby_version), platform)
end
if !spec.required_rubygems_version.nil? && !spec.required_rubygems_version.none?
dependencies << DepProxy.new(Gem::Dependency.new("rubygems\0", spec.required_rubygems_version), platform)
dependencies << DepProxy.new(Gem::Dependency.new("RubyGems\0", spec.required_rubygems_version), platform)
end
dependencies
end

View file

@ -35,10 +35,10 @@ module Bundler
private
def run(&block)
@failed = false
@failed = false
@current_run += 1
@result = block.call
rescue => e
rescue StandardError => e
fail_attempt(e)
end

View file

@ -49,7 +49,7 @@ module Bundler
([\d.]+) # ruby version
(?:p(-?\d+))? # optional patchlevel
(?:\s\((\S+)\s(.+)\))? # optional engine info
/xo
/xo.freeze
# Returns a RubyVersion from the given string.
# @param [String] the version string to match.
@ -74,7 +74,7 @@ module Bundler
@host ||= [
RbConfig::CONFIG["host_cpu"],
RbConfig::CONFIG["host_vendor"],
RbConfig::CONFIG["host_os"]
RbConfig::CONFIG["host_os"],
].join("-")
end

View file

@ -2,12 +2,6 @@
require "pathname"
if defined?(Gem::QuickLoader)
# Gem Prelude makes me a sad panda :'(
Gem::QuickLoader.load_full_rubygems_library
end
require "rubygems"
require "rubygems/specification"
begin
@ -27,14 +21,16 @@ module Gem
class Specification
attr_accessor :remote, :location, :relative_loaded_from
if instance_methods(false).map(&:to_sym).include?(:source)
if instance_methods(false).include?(:source)
remove_method :source
attr_writer :source
def source
(defined?(@source) && @source) || Gem::Source::Installed.new
end
else
# rubocop:disable Lint/DuplicateMethods
attr_accessor :source
# rubocop:enable Lint/DuplicateMethods
end
alias_method :rg_full_gem_path, :full_gem_path
@ -85,10 +81,7 @@ module Gem
end
end
# RubyGems 1.8+ used only.
methods = instance_methods(false)
gem_dir = methods.first.is_a?(String) ? "gem_dir" : :gem_dir
remove_method :gem_dir if methods.include?(gem_dir)
remove_method :gem_dir if instance_methods(false).include?(:gem_dir)
def gem_dir
full_gem_path
end

View file

@ -66,7 +66,7 @@ module Bundler
If you wish to continue installing the downloaded gem, and are certain it does not pose a \
security issue despite the mismatching checksum, do the following:
1. run `bundle config disable_checksum_validation true` to turn off checksum verification
1. run `bundle config set disable_checksum_validation true` to turn off checksum verification
2. run `bundle install`
(More info: The expected SHA256 checksum was #{checksum.inspect}, but the \

View file

@ -1,8 +1,6 @@
# frozen_string_literal: true
require "monitor"
require "rubygems"
require "rubygems/config_file"
module Bundler
class RubygemsIntegration
@ -307,7 +305,7 @@ module Bundler
gem_from_path(path, security_policies[policy]).spec
rescue Gem::Package::FormatError
raise GemspecError, "Could not read gem at #{path}. It may be corrupted."
rescue Exception, Gem::Exception, Gem::Security::Exception => e
rescue Exception, Gem::Exception, Gem::Security::Exception => e # rubocop:disable Lint/RescueException
if e.is_a?(Gem::Security::Exception) ||
e.message =~ /unknown trust policy|unsigned gem/i ||
e.message =~ /couldn't verify (meta)?data signature/i
@ -436,40 +434,42 @@ module Bundler
# Used to make bin stubs that are not created by bundler work
# under bundler. The new Gem.bin_path only considers gems in
# +specs+
def replace_bin_path(specs, specs_by_name)
def replace_bin_path(specs_by_name)
gem_class = (class << Gem; self; end)
redefine_method(gem_class, :find_spec_for_exe) do |gem_name, *args|
exec_name = args.first
raise ArgumentError, "you must supply exec_name" unless exec_name
spec_with_name = specs_by_name[gem_name]
spec = if exec_name
if spec_with_name && spec_with_name.executables.include?(exec_name)
spec_with_name
else
specs.find {|s| s.executables.include?(exec_name) }
end
else
spec_with_name
end
matching_specs_by_exec_name = specs_by_name.values.select {|s| s.executables.include?(exec_name) }
spec = matching_specs_by_exec_name.delete(spec_with_name)
unless spec
unless spec || !matching_specs_by_exec_name.empty?
message = "can't find executable #{exec_name} for gem #{gem_name}"
if !exec_name || spec_with_name.nil?
if spec_with_name.nil?
message += ". #{gem_name} is not currently included in the bundle, " \
"perhaps you meant to add it to your #{Bundler.default_gemfile.basename}?"
end
raise Gem::Exception, message
end
raise Gem::Exception, "no default executable for #{spec.full_name}" unless exec_name ||= spec.default_executable
unless spec.name == gem_name
Bundler::SharedHelpers.major_deprecation 3,
unless spec
spec = matching_specs_by_exec_name.shift
warn \
"Bundler is using a binstub that was created for a different gem (#{spec.name}).\n" \
"You should run `bundle binstub #{gem_name}` " \
"to work around a system/bundle conflict."
end
unless matching_specs_by_exec_name.empty?
conflicting_names = matching_specs_by_exec_name.map(&:name).join(", ")
warn \
"The `#{exec_name}` executable in the `#{spec.name}` gem is being loaded, but it's also present in other gems (#{conflicting_names}).\n" \
"If you meant to run the executable for another gem, make sure you use a project specific binstub (`bundle binstub <gem_name>`).\n" \
"If you plan to use multiple conflicting executables, generate binstubs for them and disambiguate their names."
end
spec
end
@ -514,9 +514,18 @@ module Bundler
h
end
Bundler.rubygems.default_stubs.each do |stub|
default_spec = stub.to_spec
default_spec_name = default_spec.name
next if specs_by_name.key?(default_spec_name)
specs << default_spec
specs_by_name[default_spec_name] = default_spec
end
replace_gem(specs, specs_by_name)
stub_rubygems(specs)
replace_bin_path(specs, specs_by_name)
replace_bin_path(specs_by_name)
replace_refresh
Gem.clear_paths
@ -850,6 +859,16 @@ module Bundler
end
end
if Gem::Specification.respond_to?(:default_stubs)
def default_stubs
Gem::Specification.default_stubs("*.gemspec")
end
else
def default_stubs
Gem::Specification.send(:default_stubs, "*.gemspec")
end
end
def use_gemdeps(gemfile)
ENV["BUNDLE_GEMFILE"] ||= File.expand_path(gemfile)
require "bundler/gemdeps"

View file

@ -163,7 +163,7 @@ module Bundler
gem_dirs = Dir["#{Gem.dir}/gems/*"]
gem_files = Dir["#{Gem.dir}/cache/*.gem"]
gemspec_files = Dir["#{Gem.dir}/specifications/*.gemspec"]
extension_dirs = Dir["#{Gem.dir}/extensions/*/*/*"]
extension_dirs = Dir["#{Gem.dir}/extensions/*/*/*"] + Dir["#{Gem.dir}/bundler/gems/extensions/*/*/*"]
spec_gem_paths = []
# need to keep git sources around
spec_git_paths = @definition.spec_git_paths

View file

@ -18,7 +18,6 @@ module Bundler
cache_all
cache_all_platforms
cache_command_is_package
console_command
default_install_uses_path
deployment
deployment_means_frozen
@ -35,23 +34,21 @@ module Bundler
frozen
gem.coc
gem.mit
github.https
global_path_appends_ruby_scope
global_gem_cache
ignore_messages
init_gems_rb
list_command
lockfile_upgrade_warning
lockfile_uses_separate_rubygems_sources
major_deprecations
no_install
no_prune
only_update_to_newer_versions
path_relative_to_cwd
path.system
plugins
prefer_gems_rb
prefer_patch
print_only_version_number
setup_makes_kernel_gem_public
silence_deprecations
silence_root_warning
skip_default_git_sources
specific_platform
@ -59,7 +56,6 @@ module Bundler
unlock_source_unlocks_spec
update_requires_all_flag
use_gem_version_promoter_for_major_updates
viz_command
].freeze
NUMBER_KEYS = %w[
@ -76,7 +72,9 @@ module Bundler
].freeze
DEFAULT_CONFIG = {
:silence_deprecations => false,
:disable_version_check => true,
:prefer_patch => false,
:redirect => 5,
:retry => 3,
:timeout => 10,
@ -107,18 +105,6 @@ module Bundler
temporary(key => value)
value
else
command = if value.nil?
"bundle config --delete #{key}"
else
"bundle config #{key} #{Array(value).join(":")}"
end
Bundler::SharedHelpers.major_deprecation 3,\
"flags passed to commands " \
"will no longer be automatically remembered. Instead please set flags " \
"you want remembered between commands using `bundle config " \
"<setting name> <setting value>`, i.e. `#{command}`"
set_local(key, value)
end
end
@ -407,20 +393,6 @@ module Bundler
Pathname.new(@root).join("config") if @root
end
CONFIG_REGEX = %r{ # rubocop:disable Style/RegexpLiteral
^
(BUNDLE_.+):\s # the key
(?: !\s)? # optional exclamation mark found with ruby 1.9.3
(['"]?) # optional opening quote
(.* # contents of the value
(?: # optionally, up until the next key
(\n(?!BUNDLE).+)*
)
)
\2 # matching closing quote
$
}xo
def load_config(config_file)
return {} if !config_file || ignore_config?
SharedHelpers.filesystem_access(config_file, :read) do |file|
@ -442,7 +414,7 @@ module Bundler
(https?.*?) # URI
(\.#{Regexp.union(PER_URI_OPTIONS)})? # optional suffix key
\z
/ix
/ix.freeze
# TODO: duplicates Rubygems#normalize_uri
# TODO: is this the correct place to validate mirror URIs?

View file

@ -6,13 +6,14 @@ if Bundler::SharedHelpers.in_bundle?
require "bundler"
if STDOUT.tty? || ENV["BUNDLER_FORCE_TTY"]
Bundler.ui = Bundler::UI::Shell.new
begin
Bundler.setup
rescue Bundler::BundlerError => e
puts "\e[31m#{e.message}\e[0m"
puts e.backtrace.join("\n") if ENV["DEBUG"]
Bundler.ui.warn "\e[31m#{e.message}\e[0m"
Bundler.ui.warn e.backtrace.join("\n") if ENV["DEBUG"]
if e.is_a?(Bundler::GemNotFound)
puts "\e[33mRun `bundle install` to install missing gems.\e[0m"
Bundler.ui.warn "\e[33mRun `bundle install` to install missing gems.\e[0m"
end
exit e.status_code
end

View file

@ -3,6 +3,7 @@
require "bundler/compatibility_guard"
require "pathname"
require "rbconfig"
require "rubygems"
require "bundler/version"
@ -10,17 +11,6 @@ require "bundler/constants"
require "bundler/rubygems_integration"
require "bundler/current_ruby"
module Gem
class Dependency
# This is only needed for RubyGems < 1.4
unless method_defined? :requirement
def requirement
version_requirements
end
end
end
end
module Bundler
module SharedHelpers
def root
@ -140,33 +130,28 @@ module Bundler
end
def major_deprecation(major_version, message)
if Bundler.bundler_major_version >= major_version
bundler_major_version = Bundler.bundler_major_version
if bundler_major_version > major_version
require "bundler/errors"
raise DeprecatedError, "[REMOVED FROM #{major_version}.0] #{message}"
raise DeprecatedError, "[REMOVED] #{message}"
end
return unless prints_major_deprecations?
return unless bundler_major_version >= major_version && prints_major_deprecations?
@major_deprecation_ui ||= Bundler::UI::Shell.new("no-color" => true)
ui = Bundler.ui.is_a?(@major_deprecation_ui.class) ? Bundler.ui : @major_deprecation_ui
ui.warn("[DEPRECATED FOR #{major_version}.0] #{message}")
ui.warn("[DEPRECATED] #{message}")
end
def print_major_deprecations!
multiple_gemfiles = search_up(".") do |dir|
gemfiles = gemfile_names.select {|gf| File.file? File.expand_path(gf, dir) }
next if gemfiles.empty?
break false if gemfiles.size == 1
break gemfiles.size != 1
end
if multiple_gemfiles && Bundler.bundler_major_version == 2
Bundler::SharedHelpers.major_deprecation 3, \
"gems.rb and gems.locked will be preferred to Gemfile and Gemfile.lock."
end
if RUBY_VERSION < "2"
major_deprecation(2, "Bundler will only support ruby >= 2.0, you are running #{RUBY_VERSION}")
end
return if Bundler.rubygems.provides?(">= 2")
major_deprecation(2, "Bundler will only support rubygems >= 2.0, you are running #{Bundler.rubygems.version}")
return unless multiple_gemfiles
message = "Multiple gemfiles (gems.rb and Gemfile) detected. " \
"Make sure you remove Gemfile and Gemfile.lock since bundler is ignoring them in favor of gems.rb and gems.rb.locked."
Bundler.ui.warn message
end
def trap(signal, override = false, &block)
@ -246,13 +231,11 @@ module Bundler
def find_gemfile(order_matters = false)
given = ENV["BUNDLE_GEMFILE"]
return given if given && !given.empty?
names = gemfile_names
names.reverse! if order_matters && Bundler.feature_flag.prefer_gems_rb?
find_file(*names)
find_file(*gemfile_names)
end
def gemfile_names
["Gemfile", "gems.rb"]
["gems.rb", "Gemfile"]
end
def find_file(*names)
@ -349,9 +332,6 @@ module Bundler
end
def clean_load_path
# handle 1.9 where system gems are always on the load path
return unless defined?(::Gem)
bundler_lib = bundler_ruby_lib
loaded_gem_paths = Bundler.rubygems.loaded_gem_paths
@ -372,8 +352,7 @@ module Bundler
def prints_major_deprecations?
require "bundler"
deprecation_release = Bundler::VERSION.split(".").drop(1).include?("99")
return false if !deprecation_release && !Bundler.settings[:major_deprecations]
return false if Bundler.settings[:silence_deprecations]
require "bundler/deprecate"
return false if Bundler::Deprecate.skip
true

View file

@ -51,7 +51,7 @@ module Bundler
dm[i][j] = [
dm[i - 1][j - 1] + (this[j - 1] == that[i - 1] ? 0 : sub),
dm[i][j - 1] + ins,
dm[i - 1][j] + del
dm[i - 1][j] + del,
].min
end
end

View file

@ -118,18 +118,19 @@ module Bundler
def local_override!(path)
return false if local?
original_path = path
path = Pathname.new(path)
path = path.expand_path(Bundler.root) unless path.relative?
unless options["branch"] || Bundler.settings[:disable_local_branch_check]
raise GitError, "Cannot use local override for #{name} at #{path} because " \
":branch is not specified in Gemfile. Specify a branch or use " \
"`bundle config --delete` to remove the local override"
":branch is not specified in Gemfile. Specify a branch or run " \
"`bundle config unset local.#{override_for(original_path)}` to remove the local override"
end
unless path.exist?
raise GitError, "Cannot use local override for #{name} because #{path} " \
"does not exist. Check `bundle config --delete` to remove the local override"
"does not exist. Run `bundle config unset local.#{override_for(original_path)}` to remove the local override"
end
set_local!(path)
@ -260,7 +261,11 @@ module Bundler
end
def requires_checkout?
allow_git_ops? && !local?
allow_git_ops? && !local? && !cached_revision_checked_out?
end
def cached_revision_checked_out?
cached_revision && cached_revision == revision && install_path.exist?
end
def base_name
@ -324,6 +329,10 @@ module Bundler
def extension_cache_slug(_)
extension_dir_name
end
def override_for(path)
Bundler.settings.local_overrides.key(path)
end
end
end
end

View file

@ -253,7 +253,7 @@ module Bundler
ensure
STDERR.reopen backup_stderr
end
$stderr.puts URICredentialsFilter.credential_filtered_string(captured_err, uri) if uri && !captured_err.empty?
Bundler.ui.warn URICredentialsFilter.credential_filtered_string(captured_err, uri) if uri && !captured_err.empty?
return_value
end
end

View file

@ -5,8 +5,10 @@ module Bundler
class Metadata < Source
def specs
@specs ||= Index.build do |idx|
idx << Gem::Specification.new("ruby\0", RubyVersion.system.to_gem_version_with_patchlevel)
idx << Gem::Specification.new("rubygems\0", Gem::VERSION)
idx << Gem::Specification.new("Ruby\0", RubyVersion.system.to_gem_version_with_patchlevel)
idx << Gem::Specification.new("RubyGems\0", Gem::VERSION) do |s|
s.required_rubygems_version = Gem::Requirement.default
end
idx << Gem::Specification.new do |s|
s.name = "bundler"

View file

@ -191,10 +191,10 @@ module Bundler
else
message = String.new("The path `#{expanded_path}` ")
message << if File.exist?(expanded_path)
"is not a directory."
else
"does not exist."
end
"is not a directory."
else
"does not exist."
end
raise PathError, message
end

View file

@ -51,7 +51,7 @@ module Bundler
end
def can_lock?(spec)
return super if Bundler.feature_flag.lockfile_uses_separate_rubygems_sources?
return super if Bundler.feature_flag.disable_multisource?
spec.source.is_a?(Rubygems)
end
@ -106,7 +106,7 @@ module Bundler
end
end
if installed?(spec) && !force
if (installed?(spec) || Plugin.installed?(spec.name)) && !force
print_using_message "Using #{version_message(spec)}"
return nil # no post-install message
end
@ -120,8 +120,14 @@ module Bundler
uris.uniq!
Installer.ambiguous_gems << [spec.name, *uris] if uris.length > 1
s = Bundler.rubygems.spec_from_gem(fetch_gem(spec), Bundler.settings["trust-policy"])
spec.__swap__(s)
path = fetch_gem(spec)
begin
s = Bundler.rubygems.spec_from_gem(path, Bundler.settings["trust-policy"])
spec.__swap__(s)
rescue StandardError
Bundler.rm_rf(path)
raise
end
end
unless Bundler.settings[:no_install]

View file

@ -1,5 +1,7 @@
# frozen_string_literal: true
require "set"
module Bundler
class SourceList
attr_reader :path_sources,
@ -41,17 +43,14 @@ module Bundler
end
def global_rubygems_source=(uri)
if Bundler.feature_flag.lockfile_uses_separate_rubygems_sources?
if Bundler.feature_flag.disable_multisource?
@global_rubygems_source ||= rubygems_aggregate_class.new("remotes" => uri)
end
add_rubygems_remote(uri)
end
def add_rubygems_remote(uri)
if Bundler.feature_flag.lockfile_uses_separate_rubygems_sources?
return if Bundler.feature_flag.disable_multisource?
raise InvalidOption, "`lockfile_uses_separate_rubygems_sources` cannot be set without `disable_multisource` being set"
end
return if Bundler.feature_flag.disable_multisource?
@rubygems_aggregate.add_remote(uri)
@rubygems_aggregate
end
@ -77,12 +76,10 @@ module Bundler
end
def lock_sources
if Bundler.feature_flag.lockfile_uses_separate_rubygems_sources?
[[default_source], @rubygems_sources, git_sources, path_sources, plugin_sources].map do |sources|
sources.sort_by(&:to_s)
end.flatten(1)
lock_sources = (path_sources + git_sources + plugin_sources).sort_by(&:to_s)
if Bundler.feature_flag.disable_multisource?
lock_sources + rubygems_sources.sort_by(&:to_s)
else
lock_sources = (path_sources + git_sources + plugin_sources).sort_by(&:to_s)
lock_sources << combine_rubygems_sources
end
end
@ -97,7 +94,7 @@ module Bundler
end
end
replacement_rubygems = !Bundler.feature_flag.lockfile_uses_separate_rubygems_sources? &&
replacement_rubygems = !Bundler.feature_flag.disable_multisource? &&
replacement_sources.detect {|s| s.is_a?(Source::Rubygems) }
@rubygems_aggregate = replacement_rubygems if replacement_rubygems
@ -150,7 +147,7 @@ module Bundler
if source.uri =~ /^git\:/
Bundler.ui.warn "The git source `#{source.uri}` uses the `git` protocol, " \
"which transmits data without encryption. Disable this warning with " \
"`bundle config git.allow_insecure true`, or switch to the `https` " \
"`bundle config set git.allow_insecure true`, or switch to the `https` " \
"protocol to keep your data secure."
end
end

View file

@ -60,7 +60,6 @@ module Bundler
@specs << value
@lookup = nil
@sorted = nil
value
end
def sort!

View file

@ -1 +0,0 @@
# Ignore all files in this directory

View file

@ -1,66 +0,0 @@
# frozen_string_literal: true
require "bundler/vendored_fileutils"
require "net/https"
require "openssl"
module Bundler
module SSLCerts
class CertificateManager
attr_reader :bundler_cert_path, :bundler_certs, :rubygems_certs
def self.update_from!(rubygems_path)
new(rubygems_path).update!
end
def initialize(rubygems_path = nil)
if rubygems_path
rubygems_cert_path = File.join(rubygems_path, "lib/rubygems/ssl_certs")
@rubygems_certs = certificates_in(rubygems_cert_path)
end
@bundler_cert_path = File.expand_path("..", __FILE__)
@bundler_certs = certificates_in(bundler_cert_path)
end
def up_to_date?
rubygems_certs.all? do |rc|
bundler_certs.find do |bc|
File.basename(bc) == File.basename(rc) && FileUtils.compare_file(bc, rc)
end
end
end
def update!
return if up_to_date?
FileUtils.rm bundler_certs
FileUtils.cp rubygems_certs, bundler_cert_path
end
def connect_to(host)
http = Net::HTTP.new(host, 443)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
http.cert_store = store
http.head("/")
end
private
def certificates_in(path)
Dir[File.join(path, "**/*.pem")].sort
end
def store
@store ||= begin
store = OpenSSL::X509::Store.new
bundler_certs.each do |cert|
store.add_file cert
end
store
end
end
end
end
end

View file

@ -1,21 +0,0 @@
-----BEGIN CERTIFICATE-----
MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkG
A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv
b3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAw
MDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9i
YWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJHbG9iYWxT
aWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDaDuaZ
jc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavp
xy0Sy6scTHAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp
1Wrjsok6Vjk4bwY8iGlbKk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdG
snUOhugZitVtbNV4FpWi6cgKOOvyJBNPc1STE4U6G7weNLWLBYy5d4ux2x8gkasJ
U26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrXgzT/LCrBbBlDSgeF59N8
9iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8E
BTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0B
AQUFAAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOz
yj1hTdNGCbM+w6DjY1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE
38NflNUVyRRBnMRddWQVDf9VMOyGj/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymP
AbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhHhm4qxFYxldBniYUr+WymXUad
DKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveCX4XSQRjbgbME
HMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A==
-----END CERTIFICATE-----

View file

@ -1,23 +0,0 @@
-----BEGIN CERTIFICATE-----
MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j
ZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL
MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3
LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug
RVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm
+9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW
PNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEM
xChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFB
Ik5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQNAQTXKFx01p8VdteZOE3
hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsg
EsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQF
MAMBAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaA
FLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3Nec
nzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6z
eM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jF
hS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2
Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe
vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep
+OkuE6N36B9K
-----END CERTIFICATE-----

View file

@ -1,25 +0,0 @@
-----BEGIN CERTIFICATE-----
MIIENjCCAx6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBvMQswCQYDVQQGEwJTRTEU
MBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFkZFRydXN0IEV4dGVybmFs
IFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBFeHRlcm5hbCBDQSBSb290
MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEwNDgzOFowbzELMAkGA1UEBhMCU0Ux
FDASBgNVBAoTC0FkZFRydXN0IEFCMSYwJAYDVQQLEx1BZGRUcnVzdCBFeHRlcm5h
bCBUVFAgTmV0d29yazEiMCAGA1UEAxMZQWRkVHJ1c3QgRXh0ZXJuYWwgQ0EgUm9v
dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALf3GjPm8gAELTngTlvt
H7xsD821+iO2zt6bETOXpClMfZOfvUq8k+0DGuOPz+VtUFrWlymUWoCwSXrbLpX9
uMq/NzgtHj6RQa1wVsfwTz/oMp50ysiQVOnGXw94nZpAPA6sYapeFI+eh6FqUNzX
mk6vBbOmcZSccbNQYArHE504B4YCqOmoaSYYkKtMsE8jqzpPhNjfzp/haW+710LX
a0Tkx63ubUFfclpxCDezeWWkWaCUN/cALw3CknLa0Dhy2xSoRcRdKn23tNbE7qzN
E0S3ySvdQwAl+mG5aWpYIxG3pzOPVnVZ9c0p10a3CitlttNCbxWyuHv77+ldU9U0
WicCAwEAAaOB3DCB2TAdBgNVHQ4EFgQUrb2YejS0Jvf6xCZU7wO94CTLVBowCwYD
VR0PBAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wgZkGA1UdIwSBkTCBjoAUrb2YejS0
Jvf6xCZU7wO94CTLVBqhc6RxMG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRU
cnVzdCBBQjEmMCQGA1UECxMdQWRkVHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsx
IjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENBIFJvb3SCAQEwDQYJKoZIhvcN
AQEFBQADggEBALCb4IUlwtYj4g+WBpKdQZic2YR5gdkeWxQHIzZlj7DYd7usQWxH
YINRsPkyPef89iYTx4AWpb9a/IfPeHmJIZriTAcKhjW88t5RxNKWt9x+Tu5w/Rw5
6wwCURQtjr0W4MHfRnXnJK3s9EK0hZNwEGe6nQY1ShjTK3rMUUKhemPR5ruhxSvC
Nr4TDea9Y355e6cJDUCrat2PisP29owaQgVR1EX1n6diIWgVIEM8med8vSTYqZEX
c4g/VhsxOBi0cQ+azcgOno4uG+GMmIPLHzHxREzGBHNJdmAPx/i9F4BrLunMTA5a
mnkPIAou1Z5jJh5VkpTYghdae9C8x49OhgQ=
-----END CERTIFICATE-----

View file

@ -13,17 +13,13 @@ module Bundler
attr_accessor :stub, :ignored
# Pre 2.2.0 did not include extension_dir
# https://github.com/rubygems/rubygems/commit/9485ca2d101b82a946d6f327f4bdcdea6d4946ea
if Bundler.rubygems.provides?(">= 2.2.0")
def source=(source)
super
# Stub has no concept of source, which means that extension_dir may be wrong
# This is the case for git-based gems. So, instead manually assign the extension dir
return unless source.respond_to?(:extension_dir_name)
path = File.join(stub.extensions_dir, source.extension_dir_name)
stub.extension_dir = File.expand_path(path)
end
def source=(source)
super
# Stub has no concept of source, which means that extension_dir may be wrong
# This is the case for git-based gems. So, instead manually assign the extension dir
return unless source.respond_to?(:extension_dir_name)
path = File.join(stub.extensions_dir, source.extension_dir_name)
stub.extension_dir = File.expand_path(path)
end
def to_yaml
@ -32,11 +28,9 @@ module Bundler
# @!group Stub Delegates
if Bundler.rubygems.provides?(">= 2.3")
# This is defined directly to avoid having to load every installed spec
def missing_extensions?
stub.missing_extensions?
end
# This is defined directly to avoid having to load every installed spec
def missing_extensions?
stub.missing_extensions?
end
def activated
@ -57,16 +51,14 @@ module Bundler
stub.full_gem_path || method_missing(:full_gem_path)
end
if Bundler.rubygems.provides?(">= 2.2.0")
def full_require_paths
stub.full_require_paths
end
def full_require_paths
stub.full_require_paths
end
# This is what we do in bundler/rubygems_ext
# full_require_paths is always implemented in >= 2.2.0
def load_paths
full_require_paths
end
# This is what we do in bundler/rubygems_ext
# full_require_paths is always implemented
def load_paths
full_require_paths
end
def loaded_from

View file

@ -11,7 +11,7 @@
require "rubygems"
m = Module.new do
module_function
module_function
def invoked_as_script?
File.expand_path($0) == File.expand_path(__FILE__)

View file

@ -14,7 +14,7 @@ gem '<%= config[:name] %>'
And then execute:
$ bundle
$ bundle install
Or install it yourself as:

View file

@ -1,8 +1,4 @@
<%- if RUBY_VERSION < "2.0.0" -%>
# coding: utf-8
<%- end -%>
lib = File.expand_path("../lib", __FILE__)
lib = File.expand_path("lib", __dir__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require "<%= config[:namespaced_path] %>/version"
@ -19,18 +15,11 @@ Gem::Specification.new do |spec|
spec.license = "MIT"
<%- end -%>
# Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
# to allow pushing to a single host or delete this section to allow pushing to any host.
if spec.respond_to?(:metadata)
spec.metadata["allowed_push_host"] = "TODO: Set to 'http://mygemserver.com'"
spec.metadata["allowed_push_host"] = "TODO: Set to 'http://mygemserver.com'"
spec.metadata["homepage_uri"] = spec.homepage
spec.metadata["source_code_uri"] = "TODO: Put your gem's public repo URL here."
spec.metadata["changelog_uri"] = "TODO: Put your gem's CHANGELOG.md URL here."
else
raise "RubyGems 2.0 or newer is required to protect against " \
"public gem pushes."
end
spec.metadata["homepage_uri"] = spec.homepage
spec.metadata["source_code_uri"] = "TODO: Put your gem's public repo URL here."
spec.metadata["changelog_uri"] = "TODO: Put your gem's CHANGELOG.md URL here."
# Specify which files should be added to the gem when it is released.
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
@ -45,7 +34,7 @@ Gem::Specification.new do |spec|
<%- end -%>
spec.add_development_dependency "bundler", "~> <%= config[:bundler_version] %>"
spec.add_development_dependency "rake", "~> 10.0"
spec.add_development_dependency "rake", "~> 12.0"
<%- if config[:ext] -%>
spec.add_development_dependency "rake-compiler"
<%- end -%>

View file

@ -1,4 +1,4 @@
$LOAD_PATH.unshift File.expand_path("../../lib", __FILE__)
$LOAD_PATH.unshift File.expand_path("../lib", __dir__)
require "<%= config[:namespaced_path] %>"
require "minitest/autorun"

View file

@ -1,5 +1,4 @@
---
sudo: false
language: ruby
cache: bundler
rvm:

View file

@ -1,4 +1,13 @@
# frozen_string_literal: true
begin
require 'rbconfig'
rescue LoadError
# for make mjit-headers
end
require "bundler/vendor/fileutils/lib/fileutils/version"
#
# = fileutils.rb
#
@ -56,7 +65,7 @@
#
# There are some `low level' methods, which do not accept any option:
#
# Bundler::FileUtils.copy_entry(src, dest, preserve = false, dereference = false)
# Bundler::FileUtils.copy_entry(src, dest, preserve = false, dereference_root = false, remove_destination = false)
# Bundler::FileUtils.copy_file(src, dest, preserve = false, dereference = true)
# Bundler::FileUtils.copy_stream(srcstream, deststream)
# Bundler::FileUtils.remove_entry(path, force = false)
@ -84,7 +93,6 @@
# files/directories. This equates to passing the <tt>:noop</tt> and
# <tt>:verbose</tt> flags to methods in Bundler::FileUtils.
#
module Bundler::FileUtils
def self.private_module_function(name) #:nodoc:
@ -106,19 +114,22 @@ module Bundler::FileUtils
#
# Changes the current directory to the directory +dir+.
#
# If this method is called with block, resumes to the old
# working directory after the block execution finished.
# If this method is called with block, resumes to the previous
# working directory after the block execution has finished.
#
# Bundler::FileUtils.cd('/', :verbose => true) # chdir and report it
# Bundler::FileUtils.cd('/') # change directory
#
# Bundler::FileUtils.cd('/') do # chdir
# Bundler::FileUtils.cd('/', :verbose => true) # change directory and report it
#
# Bundler::FileUtils.cd('/') do # change directory
# # ... # do something
# end # return to original directory
#
def cd(dir, verbose: nil, &block) # :yield: dir
fu_output_message "cd #{dir}" if verbose
Dir.chdir(dir, &block)
result = Dir.chdir(dir, &block)
fu_output_message 'cd -' if verbose and block
result
end
module_function :cd
@ -245,15 +256,15 @@ module Bundler::FileUtils
fu_output_message "rmdir #{parents ? '-p ' : ''}#{list.join ' '}" if verbose
return if noop
list.each do |dir|
begin
Dir.rmdir(dir = remove_trailing_slash(dir))
if parents
Dir.rmdir(dir = remove_trailing_slash(dir))
if parents
begin
until (parent = File.dirname(dir)) == '.' or parent == dir
dir = parent
Dir.rmdir(dir)
end
rescue Errno::ENOTEMPTY, Errno::EEXIST, Errno::ENOENT
end
rescue Errno::ENOTEMPTY, Errno::EEXIST, Errno::ENOENT
end
end
end
@ -293,6 +304,39 @@ module Bundler::FileUtils
alias link ln
module_function :link
#
# :call-seq:
# Bundler::FileUtils.cp_lr(src, dest, noop: nil, verbose: nil, dereference_root: true, remove_destination: false)
#
# Hard link +src+ to +dest+. If +src+ is a directory, this method links
# all its contents recursively. If +dest+ is a directory, links
# +src+ to +dest/src+.
#
# +src+ can be a list of files.
#
# # Installing the library "mylib" under the site_ruby directory.
# Bundler::FileUtils.rm_r site_ruby + '/mylib', :force => true
# Bundler::FileUtils.cp_lr 'lib/', site_ruby + '/mylib'
#
# # Examples of linking several files to target directory.
# Bundler::FileUtils.cp_lr %w(mail.rb field.rb debug/), site_ruby + '/tmail'
# Bundler::FileUtils.cp_lr Dir.glob('*.rb'), '/home/aamine/lib/ruby', :noop => true, :verbose => true
#
# # If you want to link all contents of a directory instead of the
# # directory itself, c.f. src/x -> dest/x, src/y -> dest/y,
# # use the following code.
# Bundler::FileUtils.cp_lr 'src/.', 'dest' # cp_lr('src', 'dest') makes dest/src, but this doesn't.
#
def cp_lr(src, dest, noop: nil, verbose: nil,
dereference_root: true, remove_destination: false)
fu_output_message "cp -lr#{remove_destination ? ' --remove-destination' : ''} #{[src,dest].flatten.join ' '}" if verbose
return if noop
fu_each_src_dest(src, dest) do |s, d|
link_entry s, d, dereference_root, remove_destination
end
end
module_function :cp_lr
#
# :call-seq:
# Bundler::FileUtils.ln_s(target, link, force: nil, noop: nil, verbose: nil)
@ -339,6 +383,26 @@ module Bundler::FileUtils
end
module_function :ln_sf
#
# Hard links a file system entry +src+ to +dest+.
# If +src+ is a directory, this method links its contents recursively.
#
# Both of +src+ and +dest+ must be a path name.
# +src+ must exist, +dest+ must not exist.
#
# If +dereference_root+ is true, this method dereferences the tree root.
#
# If +remove_destination+ is true, this method removes each destination file before copy.
#
def link_entry(src, dest, dereference_root = false, remove_destination = false)
Entry_.new(src, nil, dereference_root).traverse do |ent|
destent = Entry_.new(dest, ent.rel, false)
File.unlink destent.path if remove_destination && File.file?(destent.path)
ent.link destent.path
end
end
module_function :link_entry
#
# Copies a file content +src+ to +dest+. If +dest+ is a directory,
# copies +src+ to +dest/src+.
@ -412,7 +476,7 @@ module Bundler::FileUtils
def copy_entry(src, dest, preserve = false, dereference_root = false, remove_destination = false)
Entry_.new(src, nil, dereference_root).wrap_traverse(proc do |ent|
destent = Entry_.new(dest, ent.rel, false)
File.unlink destent.path if remove_destination && File.file?(destent.path)
File.unlink destent.path if remove_destination && (File.file?(destent.path) || File.symlink?(destent.path))
ent.copy destent.path
end, proc do |ent|
destent = Entry_.new(dest, ent.rel, false)
@ -461,13 +525,12 @@ module Bundler::FileUtils
if destent.exist?
if destent.directory?
raise Errno::EEXIST, d
else
destent.remove_file if rename_cannot_overwrite_file?
end
end
begin
File.rename s, d
rescue Errno::EXDEV
rescue Errno::EXDEV,
Errno::EPERM # move from unencrypted to encrypted dir (ext4)
copy_entry s, d, true
if secure
remove_entry_secure s, force
@ -485,11 +548,6 @@ module Bundler::FileUtils
alias move mv
module_function :move
def rename_cannot_overwrite_file? #:nodoc:
/emx/ =~ RUBY_PLATFORM
end
private_module_function :rename_cannot_overwrite_file?
#
# Remove file(s) specified in +list+. This method cannot remove directories.
# All StandardErrors are ignored when the :force option is set.
@ -601,8 +659,8 @@ module Bundler::FileUtils
#
# For details of this security vulnerability, see Perl's case:
#
# * http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2005-0448
# * http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2004-0452
# * https://cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2005-0448
# * https://cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2004-0452
#
# For fileutils.rb, this vulnerability is reported in [ruby-dev:26100].
#
@ -626,22 +684,38 @@ module Bundler::FileUtils
unless parent_st.sticky?
raise ArgumentError, "parent directory is world writable, Bundler::FileUtils#remove_entry_secure does not work; abort: #{path.inspect} (parent directory mode #{'%o' % parent_st.mode})"
end
# freeze tree root
euid = Process.euid
File.open(fullpath + '/.') {|f|
unless fu_stat_identical_entry?(st, f.stat)
# symlink (TOC-to-TOU attack?)
File.unlink fullpath
return
end
f.chown euid, -1
f.chmod 0700
unless fu_stat_identical_entry?(st, File.lstat(fullpath))
# TOC-to-TOU attack?
File.unlink fullpath
return
end
}
dot_file = fullpath + "/."
begin
File.open(dot_file) {|f|
unless fu_stat_identical_entry?(st, f.stat)
# symlink (TOC-to-TOU attack?)
File.unlink fullpath
return
end
f.chown euid, -1
f.chmod 0700
}
rescue Errno::EISDIR # JRuby in non-native mode can't open files as dirs
File.lstat(dot_file).tap {|fstat|
unless fu_stat_identical_entry?(st, fstat)
# symlink (TOC-to-TOU attack?)
File.unlink fullpath
return
end
File.chown euid, -1, dot_file
File.chmod 0700, dot_file
}
end
unless fu_stat_identical_entry?(st, File.lstat(fullpath))
# TOC-to-TOU attack?
File.unlink fullpath
return
end
# ---- tree root is frozen ----
root = Entry_.new(path)
root.preorder_traverse do |ent|
@ -742,8 +816,15 @@ module Bundler::FileUtils
#
def compare_stream(a, b)
bsize = fu_stream_blksize(a, b)
sa = String.new(capacity: bsize)
sb = String.new(capacity: bsize)
if RUBY_VERSION > "2.4"
sa = String.new(capacity: bsize)
sb = String.new(capacity: bsize)
else
sa = String.new
sb = String.new
end
begin
a.read(bsize, sa)
b.read(bsize, sb)
@ -1001,11 +1082,6 @@ module Bundler::FileUtils
end
module_function :chown_R
begin
require 'etc'
rescue LoadError # rescue LoadError for miniruby
end
def fu_get_uid(user) #:nodoc:
return nil unless user
case user
@ -1014,6 +1090,7 @@ module Bundler::FileUtils
when /\A\d+\z/
user.to_i
else
require 'etc'
Etc.getpwnam(user) ? Etc.getpwnam(user).uid : nil
end
end
@ -1027,6 +1104,7 @@ module Bundler::FileUtils
when /\A\d+\z/
group.to_i
else
require 'etc'
Etc.getgrnam(group) ? Etc.getgrnam(group).gid : nil
end
end
@ -1067,8 +1145,11 @@ module Bundler::FileUtils
module StreamUtils_
private
def fu_windows?
/mswin|mingw|bccwin|emx/ =~ RUBY_PLATFORM
case (defined?(::RbConfig) ? ::RbConfig::CONFIG['host_os'] : ::RUBY_PLATFORM)
when /mswin|mingw/
def fu_windows?; true end
else
def fu_windows?; false end
end
def fu_copy_stream0(src, dest, blksize = nil) #:nodoc:
@ -1193,9 +1274,15 @@ module Bundler::FileUtils
def entries
opts = {}
opts[:encoding] = ::Encoding::UTF_8 if fu_windows?
Dir.entries(path(), opts)\
.reject {|n| n == '.' or n == '..' }\
.map {|n| Entry_.new(prefix(), join(rel(), n.untaint)) }
files = if Dir.respond_to?(:children)
Dir.children(path, opts)
else
Dir.entries(path(), opts)
.reject {|n| n == '.' or n == '..' }
end
files.map {|n| Entry_.new(prefix(), join(rel(), n.untaint)) }
end
def stat
@ -1250,6 +1337,22 @@ module Bundler::FileUtils
end
end
def link(dest)
case
when directory?
if !File.exist?(dest) and descendant_directory?(dest, path)
raise ArgumentError, "cannot link directory %s to itself %s" % [path, dest]
end
begin
Dir.mkdir dest
rescue
raise unless File.directory?(dest)
end
else
File.link path(), dest
end
end
def copy(dest)
lstat
case

View file

@ -0,0 +1,5 @@
# frozen_string_literal: true
module Bundler::FileUtils
VERSION = "1.2.0"
end

View file

@ -50,14 +50,25 @@ module Bundler::Molinillo
incoming_edges.map(&:origin)
end
# @return [Array<Vertex>] the vertices of {#graph} where `self` is a
# @return [Set<Vertex>] the vertices of {#graph} where `self` is a
# {#descendent?}
def recursive_predecessors
vertices = predecessors
vertices += Compatibility.flat_map(vertices, &:recursive_predecessors)
vertices.uniq!
_recursive_predecessors
end
# @param [Set<Vertex>] vertices the set to add the predecessors to
# @return [Set<Vertex>] the vertices of {#graph} where `self` is a
# {#descendent?}
def _recursive_predecessors(vertices = Set.new)
incoming_edges.each do |edge|
vertex = edge.origin
next unless vertices.add?(vertex)
vertex._recursive_predecessors(vertices)
end
vertices
end
protected :_recursive_predecessors
# @return [Array<Vertex>] the vertices of {#graph} that have an edge with
# `self` as their {Edge#origin}
@ -65,14 +76,25 @@ module Bundler::Molinillo
outgoing_edges.map(&:destination)
end
# @return [Array<Vertex>] the vertices of {#graph} where `self` is an
# @return [Set<Vertex>] the vertices of {#graph} where `self` is an
# {#ancestor?}
def recursive_successors
vertices = successors
vertices += Compatibility.flat_map(vertices, &:recursive_successors)
vertices.uniq!
_recursive_successors
end
# @param [Set<Vertex>] vertices the set to add the successors to
# @return [Set<Vertex>] the vertices of {#graph} where `self` is an
# {#ancestor?}
def _recursive_successors(vertices = Set.new)
outgoing_edges.each do |edge|
vertex = edge.destination
next unless vertices.add?(vertex)
vertex._recursive_successors(vertices)
end
vertices
end
protected :_recursive_successors
# @return [String] a string suitable for debugging
def inspect

View file

@ -113,8 +113,10 @@ class Bundler::Thor
# the script started).
#
def relative_to_original_destination_root(path, remove_dot = true)
path = path.dup
if path.gsub!(@destination_stack[0], ".")
root = @destination_stack[0]
if path.start_with?(root) && [File::SEPARATOR, File::ALT_SEPARATOR, nil, ''].include?(path[root.size..root.size])
path = path.dup
path[0...root.size] = '.'
remove_dot ? (path[2..-1] || "") : path
else
path
@ -217,6 +219,7 @@ class Bundler::Thor
shell.padding += 1 if verbose
contents = if is_uri
require "open-uri"
open(path, "Accept" => "application/x-thor-template", &:read)
else
open(path, &:read)
@ -252,9 +255,16 @@ class Bundler::Thor
say_status :run, desc, config.fetch(:verbose, true)
unless options[:pretend]
config[:capture] ? `#{command}` : system(command.to_s)
return if options[:pretend]
result = config[:capture] ? `#{command}` : system(command.to_s)
if config[:abort_on_failure]
success = config[:capture] ? $?.success? : result
abort unless success
end
result
end
# Executes a ruby script (taking into account WIN32 platform quirks).

View file

@ -60,6 +60,9 @@ class Bundler::Thor
# destination. If a block is given instead of destination, the content of
# the url is yielded and used as location.
#
# +get+ relies on open-uri, so passing application user input would provide
# a command injection attack vector.
#
# ==== Parameters
# source<String>:: the address of the given content.
# destination<String>:: the relative path to the destination root.
@ -117,7 +120,13 @@ class Bundler::Thor
context = config.delete(:context) || instance_eval("binding")
create_file destination, nil, config do
content = CapturableERB.new(::File.binread(source), nil, "-", "@output_buffer").tap do |erb|
match = ERB.version.match(/(\d+\.\d+\.\d+)/)
capturable_erb = if match && match[1] >= "2.2.0" # Ruby 2.6+
CapturableERB.new(::File.binread(source), :trim_mode => "-", :eoutvar => "@output_buffer")
else
CapturableERB.new(::File.binread(source), nil, "-", "@output_buffer")
end
content = capturable_erb.tap do |erb|
erb.filename = source
end.result(context)
content = yield(content) if block
@ -301,7 +310,7 @@ class Bundler::Thor
def comment_lines(path, flag, *args)
flag = flag.respond_to?(:source) ? flag.source : flag
gsub_file(path, /^(\s*)([^#|\n]*#{flag})/, '\1# \2', *args)
gsub_file(path, /^(\s*)([^#\n]*#{flag})/, '\1# \2', *args)
end
# Removes a file at the given location.

View file

@ -113,7 +113,7 @@ class Bundler::Thor
end
# Whenever a class inherits from Bundler::Thor or Bundler::Thor::Group, we should track the
# class and the file on Bundler::Thor::Base. This is the method responsable for it.
# class and the file on Bundler::Thor::Base. This is the method responsible for it.
#
def register_klass_file(klass) #:nodoc:
file = caller[1].match(/(.*):\d+/)[1]
@ -466,13 +466,13 @@ class Bundler::Thor
dispatch(nil, given_args.dup, nil, config)
rescue Bundler::Thor::Error => e
config[:debug] || ENV["THOR_DEBUG"] == "1" ? (raise e) : config[:shell].error(e.message)
exit(1) if exit_on_failure?
exit(false) if exit_on_failure?
rescue Errno::EPIPE
# This happens if a thor command is piped to something like `head`,
# which closes the pipe when it's done reading. This will also
# mean that if the pipe is closed, further unnecessary
# computation will not occur.
exit(0)
exit(true)
end
# Allows to use private methods from parent in child classes as commands.
@ -493,8 +493,7 @@ class Bundler::Thor
alias_method :public_task, :public_command
def handle_no_command_error(command, has_namespace = $thor_runner) #:nodoc:
raise UndefinedCommandError, "Could not find command #{command.inspect} in #{namespace.inspect} namespace." if has_namespace
raise UndefinedCommandError, "Could not find command #{command.inspect}."
raise UndefinedCommandError.new(command, all_commands.keys, (namespace if has_namespace))
end
alias_method :handle_no_task_error, :handle_no_command_error

View file

@ -1,4 +1,23 @@
class Bundler::Thor
Correctable =
begin
require 'did_you_mean'
# In order to support versions of Ruby that don't have keyword
# arguments, we need our own spell checker class that doesn't take key
# words. Even though this code wouldn't be hit because of the check
# above, it's still necessary because the interpreter would otherwise be
# unable to parse the file.
class NoKwargSpellChecker < DidYouMean::SpellChecker # :nodoc:
def initialize(dictionary)
@dictionary = dictionary
end
end
DidYouMean::Correctable
rescue LoadError, NameError
end
# Bundler::Thor::Error is raised when it's caused by wrong usage of thor classes. Those
# errors have their backtrace suppressed and are nicely shown to the user.
#
@ -10,6 +29,35 @@ class Bundler::Thor
# Raised when a command was not found.
class UndefinedCommandError < Error
class SpellChecker
attr_reader :error
def initialize(error)
@error = error
end
def corrections
@corrections ||= spell_checker.correct(error.command).map(&:inspect)
end
def spell_checker
NoKwargSpellChecker.new(error.all_commands)
end
end
attr_reader :command, :all_commands
def initialize(command, all_commands, namespace)
@command = command
@all_commands = all_commands
message = "Could not find command #{command.inspect}"
message = namespace ? "#{message} in #{namespace.inspect} namespace." : "#{message}."
super(message)
end
prepend Correctable if Correctable
end
UndefinedTaskError = UndefinedCommandError
@ -22,6 +70,33 @@ class Bundler::Thor
end
class UnknownArgumentError < Error
class SpellChecker
attr_reader :error
def initialize(error)
@error = error
end
def corrections
@corrections ||=
error.unknown.flat_map { |unknown| spell_checker.correct(unknown) }.uniq.map(&:inspect)
end
def spell_checker
@spell_checker ||= NoKwargSpellChecker.new(error.switches)
end
end
attr_reader :switches, :unknown
def initialize(switches, unknown)
@switches = switches
@unknown = unknown
super("Unknown switches #{unknown.map(&:inspect).join(', ')}")
end
prepend Correctable if Correctable
end
class RequiredArgumentMissingError < InvocationError
@ -29,4 +104,11 @@ class Bundler::Thor
class MalformattedArgumentError < InvocationError
end
if Correctable
DidYouMean::SPELL_CHECKERS.merge!(
'Bundler::Thor::UndefinedCommandError' => UndefinedCommandError::SpellChecker,
'Bundler::Thor::UnknownArgumentError' => UnknownArgumentError::SpellChecker
)
end
end

View file

@ -61,7 +61,7 @@ class Bundler::Thor::Group
invocations[name] = false
invocation_blocks[name] = block if block_given?
class_eval <<-METHOD, __FILE__, __LINE__
class_eval <<-METHOD, __FILE__, __LINE__ + 1
def _invoke_#{name.to_s.gsub(/\W/, '_')}
klass, command = self.class.prepare_for_invocation(nil, #{name.inspect})
@ -120,7 +120,7 @@ class Bundler::Thor::Group
invocations[name] = true
invocation_blocks[name] = block if block_given?
class_eval <<-METHOD, __FILE__, __LINE__
class_eval <<-METHOD, __FILE__, __LINE__ + 1
def _invoke_from_option_#{name.to_s.gsub(/\W/, '_')}
return unless options[#{name.inspect}]

View file

@ -44,6 +44,7 @@ class Bundler::Thor
@shorts = {}
@switches = {}
@extra = []
@stopped_parsing_after_extra_index = nil
options.each do |option|
@switches[option.switch_name] = option
@ -66,6 +67,7 @@ class Bundler::Thor
if result == OPTS_END
shift
@parsing_options = false
@stopped_parsing_after_extra_index ||= @extra.size
super
else
result
@ -99,6 +101,7 @@ class Bundler::Thor
elsif @stop_on_unknown
@parsing_options = false
@extra << shifted
@stopped_parsing_after_extra_index ||= @extra.size
@extra << shift while peek
break
elsif match
@ -120,9 +123,11 @@ class Bundler::Thor
end
def check_unknown!
to_check = @stopped_parsing_after_extra_index ? @extra[0...@stopped_parsing_after_extra_index] : @extra
# an unknown option starts with - or -- and has no more --'s afterward.
unknown = @extra.select { |str| str =~ /^--?(?:(?!--).)*$/ }
raise UnknownArgumentError, "Unknown switches '#{unknown.join(', ')}'" unless unknown.empty?
unknown = to_check.select { |str| str =~ /^--?(?:(?!--).)*$/ }
raise UnknownArgumentError.new(@switches.keys, unknown) unless unknown.empty?
end
protected

View file

@ -3,7 +3,7 @@ require "bundler/vendor/thor/lib/thor/group"
require "bundler/vendor/thor/lib/thor/core_ext/io_binary_read"
require "yaml"
require "digest"
require "digest/md5"
require "pathname"
class Bundler::Thor::Runner < Bundler::Thor #:nodoc: # rubocop:disable ClassLength
@ -90,7 +90,7 @@ class Bundler::Thor::Runner < Bundler::Thor #:nodoc: # rubocop:disable ClassLeng
end
thor_yaml[as] = {
:filename => Digest(:MD5).hexdigest(name + as),
:filename => Digest::MD5.hexdigest(name + as),
:location => location,
:namespaces => Bundler::Thor::Util.namespaces_in_content(contents, base)
}

View file

@ -55,7 +55,7 @@ class Bundler::Thor
# Common methods that are delegated to the shell.
SHELL_DELEGATED_METHODS.each do |method|
module_eval <<-METHOD, __FILE__, __LINE__
module_eval <<-METHOD, __FILE__, __LINE__ + 1
def #{method}(*args,&block)
shell.#{method}(*args,&block)
end

View file

@ -1,6 +1,8 @@
class Bundler::Thor
module Shell
class Basic
DEFAULT_TERMINAL_WIDTH = 80
attr_accessor :base
attr_reader :padding
@ -45,6 +47,10 @@ class Bundler::Thor
# Asks something to the user and receives a response.
#
# If a default value is specified it will be presented to the user
# and allows them to select that value with an empty response. This
# option is ignored when limited answers are supplied.
#
# If asked to limit the correct responses, you can pass in an
# array of acceptable answers. If one of those is not supplied,
# they will be shown a message stating that one of those answers
@ -61,6 +67,8 @@ class Bundler::Thor
# ==== Example
# ask("What is your name?")
#
# ask("What is the planet furthest from the sun?", :default => "Pluto")
#
# ask("What is your favorite Neopolitan flavor?", :limited_to => ["strawberry", "chocolate", "vanilla"])
#
# ask("What is your password?", :echo => false)
@ -222,8 +230,20 @@ class Bundler::Thor
paras = message.split("\n\n")
paras.map! do |unwrapped|
unwrapped.strip.tr("\n", " ").squeeze(" ").gsub(/.{1,#{width}}(?:\s|\Z)/) { ($& + 5.chr).gsub(/\n\005/, "\n").gsub(/\005/, "\n") }
end
counter = 0
unwrapped.split(" ").inject do |memo, word|
word = word.gsub(/\n\005/, "\n").gsub(/\005/, "\n")
counter = 0 if word.include? "\n"
if (counter + word.length + 1) < width
memo = "#{memo} #{word}"
counter += (word.length + 1)
else
memo = "#{memo}\n#{word}"
counter = word.length
end
memo
end
end.compact!
paras.each do |para|
para.split("\n").each do |line|
@ -239,11 +259,11 @@ class Bundler::Thor
#
# ==== Parameters
# destination<String>:: the destination file to solve conflicts
# block<Proc>:: an optional block that returns the value to be used in diff
# block<Proc>:: an optional block that returns the value to be used in diff and merge
#
def file_collision(destination)
return true if @always_force
options = block_given? ? "[Ynaqdh]" : "[Ynaqh]"
options = block_given? ? "[Ynaqdhm]" : "[Ynaqh]"
loop do
answer = ask(
@ -267,6 +287,13 @@ class Bundler::Thor
when is?(:diff)
show_diff(destination, yield) if block_given?
say "Retrying..."
when is?(:merge)
if block_given? && !merge_tool.empty?
merge(destination, yield)
return nil
end
say "Please specify merge tool to `THOR_MERGE` env."
else
say file_collision_help
end
@ -279,11 +306,11 @@ class Bundler::Thor
result = if ENV["THOR_COLUMNS"]
ENV["THOR_COLUMNS"].to_i
else
unix? ? dynamic_width : 80
unix? ? dynamic_width : DEFAULT_TERMINAL_WIDTH
end
result < 10 ? 80 : result
result < 10 ? DEFAULT_TERMINAL_WIDTH : result
rescue
80
DEFAULT_TERMINAL_WIDTH
end
# Called if something goes wrong during the execution. This is used by Bundler::Thor
@ -344,6 +371,7 @@ class Bundler::Thor
q - quit, abort
d - diff, show the differences between the old and the new
h - help, show this help
m - merge, run merge tool
HELP
end
@ -432,6 +460,23 @@ class Bundler::Thor
end
correct_answer
end
def merge(destination, content) #:nodoc:
require "tempfile"
Tempfile.open([File.basename(destination), File.extname(destination)], File.dirname(destination)) do |temp|
temp.write content
temp.rewind
system %(#{merge_tool} "#{temp.path}" "#{destination}")
end
end
def merge_tool #:nodoc:
@merge_tool ||= ENV["THOR_MERGE"] || git_merge_tool
end
def git_merge_tool #:nodoc:
`git config merge.tool`.rstrip rescue ""
end
end
end
end

View file

@ -27,7 +27,7 @@ class Bundler::Thor
end
# Receives a constant and converts it to a Bundler::Thor namespace. Since Bundler::Thor
# commands can be added to a sandbox, this method is also responsable for
# commands can be added to a sandbox, this method is also responsible for
# removing the sandbox namespace.
#
# This method should not be used in general because it's used to deal with

View file

@ -1,3 +1,3 @@
class Bundler::Thor
VERSION = "0.20.0"
VERSION = "0.20.3"
end

View file

@ -1,13 +1,10 @@
# frozen_string_literal: false
# Ruby 1.9.3 and old RubyGems don't play nice with frozen version strings
# rubocop:disable MutableConstant
module Bundler
# We're doing this because we might write tests that deal
# with other versions of bundler and we are unsure how to
# handle this better.
VERSION = "2.0.1" unless defined?(::Bundler::VERSION)
VERSION = "2.1.0.pre.1".freeze unless defined?(::Bundler::VERSION)
def self.overwrite_loaded_gem_version
begin

View file

@ -5,11 +5,42 @@ module Bundler
NEq = Struct.new(:version)
ReqR = Struct.new(:left, :right)
class ReqR
Endpoint = Struct.new(:version, :inclusive)
Endpoint = Struct.new(:version, :inclusive) do
def <=>(other)
if version.equal?(INFINITY)
return 0 if other.version.equal?(INFINITY)
return 1
elsif other.version.equal?(INFINITY)
return -1
end
comp = version <=> other.version
return comp unless comp.zero?
if inclusive && !other.inclusive
1
elsif !inclusive && other.inclusive
-1
else
0
end
end
end
def to_s
"#{left.inclusive ? "[" : "("}#{left.version}, #{right.version}#{right.inclusive ? "]" : ")"}"
end
INFINITY = Object.new.freeze
INFINITY = begin
inf = Object.new
def inf.to_s
""
end
def inf.<=>(other)
return 0 if other.equal?(self)
1
end
inf.freeze
end
ZERO = Gem::Version.new("0.a")
def cover?(v)
@ -32,6 +63,15 @@ module Bundler
left.version == right.version
end
def <=>(other)
return -1 if other.equal?(INFINITY)
comp = left <=> other.left
return comp unless comp.zero?
right <=> other.right
end
UNIVERSAL = ReqR.new(ReqR::Endpoint.new(Gem::Version.new("0.a"), true), ReqR::Endpoint.new(ReqR::INFINITY, false)).freeze
end
@ -57,7 +97,7 @@ module Bundler
end.uniq
ranges, neqs = ranges.partition {|r| !r.is_a?(NEq) }
[ranges.sort_by {|range| [range.left.version, range.left.inclusive ? 0 : 1] }, neqs.map(&:version)]
[ranges.sort, neqs.map(&:version)]
end
def self.empty?(ranges, neqs)
@ -66,8 +106,14 @@ module Bundler
next false if curr_range.single? && neqs.include?(curr_range.left.version)
next curr_range if last_range.right.version == ReqR::INFINITY
case last_range.right.version <=> curr_range.left.version
when 1 then next curr_range
when 0 then next(last_range.right.inclusive && curr_range.left.inclusive && !neqs.include?(curr_range.left.version) && curr_range)
# higher
when 1 then next ReqR.new(curr_range.left, last_range.right)
# equal
when 0
if last_range.right.inclusive && curr_range.left.inclusive && !neqs.include?(curr_range.left.version)
ReqR.new(curr_range.left, [curr_range.right, last_range.right].max)
end
# lower
when -1 then next false
end
end

View file

@ -1,7 +1,7 @@
# frozen_string_literal: true
require "bundler/shared_helpers"
Bundler::SharedHelpers.major_deprecation 3,
Bundler::SharedHelpers.major_deprecation 2,
"The Bundler task for Vlad"
# Vlad task for Bundler.

View file

@ -1,7 +1,5 @@
# frozen_string_literal: true
require "thread"
module Bundler
class Worker
POISON = Object.new
@ -62,7 +60,7 @@ module Bundler
def apply_func(obj, i)
@func.call(obj, i)
rescue Exception => e
rescue Exception => e # rubocop:disable Lint/RescueException
WrappedException.new(e)
end

View file

@ -32,7 +32,7 @@ module Bundler
(.*) # value
\1 # matching closing quote
$
/xo
/xo.freeze
HASH_REGEX = /
^
@ -40,12 +40,11 @@ module Bundler
(.+) # key
(?::(?=(?:\s|$))) # : (without the lookahead the #key includes this when : is present in value)
[ ]?
(?: !\s)? # optional exclamation mark found with ruby 1.9.3
(['"]?) # optional opening quote
(.*) # value
\3 # matching closing quote
$
/xo
/xo.freeze
def load(str)
res = {}

View file

@ -1,60 +0,0 @@
#!/usr/bin/env ruby
# frozen_string_literal: true
require "bundler/shared_helpers"
Bundler::SharedHelpers.major_deprecation(3, "the bundle_ruby executable has been removed in favor of `bundle platform --ruby`")
Signal.trap("INT") { exit 1 }
require "bundler/errors"
require "bundler/ruby_version"
require "bundler/ruby_dsl"
module Bundler
class Dsl
include RubyDsl
attr_accessor :ruby_version
def initialize
@ruby_version = nil
end
def eval_gemfile(gemfile, contents = nil)
contents ||= File.open(gemfile, "rb", &:read)
instance_eval(contents, gemfile.to_s, 1)
rescue SyntaxError => e
bt = e.message.split("\n")[1..-1]
raise GemfileError, ["Gemfile syntax error:", *bt].join("\n")
rescue ScriptError, RegexpError, NameError, ArgumentError => e
e.backtrace[0] = "#{e.backtrace[0]}: #{e.message} (#{e.class})"
STDERR.puts e.backtrace.join("\n ")
raise GemfileError, "There was an error in your Gemfile," \
" and Bundler cannot continue."
end
def source(source, options = {})
end
def gem(name, *args)
end
def group(*args)
end
end
end
dsl = Bundler::Dsl.new
begin
dsl.eval_gemfile(Bundler::SharedHelpers.default_gemfile)
ruby_version = dsl.ruby_version
if ruby_version
puts ruby_version
else
puts "No ruby version specified"
end
rescue Bundler::GemfileError => e
puts e.message
exit(-1)
end

View file

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "BUNDLE\-ADD" "1" "November 2018" "" ""
.TH "BUNDLE\-ADD" "1" "March 2019" "" ""
.
.SH "NAME"
\fBbundle\-add\fR \- Add gem to the Gemfile and run bundle install

View file

@ -2,16 +2,16 @@ BUNDLE-ADD(1) BUNDLE-ADD(1)
1mNAME0m
1mbundle-add 22m- Add gem to the Gemfile and run bundle install
NAME
bundle-add - Add gem to the Gemfile and run bundle install
1mSYNOPSIS0m
1mbundle add 4m22mGEM_NAME24m [--group=GROUP] [--version=VERSION]
SYNOPSIS
bundle add GEM_NAME [--group=GROUP] [--version=VERSION]
[--source=SOURCE] [--skip-install] [--strict] [--optimistic]
1mDESCRIPTION0m
Adds the named gem to the Gemfile and run 1mbundle install22m. 1mbundle in-0m
1mstall 22mcan be avoided by using the flag 1m--skip-install22m.
DESCRIPTION
Adds the named gem to the Gemfile and run bundle install. bundle
install can be avoided by using the flag --skip-install.
Example:
@ -26,27 +26,27 @@ BUNDLE-ADD(1) BUNDLE-ADD(1)
bundle add rails --group "development, test"
1mOPTIONS0m
1m--version22m, 1m-v0m
OPTIONS
--version, -v
Specify version requirements(s) for the added gem.
1m--group22m, 1m-g0m
--group, -g
Specify the group(s) for the added gem. Multiple groups should
be separated by commas.
1m--source22m, , 1m-s0m
--source, , -s
Specify the source for the added gem.
1m--skip-install0m
--skip-install
Adds the gem to the Gemfile but does not install it.
1m--optimistic0m
--optimistic
Adds optimistic declaration of version
1m--strict0m
--strict
Adds strict declaration of version
November 2018 BUNDLE-ADD(1)
March 2019 BUNDLE-ADD(1)

View file

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "BUNDLE\-BINSTUBS" "1" "November 2018" "" ""
.TH "BUNDLE\-BINSTUBS" "1" "March 2019" "" ""
.
.SH "NAME"
\fBbundle\-binstubs\fR \- Install the binstubs of the listed gems

Some files were not shown because too many files have changed in this diff Show more