summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHiroshi SHIBATA <hsbt@ruby-lang.org>2021-04-15 12:47:04 +0900
committerHiroshi SHIBATA <hsbt@ruby-lang.org>2021-04-15 15:36:15 +0900
commited149dbf46d1a8b16e6de9c3dbbcc10f72c9c019 (patch)
tree1c8c755fa592e280dc7718dc8a9317d1ac368394
parent0d9496f924d36534bd524791554d49dc0026b0e0 (diff)
Merge the master branch of Bundler
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/4383
-rw-r--r--lib/bundler.rb2
-rw-r--r--lib/bundler/cli.rb9
-rw-r--r--lib/bundler/cli/common.rb15
-rw-r--r--lib/bundler/cli/gem.rb77
-rw-r--r--lib/bundler/cli/install.rb8
-rw-r--r--lib/bundler/cli/outdated.rb2
-rw-r--r--lib/bundler/compact_index_client/updater.rb4
-rw-r--r--lib/bundler/definition.rb32
-rw-r--r--lib/bundler/dsl.rb9
-rw-r--r--lib/bundler/feature_flag.rb2
-rw-r--r--lib/bundler/gem_helper.rb16
-rw-r--r--lib/bundler/injector.rb4
-rw-r--r--lib/bundler/inline.rb2
-rw-r--r--lib/bundler/installer/parallel_installer.rb51
-rw-r--r--lib/bundler/lazy_specification.rb7
-rw-r--r--lib/bundler/lockfile_parser.rb18
-rw-r--r--lib/bundler/man/bundle-add.12
-rw-r--r--lib/bundler/man/bundle-binstubs.12
-rw-r--r--lib/bundler/man/bundle-cache.12
-rw-r--r--lib/bundler/man/bundle-check.12
-rw-r--r--lib/bundler/man/bundle-clean.12
-rw-r--r--lib/bundler/man/bundle-config.18
-rw-r--r--lib/bundler/man/bundle-config.1.ronn7
-rw-r--r--lib/bundler/man/bundle-doctor.12
-rw-r--r--lib/bundler/man/bundle-exec.12
-rw-r--r--lib/bundler/man/bundle-gem.115
-rw-r--r--lib/bundler/man/bundle-gem.1.ronn16
-rw-r--r--lib/bundler/man/bundle-info.12
-rw-r--r--lib/bundler/man/bundle-init.12
-rw-r--r--lib/bundler/man/bundle-inject.12
-rw-r--r--lib/bundler/man/bundle-install.12
-rw-r--r--lib/bundler/man/bundle-list.12
-rw-r--r--lib/bundler/man/bundle-lock.12
-rw-r--r--lib/bundler/man/bundle-open.12
-rw-r--r--lib/bundler/man/bundle-outdated.12
-rw-r--r--lib/bundler/man/bundle-platform.12
-rw-r--r--lib/bundler/man/bundle-pristine.12
-rw-r--r--lib/bundler/man/bundle-remove.12
-rw-r--r--lib/bundler/man/bundle-show.12
-rw-r--r--lib/bundler/man/bundle-update.12
-rw-r--r--lib/bundler/man/bundle-viz.12
-rw-r--r--lib/bundler/man/bundle.12
-rw-r--r--lib/bundler/man/gemfile.52
-rw-r--r--lib/bundler/plugin/api/source.rb7
-rw-r--r--lib/bundler/settings.rb2
-rw-r--r--lib/bundler/source.rb6
-rw-r--r--lib/bundler/source/metadata.rb4
-rw-r--r--lib/bundler/source/path.rb4
-rw-r--r--lib/bundler/source/path/installer.rb2
-rw-r--r--lib/bundler/source/rubygems.rb24
-rw-r--r--lib/bundler/source_list.rb20
-rw-r--r--lib/bundler/spec_set.rb2
-rw-r--r--lib/bundler/templates/Gemfile2
-rw-r--r--lib/bundler/templates/gems.rb2
-rw-r--r--lib/bundler/templates/newgem/Gemfile.tt7
-rw-r--r--lib/bundler/templates/newgem/Rakefile.tt6
-rw-r--r--lib/bundler/templates/newgem/github/workflows/main.yml.tt6
-rw-r--r--lib/bundler/templates/newgem/newgem.gemspec.tt24
-rw-r--r--lib/bundler/templates/newgem/standard.yml.tt4
-rw-r--r--lib/bundler/vendor/tmpdir/lib/tmpdir.rb2
-rw-r--r--spec/bundler/bundler/dep_proxy_spec.rb2
-rw-r--r--spec/bundler/bundler/gem_helper_spec.rb39
-rw-r--r--spec/bundler/bundler/installer/parallel_installer_spec.rb33
-rw-r--r--spec/bundler/bundler/installer/spec_installation_spec.rb4
-rw-r--r--spec/bundler/bundler/source_list_spec.rb21
-rw-r--r--spec/bundler/commands/info_spec.rb14
-rw-r--r--spec/bundler/commands/lock_spec.rb2
-rw-r--r--spec/bundler/commands/newgem_spec.rb410
-rw-r--r--spec/bundler/commands/outdated_spec.rb50
-rw-r--r--spec/bundler/commands/post_bundle_message_spec.rb24
-rw-r--r--spec/bundler/commands/update_spec.rb100
-rw-r--r--spec/bundler/install/deploy_spec.rb20
-rw-r--r--spec/bundler/install/gemfile/gemspec_spec.rb4
-rw-r--r--spec/bundler/install/gemfile/path_spec.rb7
-rw-r--r--spec/bundler/install/gemfile/sources_spec.rb506
-rw-r--r--spec/bundler/install/gemfile/specific_platform_spec.rb44
-rw-r--r--spec/bundler/install/gems/flex_spec.rb32
-rw-r--r--spec/bundler/install/gems/resolving_spec.rb45
-rw-r--r--spec/bundler/install/gems/sudo_spec.rb17
-rw-r--r--spec/bundler/install/git_spec.rb2
-rw-r--r--spec/bundler/lock/lockfile_spec.rb59
-rw-r--r--spec/bundler/other/major_deprecation_spec.rb112
-rw-r--r--spec/bundler/quality_spec.rb1
-rw-r--r--spec/bundler/realworld/fixtures/warbler/Gemfile.lock5
-rw-r--r--spec/bundler/runtime/inline_spec.rb13
-rw-r--r--spec/bundler/runtime/platform_spec.rb38
-rw-r--r--spec/bundler/runtime/setup_spec.rb12
-rw-r--r--spec/bundler/spec_helper.rb13
-rw-r--r--spec/bundler/support/builders.rb44
-rw-r--r--spec/bundler/support/bundle.rb8
-rw-r--r--spec/bundler/support/hax.rb2
-rw-r--r--spec/bundler/support/helpers.rb4
-rw-r--r--spec/bundler/support/matchers.rb51
-rw-r--r--spec/bundler/support/path.rb40
-rw-r--r--spec/bundler/support/rubygems_ext.rb69
95 files changed, 1757 insertions, 564 deletions
diff --git a/lib/bundler.rb b/lib/bundler.rb
index d370d8a53a..9f7f9b218f 100644
--- a/lib/bundler.rb
+++ b/lib/bundler.rb
@@ -197,7 +197,7 @@ module Bundler
def frozen_bundle?
frozen = settings[:deployment]
- frozen ||= settings[:frozen] unless feature_flag.deployment_means_frozen?
+ frozen ||= settings[:frozen]
frozen
end
diff --git a/lib/bundler/cli.rb b/lib/bundler/cli.rb
index 421f42cb52..b924edb28e 100644
--- a/lib/bundler/cli.rb
+++ b/lib/bundler/cli.rb
@@ -475,6 +475,12 @@ module Bundler
"do in future versions. Instead please use `bundle config set cache_all true`, " \
"and stop using this flag" if ARGV.include?("--all")
+ SharedHelpers.major_deprecation 2,
+ "The `--path` flag is deprecated because its semantics are unclear. " \
+ "Use `bundle config cache_path` to configure the path of your cache of gems, " \
+ "and `bundle config path` to configure the path where your gems are installed, " \
+ "and stop using this flag" if ARGV.include?("--path")
+
require_relative "cli/cache"
Cache.new(options).run
end
@@ -591,6 +597,9 @@ module Bundler
:desc => "Generate a test directory for your library, either rspec, minitest or test-unit. Set a default with `bundle config set --global gem.test (rspec|minitest|test-unit)`."
method_option :ci, :type => :string, :lazy_default => Bundler.settings["gem.ci"] || "",
:desc => "Generate CI configuration, either GitHub Actions, Travis CI, GitLab CI or CircleCI. Set a default with `bundle config set --global gem.ci (github|travis|gitlab|circle)`"
+ method_option :linter, :type => :string, :lazy_default => Bundler.settings["gem.linter"] || "",
+ :desc => "Add a linter and code formatter, either RuboCop or Standard. Set a default with `bundle config set --global gem.linter (rubocop|standard)`"
+ method_option :github_username, :type => :string, :default => Bundler.settings["gem.github_username"], :banner => "Set your username on GitHub", :desc => "Fill in GitHub username on README so that you don't have to do it manually. Set a default with `bundle config set --global gem.github_username <your_username>`."
def gem(name)
end
diff --git a/lib/bundler/cli/common.rb b/lib/bundler/cli/common.rb
index 23ac78a103..32d952fb72 100644
--- a/lib/bundler/cli/common.rb
+++ b/lib/bundler/cli/common.rb
@@ -36,10 +36,15 @@ module Bundler
def self.without_groups_message(command)
command_in_past_tense = command == :install ? "installed" : "updated"
groups = Bundler.settings[:without]
+ "Gems in the #{verbalize_groups(groups)} were not #{command_in_past_tense}."
+ end
+
+ def self.verbalize_groups(groups)
+ groups.map!{|g| "'#{g}'" }
group_list = [groups[0...-1].join(", "), groups[-1..-1]].
reject {|s| s.to_s.empty? }.join(" and ")
group_str = groups.size == 1 ? "group" : "groups"
- "Gems in the #{group_str} #{group_list} were not #{command_in_past_tense}."
+ "#{group_str} #{group_list}"
end
def self.select_spec(name, regex_match = nil)
@@ -53,7 +58,13 @@ module Bundler
case specs.count
when 0
- raise GemNotFound, gem_not_found_message(name, Bundler.definition.dependencies)
+ dep_in_other_group = Bundler.definition.current_dependencies.find {|dep|dep.name == name }
+
+ if dep_in_other_group
+ raise GemNotFound, "Could not find gem '#{name}', because it's in the #{verbalize_groups(dep_in_other_group.groups)}, configured to be ignored."
+ else
+ raise GemNotFound, gem_not_found_message(name, Bundler.definition.dependencies)
+ end
when 1
specs.first
else
diff --git a/lib/bundler/cli/gem.rb b/lib/bundler/cli/gem.rb
index 5b3d9c332e..c9794c4003 100644
--- a/lib/bundler/cli/gem.rb
+++ b/lib/bundler/cli/gem.rb
@@ -42,9 +42,17 @@ module Bundler
use_git = Bundler.git_present? && options[:git]
git_author_name = use_git ? `git config user.name`.chomp : ""
- github_username = use_git ? `git config github.user`.chomp : ""
+ git_username = use_git ? `git config github.user`.chomp : ""
git_user_email = use_git ? `git config user.email`.chomp : ""
+ github_username = if options[:github_username].nil?
+ git_username
+ elsif options[:github_username] == false
+ ""
+ else
+ options[:github_username]
+ end
+
config = {
:name => name,
:underscored_name => underscored_name,
@@ -155,15 +163,16 @@ module Bundler
templates.merge!("CHANGELOG.md.tt" => "CHANGELOG.md")
end
- if ask_and_set(:rubocop, "Do you want to add rubocop as a dependency for gems you generate?",
- "RuboCop is a static code analyzer that has out-of-the-box rules for many " \
- "of the guidelines in the community style guide. " \
- "For more information, see the RuboCop docs (https://docs.rubocop.org/en/stable/) " \
- "and the Ruby Style Guides (https://github.com/rubocop-hq/ruby-style-guide).")
- config[:rubocop] = true
- config[:rubocop_version] = Gem.ruby_version < Gem::Version.new("2.4.a") ? "0.81.0" : "1.7"
+ config[:linter] = ask_and_set_linter
+ case config[:linter]
+ when "rubocop"
+ config[:linter_version] = Gem.ruby_version < Gem::Version.new("2.4.a") ? "0.81.0" : "1.7"
Bundler.ui.info "RuboCop enabled in config"
templates.merge!("rubocop.yml.tt" => ".rubocop.yml")
+ when "standard"
+ config[:linter_version] = Gem.ruby_version < Gem::Version.new("2.4.a") ? "0.2.5" : "1.0"
+ Bundler.ui.info "Standard enabled in config"
+ templates.merge!("standard.yml.tt" => ".standard.yml")
end
templates.merge!("exe/newgem.tt" => "exe/#{name}") if config[:exe]
@@ -308,6 +317,58 @@ module Bundler
ci_template
end
+ def ask_and_set_linter
+ linter_template = options[:linter] || Bundler.settings["gem.linter"]
+ linter_template = deprecated_rubocop_option if linter_template.nil?
+
+ if linter_template.to_s.empty?
+ Bundler.ui.confirm "Do you want to add a code linter and formatter to your gem? " \
+ "Supported Linters:\n" \
+ "* RuboCop: https://rubocop.org\n" \
+ "* Standard: https://github.com/testdouble/standard\n" \
+ "\n"
+ Bundler.ui.info hint_text("linter")
+
+ result = Bundler.ui.ask "Enter a linter. rubocop/standard/(none):"
+ if result =~ /rubocop|standard/
+ linter_template = result
+ else
+ linter_template = false
+ end
+ end
+
+ if Bundler.settings["gem.linter"].nil?
+ Bundler.settings.set_global("gem.linter", linter_template)
+ end
+
+ # Once gem.linter safely set, unset the deprecated gem.rubocop
+ unless Bundler.settings["gem.rubocop"].nil?
+ Bundler.settings.set_global("gem.rubocop", nil)
+ end
+
+ if options[:linter] == Bundler.settings["gem.linter"]
+ Bundler.ui.info "#{options[:linter]} is already configured, ignoring --linter flag."
+ end
+
+ linter_template
+ end
+
+ def deprecated_rubocop_option
+ if !options[:rubocop].nil?
+ if options[:rubocop]
+ Bundler::SharedHelpers.major_deprecation 2, "--rubocop is deprecated, use --linter=rubocop"
+ "rubocop"
+ else
+ Bundler::SharedHelpers.major_deprecation 2, "--no-rubocop is deprecated, use --linter"
+ false
+ end
+ elsif !Bundler.settings["gem.rubocop"].nil?
+ Bundler::SharedHelpers.major_deprecation 2,
+ "config gem.rubocop is deprecated; we've updated your config to use gem.linter instead"
+ Bundler.settings["gem.rubocop"] ? "rubocop" : false
+ end
+ end
+
def bundler_dependency_version
v = Gem::Version.new(Bundler::VERSION)
req = v.segments[0..1]
diff --git a/lib/bundler/cli/install.rb b/lib/bundler/cli/install.rb
index c702eb14d1..cfbf4bee6e 100644
--- a/lib/bundler/cli/install.rb
+++ b/lib/bundler/cli/install.rb
@@ -33,12 +33,8 @@ module Bundler
options[:local] = true if Bundler.app_cache.exist?
- if Bundler.feature_flag.deployment_means_frozen?
- Bundler.settings.set_command_option :deployment, true
- else
- Bundler.settings.set_command_option :deployment, true if options[:deployment]
- Bundler.settings.set_command_option :frozen, true if options[:frozen]
- end
+ Bundler.settings.set_command_option :deployment, true if options[:deployment]
+ Bundler.settings.set_command_option :frozen, true if options[:frozen]
end
# When install is called with --no-deployment, disable deployment mode
diff --git a/lib/bundler/cli/outdated.rb b/lib/bundler/cli/outdated.rb
index 6a1789e235..e5d9af477c 100644
--- a/lib/bundler/cli/outdated.rb
+++ b/lib/bundler/cli/outdated.rb
@@ -72,7 +72,7 @@ module Bundler
gemfile_specs + dependency_specs
end
- specs.sort_by(&:name).each do |current_spec|
+ specs.sort_by(&:name).uniq(&:name).each do |current_spec|
next unless gems.empty? || gems.include?(current_spec.name)
active_spec = retrieve_active_spec(definition, current_spec)
diff --git a/lib/bundler/compact_index_client/updater.rb b/lib/bundler/compact_index_client/updater.rb
index 9e0180fac7..b4b2321797 100644
--- a/lib/bundler/compact_index_client/updater.rb
+++ b/lib/bundler/compact_index_client/updater.rb
@@ -92,11 +92,11 @@ module Bundler
def checksum_for_file(path)
return nil unless path.file?
- # This must use IO.read instead of Digest.file().hexdigest
+ # This must use File.read instead of Digest.file().hexdigest
# because we need to preserve \n line endings on windows when calculating
# the checksum
SharedHelpers.filesystem_access(path, :read) do
- SharedHelpers.digest(:MD5).hexdigest(IO.read(path))
+ SharedHelpers.digest(:MD5).hexdigest(File.read(path))
end
end
end
diff --git a/lib/bundler/definition.rb b/lib/bundler/definition.rb
index 5f02b15e5f..ca5aadba9d 100644
--- a/lib/bundler/definition.rb
+++ b/lib/bundler/definition.rb
@@ -111,6 +111,17 @@ module Bundler
@locked_platforms = []
end
+ @locked_gem_sources = @locked_sources.select {|s| s.is_a?(Source::Rubygems) }
+ @disable_multisource = @locked_gem_sources.all?(&:disable_multisource?)
+
+ unless @disable_multisource
+ msg = "Your lockfile contains a single rubygems source section with multiple remotes, which is insecure. You should run `bundle update` or generate your lockfile from scratch."
+
+ Bundler::SharedHelpers.major_deprecation 2, msg
+
+ @sources.merged_gem_lockfile_sections!
+ end
+
@unlock[:gems] ||= []
@unlock[:sources] ||= []
@unlock[:ruby] ||= if @ruby_version && locked_ruby_version_object
@@ -150,6 +161,10 @@ module Bundler
end
end
+ def disable_multisource?
+ @disable_multisource
+ end
+
def resolve_with_cache!
raise "Specs already loaded" if @specs
sources.cached!
@@ -177,10 +192,10 @@ module Bundler
gem_name, gem_version = extract_gem_info(e)
locked_gem = @locked_specs[gem_name].last
raise if locked_gem.nil? || locked_gem.version.to_s != gem_version || !@remote
- raise GemNotFound, "Your bundle is locked to #{locked_gem}, but that version could not " \
- "be found in any of the sources listed in your Gemfile. If you haven't changed sources, " \
- "that means the author of #{locked_gem} has removed it. You'll need to update your bundle " \
- "to a version other than #{locked_gem} that hasn't been removed in order to install."
+ raise GemNotFound, "Your bundle is locked to #{locked_gem} from #{locked_gem.source}, but that version can " \
+ "no longer be found in that source. That means the author of #{locked_gem} has removed it. " \
+ "You'll need to update your bundle to a version other than #{locked_gem} that hasn't been " \
+ "removed in order to install."
end
unless specs["bundler"].any?
bundler = sources.metadata_source.specs.search(Gem::Dependency.new("bundler", VERSION)).last
@@ -537,6 +552,9 @@ module Bundler
attr_reader :sources
private :sources
+ attr_reader :locked_gem_sources
+ private :locked_gem_sources
+
def nothing_changed?
!@source_changes && !@dependency_changes && !@new_platform && !@path_changes && !@local_changes && !@locked_specs_incomplete_for_platform
end
@@ -661,10 +679,8 @@ module Bundler
end
def converge_rubygems_sources
- return false if Bundler.feature_flag.disable_multisource?
+ return false if disable_multisource?
- # Get the RubyGems sources from the Gemfile.lock
- locked_gem_sources = @locked_sources.select {|s| s.is_a?(Source::Rubygems) }
return false if locked_gem_sources.empty?
# Get the RubyGems remotes from the Gemfile
@@ -950,7 +966,7 @@ module Bundler
end
def additional_base_requirements_for_resolve
- return [] unless @locked_gems && Bundler.feature_flag.only_update_to_newer_versions?
+ return [] unless @locked_gems
dependencies_by_name = dependencies.inject({}) {|memo, dep| memo.update(dep.name => dep) }
@locked_gems.specs.reduce({}) do |requirements, locked_spec|
name = locked_spec.name
diff --git a/lib/bundler/dsl.rb b/lib/bundler/dsl.rb
index 23fba99ffa..313d1a9a41 100644
--- a/lib/bundler/dsl.rb
+++ b/lib/bundler/dsl.rb
@@ -460,19 +460,16 @@ repo_name ||= user_name
@sources.add_rubygems_remote(source)
end
- if Bundler.feature_flag.disable_multisource?
+ if Bundler.feature_flag.bundler_3_mode?
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. To downgrade this error to a warning, run " \
- "`bundle config unset disable_multisource`"
+ "should come from that source"
raise GemfileEvalError, msg
else
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 set --local " \
- "disable_multisource true`."
+ "a block to indicate which gems should come from the secondary source."
end
end
diff --git a/lib/bundler/feature_flag.rb b/lib/bundler/feature_flag.rb
index a1b443b042..36c18ead22 100644
--- a/lib/bundler/feature_flag.rb
+++ b/lib/bundler/feature_flag.rb
@@ -31,11 +31,9 @@ module Bundler
settings_flag(:auto_clean_without_path) { bundler_3_mode? }
settings_flag(:cache_all) { 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? }
settings_flag(:forget_cli_options) { bundler_3_mode? }
settings_flag(:global_gem_cache) { 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(:print_only_version_number) { bundler_3_mode? }
diff --git a/lib/bundler/gem_helper.rb b/lib/bundler/gem_helper.rb
index d3e30124f9..6096adfa27 100644
--- a/lib/bundler/gem_helper.rb
+++ b/lib/bundler/gem_helper.rb
@@ -47,6 +47,11 @@ module Bundler
built_gem_path = build_gem
end
+ desc "Generate SHA512 checksum if #{name}-#{version}.gem into the checksums directory."
+ task "build:checksum" => "build" do
+ build_checksum(built_gem_path)
+ end
+
desc "Build and install #{name}-#{version}.gem into system gems."
task "install" => "build" do
install_gem(built_gem_path)
@@ -100,6 +105,17 @@ module Bundler
Bundler.ui.confirm "#{name} (#{version}) installed."
end
+ def build_checksum(built_gem_path = nil)
+ built_gem_path ||= build_gem
+ SharedHelpers.filesystem_access(File.join(base, "checksums")) {|p| FileUtils.mkdir_p(p) }
+ file_name = "#{File.basename(built_gem_path)}.sha512"
+ require "digest/sha2"
+ checksum = Digest::SHA512.new.hexdigest(built_gem_path.to_s)
+ target = File.join(base, "checksums", file_name)
+ File.write(target, checksum)
+ Bundler.ui.confirm "#{name} #{version} checksum written to checksums/#{file_name}."
+ end
+
protected
def rubygem_push(path)
diff --git a/lib/bundler/injector.rb b/lib/bundler/injector.rb
index e9aa13a357..613bda4f84 100644
--- a/lib/bundler/injector.rb
+++ b/lib/bundler/injector.rb
@@ -128,7 +128,7 @@ module Bundler
# evaluates a gemfile to remove the specified gem
# from it.
def remove_deps(gemfile_path)
- initial_gemfile = IO.readlines(gemfile_path)
+ initial_gemfile = File.readlines(gemfile_path)
Bundler.ui.info "Removing gems from #{gemfile_path}"
@@ -181,7 +181,7 @@ module Bundler
patterns = /gem\s+(['"])#{Regexp.union(gems)}\1|gem\s*\((['"])#{Regexp.union(gems)}\2\)/
new_gemfile = []
multiline_removal = false
- IO.readlines(gemfile_path).each do |line|
+ File.readlines(gemfile_path).each do |line|
match_data = line.match(patterns)
if match_data && is_not_within_comment?(line, match_data)
multiline_removal = line.rstrip.end_with?(",")
diff --git a/lib/bundler/inline.rb b/lib/bundler/inline.rb
index 02da06cee9..a718418fce 100644
--- a/lib/bundler/inline.rb
+++ b/lib/bundler/inline.rb
@@ -52,7 +52,7 @@ def gemfile(install = false, options = {}, &gemfile)
builder.instance_eval(&gemfile)
builder.check_primary_source_safety
- Bundler.settings.temporary(:frozen => false) do
+ Bundler.settings.temporary(:deployment => false, :frozen => false) do
definition = builder.to_definition(nil, true)
def definition.lock(*); end
definition.validate_runtime!
diff --git a/lib/bundler/installer/parallel_installer.rb b/lib/bundler/installer/parallel_installer.rb
index a6d1de29e6..5b6680e5e1 100644
--- a/lib/bundler/installer/parallel_installer.rb
+++ b/lib/bundler/installer/parallel_installer.rb
@@ -6,10 +6,11 @@ require_relative "gem_installer"
module Bundler
class ParallelInstaller
class SpecInstallation
- attr_accessor :spec, :name, :post_install_message, :state, :error
+ attr_accessor :spec, :name, :full_name, :post_install_message, :state, :error
def initialize(spec)
@spec = spec
@name = spec.name
+ @full_name = spec.full_name
@state = :none
@post_install_message = ""
@error = nil
@@ -27,13 +28,8 @@ module Bundler
state == :failed
end
- def installation_attempted?
- installed? || failed?
- end
-
- # Only true when spec in neither installed nor already enqueued
def ready_to_enqueue?
- !enqueued? && !installation_attempted?
+ state == :none
end
def has_post_install_message?
@@ -54,14 +50,11 @@ module Bundler
# Represents only the non-development dependencies, the ones that are
# itself and are in the total list.
def dependencies
- @dependencies ||= begin
- all_dependencies.reject {|dep| ignorable_dependency? dep }
- end
+ @dependencies ||= all_dependencies.reject {|dep| ignorable_dependency? dep }
end
def missing_lockfile_dependencies(all_spec_names)
- deps = all_dependencies.reject {|dep| ignorable_dependency? dep }
- deps.reject {|dep| all_spec_names.include? dep.name }
+ dependencies.reject {|dep| all_spec_names.include? dep.name }
end
# Represents all dependencies
@@ -70,7 +63,7 @@ module Bundler
end
def to_s
- "#<#{self.class} #{@spec.full_name} (#{state})>"
+ "#<#{self.class} #{full_name} (#{state})>"
end
end
@@ -93,18 +86,48 @@ module Bundler
def call
check_for_corrupt_lockfile
+ if @rake
+ do_install(@rake, 0)
+ Gem::Specification.reset
+ end
+
if @size > 1
install_with_worker
else
install_serially
end
+ check_for_unmet_dependencies
+
handle_error if failed_specs.any?
@specs
ensure
worker_pool && worker_pool.stop
end
+ def check_for_unmet_dependencies
+ unmet_dependencies = @specs.map do |s|
+ [
+ s,
+ s.dependencies.reject {|dep| @specs.any? {|spec| dep.matches_spec?(spec.spec) } },
+ ]
+ end.reject {|a| a.last.empty? }
+ return if unmet_dependencies.empty?
+
+ warning = []
+ warning << "Your lockfile doesn't include a valid resolution."
+ warning << "You can fix this by regenerating your lockfile or trying to manually editing the bad locked gems to a version that satisfies all dependencies."
+ warning << "The unmet dependencies are:"
+
+ unmet_dependencies.each do |spec, unmet_spec_dependencies|
+ unmet_spec_dependencies.each do |unmet_spec_dependency|
+ warning << "* #{unmet_spec_dependency}, depended upon #{spec.full_name}, unsatisfied by #{@specs.find {|s| s.name == unmet_spec_dependency.name && !unmet_spec_dependency.matches_spec?(s.spec) }.full_name}"
+ end
+ end
+
+ Bundler.ui.warn(warning.join("\n"))
+ end
+
def check_for_corrupt_lockfile
missing_dependencies = @specs.map do |s|
[
@@ -217,8 +240,6 @@ module Bundler
# are installed.
def enqueue_specs
@specs.select(&:ready_to_enqueue?).each do |spec|
- next if @rake && !@rake.installed? && spec.name != @rake.name
-
if spec.dependencies_installed? @specs
spec.state = :enqueued
worker_pool.enq spec
diff --git a/lib/bundler/lazy_specification.rb b/lib/bundler/lazy_specification.rb
index 04ba2a2364..6760edba42 100644
--- a/lib/bundler/lazy_specification.rb
+++ b/lib/bundler/lazy_specification.rb
@@ -73,7 +73,12 @@ module Bundler
same_platform_candidates = candidates.select do |spec|
MatchPlatform.platforms_match?(spec.platform, platform_object)
end
- search = same_platform_candidates.last || candidates.last
+ installable_candidates = same_platform_candidates.select do |spec|
+ !spec.is_a?(EndpointSpecification) ||
+ (spec.required_ruby_version.satisfied_by?(Gem.ruby_version) &&
+ spec.required_rubygems_version.satisfied_by?(Gem.rubygems_version))
+ end
+ search = installable_candidates.last || same_platform_candidates.last
search.dependencies = dependencies if search && (search.is_a?(RemoteSpecification) || search.is_a?(EndpointSpecification))
search
end
diff --git a/lib/bundler/lockfile_parser.rb b/lib/bundler/lockfile_parser.rb
index 058d353bbe..f87faff70c 100644
--- a/lib/bundler/lockfile_parser.rb
+++ b/lib/bundler/lockfile_parser.rb
@@ -131,18 +131,8 @@ module Bundler
@sources << @current_source
end
when GEM
- source_remotes = Array(@opts["remote"])
-
- if source_remotes.size == 1
- @opts["remotes"] = @opts.delete("remote")
- @current_source = TYPES[@type].from_lock(@opts)
- else
- source_remotes.each do |url|
- rubygems_aggregate.add_remote(url)
- end
- @current_source = rubygems_aggregate
- end
-
+ @opts["remotes"] = Array(@opts.delete("remote")).reverse
+ @current_source = TYPES[@type].from_lock(@opts)
@sources << @current_source
when PLUGIN
@current_source = Plugin.source_from_lock(@opts)
@@ -245,9 +235,5 @@ module Bundler
def parse_ruby(line)
@ruby_version = line.strip
end
-
- def rubygems_aggregate
- @rubygems_aggregate ||= Source::Rubygems.new
- end
end
end
diff --git a/lib/bundler/man/bundle-add.1 b/lib/bundler/man/bundle-add.1
index b44295b2d3..ffcd63bbcc 100644
--- a/lib/bundler/man/bundle-add.1
+++ b/lib/bundler/man/bundle-add.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE\-ADD" "1" "January 2021" "" ""
+.TH "BUNDLE\-ADD" "1" "April 2021" "" ""
.
.SH "NAME"
\fBbundle\-add\fR \- Add gem to the Gemfile and run bundle install
diff --git a/lib/bundler/man/bundle-binstubs.1 b/lib/bundler/man/bundle-binstubs.1
index 99876d023e..23c371b7de 100644
--- a/lib/bundler/man/bundle-binstubs.1
+++ b/lib/bundler/man/bundle-binstubs.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE\-BINSTUBS" "1" "January 2021" "" ""
+.TH "BUNDLE\-BINSTUBS" "1" "April 2021" "" ""
.
.SH "NAME"
\fBbundle\-binstubs\fR \- Install the binstubs of the listed gems
diff --git a/lib/bundler/man/bundle-cache.1 b/lib/bundler/man/bundle-cache.1
index 3b3c6f9734..9bb8011a8a 100644
--- a/lib/bundler/man/bundle-cache.1
+++ b/lib/bundler/man/bundle-cache.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE\-CACHE" "1" "January 2021" "" ""
+.TH "BUNDLE\-CACHE" "1" "April 2021" "" ""
.
.SH "NAME"
\fBbundle\-cache\fR \- Package your needed \fB\.gem\fR files into your application
diff --git a/lib/bundler/man/bundle-check.1 b/lib/bundler/man/bundle-check.1
index 4436c3e971..6696479fef 100644
--- a/lib/bundler/man/bundle-check.1
+++ b/lib/bundler/man/bundle-check.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE\-CHECK" "1" "January 2021" "" ""
+.TH "BUNDLE\-CHECK" "1" "April 2021" "" ""
.
.SH "NAME"
\fBbundle\-check\fR \- Verifies if dependencies are satisfied by installed gems
diff --git a/lib/bundler/man/bundle-clean.1 b/lib/bundler/man/bundle-clean.1
index b7e882ecbf..625d87c580 100644
--- a/lib/bundler/man/bundle-clean.1
+++ b/lib/bundler/man/bundle-clean.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE\-CLEAN" "1" "January 2021" "" ""
+.TH "BUNDLE\-CLEAN" "1" "April 2021" "" ""
.
.SH "NAME"
\fBbundle\-clean\fR \- Cleans up unused gems in your bundler directory
diff --git a/lib/bundler/man/bundle-config.1 b/lib/bundler/man/bundle-config.1
index ad36c6bde0..b17b3aea3c 100644
--- a/lib/bundler/man/bundle-config.1
+++ b/lib/bundler/man/bundle-config.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE\-CONFIG" "1" "January 2021" "" ""
+.TH "BUNDLE\-CONFIG" "1" "April 2021" "" ""
.
.SH "NAME"
\fBbundle\-config\fR \- Set bundler configuration options
@@ -199,6 +199,9 @@ The following is a list of all configuration keys and their purpose\. You can le
\fBfrozen\fR (\fBBUNDLE_FROZEN\fR): Disallow changes to the \fBGemfile\fR\. When the \fBGemfile\fR is changed and the lockfile has not been updated, running Bundler commands will be blocked\. Defaults to \fBtrue\fR when \fB\-\-deployment\fR is used\.
.
.IP "\(bu" 4
+\fBgem\.github_username\fR (\fBBUNDLE_GEM__GITHUB_USERNAME\fR): Sets a GitHub username or organization to be used in \fBREADME\fR file when you create a new gem via \fBbundle gem\fR command\. It can be overriden by passing an explicit \fB\-\-github\-username\fR flag to \fBbundle gem\fR\.
+.
+.IP "\(bu" 4
\fBgem\.push_key\fR (\fBBUNDLE_GEM__PUSH_KEY\fR): Sets the \fB\-\-key\fR parameter for \fBgem push\fR when using the \fBrake release\fR command with a private gemstash server\.
.
.IP "\(bu" 4
@@ -223,9 +226,6 @@ The following is a list of all configuration keys and their purpose\. You can le
\fBno_prune\fR (\fBBUNDLE_NO_PRUNE\fR): Whether Bundler should leave outdated gems unpruned when caching\.
.
.IP "\(bu" 4
-\fBonly_update_to_newer_versions\fR (\fBBUNDLE_ONLY_UPDATE_TO_NEWER_VERSIONS\fR): During \fBbundle update\fR, only resolve to newer versions of the gems in the lockfile\.
-.
-.IP "\(bu" 4
\fBpath\fR (\fBBUNDLE_PATH\fR): The location on disk where all gems in your bundle will be located regardless of \fB$GEM_HOME\fR or \fB$GEM_PATH\fR values\. Bundle gems not found in this location will be installed by \fBbundle install\fR\. Defaults to \fBGem\.dir\fR\. When \-\-deployment is used, defaults to vendor/bundle\.
.
.IP "\(bu" 4
diff --git a/lib/bundler/man/bundle-config.1.ronn b/lib/bundler/man/bundle-config.1.ronn
index 90ec5ab59e..c260561109 100644
--- a/lib/bundler/man/bundle-config.1.ronn
+++ b/lib/bundler/man/bundle-config.1.ronn
@@ -194,6 +194,10 @@ learn more about their operation in [bundle install(1)](bundle-install.1.html).
Disallow changes to the `Gemfile`. When the `Gemfile` is changed and the
lockfile has not been updated, running Bundler commands will be blocked.
Defaults to `true` when `--deployment` is used.
+* `gem.github_username` (`BUNDLE_GEM__GITHUB_USERNAME`):
+ Sets a GitHub username or organization to be used in `README` file when you
+ create a new gem via `bundle gem` command. It can be overriden by passing an
+ explicit `--github-username` flag to `bundle gem`.
* `gem.push_key` (`BUNDLE_GEM__PUSH_KEY`):
Sets the `--key` parameter for `gem push` when using the `rake release`
command with a private gemstash server.
@@ -218,9 +222,6 @@ learn more about their operation in [bundle install(1)](bundle-install.1.html).
Whether `bundle package` should skip installing gems.
* `no_prune` (`BUNDLE_NO_PRUNE`):
Whether Bundler should leave outdated gems unpruned when caching.
-* `only_update_to_newer_versions` (`BUNDLE_ONLY_UPDATE_TO_NEWER_VERSIONS`):
- During `bundle update`, only resolve to newer versions of the gems in the
- lockfile.
* `path` (`BUNDLE_PATH`):
The location on disk where all gems in your bundle will be located regardless
of `$GEM_HOME` or `$GEM_PATH` values. Bundle gems not found in this location
diff --git a/lib/bundler/man/bundle-doctor.1 b/lib/bundler/man/bundle-doctor.1
index 2923517608..8e4c47c683 100644
--- a/lib/bundler/man/bundle-doctor.1
+++ b/lib/bundler/man/bundle-doctor.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE\-DOCTOR" "1" "January 2021" "" ""
+.TH "BUNDLE\-DOCTOR" "1" "April 2021" "" ""
.
.SH "NAME"
\fBbundle\-doctor\fR \- Checks the bundle for common problems
diff --git a/lib/bundler/man/bundle-exec.1 b/lib/bundler/man/bundle-exec.1
index aa0c509278..863b76e4b7 100644
--- a/lib/bundler/man/bundle-exec.1
+++ b/lib/bundler/man/bundle-exec.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE\-EXEC" "1" "January 2021" "" ""
+.TH "BUNDLE\-EXEC" "1" "April 2021" "" ""
.
.SH "NAME"
\fBbundle\-exec\fR \- Execute a command in the context of the bundle
diff --git a/lib/bundler/man/bundle-gem.1 b/lib/bundler/man/bundle-gem.1
index c1abf90f5c..ae4e173008 100644
--- a/lib/bundler/man/bundle-gem.1
+++ b/lib/bundler/man/bundle-gem.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE\-GEM" "1" "January 2021" "" ""
+.TH "BUNDLE\-GEM" "1" "April 2021" "" ""
.
.SH "NAME"
\fBbundle\-gem\fR \- Generate a project skeleton for creating a rubygem
@@ -90,6 +90,19 @@ When Bundler is configured to not generate CI files, an interactive prompt will
When Bundler is unconfigured, an interactive prompt will be displayed and the answer will be saved in Bundler\'s global config for future \fBbundle gem\fR use\.
.
.TP
+\fB\-\-linter\fR, \fB\-\-linter=rubocop\fR, \fB\-\-linter=standard\fR
+Specify the linter and code formatter that Bundler should add to the project\'s development dependencies\. Acceptable values are \fBrubocop\fR and \fBstandard\fR\. A configuration file will be generated in the project directory\. Given no option is specified:
+.
+.IP
+When Bundler is configured to add a linter, this defaults to Bundler\'s global config setting \fBgem\.linter\fR\.
+.
+.IP
+When Bundler is configured not to add a linter, an interactive prompt will be displayed and the answer will be used for the current rubygem project\.
+.
+.IP
+When Bundler is unconfigured, an interactive prompt will be displayed and the answer will be saved in Bundler\'s global config for future \fBbundle gem\fR use\.
+.
+.TP
\fB\-e\fR, \fB\-\-edit[=EDITOR]\fR
Open the resulting GEM_NAME\.gemspec in EDITOR, or the default editor if not specified\. The default is \fB$BUNDLER_EDITOR\fR, \fB$VISUAL\fR, or \fB$EDITOR\fR\.
.
diff --git a/lib/bundler/man/bundle-gem.1.ronn b/lib/bundler/man/bundle-gem.1.ronn
index a997cb907a..61c741fb24 100644
--- a/lib/bundler/man/bundle-gem.1.ronn
+++ b/lib/bundler/man/bundle-gem.1.ronn
@@ -92,6 +92,22 @@ configuration file using the following names:
the answer will be saved in Bundler's global config for future `bundle gem`
use.
+* `--linter`, `--linter=rubocop`, `--linter=standard`:
+ Specify the linter and code formatter that Bundler should add to the
+ project's development dependencies. Acceptable values are `rubocop` and
+ `standard`. A configuration file will be generated in the project directory.
+ Given no option is specified:
+
+ When Bundler is configured to add a linter, this defaults to Bundler's
+ global config setting `gem.linter`.
+
+ When Bundler is configured not to add a linter, an interactive prompt
+ will be displayed and the answer will be used for the current rubygem project.
+
+ When Bundler is unconfigured, an interactive prompt will be displayed and
+ the answer will be saved in Bundler's global config for future `bundle gem`
+ use.
+
* `-e`, `--edit[=EDITOR]`:
Open the resulting GEM_NAME.gemspec in EDITOR, or the default editor if not
specified. The default is `$BUNDLER_EDITOR`, `$VISUAL`, or `$EDITOR`.
diff --git a/lib/bundler/man/bundle-info.1 b/lib/bundler/man/bundle-info.1
index c715af4063..168d021112 100644
--- a/lib/bundler/man/bundle-info.1
+++ b/lib/bundler/man/bundle-info.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE\-INFO" "1" "January 2021" "" ""
+.TH "BUNDLE\-INFO" "1" "April 2021" "" ""
.
.SH "NAME"
\fBbundle\-info\fR \- Show information for the given gem in your bundle
diff --git a/lib/bundler/man/bundle-init.1 b/lib/bundler/man/bundle-init.1
index 6c8f441bdd..5d3e61d05b 100644
--- a/lib/bundler/man/bundle-init.1
+++ b/lib/bundler/man/bundle-init.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE\-INIT" "1" "January 2021" "" ""
+.TH "BUNDLE\-INIT" "1" "April 2021" "" ""
.
.SH "NAME"
\fBbundle\-init\fR \- Generates a Gemfile into the current working directory
diff --git a/lib/bundler/man/bundle-inject.1 b/lib/bundler/man/bundle-inject.1
index 2342b44716..37acabfa9a 100644
--- a/lib/bundler/man/bundle-inject.1
+++ b/lib/bundler/man/bundle-inject.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE\-INJECT" "1" "January 2021" "" ""
+.TH "BUNDLE\-INJECT" "1" "April 2021" "" ""
.
.SH "NAME"
\fBbundle\-inject\fR \- Add named gem(s) with version requirements to Gemfile
diff --git a/lib/bundler/man/bundle-install.1 b/lib/bundler/man/bundle-install.1
index c223185b6f..2dcb4d3ac6 100644
--- a/lib/bundler/man/bundle-install.1
+++ b/lib/bundler/man/bundle-install.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE\-INSTALL" "1" "January 2021" "" ""
+.TH "BUNDLE\-INSTALL" "1" "April 2021" "" ""
.
.SH "NAME"
\fBbundle\-install\fR \- Install the dependencies specified in your Gemfile
diff --git a/lib/bundler/man/bundle-list.1 b/lib/bundler/man/bundle-list.1
index 929b0f79f8..7c93b89dc3 100644
--- a/lib/bundler/man/bundle-list.1
+++ b/lib/bundler/man/bundle-list.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE\-LIST" "1" "January 2021" "" ""
+.TH "BUNDLE\-LIST" "1" "April 2021" "" ""
.
.SH "NAME"
\fBbundle\-list\fR \- List all the gems in the bundle
diff --git a/lib/bundler/man/bundle-lock.1 b/lib/bundler/man/bundle-lock.1
index bcf588a3cf..a4dfda9c86 100644
--- a/lib/bundler/man/bundle-lock.1
+++ b/lib/bundler/man/bundle-lock.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE\-LOCK" "1" "January 2021" "" ""
+.TH "BUNDLE\-LOCK" "1" "April 2021" "" ""
.
.SH "NAME"
\fBbundle\-lock\fR \- Creates / Updates a lockfile without installing
diff --git a/lib/bundler/man/bundle-open.1 b/lib/bundler/man/bundle-open.1
index 27308ff624..0511bc655b 100644
--- a/lib/bundler/man/bundle-open.1
+++ b/lib/bundler/man/bundle-open.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE\-OPEN" "1" "January 2021" "" ""
+.TH "BUNDLE\-OPEN" "1" "April 2021" "" ""
.
.SH "NAME"
\fBbundle\-open\fR \- Opens the source directory for a gem in your bundle
diff --git a/lib/bundler/man/bundle-outdated.1 b/lib/bundler/man/bundle-outdated.1
index 40b23568d5..268b4b157c 100644
--- a/lib/bundler/man/bundle-outdated.1
+++ b/lib/bundler/man/bundle-outdated.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE\-OUTDATED" "1" "January 2021" "" ""
+.TH "BUNDLE\-OUTDATED" "1" "April 2021" "" ""
.
.SH "NAME"
\fBbundle\-outdated\fR \- List installed gems with newer versions available
diff --git a/lib/bundler/man/bundle-platform.1 b/lib/bundler/man/bundle-platform.1
index d0ec5c643c..77638b2b4b 100644
--- a/lib/bundler/man/bundle-platform.1
+++ b/lib/bundler/man/bundle-platform.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE\-PLATFORM" "1" "January 2021" "" ""
+.TH "BUNDLE\-PLATFORM" "1" "April 2021" "" ""
.
.SH "NAME"
\fBbundle\-platform\fR \- Displays platform compatibility information
diff --git a/lib/bundler/man/bundle-pristine.1 b/lib/bundler/man/bundle-pristine.1
index 9fd42d04a4..0fcf9fdb39 100644
--- a/lib/bundler/man/bundle-pristine.1
+++ b/lib/bundler/man/bundle-pristine.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE\-PRISTINE" "1" "January 2021" "" ""
+.TH "BUNDLE\-PRISTINE" "1" "April 2021" "" ""
.
.SH "NAME"
\fBbundle\-pristine\fR \- Restores installed gems to their pristine condition
diff --git a/lib/bundler/man/bundle-remove.1 b/lib/bundler/man/bundle-remove.1
index 366e5f4be2..ca366b81a9 100644
--- a/lib/bundler/man/bundle-remove.1
+++ b/lib/bundler/man/bundle-remove.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE\-REMOVE" "1" "January 2021" "" ""
+.TH "BUNDLE\-REMOVE" "1" "April 2021" "" ""
.
.SH "NAME"
\fBbundle\-remove\fR \- Removes gems from the Gemfile
diff --git a/lib/bundler/man/bundle-show.1 b/lib/bundler/man/bundle-show.1
index e2de241438..e403ae980f 100644
--- a/lib/bundler/man/bundle-show.1
+++ b/lib/bundler/man/bundle-show.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE\-SHOW" "1" "January 2021" "" ""
+.TH "BUNDLE\-SHOW" "1" "April 2021" "" ""
.
.SH "NAME"
\fBbundle\-show\fR \- Shows all the gems in your bundle, or the path to a gem
diff --git a/lib/bundler/man/bundle-update.1 b/lib/bundler/man/bundle-update.1
index a78633bbf8..5546b51792 100644
--- a/lib/bundler/man/bundle-update.1
+++ b/lib/bundler/man/bundle-update.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE\-UPDATE" "1" "January 2021" "" ""
+.TH "BUNDLE\-UPDATE" "1" "April 2021" "" ""
.
.SH "NAME"
\fBbundle\-update\fR \- Update your gems to the latest available versions
diff --git a/lib/bundler/man/bundle-viz.1 b/lib/bundler/man/bundle-viz.1
index fead09e6ad..645c45b607 100644
--- a/lib/bundler/man/bundle-viz.1
+++ b/lib/bundler/man/bundle-viz.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE\-VIZ" "1" "January 2021" "" ""
+.TH "BUNDLE\-VIZ" "1" "April 2021" "" ""
.
.SH "NAME"
\fBbundle\-viz\fR \- Generates a visual dependency graph for your Gemfile
diff --git a/lib/bundler/man/bundle.1 b/lib/bundler/man/bundle.1
index 50aa6e17c7..5c1bc96572 100644
--- a/lib/bundler/man/bundle.1
+++ b/lib/bundler/man/bundle.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE" "1" "January 2021" "" ""
+.TH "BUNDLE" "1" "April 2021" "" ""
.
.SH "NAME"
\fBbundle\fR \- Ruby Dependency Management
diff --git a/lib/bundler/man/gemfile.5 b/lib/bundler/man/gemfile.5
index 460295da4d..c23c26ad7a 100644
--- a/lib/bundler/man/gemfile.5
+++ b/lib/bundler/man/gemfile.5
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "GEMFILE" "5" "January 2021" "" ""
+.TH "GEMFILE" "5" "April 2021" "" ""
.
.SH "NAME"
\fBGemfile\fR \- A format for describing gem dependencies for Ruby programs
diff --git a/lib/bundler/plugin/api/source.rb b/lib/bundler/plugin/api/source.rb
index e1f0826874..d70a16f4bc 100644
--- a/lib/bundler/plugin/api/source.rb
+++ b/lib/bundler/plugin/api/source.rb
@@ -140,6 +140,13 @@ module Bundler
end
end
+ # Set internal representation to fetch the gems/specs locally.
+ #
+ # When this is called, the source should try to fetch the specs and
+ # install from the local system.
+ def local!
+ end
+
# Set internal representation to fetch the gems/specs from remote.
#
# When this is called, the source should try to fetch the specs and
diff --git a/lib/bundler/settings.rb b/lib/bundler/settings.rb
index 749e4eb60e..f59ae37eed 100644
--- a/lib/bundler/settings.rb
+++ b/lib/bundler/settings.rb
@@ -15,7 +15,6 @@ module Bundler
cache_all_platforms
default_install_uses_path
deployment
- deployment_means_frozen
disable_checksum_validation
disable_exec_load
disable_local_branch_check
@@ -33,7 +32,6 @@ module Bundler
init_gems_rb
no_install
no_prune
- only_update_to_newer_versions
path_relative_to_cwd
path.system
plugins
diff --git a/lib/bundler/source.rb b/lib/bundler/source.rb
index be00143f5a..a3f4b09cce 100644
--- a/lib/bundler/source.rb
+++ b/lib/bundler/source.rb
@@ -33,6 +33,12 @@ module Bundler
spec.source == self
end
+ def local!; end
+
+ def cached!; end
+
+ def remote!; end
+
# it's possible that gems from one source depend on gems from some
# other source, so now we download gemspecs and iterate over those
# dependencies, looking for gems we don't have info on yet.
diff --git a/lib/bundler/source/metadata.rb b/lib/bundler/source/metadata.rb
index 0867879861..50b65ce0ea 100644
--- a/lib/bundler/source/metadata.rb
+++ b/lib/bundler/source/metadata.rb
@@ -33,10 +33,6 @@ module Bundler
end
end
- def cached!; end
-
- def remote!; end
-
def options
{}
end
diff --git a/lib/bundler/source/path.rb b/lib/bundler/source/path.rb
index 2c2e9023b3..01f89b204d 100644
--- a/lib/bundler/source/path.rb
+++ b/lib/bundler/source/path.rb
@@ -82,7 +82,9 @@ module Bundler
end
def install(spec, options = {})
- print_using_message "Using #{version_message(spec)} from #{self}"
+ using_message = "Using #{version_message(spec)} from #{self}"
+ using_message += " and installing its executables" unless spec.executables.empty?
+ print_using_message using_message
generate_bin(spec, :disable_extensions => true)
nil # no post-install message
end
diff --git a/lib/bundler/source/path/installer.rb b/lib/bundler/source/path/installer.rb
index 72bfbb4836..a70973bde7 100644
--- a/lib/bundler/source/path/installer.rb
+++ b/lib/bundler/source/path/installer.rb
@@ -35,7 +35,7 @@ module Bundler
run_hooks(:post_build)
end
- generate_bin unless spec.executables.nil? || spec.executables.empty?
+ generate_bin unless spec.executables.empty?
run_hooks(:post_install)
ensure
diff --git a/lib/bundler/source/rubygems.rb b/lib/bundler/source/rubygems.rb
index 5b89b1645d..cede580b0a 100644
--- a/lib/bundler/source/rubygems.rb
+++ b/lib/bundler/source/rubygems.rb
@@ -20,17 +20,29 @@ module Bundler
@dependency_names = []
@allow_remote = false
@allow_cached = false
+ @allow_local = options["allow_local"] || false
@caches = [cache_path, *Bundler.rubygems.gem_cache]
- Array(options["remotes"] || []).reverse_each {|r| add_remote(r) }
+ Array(options["remotes"]).reverse_each {|r| add_remote(r) }
+ end
+
+ def local!
+ return if @allow_local
+
+ @specs = nil
+ @allow_local = true
end
def remote!
+ return if @allow_remote
+
@specs = nil
@allow_remote = true
end
def cached!
+ return if @allow_cached
+
@specs = nil
@allow_cached = true
end
@@ -49,8 +61,12 @@ module Bundler
o.is_a?(Rubygems) && (o.credless_remotes - credless_remotes).empty?
end
+ def disable_multisource?
+ @remotes.size <= 1
+ end
+
def can_lock?(spec)
- return super if Bundler.feature_flag.disable_multisource?
+ return super if disable_multisource?
spec.source.is_a?(Rubygems)
end
@@ -87,7 +103,7 @@ module Bundler
# small_idx.use large_idx.
idx = @allow_remote ? remote_specs.dup : Index.new
idx.use(cached_specs, :override_dupes) if @allow_cached || @allow_remote
- idx.use(installed_specs, :override_dupes)
+ idx.use(installed_specs, :override_dupes) if @allow_local
idx
end
end
@@ -365,7 +381,7 @@ module Bundler
def cached_specs
@cached_specs ||= begin
- idx = installed_specs.dup
+ idx = @allow_local ? installed_specs.dup : Index.new
Dir["#{cache_path}/*.gem"].each do |gemfile|
next if gemfile =~ /^bundler\-[\d\.]+?\.gem/
diff --git a/lib/bundler/source_list.rb b/lib/bundler/source_list.rb
index 44b167ca3e..6f5636f41e 100644
--- a/lib/bundler/source_list.rb
+++ b/lib/bundler/source_list.rb
@@ -9,7 +9,7 @@ module Bundler
:metadata_source
def global_rubygems_source
- @global_rubygems_source ||= rubygems_aggregate_class.new
+ @global_rubygems_source ||= rubygems_aggregate_class.new("allow_local" => true)
end
def initialize
@@ -20,6 +20,16 @@ module Bundler
@global_path_source = nil
@rubygems_sources = []
@metadata_source = Source::Metadata.new
+
+ @disable_multisource = true
+ end
+
+ def disable_multisource?
+ @disable_multisource
+ end
+
+ def merged_gem_lockfile_sections!
+ @disable_multisource = false
end
def add_path_source(options = {})
@@ -47,7 +57,7 @@ module Bundler
end
def global_rubygems_source=(uri)
- @global_rubygems_source ||= rubygems_aggregate_class.new("remotes" => uri)
+ @global_rubygems_source ||= rubygems_aggregate_class.new("remotes" => uri, "allow_local" => true)
end
def add_rubygems_remote(uri)
@@ -77,8 +87,8 @@ module Bundler
def lock_sources
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)
+ if disable_multisource?
+ lock_sources + rubygems_sources.sort_by(&:to_s).uniq
else
lock_sources << combine_rubygems_sources
end
@@ -94,7 +104,7 @@ module Bundler
end
end
- replacement_rubygems = !Bundler.feature_flag.disable_multisource? &&
+ replacement_rubygems = !disable_multisource? &&
replacement_sources.detect {|s| s.is_a?(Source::Rubygems) }
@global_rubygems_source = replacement_rubygems if replacement_rubygems
diff --git a/lib/bundler/spec_set.rb b/lib/bundler/spec_set.rb
index 399c91fea5..dfc3114c41 100644
--- a/lib/bundler/spec_set.rb
+++ b/lib/bundler/spec_set.rb
@@ -82,6 +82,7 @@ module Bundler
materialized.map! do |s|
next s unless s.is_a?(LazySpecification)
s.source.dependency_names = deps if s.source.respond_to?(:dependency_names=)
+ s.source.local!
spec = s.__materialize__
unless spec
unless missing_specs
@@ -102,6 +103,7 @@ module Bundler
@specs.map do |s|
next s unless s.is_a?(LazySpecification)
s.source.dependency_names = names if s.source.respond_to?(:dependency_names=)
+ s.source.local!
s.source.remote!
spec = s.__materialize__
raise GemNotFound, "Could not find #{s.full_name} in any of the sources" unless spec
diff --git a/lib/bundler/templates/Gemfile b/lib/bundler/templates/Gemfile
index 1afd2cce67..d41f2719b4 100644
--- a/lib/bundler/templates/Gemfile
+++ b/lib/bundler/templates/Gemfile
@@ -2,6 +2,6 @@
source "https://rubygems.org"
-git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
+git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
# gem "rails"
diff --git a/lib/bundler/templates/gems.rb b/lib/bundler/templates/gems.rb
index 547cd6e8d9..56a62a7a82 100644
--- a/lib/bundler/templates/gems.rb
+++ b/lib/bundler/templates/gems.rb
@@ -3,6 +3,6 @@
# A sample gems.rb
source "https://rubygems.org"
-git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
+git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
# gem "rails"
diff --git a/lib/bundler/templates/newgem/Gemfile.tt b/lib/bundler/templates/newgem/Gemfile.tt
index b09ccfff15..de82a63c5f 100644
--- a/lib/bundler/templates/newgem/Gemfile.tt
+++ b/lib/bundler/templates/newgem/Gemfile.tt
@@ -14,7 +14,10 @@ gem "rake-compiler"
gem "<%= config[:test] %>", "~> <%= config[:test_framework_version] %>"
<%- end -%>
-<%- if config[:rubocop] -%>
+<%- if config[:linter] == "rubocop" -%>
-gem "rubocop", "~> <%= config[:rubocop_version] %>"
+gem "rubocop", "~> <%= config[:linter_version] %>"
+<%- elsif config[:linter] == "standard" -%>
+
+gem "standard", "~> <%= config[:linter_version] %>"
<%- end -%>
diff --git a/lib/bundler/templates/newgem/Rakefile.tt b/lib/bundler/templates/newgem/Rakefile.tt
index 0b61f1a47f..b02ada9b6c 100644
--- a/lib/bundler/templates/newgem/Rakefile.tt
+++ b/lib/bundler/templates/newgem/Rakefile.tt
@@ -27,12 +27,16 @@ require "rspec/core/rake_task"
RSpec::Core::RakeTask.new(:spec)
<% end -%>
-<% if config[:rubocop] -%>
+<% if config[:linter] == "rubocop" -%>
<% default_task_names << :rubocop -%>
require "rubocop/rake_task"
RuboCop::RakeTask.new
+<% elsif config[:linter] == "standard" -%>
+<% default_task_names << :standard -%>
+require "standard/rake"
+
<% end -%>
<% if config[:ext] -%>
<% default_task_names.unshift(:clobber, :compile) -%>
diff --git a/lib/bundler/templates/newgem/github/workflows/main.yml.tt b/lib/bundler/templates/newgem/github/workflows/main.yml.tt
index 807c8dd79a..654978033f 100644
--- a/lib/bundler/templates/newgem/github/workflows/main.yml.tt
+++ b/lib/bundler/templates/newgem/github/workflows/main.yml.tt
@@ -11,8 +11,6 @@ jobs:
uses: ruby/setup-ruby@v1
with:
ruby-version: <%= RUBY_VERSION %>
+ bundler-cache: true
- name: Run the default task
- run: |
- gem install bundler -v <%= Bundler::VERSION %>
- bundle install
- bundle exec rake
+ run: bundle exec rake
diff --git a/lib/bundler/templates/newgem/newgem.gemspec.tt b/lib/bundler/templates/newgem/newgem.gemspec.tt
index 5be20c7e4b..1f2da6d077 100644
--- a/lib/bundler/templates/newgem/newgem.gemspec.tt
+++ b/lib/bundler/templates/newgem/newgem.gemspec.tt
@@ -3,16 +3,16 @@
require_relative "lib/<%=config[:namespaced_path]%>/version"
Gem::Specification.new do |spec|
- spec.name = <%= config[:name].inspect %>
- spec.version = <%= config[:constant_name] %>::VERSION
- spec.authors = [<%= config[:author].inspect %>]
- spec.email = [<%= config[:email].inspect %>]
-
- spec.summary = "TODO: Write a short summary, because RubyGems requires one."
- spec.description = "TODO: Write a longer description or delete this line."
- spec.homepage = "TODO: Put your gem's website or public repo URL here."
+ spec.name = <%= config[:name].inspect %>
+ spec.version = <%= config[:constant_name] %>::VERSION
+ spec.authors = [<%= config[:author].inspect %>]
+ spec.email = [<%= config[:email].inspect %>]
+
+ spec.summary = "TODO: Write a short summary, because RubyGems requires one."
+ spec.description = "TODO: Write a longer description or delete this line."
+ spec.homepage = "TODO: Put your gem's website or public repo URL here."
<%- if config[:mit] -%>
- spec.license = "MIT"
+ spec.license = "MIT"
<%- end -%>
spec.required_ruby_version = Gem::Requirement.new(">= <%= config[:required_ruby_version] %>")
@@ -29,11 +29,11 @@ Gem::Specification.new do |spec|
f.match(%r{\A(?:(?:test|spec|features)/|\.(?:git|travis|circleci)|appveyor)})
end
end
- spec.bindir = "exe"
- spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
+ spec.bindir = "exe"
+ spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
spec.require_paths = ["lib"]
<%- if config[:ext] -%>
- spec.extensions = ["ext/<%= config[:underscored_name] %>/extconf.rb"]
+ spec.extensions = ["ext/<%= config[:underscored_name] %>/extconf.rb"]
<%- end -%>
# Uncomment to register a new dependency of your gem
diff --git a/lib/bundler/templates/newgem/standard.yml.tt b/lib/bundler/templates/newgem/standard.yml.tt
new file mode 100644
index 0000000000..e720f41031
--- /dev/null
+++ b/lib/bundler/templates/newgem/standard.yml.tt
@@ -0,0 +1,4 @@
+# For available configuration options, see:
+# https://github.com/testdouble/standard
+
+default_ignores: false
diff --git a/lib/bundler/vendor/tmpdir/lib/tmpdir.rb b/lib/bundler/vendor/tmpdir/lib/tmpdir.rb
index a00496687c..70d43e0c6b 100644
--- a/lib/bundler/vendor/tmpdir/lib/tmpdir.rb
+++ b/lib/bundler/vendor/tmpdir/lib/tmpdir.rb
@@ -115,7 +115,7 @@ class Bundler::Dir < Dir
Bundler::Dir.tmpdir
end
- UNUSABLE_CHARS = [File::SEPARATOR, File::ALT_SEPARATOR, File::PATH_SEPARATOR, ":"].uniq.join("").freeze
+ UNUSABLE_CHARS = "^,-.0-9A-Z_a-z~"
class << (RANDOM = Random.new)
MAX = 36**6 # < 0x100000000
diff --git a/spec/bundler/bundler/dep_proxy_spec.rb b/spec/bundler/bundler/dep_proxy_spec.rb
index 84243d2ee2..8d02a33725 100644
--- a/spec/bundler/bundler/dep_proxy_spec.rb
+++ b/spec/bundler/bundler/dep_proxy_spec.rb
@@ -22,7 +22,7 @@ RSpec.describe Bundler::DepProxy do
end
describe "frozen" do
- if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new("2.5.0")
+ if Gem.ruby_version >= Gem::Version.new("2.5.0")
error = Object.const_get("FrozenError")
else
error = RuntimeError
diff --git a/spec/bundler/bundler/gem_helper_spec.rb b/spec/bundler/bundler/gem_helper_spec.rb
index d718615ad2..6c3ac3e035 100644
--- a/spec/bundler/bundler/gem_helper_spec.rb
+++ b/spec/bundler/bundler/gem_helper_spec.rb
@@ -9,7 +9,7 @@ RSpec.describe Bundler::GemHelper do
let(:app_gemspec_path) { app_path.join("#{app_name}.gemspec") }
before(:each) do
- global_config "BUNDLE_GEM__MIT" => "false", "BUNDLE_GEM__TEST" => "false", "BUNDLE_GEM__COC" => "false", "BUNDLE_GEM__RUBOCOP" => "false",
+ global_config "BUNDLE_GEM__MIT" => "false", "BUNDLE_GEM__TEST" => "false", "BUNDLE_GEM__COC" => "false", "BUNDLE_GEM__LINTER" => "false",
"BUNDLE_GEM__CI" => "false", "BUNDLE_GEM__CHANGELOG" => "false"
bundle "gem #{app_name}"
prepare_gemspec(app_gemspec_path)
@@ -61,10 +61,16 @@ RSpec.describe Bundler::GemHelper do
mock_confirm_message message
end
+ def mock_checksum_message(name, version)
+ message = "#{name} #{version} checksum written to checksums/#{name}-#{version}.gem.sha512."
+ mock_confirm_message message
+ end
+
subject! { Bundler::GemHelper.new(app_path) }
let(:app_version) { "0.1.0" }
let(:app_gem_dir) { app_path.join("pkg") }
let(:app_gem_path) { app_gem_dir.join("#{app_name}-#{app_version}.gem") }
+ let(:app_sha_path) { app_path.join("checksums", "#{app_name}-#{app_version}.gem.sha512") }
let(:app_gemspec_content) { File.read(app_gemspec_path) }
before(:each) do
@@ -162,6 +168,37 @@ RSpec.describe Bundler::GemHelper do
end
end
+ describe "#build_checksum" do
+ context "when build was successful" do
+ it "creates .sha512 file" do
+ mock_build_message app_name, app_version
+ mock_checksum_message app_name, app_version
+ subject.build_checksum
+ expect(app_sha_path).to exist
+ end
+ end
+ context "when building in the current working directory" do
+ it "creates a .sha512 file" do
+ mock_build_message app_name, app_version
+ mock_checksum_message app_name, app_version
+ Dir.chdir app_path do
+ Bundler::GemHelper.new.build_checksum
+ end
+ expect(app_sha_path).to exist
+ end
+ end
+ context "when building in a location relative to the current working directory" do
+ it "creates a .sha512 file" do
+ mock_build_message app_name, app_version
+ mock_checksum_message app_name, app_version
+ Dir.chdir File.dirname(app_path) do
+ Bundler::GemHelper.new(File.basename(app_path)).build_checksum
+ end
+ expect(app_sha_path).to exist
+ end
+ end
+ end
+
describe "#install_gem" do
context "when installation was successful" do
it "gem is installed" do
diff --git a/spec/bundler/bundler/installer/parallel_installer_spec.rb b/spec/bundler/bundler/installer/parallel_installer_spec.rb
index ace5c1a23a..e680633862 100644
--- a/spec/bundler/bundler/installer/parallel_installer_spec.rb
+++ b/spec/bundler/bundler/installer/parallel_installer_spec.rb
@@ -44,4 +44,37 @@ The missing gems are:
end
end
end
+
+ context "when the spec set is not a valid resolution" do
+ let(:all_specs) do
+ [
+ build_spec("cucumber", "4.1.0") {|s| s.runtime "diff-lcs", "< 1.4" },
+ build_spec("diff-lcs", "1.4.4"),
+ ].flatten
+ end
+
+ it "prints a warning" do
+ expect(Bundler.ui).to receive(:warn).with(<<-W.strip)
+Your lockfile doesn't include a valid resolution.
+You can fix this by regenerating your lockfile or trying to manually editing the bad locked gems to a version that satisfies all dependencies.
+The unmet dependencies are:
+* diff-lcs (< 1.4), depended upon cucumber-4.1.0, unsatisfied by diff-lcs-1.4.4
+ W
+ subject.check_for_unmet_dependencies
+ end
+ end
+
+ context "when the spec set is a valid resolution" do
+ let(:all_specs) do
+ [
+ build_spec("cucumber", "4.1.0") {|s| s.runtime "diff-lcs", "< 1.4" },
+ build_spec("diff-lcs", "1.3"),
+ ].flatten
+ end
+
+ it "doesn't print a warning" do
+ expect(Bundler.ui).not_to receive(:warn)
+ subject.check_for_unmet_dependencies
+ end
+ end
end
diff --git a/spec/bundler/bundler/installer/spec_installation_spec.rb b/spec/bundler/bundler/installer/spec_installation_spec.rb
index a9cf09a372..e63ef26cb3 100644
--- a/spec/bundler/bundler/installer/spec_installation_spec.rb
+++ b/spec/bundler/bundler/installer/spec_installation_spec.rb
@@ -8,6 +8,10 @@ RSpec.describe Bundler::ParallelInstaller::SpecInstallation do
def a_spec.name
"I like tests"
end
+
+ def a_spec.full_name
+ "I really like tests"
+ end
a_spec
end
diff --git a/spec/bundler/bundler/source_list_spec.rb b/spec/bundler/bundler/source_list_spec.rb
index 3a0691b959..0c40ba8a77 100644
--- a/spec/bundler/bundler/source_list_spec.rb
+++ b/spec/bundler/bundler/source_list_spec.rb
@@ -372,26 +372,7 @@ RSpec.describe Bundler::SourceList do
source_list.add_git_source("uri" => "git://first-git.org/path.git")
end
- it "combines the rubygems sources into a single instance, removing duplicate remotes from the end", :bundler => "< 3" do
- expect(source_list.lock_sources).to eq [
- Bundler::Source::Git.new("uri" => "git://first-git.org/path.git"),
- Bundler::Source::Git.new("uri" => "git://second-git.org/path.git"),
- Bundler::Source::Git.new("uri" => "git://third-git.org/path.git"),
- ASourcePlugin.new("uri" => "https://second-plugin.org/random"),
- ASourcePlugin.new("uri" => "https://third-bar.org/foo"),
- Bundler::Source::Path.new("path" => "/first/path/to/gem"),
- Bundler::Source::Path.new("path" => "/second/path/to/gem"),
- Bundler::Source::Path.new("path" => "/third/path/to/gem"),
- Bundler::Source::Rubygems.new("remotes" => [
- "https://duplicate-rubygems.org",
- "https://first-rubygems.org",
- "https://second-rubygems.org",
- "https://third-rubygems.org",
- ]),
- ]
- end
-
- it "returns all sources, without combining rubygems sources", :bundler => "3" do
+ it "returns all sources, without combining rubygems sources" do
expect(source_list.lock_sources).to eq [
Bundler::Source::Git.new("uri" => "git://first-git.org/path.git"),
Bundler::Source::Git.new("uri" => "git://second-git.org/path.git"),
diff --git a/spec/bundler/commands/info_spec.rb b/spec/bundler/commands/info_spec.rb
index 7702959306..daed4587d5 100644
--- a/spec/bundler/commands/info_spec.rb
+++ b/spec/bundler/commands/info_spec.rb
@@ -182,4 +182,18 @@ RSpec.describe "bundle info" do
expect(err).to include("Could not find gem '#{invalid_regexp}'.")
end
end
+
+ context "with without configured" do
+ it "does not find the gem, but gives a helpful error" do
+ bundle "config without test"
+
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rails", group: :test
+ G
+
+ bundle "info rails", :raise_on_error => false
+ expect(err).to include("Could not find gem 'rails', because it's in the group 'test', configured to be ignored.")
+ end
+ end
end
diff --git a/spec/bundler/commands/lock_spec.rb b/spec/bundler/commands/lock_spec.rb
index 7724170a63..264af30f6c 100644
--- a/spec/bundler/commands/lock_spec.rb
+++ b/spec/bundler/commands/lock_spec.rb
@@ -86,7 +86,7 @@ RSpec.describe "bundle lock" do
it "does not fetch remote specs when using the --local option" do
bundle "lock --update --local", :raise_on_error => false
- expect(err).to match(/sources listed in your Gemfile|installed locally/)
+ expect(err).to match(/installed locally/)
end
it "works with --gemfile flag" do
diff --git a/spec/bundler/commands/newgem_spec.rb b/spec/bundler/commands/newgem_spec.rb
index c1d5e1814d..00bd009c5a 100644
--- a/spec/bundler/commands/newgem_spec.rb
+++ b/spec/bundler/commands/newgem_spec.rb
@@ -12,15 +12,16 @@ RSpec.describe "bundle gem" do
def bundle_exec_rubocop
prepare_gemspec(bundled_app(gem_name, "#{gem_name}.gemspec"))
- rubocop_version = RUBY_VERSION > "2.4" ? "1.7.0" : "0.81.0"
- gems = ["minitest", "rake", "rake-compiler", "rspec", "rubocop -v #{rubocop_version}", "test-unit"]
- gems.unshift "parallel -v 1.19.2" if RUBY_VERSION < "2.5"
- gems += ["rubocop-ast -v 1.4.0"] if rubocop_version == "1.7.0"
- path = Bundler.feature_flag.default_install_uses_path? ? local_gem_path(:base => bundled_app(gem_name)) : system_gem_path
- realworld_system_gems gems, :path => path
+ bundle "config set path #{rubocop_gems}", :dir => bundled_app(gem_name)
bundle "exec rubocop --debug --config .rubocop.yml", :dir => bundled_app(gem_name)
end
+ def bundle_exec_standardrb
+ prepare_gemspec(bundled_app(gem_name, "#{gem_name}.gemspec"))
+ bundle "config set path #{standard_gems}", :dir => bundled_app(gem_name)
+ bundle "exec standardrb --debug", :dir => bundled_app(gem_name)
+ end
+
let(:generated_gemspec) { Bundler.load_gemspec_uncached(bundled_app(gem_name).join("#{gem_name}.gemspec")) }
let(:gem_name) { "mygem" }
@@ -102,7 +103,7 @@ RSpec.describe "bundle gem" do
expect(bundled_app("#{gem_name}/README.md").read).to match(%r{https://github\.com/bundleuser/#{gem_name}/blob/.*/CODE_OF_CONDUCT.md})
end
- it "generates the README with a section for the Code of Conduct, respecting the configured git default branch" do
+ it "generates the README with a section for the Code of Conduct, respecting the configured git default branch", :git => ">= 2.28.0" do
sys_exec("git config --global init.defaultBranch main")
bundle "gem #{gem_name} --coc"
@@ -147,8 +148,68 @@ RSpec.describe "bundle gem" do
end
shared_examples_for "--rubocop flag" do
+ context "is deprecated", :bundler => "< 3" do
+ before do
+ bundle "gem #{gem_name} --rubocop"
+ end
+
+ it "generates a gem skeleton with rubocop" do
+ gem_skeleton_assertions
+ expect(bundled_app("test-gem/Rakefile")).to read_as(
+ include("# frozen_string_literal: true").
+ and(include('require "rubocop/rake_task"').
+ and(include("RuboCop::RakeTask.new").
+ and(match(/default:.+:rubocop/))))
+ )
+ end
+
+ it "includes rubocop in generated Gemfile" do
+ allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile)
+ builder = Bundler::Dsl.new
+ builder.eval_gemfile(bundled_app("#{gem_name}/Gemfile"))
+ builder.dependencies
+ rubocop_dep = builder.dependencies.find {|d| d.name == "rubocop" }
+ expect(rubocop_dep).not_to be_nil
+ end
+
+ it "generates a default .rubocop.yml" do
+ expect(bundled_app("#{gem_name}/.rubocop.yml")).to exist
+ end
+ end
+ end
+
+ shared_examples_for "--no-rubocop flag" do
+ context "is deprecated", :bundler => "< 3" do
+ define_negated_matcher :exclude, :include
+
+ before do
+ bundle "gem #{gem_name} --no-rubocop"
+ end
+
+ it "generates a gem skeleton without rubocop" do
+ gem_skeleton_assertions
+ expect(bundled_app("test-gem/Rakefile")).to read_as(exclude("rubocop"))
+ expect(bundled_app("test-gem/#{gem_name}.gemspec")).to read_as(exclude("rubocop"))
+ end
+
+ it "does not include rubocop in generated Gemfile" do
+ allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile)
+ builder = Bundler::Dsl.new
+ builder.eval_gemfile(bundled_app("#{gem_name}/Gemfile"))
+ builder.dependencies
+ rubocop_dep = builder.dependencies.find {|d| d.name == "rubocop" }
+ expect(rubocop_dep).to be_nil
+ end
+
+ it "doesn't generate a default .rubocop.yml" do
+ expect(bundled_app("#{gem_name}/.rubocop.yml")).to_not exist
+ end
+ end
+ end
+
+ shared_examples_for "--linter=rubocop flag" do
before do
- bundle "gem #{gem_name} --rubocop"
+ bundle "gem #{gem_name} --linter=rubocop"
end
it "generates a gem skeleton with rubocop" do
@@ -175,11 +236,38 @@ RSpec.describe "bundle gem" do
end
end
- shared_examples_for "--no-rubocop flag" do
+ shared_examples_for "--linter=standard flag" do
+ before do
+ bundle "gem #{gem_name} --linter=standard"
+ end
+
+ it "generates a gem skeleton with standard" do
+ gem_skeleton_assertions
+ expect(bundled_app("test-gem/Rakefile")).to read_as(
+ include('require "standard/rake"').
+ and(match(/default:.+:standard/))
+ )
+ end
+
+ it "includes standard in generated Gemfile" do
+ allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile)
+ builder = Bundler::Dsl.new
+ builder.eval_gemfile(bundled_app("#{gem_name}/Gemfile"))
+ builder.dependencies
+ standard_dep = builder.dependencies.find {|d| d.name == "standard" }
+ expect(standard_dep).not_to be_nil
+ end
+
+ it "generates a default .standard.yml" do
+ expect(bundled_app("#{gem_name}/.standard.yml")).to exist
+ end
+ end
+
+ shared_examples_for "--linter=none flag" do
define_negated_matcher :exclude, :include
before do
- bundle "gem #{gem_name} --no-rubocop"
+ bundle "gem #{gem_name} --linter=none"
end
it "generates a gem skeleton without rubocop" do
@@ -197,46 +285,66 @@ RSpec.describe "bundle gem" do
expect(rubocop_dep).to be_nil
end
+ it "does not include standard in generated Gemfile" do
+ allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile)
+ builder = Bundler::Dsl.new
+ builder.eval_gemfile(bundled_app("#{gem_name}/Gemfile"))
+ builder.dependencies
+ standard_dep = builder.dependencies.find {|d| d.name == "standard" }
+ expect(standard_dep).to be_nil
+ end
+
it "doesn't generate a default .rubocop.yml" do
expect(bundled_app("#{gem_name}/.rubocop.yml")).to_not exist
end
+
+ it "doesn't generate a default .standard.yml" do
+ expect(bundled_app("#{gem_name}/.standard.yml")).to_not exist
+ end
end
- it "has no rubocop offenses when using --rubocop flag", :readline do
+ it "has no rubocop offenses when using --linter=rubocop flag", :readline do
skip "ruby_core has an 'ast.rb' file that gets in the middle and breaks this spec" if ruby_core?
- bundle "gem #{gem_name} --rubocop"
+ bundle "gem #{gem_name} --linter=rubocop"
bundle_exec_rubocop
expect(err).to be_empty
end
- it "has no rubocop offenses when using --ext and --rubocop flag", :readline do
+ it "has no rubocop offenses when using --ext and --linter=rubocop flag", :readline do
skip "ruby_core has an 'ast.rb' file that gets in the middle and breaks this spec" if ruby_core?
- bundle "gem #{gem_name} --ext --rubocop"
+ bundle "gem #{gem_name} --ext --linter=rubocop"
bundle_exec_rubocop
expect(err).to be_empty
end
- it "has no rubocop offenses when using --ext, --test=minitest, and --rubocop flag", :readline do
+ it "has no rubocop offenses when using --ext, --test=minitest, and --linter=rubocop flag", :readline do
skip "ruby_core has an 'ast.rb' file that gets in the middle and breaks this spec" if ruby_core?
- bundle "gem #{gem_name} --ext --test=minitest --rubocop"
+ bundle "gem #{gem_name} --ext --test=minitest --linter=rubocop"
bundle_exec_rubocop
expect(err).to be_empty
end
- it "has no rubocop offenses when using --ext, --test=rspec, and --rubocop flag", :readline do
+ it "has no rubocop offenses when using --ext, --test=rspec, and --linter=rubocop flag", :readline do
skip "ruby_core has an 'ast.rb' file that gets in the middle and breaks this spec" if ruby_core?
- bundle "gem #{gem_name} --ext --test=rspec --rubocop"
+ bundle "gem #{gem_name} --ext --test=rspec --linter=rubocop"
bundle_exec_rubocop
expect(err).to be_empty
end
- it "has no rubocop offenses when using --ext, --ext=test-unit, and --rubocop flag", :readline do
+ it "has no rubocop offenses when using --ext, --ext=test-unit, and --linter=rubocop flag", :readline do
skip "ruby_core has an 'ast.rb' file that gets in the middle and breaks this spec" if ruby_core?
- bundle "gem #{gem_name} --ext --test=test-unit --rubocop"
+ bundle "gem #{gem_name} --ext --test=test-unit --linter=rubocop"
bundle_exec_rubocop
expect(err).to be_empty
end
+ it "has no standard offenses when using --linter=standard flag", :readline do
+ skip "ruby_core has an 'ast.rb' file that gets in the middle and breaks this spec" if ruby_core?
+ bundle "gem #{gem_name} --linter=standard"
+ bundle_exec_standardrb
+ expect(err).to be_empty
+ end
+
shared_examples_for "CI config is absent" do
it "does not create any CI files" do
expect(bundled_app("#{gem_name}/.github/workflows/main.yml")).to_not exist
@@ -351,6 +459,55 @@ RSpec.describe "bundle gem" do
end
end
+ shared_examples_for "--github-username option" do |github_username|
+ before do
+ bundle "gem #{gem_name} --github-username=#{github_username}"
+ end
+
+ it "generates a gem skeleton" do
+ gem_skeleton_assertions
+ end
+
+ it "contribute URL set to given github username" do
+ expect(bundled_app("#{gem_name}/README.md").read).not_to include("[USERNAME]")
+ expect(bundled_app("#{gem_name}/README.md").read).to include("github.com/#{github_username}")
+ end
+ end
+
+ shared_examples_for "github_username configuration" do
+ context "with github_username setting set to some value" do
+ before do
+ global_config "BUNDLE_GEM__GITHUB_USERNAME" => "different_username"
+ bundle "gem #{gem_name}"
+ end
+
+ it "generates a gem skeleton" do
+ gem_skeleton_assertions
+ end
+
+ it "contribute URL set to bundle config setting" do
+ expect(bundled_app("#{gem_name}/README.md").read).not_to include("[USERNAME]")
+ expect(bundled_app("#{gem_name}/README.md").read).to include("github.com/different_username")
+ end
+ end
+
+ context "with github_username setting set to false" do
+ before do
+ global_config "BUNDLE_GEM__GITHUB_USERNAME" => "false"
+ bundle "gem #{gem_name}"
+ end
+
+ it "generates a gem skeleton" do
+ gem_skeleton_assertions
+ end
+
+ it "contribute URL set to [USERNAME]" do
+ expect(bundled_app("#{gem_name}/README.md").read).to include("[USERNAME]")
+ expect(bundled_app("#{gem_name}/README.md").read).not_to include("github.com/bundleuser")
+ end
+ end
+ end
+
shared_examples_for "generating a gem" do
it "generates a gem skeleton" do
bundle "gem #{gem_name}"
@@ -841,6 +998,127 @@ RSpec.describe "bundle gem" do
end
end
+ context "--linter with no argument" do
+ it "does not generate any linter config" do
+ bundle "gem #{gem_name}"
+
+ expect(bundled_app("#{gem_name}/.rubocop.yml")).to_not exist
+ expect(bundled_app("#{gem_name}/.standard.yml")).to_not exist
+ end
+ end
+
+ context "--linter set to rubocop" do
+ it "generates a RuboCop config" do
+ bundle "gem #{gem_name} --linter=rubocop"
+
+ expect(bundled_app("#{gem_name}/.rubocop.yml")).to exist
+ expect(bundled_app("#{gem_name}/.standard.yml")).to_not exist
+ end
+ end
+
+ context "--linter set to standard" do
+ it "generates a Standard config" do
+ bundle "gem #{gem_name} --linter=standard"
+
+ expect(bundled_app("#{gem_name}/.standard.yml")).to exist
+ expect(bundled_app("#{gem_name}/.rubocop.yml")).to_not exist
+ end
+ end
+
+ context "gem.linter setting set to none" do
+ it "doesn't generate any linter config" do
+ bundle "gem #{gem_name}"
+
+ expect(bundled_app("#{gem_name}/.rubocop.yml")).to_not exist
+ expect(bundled_app("#{gem_name}/.standard.yml")).to_not exist
+ end
+ end
+
+ context "gem.linter setting set to rubocop" do
+ it "generates a RuboCop config file" do
+ bundle "config set gem.linter rubocop"
+ bundle "gem #{gem_name}"
+
+ expect(bundled_app("#{gem_name}/.rubocop.yml")).to exist
+ end
+ end
+
+ context "gem.linter setting set to standard" do
+ it "generates a Standard config file" do
+ bundle "config set gem.linter standard"
+ bundle "gem #{gem_name}"
+
+ expect(bundled_app("#{gem_name}/.standard.yml")).to exist
+ end
+ end
+
+ context "gem.rubocop setting set to true", :bundler => "< 3" do
+ before do
+ bundle "config set gem.rubocop true"
+ bundle "gem #{gem_name}"
+ end
+
+ it "generates rubocop config" do
+ expect(bundled_app("#{gem_name}/.rubocop.yml")).to exist
+ end
+
+ it "unsets gem.rubocop" do
+ bundle "config gem.rubocop"
+ expect(out).to include("You have not configured a value for `gem.rubocop`")
+ end
+
+ it "sets gem.linter=rubocop instead" do
+ bundle "config gem.linter"
+ expect(out).to match(/Set for the current user .*: "rubocop"/)
+ end
+ end
+
+ context "gem.linter set to rubocop and --linter with no arguments", :hint_text do
+ before do
+ bundle "config set gem.linter rubocop"
+ bundle "gem #{gem_name} --linter"
+ end
+
+ it "generates a RuboCop config file" do
+ expect(bundled_app("#{gem_name}/.rubocop.yml")).to exist
+ end
+
+ it "hints that --linter is already configured" do
+ expect(out).to match("rubocop is already configured, ignoring --linter flag.")
+ end
+ end
+
+ context "gem.linter setting set to false and --linter with no arguments", :hint_text do
+ before do
+ bundle "config set gem.linter false"
+ bundle "gem #{gem_name} --linter"
+ end
+
+ it "asks to setup a linter" do
+ expect(out).to match("Do you want to add a code linter and formatter to your gem?")
+ end
+
+ it "hints that the choice will only be applied to the current gem" do
+ expect(out).to match("Your choice will only be applied to this gem.")
+ end
+ end
+
+ context "gem.linter setting not set and --linter with no arguments", :hint_text do
+ before do
+ bundle "gem #{gem_name} --linter"
+ end
+
+ it "asks to setup a linter" do
+ expect(out).to match("Do you want to add a code linter and formatter to your gem?")
+ end
+
+ it "hints that the choice will be applied to future bundle gem calls" do
+ hint = "Future `bundle gem` calls will use your choice. " \
+ "This setting can be changed anytime with `bundle config gem.linter`."
+ expect(out).to match(hint)
+ end
+ end
+
context "--edit option" do
it "opens the generated gemspec in the user's text editor" do
output = bundle "gem #{gem_name} --edit=echo"
@@ -891,6 +1169,9 @@ RSpec.describe "bundle gem" do
before do
global_config "BUNDLE_GEM__RUBOCOP" => "true"
end
+ it_behaves_like "--linter=rubocop flag"
+ it_behaves_like "--linter=standard flag"
+ it_behaves_like "--linter=none flag"
it_behaves_like "--rubocop flag"
it_behaves_like "--no-rubocop flag"
end
@@ -899,10 +1180,40 @@ RSpec.describe "bundle gem" do
before do
global_config "BUNDLE_GEM__RUBOCOP" => "false"
end
+ it_behaves_like "--linter=rubocop flag"
+ it_behaves_like "--linter=standard flag"
+ it_behaves_like "--linter=none flag"
it_behaves_like "--rubocop flag"
it_behaves_like "--no-rubocop flag"
end
+ context "with linter option in bundle config settings set to rubocop" do
+ before do
+ global_config "BUNDLE_GEM__LINTER" => "rubocop"
+ end
+ it_behaves_like "--linter=rubocop flag"
+ it_behaves_like "--linter=standard flag"
+ it_behaves_like "--linter=none flag"
+ end
+
+ context "with linter option in bundle config settings set to standard" do
+ before do
+ global_config "BUNDLE_GEM__LINTER" => "standard"
+ end
+ it_behaves_like "--linter=rubocop flag"
+ it_behaves_like "--linter=standard flag"
+ it_behaves_like "--linter=none flag"
+ end
+
+ context "with linter option in bundle config settings set to false" do
+ before do
+ global_config "BUNDLE_GEM__LINTER" => "false"
+ end
+ it_behaves_like "--linter=rubocop flag"
+ it_behaves_like "--linter=standard flag"
+ it_behaves_like "--linter=none flag"
+ end
+
context "with changelog option in bundle config settings set to true" do
before do
global_config "BUNDLE_GEM__CHANGELOG" => "true"
@@ -920,6 +1231,57 @@ RSpec.describe "bundle gem" do
end
end
+ context "testing --github-username option against git and bundle config settings", :readline do
+ context "without git config set" do
+ before do
+ sys_exec("git config --global --unset github.user")
+ end
+ context "with github-username option in bundle config settings set to some value" do
+ before do
+ global_config "BUNDLE_GEM__GITHUB_USERNAME" => "different_username"
+ end
+ it_behaves_like "--github-username option", "gh_user"
+ end
+
+ context "with github-username option in bundle config settings set to false" do
+ before do
+ global_config "BUNDLE_GEM__GITHUB_USERNAME" => "false"
+ end
+ it_behaves_like "--github-username option", "gh_user"
+ end
+ end
+
+ context "with git config set" do
+ context "with github-username option in bundle config settings set to some value" do
+ before do
+ global_config "BUNDLE_GEM__GITHUB_USERNAME" => "different_username"
+ end
+ it_behaves_like "--github-username option", "gh_user"
+ end
+
+ context "with github-username option in bundle config settings set to false" do
+ before do
+ global_config "BUNDLE_GEM__GITHUB_USERNAME" => "false"
+ end
+ it_behaves_like "--github-username option", "gh_user"
+ end
+ end
+ end
+
+ context "testing github_username bundle config against git config settings", :readline do
+ context "without git config set" do
+ before do
+ sys_exec("git config --global --unset github.user")
+ end
+
+ it_behaves_like "github_username configuration"
+ end
+
+ context "with git config set" do
+ it_behaves_like "github_username configuration"
+ end
+ end
+
context "gem naming with underscore", :readline do
let(:gem_name) { "test_gem" }
@@ -1073,7 +1435,7 @@ Usage: "bundle gem NAME [OPTIONS]"
end
it "asks about CI service" do
- global_config "BUNDLE_GEM__TEST" => "false", "BUNDLE_GEM__MIT" => "false", "BUNDLE_GEM__COC" => "false", "BUNDLE_GEM__RUBOCOP" => "false"
+ global_config "BUNDLE_GEM__TEST" => "false", "BUNDLE_GEM__MIT" => "false", "BUNDLE_GEM__COC" => "false", "BUNDLE_GEM__LINTER" => "false"
bundle "gem foobar" do |input, _, _|
input.puts "github"
@@ -1083,7 +1445,7 @@ Usage: "bundle gem NAME [OPTIONS]"
end
it "asks about MIT license" do
- global_config "BUNDLE_GEM__TEST" => "false", "BUNDLE_GEM__COC" => "false", "BUNDLE_GEM__CI" => "false", "BUNDLE_GEM__RUBOCOP" => "false"
+ global_config "BUNDLE_GEM__TEST" => "false", "BUNDLE_GEM__COC" => "false", "BUNDLE_GEM__CI" => "false", "BUNDLE_GEM__LINTER" => "false"
bundle "config list"
@@ -1095,7 +1457,7 @@ Usage: "bundle gem NAME [OPTIONS]"
end
it "asks about CoC" do
- global_config "BUNDLE_GEM__MIT" => "false", "BUNDLE_GEM__TEST" => "false", "BUNDLE_GEM__CI" => "false", "BUNDLE_GEM__RUBOCOP" => "false"
+ global_config "BUNDLE_GEM__MIT" => "false", "BUNDLE_GEM__TEST" => "false", "BUNDLE_GEM__CI" => "false", "BUNDLE_GEM__LINTER" => "false"
bundle "gem foobar" do |input, _, _|
input.puts "yes"
@@ -1105,7 +1467,7 @@ Usage: "bundle gem NAME [OPTIONS]"
end
it "asks about CHANGELOG" do
- global_config "BUNDLE_GEM__MIT" => "false", "BUNDLE_GEM__TEST" => "false", "BUNDLE_GEM__CI" => "false", "BUNDLE_GEM__RUBOCOP" => "false",
+ global_config "BUNDLE_GEM__MIT" => "false", "BUNDLE_GEM__TEST" => "false", "BUNDLE_GEM__CI" => "false", "BUNDLE_GEM__LINTER" => "false",
"BUNDLE_GEM__COC" => "false"
bundle "gem foobar" do |input, _, _|
diff --git a/spec/bundler/commands/outdated_spec.rb b/spec/bundler/commands/outdated_spec.rb
index 0ee8bd425a..7c4005824c 100644
--- a/spec/bundler/commands/outdated_spec.rb
+++ b/spec/bundler/commands/outdated_spec.rb
@@ -929,4 +929,54 @@ RSpec.describe "bundle outdated" do
expect(out).to end_with(expected_output)
end
end
+
+ describe "with a multiplatform lockfile" do
+ before do
+ build_repo4 do
+ build_gem "nokogiri", "1.11.1"
+ build_gem "nokogiri", "1.11.1" do |s|
+ s.platform = Bundler.local_platform
+ end
+
+ build_gem "nokogiri", "1.11.2"
+ build_gem "nokogiri", "1.11.2" do |s|
+ s.platform = Bundler.local_platform
+ end
+ end
+
+ lockfile <<~L
+ GEM
+ remote: #{file_uri_for(gem_repo4)}/
+ specs:
+ nokogiri (1.11.1)
+ nokogiri (1.11.1-#{Bundler.local_platform})
+
+ PLATFORMS
+ ruby
+ #{Bundler.local_platform}
+
+ DEPENDENCIES
+ nokogiri
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
+
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo4)}"
+ gem "nokogiri"
+ G
+ end
+
+ it "reports a single entry per gem" do
+ bundle "outdated", :raise_on_error => false
+
+ expected_output = <<~TABLE.strip
+ Gem Current Latest Requested Groups
+ nokogiri 1.11.1 1.11.2 >= 0 default
+ TABLE
+
+ expect(out).to end_with(expected_output)
+ end
+ end
end
diff --git a/spec/bundler/commands/post_bundle_message_spec.rb b/spec/bundler/commands/post_bundle_message_spec.rb
index 104221efbe..72f8020b44 100644
--- a/spec/bundler/commands/post_bundle_message_spec.rb
+++ b/spec/bundler/commands/post_bundle_message_spec.rb
@@ -32,21 +32,21 @@ RSpec.describe "post bundle message" do
bundle "config set --local without emo"
bundle :install
expect(out).to include(bundle_show_message)
- expect(out).to include("Gems in the group emo were not installed")
+ expect(out).to include("Gems in the group 'emo' were not installed")
expect(out).to include(bundle_complete_message)
expect(out).to include(installed_gems_stats)
bundle "config set --local without emo test"
bundle :install
expect(out).to include(bundle_show_message)
- expect(out).to include("Gems in the groups emo and test were not installed")
+ expect(out).to include("Gems in the groups 'emo' and 'test' were not installed")
expect(out).to include(bundle_complete_message)
expect(out).to include("4 Gemfile dependencies, 3 gems now installed.")
bundle "config set --local without emo obama test"
bundle :install
expect(out).to include(bundle_show_message)
- expect(out).to include("Gems in the groups emo, obama and test were not installed")
+ expect(out).to include("Gems in the groups 'emo', 'obama' and 'test' were not installed")
expect(out).to include(bundle_complete_message)
expect(out).to include("4 Gemfile dependencies, 2 gems now installed.")
end
@@ -65,21 +65,21 @@ RSpec.describe "post bundle message" do
bundle "config set --local without emo"
bundle :install
expect(out).to include(bundle_show_path_message)
- expect(out).to include("Gems in the group emo were not installed")
+ expect(out).to include("Gems in the group 'emo' were not installed")
expect(out).to include(bundle_complete_message)
bundle "config set --local path vendor"
bundle "config set --local without emo test"
bundle :install
expect(out).to include(bundle_show_path_message)
- expect(out).to include("Gems in the groups emo and test were not installed")
+ expect(out).to include("Gems in the groups 'emo' and 'test' were not installed")
expect(out).to include(bundle_complete_message)
bundle "config set --local path vendor"
bundle "config set --local without emo obama test"
bundle :install
expect(out).to include(bundle_show_path_message)
- expect(out).to include("Gems in the groups emo, obama and test were not installed")
+ expect(out).to include("Gems in the groups 'emo', 'obama' and 'test' were not installed")
expect(out).to include(bundle_complete_message)
end
end
@@ -156,7 +156,7 @@ The source does not contain any versions of 'not-a-gem'
bundle "install --without emo"
bundle :install
expect(out).to include(bundle_show_message)
- expect(out).to include("Gems in the group emo were not installed")
+ expect(out).to include("Gems in the group 'emo' were not installed")
expect(out).to include(bundle_complete_message)
expect(out).to include(installed_gems_stats)
end
@@ -165,7 +165,7 @@ The source does not contain any versions of 'not-a-gem'
bundle "install --without emo test"
bundle :install
expect(out).to include(bundle_show_message)
- expect(out).to include("Gems in the groups emo and test were not installed")
+ expect(out).to include("Gems in the groups 'emo' and 'test' were not installed")
expect(out).to include(bundle_complete_message)
end
@@ -173,7 +173,7 @@ The source does not contain any versions of 'not-a-gem'
bundle "install --without emo obama test"
bundle :install
expect(out).to include(bundle_show_message)
- expect(out).to include("Gems in the groups emo, obama and test were not installed")
+ expect(out).to include("Gems in the groups 'emo', 'obama' and 'test' were not installed")
expect(out).to include(bundle_complete_message)
end
end
@@ -187,19 +187,19 @@ The source does not contain any versions of 'not-a-gem'
bundle "config set --local without emo"
bundle :install
bundle :update, :all => true
- expect(out).to include("Gems in the group emo were not updated")
+ expect(out).to include("Gems in the group 'emo' were not updated")
expect(out).to include(bundle_updated_message)
bundle "config set --local without emo test"
bundle :install
bundle :update, :all => true
- expect(out).to include("Gems in the groups emo and test were not updated")
+ expect(out).to include("Gems in the groups 'emo' and 'test' were not updated")
expect(out).to include(bundle_updated_message)
bundle "config set --local without emo obama test"
bundle :install
bundle :update, :all => true
- expect(out).to include("Gems in the groups emo, obama and test were not updated")
+ expect(out).to include("Gems in the groups 'emo', 'obama' and 'test' were not updated")
expect(out).to include(bundle_updated_message)
end
end
diff --git a/spec/bundler/commands/update_spec.rb b/spec/bundler/commands/update_spec.rb
index 521c175711..0f17d931a3 100644
--- a/spec/bundler/commands/update_spec.rb
+++ b/spec/bundler/commands/update_spec.rb
@@ -148,72 +148,66 @@ RSpec.describe "bundle update" do
end
describe "when a possible resolve requires an older version of a locked gem" do
- context "and only_update_to_newer_versions is set" do
- before do
- bundle "config set only_update_to_newer_versions true"
- end
-
- it "does not go to an older version" do
- build_repo4 do
- build_gem "tilt", "2.0.8"
- build_gem "slim", "3.0.9" do |s|
- s.add_dependency "tilt", [">= 1.3.3", "< 2.1"]
- end
- build_gem "slim_lint", "0.16.1" do |s|
- s.add_dependency "slim", [">= 3.0", "< 5.0"]
- end
- build_gem "slim-rails", "0.2.1" do |s|
- s.add_dependency "slim", ">= 0.9.2"
- end
- build_gem "slim-rails", "3.1.3" do |s|
- s.add_dependency "slim", "~> 3.0"
- end
+ it "does not go to an older version" do
+ build_repo4 do
+ build_gem "tilt", "2.0.8"
+ build_gem "slim", "3.0.9" do |s|
+ s.add_dependency "tilt", [">= 1.3.3", "< 2.1"]
+ end
+ build_gem "slim_lint", "0.16.1" do |s|
+ s.add_dependency "slim", [">= 3.0", "< 5.0"]
+ end
+ build_gem "slim-rails", "0.2.1" do |s|
+ s.add_dependency "slim", ">= 0.9.2"
+ end
+ build_gem "slim-rails", "3.1.3" do |s|
+ s.add_dependency "slim", "~> 3.0"
end
+ end
- install_gemfile <<-G
- source "#{file_uri_for(gem_repo4)}"
- gem "slim-rails"
- gem "slim_lint"
- G
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo4)}"
+ gem "slim-rails"
+ gem "slim_lint"
+ G
- expect(the_bundle).to include_gems("slim 3.0.9", "slim-rails 3.1.3", "slim_lint 0.16.1")
+ expect(the_bundle).to include_gems("slim 3.0.9", "slim-rails 3.1.3", "slim_lint 0.16.1")
- update_repo4 do
- build_gem "slim", "4.0.0" do |s|
- s.add_dependency "tilt", [">= 2.0.6", "< 2.1"]
- end
+ update_repo4 do
+ build_gem "slim", "4.0.0" do |s|
+ s.add_dependency "tilt", [">= 2.0.6", "< 2.1"]
end
+ end
- bundle "update", :all => true
+ bundle "update", :all => true
- expect(the_bundle).to include_gems("slim 3.0.9", "slim-rails 3.1.3", "slim_lint 0.16.1")
- end
+ expect(the_bundle).to include_gems("slim 3.0.9", "slim-rails 3.1.3", "slim_lint 0.16.1")
+ end
- it "should still downgrade if forced by the Gemfile" do
- build_repo4 do
- build_gem "a"
- build_gem "b", "1.0"
- build_gem "b", "2.0"
- end
+ it "should still downgrade if forced by the Gemfile" do
+ build_repo4 do
+ build_gem "a"
+ build_gem "b", "1.0"
+ build_gem "b", "2.0"
+ end
- install_gemfile <<-G
- source "#{file_uri_for(gem_repo4)}"
- gem "a"
- gem "b"
- G
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo4)}"
+ gem "a"
+ gem "b"
+ G
- expect(the_bundle).to include_gems("a 1.0", "b 2.0")
+ expect(the_bundle).to include_gems("a 1.0", "b 2.0")
- gemfile <<-G
- source "#{file_uri_for(gem_repo4)}"
- gem "a"
- gem "b", "1.0"
- G
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo4)}"
+ gem "a"
+ gem "b", "1.0"
+ G
- bundle "update b"
+ bundle "update b"
- expect(the_bundle).to include_gems("a 1.0", "b 1.0")
- end
+ expect(the_bundle).to include_gems("a 1.0", "b 1.0")
end
end
diff --git a/spec/bundler/install/deploy_spec.rb b/spec/bundler/install/deploy_spec.rb
index f3898c0a65..8f6298b301 100644
--- a/spec/bundler/install/deploy_spec.rb
+++ b/spec/bundler/install/deploy_spec.rb
@@ -126,21 +126,21 @@ RSpec.describe "install in deployment or frozen mode" do
bundle "config set --local path vendor/bundle"
bundle "install"
gemfile <<-G
- source "http://user_name:password@localgemserver.test/"
- gem "rack"
+ source "http://user_name:password@localgemserver.test/"
+ gem "rack"
G
lockfile <<-G
- GEM
- remote: http://localgemserver.test/
- specs:
- rack (1.0.0)
+ GEM
+ remote: http://localgemserver.test/
+ specs:
+ rack (1.0.0)
- PLATFORMS
- #{local}
+ PLATFORMS
+ #{local}
- DEPENDENCIES
- rack
+ DEPENDENCIES
+ rack
G
bundle "config set --local deployment true"
diff --git a/spec/bundler/install/gemfile/gemspec_spec.rb b/spec/bundler/install/gemfile/gemspec_spec.rb
index a70b950e1b..ec6a1d4a4a 100644
--- a/spec/bundler/install/gemfile/gemspec_spec.rb
+++ b/spec/bundler/install/gemfile/gemspec_spec.rb
@@ -259,7 +259,7 @@ RSpec.describe "bundle install from an existing gemspec" do
expect(out).to eq("WIN")
end
- it "works with only_update_to_newer_versions" do
+ it "handles downgrades" do
build_lib "omg", "2.0", :path => lib_path("omg")
install_gemfile <<-G
@@ -268,7 +268,7 @@ RSpec.describe "bundle install from an existing gemspec" do
build_lib "omg", "1.0", :path => lib_path("omg")
- bundle :install, :env => { "BUNDLE_BUNDLE_ONLY_UPDATE_TO_NEWER_VERSIONS" => "true" }
+ bundle :install
expect(the_bundle).to include_gems "omg 1.0"
end
diff --git a/spec/bundler/install/gemfile/path_spec.rb b/spec/bundler/install/gemfile/path_spec.rb
index 3463c5ec06..1c77b3a37e 100644
--- a/spec/bundler/install/gemfile/path_spec.rb
+++ b/spec/bundler/install/gemfile/path_spec.rb
@@ -173,7 +173,7 @@ RSpec.describe "bundle install with explicit source paths" do
expect(the_bundle).to include_gems "foo 1.0"
end
- it "works with only_update_to_newer_versions" do
+ it "handles downgrades" do
build_lib "omg", "2.0", :path => lib_path("omg")
install_gemfile <<-G
@@ -182,7 +182,7 @@ RSpec.describe "bundle install with explicit source paths" do
build_lib "omg", "1.0", :path => lib_path("omg")
- bundle :install, :env => { "BUNDLE_BUNDLE_ONLY_UPDATE_TO_NEWER_VERSIONS" => "true" }
+ bundle :install
expect(the_bundle).to include_gems "omg 1.0"
end
@@ -328,11 +328,12 @@ RSpec.describe "bundle install with explicit source paths" do
s.executables = "foobar"
end
- install_gemfile <<-G
+ install_gemfile <<-G, :verbose => true
path "#{lib_path("foo-1.0")}" do
gem 'foo'
end
G
+ expect(out).to include("Using foo 1.0 from source at `#{lib_path("foo-1.0")}` and installing its executables")
expect(the_bundle).to include_gems "foo 1.0"
bundle "exec foobar"
diff --git a/spec/bundler/install/gemfile/sources_spec.rb b/spec/bundler/install/gemfile/sources_spec.rb
index b388b17881..d86bc18311 100644
--- a/spec/bundler/install/gemfile/sources_spec.rb
+++ b/spec/bundler/install/gemfile/sources_spec.rb
@@ -141,156 +141,159 @@ RSpec.describe "bundle install with gems on multiple sources" do
end
end
- context "when a pinned gem has an indirect dependency" do
+ context "when a pinned gem has an indirect dependency in the pinned source" do
before do
build_repo gem_repo3 do
build_gem "depends_on_rack", "1.0.1" do |s|
s.add_dependency "rack"
end
end
- end
- context "when the indirect dependency is in the pinned source" do
- before do
- # we need a working rack gem in repo3
- update_repo gem_repo3 do
- build_gem "rack", "1.0.0"
- end
-
- gemfile <<-G
- source "#{file_uri_for(gem_repo2)}"
- source "#{file_uri_for(gem_repo3)}" do
- gem "depends_on_rack"
- end
- G
+ # we need a working rack gem in repo3
+ update_repo gem_repo3 do
+ build_gem "rack", "1.0.0"
end
- context "and not in any other sources" do
- before do
- build_repo(gem_repo2) {}
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
+ source "#{file_uri_for(gem_repo3)}" do
+ gem "depends_on_rack"
end
+ G
+ end
- it "installs from the same source without any warning" do
- bundle :install
- expect(err).not_to include("Warning")
- expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0", :source => "remote3")
- end
+ context "and not in any other sources" do
+ before do
+ build_repo(gem_repo2) {}
end
- context "and in another source" do
- before do
- # need this to be broken to check for correct source ordering
- build_repo gem_repo2 do
- build_gem "rack", "1.0.0" do |s|
- s.write "lib/rack.rb", "RACK = 'FAIL'"
- end
+ it "installs from the same source without any warning" do
+ bundle :install
+ expect(err).not_to include("Warning")
+ expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0", :source => "remote3")
+ end
+ end
+
+ context "and in another source" do
+ before do
+ # need this to be broken to check for correct source ordering
+ build_repo gem_repo2 do
+ build_gem "rack", "1.0.0" do |s|
+ s.write "lib/rack.rb", "RACK = 'FAIL'"
end
end
+ end
- it "installs from the same source without any warning" do
- bundle :install
+ it "installs from the same source without any warning" do
+ bundle :install
- expect(err).not_to include("Warning: the gem 'rack' was found in multiple sources.")
- expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0", :source => "remote3")
+ expect(err).not_to include("Warning: the gem 'rack' was found in multiple sources.")
+ expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0", :source => "remote3")
- # In https://github.com/bundler/bundler/issues/3585 this failed
- # when there is already a lock file, and the gems are missing, so try again
- system_gems []
- bundle :install
+ # In https://github.com/bundler/bundler/issues/3585 this failed
+ # when there is already a lock file, and the gems are missing, so try again
+ system_gems []
+ bundle :install
- expect(err).not_to include("Warning: the gem 'rack' was found in multiple sources.")
- expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0", :source => "remote3")
- end
+ expect(err).not_to include("Warning: the gem 'rack' was found in multiple sources.")
+ expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0", :source => "remote3")
end
end
+ end
- context "when the indirect dependency is in a different source" do
- before do
- # In these tests, we need a working rack gem in repo2 and not repo3
- build_repo gem_repo2 do
- build_gem "rack", "1.0.0"
+ context "when a pinned gem has an indirect dependency in a different source" do
+ before do
+ # In these tests, we need a working rack gem in repo2 and not repo3
+
+ build_repo gem_repo3 do
+ build_gem "depends_on_rack", "1.0.1" do |s|
+ s.add_dependency "rack"
end
end
- context "and not in any other sources" do
- before do
- install_gemfile <<-G
- source "#{file_uri_for(gem_repo2)}"
- source "#{file_uri_for(gem_repo3)}" do
- gem "depends_on_rack"
- end
- G
- end
+ build_repo gem_repo2 do
+ build_gem "rack", "1.0.0"
+ end
+ end
- it "installs from the other source without any warning" do
- expect(err).not_to include("Warning")
- expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0")
- end
+ context "and not in any other sources" do
+ before do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
+ source "#{file_uri_for(gem_repo3)}" do
+ gem "depends_on_rack"
+ end
+ G
end
- context "and in yet another source" do
- before do
- gemfile <<-G
- source "#{file_uri_for(gem_repo1)}"
- source "#{file_uri_for(gem_repo2)}"
- source "#{file_uri_for(gem_repo3)}" do
- gem "depends_on_rack"
- end
- G
- end
+ it "installs from the other source without any warning" do
+ expect(err).not_to include("Warning")
+ expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0")
+ end
+ end
- it "installs from the other source and warns about ambiguous gems", :bundler => "< 3" do
- bundle :install
- expect(err).to include("Warning: the gem 'rack' was found in multiple sources.")
- expect(err).to include("Installed from: #{file_uri_for(gem_repo2)}")
- expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0")
- end
+ context "and in yet another source" do
+ before do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ source "#{file_uri_for(gem_repo2)}"
+ source "#{file_uri_for(gem_repo3)}" do
+ gem "depends_on_rack"
+ end
+ G
+ end
- it "fails", :bundler => "3" do
- bundle :install, :raise_on_error => false
- expect(err).to include("Each source after the first must include a block")
- expect(exitstatus).to eq(4)
- end
+ it "installs from the other source and warns about ambiguous gems", :bundler => "< 3" do
+ bundle :install
+ expect(err).to include("Warning: the gem 'rack' was found in multiple sources.")
+ expect(err).to include("Installed from: #{file_uri_for(gem_repo2)}")
+ expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0")
end
- context "and only the dependency is pinned" do
- before do
- # need this to be broken to check for correct source ordering
- build_repo gem_repo2 do
- build_gem "rack", "1.0.0" do |s|
- s.write "lib/rack.rb", "RACK = 'FAIL'"
- end
+ it "fails", :bundler => "3" do
+ bundle :install, :raise_on_error => false
+ expect(err).to include("Each source after the first must include a block")
+ expect(exitstatus).to eq(4)
+ end
+ end
+
+ context "and only the dependency is pinned" do
+ before do
+ # need this to be broken to check for correct source ordering
+ build_repo gem_repo2 do
+ build_gem "rack", "1.0.0" do |s|
+ s.write "lib/rack.rb", "RACK = 'FAIL'"
end
+ end
- gemfile <<-G
- source "#{file_uri_for(gem_repo3)}" # contains depends_on_rack
- source "#{file_uri_for(gem_repo2)}" # contains broken rack
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo3)}" # contains depends_on_rack
+ source "#{file_uri_for(gem_repo2)}" # contains broken rack
- gem "depends_on_rack" # installed from gem_repo3
- gem "rack", :source => "#{file_uri_for(gem_repo1)}"
- G
- end
+ gem "depends_on_rack" # installed from gem_repo3
+ gem "rack", :source => "#{file_uri_for(gem_repo1)}"
+ G
+ end
- it "installs the dependency from the pinned source without warning", :bundler => "< 3" do
- bundle :install
+ it "installs the dependency from the pinned source without warning", :bundler => "< 3" do
+ bundle :install
- expect(err).not_to include("Warning: the gem 'rack' was found in multiple sources.")
- expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0")
+ expect(err).not_to include("Warning: the gem 'rack' was found in multiple sources.")
+ expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0")
- # In https://github.com/rubygems/bundler/issues/3585 this failed
- # when there is already a lock file, and the gems are missing, so try again
- system_gems []
- bundle :install
+ # In https://github.com/rubygems/bundler/issues/3585 this failed
+ # when there is already a lock file, and the gems are missing, so try again
+ system_gems []
+ bundle :install
- expect(err).not_to include("Warning: the gem 'rack' was found in multiple sources.")
- expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0")
- end
+ expect(err).not_to include("Warning: the gem 'rack' was found in multiple sources.")
+ expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0")
+ end
- it "fails", :bundler => "3" do
- bundle :install, :raise_on_error => false
- expect(err).to include("Each source after the first must include a block")
- expect(exitstatus).to eq(4)
- end
+ it "fails", :bundler => "3" do
+ bundle :install, :raise_on_error => false
+ expect(err).to include("Each source after the first must include a block")
+ expect(exitstatus).to eq(4)
end
end
end
@@ -511,9 +514,149 @@ RSpec.describe "bundle install with gems on multiple sources" do
L
end
- it "upgrades gems when running bundle update, without printing any warnings or errors" do
+ it "does not install newer versions or generate lockfile changes when running bundle install, and warns", :bundler => "< 3" do
+ initial_lockfile = lockfile
+
+ bundle :install
+
+ expect(err).to include("Your lockfile contains a single rubygems source section with multiple remotes, which is insecure.")
+
+ expect(the_bundle).to include_gems("activesupport 6.0.3.4")
+ expect(the_bundle).not_to include_gems("activesupport 6.1.2.1")
+ expect(the_bundle).to include_gems("tzinfo 1.2.9")
+ expect(the_bundle).not_to include_gems("tzinfo 2.0.4")
+ expect(the_bundle).to include_gems("concurrent-ruby 1.1.8")
+ expect(the_bundle).not_to include_gems("concurrent-ruby 1.1.9")
+
+ expect(lockfile).to eq(initial_lockfile)
+ end
+
+ it "fails when running bundle install", :bundler => "3" do
+ initial_lockfile = lockfile
+
+ bundle :install, :raise_on_error => false
+
+ expect(err).to include("Your lockfile contains a single rubygems source section with multiple remotes, which is insecure.")
+
+ expect(lockfile).to eq(initial_lockfile)
+ end
+
+ it "splits sections and upgrades gems when running bundle update, and doesn't warn" do
bundle "update --all"
expect(err).to be_empty
+
+ expect(the_bundle).not_to include_gems("activesupport 6.0.3.4")
+ expect(the_bundle).to include_gems("activesupport 6.1.2.1")
+ expect(the_bundle).not_to include_gems("tzinfo 1.2.9")
+ expect(the_bundle).to include_gems("tzinfo 2.0.4")
+ expect(the_bundle).not_to include_gems("concurrent-ruby 1.1.8")
+ expect(the_bundle).to include_gems("concurrent-ruby 1.1.9")
+
+ expect(lockfile).to eq <<~L
+ GEM
+ remote: #{file_uri_for(gem_repo2)}/
+ specs:
+ activesupport (6.1.2.1)
+ concurrent-ruby (~> 1.0, >= 1.0.2)
+ i18n (>= 1.6, < 2)
+ minitest (>= 5.1)
+ tzinfo (~> 2.0)
+ zeitwerk (~> 2.3)
+ concurrent-ruby (1.1.9)
+ connection_pool (2.2.3)
+ i18n (1.8.9)
+ concurrent-ruby (~> 1.0)
+ minitest (5.14.3)
+ rack (2.2.3)
+ redis (4.2.5)
+ sidekiq (6.1.3)
+ connection_pool (>= 2.2.2)
+ rack (~> 2.0)
+ redis (>= 4.2.0)
+ tzinfo (2.0.4)
+ concurrent-ruby (~> 1.0)
+ zeitwerk (2.4.2)
+
+ GEM
+ remote: #{file_uri_for(gem_repo3)}/
+ specs:
+ sidekiq-pro (5.2.1)
+ connection_pool (>= 2.2.3)
+ sidekiq (>= 6.1.0)
+
+ PLATFORMS
+ #{specific_local_platform}
+
+ DEPENDENCIES
+ activesupport
+ sidekiq-pro!
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
+ end
+
+ it "it keeps the currrent lockfile format and upgrades the requested gem when running bundle update with an argument, and warns", :bundler => "< 3" do
+ bundle "update concurrent-ruby"
+ expect(err).to include("Your lockfile contains a single rubygems source section with multiple remotes, which is insecure.")
+
+ expect(the_bundle).to include_gems("activesupport 6.0.3.4")
+ expect(the_bundle).not_to include_gems("activesupport 6.1.2.1")
+ expect(the_bundle).to include_gems("tzinfo 1.2.9")
+ expect(the_bundle).not_to include_gems("tzinfo 2.0.4")
+ expect(the_bundle).to include_gems("concurrent-ruby 1.1.9")
+ expect(the_bundle).not_to include_gems("concurrent-ruby 1.1.8")
+
+ expect(lockfile).to eq <<~L
+ GEM
+ remote: #{file_uri_for(gem_repo2)}/
+ remote: #{file_uri_for(gem_repo3)}/
+ specs:
+ activesupport (6.0.3.4)
+ concurrent-ruby (~> 1.0, >= 1.0.2)
+ i18n (>= 0.7, < 2)
+ minitest (~> 5.1)
+ tzinfo (~> 1.1)
+ zeitwerk (~> 2.2, >= 2.2.2)
+ concurrent-ruby (1.1.9)
+ connection_pool (2.2.3)
+ i18n (1.8.9)
+ concurrent-ruby (~> 1.0)
+ minitest (5.14.3)
+ rack (2.2.3)
+ redis (4.2.5)
+ sidekiq (6.1.3)
+ connection_pool (>= 2.2.2)
+ rack (~> 2.0)
+ redis (>= 4.2.0)
+ sidekiq-pro (5.2.1)
+ connection_pool (>= 2.2.3)
+ sidekiq (>= 6.1.0)
+ thread_safe (0.3.6)
+ tzinfo (1.2.9)
+ thread_safe (~> 0.1)
+ zeitwerk (2.4.2)
+
+ PLATFORMS
+ #{specific_local_platform}
+
+ DEPENDENCIES
+ activesupport
+ sidekiq-pro!
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
+ end
+
+ it "fails when running bundle update with an argument", :bundler => "3" do
+ initial_lockfile = lockfile
+
+ bundle "update concurrent-ruby", :raise_on_error => false
+
+ expect(err).to include("Your lockfile contains a single rubygems source section with multiple remotes, which is insecure.")
+
+ expect(lockfile).to eq(initial_lockfile)
end
end
end
@@ -551,7 +694,7 @@ RSpec.describe "bundle install with gems on multiple sources" do
end
end
- context "when a pinned gem has an indirect dependency with more than one level of indirection in the default source ", :bundler => "< 3" do
+ context "when a pinned gem has an indirect dependency with more than one level of indirection in the default source " do
before do
build_repo gem_repo3 do
build_gem "handsoap", "0.2.5.5" do |s|
@@ -578,12 +721,38 @@ RSpec.describe "bundle install with gems on multiple sources" do
G
end
- it "installs from the proper sources without any warnings or errors" do
+ it "installs from the default source without any warnings or errors and generates a proper lockfile" do
+ expected_lockfile = <<~L
+ GEM
+ remote: #{file_uri_for(gem_repo2)}/
+ specs:
+ nokogiri (1.11.1)
+ racca (~> 1.4)
+ racca (1.5.2)
+
+ GEM
+ remote: #{file_uri_for(gem_repo3)}/
+ specs:
+ handsoap (0.2.5.5)
+ nokogiri (>= 1.2.3)
+
+ PLATFORMS
+ #{specific_local_platform}
+
+ DEPENDENCIES
+ handsoap!
+ nokogiri
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
+
bundle "install --verbose"
expect(err).not_to include("Warning")
expect(the_bundle).to include_gems("handsoap 0.2.5.5", "nokogiri 1.11.1", "racca 1.5.2")
expect(the_bundle).to include_gems("handsoap 0.2.5.5", :source => "remote3")
expect(the_bundle).to include_gems("nokogiri 1.11.1", "racca 1.5.2", :source => "remote2")
+ expect(lockfile).to eq(expected_lockfile)
# Even if the gems are already installed
FileUtils.rm bundled_app_lock
@@ -592,6 +761,7 @@ RSpec.describe "bundle install with gems on multiple sources" do
expect(the_bundle).to include_gems("handsoap 0.2.5.5", "nokogiri 1.11.1", "racca 1.5.2")
expect(the_bundle).to include_gems("handsoap 0.2.5.5", :source => "remote3")
expect(the_bundle).to include_gems("nokogiri 1.11.1", "racca 1.5.2", :source => "remote2")
+ expect(lockfile).to eq(expected_lockfile)
end
end
@@ -619,6 +789,9 @@ RSpec.describe "bundle install with gems on multiple sources" do
lockfile <<-L
GEM
remote: #{file_uri_for(gem_repo1)}
+ specs:
+
+ GEM
remote: #{file_uri_for(gem_repo3)}
specs:
rack (0.9.1)
@@ -644,6 +817,84 @@ RSpec.describe "bundle install with gems on multiple sources" do
end
end
+ context "with a lockfile with aggregated rubygems sources" do
+ let(:aggregate_gem_section_lockfile) do
+ <<~L
+ GEM
+ remote: #{file_uri_for(gem_repo1)}/
+ remote: #{file_uri_for(gem_repo3)}/
+ specs:
+ rack (0.9.1)
+
+ PLATFORMS
+ #{specific_local_platform}
+
+ DEPENDENCIES
+ rack!
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
+ end
+
+ let(:split_gem_section_lockfile) do
+ <<~L
+ GEM
+ remote: #{file_uri_for(gem_repo1)}/
+ specs:
+
+ GEM
+ remote: #{file_uri_for(gem_repo3)}/
+ specs:
+ rack (0.9.1)
+
+ PLATFORMS
+ #{specific_local_platform}
+
+ DEPENDENCIES
+ rack!
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
+ end
+
+ before do
+ build_repo gem_repo3 do
+ build_gem "rack", "0.9.1"
+ end
+
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ source "#{file_uri_for(gem_repo3)}" do
+ gem 'rack'
+ end
+ G
+
+ lockfile aggregate_gem_section_lockfile
+ end
+
+ it "installs the existing lockfile but prints a warning", :bundler => "< 3" do
+ bundle "config set --local deployment true"
+
+ bundle "install"
+
+ expect(lockfile).to eq(aggregate_gem_section_lockfile)
+ expect(err).to include("Your lockfile contains a single rubygems source section with multiple remotes, which is insecure.")
+ expect(the_bundle).to include_gems("rack 0.9.1", :source => "remote3")
+ end
+
+ it "refuses to install the existing lockfile and prints an error", :bundler => "3" do
+ bundle "config set --local deployment true"
+
+ bundle "install", :raise_on_error =>false
+
+ expect(lockfile).to eq(aggregate_gem_section_lockfile)
+ expect(err).to include("Your lockfile contains a single rubygems source section with multiple remotes, which is insecure.")
+ expect(out).to be_empty
+ end
+ end
+
context "with a path gem in the same Gemfile" do
before do
build_lib "foo"
@@ -825,13 +1076,34 @@ RSpec.describe "bundle install with gems on multiple sources" do
G
end
- it "keeps the old version", :bundler => "< 3" do
- expect(the_bundle).to include_gems("rack 1.0.0")
+ it "installs the higher version in the new repo" do
+ expect(the_bundle).to include_gems("rack 1.2")
+ end
+ end
+
+ it "doesn't update version when a gem uses a source block but a higher version from another source is already installed locally" do
+ build_repo2 do
+ build_gem "example", "0.1.0"
end
- it "installs the higher version in the new repo", :bundler => "3" do
- expect(the_bundle).to include_gems("rack 1.2")
+ build_repo4 do
+ build_gem "example", "1.0.2"
end
+
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo4)}"
+
+ gem "example", :source => "#{file_uri_for(gem_repo2)}"
+ G
+
+ bundle "info example"
+ expect(out).to include("example (0.1.0)")
+
+ system_gems "example-1.0.2", :path => default_bundle_path, :gem_repo => gem_repo4
+
+ bundle "update example --verbose"
+ expect(out).not_to include("Using example 1.0.2")
+ expect(out).to include("Using example 0.1.0")
end
context "when a gem is available from multiple ambiguous sources", :bundler => "3" do
diff --git a/spec/bundler/install/gemfile/specific_platform_spec.rb b/spec/bundler/install/gemfile/specific_platform_spec.rb
index 9e30fc4fd4..a5b78443b9 100644
--- a/spec/bundler/install/gemfile/specific_platform_spec.rb
+++ b/spec/bundler/install/gemfile/specific_platform_spec.rb
@@ -104,6 +104,50 @@ RSpec.describe "bundle install with specific platforms" do
L
end
+ it "doesn't discard previously installed platform specific gem and fall back to ruby on subsequent bundles" do
+ build_repo2 do
+ build_gem("libv8", "8.4.255.0")
+ build_gem("libv8", "8.4.255.0") {|s| s.platform = "universal-darwin" }
+
+ build_gem("mini_racer", "1.0.0") do |s|
+ s.add_runtime_dependency "libv8"
+ end
+ end
+
+ system_gems "bundler-2.1.4"
+
+ # Consistent location to install and look for gems
+ bundle "config set --local path vendor/bundle", :env => { "BUNDLER_VERSION" => "2.1.4" }
+
+ gemfile <<-G
+ source "https://localgemserver.test"
+ gem "libv8"
+ G
+
+ # simulate lockfile created with old bundler, which only locks for ruby platform
+ lockfile <<-L
+ GEM
+ remote: https://localgemserver.test/
+ specs:
+ libv8 (8.4.255.0)
+
+ PLATFORMS
+ ruby
+
+ DEPENDENCIES
+ libv8
+
+ BUNDLED WITH
+ 2.1.4
+ L
+
+ bundle "install --verbose", :artifice => :compact_index, :env => { "BUNDLER_VERSION" => "2.1.4", "BUNDLER_SPEC_GEM_REPO" => gem_repo2.to_s }
+ expect(out).to include("Installing libv8 8.4.255.0 (universal-darwin)")
+
+ bundle "add mini_racer --verbose", :artifice => :compact_index, :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo2.to_s }
+ expect(out).to include("Using libv8 8.4.255.0 (universal-darwin)")
+ end
+
it "caches the universal-darwin gem when --all-platforms is passed and properly picks it up on further bundler invocations" do
setup_multiplatform_gem
gemfile(google_protobuf)
diff --git a/spec/bundler/install/gems/flex_spec.rb b/spec/bundler/install/gems/flex_spec.rb
index 7ab0ded26d..326ec51214 100644
--- a/spec/bundler/install/gems/flex_spec.rb
+++ b/spec/bundler/install/gems/flex_spec.rb
@@ -245,37 +245,7 @@ RSpec.describe "bundle flex_install" do
end
describe "when adding a new source" do
- it "updates the lockfile", :bundler => "< 3" do
- build_repo2
- install_gemfile <<-G
- source "#{file_uri_for(gem_repo1)}"
- gem "rack"
- G
- install_gemfile <<-G
- source "#{file_uri_for(gem_repo1)}"
- source "#{file_uri_for(gem_repo2)}"
- gem "rack"
- G
-
- lockfile_should_be <<-L
- GEM
- remote: #{file_uri_for(gem_repo1)}/
- remote: #{file_uri_for(gem_repo2)}/
- specs:
- rack (1.0.0)
-
- PLATFORMS
- #{lockfile_platforms}
-
- DEPENDENCIES
- rack
-
- BUNDLED WITH
- #{Bundler::VERSION}
- L
- end
-
- it "updates the lockfile", :bundler => "3" do
+ it "updates the lockfile" do
build_repo2
install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
diff --git a/spec/bundler/install/gems/resolving_spec.rb b/spec/bundler/install/gems/resolving_spec.rb
index 035ed9a7f3..94fac0052c 100644
--- a/spec/bundler/install/gems/resolving_spec.rb
+++ b/spec/bundler/install/gems/resolving_spec.rb
@@ -3,6 +3,32 @@
RSpec.describe "bundle install with install-time dependencies" do
before do
build_repo2 do
+ build_gem "with_implicit_rake_dep" do |s|
+ s.extensions << "Rakefile"
+ s.write "Rakefile", <<-RUBY
+ task :default do
+ path = File.expand_path("../lib", __FILE__)
+ FileUtils.mkdir_p(path)
+ File.open("\#{path}/implicit_rake_dep.rb", "w") do |f|
+ f.puts "IMPLICIT_RAKE_DEP = 'YES'"
+ end
+ end
+ RUBY
+ end
+
+ build_gem "another_implicit_rake_dep" do |s|
+ s.extensions << "Rakefile"
+ s.write "Rakefile", <<-RUBY
+ task :default do
+ path = File.expand_path("../lib", __FILE__)
+ FileUtils.mkdir_p(path)
+ File.open("\#{path}/another_implicit_rake_dep.rb", "w") do |f|
+ f.puts "ANOTHER_IMPLICIT_RAKE_DEP = 'YES'"
+ end
+ end
+ RUBY
+ end
+
# Test complicated gem dependencies for install
build_gem "net_a" do |s|
s.add_dependency "net_b"
@@ -55,6 +81,25 @@ RSpec.describe "bundle install with install-time dependencies" do
expect(out).to eq("YES\nYES")
end
+ it "installs gems with implicit rake dependencies without rake previously installed" do
+ with_path_as("") do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}"
+ gem "with_implicit_rake_dep"
+ gem "another_implicit_rake_dep"
+ gem "rake"
+ G
+ end
+
+ run <<-R
+ require 'implicit_rake_dep'
+ require 'another_implicit_rake_dep'
+ puts IMPLICIT_RAKE_DEP
+ puts ANOTHER_IMPLICIT_RAKE_DEP
+ R
+ expect(out).to eq("YES\nYES")
+ end
+
it "installs gems with a dependency with no type" do
skip "incorrect data check error" if Gem.win_platform?
diff --git a/spec/bundler/install/gems/sudo_spec.rb b/spec/bundler/install/gems/sudo_spec.rb
index ff73b4a1fa..3e5d38ea4c 100644
--- a/spec/bundler/install/gems/sudo_spec.rb
+++ b/spec/bundler/install/gems/sudo_spec.rb
@@ -49,8 +49,23 @@ RSpec.describe "when using sudo", :sudo => true do
end
it "installs rake and a gem dependent on rake in the same session" do
+ build_repo2 do
+ build_gem "another_implicit_rake_dep" do |s|
+ s.extensions << "Rakefile"
+ s.write "Rakefile", <<-RUBY
+ task :default do
+ path = File.expand_path("../lib", __FILE__)
+ FileUtils.mkdir_p(path)
+ File.open("\#{path}/another_implicit_rake_dep.rb", "w") do |f|
+ f.puts "ANOTHER_IMPLICIT_RAKE_DEP = 'YES'"
+ end
+ end
+ RUBY
+ end
+ end
+
gemfile <<-G
- source "#{file_uri_for(gem_repo1)}"
+ source "#{file_uri_for(gem_repo2)}"
gem "rake"
gem "another_implicit_rake_dep"
G
diff --git a/spec/bundler/install/git_spec.rb b/spec/bundler/install/git_spec.rb
index 71771d3dc2..4a3827eafd 100644
--- a/spec/bundler/install/git_spec.rb
+++ b/spec/bundler/install/git_spec.rb
@@ -13,7 +13,7 @@ RSpec.describe "bundle install" do
expect(the_bundle).to include_gems "foo 1.0", :source => "git@#{lib_path("foo")}"
end
- it "displays the correct default branch" do
+ it "displays the correct default branch", :git => ">= 2.28.0" do
build_git "foo", "1.0", :path => lib_path("foo"), :default_branch => "main"
install_gemfile <<-G, :verbose => true
diff --git a/spec/bundler/lock/lockfile_spec.rb b/spec/bundler/lock/lockfile_spec.rb
index 976db33b0e..d68410824e 100644
--- a/spec/bundler/lock/lockfile_spec.rb
+++ b/spec/bundler/lock/lockfile_spec.rb
@@ -318,40 +318,7 @@ RSpec.describe "the lockfile format" do
G
end
- it "generates a lockfile without credentials for a configured source", :bundler => "< 3" do
- bundle "config set http://localgemserver.test/ user:pass"
-
- install_gemfile(<<-G, :artifice => "endpoint_strict_basic_authentication", :quiet => true)
- source "http://localgemserver.test/" do
-
- end
-
- source "http://user:pass@othergemserver.test/" do
- gem "rack-obama", ">= 1.0"
- end
- G
-
- lockfile_should_be <<-G
- GEM
- remote: http://localgemserver.test/
- remote: http://user:pass@othergemserver.test/
- specs:
- rack (1.0.0)
- rack-obama (1.0)
- rack
-
- PLATFORMS
- #{lockfile_platforms}
-
- DEPENDENCIES
- rack-obama (>= 1.0)!
-
- BUNDLED WITH
- #{Bundler::VERSION}
- G
- end
-
- it "generates a lockfile without credentials for a configured source", :bundler => "3" do
+ it "generates a lockfile without credentials for a configured source" do
bundle "config set http://localgemserver.test/ user:pass"
install_gemfile(<<-G, :artifice => "endpoint_strict_basic_authentication", :quiet => true)
@@ -674,6 +641,30 @@ RSpec.describe "the lockfile format" do
G
end
+ it "removes redundant sources" do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}/"
+
+ gem "rack", :source => "#{file_uri_for(gem_repo2)}/"
+ G
+
+ lockfile_should_be <<-G
+ GEM
+ remote: #{file_uri_for(gem_repo2)}/
+ specs:
+ rack (1.0.0)
+
+ PLATFORMS
+ #{lockfile_platforms}
+
+ DEPENDENCIES
+ rack!
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ G
+ end
+
it "lists gems alphabetically" do
install_gemfile <<-G
source "#{file_uri_for(gem_repo2)}/"
diff --git a/spec/bundler/other/major_deprecation_spec.rb b/spec/bundler/other/major_deprecation_spec.rb
index 0758d29746..92b05d8b74 100644
--- a/spec/bundler/other/major_deprecation_spec.rb
+++ b/spec/bundler/other/major_deprecation_spec.rb
@@ -165,6 +165,28 @@ RSpec.describe "major deprecations" do
pending "fails with a helpful error", :bundler => "3"
end
+ context "bundle cache --path" do
+ before do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack"
+ G
+
+ bundle "cache --path foo", :raise_on_error => false
+ end
+
+ it "should print a deprecation warning", :bundler => "< 3" do
+ expect(deprecations).to include(
+ "The `--path` flag is deprecated because its semantics are unclear. " \
+ "Use `bundle config cache_path` to configure the path of your cache of gems, " \
+ "and `bundle config path` to configure the path where your gems are installed, " \
+ "and stop using this flag"
+ )
+ end
+
+ pending "fails with a helpful error", :bundler => "3"
+ end
+
describe "bundle config" do
describe "old list interface" do
before do
@@ -383,15 +405,53 @@ RSpec.describe "major deprecations" do
"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 set --local " \
- "disable_multisource true`."
+ "a block to indicate which gems should come from the secondary source."
)
end
pending "fails with a helpful error", :bundler => "3"
end
+ context "bundle install with a lockfile with a single rubygems section with multiple remotes" do
+ before do
+ build_repo gem_repo3 do
+ build_gem "rack", "0.9.1"
+ end
+
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ source "#{file_uri_for(gem_repo3)}" do
+ gem 'rack'
+ end
+ G
+
+ lockfile <<~L
+ GEM
+ remote: #{file_uri_for(gem_repo1)}/
+ remote: #{file_uri_for(gem_repo3)}/
+ specs:
+ rack (0.9.1)
+
+ PLATFORMS
+ ruby
+
+ DEPENDENCIES
+ rack!
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
+ end
+
+ it "shows a deprecation", :bundler => "< 3" do
+ bundle "install"
+
+ expect(deprecations).to include("Your lockfile contains a single rubygems source section with multiple remotes, which is insecure. You should run `bundle update` or generate your lockfile from scratch.")
+ end
+
+ pending "fails with a helpful error", :bundler => "3"
+ end
+
context "when Bundler.setup is run in a ruby script" do
before do
create_file "gems.rb"
@@ -609,4 +669,50 @@ The :gist git source is deprecated, and will be removed in the future. Add this
pending "fails with a helpful message", :bundler => "3"
end
+
+ describe "deprecating rubocop", :readline do
+ context "bundle gem --rubocop" do
+ before do
+ bundle "gem my_new_gem --rubocop", :raise_on_error => false
+ end
+
+ it "prints a deprecation warning", :bundler => "< 3" do
+ expect(deprecations).to include \
+ "--rubocop is deprecated, use --linter=rubocop"
+ end
+ end
+
+ context "bundle gem --no-rubocop" do
+ before do
+ bundle "gem my_new_gem --no-rubocop", :raise_on_error => false
+ end
+
+ it "prints a deprecation warning", :bundler => "< 3" do
+ expect(deprecations).to include \
+ "--no-rubocop is deprecated, use --linter"
+ end
+ end
+
+ context "bundle gem with gem.rubocop set to true" do
+ before do
+ bundle "gem my_new_gem", :env => { "BUNDLE_GEM__RUBOCOP" => "true" }, :raise_on_error => false
+ end
+
+ it "prints a deprecation warning", :bundler => "< 3" do
+ expect(deprecations).to include \
+ "config gem.rubocop is deprecated; we've updated your config to use gem.linter instead"
+ end
+ end
+
+ context "bundle gem with gem.rubocop set to false" do
+ before do
+ bundle "gem my_new_gem", :env => { "BUNDLE_GEM__RUBOCOP" => "false" }, :raise_on_error => false
+ end
+
+ it "prints a deprecation warning", :bundler => "< 3" do
+ expect(deprecations).to include \
+ "config gem.rubocop is deprecated; we've updated your config to use gem.linter instead"
+ end
+ end
+ end
end
diff --git a/spec/bundler/quality_spec.rb b/spec/bundler/quality_spec.rb
index 2b1e28fa30..dcdbf61f52 100644
--- a/spec/bundler/quality_spec.rb
+++ b/spec/bundler/quality_spec.rb
@@ -169,7 +169,6 @@ RSpec.describe "The library itself" do
it "documents all used settings" do
exemptions = %w[
- deployment_means_frozen
forget_cli_options
gem.coc
gem.mit
diff --git a/spec/bundler/realworld/fixtures/warbler/Gemfile.lock b/spec/bundler/realworld/fixtures/warbler/Gemfile.lock
index 6945be3ed2..05bcb877db 100644
--- a/spec/bundler/realworld/fixtures/warbler/Gemfile.lock
+++ b/spec/bundler/realworld/fixtures/warbler/Gemfile.lock
@@ -6,7 +6,7 @@ PATH
GEM
remote: https://rubygems.org/
specs:
- jruby-jars (9.2.14.0)
+ jruby-jars (9.2.16.0)
jruby-rack (1.1.21)
rake (13.0.1)
rubyzip (1.3.0)
@@ -19,6 +19,7 @@ GEM
PLATFORMS
java
ruby
+ universal-java-11
DEPENDENCIES
demo!
@@ -26,4 +27,4 @@ DEPENDENCIES
warbler (~> 2.0)
BUNDLED WITH
- 2.2.0.rc.2
+ 2.3.0.dev
diff --git a/spec/bundler/runtime/inline_spec.rb b/spec/bundler/runtime/inline_spec.rb
index bd136ddcd7..bad1df93a9 100644
--- a/spec/bundler/runtime/inline_spec.rb
+++ b/spec/bundler/runtime/inline_spec.rb
@@ -246,6 +246,19 @@ RSpec.describe "bundler/inline#gemfile" do
expect(last_command.stderr).to be_empty
end
+ it "installs inline gems when deployment is set" do
+ script <<-RUBY, :env => { "BUNDLE_DEPLOYMENT" => "true" }
+ gemfile do
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack"
+ end
+
+ puts RACK
+ RUBY
+
+ expect(last_command.stderr).to be_empty
+ end
+
it "installs inline gems when BUNDLE_GEMFILE is set to an empty string" do
ENV["BUNDLE_GEMFILE"] = ""
diff --git a/spec/bundler/runtime/platform_spec.rb b/spec/bundler/runtime/platform_spec.rb
index 154d967e12..bec42e0f70 100644
--- a/spec/bundler/runtime/platform_spec.rb
+++ b/spec/bundler/runtime/platform_spec.rb
@@ -108,6 +108,44 @@ RSpec.describe "Bundler.setup with multi platform stuff" do
expect(lockfile).to eq(good_lockfile)
end
+ it "will not try to install platform specific gems when they don't match the current ruby if locked only to ruby" do
+ build_repo4 do
+ build_gem "nokogiri", "1.11.1"
+
+ build_gem "nokogiri", "1.11.1" do |s|
+ s.platform = Bundler.local_platform
+ s.required_ruby_version = "< #{Gem.ruby_version}"
+ end
+ end
+
+ gemfile <<-G
+ source "https://gems.repo4"
+ gem "nokogiri"
+ G
+
+ lockfile <<~L
+ GEM
+ remote: https://gems.repo4/
+ specs:
+ nokogiri (1.11.1)
+
+ PLATFORMS
+ ruby
+
+ DEPENDENCIES
+ nokogiri
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
+
+ bundle "install", :artifice => "compact_index", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s }
+
+ expect(out).to include("Fetching nokogiri 1.11.1")
+ expect(the_bundle).to include_gems "nokogiri 1.11.1"
+ expect(the_bundle).not_to include_gems "nokogiri 1.11.1 #{Bundler.local_platform}"
+ end
+
it "will use the java platform if both generic java and generic ruby platforms are locked", :jruby do
gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
diff --git a/spec/bundler/runtime/setup_spec.rb b/spec/bundler/runtime/setup_spec.rb
index a0036df39e..4d5e1c616e 100644
--- a/spec/bundler/runtime/setup_spec.rb
+++ b/spec/bundler/runtime/setup_spec.rb
@@ -1244,16 +1244,16 @@ end
describe "default gem activation" do
let(:exemptions) do
- exempts = if Gem::Version.new(Gem::VERSION) >= Gem::Version.new("2.7")
+ exempts = if Gem.rubygems_version >= Gem::Version.new("2.7")
%w[did_you_mean]
else
%w[io-console openssl]
end << "bundler"
- exempts << "fiddle" if Gem.win_platform? && Gem::Version.new(Gem::VERSION) >= Gem::Version.new("2.7")
- exempts << "uri" if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new("2.7")
- exempts << "pathname" if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new("3.0")
- exempts << "set" unless Gem::Version.new(Gem::VERSION) >= Gem::Version.new("3.2.6")
- exempts << "tsort" if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new("3.0")
+ exempts << "fiddle" if Gem.win_platform? && Gem.rubygems_version >= Gem::Version.new("2.7")
+ exempts << "uri" if Gem.ruby_version >= Gem::Version.new("2.7")
+ exempts << "pathname" if Gem.ruby_version >= Gem::Version.new("3.0")
+ exempts << "set" unless Gem.rubygems_version >= Gem::Version.new("3.2.6")
+ exempts << "tsort" if Gem.ruby_version >= Gem::Version.new("3.0")
exempts
end
diff --git a/spec/bundler/spec_helper.rb b/spec/bundler/spec_helper.rb
index a72a1f5255..db1055c295 100644
--- a/spec/bundler/spec_helper.rb
+++ b/spec/bundler/spec_helper.rb
@@ -66,16 +66,9 @@ RSpec.configure do |config|
mocks.allow_message_expectations_on_nil = false
end
- config.around :each do |example|
- if ENV["RUBY"]
- orig_ruby = Gem.ruby
- Gem.ruby = ENV["RUBY"]
- end
- example.run
- Gem.ruby = orig_ruby if ENV["RUBY"]
- end
-
config.before :suite do
+ Gem.ruby = ENV["RUBY"] if ENV["RUBY"]
+
require_relative "support/rubygems_ext"
Spec::Rubygems.test_setup
ENV["BUNDLE_SPEC_RUN"] = "true"
@@ -90,6 +83,8 @@ RSpec.configure do |config|
end
config.before :all do
+ check_test_gems!
+
build_repo1
reset_paths!
diff --git a/spec/bundler/support/builders.rb b/spec/bundler/support/builders.rb
index c76c3f505e..d593ced27e 100644
--- a/spec/bundler/support/builders.rb
+++ b/spec/bundler/support/builders.rb
@@ -30,7 +30,11 @@ module Spec
end
def build_repo1
+ rake_path = Dir["#{Path.base_system_gems}/**/rake*.gem"].first
+
build_repo gem_repo1 do
+ FileUtils.cp rake_path, "#{gem_repo1}/gems/"
+
build_gem "rack", %w[0.9.1 1.0.0] do |s|
s.executables = "rackup"
s.post_install_message = "Rack's post install message"
@@ -150,32 +154,6 @@ module Spec
build_gem "duradura", "7.0"
- build_gem "with_implicit_rake_dep" do |s|
- s.extensions << "Rakefile"
- s.write "Rakefile", <<-RUBY
- task :default do
- path = File.expand_path("../lib", __FILE__)
- FileUtils.mkdir_p(path)
- File.open("\#{path}/implicit_rake_dep.rb", "w") do |f|
- f.puts "IMPLICIT_RAKE_DEP = 'YES'"
- end
- end
- RUBY
- end
-
- build_gem "another_implicit_rake_dep" do |s|
- s.extensions << "Rakefile"
- s.write "Rakefile", <<-RUBY
- task :default do
- path = File.expand_path("../lib", __FILE__)
- FileUtils.mkdir_p(path)
- File.open("\#{path}/another_implicit_rake_dep.rb", "w") do |f|
- f.puts "ANOTHER_IMPLICIT_RAKE_DEP = 'YES'"
- end
- end
- RUBY
- end
-
build_gem "very_simple_binary", &:add_c_extension
build_gem "simple_binary", &:add_c_extension
@@ -255,6 +233,13 @@ module Spec
def build_repo(path, &blk)
return if File.directory?(path)
+
+ FileUtils.mkdir_p("#{path}/gems")
+
+ update_repo(path, &blk)
+ end
+
+ def check_test_gems!
rake_path = Dir["#{Path.base_system_gems}/**/rake*.gem"].first
if rake_path.nil?
@@ -263,14 +248,9 @@ module Spec
rake_path = Dir["#{Path.base_system_gems}/**/rake*.gem"].first
end
- if rake_path
- FileUtils.mkdir_p("#{path}/gems")
- FileUtils.cp rake_path, "#{path}/gems/"
- else
+ if rake_path.nil?
abort "Your test gems are missing! Run `rm -rf #{tmp}` and try again."
end
-
- update_repo(path, &blk)
end
def update_repo(path)
diff --git a/spec/bundler/support/bundle.rb b/spec/bundler/support/bundle.rb
new file mode 100644
index 0000000000..bb21526d35
--- /dev/null
+++ b/spec/bundler/support/bundle.rb
@@ -0,0 +1,8 @@
+# frozen_string_literal: true
+
+require "rubygems"
+require_relative "path"
+bundler_gemspec = Spec::Path.loaded_gemspec
+bundler_gemspec.instance_variable_set(:@full_gem_path, Spec::Path.source_root)
+bundler_gemspec.activate if bundler_gemspec.respond_to?(:activate)
+load File.expand_path("bundle", Spec::Path.bindir)
diff --git a/spec/bundler/support/hax.rb b/spec/bundler/support/hax.rb
index fc8e0ad55d..8fd35890ae 100644
--- a/spec/bundler/support/hax.rb
+++ b/spec/bundler/support/hax.rb
@@ -29,7 +29,7 @@ module Gem
end
# We only need this hack for rubygems versions without the BundlerVersionFinder
- if Gem::Version.new(Gem::VERSION) < Gem::Version.new("2.7.0")
+ if Gem.rubygems_version < Gem::Version.new("2.7.0")
@path_to_default_spec_map.delete_if do |_path, spec|
spec.name == "bundler"
end
diff --git a/spec/bundler/support/helpers.rb b/spec/bundler/support/helpers.rb
index a7cc1ce810..d896b5276e 100644
--- a/spec/bundler/support/helpers.rb
+++ b/spec/bundler/support/helpers.rb
@@ -10,7 +10,7 @@ module Spec
def reset!
Dir.glob("#{tmp}/{gems/*,*}", File::FNM_DOTMATCH).each do |dir|
- next if %w[base base_system remote1 gems rubygems . ..].include?(File.basename(dir))
+ next if %w[base base_system remote1 rubocop standard gems rubygems . ..].include?(File.basename(dir))
FileUtils.rm_rf(dir)
end
FileUtils.mkdir_p(home)
@@ -130,7 +130,7 @@ module Spec
def ruby(ruby, options = {})
ruby_cmd = build_ruby_cmd
- escaped_ruby = RUBY_PLATFORM == "java" ? ruby.shellescape.dump : ruby.shellescape
+ escaped_ruby = ruby.shellescape
sys_exec(%(#{ruby_cmd} -w -e #{escaped_ruby}), options)
end
diff --git a/spec/bundler/support/matchers.rb b/spec/bundler/support/matchers.rb
index 5d129ed849..1613662981 100644
--- a/spec/bundler/support/matchers.rb
+++ b/spec/bundler/support/matchers.rb
@@ -114,30 +114,49 @@ module Spec
match do
opts = names.last.is_a?(Hash) ? names.pop : {}
source = opts.delete(:source)
- groups = Array(opts[:groups])
+ groups = Array(opts.delete(:groups)).map(&:inspect).join(", ")
opts[:raise_on_error] = false
- groups << opts
- @errors = names.map do |name|
- name, version, platform = name.split(/\s+/)
+ @errors = names.map do |full_name|
+ name, version, platform = full_name.split(/\s+/)
require_path = name == "bundler" ? "#{lib_dir}/bundler" : name.tr("-", "/")
version_const = name == "bundler" ? "Bundler::VERSION" : Spec::Builders.constantize(name)
- code = []
- code << "require '#{require_path}.rb'"
- code << "puts #{version_const}"
- run code.join("; "), *groups
- actual_version, actual_platform = out.strip.split(/\s+/, 2)
- unless Gem::Version.new(actual_version) == Gem::Version.new(version)
+ source_const = "#{Spec::Builders.constantize(name)}_SOURCE"
+ ruby <<~R, opts
+ require '#{lib_dir}/bundler'
+ Bundler.setup(#{groups})
+
+ require '#{require_path}.rb'
+ actual_version, actual_platform = #{version_const}.split(/\s+/, 2)
+ unless Gem::Version.new(actual_version) == Gem::Version.new('#{version}')
+ puts actual_version
+ exit 64
+ end
+ unless actual_platform.to_s == '#{platform}'
+ puts actual_platform
+ exit 65
+ end
+ require '#{require_path}/source'
+ exit 0 if #{source.nil?}
+ actual_source = #{source_const}
+ unless actual_source == '#{source}'
+ puts actual_source
+ exit 66
+ end
+ R
+ next if exitstatus == 0
+ if exitstatus == 64
+ actual_version = out.split("\n").last
next "#{name} was expected to be at version #{version} but was #{actual_version}"
end
- unless actual_platform == platform
+ if exitstatus == 65
+ actual_platform = out.split("\n").last
next "#{name} was expected to be of platform #{platform} but was #{actual_platform}"
end
- next unless source
- source_const = "#{Spec::Builders.constantize(name)}_SOURCE"
- run "require '#{require_path}/source'; puts #{source_const}", *groups
- unless out.strip == source
- next "Expected #{name} (#{version}) to be installed from `#{source}`, was actually from `#{out}`"
+ if exitstatus == 66
+ actual_source = out.split("\n").last
+ next "Expected #{name} (#{version}) to be installed from `#{source}`, was actually from `#{actual_source}`"
end
+ next "Command to check forgem inclusion of gem #{full_name} failed"
end.compact
@errors.empty?
diff --git a/spec/bundler/support/path.rb b/spec/bundler/support/path.rb
index 62f136aa0b..a9e9704cf9 100644
--- a/spec/bundler/support/path.rb
+++ b/spec/bundler/support/path.rb
@@ -6,7 +6,7 @@ require "rbconfig"
module Spec
module Path
def source_root
- @source_root ||= Pathname.new(ruby_core? ? "../../../.." : "../../..").expand_path(__FILE__)
+ @source_root ||= Pathname.new(ruby_core? ? "../../.." : "../..").expand_path(__dir__)
end
def root
@@ -30,7 +30,15 @@ module Spec
end
def test_gemfile
- @test_gemfile ||= source_root.join(ruby_core? ? "tool/bundler/test_gems.rb" : "test_gems.rb")
+ @test_gemfile ||= source_root.join("tool/bundler/test_gems.rb")
+ end
+
+ def rubocop_gemfile
+ @rubocop_gemfile ||= source_root.join(rubocop_gemfile_basename)
+ end
+
+ def standard_gemfile
+ @standard_gemfile ||= source_root.join(standard_gemfile_basename)
end
def dev_gemfile
@@ -119,7 +127,7 @@ module Spec
end
def vendored_gems(path = nil)
- bundled_app(*["vendor/bundle", Gem.ruby_engine, RbConfig::CONFIG["ruby_version"], path].compact)
+ scoped_gem_path(bundled_app("vendor/bundle")).join(*[path].compact)
end
def cached_gem(path)
@@ -138,6 +146,14 @@ module Spec
tmp.join("gems/base")
end
+ def rubocop_gems
+ tmp.join("gems/rubocop")
+ end
+
+ def standard_gems
+ tmp.join("gems/standard")
+ end
+
def file_uri_for(path)
protocol = "file://"
root = Gem.win_platform? ? "/" : ""
@@ -178,7 +194,11 @@ module Spec
end
def local_gem_path(*path, base: bundled_app)
- base.join(*[".bundle", Gem.ruby_engine, RbConfig::CONFIG["ruby_version"], *path].compact)
+ scoped_gem_path(base.join(".bundle")).join(*path)
+ end
+
+ def scoped_gem_path(base)
+ base.join(Gem.ruby_engine, RbConfig::CONFIG["ruby_version"])
end
def lib_path(*args)
@@ -193,10 +213,6 @@ module Spec
root.join("lib")
end
- def xdg_config_home
- home(".config")
- end
-
def global_plugin_gem(*args)
home ".bundle", "plugin", "gems", *args
end
@@ -255,6 +271,14 @@ module Spec
!git_root.join(".git").directory?
end
+ def rubocop_gemfile_basename
+ source_root.join("tool/bundler/#{RUBY_VERSION.start_with?("2.3") ? "rubocop23_gems.rb" : "rubocop_gems.rb"}")
+ end
+
+ def standard_gemfile_basename
+ source_root.join("tool/bundler/#{RUBY_VERSION.start_with?("2.3") ? "standard23_gems.rb" : "standard_gems.rb"}")
+ end
+
extend self
end
end
diff --git a/spec/bundler/support/rubygems_ext.rb b/spec/bundler/support/rubygems_ext.rb
index 59429884d6..ea774429c9 100644
--- a/spec/bundler/support/rubygems_ext.rb
+++ b/spec/bundler/support/rubygems_ext.rb
@@ -9,7 +9,7 @@ module Spec
extend self
def dev_setup
- install_gems(dev_gemfile, dev_lockfile)
+ install_gems(dev_gemfile)
end
def gem_load(gem_name, bin_container)
@@ -33,25 +33,25 @@ module Spec
ENV["HOME"] = Path.home.to_s
ENV["TMPDIR"] = Path.tmpdir.to_s
- ENV["XDG_CONFIG_HOME"] = Path.xdg_config_home.to_s
require "rubygems/user_interaction"
Gem::DefaultUserInteraction.ui = Gem::SilentUI.new
end
def install_parallel_test_deps
+ Gem.clear_paths
+
require "parallel"
+ require "fileutils"
- prev_env_test_number = ENV["TEST_ENV_NUMBER"]
+ install_test_deps
- begin
- Parallel.processor_count.times do |n|
- ENV["TEST_ENV_NUMBER"] = (n + 1).to_s
+ (2..Parallel.processor_count).each do |n|
+ source = Path.source_root.join("tmp", "1")
+ destination = Path.source_root.join("tmp", n.to_s)
- install_test_deps
- end
- ensure
- ENV["TEST_ENV_NUMBER"] = prev_env_test_number
+ FileUtils.rm_rf destination
+ FileUtils.cp_r source, destination
end
end
@@ -67,9 +67,9 @@ module Spec
def install_test_deps
setup_test_paths
- workaround_loaded_specs_issue
-
- install_gems(test_gemfile, test_lockfile)
+ install_gems(test_gemfile)
+ install_gems(rubocop_gemfile, Path.rubocop_gems.to_s)
+ install_gems(standard_gemfile, Path.standard_gems.to_s)
end
def check_source_control_changes(success_message:, error_message:)
@@ -94,18 +94,6 @@ module Spec
private
- # Some rubygems versions include loaded specs when loading gemspec stubs
- # from the file system. In this situation, that makes bundler incorrectly
- # assume that `rake` is already installed at `tmp/` because it's installed
- # globally, and makes it skip installing it to the proper location for our
- # tests. To workaround, we remove `rake` from the loaded specs when running
- # under those versions, so that `bundler` does the right thing.
- def workaround_loaded_specs_issue
- current_rubygems_version = Gem::Version.new(Gem::VERSION)
-
- Gem.loaded_specs.delete("rake") if current_rubygems_version >= Gem::Version.new("3.0.0.beta2") && current_rubygems_version < Gem::Version.new("3.2.0")
- end
-
def gem_load_and_activate(gem_name, bin_container)
gem_activate(gem_name)
load Gem.bin_path(gem_name, bin_container)
@@ -119,14 +107,27 @@ module Spec
gem gem_name, gem_requirement
end
- def install_gems(gemfile, lockfile)
+ def install_gems(gemfile, path = nil)
old_gemfile = ENV["BUNDLE_GEMFILE"]
ENV["BUNDLE_GEMFILE"] = gemfile.to_s
- require "bundler"
- definition = Bundler::Definition.build(gemfile, lockfile, nil)
- definition.validate_runtime!
- Bundler::Installer.install(Path.source_root, definition, :path => ENV["GEM_HOME"])
+
+ if path
+ old_path = ENV["BUNDLE_PATH"]
+ ENV["BUNDLE_PATH"] = path
+ else
+ old_path__system = ENV["BUNDLE_PATH__SYSTEM"]
+ ENV["BUNDLE_PATH__SYSTEM"] = "true"
+ end
+
+ output = `#{Gem.ruby} #{File.expand_path("support/bundle.rb", Path.spec_dir)} install`
+ raise "Error when installing gems in #{gemfile}: #{output}" unless $?.success?
ensure
+ if path
+ ENV["BUNDLE_PATH"] = old_path
+ else
+ ENV["BUNDLE_PATH__SYSTEM"] = old_path__system
+ end
+
ENV["BUNDLE_GEMFILE"] = old_gemfile
end
@@ -134,8 +135,12 @@ module Spec
Path.test_gemfile
end
- def test_lockfile
- lockfile_for(test_gemfile)
+ def rubocop_gemfile
+ Path.rubocop_gemfile
+ end
+
+ def standard_gemfile
+ Path.standard_gemfile
end
def dev_gemfile