bundler 4.0.22 → 4.1.0.beta2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/{lib/bundler/vendor/connection_pool/LICENSE → MIT.txt} +8 -6
- data/bundler.gemspec +23 -6
- data/lib/bundler/build_metadata.rb +2 -2
- data/lib/bundler/checksum.rb +40 -25
- data/lib/bundler/ci_detector.rb +1 -1
- data/lib/bundler/cli/add.rb +3 -4
- data/lib/bundler/cli/cache.rb +4 -0
- data/lib/bundler/cli/clean.rb +5 -0
- data/lib/bundler/cli/common.rb +41 -1
- data/lib/bundler/cli/config.rb +4 -2
- data/lib/bundler/cli/doctor/ssl.rb +4 -8
- data/lib/bundler/cli/gem.rb +0 -17
- data/lib/bundler/cli/info.rb +1 -1
- data/lib/bundler/cli/install.rb +4 -5
- data/lib/bundler/cli/lock.rb +15 -5
- data/lib/bundler/cli/open.rb +7 -1
- data/lib/bundler/cli/outdated.rb +16 -13
- data/lib/bundler/cli/pristine.rb +2 -1
- data/lib/bundler/cli/show.rb +5 -1
- data/lib/bundler/cli/update.rb +20 -11
- data/lib/bundler/cli.rb +15 -9
- data/lib/bundler/constants.rb +1 -1
- data/lib/bundler/definition.rb +102 -15
- data/lib/bundler/dependency.rb +4 -0
- data/lib/bundler/dsl.rb +137 -13
- data/lib/bundler/endpoint_specification.rb +51 -14
- data/lib/bundler/env.rb +7 -24
- data/lib/bundler/errors.rb +34 -5
- data/lib/bundler/fetcher/compact_index.rb +14 -5
- data/lib/bundler/fetcher/connection_pools.rb +150 -0
- data/lib/bundler/fetcher/downloader.rb +35 -16
- data/lib/bundler/fetcher.rb +8 -47
- data/lib/bundler/gem_helper.rb +1 -1
- data/lib/bundler/injector.rb +3 -3
- data/lib/bundler/inline.rb +44 -4
- data/lib/bundler/installer/parallel_installer.rb +27 -31
- data/lib/bundler/installer.rb +21 -7
- data/lib/bundler/lazy_specification.rb +45 -18
- data/lib/bundler/lockfile_generator.rb +24 -2
- data/lib/bundler/lockfile_parser.rb +44 -6
- data/lib/bundler/man/bundle-add.1 +7 -4
- data/lib/bundler/man/bundle-add.1.ronn +8 -4
- data/lib/bundler/man/bundle-binstubs.1 +1 -1
- data/lib/bundler/man/bundle-cache.1 +2 -2
- data/lib/bundler/man/bundle-cache.1.ronn +2 -2
- data/lib/bundler/man/bundle-check.1 +1 -1
- data/lib/bundler/man/bundle-clean.1 +1 -1
- data/lib/bundler/man/bundle-config.1 +38 -6
- data/lib/bundler/man/bundle-config.1.ronn +143 -10
- data/lib/bundler/man/bundle-console.1 +1 -1
- data/lib/bundler/man/bundle-doctor.1 +1 -1
- data/lib/bundler/man/bundle-env.1 +1 -1
- data/lib/bundler/man/bundle-exec.1 +1 -1
- data/lib/bundler/man/bundle-fund.1 +1 -1
- data/lib/bundler/man/bundle-gem.1 +1 -1
- data/lib/bundler/man/bundle-help.1 +1 -1
- data/lib/bundler/man/bundle-info.1 +5 -2
- data/lib/bundler/man/bundle-info.1.ronn +4 -0
- data/lib/bundler/man/bundle-init.1 +1 -1
- data/lib/bundler/man/bundle-install.1 +2 -2
- data/lib/bundler/man/bundle-install.1.ronn +4 -4
- data/lib/bundler/man/bundle-issue.1 +1 -1
- data/lib/bundler/man/bundle-licenses.1 +1 -1
- data/lib/bundler/man/bundle-list.1 +1 -1
- data/lib/bundler/man/bundle-lock.1 +2 -2
- data/lib/bundler/man/bundle-lock.1.ronn +3 -2
- data/lib/bundler/man/bundle-open.1 +5 -2
- data/lib/bundler/man/bundle-open.1.ronn +4 -1
- data/lib/bundler/man/bundle-outdated.1 +1 -1
- data/lib/bundler/man/bundle-platform.1 +1 -1
- data/lib/bundler/man/bundle-plugin.1 +1 -1
- data/lib/bundler/man/bundle-pristine.1 +1 -1
- data/lib/bundler/man/bundle-remove.1 +1 -1
- data/lib/bundler/man/bundle-show.1 +5 -2
- data/lib/bundler/man/bundle-show.1.ronn +4 -0
- data/lib/bundler/man/bundle-update.1 +2 -2
- data/lib/bundler/man/bundle-update.1.ronn +2 -2
- data/lib/bundler/man/bundle-version.1 +1 -1
- data/lib/bundler/man/bundle.1 +1 -1
- data/lib/bundler/man/gemfile.5 +77 -1
- data/lib/bundler/man/gemfile.5.ronn +104 -0
- data/lib/bundler/match_metadata.rb +20 -0
- data/lib/bundler/match_platform.rb +25 -2
- data/lib/bundler/match_remote_metadata.rb +21 -6
- data/lib/bundler/materialization.rb +5 -2
- data/lib/bundler/override.rb +97 -0
- data/lib/bundler/plugin/dsl.rb +3 -5
- data/lib/bundler/plugin/events.rb +55 -13
- data/lib/bundler/plugin/index.rb +87 -11
- data/lib/bundler/plugin/installer/path.rb +1 -1
- data/lib/bundler/plugin/installer.rb +13 -5
- data/lib/bundler/plugin.rb +58 -30
- data/lib/bundler/remote_specification.rb +6 -3
- data/lib/bundler/resolver/base.rb +2 -1
- data/lib/bundler/resolver/incompatibility.rb +1 -1
- data/lib/bundler/resolver.rb +97 -23
- data/lib/bundler/ruby_version.rb +0 -2
- data/lib/bundler/rubygems_ext.rb +71 -1
- data/lib/bundler/rubygems_gem_installer.rb +41 -2
- data/lib/bundler/rubygems_integration.rb +7 -2
- data/lib/bundler/runtime.rb +69 -2
- data/lib/bundler/settings.rb +383 -56
- data/lib/bundler/shared_helpers.rb +2 -1
- data/lib/bundler/source/git/git_proxy.rb +31 -2
- data/lib/bundler/source/git.rb +49 -13
- data/lib/bundler/source/path/installer.rb +1 -1
- data/lib/bundler/source/rubygems/remote.rb +10 -5
- data/lib/bundler/source/rubygems.rb +48 -12
- data/lib/bundler/source/rubygems_aggregate.rb +1 -1
- data/lib/bundler/source_map.rb +7 -3
- data/lib/bundler/spec_set.rb +23 -7
- data/lib/bundler/stub_specification.rb +2 -1
- data/lib/bundler/templates/newgem/Gemfile.tt +4 -4
- data/lib/bundler/templates/newgem/newgem.gemspec.tt +3 -3
- data/lib/bundler/templates/newgem/spec/newgem_spec.rb.tt +1 -1
- data/lib/bundler/templates/newgem/test/minitest/test_newgem.rb.tt +1 -1
- data/lib/bundler/ui/shell.rb +0 -4
- data/lib/bundler/ui/silent.rb +0 -4
- data/lib/bundler/vendor/thor/lib/thor/actions/inject_into_file.rb +35 -2
- data/lib/bundler/vendor/thor/lib/thor/base.rb +2 -1
- data/lib/bundler/vendor/thor/lib/thor/shell/basic.rb +14 -6
- data/lib/bundler/vendor/thor/lib/thor/shell/color.rb +2 -0
- data/lib/bundler/vendor/thor/lib/thor/version.rb +1 -1
- data/lib/bundler/vendor/thor/lib/thor.rb +34 -1
- data/lib/bundler/vendored_pub_grub.rb +5 -2
- data/lib/bundler/vendored_securerandom.rb +11 -8
- data/lib/bundler/vendored_uri.rb +14 -14
- data/lib/bundler/version.rb +1 -1
- data/lib/bundler/worker.rb +3 -2
- data/lib/bundler.rb +1 -1
- data/lib/rubygems/compact_index_client/cache.rb +122 -0
- data/lib/rubygems/compact_index_client/cache_file.rb +147 -0
- data/lib/rubygems/compact_index_client/http_fetcher.rb +90 -0
- data/lib/rubygems/compact_index_client/parser.rb +90 -0
- data/lib/rubygems/compact_index_client/updater.rb +113 -0
- data/lib/rubygems/compact_index_client.rb +111 -0
- data/lib/rubygems/cooldown_settings.rb +57 -0
- data/lib/rubygems/credential_store/native/linux.rb +97 -0
- data/lib/rubygems/credential_store/native/macos.rb +88 -0
- data/lib/rubygems/credential_store/native/windows.rb +130 -0
- data/lib/rubygems/credential_store.rb +332 -0
- data/lib/{bundler → rubygems}/vendor/pub_grub/lib/pub_grub/assignment.rb +1 -1
- data/lib/{bundler → rubygems}/vendor/pub_grub/lib/pub_grub/basic_package_source.rb +7 -7
- data/lib/{bundler → rubygems}/vendor/pub_grub/lib/pub_grub/failure_writer.rb +1 -1
- data/lib/{bundler → rubygems}/vendor/pub_grub/lib/pub_grub/incompatibility.rb +4 -4
- data/lib/{bundler → rubygems}/vendor/pub_grub/lib/pub_grub/package.rb +1 -1
- data/lib/{bundler → rubygems}/vendor/pub_grub/lib/pub_grub/partial_solution.rb +1 -1
- data/lib/{bundler → rubygems}/vendor/pub_grub/lib/pub_grub/rubygems.rb +3 -3
- data/lib/{bundler → rubygems}/vendor/pub_grub/lib/pub_grub/solve_failure.rb +1 -1
- data/lib/{bundler → rubygems}/vendor/pub_grub/lib/pub_grub/static_package_source.rb +3 -3
- data/lib/{bundler → rubygems}/vendor/pub_grub/lib/pub_grub/strategy.rb +2 -2
- data/lib/{bundler → rubygems}/vendor/pub_grub/lib/pub_grub/term.rb +1 -1
- data/lib/{bundler → rubygems}/vendor/pub_grub/lib/pub_grub/version.rb +1 -1
- data/lib/{bundler → rubygems}/vendor/pub_grub/lib/pub_grub/version_constraint.rb +3 -3
- data/lib/{bundler → rubygems}/vendor/pub_grub/lib/pub_grub/version_range.rb +1 -1
- data/lib/{bundler → rubygems}/vendor/pub_grub/lib/pub_grub/version_solver.rb +2 -2
- data/lib/{bundler → rubygems}/vendor/pub_grub/lib/pub_grub/version_union.rb +1 -1
- data/lib/rubygems/vendor/pub_grub/lib/pub_grub.rb +57 -0
- data/lib/{bundler → rubygems}/vendor/securerandom/lib/securerandom.rb +10 -6
- data/lib/{bundler → rubygems}/vendor/uri/lib/uri/common.rb +119 -119
- data/lib/{bundler → rubygems}/vendor/uri/lib/uri/file.rb +13 -13
- data/lib/{bundler → rubygems}/vendor/uri/lib/uri/ftp.rb +24 -24
- data/lib/{bundler → rubygems}/vendor/uri/lib/uri/generic.rb +132 -132
- data/lib/{bundler → rubygems}/vendor/uri/lib/uri/http.rb +18 -18
- data/lib/{bundler → rubygems}/vendor/uri/lib/uri/https.rb +4 -4
- data/lib/{bundler → rubygems}/vendor/uri/lib/uri/ldap.rb +14 -14
- data/lib/{bundler → rubygems}/vendor/uri/lib/uri/ldaps.rb +4 -4
- data/lib/{bundler → rubygems}/vendor/uri/lib/uri/mailto.rb +21 -21
- data/lib/{bundler → rubygems}/vendor/uri/lib/uri/rfc2396_parser.rb +39 -39
- data/lib/{bundler → rubygems}/vendor/uri/lib/uri/rfc3986_parser.rb +14 -14
- data/lib/{bundler → rubygems}/vendor/uri/lib/uri/version.rb +1 -1
- data/lib/{bundler → rubygems}/vendor/uri/lib/uri/ws.rb +12 -12
- data/lib/{bundler → rubygems}/vendor/uri/lib/uri/wss.rb +4 -4
- data/lib/{bundler → rubygems}/vendor/uri/lib/uri.rb +35 -31
- data/lib/rubygems/yaml_serializer.rb +880 -0
- metadata +391 -381
- data/CHANGELOG.md +0 -5801
- data/LICENSE.md +0 -22
- data/README.md +0 -58
- data/lib/bundler/compact_index_client/cache.rb +0 -107
- data/lib/bundler/compact_index_client/cache_file.rb +0 -148
- data/lib/bundler/compact_index_client/parser.rb +0 -87
- data/lib/bundler/compact_index_client/updater.rb +0 -105
- data/lib/bundler/compact_index_client.rb +0 -92
- data/lib/bundler/vendor/connection_pool/lib/connection_pool/timed_stack.rb +0 -227
- data/lib/bundler/vendor/connection_pool/lib/connection_pool/version.rb +0 -3
- data/lib/bundler/vendor/connection_pool/lib/connection_pool/wrapper.rb +0 -56
- data/lib/bundler/vendor/connection_pool/lib/connection_pool.rb +0 -230
- data/lib/bundler/vendor/net-http-persistent/README.rdoc +0 -82
- data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/connection.rb +0 -41
- data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/pool.rb +0 -65
- data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/timed_stack_multi.rb +0 -80
- data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb +0 -1153
- data/lib/bundler/vendor/pub_grub/lib/pub_grub.rb +0 -31
- data/lib/bundler/vendored_persistent.rb +0 -11
- data/lib/bundler/yaml_serializer.rb +0 -98
- /data/lib/{bundler → rubygems}/vendor/pub_grub/LICENSE.txt +0 -0
- /data/lib/{bundler → rubygems}/vendor/securerandom/COPYING +0 -0
- /data/lib/{bundler → rubygems}/vendor/uri/COPYING +0 -0
data/lib/bundler/inline.rb
CHANGED
|
@@ -62,13 +62,52 @@ def gemfile(force_latest_compatible = false, options = {}, &gemfile)
|
|
|
62
62
|
definition.validate_runtime!
|
|
63
63
|
|
|
64
64
|
if force_latest_compatible || definition.missing_specs?
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
65
|
+
do_install = -> do
|
|
66
|
+
Bundler.settings.temporary(inline: true, no_install: false) do
|
|
67
|
+
installer = Bundler::Installer.install(Bundler.root, definition, system: true)
|
|
68
|
+
installer.post_install_messages.each do |name, message|
|
|
69
|
+
Bundler.ui.info "Post-install message from #{name}:\n#{message}"
|
|
70
|
+
end
|
|
69
71
|
end
|
|
70
72
|
end
|
|
73
|
+
|
|
74
|
+
# When possible we do the install in a subprocess because to install
|
|
75
|
+
# gems we need to require some default gems like `securerandom` etc
|
|
76
|
+
# which may later conflict with the Gemfile requirements.
|
|
77
|
+
installed_in_fork = false
|
|
78
|
+
if Process.respond_to?(:fork)
|
|
79
|
+
Gem.load_yaml # Avoid NameError on Ruby 3.2's safe_yaml.rb after Gem::Specification.reset
|
|
80
|
+
_, status = Process.waitpid2(Process.fork do
|
|
81
|
+
$VERBOSE = nil
|
|
82
|
+
do_install.call end)
|
|
83
|
+
exit(status.exitstatus || status.to_i) unless status.success?
|
|
84
|
+
|
|
85
|
+
installed_in_fork = true
|
|
86
|
+
|
|
87
|
+
Bundler.reset!
|
|
88
|
+
Gem::Specification.reset
|
|
89
|
+
Bundler.instance_variable_set(:@bundle_path, Pathname.new(Gem.dir))
|
|
90
|
+
|
|
91
|
+
builder = Bundler::Dsl.new
|
|
92
|
+
builder.instance_eval(&gemfile)
|
|
93
|
+
builder.check_primary_source_safety
|
|
94
|
+
|
|
95
|
+
definition = builder.to_definition(nil, true)
|
|
96
|
+
definition.validate_runtime!
|
|
97
|
+
else
|
|
98
|
+
do_install.call
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
configure_forked_definition = ->(d) do
|
|
103
|
+
d.sources.rubygems_sources.each(&:remote!)
|
|
104
|
+
d.sources.git_sources.each do |source|
|
|
105
|
+
source.cached!
|
|
106
|
+
source.instance_variable_set(:@copied, true)
|
|
107
|
+
end
|
|
108
|
+
def d.lock(*); end
|
|
71
109
|
end
|
|
110
|
+
configure_forked_definition.call(definition) if installed_in_fork
|
|
72
111
|
|
|
73
112
|
begin
|
|
74
113
|
runtime = Bundler::Runtime.new(nil, definition).setup
|
|
@@ -84,6 +123,7 @@ def gemfile(force_latest_compatible = false, options = {}, &gemfile)
|
|
|
84
123
|
builder.dependencies.delete_if {|d| d.name == name }
|
|
85
124
|
builder.instance_eval { gem name, activated_version }
|
|
86
125
|
definition = builder.to_definition(nil, true)
|
|
126
|
+
configure_forked_definition.call(definition) if installed_in_fork
|
|
87
127
|
|
|
88
128
|
retry
|
|
89
129
|
end
|
|
@@ -20,10 +20,6 @@ module Bundler
|
|
|
20
20
|
state == :installed
|
|
21
21
|
end
|
|
22
22
|
|
|
23
|
-
def enqueued?
|
|
24
|
-
state == :enqueued
|
|
25
|
-
end
|
|
26
|
-
|
|
27
23
|
def enqueue_with_priority?
|
|
28
24
|
state == :installable && spec.extensions.any?
|
|
29
25
|
end
|
|
@@ -73,7 +69,8 @@ module Bundler
|
|
|
73
69
|
@specs = all_specs.map {|s| SpecInstallation.new(s) }
|
|
74
70
|
specs_by_name = @specs.to_h {|s| [s.name, s] }
|
|
75
71
|
@specs.each do |spec_install|
|
|
76
|
-
|
|
72
|
+
dependencies = Override.rewrite_dependencies(installer.definition.overrides, spec_install.name, spec_install.spec.dependencies)
|
|
73
|
+
spec_install.dependencies = dependencies.filter_map do |dep|
|
|
77
74
|
specs_by_name[dep.name] unless dep.type == :development || dep.name == spec_install.name
|
|
78
75
|
end
|
|
79
76
|
end
|
|
@@ -100,7 +97,8 @@ module Bundler
|
|
|
100
97
|
handle_error if failed_specs.any?
|
|
101
98
|
@specs
|
|
102
99
|
ensure
|
|
103
|
-
worker_pool&.stop
|
|
100
|
+
@worker_pool&.stop
|
|
101
|
+
@download_worker_pool&.stop
|
|
104
102
|
end
|
|
105
103
|
|
|
106
104
|
private
|
|
@@ -170,17 +168,18 @@ module Bundler
|
|
|
170
168
|
end
|
|
171
169
|
end
|
|
172
170
|
|
|
171
|
+
def download_worker_pool
|
|
172
|
+
@download_worker_pool ||= Bundler::Worker.new(@size, "Gem Downloader",
|
|
173
|
+
->(spec_install, worker_num) { do_download(spec_install, worker_num) }, response_queue: response_queue)
|
|
174
|
+
end
|
|
175
|
+
|
|
173
176
|
def worker_pool
|
|
174
|
-
@worker_pool ||= Bundler::Worker.new
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
else
|
|
181
|
-
spec_install
|
|
182
|
-
end
|
|
183
|
-
}
|
|
177
|
+
@worker_pool ||= Bundler::Worker.new(@size, "Parallel Installer",
|
|
178
|
+
->(spec_install, worker_num) { do_install(spec_install, worker_num) }, response_queue: response_queue)
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
def response_queue
|
|
182
|
+
@response_queue ||= Thread::Queue.new
|
|
184
183
|
end
|
|
185
184
|
|
|
186
185
|
def do_download(spec_install, worker_num)
|
|
@@ -218,24 +217,24 @@ module Bundler
|
|
|
218
217
|
spec_install
|
|
219
218
|
end
|
|
220
219
|
|
|
221
|
-
#
|
|
222
|
-
#
|
|
223
|
-
#
|
|
224
|
-
# processed so the call to `enqueue_specs` is important after every
|
|
225
|
-
# dequeue.
|
|
220
|
+
# Process one completed download or installation. Downloads can finish
|
|
221
|
+
# before their dependencies are installed, so check all downloaded specs
|
|
222
|
+
# after each completion and enqueue any that are now installable.
|
|
226
223
|
def process_specs(installed_specs)
|
|
227
224
|
spec = worker_pool.deq
|
|
228
225
|
|
|
229
226
|
if spec.installed?
|
|
230
227
|
installed_specs[spec.name] = true
|
|
231
|
-
return
|
|
232
228
|
elsif spec.failed?
|
|
233
229
|
return
|
|
234
|
-
elsif spec.ready_to_install?(installed_specs)
|
|
235
|
-
spec.state = :installable
|
|
236
230
|
end
|
|
237
231
|
|
|
238
|
-
|
|
232
|
+
@specs.each do |candidate|
|
|
233
|
+
next unless candidate.ready_to_install?(installed_specs)
|
|
234
|
+
|
|
235
|
+
candidate.state = :installable
|
|
236
|
+
worker_pool.enq(candidate, priority: candidate.enqueue_with_priority?)
|
|
237
|
+
end
|
|
239
238
|
end
|
|
240
239
|
|
|
241
240
|
def finished_installing?
|
|
@@ -274,11 +273,8 @@ module Bundler
|
|
|
274
273
|
t
|
|
275
274
|
end
|
|
276
275
|
|
|
277
|
-
#
|
|
278
|
-
#
|
|
279
|
-
# Later we call this lambda again to install specs that depended on
|
|
280
|
-
# previously installed specifications. We continue until all specs
|
|
281
|
-
# are installed.
|
|
276
|
+
# Queue every missing spec for download. `process_specs` schedules each
|
|
277
|
+
# downloaded spec for installation once its dependencies are installed.
|
|
282
278
|
def enqueue_specs(installed_specs)
|
|
283
279
|
@specs.each do |spec|
|
|
284
280
|
if spec.installed?
|
|
@@ -287,7 +283,7 @@ module Bundler
|
|
|
287
283
|
end
|
|
288
284
|
|
|
289
285
|
spec.state = :enqueued
|
|
290
|
-
|
|
286
|
+
download_worker_pool.enq spec
|
|
291
287
|
end
|
|
292
288
|
end
|
|
293
289
|
end
|
data/lib/bundler/installer.rb
CHANGED
|
@@ -103,7 +103,7 @@ module Bundler
|
|
|
103
103
|
|
|
104
104
|
if options[:binstubs_cmd] && spec.executables.empty?
|
|
105
105
|
options = {}
|
|
106
|
-
spec.runtime_dependencies.each do |dep|
|
|
106
|
+
Override.rewrite_dependencies(@definition.overrides, spec.name, spec.runtime_dependencies).each do |dep|
|
|
107
107
|
bins = @definition.specs[dep].first.executables
|
|
108
108
|
options[dep.name] = bins unless bins.empty?
|
|
109
109
|
end
|
|
@@ -232,18 +232,32 @@ module Bundler
|
|
|
232
232
|
end
|
|
233
233
|
|
|
234
234
|
def ensure_specs_are_compatible!
|
|
235
|
+
overrides = @definition.overrides
|
|
235
236
|
@definition.specs.each do |spec|
|
|
236
|
-
unless spec.
|
|
237
|
-
raise InstallError,
|
|
238
|
-
"which is incompatible with the current version, #{Gem.ruby_version}"
|
|
237
|
+
unless spec.matches_current_ruby_with_overrides?(overrides)
|
|
238
|
+
raise InstallError, incompatibility_message(spec, "requires ruby version #{spec.required_ruby_version}, " \
|
|
239
|
+
"which is incompatible with the current version, #{Gem.ruby_version}")
|
|
239
240
|
end
|
|
240
|
-
unless spec.
|
|
241
|
-
raise InstallError,
|
|
242
|
-
"which is incompatible with the current version, #{Gem.rubygems_version}"
|
|
241
|
+
unless spec.matches_current_rubygems_with_overrides?(overrides)
|
|
242
|
+
raise InstallError, incompatibility_message(spec, "requires rubygems version #{spec.required_rubygems_version}, " \
|
|
243
|
+
"which is incompatible with the current version, #{Gem.rubygems_version}")
|
|
243
244
|
end
|
|
244
245
|
end
|
|
245
246
|
end
|
|
246
247
|
|
|
248
|
+
# Build the error raised when a locked spec can't run on the current Ruby or
|
|
249
|
+
# RubyGems. When the offending spec is a platform-specific variant locked in
|
|
250
|
+
# frozen mode, point users at the fix: re-resolving outside frozen mode adds
|
|
251
|
+
# the Ruby (non platform-specific) fallback variant to the lockfile.
|
|
252
|
+
def incompatibility_message(spec, reason)
|
|
253
|
+
message = "#{spec.full_name} #{reason}"
|
|
254
|
+
return message unless Bundler.frozen_bundle? && spec.platform != Gem::Platform::RUBY
|
|
255
|
+
|
|
256
|
+
message + "\n\nThe lockfile only includes the #{spec.platform} variant of #{spec.name}. " \
|
|
257
|
+
"If a compatible Ruby variant is available, run `bundle install` outside of frozen/deployment mode " \
|
|
258
|
+
"to add it to the lockfile as a fallback, then commit the updated #{SharedHelpers.relative_lockfile_path}."
|
|
259
|
+
end
|
|
260
|
+
|
|
247
261
|
def lock
|
|
248
262
|
@definition.lock
|
|
249
263
|
end
|
|
@@ -8,8 +8,9 @@ module Bundler
|
|
|
8
8
|
include MatchPlatform
|
|
9
9
|
include ForcePlatform
|
|
10
10
|
|
|
11
|
-
attr_reader :name, :version, :platform, :materialization
|
|
11
|
+
attr_reader :name, :version, :platform, :materialization, :content_address
|
|
12
12
|
attr_accessor :source, :remote, :force_ruby_platform, :dependencies, :required_ruby_version, :required_rubygems_version
|
|
13
|
+
attr_accessor :overrides
|
|
13
14
|
|
|
14
15
|
#
|
|
15
16
|
# For backwards compatibility with existing lockfiles, if the most specific
|
|
@@ -26,20 +27,22 @@ module Bundler
|
|
|
26
27
|
alias_method :runtime_dependencies, :dependencies
|
|
27
28
|
|
|
28
29
|
def self.from_spec(s)
|
|
29
|
-
lazy_spec = new(s.name, s.version, s.platform, s.source)
|
|
30
|
+
lazy_spec = new(s.name, s.version, s.platform, s.source, content_address: s.content_address)
|
|
30
31
|
lazy_spec.dependencies = s.runtime_dependencies
|
|
31
32
|
lazy_spec.required_ruby_version = s.required_ruby_version
|
|
32
33
|
lazy_spec.required_rubygems_version = s.required_rubygems_version
|
|
34
|
+
lazy_spec.overrides = s.overrides if s.is_a?(LazySpecification)
|
|
33
35
|
lazy_spec
|
|
34
36
|
end
|
|
35
37
|
|
|
36
|
-
def initialize(name, version, platform, source = nil, **materialization_options)
|
|
38
|
+
def initialize(name, version, platform, source = nil, content_address: nil, **materialization_options)
|
|
37
39
|
@name = name
|
|
38
40
|
@version = version
|
|
39
41
|
@dependencies = []
|
|
40
42
|
@required_ruby_version = Gem::Requirement.default
|
|
41
43
|
@required_rubygems_version = Gem::Requirement.default
|
|
42
44
|
@platform = platform || Gem::Platform::RUBY
|
|
45
|
+
@content_address = content_address
|
|
43
46
|
|
|
44
47
|
@original_source = source
|
|
45
48
|
@source = source
|
|
@@ -63,19 +66,25 @@ module Bundler
|
|
|
63
66
|
end
|
|
64
67
|
|
|
65
68
|
def full_name
|
|
66
|
-
@full_name ||= if
|
|
69
|
+
@full_name ||= if Gem::ContentAddress.content_addressed?(self, validate_ruby_abi: false)
|
|
70
|
+
"#{@name}-#{@version}-#{@content_address}"
|
|
71
|
+
elsif platform == Gem::Platform::RUBY
|
|
67
72
|
"#{@name}-#{@version}"
|
|
68
73
|
else
|
|
69
74
|
"#{@name}-#{@version}-#{platform}"
|
|
70
75
|
end
|
|
71
76
|
end
|
|
72
77
|
|
|
78
|
+
def file_name
|
|
79
|
+
"#{full_name}.gem"
|
|
80
|
+
end
|
|
81
|
+
|
|
73
82
|
def lock_name
|
|
74
83
|
@lock_name ||= name_tuple.lock_name
|
|
75
84
|
end
|
|
76
85
|
|
|
77
86
|
def name_tuple
|
|
78
|
-
Gem::NameTuple.new(@name, @version, @platform)
|
|
87
|
+
Gem::NameTuple.new(@name, @version, @platform, content_address: @content_address)
|
|
79
88
|
end
|
|
80
89
|
|
|
81
90
|
def ==(other)
|
|
@@ -110,6 +119,16 @@ module Bundler
|
|
|
110
119
|
@name == dependency.name && effective_requirement.satisfied_by?(Gem::Version.new(@version))
|
|
111
120
|
end
|
|
112
121
|
|
|
122
|
+
##
|
|
123
|
+
# Assigns the content address parsed from the lockfile's CONTENT
|
|
124
|
+
# ADDRESSES section. The full name embeds the content address, so its
|
|
125
|
+
# memoization must be invalidated.
|
|
126
|
+
|
|
127
|
+
def content_address=(value)
|
|
128
|
+
@content_address = value
|
|
129
|
+
@full_name = nil
|
|
130
|
+
end
|
|
131
|
+
|
|
113
132
|
def to_lock
|
|
114
133
|
out = String.new
|
|
115
134
|
out << " #{lock_name}\n"
|
|
@@ -128,13 +147,13 @@ module Bundler
|
|
|
128
147
|
materialize(self, &:first)
|
|
129
148
|
end
|
|
130
149
|
|
|
131
|
-
def materialized_for_installation
|
|
132
|
-
@materialization = materialize_for_installation
|
|
150
|
+
def materialized_for_installation(locked_platforms = nil)
|
|
151
|
+
@materialization = materialize_for_installation(locked_platforms)
|
|
133
152
|
|
|
134
153
|
self unless incomplete?
|
|
135
154
|
end
|
|
136
155
|
|
|
137
|
-
def materialize_for_installation
|
|
156
|
+
def materialize_for_installation(locked_platforms)
|
|
138
157
|
source.local!
|
|
139
158
|
|
|
140
159
|
if use_exact_resolved_specifications?
|
|
@@ -144,7 +163,7 @@ module Bundler
|
|
|
144
163
|
# Exact spec is incompatible; in frozen mode, try to find a compatible platform variant
|
|
145
164
|
# In non-frozen mode, return nil to trigger re-resolution and lockfile update
|
|
146
165
|
if Bundler.frozen_bundle?
|
|
147
|
-
materialize([name, version]) {|specs| resolve_best_platform(specs) }
|
|
166
|
+
materialize([name, version]) {|specs| resolve_best_platform(specs, locked_platforms: locked_platforms) }
|
|
148
167
|
end
|
|
149
168
|
else
|
|
150
169
|
materialize([name, version]) {|specs| resolve_best_platform(specs) }
|
|
@@ -185,12 +204,14 @@ module Bundler
|
|
|
185
204
|
# Try platforms in order of preference until finding a compatible spec.
|
|
186
205
|
# Used for legacy lockfiles and as a fallback when the exact locked spec
|
|
187
206
|
# is incompatible. Falls back to frozen bundle behavior if none match.
|
|
188
|
-
def resolve_best_platform(specs)
|
|
189
|
-
|
|
207
|
+
def resolve_best_platform(specs, locked_platforms: nil)
|
|
208
|
+
specs = MatchPlatform.select_all_content_address_match(specs, content_address)
|
|
209
|
+
|
|
210
|
+
find_compatible_platform_spec(specs, locked_platforms: locked_platforms) || frozen_bundle_fallback(specs)
|
|
190
211
|
end
|
|
191
212
|
|
|
192
|
-
def find_compatible_platform_spec(specs)
|
|
193
|
-
candidate_platforms.each do |plat|
|
|
213
|
+
def find_compatible_platform_spec(specs, locked_platforms: nil)
|
|
214
|
+
candidate_platforms(locked_platforms: locked_platforms).each do |plat|
|
|
194
215
|
candidates = MatchPlatform.select_best_platform_match(specs, plat)
|
|
195
216
|
spec = choose_compatible(candidates, fallback_to_non_installable: false)
|
|
196
217
|
return spec if spec
|
|
@@ -200,9 +221,14 @@ module Bundler
|
|
|
200
221
|
|
|
201
222
|
# Platforms to try in order of preference. Ruby platform is last since it
|
|
202
223
|
# requires compilation, but works when precompiled gems are incompatible.
|
|
203
|
-
|
|
224
|
+
# When a set of locked platforms is given (frozen mode), restrict the
|
|
225
|
+
# candidates to those, so we never materialize a platform that wasn't locked.
|
|
226
|
+
def candidate_platforms(locked_platforms: nil)
|
|
204
227
|
target = source.is_a?(Source::Path) ? platform : Bundler.local_platform
|
|
205
|
-
[target, platform, Gem::Platform::RUBY].uniq
|
|
228
|
+
platforms = [target, platform, Gem::Platform::RUBY].uniq
|
|
229
|
+
return platforms unless locked_platforms
|
|
230
|
+
|
|
231
|
+
platforms & locked_platforms
|
|
206
232
|
end
|
|
207
233
|
|
|
208
234
|
# In frozen mode, accept any candidate. Will error at install time.
|
|
@@ -234,8 +260,9 @@ module Bundler
|
|
|
234
260
|
# about the mismatch higher up the stack, right before trying to install the
|
|
235
261
|
# bad gem.
|
|
236
262
|
def choose_compatible(candidates, fallback_to_non_installable: Bundler.frozen_bundle?)
|
|
263
|
+
override_list = overrides || []
|
|
237
264
|
search = candidates.reverse.find do |spec|
|
|
238
|
-
spec.is_a?(StubSpecification) || spec.
|
|
265
|
+
spec.is_a?(StubSpecification) || spec.matches_current_metadata_with_overrides?(override_list)
|
|
239
266
|
end
|
|
240
267
|
if search.nil? && fallback_to_non_installable
|
|
241
268
|
search = candidates.last
|
|
@@ -259,10 +286,10 @@ module Bundler
|
|
|
259
286
|
# which would affect `bundler/setup` performance.
|
|
260
287
|
def validate_dependencies(spec)
|
|
261
288
|
if !@materialization_options[:strict] && spec.is_a?(StubSpecification)
|
|
262
|
-
spec.dependencies = dependencies
|
|
289
|
+
spec.dependencies = Override.rewrite_dependencies(overrides, name, dependencies)
|
|
263
290
|
else
|
|
264
291
|
if !source.is_a?(Source::Path) && spec.runtime_dependencies.sort != dependencies.sort
|
|
265
|
-
raise IncorrectLockfileDependencies.new(self)
|
|
292
|
+
raise IncorrectLockfileDependencies.new(self, spec.runtime_dependencies, dependencies)
|
|
266
293
|
end
|
|
267
294
|
end
|
|
268
295
|
end
|
|
@@ -19,6 +19,7 @@ module Bundler
|
|
|
19
19
|
add_sources
|
|
20
20
|
add_platforms
|
|
21
21
|
add_dependencies
|
|
22
|
+
add_content_addresses
|
|
22
23
|
add_checksums
|
|
23
24
|
add_locked_ruby_version
|
|
24
25
|
add_bundled_with
|
|
@@ -66,10 +67,31 @@ module Bundler
|
|
|
66
67
|
end
|
|
67
68
|
end
|
|
68
69
|
|
|
70
|
+
def add_content_addresses
|
|
71
|
+
content_addresses = definition.resolve.filter_map do |spec|
|
|
72
|
+
next unless Gem::ContentAddress.content_addressed?(spec, validate_ruby_abi: false)
|
|
73
|
+
|
|
74
|
+
line = "#{spec.lock_name} #{spec.content_address}"
|
|
75
|
+
|
|
76
|
+
if definition.locked_checksums
|
|
77
|
+
checksums = spec.source.checksum_store.checksums_to_lock(spec.full_name)
|
|
78
|
+
line += " #{checksums}" if checksums
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
line
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
add_section("CONTENT ADDRESSES", content_addresses) unless content_addresses.empty?
|
|
85
|
+
end
|
|
86
|
+
|
|
69
87
|
def add_checksums
|
|
70
88
|
return unless definition.locked_checksums
|
|
71
|
-
checksums = definition.resolve.
|
|
72
|
-
spec.source.checksum_store.to_lock(spec)
|
|
89
|
+
checksums = definition.resolve.filter_map do |spec|
|
|
90
|
+
line = spec.source.checksum_store.to_lock(spec)
|
|
91
|
+
|
|
92
|
+
next if line == spec.lock_name && Gem::ContentAddress.content_addressed?(spec, validate_ruby_abi: false)
|
|
93
|
+
|
|
94
|
+
line
|
|
73
95
|
end
|
|
74
96
|
|
|
75
97
|
add_section("CHECKSUMS", checksums + bundler_checksum)
|
|
@@ -41,6 +41,7 @@ module Bundler
|
|
|
41
41
|
BUNDLED = "BUNDLED WITH"
|
|
42
42
|
DEPENDENCIES = "DEPENDENCIES"
|
|
43
43
|
CHECKSUMS = "CHECKSUMS"
|
|
44
|
+
CONTENT_ADDRESSES = "CONTENT ADDRESSES"
|
|
44
45
|
PLATFORMS = "PLATFORMS"
|
|
45
46
|
RUBY = "RUBY VERSION"
|
|
46
47
|
GIT = "GIT"
|
|
@@ -48,7 +49,7 @@ module Bundler
|
|
|
48
49
|
PATH = "PATH"
|
|
49
50
|
PLUGIN = "PLUGIN SOURCE"
|
|
50
51
|
SPECS = " specs:"
|
|
51
|
-
OPTIONS = /^ ([a-
|
|
52
|
+
OPTIONS = /^ ([a-z_]+): (.*)$/i
|
|
52
53
|
SOURCE = [GIT, GEM, PATH, PLUGIN].freeze
|
|
53
54
|
|
|
54
55
|
SECTIONS_BY_VERSION_INTRODUCED = {
|
|
@@ -57,6 +58,7 @@ module Bundler
|
|
|
57
58
|
Gem::Version.create("1.12") => [RUBY].freeze,
|
|
58
59
|
Gem::Version.create("1.13") => [PLUGIN].freeze,
|
|
59
60
|
Gem::Version.create("2.5.0") => [CHECKSUMS].freeze,
|
|
61
|
+
Gem::Version.create("4.1.0") => [CONTENT_ADDRESSES].freeze,
|
|
60
62
|
}.freeze
|
|
61
63
|
|
|
62
64
|
KNOWN_SECTIONS = SECTIONS_BY_VERSION_INTRODUCED.values.flatten!.freeze
|
|
@@ -95,14 +97,14 @@ module Bundler
|
|
|
95
97
|
lockfile_contents.split(BUNDLED).last.strip
|
|
96
98
|
end
|
|
97
99
|
|
|
98
|
-
def initialize(lockfile, strict: false)
|
|
100
|
+
def initialize(lockfile, strict: false, lockfile_path: nil)
|
|
99
101
|
@platforms = []
|
|
100
102
|
@sources = []
|
|
101
103
|
@metadata_source = Source::Metadata.new
|
|
102
104
|
@dependencies = {}
|
|
103
105
|
@parse_method = nil
|
|
104
106
|
@specs = {}
|
|
105
|
-
@lockfile_path = begin
|
|
107
|
+
@lockfile_path = lockfile_path || begin
|
|
106
108
|
SharedHelpers.relative_lockfile_path
|
|
107
109
|
rescue GemfileNotFound
|
|
108
110
|
"Gemfile.lock"
|
|
@@ -140,6 +142,8 @@ module Bundler
|
|
|
140
142
|
# for all gemfiles that don't already explicitly include the feature.
|
|
141
143
|
@checksums = true
|
|
142
144
|
@parse_method = :parse_checksum
|
|
145
|
+
elsif line == CONTENT_ADDRESSES
|
|
146
|
+
@parse_method = :parse_content_address
|
|
143
147
|
elsif line == PLATFORMS
|
|
144
148
|
@parse_method = :parse_platform
|
|
145
149
|
elsif line == RUBY
|
|
@@ -227,6 +231,16 @@ module Bundler
|
|
|
227
231
|
$ # Line end
|
|
228
232
|
/xo
|
|
229
233
|
|
|
234
|
+
NAME_VERSION_CONTENT_ADDRESS = /
|
|
235
|
+
^#{space}{2}(?!#{space}) # Exactly 2 spaces at the start of the line
|
|
236
|
+
(.*?) # Name
|
|
237
|
+
#{space}\(([^-]*) # Space, followed by version
|
|
238
|
+
-(.*)\) # Platform, always present for content-addressable gems
|
|
239
|
+
#{space}([0-9a-f]{8,64}) # Content address
|
|
240
|
+
(?:#{space}([^ ]+))? # Optional checksums
|
|
241
|
+
$ # Line end
|
|
242
|
+
/xo
|
|
243
|
+
|
|
230
244
|
def parse_dependency(line)
|
|
231
245
|
return unless line =~ NAME_VERSION
|
|
232
246
|
spaces = $1
|
|
@@ -268,7 +282,8 @@ module Bundler
|
|
|
268
282
|
|
|
269
283
|
version = Gem::Version.new(version)
|
|
270
284
|
platform = platform ? Gem::Platform.new(platform) : Gem::Platform::RUBY
|
|
271
|
-
|
|
285
|
+
name_tuple = Gem::NameTuple.new(name, version, platform)
|
|
286
|
+
full_name = name_tuple.full_name
|
|
272
287
|
spec = @specs[full_name]
|
|
273
288
|
|
|
274
289
|
if name == "bundler"
|
|
@@ -280,10 +295,33 @@ module Bundler
|
|
|
280
295
|
checksums.split(",") do |lock_checksum|
|
|
281
296
|
column = line.index(lock_checksum) + 1
|
|
282
297
|
checksum = Checksum.from_lock(lock_checksum, "#{@lockfile_path}:#{@pos.line}:#{column}")
|
|
283
|
-
spec.source.checksum_store.register(
|
|
298
|
+
spec.source.checksum_store.register(name_tuple, checksum)
|
|
284
299
|
end
|
|
285
300
|
else
|
|
286
|
-
spec.source.checksum_store.register(
|
|
301
|
+
spec.source.checksum_store.register(name_tuple, nil)
|
|
302
|
+
end
|
|
303
|
+
end
|
|
304
|
+
|
|
305
|
+
def parse_content_address(line)
|
|
306
|
+
return unless line =~ NAME_VERSION_CONTENT_ADDRESS
|
|
307
|
+
|
|
308
|
+
name = -$1
|
|
309
|
+
version = Gem::Version.new($2)
|
|
310
|
+
platform = Gem::Platform.new($3)
|
|
311
|
+
content_address = $4
|
|
312
|
+
checksums = $5
|
|
313
|
+
|
|
314
|
+
spec = @specs[Gem::NameTuple.new(name, version, platform).full_name]
|
|
315
|
+
return unless spec
|
|
316
|
+
|
|
317
|
+
spec.content_address = content_address
|
|
318
|
+
|
|
319
|
+
return unless checksums
|
|
320
|
+
|
|
321
|
+
checksums.split(",") do |lock_checksum|
|
|
322
|
+
column = line.index(lock_checksum) + 1
|
|
323
|
+
checksum = Checksum.from_lock(lock_checksum, "#{@lockfile_path}:#{@pos.line}:#{column}")
|
|
324
|
+
spec.source.checksum_store.register(spec, checksum)
|
|
287
325
|
end
|
|
288
326
|
end
|
|
289
327
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
.\" generated with Ronn-NG/v0.10.1
|
|
2
2
|
.\" http://github.com/apjanke/ronn-ng/tree/0.10.1
|
|
3
|
-
.TH "BUNDLE\-ADD" "1" "
|
|
3
|
+
.TH "BUNDLE\-ADD" "1" "May 2026" ""
|
|
4
4
|
.SH "NAME"
|
|
5
5
|
\fBbundle\-add\fR \- Add gem to the Gemfile and run bundle install
|
|
6
6
|
.SH "SYNOPSIS"
|
|
@@ -46,13 +46,16 @@ Do not print progress information to the standard output\.
|
|
|
46
46
|
Adds the gem to the Gemfile but does not install it\.
|
|
47
47
|
.TP
|
|
48
48
|
\fB\-\-optimistic\fR
|
|
49
|
-
|
|
49
|
+
Ignored (now default behavior)
|
|
50
|
+
.TP
|
|
51
|
+
\fB\-\-pessimistic\fR
|
|
52
|
+
Adds pessimistic declaration of version\.
|
|
50
53
|
.TP
|
|
51
54
|
\fB\-\-strict\fR
|
|
52
55
|
Adds strict declaration of version\.
|
|
53
56
|
.TP
|
|
54
57
|
\fB\-\-cooldown=<number>\fR
|
|
55
|
-
Only consider gem versions published at least \fInumber\fR days ago when resolving\. Pass \fB0\fR to disable cooldown for this run\. See \fBcooldown\fR in bundle\-config(1) for precedence rules\.
|
|
58
|
+
Only consider gem versions published at least \fInumber\fR days ago when resolving\. Pass \fB0\fR to disable cooldown for this run, overriding every other cooldown setting, RubyGems' own included\. See \fBcooldown\fR in bundle\-config(1) for precedence rules\.
|
|
56
59
|
.SH "EXAMPLES"
|
|
57
60
|
.IP "1." 4
|
|
58
61
|
You can add the \fBrails\fR gem to the Gemfile without any version restriction\. The source of the gem will be the global source\.
|
|
@@ -65,7 +68,7 @@ You can add the \fBrails\fR gem with version greater than 1\.1 (not including 1\
|
|
|
65
68
|
.IP "3." 4
|
|
66
69
|
You can use the \fBhttps://gems\.example\.com\fR custom source and assign the gem to a group\.
|
|
67
70
|
.IP
|
|
68
|
-
\fBbundle add rails \-\-version "
|
|
71
|
+
\fBbundle add rails \-\-version ">= 5\.0\.0" \-\-source "https://gems\.example\.com" \-\-group "development"\fR
|
|
69
72
|
.IP "4." 4
|
|
70
73
|
The following adds the \fBgem\fR entry to the Gemfile without installing the gem\. You can install gems later via \fBbundle install\fR\.
|
|
71
74
|
.IP
|
|
@@ -51,15 +51,19 @@ Adds the named gem to the [`Gemfile(5)`][Gemfile(5)] and run `bundle install`.
|
|
|
51
51
|
Adds the gem to the Gemfile but does not install it.
|
|
52
52
|
|
|
53
53
|
* `--optimistic`:
|
|
54
|
-
|
|
54
|
+
Ignored (now default behavior)
|
|
55
|
+
|
|
56
|
+
* `--pessimistic`:
|
|
57
|
+
Adds pessimistic declaration of version.
|
|
55
58
|
|
|
56
59
|
* `--strict`:
|
|
57
60
|
Adds strict declaration of version.
|
|
58
61
|
|
|
59
62
|
* `--cooldown=<number>`:
|
|
60
63
|
Only consider gem versions published at least <number> days ago when
|
|
61
|
-
resolving. Pass `0` to disable cooldown for this run
|
|
62
|
-
|
|
64
|
+
resolving. Pass `0` to disable cooldown for this run, overriding every
|
|
65
|
+
other cooldown setting, RubyGems' own included. See `cooldown` in
|
|
66
|
+
bundle-config(1) for precedence rules.
|
|
63
67
|
|
|
64
68
|
## EXAMPLES
|
|
65
69
|
|
|
@@ -75,7 +79,7 @@ Adds the named gem to the [`Gemfile(5)`][Gemfile(5)] and run `bundle install`.
|
|
|
75
79
|
3. You can use the `https://gems.example.com` custom source and assign the gem
|
|
76
80
|
to a group.
|
|
77
81
|
|
|
78
|
-
`bundle add rails --version "
|
|
82
|
+
`bundle add rails --version ">= 5.0.0" --source "https://gems.example.com" --group "development"`
|
|
79
83
|
|
|
80
84
|
4. The following adds the `gem` entry to the Gemfile without installing the
|
|
81
85
|
gem. You can install gems later via `bundle install`.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
.\" generated with Ronn-NG/v0.10.1
|
|
2
2
|
.\" http://github.com/apjanke/ronn-ng/tree/0.10.1
|
|
3
|
-
.TH "BUNDLE\-BINSTUBS" "1" "
|
|
3
|
+
.TH "BUNDLE\-BINSTUBS" "1" "May 2026" ""
|
|
4
4
|
.SH "NAME"
|
|
5
5
|
\fBbundle\-binstubs\fR \- Install the binstubs of the listed gems
|
|
6
6
|
.SH "SYNOPSIS"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
.\" generated with Ronn-NG/v0.10.1
|
|
2
2
|
.\" http://github.com/apjanke/ronn-ng/tree/0.10.1
|
|
3
|
-
.TH "BUNDLE\-CACHE" "1" "
|
|
3
|
+
.TH "BUNDLE\-CACHE" "1" "May 2026" ""
|
|
4
4
|
.SH "NAME"
|
|
5
5
|
\fBbundle\-cache\fR \- Package your needed \fB\.gem\fR files into your application
|
|
6
6
|
.SH "SYNOPSIS"
|
|
@@ -18,7 +18,7 @@ Include gems for all platforms present in the lockfile, not only the current one
|
|
|
18
18
|
Specify a different cache path than the default (vendor/cache)\.
|
|
19
19
|
.TP
|
|
20
20
|
\fB\-\-cooldown=<number>\fR
|
|
21
|
-
Only consider gem versions published at least \fInumber\fR days ago when resolving before caching\. Pass \fB0\fR to disable cooldown for this run, overriding
|
|
21
|
+
Only consider gem versions published at least \fInumber\fR days ago when resolving before caching\. Pass \fB0\fR to disable cooldown for this run, overriding every other cooldown setting, RubyGems' own included\. See \fBcooldown\fR in bundle\-config(1)\.
|
|
22
22
|
.TP
|
|
23
23
|
\fB\-\-gemfile=GEMFILE\fR
|
|
24
24
|
Use the specified gemfile instead of Gemfile\.
|
|
@@ -24,8 +24,8 @@ use the gems in the cache in preference to the ones on `rubygems.org`.
|
|
|
24
24
|
* `--cooldown=<number>`:
|
|
25
25
|
Only consider gem versions published at least <number> days ago when
|
|
26
26
|
resolving before caching. Pass `0` to disable cooldown for this run,
|
|
27
|
-
overriding
|
|
28
|
-
bundle-config(1).
|
|
27
|
+
overriding every other cooldown setting, RubyGems' own included. See
|
|
28
|
+
`cooldown` in bundle-config(1).
|
|
29
29
|
|
|
30
30
|
* `--gemfile=GEMFILE`:
|
|
31
31
|
Use the specified gemfile instead of Gemfile.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
.\" generated with Ronn-NG/v0.10.1
|
|
2
2
|
.\" http://github.com/apjanke/ronn-ng/tree/0.10.1
|
|
3
|
-
.TH "BUNDLE\-CHECK" "1" "
|
|
3
|
+
.TH "BUNDLE\-CHECK" "1" "May 2026" ""
|
|
4
4
|
.SH "NAME"
|
|
5
5
|
\fBbundle\-check\fR \- Verifies if dependencies are satisfied by installed gems
|
|
6
6
|
.SH "SYNOPSIS"
|