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>
This commit is contained in:
Hiroshi SHIBATA 2023-03-28 20:36:47 +09:00 committed by GitHub
parent f8c775cb41
commit c3c461c4ff
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
179 changed files with 2882 additions and 469 deletions

View file

@ -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"

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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)

View file

@ -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],

View file

@ -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

View file

@ -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)

View file

@ -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" \

View file

@ -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)

View file

@ -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 = []

View file

@ -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)

View file

@ -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

View file

@ -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

View file

@ -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]}"

View file

@ -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

View file

@ -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)

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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\.
.

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -83,9 +83,12 @@ module Bundler
Bundler.configure_gem_home_and_path(Plugin.root)
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
# gems to their paths

View file

@ -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)

View file

@ -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

View file

@ -49,10 +49,18 @@ module Bundler
end
def unlock_names(names)
names.each do |name|
@base.delete_by_name(name)
indirect_pins = indirect_pins(names)
@base_requirements.delete(name)
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|

View file

@ -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"

View file

@ -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?

View file

@ -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

View file

@ -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)

View file

@ -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}"

View file

@ -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

View file

@ -11,7 +11,7 @@ module Bundler
protected :original_path
DEFAULT_GLOB = "{,*,*/*}.gemspec".freeze
DEFAULT_GLOB = "{,*,*/*}.gemspec"
def initialize(options)
@options = options.dup

View file

@ -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" \

View file

@ -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?

View file

@ -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)

View file

@ -1,5 +0,0 @@
# frozen_string_literal: true
source "https://rubygems.org"
# gem "rails"

View file

@ -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] -%>

View file

@ -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 -%>

View file

@ -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

View file

@ -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"

View file

@ -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

View file

@ -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
"#{terms[0].invert} is required"
"#{term.to_s(allow_every: true)} cannot be used"
end
else
"#{term.invert} is required"
end
else
if terms.all?(&:positive?)

View file

@ -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

View file

@ -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)

View file

@ -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,6 +89,7 @@ module Bundler::PubGrub
def eql?(other)
if other.is_a?(VersionRange)
!other.empty? &&
min.eql?(other.min) &&
max.eql?(other.max) &&
include_min.eql?(other.include_min) &&

View file

@ -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

View file

@ -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

View file

@ -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__)

View file

@ -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

View file

@ -201,13 +201,17 @@ class Gem::Command
# respectively.
def get_all_gem_names_and_versions
get_all_gem_names.map do |name|
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
end
##
# Get a single gem name from the command line. Fail if there is no gem name
@ -624,7 +628,7 @@ class Gem::Command
# :stopdoc:
HELP = <<-HELP.freeze
HELP = <<-HELP
RubyGems is a package manager for Ruby.
Usage:

View file

@ -43,6 +43,7 @@ class Gem::CommandManager
:contents,
:dependency,
:environment,
:exec,
:fetch,
:generate_index,
:help,

View file

@ -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

View file

@ -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`.

View file

@ -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

View file

@ -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]

View file

@ -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

View file

@ -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
##

View file

@ -299,7 +299,7 @@ class Gem::Dependency
end
def prioritizes_bundler?
name == "bundler".freeze && !specific?
name == "bundler" && !specific?
end
def to_specs

View file

@ -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

View file

@ -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

View file

@ -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|

View file

@ -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

View file

@ -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)

View file

@ -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

View file

@ -8,6 +8,20 @@
# Class for reading entries out of a tar file
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
@ -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)
@ -155,13 +187,62 @@ class Gem::Package::TarReader::Entry
outbuf
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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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 ==="

View file

@ -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

View file

@ -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/.
@ -1021,6 +1021,12 @@ class Gem::Specification < Gem::BasicSpecification
Gem::Dependency.new(name, *requirements).to_spec
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+.
@ -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"))

View file

@ -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

View file

@ -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

Some files were not shown because too many files have changed in this diff Show more