mirror of
https://github.com/ruby/ruby.git
synced 2026-10-29 08:55:35 +08:00
Merge RubyGems/Bundler 4.0.11
This commit is contained in:
1 parent
9ad5e20f41
commit
56058d238b
60 files changed
+232
-117
No files matched your search
@@ -288,7 +288,7 @@ module Bundler
|
||||
open_editor(options["edit"], target.join("#{name}.gemspec")) if options[:edit]
|
||||
|
||||
Bundler.ui.info "\nGem '#{name}' was successfully created. " \
|
||||
"For more information on making a RubyGem visit https://bundler.io/guides/creating_gem.html"
|
||||
"For more information on making a RubyGem visit https://guides.rubygems.org/make-your-own-gem/"
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
@@ -988,6 +988,8 @@ module Bundler
|
||||
end
|
||||
end
|
||||
|
||||
sources.metadata_source.checksum_store.merge!(@locked_gems.metadata_source.checksum_store) if @locked_gems
|
||||
|
||||
changes
|
||||
end
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ require_relative "gem_installer"
|
||||
module Bundler
|
||||
class ParallelInstaller
|
||||
class SpecInstallation
|
||||
attr_accessor :spec, :name, :full_name, :post_install_message, :state, :error
|
||||
attr_accessor :spec, :name, :full_name, :post_install_message, :state, :error, :dependencies
|
||||
def initialize(spec)
|
||||
@spec = spec
|
||||
@name = spec.name
|
||||
@@ -46,25 +46,11 @@ module Bundler
|
||||
!post_install_message.empty?
|
||||
end
|
||||
|
||||
def ignorable_dependency?(dep)
|
||||
dep.type == :development || dep.name == @name
|
||||
end
|
||||
|
||||
# Checks installed dependencies against spec's dependencies to make
|
||||
# sure needed dependencies have been installed.
|
||||
# Recursively checks that all dependencies (direct and transitive) have been installed.
|
||||
def dependencies_installed?(installed_specs)
|
||||
dependencies.all? {|d| installed_specs.include? d.name }
|
||||
end
|
||||
|
||||
# Represents only the non-development dependencies, the ones that are
|
||||
# itself and are in the total list.
|
||||
def dependencies
|
||||
@dependencies ||= all_dependencies.reject {|dep| ignorable_dependency? dep }
|
||||
end
|
||||
|
||||
# Represents all dependencies
|
||||
def all_dependencies
|
||||
@spec.dependencies
|
||||
dependencies.all? do |dep|
|
||||
installed_specs.include?(dep.name) && dep.dependencies_installed?(installed_specs)
|
||||
end
|
||||
end
|
||||
|
||||
def to_s
|
||||
@@ -85,6 +71,12 @@ module Bundler
|
||||
@force = force
|
||||
@local = local
|
||||
@specs = all_specs.map {|s| SpecInstallation.new(s) }
|
||||
specs_by_name = @specs.to_h {|s| [s.name, s] }
|
||||
@specs.each do |spec_install|
|
||||
spec_install.dependencies = spec_install.spec.dependencies.filter_map do |dep|
|
||||
specs_by_name[dep.name] unless dep.type == :development || dep.name == spec_install.name
|
||||
end
|
||||
end
|
||||
@specs.each do |spec_install|
|
||||
spec_install.state = :installed if skip.include?(spec_install.name)
|
||||
end if skip
|
||||
|
||||
@@ -71,7 +71,8 @@ module Bundler
|
||||
checksums = definition.resolve.map do |spec|
|
||||
spec.source.checksum_store.to_lock(spec)
|
||||
end
|
||||
add_section("CHECKSUMS", checksums)
|
||||
|
||||
add_section("CHECKSUMS", checksums + bundler_checksum)
|
||||
end
|
||||
|
||||
def add_locked_ruby_version
|
||||
@@ -100,5 +101,19 @@ module Bundler
|
||||
raise ArgumentError, "#{value.inspect} can't be serialized in a lockfile"
|
||||
end
|
||||
end
|
||||
|
||||
def bundler_checksum
|
||||
return [] if Bundler.gem_version.to_s.end_with?(".dev") || ENV["SKIP_BUNDLER_CHECKSUM"]
|
||||
|
||||
bundler_spec = definition.sources.metadata_source.specs.search(["bundler", Bundler.gem_version]).last
|
||||
return [] unless File.exist?(bundler_spec.cache_file)
|
||||
|
||||
require "rubygems/package"
|
||||
|
||||
package = Gem::Package.new(bundler_spec.cache_file)
|
||||
definition.sources.metadata_source.checksum_store.register(bundler_spec, Checksum.from_gem_package(package))
|
||||
|
||||
[definition.sources.metadata_source.checksum_store.to_lock(bundler_spec)]
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -28,6 +28,7 @@ module Bundler
|
||||
|
||||
attr_reader(
|
||||
:sources,
|
||||
:metadata_source,
|
||||
:dependencies,
|
||||
:specs,
|
||||
:platforms,
|
||||
@@ -97,6 +98,7 @@ module Bundler
|
||||
def initialize(lockfile, strict: false)
|
||||
@platforms = []
|
||||
@sources = []
|
||||
@metadata_source = Source::Metadata.new
|
||||
@dependencies = {}
|
||||
@parse_method = nil
|
||||
@specs = {}
|
||||
@@ -252,7 +254,12 @@ module Bundler
|
||||
version = Gem::Version.new(version)
|
||||
platform = platform ? Gem::Platform.new(platform) : Gem::Platform::RUBY
|
||||
full_name = Gem::NameTuple.new(name, version, platform).full_name
|
||||
return unless spec = @specs[full_name]
|
||||
spec = @specs[full_name]
|
||||
|
||||
if name == "bundler"
|
||||
spec ||= LazySpecification.new(name, version, platform, @metadata_source)
|
||||
end
|
||||
return unless spec
|
||||
|
||||
if checksums
|
||||
checksums.split(",") do |lock_checksum|
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.\" generated with Ronn-NG/v0.10.1
|
||||
.\" http://github.com/apjanke/ronn-ng/tree/0.10.1
|
||||
.TH "BUNDLE\-ADD" "1" "March 2026" ""
|
||||
.TH "BUNDLE\-ADD" "1" "April 2026" ""
|
||||
.SH "NAME"
|
||||
\fBbundle\-add\fR \- Add gem to the Gemfile and run bundle install
|
||||
.SH "SYNOPSIS"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.\" generated with Ronn-NG/v0.10.1
|
||||
.\" http://github.com/apjanke/ronn-ng/tree/0.10.1
|
||||
.TH "BUNDLE\-BINSTUBS" "1" "March 2026" ""
|
||||
.TH "BUNDLE\-BINSTUBS" "1" "April 2026" ""
|
||||
.SH "NAME"
|
||||
\fBbundle\-binstubs\fR \- Install the binstubs of the listed gems
|
||||
.SH "SYNOPSIS"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.\" generated with Ronn-NG/v0.10.1
|
||||
.\" http://github.com/apjanke/ronn-ng/tree/0.10.1
|
||||
.TH "BUNDLE\-CACHE" "1" "March 2026" ""
|
||||
.TH "BUNDLE\-CACHE" "1" "April 2026" ""
|
||||
.SH "NAME"
|
||||
\fBbundle\-cache\fR \- Package your needed \fB\.gem\fR files into your application
|
||||
.SH "SYNOPSIS"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.\" generated with Ronn-NG/v0.10.1
|
||||
.\" http://github.com/apjanke/ronn-ng/tree/0.10.1
|
||||
.TH "BUNDLE\-CHECK" "1" "March 2026" ""
|
||||
.TH "BUNDLE\-CHECK" "1" "April 2026" ""
|
||||
.SH "NAME"
|
||||
\fBbundle\-check\fR \- Verifies if dependencies are satisfied by installed gems
|
||||
.SH "SYNOPSIS"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.\" generated with Ronn-NG/v0.10.1
|
||||
.\" http://github.com/apjanke/ronn-ng/tree/0.10.1
|
||||
.TH "BUNDLE\-CLEAN" "1" "March 2026" ""
|
||||
.TH "BUNDLE\-CLEAN" "1" "April 2026" ""
|
||||
.SH "NAME"
|
||||
\fBbundle\-clean\fR \- Cleans up unused gems in your bundler directory
|
||||
.SH "SYNOPSIS"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.\" generated with Ronn-NG/v0.10.1
|
||||
.\" http://github.com/apjanke/ronn-ng/tree/0.10.1
|
||||
.TH "BUNDLE\-CONFIG" "1" "March 2026" ""
|
||||
.TH "BUNDLE\-CONFIG" "1" "April 2026" ""
|
||||
.SH "NAME"
|
||||
\fBbundle\-config\fR \- Set bundler configuration options
|
||||
.SH "SYNOPSIS"
|
||||
@@ -172,7 +172,7 @@ Whether Bundler will install gems into the default system path (\fBGem\.dir\fR)\
|
||||
\fBplugins\fR (\fBBUNDLE_PLUGINS\fR)
|
||||
Enable Bundler's experimental plugin system\.
|
||||
.TP
|
||||
\fBprefer_patch\fR (BUNDLE_PREFER_PATCH)
|
||||
\fBprefer_patch\fR (\fBBUNDLE_PREFER_PATCH\fR)
|
||||
Prefer updating only to next patch version during updates\. Makes \fBbundle update\fR calls equivalent to \fBbundler update \-\-patch\fR\.
|
||||
.TP
|
||||
\fBredirect\fR (\fBBUNDLE_REDIRECT\fR)
|
||||
|
||||
@@ -223,7 +223,7 @@ learn more about their operation in [bundle install(1)](bundle-install.1.html).
|
||||
Whether Bundler will install gems into the default system path (`Gem.dir`).
|
||||
* `plugins` (`BUNDLE_PLUGINS`):
|
||||
Enable Bundler's experimental plugin system.
|
||||
* `prefer_patch` (BUNDLE_PREFER_PATCH):
|
||||
* `prefer_patch` (`BUNDLE_PREFER_PATCH`):
|
||||
Prefer updating only to next patch version during updates. Makes `bundle update` calls equivalent to `bundler update --patch`.
|
||||
* `redirect` (`BUNDLE_REDIRECT`):
|
||||
The number of redirects allowed for network requests. Defaults to `5`.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.\" generated with Ronn-NG/v0.10.1
|
||||
.\" http://github.com/apjanke/ronn-ng/tree/0.10.1
|
||||
.TH "BUNDLE\-CONSOLE" "1" "March 2026" ""
|
||||
.TH "BUNDLE\-CONSOLE" "1" "April 2026" ""
|
||||
.SH "NAME"
|
||||
\fBbundle\-console\fR \- Open an IRB session with the bundle pre\-loaded
|
||||
.SH "SYNOPSIS"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.\" generated with Ronn-NG/v0.10.1
|
||||
.\" http://github.com/apjanke/ronn-ng/tree/0.10.1
|
||||
.TH "BUNDLE\-DOCTOR" "1" "March 2026" ""
|
||||
.TH "BUNDLE\-DOCTOR" "1" "April 2026" ""
|
||||
.SH "NAME"
|
||||
\fBbundle\-doctor\fR \- Checks the bundle for common problems
|
||||
.SH "SYNOPSIS"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.\" generated with Ronn-NG/v0.10.1
|
||||
.\" http://github.com/apjanke/ronn-ng/tree/0.10.1
|
||||
.TH "BUNDLE\-ENV" "1" "March 2026" ""
|
||||
.TH "BUNDLE\-ENV" "1" "April 2026" ""
|
||||
.SH "NAME"
|
||||
\fBbundle\-env\fR \- Print information about the environment Bundler is running under
|
||||
.SH "SYNOPSIS"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.\" generated with Ronn-NG/v0.10.1
|
||||
.\" http://github.com/apjanke/ronn-ng/tree/0.10.1
|
||||
.TH "BUNDLE\-EXEC" "1" "March 2026" ""
|
||||
.TH "BUNDLE\-EXEC" "1" "April 2026" ""
|
||||
.SH "NAME"
|
||||
\fBbundle\-exec\fR \- Execute a command in the context of the bundle
|
||||
.SH "SYNOPSIS"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.\" generated with Ronn-NG/v0.10.1
|
||||
.\" http://github.com/apjanke/ronn-ng/tree/0.10.1
|
||||
.TH "BUNDLE\-FUND" "1" "March 2026" ""
|
||||
.TH "BUNDLE\-FUND" "1" "April 2026" ""
|
||||
.SH "NAME"
|
||||
\fBbundle\-fund\fR \- Lists information about gems seeking funding assistance
|
||||
.SH "SYNOPSIS"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.\" generated with Ronn-NG/v0.10.1
|
||||
.\" http://github.com/apjanke/ronn-ng/tree/0.10.1
|
||||
.TH "BUNDLE\-GEM" "1" "March 2026" ""
|
||||
.TH "BUNDLE\-GEM" "1" "April 2026" ""
|
||||
.SH "NAME"
|
||||
\fBbundle\-gem\fR \- Generate a project skeleton for creating a rubygem
|
||||
.SH "SYNOPSIS"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.\" generated with Ronn-NG/v0.10.1
|
||||
.\" http://github.com/apjanke/ronn-ng/tree/0.10.1
|
||||
.TH "BUNDLE\-HELP" "1" "March 2026" ""
|
||||
.TH "BUNDLE\-HELP" "1" "April 2026" ""
|
||||
.SH "NAME"
|
||||
\fBbundle\-help\fR \- Displays detailed help for each subcommand
|
||||
.SH "SYNOPSIS"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.\" generated with Ronn-NG/v0.10.1
|
||||
.\" http://github.com/apjanke/ronn-ng/tree/0.10.1
|
||||
.TH "BUNDLE\-INFO" "1" "March 2026" ""
|
||||
.TH "BUNDLE\-INFO" "1" "April 2026" ""
|
||||
.SH "NAME"
|
||||
\fBbundle\-info\fR \- Show information for the given gem in your bundle
|
||||
.SH "SYNOPSIS"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.\" generated with Ronn-NG/v0.10.1
|
||||
.\" http://github.com/apjanke/ronn-ng/tree/0.10.1
|
||||
.TH "BUNDLE\-INIT" "1" "March 2026" ""
|
||||
.TH "BUNDLE\-INIT" "1" "April 2026" ""
|
||||
.SH "NAME"
|
||||
\fBbundle\-init\fR \- Generates a Gemfile into the current working directory
|
||||
.SH "SYNOPSIS"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.\" generated with Ronn-NG/v0.10.1
|
||||
.\" http://github.com/apjanke/ronn-ng/tree/0.10.1
|
||||
.TH "BUNDLE\-INSTALL" "1" "March 2026" ""
|
||||
.TH "BUNDLE\-INSTALL" "1" "April 2026" ""
|
||||
.SH "NAME"
|
||||
\fBbundle\-install\fR \- Install the dependencies specified in your Gemfile
|
||||
.SH "SYNOPSIS"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.\" generated with Ronn-NG/v0.10.1
|
||||
.\" http://github.com/apjanke/ronn-ng/tree/0.10.1
|
||||
.TH "BUNDLE\-ISSUE" "1" "March 2026" ""
|
||||
.TH "BUNDLE\-ISSUE" "1" "April 2026" ""
|
||||
.SH "NAME"
|
||||
\fBbundle\-issue\fR \- Get help reporting Bundler issues
|
||||
.SH "SYNOPSIS"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.\" generated with Ronn-NG/v0.10.1
|
||||
.\" http://github.com/apjanke/ronn-ng/tree/0.10.1
|
||||
.TH "BUNDLE\-LICENSES" "1" "March 2026" ""
|
||||
.TH "BUNDLE\-LICENSES" "1" "April 2026" ""
|
||||
.SH "NAME"
|
||||
\fBbundle\-licenses\fR \- Print the license of all gems in the bundle
|
||||
.SH "SYNOPSIS"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.\" generated with Ronn-NG/v0.10.1
|
||||
.\" http://github.com/apjanke/ronn-ng/tree/0.10.1
|
||||
.TH "BUNDLE\-LIST" "1" "March 2026" ""
|
||||
.TH "BUNDLE\-LIST" "1" "April 2026" ""
|
||||
.SH "NAME"
|
||||
\fBbundle\-list\fR \- List all the gems in the bundle
|
||||
.SH "SYNOPSIS"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.\" generated with Ronn-NG/v0.10.1
|
||||
.\" http://github.com/apjanke/ronn-ng/tree/0.10.1
|
||||
.TH "BUNDLE\-LOCK" "1" "March 2026" ""
|
||||
.TH "BUNDLE\-LOCK" "1" "April 2026" ""
|
||||
.SH "NAME"
|
||||
\fBbundle\-lock\fR \- Creates / Updates a lockfile without installing
|
||||
.SH "SYNOPSIS"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.\" generated with Ronn-NG/v0.10.1
|
||||
.\" http://github.com/apjanke/ronn-ng/tree/0.10.1
|
||||
.TH "BUNDLE\-OPEN" "1" "March 2026" ""
|
||||
.TH "BUNDLE\-OPEN" "1" "April 2026" ""
|
||||
.SH "NAME"
|
||||
\fBbundle\-open\fR \- Opens the source directory for a gem in your bundle
|
||||
.SH "SYNOPSIS"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.\" generated with Ronn-NG/v0.10.1
|
||||
.\" http://github.com/apjanke/ronn-ng/tree/0.10.1
|
||||
.TH "BUNDLE\-OUTDATED" "1" "March 2026" ""
|
||||
.TH "BUNDLE\-OUTDATED" "1" "April 2026" ""
|
||||
.SH "NAME"
|
||||
\fBbundle\-outdated\fR \- List installed gems with newer versions available
|
||||
.SH "SYNOPSIS"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.\" generated with Ronn-NG/v0.10.1
|
||||
.\" http://github.com/apjanke/ronn-ng/tree/0.10.1
|
||||
.TH "BUNDLE\-PLATFORM" "1" "March 2026" ""
|
||||
.TH "BUNDLE\-PLATFORM" "1" "April 2026" ""
|
||||
.SH "NAME"
|
||||
\fBbundle\-platform\fR \- Displays platform compatibility information
|
||||
.SH "SYNOPSIS"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.\" generated with Ronn-NG/v0.10.1
|
||||
.\" http://github.com/apjanke/ronn-ng/tree/0.10.1
|
||||
.TH "BUNDLE\-PLUGIN" "1" "March 2026" ""
|
||||
.TH "BUNDLE\-PLUGIN" "1" "April 2026" ""
|
||||
.SH "NAME"
|
||||
\fBbundle\-plugin\fR \- Manage Bundler plugins
|
||||
.SH "SYNOPSIS"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.\" generated with Ronn-NG/v0.10.1
|
||||
.\" http://github.com/apjanke/ronn-ng/tree/0.10.1
|
||||
.TH "BUNDLE\-PRISTINE" "1" "March 2026" ""
|
||||
.TH "BUNDLE\-PRISTINE" "1" "April 2026" ""
|
||||
.SH "NAME"
|
||||
\fBbundle\-pristine\fR \- Restores installed gems to their pristine condition
|
||||
.SH "SYNOPSIS"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.\" generated with Ronn-NG/v0.10.1
|
||||
.\" http://github.com/apjanke/ronn-ng/tree/0.10.1
|
||||
.TH "BUNDLE\-REMOVE" "1" "March 2026" ""
|
||||
.TH "BUNDLE\-REMOVE" "1" "April 2026" ""
|
||||
.SH "NAME"
|
||||
\fBbundle\-remove\fR \- Removes gems from the Gemfile
|
||||
.SH "SYNOPSIS"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.\" generated with Ronn-NG/v0.10.1
|
||||
.\" http://github.com/apjanke/ronn-ng/tree/0.10.1
|
||||
.TH "BUNDLE\-SHOW" "1" "March 2026" ""
|
||||
.TH "BUNDLE\-SHOW" "1" "April 2026" ""
|
||||
.SH "NAME"
|
||||
\fBbundle\-show\fR \- Shows all the gems in your bundle, or the path to a gem
|
||||
.SH "SYNOPSIS"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.\" generated with Ronn-NG/v0.10.1
|
||||
.\" http://github.com/apjanke/ronn-ng/tree/0.10.1
|
||||
.TH "BUNDLE\-UPDATE" "1" "March 2026" ""
|
||||
.TH "BUNDLE\-UPDATE" "1" "April 2026" ""
|
||||
.SH "NAME"
|
||||
\fBbundle\-update\fR \- Update your gems to the latest available versions
|
||||
.SH "SYNOPSIS"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.\" generated with Ronn-NG/v0.10.1
|
||||
.\" http://github.com/apjanke/ronn-ng/tree/0.10.1
|
||||
.TH "BUNDLE\-VERSION" "1" "March 2026" ""
|
||||
.TH "BUNDLE\-VERSION" "1" "April 2026" ""
|
||||
.SH "NAME"
|
||||
\fBbundle\-version\fR \- Prints Bundler version information
|
||||
.SH "SYNOPSIS"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.\" generated with Ronn-NG/v0.10.1
|
||||
.\" http://github.com/apjanke/ronn-ng/tree/0.10.1
|
||||
.TH "BUNDLE" "1" "March 2026" ""
|
||||
.TH "BUNDLE" "1" "April 2026" ""
|
||||
.SH "NAME"
|
||||
\fBbundle\fR \- Ruby Dependency Management
|
||||
.SH "SYNOPSIS"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.\" generated with Ronn-NG/v0.10.1
|
||||
.\" http://github.com/apjanke/ronn-ng/tree/0.10.1
|
||||
.TH "GEMFILE" "5" "March 2026" ""
|
||||
.TH "GEMFILE" "5" "April 2026" ""
|
||||
.SH "NAME"
|
||||
\fBGemfile\fR \- A format for describing gem dependencies for Ruby programs
|
||||
.SH "SYNOPSIS"
|
||||
|
||||
@@ -58,6 +58,10 @@ module Bundler
|
||||
def version_message(spec)
|
||||
"#{spec.name} #{spec.version}"
|
||||
end
|
||||
|
||||
def checksum_store
|
||||
@checksum_store ||= Checksum::Store.new
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -508,7 +508,7 @@ module Bundler
|
||||
|
||||
# We are using a mutex to reaed and write from/to the hash.
|
||||
# The reason this double synchronization was added is for performance
|
||||
# and lock the mutex for the shortest possible amount of time. Otherwise,
|
||||
# and to lock the mutex for the shortest possible amount of time. Otherwise,
|
||||
# all threads are fighting over this mutex and when it gets acquired it gets locked
|
||||
# until a threads finishes downloading a gem, leaving the other threads waiting
|
||||
# doing nothing.
|
||||
|
||||
@@ -22,6 +22,12 @@ Gem::Specification.new do |spec|
|
||||
spec.metadata["changelog_uri"] = "<%= config[:changelog_uri] %>"
|
||||
<%- end -%>
|
||||
|
||||
# Uncomment the line below to require MFA for gem pushes.
|
||||
# This helps protect your gem from supply chain attacks by ensuring
|
||||
# no one can publish a new version without multi-factor authentication.
|
||||
# See: https://guides.rubygems.org/mfa-requirement-opt-in/
|
||||
# spec.metadata["rubygems_mfa_required"] = "true"
|
||||
|
||||
# Specify which files should be added to the gem when it is released.
|
||||
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
||||
gemspec = File.basename(__FILE__)
|
||||
@@ -48,5 +54,5 @@ Gem::Specification.new do |spec|
|
||||
<%- end -%>
|
||||
|
||||
# For more information and examples about making a new gem, check out our
|
||||
# guide at: https://bundler.io/guides/creating_gem.html
|
||||
# guide at: https://guides.rubygems.org/make-your-own-gem/
|
||||
end
|
||||
@@ -1,7 +1,7 @@
|
||||
# frozen_string_literal: false
|
||||
|
||||
module Bundler
|
||||
VERSION = "4.0.10".freeze
|
||||
VERSION = "4.0.11".freeze
|
||||
|
||||
def self.bundler_major_version
|
||||
@bundler_major_version ||= gem_version.segments.first
|
||||
|
||||
+1
-1
@@ -9,7 +9,7 @@
|
||||
require "rbconfig"
|
||||
|
||||
module Gem
|
||||
VERSION = "4.0.10"
|
||||
VERSION = "4.0.11"
|
||||
end
|
||||
|
||||
require_relative "rubygems/defaults"
|
||||
|
||||
@@ -42,7 +42,7 @@ class Gem::Commands::SpecificationCommand < Gem::Command
|
||||
|
||||
def arguments # :nodoc:
|
||||
<<-ARGS
|
||||
GEMFILE name of gem to show the gemspec for
|
||||
GEM_OR_FILE gem name or a .gem file to show the gemspec for
|
||||
FIELD name of gemspec field to show
|
||||
ARGS
|
||||
end
|
||||
@@ -68,7 +68,7 @@ Specific fields in the specification can be extracted in YAML format:
|
||||
end
|
||||
|
||||
def usage # :nodoc:
|
||||
"#{program_name} [GEMFILE] [FIELD]"
|
||||
"#{program_name} [GEM_OR_FILE] [FIELD]"
|
||||
end
|
||||
|
||||
def execute
|
||||
@@ -77,7 +77,7 @@ Specific fields in the specification can be extracted in YAML format:
|
||||
|
||||
unless gem
|
||||
raise Gem::CommandLineError,
|
||||
"Please specify a gem name or file on the command line"
|
||||
"Please specify a gem name or a .gem file on the command line"
|
||||
end
|
||||
|
||||
case v = options[:version]
|
||||
|
||||
@@ -3,18 +3,17 @@
|
||||
require "bundler/installer/parallel_installer"
|
||||
|
||||
RSpec.describe Bundler::ParallelInstaller::SpecInstallation do
|
||||
let!(:dep) do
|
||||
a_spec = Object.new
|
||||
def a_spec.name
|
||||
"I like tests"
|
||||
end
|
||||
|
||||
def a_spec.full_name
|
||||
"I really like tests"
|
||||
end
|
||||
a_spec
|
||||
def build_spec(name, extensions: [])
|
||||
spec = Object.new
|
||||
spec.define_singleton_method(:name) { name }
|
||||
spec.define_singleton_method(:full_name) { "#{name}-1.0" }
|
||||
spec.define_singleton_method(:extensions) { extensions }
|
||||
spec.define_singleton_method(:dependencies) { [] }
|
||||
spec
|
||||
end
|
||||
|
||||
let!(:dep) { build_spec("I like tests") }
|
||||
|
||||
describe "#ready_to_enqueue?" do
|
||||
context "when in enqueued state" do
|
||||
it "is falsey" do
|
||||
@@ -39,29 +38,51 @@ RSpec.describe Bundler::ParallelInstaller::SpecInstallation do
|
||||
end
|
||||
|
||||
describe "#dependencies_installed?" do
|
||||
context "when all dependencies are installed" do
|
||||
it "returns true" do
|
||||
dependencies = []
|
||||
dependencies << instance_double("SpecInstallation", spec: "alpha", name: "alpha", installed?: true, all_dependencies: [], type: :production)
|
||||
dependencies << instance_double("SpecInstallation", spec: "beta", name: "beta", installed?: true, all_dependencies: [], type: :production)
|
||||
all_specs = dependencies + [instance_double("SpecInstallation", spec: "gamma", name: "gamma", installed?: false, all_dependencies: [], type: :production)]
|
||||
it "returns true when all dependencies are installed" do
|
||||
alpha = described_class.new(build_spec("alpha"))
|
||||
alpha.dependencies = []
|
||||
|
||||
beta = described_class.new(build_spec("beta"))
|
||||
beta.dependencies = [alpha]
|
||||
|
||||
gamma = described_class.new(build_spec("gamma"))
|
||||
gamma.dependencies = [beta]
|
||||
|
||||
expect(gamma.dependencies_installed?({})).to be_falsey
|
||||
expect(gamma.dependencies_installed?({ "beta" => true })).to be_falsey
|
||||
expect(gamma.dependencies_installed?({ "alpha" => true, "beta" => true })).to be_truthy
|
||||
end
|
||||
end
|
||||
|
||||
describe "#ready_to_install?" do
|
||||
context "when spec has no extensions" do
|
||||
it "returns true regardless of dependencies" do
|
||||
beta = described_class.new(build_spec("beta"))
|
||||
beta.dependencies = []
|
||||
|
||||
spec = described_class.new(dep)
|
||||
allow(spec).to receive(:all_dependencies).and_return(dependencies)
|
||||
installed_specs = all_specs.select(&:installed?).map {|s| [s.name, true] }.to_h
|
||||
expect(spec.dependencies_installed?(installed_specs)).to be_truthy
|
||||
spec.state = :downloaded
|
||||
spec.dependencies = [beta]
|
||||
|
||||
expect(spec.ready_to_install?({})).to be_truthy
|
||||
end
|
||||
end
|
||||
|
||||
context "when all dependencies are not installed" do
|
||||
it "returns false" do
|
||||
dependencies = []
|
||||
dependencies << instance_double("SpecInstallation", spec: "alpha", name: "alpha", installed?: false, all_dependencies: [], type: :production)
|
||||
dependencies << instance_double("SpecInstallation", spec: "beta", name: "beta", installed?: true, all_dependencies: [], type: :production)
|
||||
all_specs = dependencies + [instance_double("SpecInstallation", spec: "gamma", name: "gamma", installed?: false, all_dependencies: [], type: :production)]
|
||||
spec = described_class.new(dep)
|
||||
allow(spec).to receive(:all_dependencies).and_return(dependencies)
|
||||
installed_specs = all_specs.select(&:installed?).map {|s| [s.name, true] }.to_h
|
||||
expect(spec.dependencies_installed?(installed_specs)).to be_falsey
|
||||
context "when spec has extensions" do
|
||||
it "returns true when all dependencies are installed" do
|
||||
alpha = described_class.new(build_spec("alpha"))
|
||||
alpha.dependencies = []
|
||||
|
||||
beta = described_class.new(build_spec("beta"))
|
||||
beta.dependencies = [alpha]
|
||||
|
||||
gamma = described_class.new(build_spec("gamma", extensions: ["ext/Rakefile"]))
|
||||
gamma.state = :downloaded
|
||||
gamma.dependencies = [beta]
|
||||
|
||||
expect(gamma.ready_to_install?({})).to be_falsey
|
||||
expect(gamma.ready_to_install?({ "beta" => true })).to be_falsey
|
||||
expect(gamma.ready_to_install?({ "alpha" => true, "beta" => true })).to be_truthy
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1379,6 +1379,48 @@ RSpec.describe "bundle install with gem sources" do
|
||||
end
|
||||
end
|
||||
|
||||
describe "when a native extension requires a transitive dependency at build time" do
|
||||
before do
|
||||
build_repo4 do
|
||||
build_gem "alpha", "1.0.0" do |s|
|
||||
extension = "ext/alpha/extconf.rb"
|
||||
s.extensions = extension
|
||||
s.write(extension, <<~CODE)
|
||||
require "mkmf"
|
||||
sleep 1
|
||||
create_makefile("alpha")
|
||||
CODE
|
||||
s.write "lib/alpha.rb", "ALPHA = '1.0.0'"
|
||||
end
|
||||
|
||||
build_gem "beta", "1.0.0" do |s|
|
||||
s.add_dependency "alpha"
|
||||
s.write "lib/beta.rb", "require 'alpha'\nBETA = '1.0.0'"
|
||||
end
|
||||
|
||||
build_gem "gamma", "1.0.0" do |s|
|
||||
s.add_dependency "beta"
|
||||
extension = "ext/gamma/extconf.rb"
|
||||
s.extensions = extension
|
||||
s.write(extension, <<~EXTCONF)
|
||||
require "beta"
|
||||
require "mkmf"
|
||||
create_makefile("gamma")
|
||||
EXTCONF
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it "installs successfully" do
|
||||
install_gemfile <<~G
|
||||
source "https://gem.repo4"
|
||||
gem "gamma"
|
||||
G
|
||||
|
||||
expect(the_bundle).to include_gems "alpha 1.0.0", "beta 1.0.0", "gamma 1.0.0"
|
||||
end
|
||||
end
|
||||
|
||||
describe "when configured path is UTF-8 and a file inside a gem package too" do
|
||||
let(:app_path) do
|
||||
path = tmp("♥")
|
||||
|
||||
@@ -2295,6 +2295,10 @@ RSpec.describe "bundle lock" do
|
||||
|
||||
bundle("lock --add-checksums", artifice: "endpoint")
|
||||
|
||||
checksums = checksums_section_when_enabled do |c|
|
||||
c.no_checksum "warning", "18.0.0"
|
||||
end
|
||||
|
||||
expect(lockfile).to eq <<~L
|
||||
GEM
|
||||
remote: https://gem.repo4/
|
||||
@@ -2306,10 +2310,7 @@ RSpec.describe "bundle lock" do
|
||||
|
||||
DEPENDENCIES
|
||||
warning
|
||||
|
||||
CHECKSUMS
|
||||
warning (18.0.0)
|
||||
|
||||
#{checksums}
|
||||
BUNDLED WITH
|
||||
#{Bundler::VERSION}
|
||||
L
|
||||
|
||||
@@ -645,6 +645,15 @@ RSpec.describe "bundle gem" do
|
||||
to match(/example\.com/)
|
||||
end
|
||||
|
||||
it "includes a commented-out rubygems_mfa_required metadata hint" do
|
||||
bundle "gem #{gem_name}"
|
||||
|
||||
gemspec_contents = bundled_app("#{gem_name}/#{gem_name}.gemspec").read
|
||||
|
||||
expect(gemspec_contents).to include('# spec.metadata["rubygems_mfa_required"] = "true"')
|
||||
expect(gemspec_contents).to include("https://guides.rubygems.org/mfa-requirement-opt-in/")
|
||||
end
|
||||
|
||||
it "sets a minimum ruby version" do
|
||||
bundle "gem #{gem_name}"
|
||||
|
||||
|
||||
@@ -1419,9 +1419,7 @@ RSpec.describe "bundle update --ruby" do
|
||||
#{lockfile_platforms}
|
||||
|
||||
DEPENDENCIES
|
||||
|
||||
CHECKSUMS
|
||||
|
||||
#{checksums_section_when_enabled}
|
||||
RUBY VERSION
|
||||
#{Bundler::RubyVersion.system}
|
||||
|
||||
@@ -1537,6 +1535,7 @@ RSpec.describe "bundle update --bundler" do
|
||||
|
||||
checksums = checksums_section do |c|
|
||||
c.checksum(gem_repo4, "myrack", "1.0")
|
||||
c.checksum(gem_repo4, "bundler", "999.0.0")
|
||||
end
|
||||
|
||||
install_gemfile <<-G
|
||||
@@ -1621,6 +1620,7 @@ RSpec.describe "bundle update --bundler" do
|
||||
|
||||
checksums = checksums_section do |c|
|
||||
c.checksum(gem_repo4, "myrack", "1.0")
|
||||
c.checksum(gem_repo4, "bundler", "9.9.9")
|
||||
end
|
||||
|
||||
install_gemfile <<-G
|
||||
@@ -1706,6 +1706,7 @@ RSpec.describe "bundle update --bundler" do
|
||||
checksums = checksums_section_when_enabled do |c|
|
||||
c.checksum(gem_repo4, "myrack", "1.0")
|
||||
end
|
||||
checksums.delete("bundler")
|
||||
|
||||
expect(lockfile).to eq <<~L
|
||||
GEM
|
||||
@@ -1745,6 +1746,7 @@ RSpec.describe "bundle update --bundler" do
|
||||
# Only updates properly on modern RubyGems.
|
||||
checksums = checksums_section_when_enabled do |c|
|
||||
c.checksum(gem_repo4, "myrack", "1.0")
|
||||
c.checksum(local_gem_path, "bundler", "9.0.0", Gem::Platform::RUBY, "cache")
|
||||
end
|
||||
|
||||
expect(lockfile).to eq <<~L
|
||||
|
||||
@@ -478,7 +478,7 @@ RSpec.describe "bundle install with git sources" do
|
||||
update_git("foo", path: repo, tag: tag)
|
||||
|
||||
install_gemfile <<-G
|
||||
source "https://gem.repo1"
|
||||
source "https://gem.repo1"
|
||||
git "#{repo}", :tag => #{tag.dump} do
|
||||
gem "foo"
|
||||
end
|
||||
@@ -1078,7 +1078,7 @@ RSpec.describe "bundle install with git sources" do
|
||||
expect(out).to eq("WIN")
|
||||
end
|
||||
|
||||
it "does not to a remote fetch if the revision is cached locally" do
|
||||
it "does not do a remote fetch if the revision is cached locally" do
|
||||
build_git "foo"
|
||||
|
||||
install_gemfile <<-G
|
||||
|
||||
@@ -358,7 +358,7 @@ RSpec.describe "bundle install with install-time dependencies" do
|
||||
#{lockfile_platforms}
|
||||
|
||||
DEPENDENCIES
|
||||
parallel_tests
|
||||
rubocop
|
||||
#{checksums}
|
||||
BUNDLED WITH
|
||||
#{Bundler::VERSION}
|
||||
|
||||
@@ -46,4 +46,4 @@ DEPENDENCIES
|
||||
tapioca
|
||||
|
||||
BUNDLED WITH
|
||||
4.0.10
|
||||
4.0.11
|
||||
@@ -36,4 +36,4 @@ DEPENDENCIES
|
||||
warbler!
|
||||
|
||||
BUNDLED WITH
|
||||
4.0.10
|
||||
4.0.11
|
||||
@@ -1283,7 +1283,12 @@ end
|
||||
end
|
||||
|
||||
context "is not present" do
|
||||
it "does not change the lock" do
|
||||
# Skipped on ruby-core because `ruby "require 'bundler/setup'"` does not
|
||||
# activate bundler as a gem there, so Source::Metadata falls back to a
|
||||
# synthetic spec whose cache_file does not exist on disk and
|
||||
# LockfileGenerator#bundler_checksum drops the bundler checksum, while
|
||||
# the on-disk lockfile still has it.
|
||||
it "does not change the lock", :ruby_repo do
|
||||
expect { ruby "require 'bundler/setup'" }.not_to change { lockfile }
|
||||
end
|
||||
end
|
||||
@@ -1329,7 +1334,7 @@ end
|
||||
gem "bar", :git => "#{lib_path("bar-1.0")}"
|
||||
G
|
||||
|
||||
bundle :install
|
||||
bundle :install, env: { "BUNDLE_LOCKFILE_CHECKSUMS" => "false" }
|
||||
|
||||
ruby <<-RUBY, artifice: nil
|
||||
require 'bundler/setup'
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
module Spec
|
||||
module Checksums
|
||||
class ChecksumsBuilder
|
||||
attr_reader :bundler_registered
|
||||
|
||||
def initialize(enabled = true, &block)
|
||||
@enabled = enabled
|
||||
@checksums = {}
|
||||
@@ -14,9 +16,11 @@ module Spec
|
||||
@checksums = @checksums.dup
|
||||
end
|
||||
|
||||
def checksum(repo, name, version, platform = Gem::Platform::RUBY)
|
||||
def checksum(repo, name, version, platform = Gem::Platform::RUBY, folder = "gems")
|
||||
@bundler_registered = true if name == "bundler"
|
||||
|
||||
name_tuple = Gem::NameTuple.new(name, version, platform)
|
||||
gem_file = File.join(repo, "gems", "#{name_tuple.full_name}.gem")
|
||||
gem_file = File.join(repo, folder, "#{name_tuple.full_name}.gem")
|
||||
File.open(gem_file, "rb") do |f|
|
||||
register(name_tuple, Bundler::Checksum.from_gem(f, "#{gem_file} (via ChecksumsBuilder#checksum)"))
|
||||
end
|
||||
@@ -50,8 +54,13 @@ module Spec
|
||||
end
|
||||
end
|
||||
|
||||
def checksums_section(enabled = true, &block)
|
||||
ChecksumsBuilder.new(enabled, &block)
|
||||
def checksums_section(enabled = true, bundler_checksum: true, &block)
|
||||
ChecksumsBuilder.new(enabled, &block).tap do |builder|
|
||||
next if builder.bundler_registered || !bundler_checksum
|
||||
|
||||
next if Bundler::VERSION.to_s.end_with?(".dev")
|
||||
builder.checksum(system_gem_path, "bundler", Bundler::VERSION, Gem::Platform::RUBY, "cache")
|
||||
end
|
||||
end
|
||||
|
||||
def checksums_section_when_enabled(target_lockfile = nil, &block)
|
||||
@@ -64,7 +73,7 @@ module Spec
|
||||
end
|
||||
|
||||
def checksum_to_lock(*args)
|
||||
checksums_section do |c|
|
||||
checksums_section(true, bundler_checksum: false) do |c|
|
||||
c.checksum(*args)
|
||||
end.to_s.sub(/^CHECKSUMS\n/, "").strip
|
||||
end
|
||||
|
||||
@@ -148,7 +148,7 @@ class TestGemCommandsPushCommand < Gem::TestCase
|
||||
spec.metadata["allowed_push_host"] = "https://privategemserver.example"
|
||||
end
|
||||
|
||||
@response = "Successfully registered gem: freewill (1.0.0)"
|
||||
@response = "Successfully registered gem: freebird (1.0.1)"
|
||||
@fetcher.data["#{@spec.metadata["allowed_push_host"]}/api/v1/gems"] = HTTPResponseFactory.create(body: @response, code: 200, msg: "OK")
|
||||
@fetcher.data["#{Gem.host}/api/v1/gems"] =
|
||||
["fail", 500, "Internal Server Error"]
|
||||
|
||||
@@ -221,7 +221,7 @@ class TestStubSpecification < Gem::TestCase
|
||||
end
|
||||
|
||||
def stub_with_version
|
||||
spec = File.join @gemhome, "specifications", "stub_e-2.gemspec"
|
||||
spec = File.join @gemhome, "specifications", "stub_v-with-version.gemspec"
|
||||
File.open spec, "w" do |io|
|
||||
io.write <<~STUB
|
||||
# -*- encoding: utf-8 -*-
|
||||
@@ -244,7 +244,7 @@ class TestStubSpecification < Gem::TestCase
|
||||
end
|
||||
|
||||
def stub_without_version
|
||||
spec = File.join @gemhome, "specifications", "stub-2.gemspec"
|
||||
spec = File.join @gemhome, "specifications", "stub_v-without-version.gemspec"
|
||||
File.open spec, "w" do |io|
|
||||
io.write <<~STUB
|
||||
# -*- encoding: utf-8 -*-
|
||||
|
||||
@@ -129,4 +129,4 @@ CHECKSUMS
|
||||
turbo_tests (2.2.5) sha256=3fa31497d12976d11ccc298add29107b92bda94a90d8a0a5783f06f05102509f
|
||||
|
||||
BUNDLED WITH
|
||||
4.0.10
|
||||
4.0.11
|
||||
@@ -156,4 +156,4 @@ CHECKSUMS
|
||||
unicode-emoji (4.2.0) sha256=519e69150f75652e40bf736106cfbc8f0f73aa3fb6a65afe62fefa7f80b0f80f
|
||||
|
||||
BUNDLED WITH
|
||||
4.0.10
|
||||
4.0.11
|
||||
@@ -176,4 +176,4 @@ CHECKSUMS
|
||||
unicode-emoji (4.2.0) sha256=519e69150f75652e40bf736106cfbc8f0f73aa3fb6a65afe62fefa7f80b0f80f
|
||||
|
||||
BUNDLED WITH
|
||||
4.0.10
|
||||
4.0.11
|
||||
@@ -103,4 +103,4 @@ CHECKSUMS
|
||||
tilt (2.6.1) sha256=35a99bba2adf7c1e362f5b48f9b581cce4edfba98117e34696dde6d308d84770
|
||||
|
||||
BUNDLED WITH
|
||||
4.0.10
|
||||
4.0.11
|
||||
Reference in new issue
Block a user