diff --git a/lib/bundler/bundler.gemspec b/lib/bundler/bundler.gemspec index 48410e76f4..f6cb02cea2 100644 --- a/lib/bundler/bundler.gemspec +++ b/lib/bundler/bundler.gemspec @@ -34,11 +34,14 @@ Gem::Specification.new do |s| s.required_ruby_version = ">= 2.3.0" s.required_rubygems_version = ">= 2.5.2" - s.files = (Dir.glob("lib/bundler/**/*", File::FNM_DOTMATCH) + Dir.glob("man/bundle*") + Dir.glob("man/gemfile*") + Dir.glob("libexec/bundle*")).reject {|f| File.directory?(f) } + s.files = Dir.glob("{lib,exe}/**/*", File::FNM_DOTMATCH).reject {|f| File.directory?(f) } - s.files += ["lib/bundler.rb"] + # Include the CHANGELOG.md, LICENSE.md, README.md manually + s.files += %w[CHANGELOG.md LICENSE.md README.md] + # include the gemspec itself because warbler breaks w/o it + s.files += %w[bundler.gemspec] - s.bindir = "libexec" + s.bindir = "exe" s.executables = %w[bundle bundler] s.require_paths = ["lib"] end diff --git a/lib/bundler/cli.rb b/lib/bundler/cli.rb index 421f42cb52..981c885f6f 100644 --- a/lib/bundler/cli.rb +++ b/lib/bundler/cli.rb @@ -591,6 +591,7 @@ 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 :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 `." 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 2c63da9eb4..eb1119859c 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, 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/definition.rb b/lib/bundler/definition.rb index 686721cd32..562f50c3fb 100644 --- a/lib/bundler/definition.rb +++ b/lib/bundler/definition.rb @@ -187,10 +187,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 @@ -959,7 +959,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/feature_flag.rb b/lib/bundler/feature_flag.rb index a1b443b042..3f9a502179 100644 --- a/lib/bundler/feature_flag.rb +++ b/lib/bundler/feature_flag.rb @@ -35,7 +35,6 @@ module Bundler 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/lazy_specification.rb b/lib/bundler/lazy_specification.rb index 7cd7e4254d..6760edba42 100644 --- a/lib/bundler/lazy_specification.rb +++ b/lib/bundler/lazy_specification.rb @@ -74,9 +74,9 @@ module Bundler MatchPlatform.platforms_match?(spec.platform, platform_object) end installable_candidates = same_platform_candidates.select do |spec| - !spec.is_a?(RemoteSpecification) && - spec.required_ruby_version.satisfied_by?(Gem.ruby_version) && - spec.required_rubygems_version.satisfied_by?(Gem.rubygems_version) + !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)) 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 00bb708240..667249c665 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 dc99c69412..ba4bd5ff23 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..e71ccb4832 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 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 3942806f75..480d38f39c 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/settings.rb b/lib/bundler/settings.rb index 749e4eb60e..2c0edd0c68 100644 --- a/lib/bundler/settings.rb +++ b/lib/bundler/settings.rb @@ -33,7 +33,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/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/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/lib/bundler/version.rb b/lib/bundler/version.rb index 5b6473c465..1f5014bc1f 100644 --- a/lib/bundler/version.rb +++ b/lib/bundler/version.rb @@ -1,7 +1,7 @@ # frozen_string_literal: false module Bundler - VERSION = "2.2.15".freeze + VERSION = "2.2.16".freeze def self.bundler_major_version @bundler_major_version ||= VERSION.split(".").first.to_i diff --git a/lib/rubygems.rb b/lib/rubygems.rb index 61a2d465a2..57574474ea 100644 --- a/lib/rubygems.rb +++ b/lib/rubygems.rb @@ -8,7 +8,7 @@ require 'rbconfig' module Gem - VERSION = "3.2.15".freeze + VERSION = "3.2.16".freeze end # Must be first since it unloads the prelude from 1.9.2 diff --git a/lib/rubygems/installer.rb b/lib/rubygems/installer.rb index 3ec6d743a2..7af51056b7 100644 --- a/lib/rubygems/installer.rb +++ b/lib/rubygems/installer.rb @@ -484,8 +484,11 @@ class Gem::Installer bin_path = File.join gem_dir, spec.bindir, filename unless File.exist? bin_path - # TODO change this to a more useful warning - warn "`#{bin_path}` does not exist, maybe `gem pristine #{spec.name}` will fix it?" + if File.symlink? bin_path + alert_warning "`#{bin_path}` is dangling symlink pointing to `#{File.readlink bin_path}`" + else + alert_warning "`#{bin_path}` does not exist, maybe `gem pristine #{spec.name}` will fix it?" + end next end diff --git a/lib/rubygems/package.rb b/lib/rubygems/package.rb index 0587cd212b..a4ae3e9ea5 100644 --- a/lib/rubygems/package.rb +++ b/lib/rubygems/package.rb @@ -252,14 +252,7 @@ class Gem::Package stat = File.lstat file if stat.symlink? - target_path = File.readlink(file) - - unless target_path.start_with? '.' - relative_dir = File.dirname(file).sub("#{Dir.pwd}/", '') - target_path = File.join(relative_dir, target_path) - end - - tar.add_symlink file, target_path, stat.mode + tar.add_symlink file, File.readlink(file), stat.mode end next unless stat.file? 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..43c9329fdb 100644 --- a/spec/bundler/bundler/gem_helper_spec.rb +++ b/spec/bundler/bundler/gem_helper_spec.rb @@ -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/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/newgem_spec.rb b/spec/bundler/commands/newgem_spec.rb index 297d380059..ac452a737a 100644 --- a/spec/bundler/commands/newgem_spec.rb +++ b/spec/bundler/commands/newgem_spec.rb @@ -12,12 +12,7 @@ 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 @@ -351,6 +346,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}" @@ -920,6 +964,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" } 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 3f81808980..3092f9a9b7 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 --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 --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 --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 --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 --local path vendor" bundle "config --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 --local path vendor" bundle "config --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 --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 --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 --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" + 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 - 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 + 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") + + update_repo4 do + build_gem "slim", "4.0.0" do |s| + s.add_dependency "tilt", [">= 2.0.6", "< 2.1"] end - - 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") - - 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 - - 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 + bundle "update", :all => true - install_gemfile <<-G - source "#{file_uri_for(gem_repo4)}" - gem "a" - gem "b" - G + 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("a 1.0", "b 2.0") - - gemfile <<-G - source "#{file_uri_for(gem_repo4)}" - gem "a" - gem "b", "1.0" - G - - bundle "update b" - - expect(the_bundle).to include_gems("a 1.0", "b 1.0") + 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 + + 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 + + bundle "update b" + + expect(the_bundle).to include_gems("a 1.0", "b 1.0") end end diff --git a/spec/bundler/install/gemfile/gemspec_spec.rb b/spec/bundler/install/gemfile/gemspec_spec.rb index 4001df26da..b04db18f49 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 e78217d369..5772c4edc6 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 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/runtime/setup_spec.rb b/spec/bundler/runtime/setup_spec.rb index 7af1cd9801..46663bc76f 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 6587ce5d55..d09ccb6e90 100644 --- a/spec/bundler/spec_helper.rb +++ b/spec/bundler/spec_helper.rb @@ -65,16 +65,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" 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 7e2e92a1ec..73dd508e54 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 gems rubygems . ..].include?(File.basename(dir)) FileUtils.rm_rf(dir) end FileUtils.mkdir_p(home) diff --git a/spec/bundler/support/path.rb b/spec/bundler/support/path.rb index 56d3c71f3c..483c7da347 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,11 @@ 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 dev_gemfile @@ -119,7 +123,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 +142,10 @@ module Spec tmp.join("gems/base") end + def rubocop_gems + tmp.join("gems/rubocop") + end + def file_uri_for(path) protocol = "file://" root = Gem.win_platform? ? "/" : "" @@ -178,7 +186,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) @@ -251,6 +263,10 @@ 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 + extend self end end diff --git a/spec/bundler/support/rubygems_ext.rb b/spec/bundler/support/rubygems_ext.rb index d743a76391..c6202ebb1f 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) @@ -39,18 +39,19 @@ module Spec 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 @@ -66,25 +67,12 @@ 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) end 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) @@ -98,14 +86,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 @@ -113,8 +114,8 @@ module Spec Path.test_gemfile end - def test_lockfile - lockfile_for(test_gemfile) + def rubocop_gemfile + Path.rubocop_gemfile end def dev_gemfile diff --git a/test/rubygems/packages/ascii_binder-0.1.10.1.gem b/test/rubygems/packages/ascii_binder-0.1.10.1.gem new file mode 100644 index 0000000000..19c505395e Binary files /dev/null and b/test/rubygems/packages/ascii_binder-0.1.10.1.gem differ diff --git a/test/rubygems/test_gem_installer.rb b/test/rubygems/test_gem_installer.rb index 5652d86331..058e3b3c20 100644 --- a/test/rubygems/test_gem_installer.rb +++ b/test/rubygems/test_gem_installer.rb @@ -735,6 +735,26 @@ gem 'other', version assert_match(/#{default_shebang}/, shebang_line) end + def test_generate_bin_with_dangling_symlink + gem_with_dangling_symlink = File.expand_path("packages/ascii_binder-0.1.10.1.gem", __dir__) + + installer = Gem::Installer.at( + gem_with_dangling_symlink, + :install_dir => @gem_home, + :user_install => false, + :force => true + ) + + build_rake_in do + use_ui @ui do + installer.install + end + end + + assert_match %r{bin/ascii_binder` is dangling symlink pointing to `bin/asciibinder`}, @ui.error + assert_empty @ui.output + end + def test_generate_plugins installer = util_setup_installer do |spec| write_file File.join(@tempdir, 'lib', 'rubygems_plugin.rb') do |io| diff --git a/test/rubygems/test_gem_package.rb b/test/rubygems/test_gem_package.rb index fd28f9a2a5..eb10ea3437 100644 --- a/test/rubygems/test_gem_package.rb +++ b/test/rubygems/test_gem_package.rb @@ -218,7 +218,7 @@ class TestGemPackage < Gem::Package::TarTestCase end assert_equal %w[lib/code.rb], files - assert_equal [{'lib/code_sym.rb' => 'lib/code.rb'}, {'lib/code_sym2.rb' => '../lib/code.rb'}], symlinks + assert_equal [{'lib/code_sym.rb' => 'code.rb'}, {'lib/code_sym2.rb' => '../lib/code.rb'}], symlinks end def test_build