diff options
author | Hiroshi SHIBATA <[email protected]> | 2022-12-20 09:43:53 +0900 |
---|---|---|
committer | Hiroshi SHIBATA <[email protected]> | 2022-12-20 13:15:02 +0900 |
commit | 18ba89093a0b214cd89f1567c037c239f094496d (patch) | |
tree | bb4e07c66cca5fd2da04da297e8c66fbf883fdad | |
parent | ad1f61fe80dea7a1b1e8d27a4232d7b10b820960 (diff) |
Merge RubyGems/Bundler master
Pick from https://github.com/rubygems/rubygems/commit/ba3adad4d80038ffd7bea015da2f11d3e8a2ff82
Notes
Notes:
Merged: https://github.com/ruby/ruby/pull/6966
-rw-r--r-- | lib/bundler/cli.rb | 2 | ||||
-rw-r--r-- | lib/bundler/cli/gem.rb | 22 | ||||
-rw-r--r-- | lib/bundler/man/bundle-gem.1 | 4 | ||||
-rw-r--r-- | lib/bundler/man/bundle-gem.1.ronn | 4 | ||||
-rw-r--r-- | lib/bundler/source/git/git_proxy.rb | 65 | ||||
-rw-r--r-- | lib/bundler/source_list.rb | 8 | ||||
-rw-r--r-- | lib/bundler/templates/newgem/newgem.gemspec.tt | 2 | ||||
-rw-r--r-- | lib/bundler/templates/newgem/travis.yml.tt | 6 | ||||
-rw-r--r-- | spec/bundler/commands/newgem_spec.rb | 50 | ||||
-rw-r--r-- | spec/bundler/commands/update_spec.rb | 62 | ||||
-rw-r--r-- | spec/bundler/lock/git_spec.rb | 11 |
11 files changed, 169 insertions, 67 deletions
diff --git a/lib/bundler/cli.rb b/lib/bundler/cli.rb index 9c164b09f4..a9331a0131 100644 --- a/lib/bundler/cli.rb +++ b/lib/bundler/cli.rb @@ -587,7 +587,7 @@ module Bundler method_option :test, :type => :string, :lazy_default => Bundler.settings["gem.test"] || "", :aliases => "-t", :banner => "Use the specified test framework for your library", :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)`" + :desc => "Generate CI configuration, either GitHub Actions, GitLab CI or CircleCI. Set a default with `bundle config set --global gem.ci (github|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>`." diff --git a/lib/bundler/cli/gem.rb b/lib/bundler/cli/gem.rb index 584b28d67d..40c464cc2c 100644 --- a/lib/bundler/cli/gem.rb +++ b/lib/bundler/cli/gem.rb @@ -31,6 +31,7 @@ module Bundler @extension = options[:ext] validate_ext_name if @extension + travis_removal_info end def run @@ -134,8 +135,6 @@ module Bundler case config[:ci] when "github" templates.merge!("github/workflows/main.yml.tt" => ".github/workflows/main.yml") - when "travis" - templates.merge!("travis.yml.tt" => ".travis.yml") when "gitlab" templates.merge!("gitlab-ci.yml.tt" => ".gitlab-ci.yml") when "circle" @@ -308,12 +307,11 @@ module Bundler "* CircleCI: https://circleci.com/\n" \ "* GitHub Actions: https://github.com/features/actions\n" \ "* GitLab CI: https://docs.gitlab.com/ee/ci/\n" \ - "* Travis CI: https://travis-ci.org/\n" \ "\n" Bundler.ui.info hint_text("ci") - result = Bundler.ui.ask "Enter a CI service. github/travis/gitlab/circle/(none):" - if /github|travis|gitlab|circle/.match?(result) + result = Bundler.ui.ask "Enter a CI service. github/gitlab/circle/(none):" + if /github|gitlab|circle/.match?(result) ci_template = result else ci_template = false @@ -428,5 +426,19 @@ module Bundler def standard_version "1.3" end + + # + # TODO: remove at next minor release + def travis_removal_info + if options[:ci] == "travis" + Bundler.ui.error "Support for Travis CI was removed from gem skeleton generator." + exit 1 + end + + if Bundler.settings["gem.ci"] == "travis" + Bundler.ui.error "Support for Travis CI was removed from gem skeleton generator, but it is present in bundle config. Please configure another provider using `bundle config set gem.ci SERVICE` (where SERVICE is one of github/gitlab/circle) or unset configuration using `bundle config unset gem.ci`." + exit 1 + end + end end end diff --git a/lib/bundler/man/bundle-gem.1 b/lib/bundler/man/bundle-gem.1 index e32a03daf4..efd7c8edbc 100644 --- a/lib/bundler/man/bundle-gem.1 +++ b/lib/bundler/man/bundle-gem.1 @@ -77,8 +77,8 @@ When Bundler is configured to not generate tests, an interactive prompt will be 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\-\-ci\fR, \fB\-\-ci=github\fR, \fB\-\-ci=travis\fR, \fB\-\-ci=gitlab\fR, \fB\-\-ci=circle\fR -Specify the continuous integration service that Bundler should use when generating the project\. Acceptable values are \fBgithub\fR, \fBtravis\fR, \fBgitlab\fR and \fBcircle\fR\. A configuration file will be generated in the project directory\. Given no option is specified: +\fB\-\-ci\fR, \fB\-\-ci=github\fR, \fB\-\-ci=gitlab\fR, \fB\-\-ci=circle\fR +Specify the continuous integration service that Bundler should use when generating the project\. Acceptable values are \fBgithub\fR, \fBgitlab\fR and \fBcircle\fR\. A configuration file will be generated in the project directory\. Given no option is specified: . .IP When Bundler is configured to generate CI files, this defaults to Bundler\'s global config setting \fBgem\.ci\fR\. diff --git a/lib/bundler/man/bundle-gem.1.ronn b/lib/bundler/man/bundle-gem.1.ronn index 6169175f3c..96966107e3 100644 --- a/lib/bundler/man/bundle-gem.1.ronn +++ b/lib/bundler/man/bundle-gem.1.ronn @@ -76,9 +76,9 @@ configuration file using the following names: the answer will be saved in Bundler's global config for future `bundle gem` use. -* `--ci`, `--ci=github`, `--ci=travis`, `--ci=gitlab`, `--ci=circle`: +* `--ci`, `--ci=github`, `--ci=gitlab`, `--ci=circle`: Specify the continuous integration service that Bundler should use when - generating the project. Acceptable values are `github`, `travis`, `gitlab` + generating the project. Acceptable values are `github`, `gitlab` and `circle`. A configuration file will be generated in the project directory. Given no option is specified: diff --git a/lib/bundler/source/git/git_proxy.rb b/lib/bundler/source/git/git_proxy.rb index e6c138c9aa..31b3107c9e 100644 --- a/lib/bundler/source/git/git_proxy.rb +++ b/lib/bundler/source/git/git_proxy.rb @@ -31,7 +31,6 @@ module Bundler msg = String.new msg << "Git error: command `#{command}` in directory #{path} has failed." msg << "\n#{extra_info}" if extra_info - msg << "\nIf this error persists you could try removing the cache directory '#{path}'" if path.exist? super msg end end @@ -47,7 +46,7 @@ module Bundler # All actions required by the Git source is encapsulated in this # object. class GitProxy - attr_accessor :path, :uri, :branch, :tag, :ref + attr_accessor :path, :uri, :branch, :tag, :ref, :explicit_ref attr_writer :revision def initialize(path, uri, options = {}, revision = nil, git = nil) @@ -56,6 +55,7 @@ module Bundler @branch = options["branch"] @tag = options["tag"] @ref = options["ref"] + @explicit_ref = branch || tag || ref @revision = revision @git = git end @@ -94,9 +94,7 @@ module Bundler unshallow_needed = clone_needs_unshallow? return unless extra_fetch_needed || unshallow_needed - fetch_args = unshallow_needed ? ["--unshallow"] : depth_args - - git_retry(*["fetch", "--force", "--quiet", "--no-tags", *fetch_args, "--", configured_uri, refspec].compact, :dir => path) + git_remote_fetch(unshallow_needed ? ["--unshallow"] : depth_args) end def copy_to(destination, submodules = false) @@ -132,6 +130,22 @@ module Bundler private + def git_remote_fetch(args) + command = ["fetch", "--force", "--quiet", "--no-tags", *args, "--", configured_uri, refspec].compact + command_with_no_credentials = check_allowed(command) + + Bundler::Retry.new("`#{command_with_no_credentials}` at #{path}", [MissingGitRevisionError]).attempts do + out, err, status = capture(command, path) + return out if status.success? + + if err.include?("couldn't find remote ref") + raise MissingGitRevisionError.new(command_with_no_credentials, path, explicit_ref, credential_filtered_uri) + else + raise GitCommandError.new(command_with_no_credentials, path, err) + end + end + end + def clone_needs_extra_fetch? return true if path.exist? @@ -216,11 +230,7 @@ module Bundler def git_null(*command, dir: nil) check_allowed(command) - out, status = SharedHelpers.with_clean_git_env do - capture_and_ignore_stderr(*capture3_args_for(command, dir)) - end - - [URICredentialsFilter.credential_filtered_string(out, uri), status] + capture(command, dir, :ignore_err => true) end def git_retry(*command, dir: nil) @@ -234,15 +244,13 @@ module Bundler def git(*command, dir: nil) command_with_no_credentials = check_allowed(command) - out, status = SharedHelpers.with_clean_git_env do - capture_and_filter_stderr(*capture3_args_for(command, dir)) - end + out, err, status = capture(command, dir) - filtered_out = URICredentialsFilter.credential_filtered_string(out, uri) + Bundler.ui.warn err unless err.empty? - raise GitCommandError.new(command_with_no_credentials, dir || SharedHelpers.pwd, filtered_out) unless status.success? + raise GitCommandError.new(command_with_no_credentials, dir || SharedHelpers.pwd, out) unless status.success? - filtered_out + out end def has_revision_cached? @@ -254,10 +262,9 @@ module Bundler end def find_local_revision - options_ref = branch || tag || ref - return head_revision if options_ref.nil? + return head_revision if explicit_ref.nil? - find_revision_for(options_ref) + find_revision_for(explicit_ref) end def head_revision @@ -318,17 +325,17 @@ module Bundler command_with_no_credentials end - def capture_and_filter_stderr(*cmd) - require "open3" - return_value, captured_err, status = Open3.capture3(*cmd) - Bundler.ui.warn URICredentialsFilter.credential_filtered_string(captured_err, uri) unless captured_err.empty? - [return_value, status] - end + def capture(cmd, dir, ignore_err: false) + SharedHelpers.with_clean_git_env do + require "open3" + out, err, status = Open3.capture3(*capture3_args_for(cmd, dir)) + + filtered_out = URICredentialsFilter.credential_filtered_string(out, uri) + return [filtered_out, status] if ignore_err - def capture_and_ignore_stderr(*cmd) - require "open3" - return_value, _, status = Open3.capture3(*cmd) - [return_value, status] + filtered_err = URICredentialsFilter.credential_filtered_string(err, uri) + [filtered_out, filtered_err, status] + end end def capture3_args_for(cmd, dir) diff --git a/lib/bundler/source_list.rb b/lib/bundler/source_list.rb index ab05e1334a..63798db941 100644 --- a/lib/bundler/source_list.rb +++ b/lib/bundler/source_list.rb @@ -161,11 +161,17 @@ module Bundler end def map_sources(replacement_sources) - [@rubygems_sources, @path_sources, @git_sources, @plugin_sources].map do |sources| + rubygems, git, plugin = [@rubygems_sources, @git_sources, @plugin_sources].map do |sources| sources.map do |source| replacement_sources.find {|s| s == source } || source end end + + path = @path_sources.map do |source| + replacement_sources.find {|s| s == (source.is_a?(Source::Gemspec) ? source.as_path_source : source) } || source + end + + [rubygems, path, git, plugin] end def global_replacement_source(replacement_sources) diff --git a/lib/bundler/templates/newgem/newgem.gemspec.tt b/lib/bundler/templates/newgem/newgem.gemspec.tt index ceb2e9b28d..a03dcc8bc2 100644 --- a/lib/bundler/templates/newgem/newgem.gemspec.tt +++ b/lib/bundler/templates/newgem/newgem.gemspec.tt @@ -26,7 +26,7 @@ Gem::Specification.new do |spec| # The `git ls-files -z` loads the files in the RubyGem that have been added into git. spec.files = Dir.chdir(__dir__) do `git ls-files -z`.split("\x0").reject do |f| - (f == __FILE__) || f.match(%r{\A(?:(?:bin|test|spec|features)/|\.(?:git|travis|circleci)|appveyor)}) + (f == __FILE__) || f.match(%r{\A(?:(?:bin|test|spec|features)/|\.(?:git|circleci)|appveyor)}) end end spec.bindir = "exe" diff --git a/lib/bundler/templates/newgem/travis.yml.tt b/lib/bundler/templates/newgem/travis.yml.tt deleted file mode 100644 index eab16addca..0000000000 --- a/lib/bundler/templates/newgem/travis.yml.tt +++ /dev/null @@ -1,6 +0,0 @@ ---- -language: ruby -cache: bundler -rvm: - - <%= RUBY_VERSION %> -before_install: gem install bundler -v <%= Bundler::VERSION %> diff --git a/spec/bundler/commands/newgem_spec.rb b/spec/bundler/commands/newgem_spec.rb index c4e8b3a6e7..15a75577a1 100644 --- a/spec/bundler/commands/newgem_spec.rb +++ b/spec/bundler/commands/newgem_spec.rb @@ -348,7 +348,6 @@ RSpec.describe "bundle gem" do 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 - expect(bundled_app("#{gem_name}/.travis.yml")).to_not exist expect(bundled_app("#{gem_name}/.gitlab-ci.yml")).to_not exist expect(bundled_app("#{gem_name}/.circleci/config.yml")).to_not exist end @@ -888,12 +887,29 @@ RSpec.describe "bundle gem" do bundle "gem #{gem_name}" expect(bundled_app("#{gem_name}/.github/workflows/main.yml")).to_not exist - expect(bundled_app("#{gem_name}/.travis.yml")).to_not exist expect(bundled_app("#{gem_name}/.gitlab-ci.yml")).to_not exist expect(bundled_app("#{gem_name}/.circleci/config.yml")).to_not exist end end + context "--ci set to travis" do + it "generates a GitHub Actions config file" do + bundle "gem #{gem_name} --ci=travis", :raise_on_error => false + expect(err).to include("Support for Travis CI was removed from gem skeleton generator.") + + expect(bundled_app("#{gem_name}/.travis.yml")).to_not exist + end + end + + context "--ci set to travis" do + it "generates a GitHub Actions config file" do + bundle "gem #{gem_name} --ci=travis", :raise_on_error => false + expect(err).to include("Support for Travis CI was removed from gem skeleton generator.") + + expect(bundled_app("#{gem_name}/.travis.yml")).to_not exist + end + end + context "--ci set to github" do it "generates a GitHub Actions config file" do bundle "gem #{gem_name} --ci=github" @@ -918,38 +934,32 @@ RSpec.describe "bundle gem" do end end - context "--ci set to travis" do - it "generates a Travis CI config file" do - bundle "gem #{gem_name} --ci=travis" - - expect(bundled_app("#{gem_name}/.travis.yml")).to exist - end - end - context "gem.ci setting set to none" do it "doesn't generate any CI config" do expect(bundled_app("#{gem_name}/.github/workflows/main.yml")).to_not exist - expect(bundled_app("#{gem_name}/.travis.yml")).to_not exist expect(bundled_app("#{gem_name}/.gitlab-ci.yml")).to_not exist expect(bundled_app("#{gem_name}/.circleci/config.yml")).to_not exist end end - context "gem.ci setting set to github" do - it "generates a GitHub Actions config file" do - bundle "config set gem.ci github" - bundle "gem #{gem_name}" + context "gem.ci setting set to travis" do + it "errors with friendly message" do + bundle "config set gem.ci travis" + bundle "gem #{gem_name}", :raise_on_error => false - expect(bundled_app("#{gem_name}/.github/workflows/main.yml")).to exist + expect(err).to include("Support for Travis CI was removed from gem skeleton generator,") + expect(err).to include("bundle config unset gem.ci") + + expect(bundled_app("#{gem_name}/.travis.yml")).to_not exist end end - context "gem.ci setting set to travis" do - it "generates a Travis CI config file" do - bundle "config set gem.ci travis" + context "gem.ci setting set to github" do + it "generates a GitHub Actions config file" do + bundle "config set gem.ci github" bundle "gem #{gem_name}" - expect(bundled_app("#{gem_name}/.travis.yml")).to exist + expect(bundled_app("#{gem_name}/.github/workflows/main.yml")).to exist end end diff --git a/spec/bundler/commands/update_spec.rb b/spec/bundler/commands/update_spec.rb index 2d9da70617..583e2aa41b 100644 --- a/spec/bundler/commands/update_spec.rb +++ b/spec/bundler/commands/update_spec.rb @@ -361,6 +361,68 @@ RSpec.describe "bundle update" do expect(out).to include("Installing quickbooks-ruby 1.0.19").and include("Installing oauth2 1.4.10") end + it "does not downgrade direct dependencies when using gemspec sources" do + create_file("rails.gemspec", <<-G) + Gem::Specification.new do |gem| + gem.name = "rails" + gem.version = "7.1.0.alpha" + gem.author = "DHH" + gem.summary = "Full-stack web application framework." + end + G + + build_repo4 do + build_gem "rake", "12.3.3" + build_gem "rake", "13.0.6" + + build_gem "sneakers", "2.11.0" do |s| + s.add_dependency "rake" + end + + build_gem "sneakers", "2.12.0" do |s| + s.add_dependency "rake", "~> 12.3" + end + end + + gemfile <<-G + source "#{file_uri_for(gem_repo4)}" + + gemspec + + gem "rake" + gem "sneakers" + G + + lockfile <<~L + PATH + remote: . + specs: + + GEM + remote: #{file_uri_for(gem_repo4)}/ + specs: + rake (13.0.6) + sneakers (2.11.0) + rake + + PLATFORMS + #{lockfile_platforms} + + DEPENDENCIES + rake + sneakers + + BUNDLED WITH + #{Bundler::VERSION} + L + + bundle "update --verbose" + + expect(out).not_to include("Installing sneakers 2.12.0") + expect(out).not_to include("Installing rake 12.3.3") + expect(out).to include("Installing sneakers 2.11.0").and include("Installing rake 13.0.6") + end + it "does not downgrade indirect dependencies unnecessarily" do build_repo4 do build_gem "a" do |s| diff --git a/spec/bundler/lock/git_spec.rb b/spec/bundler/lock/git_spec.rb index 28d167b773..df9d71fdd6 100644 --- a/spec/bundler/lock/git_spec.rb +++ b/spec/bundler/lock/git_spec.rb @@ -22,6 +22,17 @@ RSpec.describe "bundle lock with git gems" do expect(err).to be_empty end + it "prints a proper error when changing a locked Gemfile to point to a bad branch" do + gemfile <<-G + source "#{file_uri_for(gem_repo1)}" + gem 'foo', :git => "#{lib_path("foo-1.0")}", :branch => "bad" + G + + bundle "lock --update foo", :raise_on_error => false + + expect(err).to include("Revision bad does not exist in the repository") + end + it "locks a git source to the current ref" do update_git "foo" bundle :install |