bundler 4.0.10 → 4.0.20

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.
Files changed (106) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +174 -0
  3. data/bundler.gemspec +2 -2
  4. data/lib/bundler/build_metadata.rb +2 -2
  5. data/lib/bundler/cli/add.rb +3 -0
  6. data/lib/bundler/cli/check.rb +1 -3
  7. data/lib/bundler/cli/common.rb +17 -0
  8. data/lib/bundler/cli/config.rb +8 -3
  9. data/lib/bundler/cli/doctor/diagnose.rb +1 -1
  10. data/lib/bundler/cli/exec.rb +15 -1
  11. data/lib/bundler/cli/gem.rb +2 -3
  12. data/lib/bundler/cli/init.rb +4 -0
  13. data/lib/bundler/cli/install.rb +4 -0
  14. data/lib/bundler/cli/issue.rb +2 -2
  15. data/lib/bundler/cli/lock.rb +10 -2
  16. data/lib/bundler/cli/open.rb +12 -2
  17. data/lib/bundler/cli/outdated.rb +76 -6
  18. data/lib/bundler/cli/update.rb +3 -0
  19. data/lib/bundler/cli.rb +21 -15
  20. data/lib/bundler/compact_index_client/cache.rb +11 -0
  21. data/lib/bundler/compact_index_client/cache_file.rb +1 -1
  22. data/lib/bundler/compact_index_client/parser.rb +4 -1
  23. data/lib/bundler/definition.rb +64 -15
  24. data/lib/bundler/dsl.rb +11 -4
  25. data/lib/bundler/endpoint_specification.rb +30 -2
  26. data/lib/bundler/fetcher/base.rb +3 -0
  27. data/lib/bundler/fetcher/compact_index.rb +13 -0
  28. data/lib/bundler/fetcher/gem_remote_fetcher.rb +2 -0
  29. data/lib/bundler/fetcher.rb +12 -2
  30. data/lib/bundler/gem_helper.rb +2 -2
  31. data/lib/bundler/installer/parallel_installer.rb +68 -23
  32. data/lib/bundler/installer.rb +18 -1
  33. data/lib/bundler/lockfile_generator.rb +55 -1
  34. data/lib/bundler/lockfile_parser.rb +23 -1
  35. data/lib/bundler/man/bundle-add.1 +6 -3
  36. data/lib/bundler/man/bundle-add.1.ronn +7 -2
  37. data/lib/bundler/man/bundle-binstubs.1 +1 -1
  38. data/lib/bundler/man/bundle-cache.1 +4 -1
  39. data/lib/bundler/man/bundle-cache.1.ronn +6 -0
  40. data/lib/bundler/man/bundle-check.1 +1 -1
  41. data/lib/bundler/man/bundle-clean.1 +1 -1
  42. data/lib/bundler/man/bundle-config.1 +121 -157
  43. data/lib/bundler/man/bundle-config.1.ronn +38 -6
  44. data/lib/bundler/man/bundle-console.1 +3 -3
  45. data/lib/bundler/man/bundle-console.1.ronn +2 -2
  46. data/lib/bundler/man/bundle-doctor.1 +1 -1
  47. data/lib/bundler/man/bundle-env.1 +1 -1
  48. data/lib/bundler/man/bundle-exec.1 +1 -1
  49. data/lib/bundler/man/bundle-fund.1 +1 -1
  50. data/lib/bundler/man/bundle-gem.1 +1 -1
  51. data/lib/bundler/man/bundle-help.1 +1 -1
  52. data/lib/bundler/man/bundle-info.1 +1 -1
  53. data/lib/bundler/man/bundle-init.1 +2 -2
  54. data/lib/bundler/man/bundle-init.1.ronn +1 -1
  55. data/lib/bundler/man/bundle-install.1 +5 -2
  56. data/lib/bundler/man/bundle-install.1.ronn +9 -1
  57. data/lib/bundler/man/bundle-issue.1 +1 -1
  58. data/lib/bundler/man/bundle-licenses.1 +1 -1
  59. data/lib/bundler/man/bundle-list.1 +1 -1
  60. data/lib/bundler/man/bundle-lock.1 +5 -2
  61. data/lib/bundler/man/bundle-lock.1.ronn +6 -0
  62. data/lib/bundler/man/bundle-open.1 +1 -1
  63. data/lib/bundler/man/bundle-outdated.1 +17 -14
  64. data/lib/bundler/man/bundle-outdated.1.ronn +25 -12
  65. data/lib/bundler/man/bundle-platform.1 +5 -1
  66. data/lib/bundler/man/bundle-platform.1.ronn +4 -0
  67. data/lib/bundler/man/bundle-plugin.1 +2 -2
  68. data/lib/bundler/man/bundle-plugin.1.ronn +1 -1
  69. data/lib/bundler/man/bundle-pristine.1 +1 -1
  70. data/lib/bundler/man/bundle-remove.1 +1 -1
  71. data/lib/bundler/man/bundle-show.1 +1 -1
  72. data/lib/bundler/man/bundle-update.1 +5 -2
  73. data/lib/bundler/man/bundle-update.1.ronn +8 -0
  74. data/lib/bundler/man/bundle-version.1 +1 -1
  75. data/lib/bundler/man/bundle.1 +23 -2
  76. data/lib/bundler/man/bundle.1.ronn +22 -1
  77. data/lib/bundler/man/gemfile.5 +14 -3
  78. data/lib/bundler/man/gemfile.5.ronn +23 -2
  79. data/lib/bundler/mirror.rb +7 -7
  80. data/lib/bundler/plugin/unloaded_source.rb +25 -0
  81. data/lib/bundler/plugin.rb +12 -6
  82. data/lib/bundler/remote_specification.rb +1 -1
  83. data/lib/bundler/resolver/base.rb +9 -0
  84. data/lib/bundler/resolver.rb +116 -2
  85. data/lib/bundler/rubygems_ext.rb +22 -0
  86. data/lib/bundler/rubygems_gem_installer.rb +35 -2
  87. data/lib/bundler/runtime.rb +11 -11
  88. data/lib/bundler/self_manager.rb +6 -1
  89. data/lib/bundler/settings.rb +1 -0
  90. data/lib/bundler/shared_helpers.rb +21 -1
  91. data/lib/bundler/source/git/git_proxy.rb +83 -10
  92. data/lib/bundler/source/git.rb +4 -4
  93. data/lib/bundler/source/metadata.rb +4 -0
  94. data/lib/bundler/source/path.rb +4 -3
  95. data/lib/bundler/source/rubygems/remote.rb +12 -2
  96. data/lib/bundler/source/rubygems.rb +81 -13
  97. data/lib/bundler/source_list.rb +44 -3
  98. data/lib/bundler/spec_set.rb +2 -2
  99. data/lib/bundler/stub_specification.rb +3 -1
  100. data/lib/bundler/templates/newgem/newgem.gemspec.tt +8 -2
  101. data/lib/bundler/vendored_tsort.rb +19 -2
  102. data/lib/bundler/version.rb +1 -1
  103. data/lib/bundler.rb +26 -6
  104. metadata +5 -6
  105. data/lib/bundler/vendor/tsort/LICENSE.txt +0 -22
  106. data/lib/bundler/vendor/tsort/lib/tsort.rb +0 -455
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 54c40beb5b2e8ef4f0a575b9d408fe571ef2b1089099fc09d4b46a6adc4307ea
4
- data.tar.gz: 591339a1a0a4512ae8c386c24b98f09ca48ed571a011141dee4874ead6555a2e
3
+ metadata.gz: b47ebbcd326a80d96d63eb16bc6743f1869f9ad1f37d83fac4dc9e1ea805c82c
4
+ data.tar.gz: c4903d7995ee2fa13381891ea105a1960ed5fb2ed69255f9fab09b4a7457f89e
5
5
  SHA512:
6
- metadata.gz: 15c2b8ba181ff0f418ce40b488b3d148e661992058ed0f1af8a58c3adb774b00fc39e29211c0abd22f51b85098840514fbf35dbb8c5d0c0773f0e4cf22facb8c
7
- data.tar.gz: bf33570321010bd7e2283384c1331ee13bc1f3176de52c16c34a2e56b461c625fc955dfef9ba0d9b157ff0f11591892832eea06621a88facd7e187e85bd8c468
6
+ metadata.gz: 2bdee0e45396bc93bf1837856a137f30ac3fa2a6bd4cc805ada1c0326e25309da64571d048edcd230f4f2143e1878ca4628d525fadea65e89333255946d2ead8
7
+ data.tar.gz: a8f333636a584612db1e4ae36ad93265e22873c38b3ff6cab66bb0e935a84126eeeaef21626fa429fe3229a4f194881be7d8bfed25ebc7675719644d538f0d2e
data/CHANGELOG.md CHANGED
@@ -1,5 +1,179 @@
1
1
  # Changelog
2
2
 
3
+ ## 4.0.20 / 2026-09-02
4
+
5
+ ### Enhancements:
6
+
7
+ * Avoid duplicate relative path prefix in bundle exec. Pull request [#9596](https://github.com/ruby/rubygems/pull/9596) by samuel-williams-shopify
8
+ * Follow renamed default branch in git sources. Pull request [#9813](https://github.com/ruby/rubygems/pull/9813) by hsbt
9
+ * Bundler::Source::Git: avoid re-fetching the repo. Pull request [#9806](https://github.com/ruby/rubygems/pull/9806) by byroot
10
+ * Show the newest out-of-cooldown version in bundle outdated. Pull request [#9803](https://github.com/ruby/rubygems/pull/9803) by hsbt
11
+
12
+ ### Bug fixes:
13
+
14
+ * Error out when `bundle init --gemspec` gets no specification. Pull request [#9818](https://github.com/ruby/rubygems/pull/9818) by hsbt
15
+ * Fix relative gemspec paths being expanded twice. Pull request [#9814](https://github.com/ruby/rubygems/pull/9814) by hsbt
16
+ * Fix gemspec evaluation under Ruby::Box. Pull request [#9809](https://github.com/ruby/rubygems/pull/9809) by hsbt
17
+ * Fix release date extraction for the current changelog header format. Pull request [#9767](https://github.com/ruby/rubygems/pull/9767) by meganemura
18
+ * Resolve globbed entries literally in Gem::Util.glob_files_in_dir. Pull request [#9802](https://github.com/ruby/rubygems/pull/9802) by hsbt
19
+ * Preserve native extensions during implicit clean. Pull request [#9800](https://github.com/ruby/rubygems/pull/9800) by sjh9714
20
+
21
+ ### Documentation:
22
+
23
+ * Clarify :path expectations and cross-link platform docs in man pages. Pull request [#9724](https://github.com/ruby/rubygems/pull/9724) by hsbt
24
+
25
+ ## 4.0.19 / 2026-08-20
26
+
27
+ ### Enhancements:
28
+
29
+ * Validate the platform field in Gem::Installer#verify_spec. Pull request [#9780](https://github.com/ruby/rubygems/pull/9780) by hsbt
30
+ * Restrict UserDefined handling to explicit class set for Gem::SafeMashal. Pull request [#9770](https://github.com/ruby/rubygems/pull/9770) by jackorp
31
+ * Filter git command output against the configured URI. Pull request [#9778](https://github.com/ruby/rubygems/pull/9778) by hsbt
32
+ * Summarize cooldown-skipped versions at the end of install, update, and lock. Pull request [#9762](https://github.com/ruby/rubygems/pull/9762) by hsbt
33
+
34
+ ### Bug fixes:
35
+
36
+ * Make repeated bundle lock options accumulate. Pull request [#9748](https://github.com/ruby/rubygems/pull/9748) by hsbt
37
+ * Fail instead of warning when frozen mode can't update the lockfile. Pull request [#9750](https://github.com/ruby/rubygems/pull/9750) by hsbt
38
+ * Fix wrong $LOAD_PATH for gems installed in the same process. Pull request [#9784](https://github.com/ruby/rubygems/pull/9784) by hsbt
39
+
40
+ ### Documentation:
41
+
42
+ * Fix auto-clean default version in bundle config docs. Pull request [#9783](https://github.com/ruby/rubygems/pull/9783) by hsbt
43
+ * Correct Bundler 5 default path documentation. Pull request [#9771](https://github.com/ruby/rubygems/pull/9771) by alloutflo
44
+
45
+ ## 4.0.18 / 2026-08-05
46
+
47
+ ### Enhancements:
48
+
49
+ * Don't mask install errors when no Gemfile can be located. Pull request [#9757](https://github.com/ruby/rubygems/pull/9757) by hsbt
50
+ * Warn when duplicate source declarations conflict on cooldown. Pull request [#9736](https://github.com/ruby/rubygems/pull/9736) by hsbt
51
+ * Redact URI userinfo from settings names in Bundler User-Agent. Pull request [#9716](https://github.com/ruby/rubygems/pull/9716) by hsbt
52
+ * Validate gem name before building compact index cache paths. Pull request [#9717](https://github.com/ruby/rubygems/pull/9717) by hsbt
53
+
54
+ ### Bug fixes:
55
+
56
+ * Fail `bundle check` when frozen mode needs lockfile changes. Pull request [#9715](https://github.com/ruby/rubygems/pull/9715) by hsbt
57
+ * Skip empty checksum values in compact index metadata. Pull request [#9713](https://github.com/ruby/rubygems/pull/9713) by hsbt
58
+
59
+ ### Security:
60
+
61
+ * Add --cooldown flag to bundle lock and bundle cache. Pull request [#9725](https://github.com/ruby/rubygems/pull/9725) by hsbt
62
+
63
+ ### Documentation:
64
+
65
+ * Point bundler.io URLs at guides.rubygems.org. Pull request [#9737](https://github.com/ruby/rubygems/pull/9737) by hsbt
66
+ * Document Bundler checksum behavior for default gems. Pull request [#9735](https://github.com/ruby/rubygems/pull/9735) by p-linnane
67
+ * List missing subcommands in bundle(1) UTILITIES section. Pull request [#9721](https://github.com/ruby/rubygems/pull/9721) by hsbt
68
+ * Document pessimistic operator and eval_gemfile in gemfile(5). Pull request [#9719](https://github.com/ruby/rubygems/pull/9719) by hsbt
69
+
70
+ ## 4.0.17 / 2026-07-22
71
+
72
+ ### Enhancements:
73
+
74
+ * Open compact index cache in binary mode when appending. Pull request [#9679](https://github.com/ruby/rubygems/pull/9679) by hsbt
75
+
76
+ ### Bug fixes:
77
+
78
+ * Unquote Gem.ruby when spawning it as a separate argv element. Pull request [#9695](https://github.com/ruby/rubygems/pull/9695) by hsbt
79
+ * Escape glob metacharacters in install paths when globbing. Pull request [#9687](https://github.com/ruby/rubygems/pull/9687) by hsbt
80
+ * Avoid space-containing absolute path in RUBYOPT. Pull request [#9696](https://github.com/ruby/rubygems/pull/9696) by hsbt
81
+ * Preserve the locked Bundler checksum when the gem isn't cached. Pull request [#9658](https://github.com/ruby/rubygems/pull/9658) by rwstauner
82
+
83
+ ### Documentation:
84
+
85
+ * Point Bundler gemspec metadata at the moved docs. Pull request [#9648](https://github.com/ruby/rubygems/pull/9648) by hsbt
86
+
87
+ ## 4.0.16 / 2026-07-10
88
+
89
+ ### Enhancements:
90
+
91
+ * Bundler: Fix Bundler::Fetcher for PQC support, adding integration connection tests. Pull request [#9637](https://github.com/ruby/rubygems/pull/9637) by junaruga
92
+ * Reuse RubyGems' vendored tsort in Bundler. Pull request [#9647](https://github.com/ruby/rubygems/pull/9647) by hsbt
93
+
94
+ ### Bug fixes:
95
+
96
+ * Initialize the new gem's git repo without a subshell. Pull request [#9670](https://github.com/ruby/rubygems/pull/9670) by hsbt
97
+ * Preserve CRLF lockfile line endings on Windows. Pull request [#9669](https://github.com/ruby/rubygems/pull/9669) by hsbt
98
+ * Fix the gemspec error snippet on Windows drive-letter paths. Pull request [#9668](https://github.com/ruby/rubygems/pull/9668) by hsbt
99
+
100
+ ### Documentation:
101
+
102
+ * Point Bundler gemspec metadata at the moved docs. Pull request [#9648](https://github.com/ruby/rubygems/pull/9648) by hsbt
103
+
104
+ ## 4.0.15 / 2026-06-24
105
+
106
+ ### Enhancements:
107
+
108
+ * Resolve Git LFS files in git sources from the real remote. Pull request [#9632](https://github.com/ruby/rubygems/pull/9632) by hsbt
109
+ * Suggest access issues, not only yanking, for missing locked gems. Pull request [#9631](https://github.com/ruby/rubygems/pull/9631) by hsbt
110
+ * Implement a make jobserver (continuation of #9210). Pull request [#9625](https://github.com/ruby/rubygems/pull/9625) by hsbt
111
+ * Reduce peak memory usage of full index loading and bundle install. Pull request [#9618](https://github.com/ruby/rubygems/pull/9618) by hsbt
112
+ * Bump up to rb-sys 0.9.128. Pull request [#9569](https://github.com/ruby/rubygems/pull/9569) by hsbt
113
+
114
+ ### Bug fixes:
115
+
116
+ * Skip the make jobserver on Windows. Pull request [#9630](https://github.com/ruby/rubygems/pull/9630) by hsbt
117
+ * Don't require source plugins to be installed to parse a lockfile: 4.0.x. Pull request [#9621](https://github.com/ruby/rubygems/pull/9621) by hsbt
118
+ * Exempt lockfile versions from cooldown on every resolution path. Pull request [#9619](https://github.com/ruby/rubygems/pull/9619) by hsbt
119
+ * Set `Bundler.settings[:ssl_ca_cert]` to download gems. Pull request [#9610](https://github.com/ruby/rubygems/pull/9610) by junaruga
120
+
121
+ ## 4.0.14 / 2026-06-10
122
+
123
+ ### Bug fixes:
124
+
125
+ * Preserve per-source cooldown when converging sources from the lockfile. Pull request [#9601](https://github.com/ruby/rubygems/pull/9601) by bryanwoods
126
+ * Don't exclude the locked version from cooldown during bundle update. Pull request [#9599](https://github.com/ruby/rubygems/pull/9599) by hsbt
127
+
128
+ ## 4.0.13 / 2026-06-03
129
+
130
+ ### Enhancements:
131
+
132
+ * Do not hard-code permissions for new gem directories during bundle install. Pull request [#9557](https://github.com/ruby/rubygems/pull/9557) by maxfelsher-cgi
133
+ * Clear gem specification cache after acquiring process lock. Pull request [#9310](https://github.com/ruby/rubygems/pull/9310) by ngan
134
+ * Show release date with bundle outdated. Pull request [#9337](https://github.com/ruby/rubygems/pull/9337) by hsbt
135
+
136
+ ### Bug fixes:
137
+
138
+ * Apply cooldown to locally installed gem versions. Pull request [#9582](https://github.com/ruby/rubygems/pull/9582) by hsbt
139
+
140
+ ### Security:
141
+
142
+ * Add `cooldown` to delay newly published gem. Pull request [#9576](https://github.com/ruby/rubygems/pull/9576) by hsbt
143
+
144
+ ## 4.0.12 / 2026-05-20
145
+
146
+ ### Enhancements:
147
+
148
+ * Make `bundle config get` return status 1 when the value is not set. Pull request [#9505](https://github.com/ruby/rubygems/pull/9505) by willnet
149
+ * Use Pathname#absolute?. Pull request [#9529](https://github.com/ruby/rubygems/pull/9529) by nobu
150
+ * Deprecate parsing non-lockfile content in LockfileParser. Pull request [#9502](https://github.com/ruby/rubygems/pull/9502) by kurotaky
151
+ * Print a warning for a potential confusion from the indirect dependencies. Pull request [#5029](https://github.com/ruby/rubygems/pull/5029) by junaruga
152
+ * Respect Gemfile bundler setting in `Bundler.setup`. Pull request [#4892](https://github.com/ruby/rubygems/pull/4892) by godfat
153
+
154
+ ### Bug fixes:
155
+
156
+ * Gracefully handle missing checksums in Compact Index. Pull request [#9492](https://github.com/ruby/rubygems/pull/9492) by jneen
157
+ * Skip git source exclusion when lockfile cannot backfill. Pull request [#9544](https://github.com/ruby/rubygems/pull/9544) by yahonda
158
+ * Fix bundle config gemfile unset behavior. Pull request [#9514](https://github.com/ruby/rubygems/pull/9514) by afurm
159
+
160
+ ## 4.0.11 / 2026-04-30
161
+
162
+ ### Enhancements:
163
+
164
+ * Update gem creation guide URL to rubygems.org. Pull request [#9500](https://github.com/ruby/rubygems/pull/9500) by nissyi-gh
165
+ * Lock the checksum of Bundler itself in the lockfile. Pull request [#9366](https://github.com/ruby/rubygems/pull/9366) by Edouard-chin
166
+
167
+ ### Bug fixes:
168
+
169
+ * Fix installing gems with native extensions + transitive dependencies. Pull request [#9477](https://github.com/ruby/rubygems/pull/9477) by nicholasdower
170
+ * Fix the bundler version not being updated in dev/test lockfile. Pull request [#9463](https://github.com/ruby/rubygems/pull/9463) by Edouard-chin
171
+ * Ensure the release CI doesn't break due to the Bundler checksum feature. Pull request [#9436](https://github.com/ruby/rubygems/pull/9436) by Edouard-chin
172
+
173
+ ### Documentation:
174
+
175
+ * Fix formatting for BUNDLE_PREFER_PATCH variable in man page. Pull request [#9474](https://github.com/ruby/rubygems/pull/9474) by toy
176
+
3
177
  ## 4.0.10 / 2026-04-08
4
178
 
5
179
  ### Enhancements:
data/bundler.gemspec CHANGED
@@ -24,9 +24,9 @@ Gem::Specification.new do |s|
24
24
 
25
25
  s.metadata = {
26
26
  "bug_tracker_uri" => "https://github.com/ruby/rubygems/issues?q=is%3Aopen+is%3Aissue+label%3ABundler",
27
- "changelog_uri" => "https://github.com/ruby/rubygems/blob/master/bundler/CHANGELOG.md",
27
+ "changelog_uri" => "https://github.com/ruby/rubygems/blob/master/CHANGELOG-bundler.md",
28
28
  "homepage_uri" => "https://bundler.io/",
29
- "source_code_uri" => "https://github.com/ruby/rubygems/tree/master/bundler",
29
+ "source_code_uri" => "https://github.com/ruby/rubygems",
30
30
  }
31
31
 
32
32
  s.required_ruby_version = ">= 3.2.0"
@@ -4,8 +4,8 @@ module Bundler
4
4
  # Represents metadata from when the Bundler gem was built.
5
5
  module BuildMetadata
6
6
  # begin ivars
7
- @built_at = nil
8
- @git_commit_sha = "1c1d885018".freeze
7
+ @built_at = "2026-09-02".freeze
8
+ @git_commit_sha = "7f2502dc32b".freeze
9
9
  # end ivars
10
10
 
11
11
  # A hash representation of the build metadata.
@@ -14,6 +14,9 @@ module Bundler
14
14
  def run
15
15
  Bundler.ui.level = "warn" if options[:quiet]
16
16
 
17
+ Bundler::CLI::Common.validate_cooldown!(options[:cooldown])
18
+ Bundler.settings.set_command_option_if_given :cooldown, options[:cooldown]
19
+
17
20
  validate_options!
18
21
  inject_dependencies
19
22
  perform_bundle_install unless options["skip-install"]
@@ -12,6 +12,7 @@ module Bundler
12
12
  Bundler.settings.set_command_option_if_given :path, options[:path]
13
13
 
14
14
  definition = Bundler.definition
15
+ definition.ensure_equivalent_gemfile_and_lockfile
15
16
  definition.validate_runtime!
16
17
 
17
18
  begin
@@ -28,9 +29,6 @@ module Bundler
28
29
  not_installed.each {|s| Bundler.ui.error " * #{s.name} (#{s.version})" }
29
30
  Bundler.ui.warn "Install missing gems with `bundle install`"
30
31
  exit 1
31
- elsif !Bundler.default_lockfile.file? && Bundler.frozen_bundle?
32
- Bundler.ui.error "This bundle has been frozen, but there is no #{SharedHelpers.relative_lockfile_path} present"
33
- exit 1
34
32
  else
35
33
  definition.lock(true) unless options[:"dry-run"]
36
34
  Bundler.ui.info "The Gemfile's dependencies are satisfied"
@@ -2,6 +2,12 @@
2
2
 
3
3
  module Bundler
4
4
  module CLI::Common
5
+ def self.validate_cooldown!(value)
6
+ return if value.nil?
7
+ return if value.is_a?(Integer) && value >= 0
8
+ raise InvalidOption, "Expected `--cooldown` to be a non-negative integer, got #{value.inspect}"
9
+ end
10
+
5
11
  def self.output_post_install_messages(messages)
6
12
  return if Bundler.settings["ignore_messages"]
7
13
  messages.to_a.each do |name, msg|
@@ -14,6 +20,17 @@ module Bundler
14
20
  Bundler.ui.info msg
15
21
  end
16
22
 
23
+ def self.output_cooldown_skipped_summary(definition = Bundler.definition)
24
+ skipped = definition.cooldown_skipped
25
+ return if skipped.empty?
26
+
27
+ Bundler.ui.info "The following gem versions were skipped by the cooldown setting:"
28
+ skipped.each do |entry|
29
+ days = entry[:available_in_days]
30
+ Bundler.ui.info " * #{entry[:name]} #{entry[:version]} (available in #{days} #{days == 1 ? "day" : "days"}), resolved #{entry[:resolved]} instead"
31
+ end
32
+ end
33
+
17
34
  def self.output_fund_metadata_summary
18
35
  return if Bundler.settings["ignore_funding_requests"]
19
36
  definition = Bundler.definition
@@ -87,16 +87,21 @@ module Bundler
87
87
 
88
88
  if value.nil?
89
89
  warn_unused_scope "Ignoring --#{scope} since no value to set was given"
90
+ current_value = Bundler.settings[name]
90
91
 
91
92
  if options[:parseable]
92
93
  if value = Bundler.settings[name]
93
94
  Bundler.ui.info("#{name}=#{value}")
94
95
  end
95
- return
96
+ else
97
+ confirm(name)
96
98
  end
97
99
 
98
- confirm(name)
99
- return
100
+ if current_value.nil?
101
+ exit 1
102
+ else
103
+ return
104
+ end
100
105
  end
101
106
 
102
107
  Bundler.ui.info(message) if message
@@ -53,7 +53,7 @@ module Bundler
53
53
  end
54
54
 
55
55
  def bundles_for_gem(spec)
56
- Dir.glob("#{spec.full_gem_path}/**/*.bundle")
56
+ SharedHelpers.glob_files_in_dir("**/*.bundle", spec.full_gem_path)
57
57
  end
58
58
 
59
59
  def lookup_with_fiddle(path)
@@ -23,7 +23,7 @@ module Bundler
23
23
  bin_path.delete_suffix!(".bat") if Gem.win_platform?
24
24
  kernel_load(bin_path, *args)
25
25
  else
26
- bin_path = "./" + bin_path unless File.absolute_path?(bin_path)
26
+ bin_path = explicit_path(bin_path)
27
27
  kernel_exec(bin_path, *args)
28
28
  end
29
29
  else
@@ -71,6 +71,20 @@ module Bundler
71
71
  "#{file} #{args.join(" ")}".strip
72
72
  end
73
73
 
74
+ def explicit_path(path)
75
+ if File.absolute_path?(path) || explicit_relative_path?(path)
76
+ path
77
+ else
78
+ ".#{File::SEPARATOR}#{path}"
79
+ end
80
+ end
81
+
82
+ def explicit_relative_path?(path)
83
+ [File::SEPARATOR, File::ALT_SEPARATOR].compact.any? do |separator|
84
+ path.start_with?(".#{separator}", "..#{separator}")
85
+ end
86
+ end
87
+
74
88
  def directly_loadable?(file)
75
89
  if Gem.win_platform?
76
90
  script_wrapper?(file)
@@ -256,8 +256,7 @@ module Bundler
256
256
 
257
257
  if use_git
258
258
  Bundler.ui.info "\nInitializing git repo in #{target}"
259
- require "shellwords"
260
- `git init #{target.to_s.shellescape}`
259
+ IO.popen(["git", "init", target.to_s], &:read)
261
260
 
262
261
  config[:git_default_branch] = File.read("#{target}/.git/HEAD").split("/").last.chomp
263
262
  end
@@ -288,7 +287,7 @@ module Bundler
288
287
  open_editor(options["edit"], target.join("#{name}.gemspec")) if options[:edit]
289
288
 
290
289
  Bundler.ui.info "\nGem '#{name}' was successfully created. " \
291
- "For more information on making a RubyGem visit https://bundler.io/guides/creating_gem.html"
290
+ "For more information on making a RubyGem visit https://guides.rubygems.org/make-your-own-gem/"
292
291
  end
293
292
 
294
293
  private
@@ -26,6 +26,10 @@ module Bundler
26
26
  end
27
27
 
28
28
  spec = Bundler.load_gemspec_uncached(gemspec)
29
+ unless spec
30
+ Bundler.ui.error "Gem specification #{gemspec} did not produce a specification"
31
+ exit 1
32
+ end
29
33
 
30
34
  File.open(gemfile, "wb") do |file|
31
35
  file << "# Generated from #{gemspec}\n"
@@ -64,6 +64,7 @@ module Bundler
64
64
  end
65
65
 
66
66
  Bundler::CLI::Common.output_post_install_messages installer.post_install_messages
67
+ Bundler::CLI::Common.output_cooldown_skipped_summary(definition)
67
68
 
68
69
  if CLI::Common.clean_after_install?
69
70
  require_relative "clean"
@@ -112,6 +113,9 @@ module Bundler
112
113
 
113
114
  Bundler.settings.set_command_option_if_given :jobs, options["jobs"]
114
115
 
116
+ Bundler::CLI::Common.validate_cooldown!(options["cooldown"])
117
+ Bundler.settings.set_command_option_if_given :cooldown, options["cooldown"]
118
+
115
119
  Bundler.settings.set_command_option_if_given :no_prune, options["no-prune"]
116
120
 
117
121
  Bundler.settings.set_command_option_if_given :no_install, options["no-install"]
@@ -13,10 +13,10 @@ module Bundler
13
13
  https://github.com/ruby/rubygems/blob/master/doc/bundler/TROUBLESHOOTING.md
14
14
 
15
15
  2. Instructions for common Bundler uses can be found on the documentation
16
- site: https://bundler.io/
16
+ site: https://guides.rubygems.org/
17
17
 
18
18
  3. Information about each Bundler command can be found in the Bundler
19
- man pages: https://bundler.io/man/bundle.1.html
19
+ man pages: https://guides.rubygems.org/command-reference/bundle/
20
20
 
21
21
  Hopefully the troubleshooting steps above resolved your problem! If things
22
22
  still aren't working the way you expect them to, please let us know so
@@ -16,6 +16,9 @@ module Bundler
16
16
 
17
17
  check_for_conflicting_options
18
18
 
19
+ Bundler::CLI::Common.validate_cooldown!(options[:cooldown])
20
+ Bundler.settings.set_command_option_if_given :cooldown, options[:cooldown]
21
+
19
22
  print = options[:print]
20
23
  previous_output_stream = Bundler.ui.output_stream
21
24
  Bundler.ui.output_stream = :stderr if print
@@ -23,6 +26,9 @@ module Bundler
23
26
  Bundler::Fetcher.disable_endpoint = options["full-index"]
24
27
 
25
28
  update = options[:update]
29
+ # --update is repeatable, so it parses as an array with one entry per
30
+ # occurrence, where a bare `--update` produces a `true` entry
31
+ update = update.include?(true) ? true : update.flatten if update.is_a?(Array)
26
32
  conservative = options[:conservative]
27
33
  bundler = options[:bundler]
28
34
 
@@ -41,12 +47,12 @@ module Bundler
41
47
 
42
48
  Bundler::CLI::Common.configure_gem_version_promoter(definition, options) if options[:update]
43
49
 
44
- options["remove-platform"].each do |platform_string|
50
+ options["remove-platform"].flatten.each do |platform_string|
45
51
  platform = Gem::Platform.new(platform_string)
46
52
  definition.remove_platform(platform)
47
53
  end
48
54
 
49
- options["add-platform"].each do |platform_string|
55
+ options["add-platform"].flatten.each do |platform_string|
50
56
  platform = Gem::Platform.new(platform_string)
51
57
  if platform.to_s == "unknown"
52
58
  Bundler.ui.error "The platform `#{platform_string}` is unknown to RubyGems and can't be added to the lockfile."
@@ -74,6 +80,8 @@ module Bundler
74
80
  puts "Writing lockfile to #{file}"
75
81
  definition.write_lock(file, false)
76
82
  end
83
+
84
+ Bundler::CLI::Common.output_cooldown_skipped_summary(definition)
77
85
  end
78
86
 
79
87
  Bundler.ui.output_stream = previous_output_stream
@@ -18,12 +18,22 @@ module Bundler
18
18
  Bundler.ui.info "Unable to open #{name} because it's a default gem, so the directory it would normally be installed to does not exist."
19
19
  else
20
20
  root_path = spec.full_gem_path
21
- require "shellwords"
22
- command = Shellwords.split(editor) << File.join([root_path, path].compact)
21
+ command = editor_command(editor) << File.join([root_path, path].compact)
23
22
  Bundler.with_original_env do
24
23
  system(*command, { chdir: root_path })
25
24
  end || Bundler.ui.info("Could not run '#{command.join(" ")}'")
26
25
  end
27
26
  end
27
+
28
+ def editor_command(editor)
29
+ # On Windows an editor is often configured with a full path such as
30
+ # C:\Program Files\Microsoft VS Code\Code.exe, which shell splitting
31
+ # would corrupt. Take a value that names an existing file as a
32
+ # single word.
33
+ return [editor] if Gem.win_platform? && File.file?(editor)
34
+
35
+ require "shellwords"
36
+ Shellwords.split(editor)
37
+ end
28
38
  end
29
39
  end
@@ -26,6 +26,9 @@ module Bundler
26
26
  def run
27
27
  check_for_deployment_mode!
28
28
 
29
+ Bundler::CLI::Common.validate_cooldown!(options[:cooldown])
30
+ Bundler.settings.set_command_option_if_given :cooldown, options[:cooldown]
31
+
29
32
  Bundler.definition.validate_runtime!
30
33
  current_specs = Bundler.ui.silence { Bundler.definition.resolve }
31
34
 
@@ -155,11 +158,29 @@ module Bundler
155
158
 
156
159
  return active_spec if strict
157
160
 
158
- active_specs = active_spec.source.specs.search(current_spec.name).select {|spec| spec.installable_on_platform?(current_spec.platform) }.sort_by(&:version)
159
- if !current_spec.version.prerelease? && !options[:pre] && active_specs.size > 1
160
- active_specs.delete_if {|b| b.respond_to?(:version) && b.version.prerelease? }
161
+ matching_specs(active_spec, current_spec).last
162
+ end
163
+
164
+ def matching_specs(active_spec, current_spec)
165
+ @matching_specs ||= {}
166
+ @matching_specs[[active_spec.source, current_spec.name, current_spec.platform]] ||= begin
167
+ active_specs = active_spec.source.specs.search(current_spec.name).select {|spec| spec.installable_on_platform?(current_spec.platform) }.sort_by(&:version)
168
+ if !current_spec.version.prerelease? && !options[:pre] && active_specs.size > 1
169
+ active_specs.delete_if {|b| b.respond_to?(:version) && b.version.prerelease? }
170
+ end
171
+ active_specs
161
172
  end
162
- active_specs.last
173
+ end
174
+
175
+ # The newest version the cooldown setting would let bundler adopt right
176
+ # now, when the newest overall version is still inside the window. Only a
177
+ # version strictly between the installed one and the newest one is an
178
+ # adoptable update worth showing.
179
+ def newest_out_of_cooldown(active_spec, current_spec)
180
+ newest = matching_specs(active_spec, current_spec).reverse_each.find {|spec| cooldown_days_remaining(spec).nil? }
181
+ return unless newest
182
+ return if newest.version >= active_spec.version || newest.version <= current_spec.version
183
+ newest
163
184
  end
164
185
 
165
186
  def print_gems(gems_list)
@@ -199,7 +220,19 @@ module Bundler
199
220
  end
200
221
 
201
222
  spec_outdated_info = "#{active_spec.name} (newest #{spec_version}, " \
202
- "installed #{current_version}#{dependency_version})"
223
+ "installed #{current_version}#{dependency_version}"
224
+
225
+ release_date = release_date_for(active_spec)
226
+ spec_outdated_info += ", released #{release_date}" unless release_date.empty?
227
+
228
+ remaining = cooldown_days_remaining(active_spec)
229
+ if remaining
230
+ spec_outdated_info += ", in cooldown for #{remaining} more day#{"s" if remaining > 1}"
231
+ adoptable = newest_out_of_cooldown(active_spec, current_spec)
232
+ spec_outdated_info += ", newest out of cooldown #{adoptable.version}" if adoptable
233
+ end
234
+
235
+ spec_outdated_info += ")"
203
236
 
204
237
  output_message = if options[:parseable]
205
238
  spec_outdated_info.to_s
@@ -215,13 +248,33 @@ module Bundler
215
248
  def gem_column_for(current_spec, active_spec, dependency, groups)
216
249
  current_version = "#{current_spec.version}#{current_spec.git_version}"
217
250
  spec_version = "#{active_spec.version}#{active_spec.git_version}"
251
+ remaining = cooldown_days_remaining(active_spec)
252
+ if remaining
253
+ adoptable = newest_out_of_cooldown(active_spec, current_spec)
254
+ adoptable_note = adoptable ? ", #{adoptable.version} out of cooldown" : ""
255
+ spec_version += " (cooldown #{remaining}d#{adoptable_note})"
256
+ end
218
257
  dependency = dependency.requirement if dependency
219
258
 
220
259
  ret_val = [active_spec.name, current_version, spec_version, dependency.to_s, groups.to_s]
260
+ ret_val << release_date_for(active_spec)
221
261
  ret_val << loaded_from_for(active_spec).to_s if Bundler.ui.debug?
222
262
  ret_val
223
263
  end
224
264
 
265
+ def cooldown_days_remaining(spec, now = cooldown_now)
266
+ return nil unless spec.respond_to?(:created_at) && spec.created_at
267
+ return nil unless spec.respond_to?(:remote) && spec.remote
268
+ days = spec.remote.effective_cooldown
269
+ return nil if days.nil? || days <= 0
270
+ remaining = days - ((now - spec.created_at) / 86_400.0)
271
+ remaining > 0 ? remaining.ceil : nil
272
+ end
273
+
274
+ def cooldown_now
275
+ @cooldown_now ||= Time.now
276
+ end
277
+
225
278
  def check_for_deployment_mode!
226
279
  return unless Bundler.frozen_bundle?
227
280
  suggested_command = if Bundler.settings.locations("frozen").keys.&([:global, :local]).any?
@@ -283,11 +336,28 @@ module Bundler
283
336
  end
284
337
 
285
338
  def table_header
286
- header = ["Gem", "Current", "Latest", "Requested", "Groups"]
339
+ header = ["Gem", "Current", "Latest", "Requested", "Groups", "Release Date"]
287
340
  header << "Path" if Bundler.ui.debug?
288
341
  header
289
342
  end
290
343
 
344
+ def release_date_for(spec)
345
+ return "" unless spec.respond_to?(:date)
346
+
347
+ date = spec.date
348
+ return "" unless date
349
+
350
+ return "" unless Gem.const_defined?(:DEFAULT_SOURCE_DATE_EPOCH)
351
+ default_date = Time.at(Gem::DEFAULT_SOURCE_DATE_EPOCH).utc
352
+ default_date = Time.utc(default_date.year, default_date.month, default_date.day)
353
+
354
+ date = date.utc if date.respond_to?(:utc)
355
+
356
+ return "" if date == default_date
357
+
358
+ date.strftime("%Y-%m-%d")
359
+ end
360
+
291
361
  def justify(row, sizes)
292
362
  row.each_with_index.map do |element, index|
293
363
  element.ljust(sizes[index])
@@ -66,6 +66,8 @@ module Bundler
66
66
  opts["force"] = options[:redownload] if options[:redownload]
67
67
 
68
68
  Bundler.settings.set_command_option_if_given :jobs, opts["jobs"]
69
+ Bundler::CLI::Common.validate_cooldown!(options[:cooldown])
70
+ Bundler.settings.set_command_option_if_given :cooldown, options[:cooldown]
69
71
 
70
72
  Bundler.definition.validate_runtime!
71
73
 
@@ -116,6 +118,7 @@ module Bundler
116
118
  Bundler.ui.confirm "Bundle updated!"
117
119
  Bundler::CLI::Common.output_without_groups_message(:update)
118
120
  Bundler::CLI::Common.output_post_install_messages installer.post_install_messages
121
+ Bundler::CLI::Common.output_cooldown_skipped_summary
119
122
 
120
123
  Bundler::CLI::Common.output_fund_metadata_summary
121
124
  end