bundler 4.0.21 → 4.1.0.beta1
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 +37 -1
- data/lib/bundler/cli/config.rb +4 -2
- data/lib/bundler/cli/gem.rb +0 -17
- data/lib/bundler/cli/install.rb +4 -5
- data/lib/bundler/cli/lock.rb +1 -2
- data/lib/bundler/cli/outdated.rb +8 -3
- data/lib/bundler/cli/pristine.rb +2 -1
- data/lib/bundler/cli/update.rb +21 -12
- data/lib/bundler/cli.rb +14 -11
- data/lib/bundler/definition.rb +61 -24
- data/lib/bundler/dependency.rb +4 -0
- data/lib/bundler/dsl.rb +77 -11
- 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 +31 -16
- data/lib/bundler/fetcher.rb +8 -47
- data/lib/bundler/injector.rb +3 -3
- data/lib/bundler/inline.rb +44 -4
- data/lib/bundler/installer/parallel_installer.rb +25 -30
- data/lib/bundler/installer.rb +20 -6
- data/lib/bundler/lazy_specification.rb +44 -17
- data/lib/bundler/lockfile_generator.rb +24 -2
- data/lib/bundler/lockfile_parser.rb +43 -5
- 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 +1 -1
- 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 +3 -3
- data/lib/bundler/man/bundle-lock.1.ronn +5 -5
- data/lib/bundler/man/bundle-open.1 +1 -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 +1 -1
- data/lib/bundler/man/bundle-update.1 +3 -3
- data/lib/bundler/man/bundle-update.1.ronn +3 -5
- data/lib/bundler/man/bundle-version.1 +1 -1
- data/lib/bundler/man/bundle.1 +1 -1
- data/lib/bundler/man/gemfile.5 +45 -1
- data/lib/bundler/man/gemfile.5.ronn +53 -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 +2 -1
- data/lib/bundler/override.rb +69 -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 +73 -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/self_manager.rb +9 -15
- data/lib/bundler/settings.rb +373 -30
- data/lib/bundler/shared_helpers.rb +2 -1
- data/lib/bundler/source/git/git_proxy.rb +2 -10
- data/lib/bundler/source/git.rb +15 -6
- 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/spec_set.rb +16 -4
- 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 +88 -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 +77 -68
- data/CHANGELOG.md +0 -5784
- 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
|
@@ -562,6 +562,59 @@ call.
|
|
|
562
562
|
This can be useful to run tests against multiple combinations of dependencies,
|
|
563
563
|
or to load per-developer gems from an untracked gemfile.
|
|
564
564
|
|
|
565
|
+
## OVERRIDE
|
|
566
|
+
|
|
567
|
+
The `override` directive rewrites a constraint on another gem before
|
|
568
|
+
resolution runs. It targets the common case where an upstream gem's
|
|
569
|
+
published metadata is too narrow on the current project's machine -- a stale
|
|
570
|
+
upper bound, an unwanted floor, or a transitive pin that has to be lifted.
|
|
571
|
+
|
|
572
|
+
override <target>, <field>: <operation>
|
|
573
|
+
|
|
574
|
+
`<target>` is a gem name string or `:all`. `<field>` is one of `version:`,
|
|
575
|
+
`required_ruby_version:`, or `required_rubygems_version:`. `<operation>` is
|
|
576
|
+
one of:
|
|
577
|
+
|
|
578
|
+
* a version requirement string (e.g. `">= 8.0"`), which **replaces** the
|
|
579
|
+
target's requirement absolutely. The original requirement, both direct
|
|
580
|
+
and transitive, is discarded in favour of the override.
|
|
581
|
+
* `:ignore_upper`, which removes upper-bound operators (`<` and `<=`) from
|
|
582
|
+
the existing requirement and folds `~>` into its lower bound (`~> 1.5`
|
|
583
|
+
becomes `>= 1.5`). Other operators, including `!=`, are preserved.
|
|
584
|
+
* `nil`, which collapses the requirement to `>= 0` (no constraint at all).
|
|
585
|
+
|
|
586
|
+
`:all` only applies to `required_ruby_version:` and `required_rubygems_version:`.
|
|
587
|
+
A per-gem override on the same field takes precedence over an `:all` override.
|
|
588
|
+
`:all + version:` is rejected: version requirements only make sense per gem.
|
|
589
|
+
|
|
590
|
+
Multiple `override` calls for distinct targets are allowed; declaring the
|
|
591
|
+
same `target` and `field` twice is an error.
|
|
592
|
+
|
|
593
|
+
source "https://rubygems.org"
|
|
594
|
+
|
|
595
|
+
# Force every reference to "rails" -- direct or transitive -- to >= 8.0.
|
|
596
|
+
override "rails", version: ">= 8.0"
|
|
597
|
+
|
|
598
|
+
# Strip the upper bound on nokogiri.
|
|
599
|
+
override "nokogiri", version: :ignore_upper
|
|
600
|
+
|
|
601
|
+
# Drop the version pin on legacy entirely.
|
|
602
|
+
override "legacy", version: nil
|
|
603
|
+
|
|
604
|
+
# Loosen every gem's required_ruby_version upper bound.
|
|
605
|
+
override :all, required_ruby_version: :ignore_upper
|
|
606
|
+
|
|
607
|
+
# Override one specific gem's required_rubygems_version.
|
|
608
|
+
override "tricky", required_rubygems_version: nil
|
|
609
|
+
|
|
610
|
+
gem "rails", "~> 7.0"
|
|
611
|
+
|
|
612
|
+
The override only affects resolution and the install-time Ruby/RubyGems
|
|
613
|
+
compatibility checks; `Gemfile.lock` continues to reflect the resolved
|
|
614
|
+
versions, not the rewritten requirements. When resolution still fails,
|
|
615
|
+
Bundler appends the active overrides (with their Gemfile location) to the
|
|
616
|
+
error message so it is clear which override shaped the constraint set.
|
|
617
|
+
|
|
565
618
|
## SOURCE PRIORITY
|
|
566
619
|
|
|
567
620
|
When attempting to locate a gem to satisfy a gem requirement,
|
|
@@ -14,6 +14,18 @@ module Bundler
|
|
|
14
14
|
@required_rubygems_version.satisfied_by?(Gem.rubygems_version)
|
|
15
15
|
end
|
|
16
16
|
|
|
17
|
+
def matches_current_metadata_with_overrides?(overrides)
|
|
18
|
+
matches_current_ruby_with_overrides?(overrides) && matches_current_rubygems_with_overrides?(overrides)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def matches_current_ruby_with_overrides?(overrides)
|
|
22
|
+
effective_required_version(@required_ruby_version, :required_ruby_version, overrides).satisfied_by?(Gem.ruby_version)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def matches_current_rubygems_with_overrides?(overrides)
|
|
26
|
+
effective_required_version(@required_rubygems_version, :required_rubygems_version, overrides).satisfied_by?(Gem.rubygems_version)
|
|
27
|
+
end
|
|
28
|
+
|
|
17
29
|
def expanded_dependencies
|
|
18
30
|
runtime_dependencies + [
|
|
19
31
|
metadata_dependency("Ruby", @required_ruby_version),
|
|
@@ -26,5 +38,13 @@ module Bundler
|
|
|
26
38
|
|
|
27
39
|
Gem::Dependency.new("#{name}\0", requirement)
|
|
28
40
|
end
|
|
41
|
+
|
|
42
|
+
private
|
|
43
|
+
|
|
44
|
+
def effective_required_version(requirement, field, overrides)
|
|
45
|
+
return requirement if overrides.nil? || overrides.empty?
|
|
46
|
+
override = Override.find_for(overrides, name, field)
|
|
47
|
+
override ? override.apply_to(requirement) : requirement
|
|
48
|
+
end
|
|
29
49
|
end
|
|
30
50
|
end
|
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
module Bundler
|
|
4
4
|
module MatchPlatform
|
|
5
|
+
def content_address
|
|
6
|
+
nil
|
|
7
|
+
end
|
|
8
|
+
|
|
5
9
|
def installable_on_platform?(target_platform) # :nodoc:
|
|
6
10
|
return true if [Gem::Platform::RUBY, nil, target_platform].include?(platform)
|
|
7
11
|
return true if Gem::Platform.new(platform) === target_platform
|
|
@@ -11,13 +15,32 @@ module Bundler
|
|
|
11
15
|
|
|
12
16
|
def self.select_best_platform_match(specs, platform, force_ruby: false, prefer_locked: false)
|
|
13
17
|
matching = select_all_platform_match(specs, platform, force_ruby: force_ruby, prefer_locked: prefer_locked)
|
|
18
|
+
matching = prefer_content_addressable(matching)
|
|
14
19
|
|
|
15
20
|
Gem::Platform.sort_and_filter_best_platform_match(matching, platform)
|
|
16
21
|
end
|
|
17
22
|
|
|
18
|
-
def self.
|
|
23
|
+
def self.select_all_content_address_match(specs, content_address)
|
|
24
|
+
return specs unless Gem::ContentAddress.match?(content_address)
|
|
25
|
+
|
|
26
|
+
specs.select {|spec| spec.content_address == content_address }
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def self.prefer_content_addressable(matching)
|
|
30
|
+
addressable, non_addressable = matching.partition {|s| Gem::ContentAddress.content_addressed?(s, validate_ruby_abi: false) }
|
|
31
|
+
return matching if addressable.empty?
|
|
32
|
+
|
|
33
|
+
compatible = addressable.select(&:matches_current_metadata?)
|
|
34
|
+
return compatible if compatible.any?
|
|
35
|
+
|
|
36
|
+
non_addressable.any? ? non_addressable : matching
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def self.select_best_local_platform_match(specs, force_ruby: false, locked_platforms: nil)
|
|
19
40
|
local = Bundler.local_platform
|
|
20
|
-
matching = select_all_platform_match(specs, local, force_ruby: force_ruby)
|
|
41
|
+
matching = select_all_platform_match(specs, local, force_ruby: force_ruby)
|
|
42
|
+
matching = matching.filter_map {|spec| spec.materialized_for_installation(locked_platforms) }
|
|
43
|
+
matching = prefer_content_addressable(matching)
|
|
21
44
|
|
|
22
45
|
Gem::Platform.sort_best_platform_match(matching, local)
|
|
23
46
|
end
|
|
@@ -6,19 +6,34 @@ module Bundler
|
|
|
6
6
|
# API didn't include that field, so some marshalled specs in the index have it
|
|
7
7
|
# set to +nil+.
|
|
8
8
|
def matches_current_ruby?
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
ensure_required_ruby_version_loaded
|
|
11
10
|
super
|
|
12
11
|
end
|
|
13
12
|
|
|
14
13
|
def matches_current_rubygems?
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
14
|
+
ensure_required_rubygems_version_loaded
|
|
15
|
+
super
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def matches_current_ruby_with_overrides?(overrides)
|
|
19
|
+
ensure_required_ruby_version_loaded
|
|
20
|
+
super
|
|
21
|
+
end
|
|
19
22
|
|
|
23
|
+
def matches_current_rubygems_with_overrides?(overrides)
|
|
24
|
+
ensure_required_rubygems_version_loaded
|
|
20
25
|
super
|
|
21
26
|
end
|
|
27
|
+
|
|
28
|
+
private
|
|
29
|
+
|
|
30
|
+
def ensure_required_ruby_version_loaded
|
|
31
|
+
@required_ruby_version ||= _remote_specification.required_ruby_version || Gem::Requirement.default # rubocop:disable Naming/MemoizedInstanceVariableName
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def ensure_required_rubygems_version_loaded
|
|
35
|
+
@required_rubygems_version ||= _remote_specification.required_rubygems_version || Gem::Requirement.default # rubocop:disable Naming/MemoizedInstanceVariableName
|
|
36
|
+
end
|
|
22
37
|
end
|
|
23
38
|
|
|
24
39
|
module MatchRemoteMetadata
|
|
@@ -12,6 +12,7 @@ module Bundler
|
|
|
12
12
|
@dep = dep
|
|
13
13
|
@platform = platform
|
|
14
14
|
@candidates = candidates
|
|
15
|
+
@locked_platforms = candidates&.map(&:platform)
|
|
15
16
|
end
|
|
16
17
|
|
|
17
18
|
def complete?
|
|
@@ -24,7 +25,7 @@ module Bundler
|
|
|
24
25
|
elsif platform
|
|
25
26
|
MatchPlatform.select_best_platform_match(@candidates, platform, force_ruby: dep.force_ruby_platform)
|
|
26
27
|
else
|
|
27
|
-
MatchPlatform.select_best_local_platform_match(@candidates, force_ruby: dep.force_ruby_platform || dep.default_force_ruby_platform)
|
|
28
|
+
MatchPlatform.select_best_local_platform_match(@candidates, force_ruby: dep.force_ruby_platform || dep.default_force_ruby_platform, locked_platforms: @locked_platforms)
|
|
28
29
|
end
|
|
29
30
|
end
|
|
30
31
|
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Bundler
|
|
4
|
+
class Override
|
|
5
|
+
UPPER_BOUND_OPERATORS = ["<", "<="].freeze
|
|
6
|
+
|
|
7
|
+
def self.find_for(overrides, name, field)
|
|
8
|
+
overrides.find {|o| o.target == name && o.field == field } ||
|
|
9
|
+
overrides.find {|o| o.target == :all && o.field == field }
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
# Attach the given overrides onto every LazySpecification in `specs` so
|
|
13
|
+
# downstream consumers (LazySpecification#choose_compatible, the install-
|
|
14
|
+
# time compatibility check, etc.) can read the override list off the spec
|
|
15
|
+
# itself. Non-LazySpec entries (StubSpecification, Gem::Specification, ...)
|
|
16
|
+
# are left untouched.
|
|
17
|
+
def self.attach(specs, overrides)
|
|
18
|
+
return if overrides.nil? || overrides.empty?
|
|
19
|
+
specs.each {|s| s.overrides = overrides if s.is_a?(LazySpecification) }
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
attr_reader :target, :field, :operation, :source_location
|
|
23
|
+
|
|
24
|
+
def initialize(target, field, operation, source_location: nil)
|
|
25
|
+
@target = target
|
|
26
|
+
@field = field
|
|
27
|
+
@operation = operation
|
|
28
|
+
@source_location = source_location
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def source_location_label
|
|
32
|
+
return nil unless @source_location
|
|
33
|
+
"#{File.basename(@source_location.path)}:#{@source_location.lineno}"
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def apply_to(requirement)
|
|
37
|
+
case operation
|
|
38
|
+
when nil
|
|
39
|
+
Gem::Requirement.default
|
|
40
|
+
when :ignore_upper
|
|
41
|
+
remove_upper_bounds(requirement)
|
|
42
|
+
when String
|
|
43
|
+
Gem::Requirement.new(operation)
|
|
44
|
+
else
|
|
45
|
+
raise ArgumentError, "unsupported override operation: #{operation.inspect}"
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
private
|
|
50
|
+
|
|
51
|
+
def remove_upper_bounds(requirement)
|
|
52
|
+
return Gem::Requirement.default if requirement.nil? || requirement.none?
|
|
53
|
+
|
|
54
|
+
preserved = requirement.requirements.filter_map do |op, version|
|
|
55
|
+
if UPPER_BOUND_OPERATORS.include?(op)
|
|
56
|
+
nil
|
|
57
|
+
elsif op == "~>"
|
|
58
|
+
[">=", version]
|
|
59
|
+
else
|
|
60
|
+
[op, version]
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
return Gem::Requirement.default if preserved.empty?
|
|
65
|
+
|
|
66
|
+
Gem::Requirement.new(preserved.map {|op, v| "#{op} #{v}" })
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
data/lib/bundler/plugin/dsl.rb
CHANGED
|
@@ -5,12 +5,11 @@ module Bundler
|
|
|
5
5
|
# Dsl to parse the Gemfile looking for plugins to install
|
|
6
6
|
class DSL < Bundler::Dsl
|
|
7
7
|
class PluginGemfileError < PluginError; end
|
|
8
|
-
alias_method :_gem, :gem # To use for plugin installation as gem
|
|
9
8
|
|
|
10
9
|
# So that we don't have to override all there methods to dummy ones
|
|
11
10
|
# explicitly.
|
|
12
11
|
# They will be handled by method_missing
|
|
13
|
-
[:gemspec, :
|
|
12
|
+
[:gemspec, :install_if, :platforms, :env].each {|m| undef_method m }
|
|
14
13
|
|
|
15
14
|
# This lists the plugins that was added automatically and not specified by
|
|
16
15
|
# the user.
|
|
@@ -24,12 +23,11 @@ module Bundler
|
|
|
24
23
|
|
|
25
24
|
def initialize
|
|
26
25
|
super
|
|
27
|
-
@sources = Plugin::SourceList.new
|
|
28
26
|
@inferred_plugins = [] # The source plugins inferred from :type
|
|
29
27
|
end
|
|
30
28
|
|
|
31
|
-
def
|
|
32
|
-
|
|
29
|
+
def gem(*args)
|
|
30
|
+
# Ignore regular dependencies when doing the plugins-only pre-parse
|
|
33
31
|
end
|
|
34
32
|
|
|
35
33
|
def method_missing(name, *args)
|
|
@@ -30,6 +30,54 @@ module Bundler
|
|
|
30
30
|
@events.key?(event)
|
|
31
31
|
end
|
|
32
32
|
|
|
33
|
+
# @!parse
|
|
34
|
+
# A hook called before the Gemfile is evaluated
|
|
35
|
+
# Includes the Gemfile path and the Lockfile path
|
|
36
|
+
# GEM_BEFORE_EVAL = "before-eval"
|
|
37
|
+
define :GEM_BEFORE_EVAL, "before-eval"
|
|
38
|
+
|
|
39
|
+
# @!parse
|
|
40
|
+
# A hook called after the Gemfile is evaluated
|
|
41
|
+
# Includes a Bundler::Definition
|
|
42
|
+
# GEM_AFTER_EVAL = "after-eval"
|
|
43
|
+
define :GEM_AFTER_EVAL, "after-eval"
|
|
44
|
+
|
|
45
|
+
# @!parse
|
|
46
|
+
# A hook called before any gems install
|
|
47
|
+
# Includes an Array of Bundler::Dependency objects
|
|
48
|
+
# GEM_BEFORE_INSTALL_ALL = "before-install-all"
|
|
49
|
+
define :GEM_BEFORE_INSTALL_ALL, "before-install-all"
|
|
50
|
+
|
|
51
|
+
# @!parse
|
|
52
|
+
# A hook called before each individual gem is downloaded from a remote source.
|
|
53
|
+
# Includes a spec-like object responding to the Gem::Specification API
|
|
54
|
+
# (for example, a Bundler spec proxy such as Bundler::EndpointSpecification
|
|
55
|
+
# or Bundler::RemoteSpecification). Does not fire when the gem is already
|
|
56
|
+
# present at the initial download-cache check.
|
|
57
|
+
# GEM_BEFORE_FETCH = "before-fetch"
|
|
58
|
+
define :GEM_BEFORE_FETCH, "before-fetch"
|
|
59
|
+
|
|
60
|
+
# @!parse
|
|
61
|
+
# A hook called after each individual gem is downloaded from a remote source.
|
|
62
|
+
# Includes a spec-like object responding to the Gem::Specification API
|
|
63
|
+
# (for example, a Bundler spec proxy such as Bundler::EndpointSpecification
|
|
64
|
+
# or Bundler::RemoteSpecification). Does not fire when the gem is already
|
|
65
|
+
# present at the initial download-cache check.
|
|
66
|
+
# GEM_AFTER_FETCH = "after-fetch"
|
|
67
|
+
define :GEM_AFTER_FETCH, "after-fetch"
|
|
68
|
+
|
|
69
|
+
# @!parse
|
|
70
|
+
# A hook called before a git source is fetched or checked out.
|
|
71
|
+
# Includes a Bundler::Source::Git reference.
|
|
72
|
+
# GIT_BEFORE_FETCH = "before-git-fetch"
|
|
73
|
+
define :GIT_BEFORE_FETCH, "before-git-fetch"
|
|
74
|
+
|
|
75
|
+
# @!parse
|
|
76
|
+
# A hook called after a git source is fetched or checked out.
|
|
77
|
+
# Includes a Bundler::Source::Git reference.
|
|
78
|
+
# GIT_AFTER_FETCH = "after-git-fetch"
|
|
79
|
+
define :GIT_AFTER_FETCH, "after-git-fetch"
|
|
80
|
+
|
|
33
81
|
# @!parse
|
|
34
82
|
# A hook called before each individual gem is installed
|
|
35
83
|
# Includes a Bundler::ParallelInstaller::SpecInstallation.
|
|
@@ -45,18 +93,18 @@ module Bundler
|
|
|
45
93
|
# GEM_AFTER_INSTALL = "after-install"
|
|
46
94
|
define :GEM_AFTER_INSTALL, "after-install"
|
|
47
95
|
|
|
48
|
-
# @!parse
|
|
49
|
-
# A hook called before any gems install
|
|
50
|
-
# Includes an Array of Bundler::Dependency objects
|
|
51
|
-
# GEM_BEFORE_INSTALL_ALL = "before-install-all"
|
|
52
|
-
define :GEM_BEFORE_INSTALL_ALL, "before-install-all"
|
|
53
|
-
|
|
54
96
|
# @!parse
|
|
55
97
|
# A hook called after any gems install
|
|
56
98
|
# Includes an Array of Bundler::Dependency objects
|
|
57
99
|
# GEM_AFTER_INSTALL_ALL = "after-install-all"
|
|
58
100
|
define :GEM_AFTER_INSTALL_ALL, "after-install-all"
|
|
59
101
|
|
|
102
|
+
# @!parse
|
|
103
|
+
# A hook called before any gems require
|
|
104
|
+
# Includes an Array of Bundler::Dependency objects.
|
|
105
|
+
# GEM_BEFORE_REQUIRE_ALL = "before-require-all"
|
|
106
|
+
define :GEM_BEFORE_REQUIRE_ALL, "before-require-all"
|
|
107
|
+
|
|
60
108
|
# @!parse
|
|
61
109
|
# A hook called before each individual gem is required
|
|
62
110
|
# Includes a Bundler::Dependency.
|
|
@@ -69,17 +117,11 @@ module Bundler
|
|
|
69
117
|
# GEM_AFTER_REQUIRE = "after-require"
|
|
70
118
|
define :GEM_AFTER_REQUIRE, "after-require"
|
|
71
119
|
|
|
72
|
-
# @!parse
|
|
73
|
-
# A hook called before any gems require
|
|
74
|
-
# Includes an Array of Bundler::Dependency objects.
|
|
75
|
-
# GEM_BEFORE_REQUIRE_ALL = "before-require-all"
|
|
76
|
-
define :GEM_BEFORE_REQUIRE_ALL, "before-require-all"
|
|
77
|
-
|
|
78
120
|
# @!parse
|
|
79
121
|
# A hook called after all gems required
|
|
80
122
|
# Includes an Array of Bundler::Dependency objects.
|
|
81
123
|
# GEM_AFTER_REQUIRE_ALL = "after-require-all"
|
|
82
|
-
define :GEM_AFTER_REQUIRE_ALL,
|
|
124
|
+
define :GEM_AFTER_REQUIRE_ALL, "after-require-all"
|
|
83
125
|
end
|
|
84
126
|
end
|
|
85
127
|
end
|
data/lib/bundler/plugin/index.rb
CHANGED
|
@@ -163,20 +163,28 @@ module Bundler
|
|
|
163
163
|
# @param [Pathname] index file path
|
|
164
164
|
# @param [Boolean] is the index file global index
|
|
165
165
|
def load_index(index_file, global = false)
|
|
166
|
+
base = base_for_index(global)
|
|
167
|
+
|
|
166
168
|
SharedHelpers.filesystem_access(index_file, :read) do |index_f|
|
|
167
169
|
valid_file = index_f&.exist? && !index_f.size.zero?
|
|
168
170
|
break unless valid_file
|
|
169
171
|
|
|
170
172
|
data = index_f.read
|
|
171
173
|
|
|
172
|
-
|
|
173
|
-
index
|
|
174
|
+
require "rubygems/yaml_serializer"
|
|
175
|
+
# Empty sections load as nil, e.g. from index files written by
|
|
176
|
+
# older Bundler versions, which dumped empty hashes as a bare key.
|
|
177
|
+
index = Gem::YAMLSerializer.load(data) || {}
|
|
178
|
+
|
|
179
|
+
escaping = escaping_plugins(index, base)
|
|
180
|
+
hooks = (index["hooks"] || {}).transform_values {|names| Array(names) - escaping }
|
|
174
181
|
|
|
175
|
-
@commands.merge!(index["commands"])
|
|
176
|
-
|
|
177
|
-
@
|
|
178
|
-
@
|
|
179
|
-
@
|
|
182
|
+
@commands.merge!(owned_by(index["commands"] || {}, escaping))
|
|
183
|
+
# An event whose plugins all escaped is left out rather than merged in empty.
|
|
184
|
+
@hooks.merge!(hooks.reject {|_, names| names.empty? })
|
|
185
|
+
@load_paths.merge!(named(transform_index_paths(index["load_paths"]) {|p| absolutize_path(p, base) }, escaping))
|
|
186
|
+
@plugin_paths.merge!(named(transform_index_paths(index["plugin_paths"]) {|p| absolutize_path(p, base) }, escaping))
|
|
187
|
+
@sources.merge!(owned_by(index["sources"] || {}, escaping)) unless global
|
|
180
188
|
end
|
|
181
189
|
end
|
|
182
190
|
|
|
@@ -184,20 +192,88 @@ module Bundler
|
|
|
184
192
|
# instance variables in YAML format. (The instance variables are supposed
|
|
185
193
|
# to be only String key value pairs)
|
|
186
194
|
def save_index
|
|
195
|
+
base = base_for_index(false)
|
|
196
|
+
|
|
187
197
|
index = {
|
|
188
198
|
"commands" => @commands,
|
|
189
199
|
"hooks" => @hooks,
|
|
190
|
-
"load_paths" => @load_paths,
|
|
191
|
-
"plugin_paths" => @plugin_paths,
|
|
200
|
+
"load_paths" => transform_index_paths(@load_paths) {|p| relativize_path(p, base) },
|
|
201
|
+
"plugin_paths" => transform_index_paths(@plugin_paths) {|p| relativize_path(p, base) },
|
|
192
202
|
"sources" => @sources,
|
|
193
203
|
}
|
|
194
204
|
|
|
195
|
-
|
|
205
|
+
require "rubygems/yaml_serializer"
|
|
196
206
|
SharedHelpers.filesystem_access(index_file) do |index_f|
|
|
197
207
|
FileUtils.mkdir_p(index_f.dirname)
|
|
198
|
-
File.open(index_f, "w") {|f| f.puts YAMLSerializer.dump(index) }
|
|
208
|
+
File.open(index_f, "w") {|f| f.puts Gem::YAMLSerializer.dump(index) }
|
|
209
|
+
end
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
def base_for_index(global)
|
|
213
|
+
global ? Plugin.global_root : Plugin.root
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
# A relative path only means anything inside the root, so an entry that escapes is not one Bundler installed.
|
|
217
|
+
def escaping_plugins(index, base)
|
|
218
|
+
names = []
|
|
219
|
+
|
|
220
|
+
%w[load_paths plugin_paths].each do |key|
|
|
221
|
+
(index[key] || {}).each do |name, value|
|
|
222
|
+
escapes = Array(value).any? do |path|
|
|
223
|
+
!Pathname.new(path).absolute? && !contained_in?(absolutize_path(path, base), base)
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
names << name if escapes
|
|
227
|
+
end
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
names.uniq
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
# Expanded here, not by the caller: what gets stored stays joined, because
|
|
234
|
+
# #installed_in_plugin_root? matches it against Plugin.root as written.
|
|
235
|
+
def contained_in?(path, base)
|
|
236
|
+
path = File.expand_path(path)
|
|
237
|
+
base = File.expand_path(base)
|
|
238
|
+
|
|
239
|
+
path == base || path.start_with?("#{base}#{File::SEPARATOR}")
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
# commands and sources are keyed by what they provide, load_paths and plugin_paths by the plugin.
|
|
243
|
+
def owned_by(mapping, names)
|
|
244
|
+
mapping.reject {|_, plugin| names.include?(plugin) }
|
|
245
|
+
end
|
|
246
|
+
|
|
247
|
+
def named(mapping, names)
|
|
248
|
+
mapping.reject {|plugin, _| names.include?(plugin) }
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
def transform_index_paths(paths)
|
|
252
|
+
return {} unless paths
|
|
253
|
+
|
|
254
|
+
paths.transform_values do |value|
|
|
255
|
+
if value.is_a?(Array)
|
|
256
|
+
value.map {|path| yield path }
|
|
257
|
+
else
|
|
258
|
+
yield value
|
|
259
|
+
end
|
|
199
260
|
end
|
|
200
261
|
end
|
|
262
|
+
|
|
263
|
+
def relativize_path(path, base)
|
|
264
|
+
pathname = Pathname.new(path)
|
|
265
|
+
return path unless pathname.absolute?
|
|
266
|
+
|
|
267
|
+
return path unless contained_in?(pathname.to_s, base)
|
|
268
|
+
|
|
269
|
+
pathname.relative_path_from(Pathname.new(base)).to_s
|
|
270
|
+
end
|
|
271
|
+
|
|
272
|
+
def absolutize_path(path, base)
|
|
273
|
+
pathname = Pathname.new(path)
|
|
274
|
+
pathname = Pathname.new(base).join(pathname) unless pathname.absolute?
|
|
275
|
+
pathname.to_s
|
|
276
|
+
end
|
|
201
277
|
end
|
|
202
278
|
end
|
|
203
279
|
end
|
|
@@ -32,12 +32,18 @@ module Bundler
|
|
|
32
32
|
#
|
|
33
33
|
# @param [Definition] definition object
|
|
34
34
|
# @return [Hash] map of names to their specs they are installed with
|
|
35
|
-
def install_definition(definition)
|
|
35
|
+
def install_definition(definition, latest = false)
|
|
36
36
|
def definition.lock(*); end
|
|
37
|
-
|
|
37
|
+
|
|
38
|
+
if latest || definition.missing_specs?
|
|
39
|
+
definition.remotely!
|
|
40
|
+
else
|
|
41
|
+
definition.with_cache!
|
|
42
|
+
end
|
|
43
|
+
|
|
38
44
|
specs = definition.specs
|
|
39
45
|
|
|
40
|
-
install_from_specs
|
|
46
|
+
install_from_specs(specs)
|
|
41
47
|
end
|
|
42
48
|
|
|
43
49
|
private
|
|
@@ -89,14 +95,14 @@ module Bundler
|
|
|
89
95
|
end
|
|
90
96
|
|
|
91
97
|
def install_all_sources(names, version, source_list, source = nil)
|
|
92
|
-
deps = names.map {|name| Dependency.new(name, version, { "source" => source }) }
|
|
98
|
+
deps = names.map {|name| Dependency.new(name, version, { "source" => source, "plugin" => true }) }
|
|
93
99
|
|
|
94
100
|
Bundler.configure_gem_home_and_path(Plugin.root)
|
|
95
101
|
|
|
96
102
|
Bundler.settings.temporary(deployment: false, frozen: false) do
|
|
97
103
|
definition = Definition.new(nil, deps, source_list, true)
|
|
98
104
|
|
|
99
|
-
install_definition(definition)
|
|
105
|
+
install_definition(definition, true)
|
|
100
106
|
end
|
|
101
107
|
end
|
|
102
108
|
|
|
@@ -110,6 +116,8 @@ module Bundler
|
|
|
110
116
|
paths = {}
|
|
111
117
|
|
|
112
118
|
specs.each do |spec|
|
|
119
|
+
next if spec.name == "bundler"
|
|
120
|
+
|
|
113
121
|
spec.source.download(spec)
|
|
114
122
|
spec.source.install(spec)
|
|
115
123
|
|