summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorHiroshi SHIBATA <hsbt@ruby-lang.org>2023-03-28 20:36:47 +0900
committerGitHub <noreply@github.com>2023-03-28 11:36:47 +0000
commitc3c461c4ff1b998ac49ed1a3ad411d2f0a9123b8 (patch)
tree70c8438d980e19d718dc50e04b6221b023e26387 /lib
parentf8c775cb413724a45bb5641de94f4f9210044116 (diff)
Merge RubyGems-3.4.10 and Bundler-2.4.10 (#7479)
* Merge RubyGems-3.4.7 and Bundler-2.4.7 * Merge RubyGems-3.4.8 and Bundler-2.4.8 * Skip failing test on MSWin * Merge RubyGems-3.4.9 and Bundler-2.4.9 * Merge RubyGems-3.4.10 and Bundler-2.4.10 --------- Co-authored-by: Nobuyoshi Nakada <nobu@ruby-lang.org>
Diffstat (limited to 'lib')
-rw-r--r--lib/bundler.rb19
-rw-r--r--lib/bundler/cli.rb1
-rw-r--r--lib/bundler/cli/init.rb4
-rw-r--r--lib/bundler/current_ruby.rb2
-rw-r--r--lib/bundler/definition.rb6
-rw-r--r--lib/bundler/dependency.rb2
-rw-r--r--lib/bundler/endpoint_specification.rb4
-rw-r--r--lib/bundler/environment_preserver.rb4
-rw-r--r--lib/bundler/fetcher.rb4
-rw-r--r--lib/bundler/fetcher/dependency.rb6
-rw-r--r--lib/bundler/index.rb4
-rw-r--r--lib/bundler/injector.rb2
-rw-r--r--lib/bundler/installer/parallel_installer.rb5
-rw-r--r--lib/bundler/installer/standalone.rb2
-rw-r--r--lib/bundler/lazy_specification.rb12
-rw-r--r--lib/bundler/lockfile_generator.rb2
-rw-r--r--lib/bundler/lockfile_parser.rb22
-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.12
-rw-r--r--lib/bundler/man/bundle-console.12
-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.12
-rw-r--r--lib/bundler/man/bundle-help.12
-rw-r--r--lib/bundler/man/bundle-info.12
-rw-r--r--lib/bundler/man/bundle-init.16
-rw-r--r--lib/bundler/man/bundle-init.1.ronn2
-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-plugin.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-version.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.rb2
-rw-r--r--lib/bundler/plugin/installer.rb7
-rw-r--r--lib/bundler/remote_specification.rb8
-rw-r--r--lib/bundler/resolver.rb15
-rw-r--r--lib/bundler/resolver/base.rb40
-rw-r--r--lib/bundler/rubygems_integration.rb2
-rw-r--r--lib/bundler/settings.rb2
-rw-r--r--lib/bundler/setup.rb5
-rw-r--r--lib/bundler/shared_helpers.rb2
-rw-r--r--lib/bundler/source/git.rb3
-rw-r--r--lib/bundler/source/git/git_proxy.rb35
-rw-r--r--lib/bundler/source/path.rb2
-rw-r--r--lib/bundler/source/rubygems.rb3
-rw-r--r--lib/bundler/spec_set.rb16
-rw-r--r--lib/bundler/templates/Executable.bundler2
-rw-r--r--lib/bundler/templates/gems.rb5
-rw-r--r--lib/bundler/templates/newgem/Gemfile.tt2
-rw-r--r--lib/bundler/templates/newgem/Rakefile.tt10
-rw-r--r--lib/bundler/templates/newgem/github/workflows/main.yml.tt2
-rw-r--r--lib/bundler/templates/newgem/newgem.gemspec.tt2
-rw-r--r--lib/bundler/uri_normalizer.rb23
-rw-r--r--lib/bundler/vendor/pub_grub/lib/pub_grub/incompatibility.rb13
-rw-r--r--lib/bundler/vendor/pub_grub/lib/pub_grub/static_package_source.rb9
-rw-r--r--lib/bundler/vendor/pub_grub/lib/pub_grub/version_constraint.rb9
-rw-r--r--lib/bundler/vendor/pub_grub/lib/pub_grub/version_range.rb6
-rw-r--r--lib/bundler/vendor/pub_grub/lib/pub_grub/version_solver.rb5
-rw-r--r--lib/bundler/version.rb2
-rw-r--r--lib/rubygems.rb6
-rw-r--r--lib/rubygems/bundler_version_finder.rb2
-rw-r--r--lib/rubygems/command.rb16
-rw-r--r--lib/rubygems/command_manager.rb1
-rw-r--r--lib/rubygems/commands/exec_command.rb248
-rw-r--r--lib/rubygems/commands/help_command.rb6
-rw-r--r--lib/rubygems/commands/pristine_command.rb9
-rw-r--r--lib/rubygems/commands/uninstall_command.rb3
-rw-r--r--lib/rubygems/core_ext/kernel_require.rb10
-rw-r--r--lib/rubygems/defaults.rb4
-rw-r--r--lib/rubygems/dependency.rb2
-rw-r--r--lib/rubygems/deprecate.rb4
-rw-r--r--lib/rubygems/ext/builder.rb17
-rw-r--r--lib/rubygems/ext/ext_conf_builder.rb3
-rw-r--r--lib/rubygems/ext/rake_builder.rb2
-rw-r--r--lib/rubygems/package/tar_header.rb2
-rw-r--r--lib/rubygems/package/tar_reader.rb28
-rw-r--r--lib/rubygems/package/tar_reader/entry.rb95
-rw-r--r--lib/rubygems/platform.rb4
-rw-r--r--lib/rubygems/request_set/gem_dependency_api.rb1
-rw-r--r--lib/rubygems/requirement.rb2
-rw-r--r--lib/rubygems/resolver/stats.rb2
-rw-r--r--lib/rubygems/source/git.rb2
-rw-r--r--lib/rubygems/specification.rb10
-rw-r--r--lib/rubygems/specification_policy.rb5
-rw-r--r--lib/rubygems/stub_specification.rb14
-rw-r--r--lib/rubygems/text.rb2
-rw-r--r--lib/rubygems/util/licenses.rb4
-rw-r--r--lib/rubygems/version.rb4
103 files changed, 672 insertions, 233 deletions
diff --git a/lib/bundler.rb b/lib/bundler.rb
index c6a225977f..88f25b523a 100644
--- a/lib/bundler.rb
+++ b/lib/bundler.rb
@@ -39,8 +39,8 @@ module Bundler
environment_preserver.replace_with_backup
SUDO_MUTEX = Thread::Mutex.new
- SAFE_MARSHAL_CLASSES = [Symbol, TrueClass, String, Array, Hash].freeze
- SAFE_MARSHAL_ERROR = "Unexpected class %s present in marshaled data. Only %s are allowed.".freeze
+ SAFE_MARSHAL_CLASSES = [Symbol, TrueClass, String, Array, Hash, Gem::Version, Gem::Specification].freeze
+ SAFE_MARSHAL_ERROR = "Unexpected class %s present in marshaled data. Only %s are allowed."
SAFE_MARSHAL_PROC = proc do |object|
object.tap do
unless SAFE_MARSHAL_CLASSES.include?(object.class)
@@ -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
@@ -506,7 +507,7 @@ EOF
if File.file?(executable) && File.executable?(executable)
executable
elsif paths = ENV["PATH"]
- quote = '"'.freeze
+ quote = '"'
paths.split(File::PATH_SEPARATOR).find do |path|
path = path[1..-2] if path.start_with?(quote) && path.end_with?(quote)
executable_path = File.expand_path(executable, path)
@@ -525,12 +526,6 @@ EOF
load_marshal(data, :marshal_proc => SAFE_MARSHAL_PROC)
end
- def load_marshal(data, marshal_proc: nil)
- Marshal.load(data, marshal_proc)
- rescue TypeError => e
- raise MarshalError, "#{e.class}: #{e.message}"
- end
-
def load_gemspec(file, validate = false)
@gemspec_cache ||= {}
key = File.expand_path(file)
@@ -619,6 +614,12 @@ EOF
private
+ def load_marshal(data, marshal_proc: nil)
+ Marshal.load(data, marshal_proc)
+ rescue TypeError => e
+ raise MarshalError, "#{e.class}: #{e.message}"
+ end
+
def eval_yaml_gemspec(path, contents)
Kernel.require "psych"
diff --git a/lib/bundler/cli.rb b/lib/bundler/cli.rb
index ee73bdb506..a3eb494db2 100644
--- a/lib/bundler/cli.rb
+++ b/lib/bundler/cli.rb
@@ -156,6 +156,7 @@ module Bundler
dependency listed in the gemspec file to the newly created Gemfile.
D
method_option "gemspec", :type => :string, :banner => "Use the specified .gemspec to create the Gemfile"
+ method_option "gemfile", :type => :string, :banner => "Use the specified name for the gemfile instead of 'Gemfile'"
def init
require_relative "cli/init"
Init.new(options.dup).run
diff --git a/lib/bundler/cli/init.rb b/lib/bundler/cli/init.rb
index bc96507c29..246b9d6460 100644
--- a/lib/bundler/cli/init.rb
+++ b/lib/bundler/cli/init.rb
@@ -32,7 +32,7 @@ module Bundler
file << spec.to_gemfile
end
else
- File.open(File.expand_path("../templates/#{gemfile}", __dir__), "r") do |template|
+ File.open(File.expand_path("../templates/Gemfile", __dir__), "r") do |template|
File.open(gemfile, "wb") do |destination|
IO.copy_stream(template, destination)
end
@@ -45,7 +45,7 @@ module Bundler
private
def gemfile
- @gemfile ||= Bundler.preferred_gemfile_name
+ @gemfile ||= options[:gemfile] || Bundler.preferred_gemfile_name
end
end
end
diff --git a/lib/bundler/current_ruby.rb b/lib/bundler/current_ruby.rb
index f9987c4da8..f009b07ad7 100644
--- a/lib/bundler/current_ruby.rb
+++ b/lib/bundler/current_ruby.rb
@@ -22,6 +22,8 @@ module Bundler
2.7
3.0
3.1
+ 3.2
+ 3.3
].freeze
KNOWN_MAJOR_VERSIONS = KNOWN_MINOR_VERSIONS.map {|v| v.split(".", 2).first }.uniq.freeze
diff --git a/lib/bundler/definition.rb b/lib/bundler/definition.rb
index e27374f35d..bef86cdd60 100644
--- a/lib/bundler/definition.rb
+++ b/lib/bundler/definition.rb
@@ -726,6 +726,8 @@ module Bundler
dep.source = sources.get(dep.source)
end
+ next if unlocking?
+
unless locked_dep = @locked_deps[dep.name]
changes = true
next
@@ -886,8 +888,9 @@ module Bundler
end
def additional_base_requirements_for_resolve(resolution_packages, last_resolve)
- return resolution_packages unless @locked_gems && unlocking? && !sources.expired_sources?(@locked_gems.sources)
+ return resolution_packages unless @locked_gems && !sources.expired_sources?(@locked_gems.sources)
converge_specs(@originally_locked_specs - last_resolve).each do |locked_spec|
+ next if locked_spec.source.is_a?(Source::Path)
resolution_packages.base_requirements[locked_spec.name] = Gem::Requirement.new(">= #{locked_spec.version}")
end
resolution_packages
@@ -898,6 +901,7 @@ module Bundler
Bundler.local_platform == Gem::Platform::RUBY ||
!platforms.include?(Gem::Platform::RUBY) ||
(@new_platform && platforms.last == Gem::Platform::RUBY) ||
+ @dependency_changes ||
!@originally_locked_specs.incomplete_ruby_specs?(dependencies)
remove_platform(Gem::Platform::RUBY)
diff --git a/lib/bundler/dependency.rb b/lib/bundler/dependency.rb
index 1f8b9da2eb..5f17943629 100644
--- a/lib/bundler/dependency.rb
+++ b/lib/bundler/dependency.rb
@@ -9,7 +9,7 @@ module Bundler
attr_reader :autorequire
attr_reader :groups, :platforms, :gemfile, :path, :git, :github, :branch, :ref
- ALL_RUBY_VERSIONS = ((18..27).to_a + (30..31).to_a).freeze
+ ALL_RUBY_VERSIONS = ((18..27).to_a + (30..33).to_a).freeze
PLATFORM_MAP = {
:ruby => [Gem::Platform::RUBY, ALL_RUBY_VERSIONS],
:mri => [Gem::Platform::RUBY, ALL_RUBY_VERSIONS],
diff --git a/lib/bundler/endpoint_specification.rb b/lib/bundler/endpoint_specification.rb
index d315d1cc68..863544b1f9 100644
--- a/lib/bundler/endpoint_specification.rb
+++ b/lib/bundler/endpoint_specification.rb
@@ -26,10 +26,6 @@ module Bundler
@platform
end
- def identifier
- @__identifier ||= [name, version, platform.to_s]
- end
-
# needed for standalone, load required_paths from local gemspec
# after the gem is installed
def require_paths
diff --git a/lib/bundler/environment_preserver.rb b/lib/bundler/environment_preserver.rb
index 70967522af..57013f5d50 100644
--- a/lib/bundler/environment_preserver.rb
+++ b/lib/bundler/environment_preserver.rb
@@ -2,7 +2,7 @@
module Bundler
class EnvironmentPreserver
- INTENTIONALLY_NIL = "BUNDLER_ENVIRONMENT_PRESERVER_INTENTIONALLY_NIL".freeze
+ INTENTIONALLY_NIL = "BUNDLER_ENVIRONMENT_PRESERVER_INTENTIONALLY_NIL"
BUNDLER_KEYS = %w[
BUNDLE_BIN_PATH
BUNDLE_GEMFILE
@@ -16,7 +16,7 @@ module Bundler
RUBYLIB
RUBYOPT
].map(&:freeze).freeze
- BUNDLER_PREFIX = "BUNDLER_ORIG_".freeze
+ BUNDLER_PREFIX = "BUNDLER_ORIG_"
def self.from_env
new(env_to_hash(ENV), BUNDLER_KEYS)
diff --git a/lib/bundler/fetcher.rb b/lib/bundler/fetcher.rb
index a073bae278..e12c15af8a 100644
--- a/lib/bundler/fetcher.rb
+++ b/lib/bundler/fetcher.rb
@@ -102,11 +102,11 @@ module Bundler
uri = Bundler::URI.parse("#{remote_uri}#{Gem::MARSHAL_SPEC_DIR}#{spec_file_name}.rz")
if uri.scheme == "file"
path = Bundler.rubygems.correct_for_windows_path(uri.path)
- Bundler.load_marshal Bundler.rubygems.inflate(Gem.read_binary(path))
+ Bundler.safe_load_marshal Bundler.rubygems.inflate(Gem.read_binary(path))
elsif cached_spec_path = gemspec_cached_path(spec_file_name)
Bundler.load_gemspec(cached_spec_path)
else
- Bundler.load_marshal Bundler.rubygems.inflate(downloader.fetch(uri).body)
+ Bundler.safe_load_marshal Bundler.rubygems.inflate(downloader.fetch(uri).body)
end
rescue MarshalError
raise HTTPError, "Gemspec #{spec} contained invalid data.\n" \
diff --git a/lib/bundler/fetcher/dependency.rb b/lib/bundler/fetcher/dependency.rb
index 332f86139d..18b606abb6 100644
--- a/lib/bundler/fetcher/dependency.rb
+++ b/lib/bundler/fetcher/dependency.rb
@@ -34,14 +34,10 @@ module Bundler
returned_gems = spec_list.map(&:first).uniq
specs(deps_list, full_dependency_list + returned_gems, spec_list + last_spec_list)
- rescue MarshalError
+ rescue MarshalError, HTTPError, GemspecError
Bundler.ui.info "" unless Bundler.ui.debug? # new line now that the dots are over
Bundler.ui.debug "could not fetch from the dependency API, trying the full index"
nil
- rescue HTTPError, GemspecError
- Bundler.ui.info "" unless Bundler.ui.debug? # new line now that the dots are over
- Bundler.ui.debug "could not fetch from the dependency API\nit's suggested to retry using the full index via `bundle install --full-index`"
- nil
end
def dependency_specs(gem_names)
diff --git a/lib/bundler/index.rb b/lib/bundler/index.rb
index 0301986ca9..b8c599f63a 100644
--- a/lib/bundler/index.rb
+++ b/lib/bundler/index.rb
@@ -13,8 +13,8 @@ module Bundler
attr_reader :specs, :all_specs, :sources
protected :specs, :all_specs
- RUBY = "ruby".freeze
- NULL = "\0".freeze
+ RUBY = "ruby"
+ NULL = "\0"
def initialize
@sources = []
diff --git a/lib/bundler/injector.rb b/lib/bundler/injector.rb
index c2edc9b43a..cb644a7f69 100644
--- a/lib/bundler/injector.rb
+++ b/lib/bundler/injector.rb
@@ -2,7 +2,7 @@
module Bundler
class Injector
- INJECTED_GEMS = "injected gems".freeze
+ INJECTED_GEMS = "injected gems"
def self.inject(new_deps, options = {})
injector = new(new_deps, options)
diff --git a/lib/bundler/installer/parallel_installer.rb b/lib/bundler/installer/parallel_installer.rb
index dce7133769..58c5aafa1c 100644
--- a/lib/bundler/installer/parallel_installer.rb
+++ b/lib/bundler/installer/parallel_installer.rb
@@ -110,12 +110,13 @@ module Bundler
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 << "You can fix this by regenerating your lockfile or 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}"
+ found = @specs.find {|s| s.name == unmet_spec_dependency.name && !unmet_spec_dependency.matches_spec?(s.spec) }
+ warning << "* #{unmet_spec_dependency}, dependency of #{spec.full_name}, unsatisfied by #{found.full_name}"
end
end
diff --git a/lib/bundler/installer/standalone.rb b/lib/bundler/installer/standalone.rb
index 2efef61648..2a8c9a432d 100644
--- a/lib/bundler/installer/standalone.rb
+++ b/lib/bundler/installer/standalone.rb
@@ -52,7 +52,7 @@ module Bundler
def gem_path(path, spec)
full_path = Pathname.new(path).absolute? ? path : File.join(spec.full_gem_path, path)
- if spec.source.instance_of?(Source::Path)
+ if spec.source.instance_of?(Source::Path) && spec.source.path.absolute?
full_path
else
Pathname.new(full_path).relative_path_from(Bundler.root.join(bundler_path)).to_s
diff --git a/lib/bundler/lazy_specification.rb b/lib/bundler/lazy_specification.rb
index 6749892930..ad8191c55f 100644
--- a/lib/bundler/lazy_specification.rb
+++ b/lib/bundler/lazy_specification.rb
@@ -20,7 +20,7 @@ module Bundler
end
def full_name
- if platform == Gem::Platform::RUBY
+ @full_name ||= if platform == Gem::Platform::RUBY
"#{@name}-#{@version}"
else
"#{@name}-#{@version}-#{platform}"
@@ -28,15 +28,15 @@ module Bundler
end
def ==(other)
- identifier == other.identifier
+ full_name == other.full_name
end
def eql?(other)
- identifier.eql?(other.identifier)
+ full_name.eql?(other.full_name)
end
def hash
- identifier.hash
+ full_name.hash
end
##
@@ -129,10 +129,6 @@ module Bundler
end
end
- def identifier
- @__identifier ||= [name, version, platform.to_s]
- end
-
def git_version
return unless source.is_a?(Bundler::Source::Git)
" #{source.revision[0..6]}"
diff --git a/lib/bundler/lockfile_generator.rb b/lib/bundler/lockfile_generator.rb
index 23413dbdd6..a7ee026f67 100644
--- a/lib/bundler/lockfile_generator.rb
+++ b/lib/bundler/lockfile_generator.rb
@@ -45,7 +45,7 @@ module Bundler
# gems with the same name, but different platform
# are ordered consistently
specs.sort_by(&:full_name).each do |spec|
- next if spec.name == "bundler".freeze
+ next if spec.name == "bundler"
out << spec.to_lock
end
end
diff --git a/lib/bundler/lockfile_parser.rb b/lib/bundler/lockfile_parser.rb
index 0ec5b7de8a..97cbf211ba 100644
--- a/lib/bundler/lockfile_parser.rb
+++ b/lib/bundler/lockfile_parser.rb
@@ -4,15 +4,15 @@ module Bundler
class LockfileParser
attr_reader :sources, :dependencies, :specs, :platforms, :bundler_version, :ruby_version
- BUNDLED = "BUNDLED WITH".freeze
- DEPENDENCIES = "DEPENDENCIES".freeze
- PLATFORMS = "PLATFORMS".freeze
- RUBY = "RUBY VERSION".freeze
- GIT = "GIT".freeze
- GEM = "GEM".freeze
- PATH = "PATH".freeze
- PLUGIN = "PLUGIN SOURCE".freeze
- SPECS = " specs:".freeze
+ BUNDLED = "BUNDLED WITH"
+ DEPENDENCIES = "DEPENDENCIES"
+ PLATFORMS = "PLATFORMS"
+ RUBY = "RUBY VERSION"
+ GIT = "GIT"
+ GEM = "GEM"
+ PATH = "PATH"
+ PLUGIN = "PLUGIN SOURCE"
+ SPECS = " specs:"
OPTIONS = /^ ([a-z]+): (.*)$/i.freeze
SOURCE = [GIT, GEM, PATH, PLUGIN].freeze
@@ -86,7 +86,7 @@ module Bundler
send("parse_#{@state}", line)
end
end
- @specs = @specs.values.sort_by(&:identifier)
+ @specs = @specs.values.sort_by(&:full_name)
rescue ArgumentError => e
Bundler.ui.debug(e)
raise LockfileError, "Your lockfile is unreadable. Run `rm #{Bundler.default_lockfile.relative_path_from(SharedHelpers.pwd)}` " \
@@ -199,7 +199,7 @@ module Bundler
@current_spec.source = @current_source
@current_source.add_dependency_names(name)
- @specs[@current_spec.identifier] = @current_spec
+ @specs[@current_spec.full_name] = @current_spec
elsif spaces.size == 6
version = version.split(",").map(&:strip) if version
dep = Gem::Dependency.new(name, version)
diff --git a/lib/bundler/man/bundle-add.1 b/lib/bundler/man/bundle-add.1
index 805bd5450d..0e21c75506 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 2023" "" ""
+.TH "BUNDLE\-ADD" "1" "February 2023" "" ""
.
.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 f5efe77e10..2774e9d28a 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 2023" "" ""
+.TH "BUNDLE\-BINSTUBS" "1" "February 2023" "" ""
.
.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 a17f1a6b06..f24b63c6fc 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 2023" "" ""
+.TH "BUNDLE\-CACHE" "1" "February 2023" "" ""
.
.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 f1bf0b1821..7679945c48 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 2023" "" ""
+.TH "BUNDLE\-CHECK" "1" "February 2023" "" ""
.
.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 b05a8eb0eb..2eb745698c 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 2023" "" ""
+.TH "BUNDLE\-CLEAN" "1" "February 2023" "" ""
.
.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 fdb06c321d..493b57e1de 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 2023" "" ""
+.TH "BUNDLE\-CONFIG" "1" "February 2023" "" ""
.
.SH "NAME"
\fBbundle\-config\fR \- Set bundler configuration options
diff --git a/lib/bundler/man/bundle-console.1 b/lib/bundler/man/bundle-console.1
index 6cb0f0f810..ff239004bf 100644
--- a/lib/bundler/man/bundle-console.1
+++ b/lib/bundler/man/bundle-console.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE\-CONSOLE" "1" "January 2023" "" ""
+.TH "BUNDLE\-CONSOLE" "1" "February 2023" "" ""
.
.SH "NAME"
\fBbundle\-console\fR \- Deprecated way to open an IRB session with the bundle pre\-loaded
diff --git a/lib/bundler/man/bundle-doctor.1 b/lib/bundler/man/bundle-doctor.1
index bfe928c9a1..e463b67477 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 2023" "" ""
+.TH "BUNDLE\-DOCTOR" "1" "February 2023" "" ""
.
.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 281f3faede..9e9efe8b6d 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 2023" "" ""
+.TH "BUNDLE\-EXEC" "1" "February 2023" "" ""
.
.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 4bac1bf442..ea64871fb6 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 2023" "" ""
+.TH "BUNDLE\-GEM" "1" "February 2023" "" ""
.
.SH "NAME"
\fBbundle\-gem\fR \- Generate a project skeleton for creating a rubygem
diff --git a/lib/bundler/man/bundle-help.1 b/lib/bundler/man/bundle-help.1
index 47a42a497e..a3b059ea07 100644
--- a/lib/bundler/man/bundle-help.1
+++ b/lib/bundler/man/bundle-help.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE\-HELP" "1" "January 2023" "" ""
+.TH "BUNDLE\-HELP" "1" "February 2023" "" ""
.
.SH "NAME"
\fBbundle\-help\fR \- Displays detailed help for each subcommand
diff --git a/lib/bundler/man/bundle-info.1 b/lib/bundler/man/bundle-info.1
index e9f5583e85..5af60c6a77 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 2023" "" ""
+.TH "BUNDLE\-INFO" "1" "February 2023" "" ""
.
.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 9e8b059f1f..e93b4fd5e9 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 2023" "" ""
+.TH "BUNDLE\-INIT" "1" "February 2023" "" ""
.
.SH "NAME"
\fBbundle\-init\fR \- Generates a Gemfile into the current working directory
@@ -18,6 +18,10 @@ Init generates a default [\fBGemfile(5)\fR][Gemfile(5)] in the current working d
\fB\-\-gemspec\fR
Use the specified \.gemspec to create the [\fBGemfile(5)\fR][Gemfile(5)]
.
+.TP
+\fB\-\-gemfile\fR
+Use the specified name for the gemfile instead of \fBGemfile\fR
+.
.SH "FILES"
Included in the default [\fBGemfile(5)\fR][Gemfile(5)] generated is the line \fB# frozen_string_literal: true\fR\. This is a magic comment supported for the first time in Ruby 2\.3\. The presence of this line results in all string literals in the file being implicitly frozen\.
.
diff --git a/lib/bundler/man/bundle-init.1.ronn b/lib/bundler/man/bundle-init.1.ronn
index 9d3d97deea..7d3cede1f6 100644
--- a/lib/bundler/man/bundle-init.1.ronn
+++ b/lib/bundler/man/bundle-init.1.ronn
@@ -16,6 +16,8 @@ created [`Gemfile(5)`][Gemfile(5)].
* `--gemspec`:
Use the specified .gemspec to create the [`Gemfile(5)`][Gemfile(5)]
+* `--gemfile`:
+ Use the specified name for the gemfile instead of `Gemfile`
## FILES
diff --git a/lib/bundler/man/bundle-inject.1 b/lib/bundler/man/bundle-inject.1
index 0b0766a40c..657d5ef4a7 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 2023" "" ""
+.TH "BUNDLE\-INJECT" "1" "February 2023" "" ""
.
.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 fcf6a6a66c..8f144692f3 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 2023" "" ""
+.TH "BUNDLE\-INSTALL" "1" "February 2023" "" ""
.
.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 37d2c837e4..f24f62dd38 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 2023" "" ""
+.TH "BUNDLE\-LIST" "1" "February 2023" "" ""
.
.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 422da46d00..55d1035d77 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 2023" "" ""
+.TH "BUNDLE\-LOCK" "1" "February 2023" "" ""
.
.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 c831bf9ce9..ff44d1224f 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 2023" "" ""
+.TH "BUNDLE\-OPEN" "1" "February 2023" "" ""
.
.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 40fe8a4def..8455b71b45 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 2023" "" ""
+.TH "BUNDLE\-OUTDATED" "1" "February 2023" "" ""
.
.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 d0015a80ef..2794878719 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 2023" "" ""
+.TH "BUNDLE\-PLATFORM" "1" "February 2023" "" ""
.
.SH "NAME"
\fBbundle\-platform\fR \- Displays platform compatibility information
diff --git a/lib/bundler/man/bundle-plugin.1 b/lib/bundler/man/bundle-plugin.1
index a231bb1e3d..39d3dfa04e 100644
--- a/lib/bundler/man/bundle-plugin.1
+++ b/lib/bundler/man/bundle-plugin.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE\-PLUGIN" "1" "January 2023" "" ""
+.TH "BUNDLE\-PLUGIN" "1" "February 2023" "" ""
.
.SH "NAME"
\fBbundle\-plugin\fR \- Manage Bundler plugins
diff --git a/lib/bundler/man/bundle-pristine.1 b/lib/bundler/man/bundle-pristine.1
index 8f4bad3db6..f42c7ce156 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 2023" "" ""
+.TH "BUNDLE\-PRISTINE" "1" "February 2023" "" ""
.
.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 97a65016ac..b18d80554d 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 2023" "" ""
+.TH "BUNDLE\-REMOVE" "1" "February 2023" "" ""
.
.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 82706d45f3..efd9ccb0e0 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 2023" "" ""
+.TH "BUNDLE\-SHOW" "1" "February 2023" "" ""
.
.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 65448f4806..c67c44ff86 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 2023" "" ""
+.TH "BUNDLE\-UPDATE" "1" "February 2023" "" ""
.
.SH "NAME"
\fBbundle\-update\fR \- Update your gems to the latest available versions
diff --git a/lib/bundler/man/bundle-version.1 b/lib/bundler/man/bundle-version.1
index bb03e8b5d6..9a3820f3e6 100644
--- a/lib/bundler/man/bundle-version.1
+++ b/lib/bundler/man/bundle-version.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE\-VERSION" "1" "January 2023" "" ""
+.TH "BUNDLE\-VERSION" "1" "February 2023" "" ""
.
.SH "NAME"
\fBbundle\-version\fR \- Prints Bundler version information
diff --git a/lib/bundler/man/bundle-viz.1 b/lib/bundler/man/bundle-viz.1
index 23fb95b738..3a07010309 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 2023" "" ""
+.TH "BUNDLE\-VIZ" "1" "February 2023" "" ""
.
.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 39f3807f30..873ba566b1 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 2023" "" ""
+.TH "BUNDLE" "1" "February 2023" "" ""
.
.SH "NAME"
\fBbundle\fR \- Ruby Dependency Management
diff --git a/lib/bundler/man/gemfile.5 b/lib/bundler/man/gemfile.5
index 740a01e0cc..a9124d26ea 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 2023" "" ""
+.TH "GEMFILE" "5" "February 2023" "" ""
.
.SH "NAME"
\fBGemfile\fR \- A format for describing gem dependencies for Ruby programs
diff --git a/lib/bundler/plugin.rb b/lib/bundler/plugin.rb
index 26458bd596..f3caff8963 100644
--- a/lib/bundler/plugin.rb
+++ b/lib/bundler/plugin.rb
@@ -15,7 +15,7 @@ module Bundler
class UnknownSourceError < PluginError; end
class PluginInstallError < PluginError; end
- PLUGIN_FILE_NAME = "plugins.rb".freeze
+ PLUGIN_FILE_NAME = "plugins.rb"
module_function
diff --git a/lib/bundler/plugin/installer.rb b/lib/bundler/plugin/installer.rb
index 81ecafa470..c9ff12ce4b 100644
--- a/lib/bundler/plugin/installer.rb
+++ b/lib/bundler/plugin/installer.rb
@@ -83,8 +83,11 @@ module Bundler
Bundler.configure_gem_home_and_path(Plugin.root)
- definition = Definition.new(nil, deps, source_list, true)
- install_definition(definition)
+ Bundler.settings.temporary(:deployment => false, :frozen => false) do
+ definition = Definition.new(nil, deps, source_list, true)
+
+ install_definition(definition)
+ end
end
# Installs the plugins and deps from the provided specs and returns map of
diff --git a/lib/bundler/remote_specification.rb b/lib/bundler/remote_specification.rb
index 34d7fd116c..f626a3218e 100644
--- a/lib/bundler/remote_specification.rb
+++ b/lib/bundler/remote_specification.rb
@@ -29,12 +29,8 @@ module Bundler
@platform = _remote_specification.platform
end
- def identifier
- @__identifier ||= [name, version, @platform.to_s]
- end
-
def full_name
- if @platform == Gem::Platform::RUBY
+ @full_name ||= if @platform == Gem::Platform::RUBY
"#{@name}-#{@version}"
else
"#{@name}-#{@version}-#{@platform}"
@@ -106,7 +102,7 @@ module Bundler
def _remote_specification
@_remote_specification ||= @spec_fetcher.fetch_spec([@name, @version, @original_platform])
@_remote_specification || raise(GemspecError, "Gemspec data for #{full_name} was" \
- " missing from the server! Try installing with `--full-index` as a workaround.")
+ " missing from the server!")
end
def method_missing(method, *args, &blk)
diff --git a/lib/bundler/resolver.rb b/lib/bundler/resolver.rb
index 8237ff53fe..c8cc88a3ee 100644
--- a/lib/bundler/resolver.rb
+++ b/lib/bundler/resolver.rb
@@ -37,7 +37,9 @@ module Bundler
root_version = Resolver::Candidate.new(0)
@all_specs = Hash.new do |specs, name|
- specs[name] = source_for(name).specs.search(name).sort_by {|s| [s.version, s.platform.to_s] }
+ specs[name] = source_for(name).specs.search(name).reject do |s|
+ s.dependencies.any? {|d| d.name == name && !d.requirement.satisfied_by?(s.version) } # ignore versions that depend on themselves incorrectly
+ end.sort_by {|s| [s.version, s.platform.to_s] }
end
@sorted_versions = Hash.new do |candidates, package|
@@ -55,7 +57,7 @@ module Bundler
{ root_version => root_dependencies }
else
Hash.new do |versions, version|
- versions[version] = to_dependency_hash(version.dependencies, @packages)
+ versions[version] = to_dependency_hash(version.dependencies.reject {|d| d.name == package.name }, @packages)
end
end
end
@@ -186,11 +188,6 @@ module Bundler
package_deps = @cached_dependencies[package]
sorted_versions = @sorted_versions[package]
package_deps[version].map do |dep_package, dep_constraint|
- if package == dep_package
- cause = PubGrub::Incompatibility::CircularDependency.new(dep_package, dep_constraint.constraint_string)
- return [PubGrub::Incompatibility.new([PubGrub::Term.new(dep_constraint, true)], :cause => cause)]
- end
-
low = high = sorted_versions.index(version)
# find version low such that all >= low share the same dep
@@ -243,7 +240,7 @@ module Bundler
ruby_specs = select_best_platform_match(specs, Gem::Platform::RUBY)
groups << Resolver::Candidate.new(version, :specs => ruby_specs) if ruby_specs.any?
- next groups if platform_specs == ruby_specs
+ next groups if platform_specs == ruby_specs || package.force_ruby_platform?
groups << Resolver::Candidate.new(version, :specs => platform_specs)
@@ -302,7 +299,7 @@ module Bundler
end
def filter_prereleases(specs, package)
- return specs unless package.ignores_prereleases?
+ return specs unless package.ignores_prereleases? && specs.size > 1
specs.reject {|s| s.version.prerelease? }
end
diff --git a/lib/bundler/resolver/base.rb b/lib/bundler/resolver/base.rb
index 6921c047a7..c6afa82056 100644
--- a/lib/bundler/resolver/base.rb
+++ b/lib/bundler/resolver/base.rb
@@ -49,10 +49,18 @@ module Bundler
end
def unlock_names(names)
- names.each do |name|
- @base.delete_by_name(name)
-
- @base_requirements.delete(name)
+ indirect_pins = indirect_pins(names)
+
+ if indirect_pins.any?
+ loosen_names(indirect_pins)
+ else
+ pins = pins(names)
+
+ if pins.any?
+ loosen_names(pins)
+ else
+ unrestrict_names(names)
+ end
end
end
@@ -64,6 +72,30 @@ module Bundler
private
+ def indirect_pins(names)
+ names.select {|name| @base_requirements[name].exact? && @requirements.none? {|dep| dep.name == name } }
+ end
+
+ def pins(names)
+ names.select {|name| @base_requirements[name].exact? }
+ end
+
+ def loosen_names(names)
+ names.each do |name|
+ version = @base_requirements[name].requirements.first[1]
+
+ @base_requirements[name] = Gem::Requirement.new(">= #{version}")
+
+ @base.delete_by_name(name)
+ end
+ end
+
+ def unrestrict_names(names)
+ names.each do |name|
+ @base_requirements.delete(name)
+ end
+ end
+
def build_base_requirements
base_requirements = {}
@base.each do |ls|
diff --git a/lib/bundler/rubygems_integration.rb b/lib/bundler/rubygems_integration.rb
index 3857948511..72016e848b 100644
--- a/lib/bundler/rubygems_integration.rb
+++ b/lib/bundler/rubygems_integration.rb
@@ -453,7 +453,7 @@ module Bundler
fetcher = gem_remote_fetcher
fetcher.headers = { "X-Gemfile-Source" => remote.original_uri.to_s } if remote.original_uri
string = fetcher.fetch_path(path)
- Bundler.load_marshal(string)
+ Bundler.safe_load_marshal(string)
rescue Gem::RemoteFetcher::FetchError
# it's okay for prerelease to fail
raise unless name == "prerelease_specs"
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/setup.rb b/lib/bundler/setup.rb
index 32e9b2d7c0..801fd5312a 100644
--- a/lib/bundler/setup.rb
+++ b/lib/bundler/setup.rb
@@ -12,7 +12,10 @@ if Bundler::SharedHelpers.in_bundle?
Bundler.ui.error e.message
Bundler.ui.warn e.backtrace.join("\n") if ENV["DEBUG"]
if e.is_a?(Bundler::GemNotFound)
- Bundler.ui.warn "Run `bundle install` to install missing gems."
+ suggested_cmd = "bundle install"
+ original_gemfile = Bundler.original_env["BUNDLE_GEMFILE"]
+ suggested_cmd += " --gemfile #{original_gemfile}" if original_gemfile
+ Bundler.ui.warn "Run `#{suggested_cmd}` to install missing gems."
end
exit e.status_code
end
diff --git a/lib/bundler/shared_helpers.rb b/lib/bundler/shared_helpers.rb
index 794a03e62d..d1d4e1d07a 100644
--- a/lib/bundler/shared_helpers.rb
+++ b/lib/bundler/shared_helpers.rb
@@ -160,7 +160,7 @@ module Bundler
" (was expecting #{old_deps.map(&:to_s)}, but the real spec has #{new_deps.map(&:to_s)})"
raise APIResponseMismatchError,
"Downloading #{spec.full_name} revealed dependencies not in the API or the lockfile (#{extra_deps.join(", ")})." \
- "\nEither installing with `--full-index` or running `bundle update #{spec.name}` should fix the problem."
+ "\nRunning `bundle update #{spec.name}` should fix the problem."
end
def pretty_dependency(dep)
diff --git a/lib/bundler/source/git.rb b/lib/bundler/source/git.rb
index b8ee4029b4..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"]
@@ -173,6 +173,7 @@ module Bundler
end
def install(spec, options = {})
+ return if Bundler.settings[:no_install]
force = options[:force]
print_using_message "Using #{version_message(spec, options[:previous_spec])} from #{self}"
diff --git a/lib/bundler/source/git/git_proxy.rb b/lib/bundler/source/git/git_proxy.rb
index 2a7c8473f5..926c9b8ead 100644
--- a/lib/bundler/source/git/git_proxy.rb
+++ b/lib/bundler/source/git/git_proxy.rb
@@ -28,8 +28,9 @@ module Bundler
def initialize(command, path, extra_info = nil)
@command = command
- msg = String.new
- msg << "Git error: command `#{command}` in directory #{path} has failed."
+ msg = String.new("Git error: command `#{command}`")
+ msg << " in directory #{path}" if path
+ msg << " has failed."
msg << "\n#{extra_info}" if extra_info
super msg
end
@@ -139,8 +140,8 @@ module Bundler
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)
+ if err.include?("couldn't find remote ref") || err.include?("not our ref")
+ raise MissingGitRevisionError.new(command_with_no_credentials, path, commit || explicit_ref, credential_filtered_uri)
else
raise GitCommandError.new(command_with_no_credentials, path, err)
end
@@ -153,9 +154,20 @@ module Bundler
SharedHelpers.filesystem_access(path.dirname) do |p|
FileUtils.mkdir_p(p)
end
- git_retry "clone", "--bare", "--no-hardlinks", "--quiet", *extra_clone_args, "--", configured_uri, path.to_s
- extra_ref
+ command = ["clone", "--bare", "--no-hardlinks", "--quiet", *extra_clone_args, "--", configured_uri, path.to_s]
+ command_with_no_credentials = check_allowed(command)
+
+ Bundler::Retry.new("`#{command_with_no_credentials}`", [MissingGitRevisionError]).attempts do
+ _, err, status = capture(command, nil)
+ return extra_ref if status.success?
+
+ if err.include?("Could not find remote branch")
+ raise MissingGitRevisionError.new(command_with_no_credentials, nil, explicit_ref, credential_filtered_uri)
+ else
+ raise GitCommandError.new(command_with_no_credentials, path, err)
+ end
+ end
end
def clone_needs_unshallow?
@@ -186,8 +198,6 @@ module Bundler
end
def refspec
- commit = pinned_to_full_sha? ? ref : @revision
-
if commit
@commit_ref = "refs/#{commit}-sha"
return "#{commit}:#{@commit_ref}"
@@ -206,6 +216,10 @@ module Bundler
"#{reference}:#{reference}"
end
+ def commit
+ @commit ||= pinned_to_full_sha? ? ref : @revision
+ end
+
def fully_qualified_ref
if branch
"refs/heads/#{branch}"
@@ -352,6 +366,11 @@ module Bundler
args += ["--single-branch"]
args.unshift("--no-tags") if supports_cloning_with_no_tags?
+ # If there's a locked revision, no need to clone any specific branch
+ # or tag, since we will end up checking out that locked revision
+ # anyways.
+ return args if @revision
+
args += ["--branch", branch || tag] if branch || tag
args
end
diff --git a/lib/bundler/source/path.rb b/lib/bundler/source/path.rb
index 20975e20ca..bdfcf8274a 100644
--- a/lib/bundler/source/path.rb
+++ b/lib/bundler/source/path.rb
@@ -11,7 +11,7 @@ module Bundler
protected :original_path
- DEFAULT_GLOB = "{,*,*/*}.gemspec".freeze
+ DEFAULT_GLOB = "{,*,*/*}.gemspec"
def initialize(options)
@options = options.dup
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/spec_set.rb b/lib/bundler/spec_set.rb
index 7478bd9ca2..cf63c16a70 100644
--- a/lib/bundler/spec_set.rb
+++ b/lib/bundler/spec_set.rb
@@ -24,6 +24,7 @@ module Bundler
name = dep[0].name
platform = dep[1]
+ incomplete = false
key = [name, platform]
next if handled.key?(key)
@@ -36,14 +37,19 @@ module Bundler
specs_for_dep.first.dependencies.each do |d|
next if d.type == :development
+ incomplete = true if d.name != "bundler" && lookup[d.name].empty?
deps << [d, dep[1]]
end
- elsif check
- @incomplete_specs += lookup[name]
+ else
+ incomplete = true
+ end
+
+ if incomplete && check
+ @incomplete_specs += lookup[name].any? ? lookup[name] : [LazySpecification.new(name, nil, nil)]
end
end
- specs
+ specs.uniq
end
def [](key)
@@ -95,6 +101,10 @@ module Bundler
end
def incomplete_ruby_specs?(deps)
+ return false if @specs.empty?
+
+ @incomplete_specs = []
+
self.for(deps, true, [Gem::Platform::RUBY])
@incomplete_specs.any?
diff --git a/lib/bundler/templates/Executable.bundler b/lib/bundler/templates/Executable.bundler
index 6dab1688f7..e290fe91eb 100644
--- a/lib/bundler/templates/Executable.bundler
+++ b/lib/bundler/templates/Executable.bundler
@@ -47,7 +47,7 @@ m = Module.new do
def lockfile
lockfile =
case File.basename(gemfile)
- when "gems.rb" then gemfile.sub(/\.rb$/, gemfile)
+ when "gems.rb" then gemfile.sub(/\.rb$/, ".locked")
else "#{gemfile}.lock"
end
File.expand_path(lockfile)
diff --git a/lib/bundler/templates/gems.rb b/lib/bundler/templates/gems.rb
deleted file mode 100644
index d2403f18b2..0000000000
--- a/lib/bundler/templates/gems.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-# frozen_string_literal: true
-
-source "https://rubygems.org"
-
-# gem "rails"
diff --git a/lib/bundler/templates/newgem/Gemfile.tt b/lib/bundler/templates/newgem/Gemfile.tt
index 41c95677a3..a0d2ac2826 100644
--- a/lib/bundler/templates/newgem/Gemfile.tt
+++ b/lib/bundler/templates/newgem/Gemfile.tt
@@ -10,7 +10,7 @@ gem "rake", "~> 13.0"
gem "rake-compiler"
<%- if config[:ext] == 'rust' -%>
-gem "rb_sys"
+gem "rb_sys", "~> 0.9.63"
<%- end -%>
<%- end -%>
<%- if config[:test] -%>
diff --git a/lib/bundler/templates/newgem/Rakefile.tt b/lib/bundler/templates/newgem/Rakefile.tt
index ac14545126..b5a5c4e392 100644
--- a/lib/bundler/templates/newgem/Rakefile.tt
+++ b/lib/bundler/templates/newgem/Rakefile.tt
@@ -41,6 +41,15 @@ require "standard/rake"
<% if config[:ext] -%>
<% default_task_names.unshift(:compile) -%>
<% default_task_names.unshift(:clobber) unless config[:ext] == 'rust' -%>
+<% if config[:ext] == 'rust' -%>
+require "rb_sys/extensiontask"
+
+task build: :compile
+
+RbSys::ExtensionTask.new(<%= config[:name].inspect %>) do |ext|
+ ext.lib_dir = "lib/<%= config[:namespaced_path] %>"
+end
+<% else -%>
require "rake/extensiontask"
task build: :compile
@@ -48,6 +57,7 @@ task build: :compile
Rake::ExtensionTask.new("<%= config[:underscored_name] %>") do |ext|
ext.lib_dir = "lib/<%= config[:namespaced_path] %>"
end
+<% end -%>
<% end -%>
<% if default_task_names.size == 1 -%>
diff --git a/lib/bundler/templates/newgem/github/workflows/main.yml.tt b/lib/bundler/templates/newgem/github/workflows/main.yml.tt
index d4021980b4..be58dd8156 100644
--- a/lib/bundler/templates/newgem/github/workflows/main.yml.tt
+++ b/lib/bundler/templates/newgem/github/workflows/main.yml.tt
@@ -20,7 +20,7 @@ jobs:
- uses: actions/checkout@v3
<%- if config[:ext] == 'rust' -%>
- name: Set up Ruby & Rust
- uses: oxidize-rb/actions/setup-ruby-and-rust@main
+ uses: oxidize-rb/actions/setup-ruby-and-rust@v1
with:
ruby-version: ${{ matrix.ruby }}
bundler-cache: true
diff --git a/lib/bundler/templates/newgem/newgem.gemspec.tt b/lib/bundler/templates/newgem/newgem.gemspec.tt
index e35a121245..da81f046d4 100644
--- a/lib/bundler/templates/newgem/newgem.gemspec.tt
+++ b/lib/bundler/templates/newgem/newgem.gemspec.tt
@@ -29,7 +29,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|circleci)|appveyor)})
+ (File.expand_path(f) == __FILE__) || f.start_with?(*%w[bin/ test/ spec/ features/ .git .circleci appveyor])
end
end
spec.bindir = "exe"
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/lib/bundler/vendor/pub_grub/lib/pub_grub/incompatibility.rb b/lib/bundler/vendor/pub_grub/lib/pub_grub/incompatibility.rb
index dab58ecdf7..239eaf3401 100644
--- a/lib/bundler/vendor/pub_grub/lib/pub_grub/incompatibility.rb
+++ b/lib/bundler/vendor/pub_grub/lib/pub_grub/incompatibility.rb
@@ -8,9 +8,6 @@ module Bundler::PubGrub
InvalidDependency = Struct.new(:package, :constraint) do
end
- CircularDependency = Struct.new(:package, :constraint) do
- end
-
NoVersions = Struct.new(:constraint) do
end
@@ -66,8 +63,6 @@ module Bundler::PubGrub
"#{terms[0].to_s(allow_every: true)} depends on #{terms[1].invert}"
when Bundler::PubGrub::Incompatibility::InvalidDependency
"#{terms[0].to_s(allow_every: true)} depends on unknown package #{cause.package}"
- when Bundler::PubGrub::Incompatibility::CircularDependency
- "#{terms[0].to_s(allow_every: true)} depends on itself"
when Bundler::PubGrub::Incompatibility::NoVersions
"no versions satisfy #{cause.constraint}"
when Bundler::PubGrub::Incompatibility::ConflictCause
@@ -76,9 +71,13 @@ module Bundler::PubGrub
elsif terms.length == 1
term = terms[0]
if term.positive?
- "#{terms[0].to_s(allow_every: true)} is forbidden"
+ if term.constraint.any?
+ "#{term.package} cannot be used"
+ else
+ "#{term.to_s(allow_every: true)} cannot be used"
+ end
else
- "#{terms[0].invert} is required"
+ "#{term.invert} is required"
end
else
if terms.all?(&:positive?)
diff --git a/lib/bundler/vendor/pub_grub/lib/pub_grub/static_package_source.rb b/lib/bundler/vendor/pub_grub/lib/pub_grub/static_package_source.rb
index e895812bed..4bf61461b2 100644
--- a/lib/bundler/vendor/pub_grub/lib/pub_grub/static_package_source.rb
+++ b/lib/bundler/vendor/pub_grub/lib/pub_grub/static_package_source.rb
@@ -19,7 +19,14 @@ module Bundler::PubGrub
version = Gem::Version.new(version)
@packages[name] ||= {}
raise ArgumentError, "#{name} #{version} declared twice" if @packages[name].key?(version)
- @packages[name][version] = deps
+ @packages[name][version] = clean_deps(name, version, deps)
+ end
+
+ private
+
+ # Exclude redundant self-referencing dependencies
+ def clean_deps(name, version, deps)
+ deps.reject {|dep_name, req| name == dep_name && Bundler::PubGrub::RubyGems.parse_range(req).include?(version) }
end
end
diff --git a/lib/bundler/vendor/pub_grub/lib/pub_grub/version_constraint.rb b/lib/bundler/vendor/pub_grub/lib/pub_grub/version_constraint.rb
index 9133332d01..b71f3eaf53 100644
--- a/lib/bundler/vendor/pub_grub/lib/pub_grub/version_constraint.rb
+++ b/lib/bundler/vendor/pub_grub/lib/pub_grub/version_constraint.rb
@@ -15,15 +15,16 @@ module Bundler::PubGrub
package.hash ^ range.hash
end
+ def ==(other)
+ package == other.package &&
+ range == other.range
+ end
+
def eql?(other)
package.eql?(other.package) &&
range.eql?(other.range)
end
- def ==(other)
- package == other.package && range == other.range
- end
-
class << self
def exact(package, version)
range = VersionRange.new(min: version, max: version, include_min: true, include_max: true)
diff --git a/lib/bundler/vendor/pub_grub/lib/pub_grub/version_range.rb b/lib/bundler/vendor/pub_grub/lib/pub_grub/version_range.rb
index 506b447b36..8d73c3f7b5 100644
--- a/lib/bundler/vendor/pub_grub/lib/pub_grub/version_range.rb
+++ b/lib/bundler/vendor/pub_grub/lib/pub_grub/version_range.rb
@@ -19,7 +19,7 @@ module Bundler::PubGrub
true
end
- def eql?
+ def eql?(other)
other.empty?
end
@@ -65,6 +65,7 @@ module Bundler::PubGrub
end
EMPTY = Empty.new
+ Empty.singleton_class.undef_method(:new)
def self.empty
EMPTY
@@ -88,7 +89,8 @@ module Bundler::PubGrub
def eql?(other)
if other.is_a?(VersionRange)
- min.eql?(other.min) &&
+ !other.empty? &&
+ min.eql?(other.min) &&
max.eql?(other.max) &&
include_min.eql?(other.include_min) &&
include_max.eql?(other.include_max)
diff --git a/lib/bundler/vendor/pub_grub/lib/pub_grub/version_solver.rb b/lib/bundler/vendor/pub_grub/lib/pub_grub/version_solver.rb
index ea5e455968..2cb8412cf3 100644
--- a/lib/bundler/vendor/pub_grub/lib/pub_grub/version_solver.rb
+++ b/lib/bundler/vendor/pub_grub/lib/pub_grub/version_solver.rb
@@ -125,6 +125,7 @@ module Bundler::PubGrub
package = next_package_to_try
unsatisfied_term = solution.unsatisfied.find { |t| t.package == package }
version = source.versions_for(package, unsatisfied_term.constraint.range).first
+ logger.debug { "attempting #{package} #{version}" }
if version.nil?
add_incompatibility source.no_versions_incompatibility_for(package, unsatisfied_term)
@@ -148,9 +149,11 @@ module Bundler::PubGrub
end
unless conflict
- logger.info { "selecting #{package} #{version}" }
+ logger.info { "selected #{package} #{version}" }
solution.decide(package, version)
+ else
+ logger.info { "conflict: #{conflict.inspect}" }
end
package
diff --git a/lib/bundler/version.rb b/lib/bundler/version.rb
index d3bd162e48..bc9f8d22cd 100644
--- a/lib/bundler/version.rb
+++ b/lib/bundler/version.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: false
module Bundler
- VERSION = "2.4.6".freeze
+ VERSION = "2.4.10".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 26b0b1da7e..ef5f079a80 100644
--- a/lib/rubygems.rb
+++ b/lib/rubygems.rb
@@ -8,7 +8,7 @@
require "rbconfig"
module Gem
- VERSION = "3.4.6".freeze
+ VERSION = "3.4.10"
end
# Must be first since it unloads the prelude from 1.9.2
@@ -824,7 +824,7 @@ An Array (#{env.inspect}) was passed in from #{caller[3]}
def self.env_requirement(gem_name)
@env_requirements_by_name ||= {}
@env_requirements_by_name[gem_name] ||= begin
- req = ENV["GEM_REQUIREMENT_#{gem_name.upcase}"] || ">= 0".freeze
+ req = ENV["GEM_REQUIREMENT_#{gem_name.upcase}"] || ">= 0"
Gem::Requirement.create(req)
end
end
@@ -1301,7 +1301,7 @@ An Array (#{env.inspect}) was passed in from #{caller[3]}
##
# Location of Marshal quick gemspecs on remote repositories
- MARSHAL_SPEC_DIR = "quick/Marshal.#{Gem.marshal_version}/".freeze
+ MARSHAL_SPEC_DIR = "quick/Marshal.#{Gem.marshal_version}/"
autoload :ConfigFile, File.expand_path("rubygems/config_file", __dir__)
autoload :Dependency, File.expand_path("rubygems/dependency", __dir__)
diff --git a/lib/rubygems/bundler_version_finder.rb b/lib/rubygems/bundler_version_finder.rb
index f6fad0bd83..2cbc4ff624 100644
--- a/lib/rubygems/bundler_version_finder.rb
+++ b/lib/rubygems/bundler_version_finder.rb
@@ -21,7 +21,7 @@ module Gem::BundlerVersionFinder
end
def self.bundle_update_bundler_version
- return unless File.basename($0) == "bundle".freeze
+ return unless File.basename($0) == "bundle"
return unless "update".start_with?(ARGV.first || " ")
bundler_version = nil
update_index = nil
diff --git a/lib/rubygems/command.rb b/lib/rubygems/command.rb
index f4688d793b..1e15f612de 100644
--- a/lib/rubygems/command.rb
+++ b/lib/rubygems/command.rb
@@ -201,11 +201,15 @@ class Gem::Command
# respectively.
def get_all_gem_names_and_versions
get_all_gem_names.map do |name|
- if /\A(.*):(#{Gem::Requirement::PATTERN_RAW})\z/ =~ name
- [$1, $2]
- else
- [name]
- end
+ extract_gem_name_and_version(name)
+ end
+ end
+
+ def extract_gem_name_and_version(name) # :nodoc:
+ if /\A(.*):(#{Gem::Requirement::PATTERN_RAW})\z/ =~ name
+ [$1, $2]
+ else
+ [name]
end
end
@@ -624,7 +628,7 @@ class Gem::Command
# :stopdoc:
- HELP = <<-HELP.freeze
+ HELP = <<-HELP
RubyGems is a package manager for Ruby.
Usage:
diff --git a/lib/rubygems/command_manager.rb b/lib/rubygems/command_manager.rb
index 1bdbd50530..0a4b53abe5 100644
--- a/lib/rubygems/command_manager.rb
+++ b/lib/rubygems/command_manager.rb
@@ -43,6 +43,7 @@ class Gem::CommandManager
:contents,
:dependency,
:environment,
+ :exec,
:fetch,
:generate_index,
:help,
diff --git a/lib/rubygems/commands/exec_command.rb b/lib/rubygems/commands/exec_command.rb
new file mode 100644
index 0000000000..1d7e836ed0
--- /dev/null
+++ b/lib/rubygems/commands/exec_command.rb
@@ -0,0 +1,248 @@
+# frozen_string_literal: true
+require_relative "../command"
+require_relative "../dependency_installer"
+require_relative "../gem_runner"
+require_relative "../package"
+require_relative "../version_option"
+
+class Gem::Commands::ExecCommand < Gem::Command
+ include Gem::VersionOption
+
+ def initialize
+ super "exec", "Run a command from a gem", {
+ version: Gem::Requirement.default,
+ }
+
+ add_version_option
+ add_prerelease_option "to be installed"
+
+ add_option "-g", "--gem GEM", "run the executable from the given gem" do |value, options|
+ options[:gem_name] = value
+ end
+
+ add_option(:"Install/Update", "--conservative",
+ "Prefer the most recent installed version, ",
+ "rather than the latest version overall") do |value, options|
+ options[:conservative] = true
+ end
+ end
+
+ def arguments # :nodoc:
+ "COMMAND the executable command to run"
+ end
+
+ def defaults_str # :nodoc:
+ "--version '#{Gem::Requirement.default}'"
+ end
+
+ def description # :nodoc:
+ <<-EOF
+The exec command handles installing (if necessary) and running an executable
+from a gem, regardless of whether that gem is currently installed.
+
+The exec command can be thought of as a shortcut to running `gem install` and
+then the executable from the installed gem.
+
+For example, `gem exec rails new .` will run `rails new .` in the current
+directory, without having to manually run `gem install rails`.
+Additionally, the exec command ensures the most recent version of the gem
+is used (unless run with `--conservative`), and that the gem is not installed
+to the same gem path as user-installed gems.
+ EOF
+ end
+
+ def usage # :nodoc:
+ "#{program_name} [options --] COMMAND [args]"
+ end
+
+ def execute
+ gem_paths = { "GEM_HOME" => Gem.paths.home, "GEM_PATH" => Gem.paths.path.join(File::PATH_SEPARATOR), "GEM_SPEC_CACHE" => Gem.paths.spec_cache_dir }.compact
+
+ check_executable
+
+ print_command
+ if options[:gem_name] == "gem" && options[:executable] == "gem"
+ set_gem_exec_install_paths
+ Gem::GemRunner.new.run options[:args]
+ return
+ elsif options[:conservative]
+ install_if_needed
+ else
+ install
+ activate!
+ end
+
+ load!
+ ensure
+ ENV.update(gem_paths) if gem_paths
+ Gem.clear_paths
+ end
+
+ private
+
+ def handle_options(args)
+ args = add_extra_args(args)
+ check_deprecated_options(args)
+ @options = Marshal.load Marshal.dump @defaults # deep copy
+ parser.order!(args) do |v|
+ # put the non-option back at the front of the list of arguments
+ args.unshift(v)
+
+ # stop parsing once we hit the first non-option,
+ # so you can call `gem exec rails --version` and it prints the rails
+ # version rather than rubygem's
+ break
+ end
+ @options[:args] = args
+
+ options[:executable], gem_version = extract_gem_name_and_version(options[:args].shift)
+ options[:gem_name] ||= options[:executable]
+
+ if gem_version
+ if options[:version].none?
+ options[:version] = Gem::Requirement.new(gem_version)
+ else
+ options[:version].concat [gem_version]
+ end
+ end
+
+ if options[:prerelease] && !options[:version].prerelease?
+ if options[:version].none?
+ options[:version] = Gem::Requirement.default_prerelease
+ else
+ options[:version].concat [Gem::Requirement.default_prerelease]
+ end
+ end
+ end
+
+ def check_executable
+ if options[:executable].nil?
+ raise Gem::CommandLineError,
+ "Please specify an executable to run (e.g. #{program_name} COMMAND)"
+ end
+ end
+
+ def print_command
+ verbose "running #{program_name} with:\n"
+ opts = options.reject {|_, v| v.nil? || Array(v).empty? }
+ max_length = opts.map {|k, _| k.size }.max
+ opts.each do |k, v|
+ next if v.nil?
+ verbose "\t#{k.to_s.rjust(max_length)}: #{v}"
+ end
+ verbose ""
+ end
+
+ def install_if_needed
+ activate!
+ rescue Gem::MissingSpecError
+ verbose "#{Gem::Dependency.new(options[:gem_name], options[:version])} not available locally, installing from remote"
+ install
+ activate!
+ end
+
+ def set_gem_exec_install_paths
+ home = File.join(Gem.dir, "gem_exec")
+
+ ENV["GEM_PATH"] = ([home] + Gem.path).join(File::PATH_SEPARATOR)
+ ENV["GEM_HOME"] = home
+ Gem.clear_paths
+ end
+
+ def install
+ set_gem_exec_install_paths
+
+ gem_name = options[:gem_name]
+ gem_version = options[:version]
+
+ install_options = options.merge(
+ minimal_deps: false,
+ wrappers: true
+ )
+
+ suppress_always_install do
+ dep_installer = Gem::DependencyInstaller.new install_options
+
+ request_set = dep_installer.resolve_dependencies gem_name, gem_version
+
+ verbose "Gems to install:"
+ request_set.sorted_requests.each do |activation_request|
+ verbose "\t#{activation_request.full_name}"
+ end
+
+ request_set.install install_options
+ end
+
+ Gem::Specification.reset
+ rescue Gem::InstallError => e
+ alert_error "Error installing #{gem_name}:\n\t#{e.message}"
+ terminate_interaction 1
+ rescue Gem::GemNotFoundException => e
+ show_lookup_failure e.name, e.version, e.errors, false
+
+ terminate_interaction 2
+ rescue Gem::UnsatisfiableDependencyError => e
+ show_lookup_failure e.name, e.version, e.errors, false,
+ "'#{gem_name}' (#{gem_version})"
+
+ terminate_interaction 2
+ end
+
+ def activate!
+ gem(options[:gem_name], options[:version])
+ Gem.finish_resolve
+
+ verbose "activated #{options[:gem_name]} (#{Gem.loaded_specs[options[:gem_name]].version})"
+ end
+
+ def load!
+ argv = ARGV.clone
+ ARGV.replace options[:args]
+
+ exe = executable = options[:executable]
+
+ contains_executable = Gem.loaded_specs.values.select do |spec|
+ spec.executables.include?(executable)
+ end
+
+ if contains_executable.any? {|s| s.name == executable }
+ contains_executable.select! {|s| s.name == executable }
+ end
+
+ if contains_executable.empty?
+ if (spec = Gem.loaded_specs[executable]) && (exe = spec.executable)
+ contains_executable << spec
+ else
+ alert_error "Failed to load executable `#{executable}`," \
+ " are you sure the gem `#{options[:gem_name]}` contains it?"
+ terminate_interaction 1
+ end
+ end
+
+ if contains_executable.size > 1
+ alert_error "Ambiguous which gem `#{executable}` should come from: " \
+ "the options are #{contains_executable.map(&:name)}, " \
+ "specify one via `-g`"
+ terminate_interaction 1
+ end
+
+ load Gem.activate_bin_path(contains_executable.first.name, exe, ">= 0.a")
+ ensure
+ ARGV.replace argv
+ end
+
+ def suppress_always_install
+ name = :always_install
+ cls = ::Gem::Resolver::InstallerSet
+ method = cls.instance_method(name)
+ cls.remove_method(name)
+ cls.define_method(name) { [] }
+
+ begin
+ yield
+ ensure
+ cls.remove_method(name)
+ cls.define_method(name, method)
+ end
+ end
+end
diff --git a/lib/rubygems/commands/help_command.rb b/lib/rubygems/commands/help_command.rb
index 8bfb4458ff..bf4ffefbb7 100644
--- a/lib/rubygems/commands/help_command.rb
+++ b/lib/rubygems/commands/help_command.rb
@@ -3,7 +3,7 @@ require_relative "../command"
class Gem::Commands::HelpCommand < Gem::Command
# :stopdoc:
- EXAMPLES = <<-EOF.freeze
+ EXAMPLES = <<-EOF
Some examples of 'gem' usage.
* Install 'rake', either from local directory or remote server:
@@ -52,7 +52,7 @@ Some examples of 'gem' usage.
gem update --system
EOF
- GEM_DEPENDENCIES = <<-EOF.freeze
+ GEM_DEPENDENCIES = <<-EOF
A gem dependencies file allows installation of a consistent set of gems across
multiple environments. The RubyGems implementation is designed to be
compatible with Bundler's Gemfile format. You can see additional
@@ -229,7 +229,7 @@ default. This may be overridden with the :development_group option:
EOF
- PLATFORMS = <<-'EOF'.freeze
+ PLATFORMS = <<-'EOF'
RubyGems platforms are composed of three parts, a CPU, an OS, and a
version. These values are taken from values in rbconfig.rb. You can view
your current platform by running `gem environment`.
diff --git a/lib/rubygems/commands/pristine_command.rb b/lib/rubygems/commands/pristine_command.rb
index 72db53ef37..d7c78ba13d 100644
--- a/lib/rubygems/commands/pristine_command.rb
+++ b/lib/rubygems/commands/pristine_command.rb
@@ -34,6 +34,11 @@ class Gem::Commands::PristineCommand < Gem::Command
options[:extensions] = value
end
+ add_option("--only-missing-extensions",
+ "Only restore gems with missing extensions") do |value, options|
+ options[:only_missing_extensions] = value
+ end
+
add_option("--only-executables",
"Only restore executables") do |value, options|
options[:only_executables] = value
@@ -107,6 +112,10 @@ extensions will be restored.
Gem::Specification.select do |spec|
spec.extensions && !spec.extensions.empty?
end
+ elsif options[:only_missing_extensions]
+ Gem::Specification.select do |spec|
+ spec.missing_extensions?
+ end
else
get_all_gem_names.sort.map do |gem_name|
Gem::Specification.find_all_by_name(gem_name, options[:version]).reverse
diff --git a/lib/rubygems/commands/uninstall_command.rb b/lib/rubygems/commands/uninstall_command.rb
index 3c520826e5..29f6013c59 100644
--- a/lib/rubygems/commands/uninstall_command.rb
+++ b/lib/rubygems/commands/uninstall_command.rb
@@ -125,6 +125,9 @@ that is a dependency of an existing gem. You can use the
def execute
check_version
+ # Consider only gem specifications installed at `--install-dir`
+ Gem::Specification.dirs = options[:install_dir] if options[:install_dir]
+
if options[:all] && !options[:args].empty?
uninstall_specific
elsif options[:all]
diff --git a/lib/rubygems/core_ext/kernel_require.rb b/lib/rubygems/core_ext/kernel_require.rb
index 6dcc4a06e4..568ac347b4 100644
--- a/lib/rubygems/core_ext/kernel_require.rb
+++ b/lib/rubygems/core_ext/kernel_require.rb
@@ -37,9 +37,6 @@ module Kernel
return gem_original_require(path) unless Gem.discover_gems_on_require
begin
- if RUBYGEMS_ACTIVATION_MONITOR.respond_to?(:mon_owned?)
- monitor_owned = RUBYGEMS_ACTIVATION_MONITOR.mon_owned?
- end
RUBYGEMS_ACTIVATION_MONITOR.enter
path = path.to_path if path.respond_to? :to_path
@@ -163,13 +160,6 @@ module Kernel
end
raise load_error
- ensure
- if RUBYGEMS_ACTIVATION_MONITOR.respond_to?(:mon_owned?)
- if monitor_owned != (ow = RUBYGEMS_ACTIVATION_MONITOR.mon_owned?)
- STDERR.puts [$$, Thread.current, $!, $!.backtrace].inspect if $!
- raise "CRITICAL: RUBYGEMS_ACTIVATION_MONITOR.owned?: before #{monitor_owned} -> after #{ow}"
- end
- end
end
end
diff --git a/lib/rubygems/defaults.rb b/lib/rubygems/defaults.rb
index 8daff0bc30..b186375f69 100644
--- a/lib/rubygems/defaults.rb
+++ b/lib/rubygems/defaults.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
module Gem
- DEFAULT_HOST = "https://rubygems.org".freeze
+ DEFAULT_HOST = "https://rubygems.org"
@post_install_hooks ||= []
@done_installing_hooks ||= []
@@ -158,7 +158,7 @@ module Gem
# The path to standard location of the user's state directory.
def self.state_home
- @data_home ||= (ENV["XDG_STATE_HOME"] || File.join(Gem.user_home, ".local", "state"))
+ @state_home ||= (ENV["XDG_STATE_HOME"] || File.join(Gem.user_home, ".local", "state"))
end
##
diff --git a/lib/rubygems/dependency.rb b/lib/rubygems/dependency.rb
index 7fa0f91bd4..cd03e7e299 100644
--- a/lib/rubygems/dependency.rb
+++ b/lib/rubygems/dependency.rb
@@ -299,7 +299,7 @@ class Gem::Dependency
end
def prioritizes_bundler?
- name == "bundler".freeze && !specific?
+ name == "bundler" && !specific?
end
def to_specs
diff --git a/lib/rubygems/deprecate.rb b/lib/rubygems/deprecate.rb
index 5fe0afb6b0..56505512c3 100644
--- a/lib/rubygems/deprecate.rb
+++ b/lib/rubygems/deprecate.rb
@@ -143,7 +143,7 @@ module Gem::Deprecate
end
# Deprecation method to deprecate Rubygems commands
- def rubygems_deprecate_command
+ def rubygems_deprecate_command(version = Gem::Deprecate.next_rubygems_major_version)
class_eval do
define_method "deprecated?" do
true
@@ -151,7 +151,7 @@ module Gem::Deprecate
define_method "deprecation_warning" do
msg = [ "#{self.command} command is deprecated",
- ". It will be removed in Rubygems #{Gem::Deprecate.next_rubygems_major_version}.\n",
+ ". It will be removed in Rubygems #{version}.\n",
]
alert_warning "#{msg.join}" unless Gem::Deprecate.skip
diff --git a/lib/rubygems/ext/builder.rb b/lib/rubygems/ext/builder.rb
index 7fb8958d7f..43ea207b23 100644
--- a/lib/rubygems/ext/builder.rb
+++ b/lib/rubygems/ext/builder.rb
@@ -55,6 +55,23 @@ class Gem::Ext::Builder
end
end
+ def self.ruby
+ require "shellwords"
+ # Gem.ruby is quoted if it contains whitespace
+ cmd = Gem.ruby.shellsplit
+
+ # This load_path is only needed when running rubygems test without a proper installation.
+ # Prepending it in a normal installation will cause problem with order of $LOAD_PATH.
+ # Therefore only add load_path if it is not present in the default $LOAD_PATH.
+ load_path = File.expand_path("../..", __dir__)
+ case load_path
+ when RbConfig::CONFIG["sitelibdir"], RbConfig::CONFIG["vendorlibdir"], RbConfig::CONFIG["rubylibdir"]
+ cmd
+ else
+ cmd << "-I#{load_path}"
+ end
+ end
+
def self.run(command, results, command_name = nil, dir = Dir.pwd, env = {})
verbose = Gem.configuration.really_verbose
diff --git a/lib/rubygems/ext/ext_conf_builder.rb b/lib/rubygems/ext/ext_conf_builder.rb
index 27ebd8c62b..2f4193d697 100644
--- a/lib/rubygems/ext/ext_conf_builder.rb
+++ b/lib/rubygems/ext/ext_conf_builder.rb
@@ -21,8 +21,7 @@ class Gem::Ext::ExtConfBuilder < Gem::Ext::Builder
destdir = ENV["DESTDIR"]
begin
- require "shellwords"
- cmd = Gem.ruby.shellsplit << "-I" << File.expand_path("../..", __dir__) << File.basename(extension)
+ cmd = ruby << File.basename(extension)
cmd.push(*args)
run(cmd, results, class_name, extension_dir) do |s, r|
diff --git a/lib/rubygems/ext/rake_builder.rb b/lib/rubygems/ext/rake_builder.rb
index 9f2e099d40..e74ec8750f 100644
--- a/lib/rubygems/ext/rake_builder.rb
+++ b/lib/rubygems/ext/rake_builder.rb
@@ -18,7 +18,7 @@ class Gem::Ext::RakeBuilder < Gem::Ext::Builder
rake = rake.shellsplit
else
begin
- rake = [Gem.ruby, "-I#{File.expand_path("../..", __dir__)}", "-rrubygems", Gem.bin_path("rake", "rake")]
+ rake = ruby << "-rrubygems" << Gem.bin_path("rake", "rake")
rescue Gem::Exception
rake = [Gem.default_exec_format % "rake"]
end
diff --git a/lib/rubygems/package/tar_header.rb b/lib/rubygems/package/tar_header.rb
index 590a2f0315..31566e5865 100644
--- a/lib/rubygems/package/tar_header.rb
+++ b/lib/rubygems/package/tar_header.rb
@@ -208,7 +208,7 @@ class Gem::Package::TarHeader
private
def calculate_checksum(header)
- header.unpack("C*").inject {|a, b| a + b }
+ header.sum(0)
end
def header(checksum = @checksum)
diff --git a/lib/rubygems/package/tar_reader.rb b/lib/rubygems/package/tar_reader.rb
index cdc3fdc015..9f1d49035b 100644
--- a/lib/rubygems/package/tar_reader.rb
+++ b/lib/rubygems/package/tar_reader.rb
@@ -53,39 +53,11 @@ class Gem::Package::TarReader
def each
return enum_for __method__ unless block_given?
- use_seek = @io.respond_to?(:seek)
-
until @io.eof? do
header = Gem::Package::TarHeader.from @io
return if header.empty?
-
entry = Gem::Package::TarReader::Entry.new header, @io
- size = entry.header.size
-
yield entry
-
- skip = (512 - (size % 512)) % 512
- pending = size - entry.bytes_read
-
- if use_seek
- begin
- # avoid reading if the @io supports seeking
- @io.seek pending, IO::SEEK_CUR
- pending = 0
- rescue Errno::EINVAL
- end
- end
-
- # if seeking isn't supported or failed
- while pending > 0 do
- bytes_read = @io.read([pending, 4096].min).size
- raise UnexpectedEOF if @io.eof?
- pending -= bytes_read
- end
-
- @io.read skip # discard trailing zeros
-
- # make sure nobody can use #read, #getc or #rewind anymore
entry.close
end
end
diff --git a/lib/rubygems/package/tar_reader/entry.rb b/lib/rubygems/package/tar_reader/entry.rb
index 8634381c18..9e7b327431 100644
--- a/lib/rubygems/package/tar_reader/entry.rb
+++ b/lib/rubygems/package/tar_reader/entry.rb
@@ -9,6 +9,20 @@
class Gem::Package::TarReader::Entry
##
+ # Creates a new tar entry for +header+ that will be read from +io+
+ # If a block is given, the entry is yielded and then closed.
+
+ def self.open(header, io, &block)
+ entry = new header, io
+ return entry unless block_given?
+ begin
+ yield entry
+ ensure
+ entry.close
+ end
+ end
+
+ ##
# Header for this tar entry
attr_reader :header
@@ -21,6 +35,7 @@ class Gem::Package::TarReader::Entry
@header = header
@io = io
@orig_pos = @io.pos
+ @end_pos = @orig_pos + @header.size
@read = 0
end
@@ -39,7 +54,14 @@ class Gem::Package::TarReader::Entry
# Closes the tar entry
def close
+ return if closed?
+ # Seek to the end of the entry if it wasn't fully read
+ seek(0, IO::SEEK_END)
+ # discard trailing zeros
+ skip = (512 - (@header.size % 512)) % 512
+ @io.read(skip)
@closed = true
+ nil
end
##
@@ -117,6 +139,14 @@ class Gem::Package::TarReader::Entry
bytes_read
end
+ ##
+ # Seek to the position in the tar entry
+
+ def pos=(new_pos)
+ seek(new_pos, IO::SEEK_SET)
+ new_pos
+ end
+
def size
@header.size
end
@@ -130,9 +160,10 @@ class Gem::Package::TarReader::Entry
def read(len = nil)
check_closed
- return nil if @read >= @header.size
-
len ||= @header.size - @read
+
+ return nil if len > 0 && @read >= @header.size
+
max_read = [len, @header.size - @read].min
ret = @io.read max_read
@@ -144,9 +175,10 @@ class Gem::Package::TarReader::Entry
def readpartial(maxlen = nil, outbuf = "".b)
check_closed
- raise EOFError if @read >= @header.size
-
maxlen ||= @header.size - @read
+
+ raise EOFError if maxlen > 0 && @read >= @header.size
+
max_read = [maxlen, @header.size - @read].min
@io.readpartial(max_read, outbuf)
@@ -156,12 +188,61 @@ class Gem::Package::TarReader::Entry
end
##
+ # Seeks to +offset+ bytes into the tar file entry
+ # +whence+ can be IO::SEEK_SET, IO::SEEK_CUR, or IO::SEEK_END
+
+ def seek(offset, whence = IO::SEEK_SET)
+ check_closed
+
+ new_pos =
+ case whence
+ when IO::SEEK_SET then @orig_pos + offset
+ when IO::SEEK_CUR then @io.pos + offset
+ when IO::SEEK_END then @end_pos + offset
+ else
+ raise ArgumentError, "invalid whence"
+ end
+
+ if new_pos < @orig_pos
+ new_pos = @orig_pos
+ elsif new_pos > @end_pos
+ new_pos = @end_pos
+ end
+
+ pending = new_pos - @io.pos
+
+ if @io.respond_to?(:seek)
+ begin
+ # avoid reading if the @io supports seeking
+ @io.seek new_pos, IO::SEEK_SET
+ pending = 0
+ rescue Errno::EINVAL
+ end
+ end
+
+ # if seeking isn't supported or failed
+ # negative seek requires that we rewind and read
+ if pending < 0
+ @io.rewind
+ pending = new_pos
+ end
+
+ while pending > 0 do
+ size_read = @io.read([pending, 4096].min).size
+ raise UnexpectedEOF if @io.eof?
+ pending -= size_read
+ end
+
+ @read = @io.pos - @orig_pos
+
+ 0
+ end
+
+ ##
# Rewinds to the beginning of the tar file entry
def rewind
check_closed
-
- @io.pos = @orig_pos
- @read = 0
+ seek(0, IO::SEEK_SET)
end
end
diff --git a/lib/rubygems/platform.rb b/lib/rubygems/platform.rb
index 128871f2bf..f4983c1153 100644
--- a/lib/rubygems/platform.rb
+++ b/lib/rubygems/platform.rb
@@ -235,11 +235,11 @@ class Gem::Platform
# A pure-Ruby gem that may use Gem::Specification#extensions to build
# binary files.
- RUBY = "ruby".freeze
+ RUBY = "ruby"
##
# A platform-specific gem that is built for the packaging Ruby's platform.
# This will be replaced with Gem::Platform::local.
- CURRENT = "current".freeze
+ CURRENT = "current"
end
diff --git a/lib/rubygems/request_set/gem_dependency_api.rb b/lib/rubygems/request_set/gem_dependency_api.rb
index ad6e45005b..0681f8802a 100644
--- a/lib/rubygems/request_set/gem_dependency_api.rb
+++ b/lib/rubygems/request_set/gem_dependency_api.rb
@@ -435,7 +435,6 @@ Gem dependencies file #{@path} requires #{name} more than once.
reference ||= ref
reference ||= branch
reference ||= tag
- reference ||= "master"
if ref && branch
warn <<-WARNING
diff --git a/lib/rubygems/requirement.rb b/lib/rubygems/requirement.rb
index 64f9ac3465..bc2fd9af55 100644
--- a/lib/rubygems/requirement.rb
+++ b/lib/rubygems/requirement.rb
@@ -22,7 +22,7 @@ class Gem::Requirement
SOURCE_SET_REQUIREMENT = Struct.new(:for_lockfile).new "!" # :nodoc:
quoted = OPS.keys.map {|k| Regexp.quote k }.join "|"
- PATTERN_RAW = "\\s*(#{quoted})?\\s*(#{Gem::Version::VERSION_PATTERN})\\s*".freeze # :nodoc:
+ PATTERN_RAW = "\\s*(#{quoted})?\\s*(#{Gem::Version::VERSION_PATTERN})\\s*" # :nodoc:
##
# A regular expression that matches a requirement
diff --git a/lib/rubygems/resolver/stats.rb b/lib/rubygems/resolver/stats.rb
index 64b458f504..3b95efebf7 100644
--- a/lib/rubygems/resolver/stats.rb
+++ b/lib/rubygems/resolver/stats.rb
@@ -32,7 +32,7 @@ class Gem::Resolver::Stats
@iterations += 1
end
- PATTERN = "%20s: %d\n".freeze
+ PATTERN = "%20s: %d\n"
def display
$stdout.puts "=== Resolver Statistics ==="
diff --git a/lib/rubygems/source/git.rb b/lib/rubygems/source/git.rb
index 2609a309e8..7ac685f978 100644
--- a/lib/rubygems/source/git.rb
+++ b/lib/rubygems/source/git.rb
@@ -53,7 +53,7 @@ class Gem::Source::Git < Gem::Source
@uri = Gem::Uri.parse(repository)
@name = name
@repository = repository
- @reference = reference
+ @reference = reference || "HEAD"
@need_submodules = submodules
@remote = true
diff --git a/lib/rubygems/specification.rb b/lib/rubygems/specification.rb
index 5175db2d84..b8aa43bf81 100644
--- a/lib/rubygems/specification.rb
+++ b/lib/rubygems/specification.rb
@@ -338,7 +338,7 @@ class Gem::Specification < Gem::BasicSpecification
# The simplest way is to specify the standard SPDX ID
# https://spdx.org/licenses/ for the license.
# Ideally, you should pick one that is OSI (Open Source Initiative)
- # http://opensource.org/licenses/alphabetical approved.
+ # https://opensource.org/licenses/ approved.
#
# The most commonly used OSI-approved licenses are MIT and Apache-2.0.
# GitHub also provides a license picker at http://choosealicense.com/.
@@ -1022,6 +1022,12 @@ class Gem::Specification < Gem::BasicSpecification
end
##
+ # Find the best specification matching a +full_name+.
+ def self.find_by_full_name(full_name)
+ stubs.find {|s| s.full_name == full_name }&.to_spec
+ end
+
+ ##
# Return the best specification that contains the file matching +path+.
def self.find_by_path(path)
@@ -1606,6 +1612,8 @@ class Gem::Specification < Gem::BasicSpecification
def build_extensions # :nodoc:
return if extensions.empty?
return if default_gem?
+ # we need to fresh build when same name and version of default gems
+ return if self.class.find_by_full_name(full_name)&.default_gem?
return if File.exist? gem_build_complete_path
return if !File.writable?(base_dir)
return if !File.exist?(File.join(base_dir, "extensions"))
diff --git a/lib/rubygems/specification_policy.rb b/lib/rubygems/specification_policy.rb
index 6f4d79cdcf..c7e2edc2bf 100644
--- a/lib/rubygems/specification_policy.rb
+++ b/lib/rubygems/specification_policy.rb
@@ -173,6 +173,7 @@ duplicate dependency on #{dep}, (#{prev.requirement}) use:
end
##
+ # Checks that the gem does not depend on itself.
# Checks that dependencies use requirements as we recommend. Warnings are
# issued when dependencies are open-ended or overly strict for semantic
# versioning.
@@ -180,6 +181,10 @@ duplicate dependency on #{dep}, (#{prev.requirement}) use:
def validate_dependencies # :nodoc:
warning_messages = []
@specification.dependencies.each do |dep|
+ if dep.name == @specification.name # warn on self reference
+ warning_messages << "Self referencing dependency is unnecessary and strongly discouraged."
+ end
+
prerelease_dep = dep.requirements_list.any? do |req|
Gem::Requirement.new(req).prerelease?
end
diff --git a/lib/rubygems/stub_specification.rb b/lib/rubygems/stub_specification.rb
index 512ca9143d..d87abdd993 100644
--- a/lib/rubygems/stub_specification.rb
+++ b/lib/rubygems/stub_specification.rb
@@ -6,10 +6,10 @@
class Gem::StubSpecification < Gem::BasicSpecification
# :nodoc:
- PREFIX = "# stub: ".freeze
+ PREFIX = "# stub: "
# :nodoc:
- OPEN_MODE = "r:UTF-8:-".freeze
+ OPEN_MODE = "r:UTF-8:-"
class StubLine # :nodoc: all
attr_reader :name, :version, :platform, :require_paths, :extensions,
@@ -19,9 +19,9 @@ class Gem::StubSpecification < Gem::BasicSpecification
# These are common require paths.
REQUIRE_PATHS = { # :nodoc:
- "lib" => "lib".freeze,
- "test" => "test".freeze,
- "ext" => "ext".freeze,
+ "lib" => "lib",
+ "test" => "test",
+ "ext" => "ext",
}.freeze
# These are common require path lists. This hash is used to optimize
@@ -33,7 +33,7 @@ class Gem::StubSpecification < Gem::BasicSpecification
}.freeze
def initialize(data, extensions)
- parts = data[PREFIX.length..-1].split(" ".freeze, 4)
+ parts = data[PREFIX.length..-1].split(" ", 4)
@name = parts[0].freeze
@version = if Gem::Version.correct?(parts[1])
Gem::Version.new(parts[1])
@@ -50,7 +50,7 @@ class Gem::StubSpecification < Gem::BasicSpecification
end
path_list = parts.last
- @require_paths = REQUIRE_PATH_LIST[path_list] || path_list.split("\0".freeze).map! do |x|
+ @require_paths = REQUIRE_PATH_LIST[path_list] || path_list.split("\0").map! do |x|
REQUIRE_PATHS[x] || x
end
end
diff --git a/lib/rubygems/text.rb b/lib/rubygems/text.rb
index d6b891380e..be811525f2 100644
--- a/lib/rubygems/text.rb
+++ b/lib/rubygems/text.rb
@@ -9,7 +9,7 @@ module Gem::Text
# Remove any non-printable characters and make the text suitable for
# printing.
def clean_text(text)
- text.gsub(/[\000-\b\v-\f\016-\037\177]/, ".".freeze)
+ text.gsub(/[\000-\b\v-\f\016-\037\177]/, ".")
end
def truncate_text(text, description, max_length = 100_000)
diff --git a/lib/rubygems/util/licenses.rb b/lib/rubygems/util/licenses.rb
index 96f47781c0..a823521d10 100644
--- a/lib/rubygems/util/licenses.rb
+++ b/lib/rubygems/util/licenses.rb
@@ -4,8 +4,8 @@ require_relative "../text"
class Gem::Licenses
extend Gem::Text
- NONSTANDARD = "Nonstandard".freeze
- LICENSE_REF = "LicenseRef-.+".freeze
+ NONSTANDARD = "Nonstandard"
+ LICENSE_REF = "LicenseRef-.+"
# Software Package Data Exchange (SPDX) standard open-source software
# license identifiers
diff --git a/lib/rubygems/version.rb b/lib/rubygems/version.rb
index f67889ef1a..c319e1f820 100644
--- a/lib/rubygems/version.rb
+++ b/lib/rubygems/version.rb
@@ -155,7 +155,7 @@ require_relative "deprecate"
class Gem::Version
include Comparable
- VERSION_PATTERN = '[0-9]+(?>\.[0-9a-zA-Z]+)*(-[0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*)?'.freeze # :nodoc:
+ VERSION_PATTERN = '[0-9]+(?>\.[0-9a-zA-Z]+)*(-[0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*)?' # :nodoc:
ANCHORED_VERSION_PATTERN = /\A\s*(#{VERSION_PATTERN})?\s*\z/.freeze # :nodoc:
##
@@ -272,7 +272,7 @@ class Gem::Version
# string for backwards (RubyGems 1.3.5 and earlier) compatibility.
def marshal_dump
- [version]
+ [@version]
end
##