aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Rodríguez <deivid.rodriguez@riseup.net>2023-01-17 20:53:52 +0100
committerHiroshi SHIBATA <hsbt@ruby-lang.org>2023-03-17 18:50:55 +0900
commitddc4fd5644ae40e6b817fc534f0de0f9c867e7b7 (patch)
tree6555d7277c3afbfb4f66bd2eb0dc243ee90798f2
parent7800d4eeb5cfcd367a596044c183c547642066e2 (diff)
downloadruby-ddc4fd5644ae40e6b817fc534f0de0f9c867e7b7.tar.gz
Normalize git sources
Just like gem sources, a "style-only" change, like adding a trailing slash, should not expire them.
-rw-r--r--lib/bundler.rb1
-rw-r--r--lib/bundler/settings.rb2
-rw-r--r--lib/bundler/source/git.rb2
-rw-r--r--lib/bundler/source/rubygems.rb3
-rw-r--r--lib/bundler/uri_normalizer.rb23
-rw-r--r--spec/bundler/commands/lock_spec.rb18
6 files changed, 45 insertions, 4 deletions
diff --git a/lib/bundler.rb b/lib/bundler.rb
index 1598397bca..3f7fc8f5f4 100644
--- a/lib/bundler.rb
+++ b/lib/bundler.rb
@@ -85,6 +85,7 @@ module Bundler
autoload :StubSpecification, File.expand_path("bundler/stub_specification", __dir__)
autoload :UI, File.expand_path("bundler/ui", __dir__)
autoload :URICredentialsFilter, File.expand_path("bundler/uri_credentials_filter", __dir__)
+ autoload :URINormalizer, File.expand_path("bundler/uri_normalizer", __dir__)
class << self
def configure
diff --git a/lib/bundler/settings.rb b/lib/bundler/settings.rb
index a76a792743..1139eab503 100644
--- a/lib/bundler/settings.rb
+++ b/lib/bundler/settings.rb
@@ -495,7 +495,7 @@ module Bundler
uri = $2
suffix = $3
end
- uri = "#{uri}/" unless uri.end_with?("/")
+ uri = URINormalizer.normalize_suffix(uri)
require_relative "vendored_uri"
uri = Bundler::URI(uri)
unless uri.absolute?
diff --git a/lib/bundler/source/git.rb b/lib/bundler/source/git.rb
index cf8c417ca4..42897813b4 100644
--- a/lib/bundler/source/git.rb
+++ b/lib/bundler/source/git.rb
@@ -19,7 +19,7 @@ module Bundler
# Stringify options that could be set as symbols
%w[ref branch tag revision].each {|k| options[k] = options[k].to_s if options[k] }
- @uri = options["uri"] || ""
+ @uri = URINormalizer.normalize_suffix(options["uri"] || "", :trailing_slash => false)
@safe_uri = URICredentialsFilter.credential_filtered_uri(@uri)
@branch = options["branch"]
@ref = options["ref"] || options["branch"] || options["tag"]
diff --git a/lib/bundler/source/rubygems.rb b/lib/bundler/source/rubygems.rb
index c39071705a..8d0c78bd61 100644
--- a/lib/bundler/source/rubygems.rb
+++ b/lib/bundler/source/rubygems.rb
@@ -337,8 +337,7 @@ module Bundler
end
def normalize_uri(uri)
- uri = uri.to_s
- uri = "#{uri}/" unless %r{/$}.match?(uri)
+ uri = URINormalizer.normalize_suffix(uri.to_s)
require_relative "../vendored_uri"
uri = Bundler::URI(uri)
raise ArgumentError, "The source must be an absolute URI. For example:\n" \
diff --git a/lib/bundler/uri_normalizer.rb b/lib/bundler/uri_normalizer.rb
new file mode 100644
index 0000000000..ad08593256
--- /dev/null
+++ b/lib/bundler/uri_normalizer.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+module Bundler
+ module URINormalizer
+ module_function
+
+ # Normalizes uri to a consistent version, either with or without trailing
+ # slash.
+ #
+ # TODO: Currently gem sources are locked with a trailing slash, while git
+ # sources are locked without a trailing slash. This should be normalized but
+ # the inconsistency is there for now to avoid changing all lockfiles
+ # including GIT sources. We could normalize this on the next major.
+ #
+ def normalize_suffix(uri, trailing_slash: true)
+ if trailing_slash
+ uri.end_with?("/") ? uri : "#{uri}/"
+ else
+ uri.end_with?("/") ? uri.delete_suffix("/") : uri
+ end
+ end
+ end
+end
diff --git a/spec/bundler/commands/lock_spec.rb b/spec/bundler/commands/lock_spec.rb
index 8663cda643..160a17bf55 100644
--- a/spec/bundler/commands/lock_spec.rb
+++ b/spec/bundler/commands/lock_spec.rb
@@ -140,6 +140,24 @@ RSpec.describe "bundle lock" do
expect(read_lockfile).to eq(@lockfile)
end
+ it "does not unlock git sources when only uri shape changes" do
+ build_git("foo")
+
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "foo", :git => "#{file_uri_for(lib_path("foo-1.0"))}"
+ G
+
+ # Change uri format to end with "/" and reinstall
+ install_gemfile <<-G, :verbose => true
+ source "#{file_uri_for(gem_repo1)}"
+ gem "foo", :git => "#{file_uri_for(lib_path("foo-1.0"))}/"
+ G
+
+ expect(out).to include("using resolution from the lockfile")
+ expect(out).not_to include("re-resolving dependencies because the list of sources changed")
+ end
+
it "errors when updating a missing specific gems using --update" do
lockfile @lockfile