Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
560de05
[ruby/rubygems] Bump the rb-sys group across 2 directories with 1 update
dependabot[bot] May 1, 2026
2c5da6f
[ruby/rubygems] Remove cygwin from WIN_PATTERNS
fd00 May 4, 2026
4758d1b
Suppress a warning
znz May 7, 2026
ff7ed1b
[ruby/rubygems] Deprecate parsing non-lockfile content in LockfileParser
kurotaky Apr 23, 2026
f7478ab
[ruby/rubygems] Fix RuboCop Layout/MultilineOperationIndentation offense
kurotaky May 1, 2026
a42a6bc
[ruby/rubygems] Add Bundler::Override value object
hsbt May 1, 2026
bb1b229
[ruby/rubygems] Add overrides attribute to Bundler::Definition
hsbt May 1, 2026
199af7f
[ruby/rubygems] Add `override` DSL method to Bundler::Dsl
hsbt May 1, 2026
7a111be
[ruby/rubygems] Preserve != exclusions in Override :ignore_upper
hsbt May 1, 2026
77c7e15
[ruby/rubygems] Reject `override :all, version:` in Bundler::Dsl
hsbt May 1, 2026
a093612
[ruby/rubygems] Validate override target, field, and operation types
hsbt May 1, 2026
22fb622
[ruby/rubygems] Reject duplicate target+field in override DSL
hsbt May 1, 2026
464e212
[ruby/rubygems] Apply override version operations in Resolver
hsbt May 1, 2026
2da7365
[ruby/rubygems] Apply override at Definition level for direct depende…
hsbt May 1, 2026
41a558a
[ruby/rubygems] Mark overridden gems as changed against the existing …
hsbt May 1, 2026
d763aec
[ruby/rubygems] Cover prerelease pin via override
hsbt May 1, 2026
b5f31bb
[ruby/rubygems] Add :ignore_upper integration coverage
hsbt May 1, 2026
1fa4831
[ruby/rubygems] Add version: nil integration coverage
hsbt May 1, 2026
ddabda7
[ruby/rubygems] Document the override DSL in gemfile.5.ronn
hsbt May 1, 2026
9cc8943
[ruby/rubygems] Mark transitive-only overrides as changed against the…
hsbt May 1, 2026
e8a09f9
Remove unused variable warning in imemo_fields_free
etiennebarrie May 6, 2026
4ed7fa5
fix: honor --disable-multiarch in configure
fd00 May 4, 2026
18ae8d6
dir.c: fix dirent leak on glob_opendir realloc failure
May 5, 2026
58ae5ea
Split test_freeze_inside_sort! and reduce comparator count
sampokuokkanen May 7, 2026
b6e4fa7
[ruby/rubygems] Use Pathname#absolute?
nobu May 7, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -3580,7 +3580,8 @@ AS_CASE(["$target_os"],

AC_ARG_ENABLE(multiarch,
AS_HELP_STRING([--enable-multiarch], [enable multiarch compatible directories]),
[multiarch=], [unset multiarch])
[AS_CASE([$enableval], [no], [unset multiarch], [multiarch=])],
[unset multiarch])
AS_IF([test ${multiarch+set}], [
AC_DEFINE(ENABLE_MULTIARCH)
])
Expand Down
4 changes: 3 additions & 1 deletion dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -2803,8 +2803,10 @@ glob_opendir(ruby_glob_entries_t *ent, DIR *dirp, int flags, rb_encoding *enc)
}
if (count >= capacity) {
capacity += 256;
if (!(newp = GLOB_REALLOC_N(ent->sort.entries, capacity)))
if (!(newp = GLOB_REALLOC_N(ent->sort.entries, capacity))) {
GLOB_FREE(rdp);
goto nomem;
}
ent->sort.entries = newp;
}
ent->sort.entries[count++] = rdp;
Expand Down
3 changes: 1 addition & 2 deletions imemo.c
Original file line number Diff line number Diff line change
Expand Up @@ -560,8 +560,7 @@ static inline void
imemo_fields_free(struct rb_fields *fields)
{
if (FL_TEST_RAW((VALUE)fields, OBJ_FIELD_HEAP)) {
shape_id_t shape_id = RBASIC_SHAPE_ID((VALUE)fields);
RUBY_ASSERT(rb_shape_complex_p(shape_id));
RUBY_ASSERT(rb_shape_complex_p(RBASIC_SHAPE_ID((VALUE)fields)));
st_free_table(fields->as.complex.table);
}
}
Expand Down
1 change: 1 addition & 0 deletions lib/bundler.rb
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ module Bundler
autoload :MatchRemoteMetadata, File.expand_path("bundler/match_remote_metadata", __dir__)
autoload :Materialization, File.expand_path("bundler/materialization", __dir__)
autoload :NULL, File.expand_path("bundler/constants", __dir__)
autoload :Override, File.expand_path("bundler/override", __dir__)
autoload :ProcessLock, File.expand_path("bundler/process_lock", __dir__)
autoload :RemoteSpecification, File.expand_path("bundler/remote_specification", __dir__)
autoload :Resolver, File.expand_path("bundler/resolver", __dir__)
Expand Down
41 changes: 36 additions & 5 deletions lib/bundler/definition.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,14 @@ class << self
attr_accessor :no_lock
end

attr_writer :lockfile
attr_writer :lockfile, :overrides

attr_reader(
:dependencies,
:locked_checksums,
:locked_deps,
:locked_gems,
:overrides,
:platforms,
:ruby_version,
:lockfile,
Expand Down Expand Up @@ -58,7 +59,7 @@ def self.build(gemfile, lockfile, unlock)
# to be updated or true if all gems should be updated
# @param ruby_version [Bundler::RubyVersion, nil] Requested Ruby Version
# @param optional_groups [Array(String)] A list of optional groups
def initialize(lockfile, dependencies, sources, unlock, ruby_version = nil, optional_groups = [], gemfiles = [])
def initialize(lockfile, dependencies, sources, unlock, ruby_version = nil, optional_groups = [], gemfiles = [], overrides = [])
unlock ||= {}

if unlock == true
Expand Down Expand Up @@ -88,6 +89,7 @@ def initialize(lockfile, dependencies, sources, unlock, ruby_version = nil, opti
@specs = nil
@ruby_version = ruby_version
@gemfiles = gemfiles
@overrides = overrides

@lockfile = lockfile
@lockfile_contents = String.new
Expand Down Expand Up @@ -633,7 +635,20 @@ def resolver
end

def expanded_dependencies
dependencies_with_bundler + metadata_dependencies
apply_overrides_to(dependencies_with_bundler) + metadata_dependencies
end

def apply_overrides_to(deps)
return deps if @overrides.empty?
deps.map {|dep| apply_override_to(dep) }
end

def apply_override_to(dep)
override = @overrides.find {|o| o.target == dep.name && o.field == :version }
return dep unless override
new_dep = dep.dup
new_dep.instance_variable_set(:@requirement, override.apply_to(dep.requirement))
new_dep
end

def dependencies_with_bundler
Expand Down Expand Up @@ -1029,7 +1044,7 @@ def converge_dependencies
@locked_specs.delete(locked_specs.select {|s| s.source != dep.source })
end

unless dep.matches_spec?(locked_specs.first)
unless apply_override_to(dep).matches_spec?(locked_specs.first)
@gems_to_unlock << name
dep_changed = true
end
Expand All @@ -1039,9 +1054,25 @@ def converge_dependencies
@changed_dependencies << name if dep_changed
end

converge_overrides_outside_dependencies

@changed_dependencies.any?
end

def converge_overrides_outside_dependencies
@overrides.each do |override|
next unless override.target.is_a?(String)

name = override.target
next if @changed_dependencies.include?(name)
next if @dependencies.any? {|d| d.name == name }
next if @originally_locked_specs[name].empty?

@gems_to_unlock << name
@changed_dependencies << name
end
end

# Remove elements from the locked specs that are expired. This will most
# commonly happen if the Gemfile has changed since the lockfile was last
# generated
Expand Down Expand Up @@ -1273,7 +1304,7 @@ def unlocked_resolution_base

def new_resolution_base(last_resolve:, unlock:)
new_resolution_platforms = @current_platform_missing ? @new_platforms + [Bundler.local_platform] : @new_platforms
Resolver::Base.new(source_requirements, expanded_dependencies, last_resolve, @platforms, locked_specs: @originally_locked_specs, unlock: unlock, prerelease: gem_version_promoter.pre?, prefer_local: @prefer_local, new_platforms: new_resolution_platforms)
Resolver::Base.new(source_requirements, expanded_dependencies, last_resolve, @platforms, locked_specs: @originally_locked_specs, unlock: unlock, prerelease: gem_version_promoter.pre?, prefer_local: @prefer_local, new_platforms: new_resolution_platforms, overrides: @overrides)
end

def new_resolver(base)
Expand Down
54 changes: 52 additions & 2 deletions lib/bundler/dsl.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ def self.evaluate(gemfile, lockfile, unlock)
GITHUB_PULL_REQUEST_URL = %r{\Ahttps://github\.com/([A-Za-z0-9_\-\.]+/[A-Za-z0-9_\-\.]+)/pull/(\d+)\z}
GITLAB_MERGE_REQUEST_URL = %r{\Ahttps://gitlab\.com/([A-Za-z0-9_\-\./]+)/-/merge_requests/(\d+)\z}

attr_reader :gemspecs, :gemfile
attr_reader :gemspecs, :gemfile, :overrides
attr_accessor :dependencies

def initialize
Expand All @@ -40,6 +40,7 @@ def initialize
@gemfile = nil
@gemfiles = []
@lockfile = nil
@overrides = []
add_git_sources
end

Expand Down Expand Up @@ -184,10 +185,31 @@ def github(repo, options = {})
with_source(git_source) { yield }
end

SUPPORTED_OVERRIDE_FIELDS = [:version].freeze
SUPPORTED_OVERRIDE_SYMBOL_OPERATIONS = [:ignore_upper].freeze

def override(target, **operations)
validate_override_target!(target)

if target == :all && operations.key?(:version)
raise ArgumentError, "`override :all, version:` is not allowed; version requirements are per-gem"
end

operations.each do |field, operation|
validate_override_field!(field)
validate_override_operation!(operation)
validate_override_uniqueness!(target, field)
end

operations.each do |field, operation|
@overrides << Override.new(target, field, operation)
end
end

def to_definition(lockfile, unlock)
check_primary_source_safety
lockfile = @lockfile unless @lockfile.nil?
Definition.new(lockfile, @dependencies, @sources, unlock, @ruby_version, @optional_groups, @gemfiles)
Definition.new(lockfile, @dependencies, @sources, unlock, @ruby_version, @optional_groups, @gemfiles, @overrides)
end

def group(*args, &blk)
Expand Down Expand Up @@ -244,6 +266,34 @@ def check_primary_source_safety

private

def validate_override_target!(target)
return if target == :all
return if target.is_a?(String)
raise ArgumentError, "override target must be :all or a gem name string, got #{target.inspect}"
end

def validate_override_field!(field)
return if SUPPORTED_OVERRIDE_FIELDS.include?(field)
raise ArgumentError, "unsupported override field `#{field}:`; only `version:` is currently supported"
end

def validate_override_operation!(operation)
case operation
when String, nil
# ok
when Symbol
return if SUPPORTED_OVERRIDE_SYMBOL_OPERATIONS.include?(operation)
raise ArgumentError, "unsupported override operation: #{operation.inspect}"
else
raise ArgumentError, "override operation must be a String, Symbol, or nil, got #{operation.inspect}"
end
end

def validate_override_uniqueness!(target, field)
return unless @overrides.any? {|o| o.target == target && o.field == field }
raise ArgumentError, "duplicate override for #{target.inspect} `#{field}:`"
end

def add_dependency(name, version = nil, options = {})
options["gemfile"] = @gemfile
options["source"] ||= @source
Expand Down
15 changes: 15 additions & 0 deletions lib/bundler/lockfile_parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,17 @@ def initialize(lockfile, strict: false)
"Run `git checkout HEAD -- #{@lockfile_path}` first to get a clean lock."
end

@valid = lockfile.strip.empty? ||
lockfile.split(/(?:\r?\n)+/).any? {|l| KNOWN_SECTIONS.include?(l) }

unless @valid
SharedHelpers.feature_deprecated!(
"Your #{@lockfile_path} does not appear to be a valid lockfile. " \
"Run `rm #{@lockfile_path}` and then `bundle install` to generate a new lockfile. " \
"This will raise a LockfileError in a future version of Bundler."
)
end

lockfile.split(/((?:\r?\n)+)/) do |line|
# split alternates between the line and the following whitespace
next @pos.advance!(line) if line.match?(/^\s*$/)
Expand Down Expand Up @@ -164,6 +175,10 @@ def may_include_redundant_platform_specific_gems?
bundler_version.nil? || bundler_version < Gem::Version.new("1.16.2")
end

def valid?
@valid
end

private

TYPES = {
Expand Down
2 changes: 1 addition & 1 deletion lib/bundler/man/bundle-add.1
Original file line number Diff line number Diff line change
@@ -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" "April 2026" ""
.TH "BUNDLE\-ADD" "1" "May 2026" ""
.SH "NAME"
\fBbundle\-add\fR \- Add gem to the Gemfile and run bundle install
.SH "SYNOPSIS"
Expand Down
2 changes: 1 addition & 1 deletion lib/bundler/man/bundle-binstubs.1
Original file line number Diff line number Diff line change
@@ -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" "April 2026" ""
.TH "BUNDLE\-BINSTUBS" "1" "May 2026" ""
.SH "NAME"
\fBbundle\-binstubs\fR \- Install the binstubs of the listed gems
.SH "SYNOPSIS"
Expand Down
2 changes: 1 addition & 1 deletion lib/bundler/man/bundle-cache.1
Original file line number Diff line number Diff line change
@@ -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" "April 2026" ""
.TH "BUNDLE\-CACHE" "1" "May 2026" ""
.SH "NAME"
\fBbundle\-cache\fR \- Package your needed \fB\.gem\fR files into your application
.SH "SYNOPSIS"
Expand Down
2 changes: 1 addition & 1 deletion lib/bundler/man/bundle-check.1
Original file line number Diff line number Diff line change
@@ -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" "April 2026" ""
.TH "BUNDLE\-CHECK" "1" "May 2026" ""
.SH "NAME"
\fBbundle\-check\fR \- Verifies if dependencies are satisfied by installed gems
.SH "SYNOPSIS"
Expand Down
2 changes: 1 addition & 1 deletion lib/bundler/man/bundle-clean.1
Original file line number Diff line number Diff line change
@@ -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" "April 2026" ""
.TH "BUNDLE\-CLEAN" "1" "May 2026" ""
.SH "NAME"
\fBbundle\-clean\fR \- Cleans up unused gems in your bundler directory
.SH "SYNOPSIS"
Expand Down
2 changes: 1 addition & 1 deletion lib/bundler/man/bundle-config.1
Original file line number Diff line number Diff line change
@@ -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" "April 2026" ""
.TH "BUNDLE\-CONFIG" "1" "May 2026" ""
.SH "NAME"
\fBbundle\-config\fR \- Set bundler configuration options
.SH "SYNOPSIS"
Expand Down
2 changes: 1 addition & 1 deletion lib/bundler/man/bundle-console.1
Original file line number Diff line number Diff line change
@@ -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" "April 2026" ""
.TH "BUNDLE\-CONSOLE" "1" "May 2026" ""
.SH "NAME"
\fBbundle\-console\fR \- Open an IRB session with the bundle pre\-loaded
.SH "SYNOPSIS"
Expand Down
2 changes: 1 addition & 1 deletion lib/bundler/man/bundle-doctor.1
Original file line number Diff line number Diff line change
@@ -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" "April 2026" ""
.TH "BUNDLE\-DOCTOR" "1" "May 2026" ""
.SH "NAME"
\fBbundle\-doctor\fR \- Checks the bundle for common problems
.SH "SYNOPSIS"
Expand Down
2 changes: 1 addition & 1 deletion lib/bundler/man/bundle-env.1
Original file line number Diff line number Diff line change
@@ -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" "April 2026" ""
.TH "BUNDLE\-ENV" "1" "May 2026" ""
.SH "NAME"
\fBbundle\-env\fR \- Print information about the environment Bundler is running under
.SH "SYNOPSIS"
Expand Down
2 changes: 1 addition & 1 deletion lib/bundler/man/bundle-exec.1
Original file line number Diff line number Diff line change
@@ -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" "April 2026" ""
.TH "BUNDLE\-EXEC" "1" "May 2026" ""
.SH "NAME"
\fBbundle\-exec\fR \- Execute a command in the context of the bundle
.SH "SYNOPSIS"
Expand Down
2 changes: 1 addition & 1 deletion lib/bundler/man/bundle-fund.1
Original file line number Diff line number Diff line change
@@ -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" "April 2026" ""
.TH "BUNDLE\-FUND" "1" "May 2026" ""
.SH "NAME"
\fBbundle\-fund\fR \- Lists information about gems seeking funding assistance
.SH "SYNOPSIS"
Expand Down
2 changes: 1 addition & 1 deletion lib/bundler/man/bundle-gem.1
Original file line number Diff line number Diff line change
@@ -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" "April 2026" ""
.TH "BUNDLE\-GEM" "1" "May 2026" ""
.SH "NAME"
\fBbundle\-gem\fR \- Generate a project skeleton for creating a rubygem
.SH "SYNOPSIS"
Expand Down
2 changes: 1 addition & 1 deletion lib/bundler/man/bundle-help.1
Original file line number Diff line number Diff line change
@@ -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" "April 2026" ""
.TH "BUNDLE\-HELP" "1" "May 2026" ""
.SH "NAME"
\fBbundle\-help\fR \- Displays detailed help for each subcommand
.SH "SYNOPSIS"
Expand Down
2 changes: 1 addition & 1 deletion lib/bundler/man/bundle-info.1
Original file line number Diff line number Diff line change
@@ -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" "April 2026" ""
.TH "BUNDLE\-INFO" "1" "May 2026" ""
.SH "NAME"
\fBbundle\-info\fR \- Show information for the given gem in your bundle
.SH "SYNOPSIS"
Expand Down
2 changes: 1 addition & 1 deletion lib/bundler/man/bundle-init.1
Original file line number Diff line number Diff line change
@@ -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" "April 2026" ""
.TH "BUNDLE\-INIT" "1" "May 2026" ""
.SH "NAME"
\fBbundle\-init\fR \- Generates a Gemfile into the current working directory
.SH "SYNOPSIS"
Expand Down
2 changes: 1 addition & 1 deletion lib/bundler/man/bundle-install.1
Original file line number Diff line number Diff line change
@@ -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" "April 2026" ""
.TH "BUNDLE\-INSTALL" "1" "May 2026" ""
.SH "NAME"
\fBbundle\-install\fR \- Install the dependencies specified in your Gemfile
.SH "SYNOPSIS"
Expand Down
2 changes: 1 addition & 1 deletion lib/bundler/man/bundle-issue.1
Original file line number Diff line number Diff line change
@@ -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" "April 2026" ""
.TH "BUNDLE\-ISSUE" "1" "May 2026" ""
.SH "NAME"
\fBbundle\-issue\fR \- Get help reporting Bundler issues
.SH "SYNOPSIS"
Expand Down
2 changes: 1 addition & 1 deletion lib/bundler/man/bundle-licenses.1
Original file line number Diff line number Diff line change
@@ -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" "April 2026" ""
.TH "BUNDLE\-LICENSES" "1" "May 2026" ""
.SH "NAME"
\fBbundle\-licenses\fR \- Print the license of all gems in the bundle
.SH "SYNOPSIS"
Expand Down
Loading