Skip to content

Commit 1f1309a

Browse files
hsbtclaude
andcommitted
Add a v2 compact index artifice and cover cooldown end-to-end
A `CompactIndexCooldownAPI` subclass overrides `build_gem_version` to emit `CompactIndex::GemVersionV2` with `created_at` sourced from `spec.date`, letting tests carry a deterministic timestamp per built gem. `spec/install/cooldown_spec.rb` exercises the source DSL keyword, `--cooldown` flag, `BUNDLE_COOLDOWN`, `bundle config set cooldown`, the rolling-delay filter, the lockfile bypass, and the CLI vs Gemfile precedence against the new artifice. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
1 parent 6f4b304 commit 1f1309a

4 files changed

Lines changed: 178 additions & 0 deletions

File tree

spec/install/cooldown_spec.rb

Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
# frozen_string_literal: true
2+
3+
RSpec.describe "bundle install with the cooldown setting" do
4+
before do
5+
build_repo2
6+
end
7+
8+
context "Gemfile DSL" do
9+
it "accepts `source ..., cooldown: N` without error" do
10+
install_gemfile <<-G, artifice: "compact_index"
11+
source "https://gem.repo2", cooldown: 5
12+
gem "myrack"
13+
G
14+
15+
expect(the_bundle).to include_gems("myrack 1.0.0")
16+
end
17+
18+
it "accepts `cooldown: 0` to disable cooldown for a source" do
19+
install_gemfile <<-G, artifice: "compact_index"
20+
source "https://gem.repo2", cooldown: 0
21+
gem "myrack"
22+
G
23+
24+
expect(the_bundle).to include_gems("myrack 1.0.0")
25+
end
26+
end
27+
28+
context "CLI flag" do
29+
before do
30+
gemfile <<-G
31+
source "https://gem.repo2"
32+
gem "myrack"
33+
G
34+
end
35+
36+
it "accepts --cooldown N on install" do
37+
bundle "install --cooldown 7", artifice: "compact_index"
38+
39+
expect(the_bundle).to include_gems("myrack 1.0.0")
40+
end
41+
42+
it "accepts --cooldown 0 as an escape hatch" do
43+
bundle "install --cooldown 0", artifice: "compact_index"
44+
45+
expect(the_bundle).to include_gems("myrack 1.0.0")
46+
end
47+
end
48+
49+
context "configuration" do
50+
it "reads BUNDLE_COOLDOWN as an integer" do
51+
gemfile <<-G
52+
source "https://gem.repo2"
53+
gem "myrack"
54+
G
55+
56+
bundle "install", env: { "BUNDLE_COOLDOWN" => "7" }, artifice: "compact_index"
57+
58+
expect(the_bundle).to include_gems("myrack 1.0.0")
59+
end
60+
61+
it "reads `bundle config set cooldown N`" do
62+
gemfile <<-G
63+
source "https://gem.repo2"
64+
gem "myrack"
65+
G
66+
67+
bundle "config set cooldown 7"
68+
bundle "install", artifice: "compact_index"
69+
70+
expect(the_bundle).to include_gems("myrack 1.0.0")
71+
end
72+
end
73+
74+
context "end-to-end with v2 compact index" do
75+
before do
76+
now = Time.now.utc
77+
build_repo3 do
78+
build_gem "ripe_gem", "1.0.0" do |s|
79+
s.date = now - (30 * 86_400)
80+
end
81+
build_gem "ripe_gem", "2.0.0" do |s|
82+
s.date = now - (1 * 86_400)
83+
end
84+
end
85+
end
86+
87+
it "excludes versions within the cooldown window" do
88+
gemfile <<-G
89+
source "https://gem.repo3"
90+
gem "ripe_gem"
91+
G
92+
93+
bundle "install --cooldown 7", artifice: "compact_index_cooldown"
94+
95+
expect(the_bundle).to include_gems("ripe_gem 1.0.0")
96+
end
97+
98+
it "selects the latest version when --cooldown 0 is passed" do
99+
gemfile <<-G
100+
source "https://gem.repo3"
101+
gem "ripe_gem"
102+
G
103+
104+
bundle "install --cooldown 0", artifice: "compact_index_cooldown"
105+
106+
expect(the_bundle).to include_gems("ripe_gem 2.0.0")
107+
end
108+
109+
it "applies cooldown declared per-source in the Gemfile" do
110+
gemfile <<-G
111+
source "https://gem.repo3", cooldown: 7
112+
gem "ripe_gem"
113+
G
114+
115+
bundle "install", artifice: "compact_index_cooldown"
116+
117+
expect(the_bundle).to include_gems("ripe_gem 1.0.0")
118+
end
119+
120+
it "is overridden by CLI --cooldown when Gemfile sets a different per-source value" do
121+
gemfile <<-G
122+
source "https://gem.repo3", cooldown: 0
123+
gem "ripe_gem"
124+
G
125+
126+
bundle "install --cooldown 7", artifice: "compact_index_cooldown"
127+
128+
expect(the_bundle).to include_gems("ripe_gem 1.0.0")
129+
end
130+
131+
it "bypasses cooldown when bundle install uses an existing lockfile" do
132+
gemfile <<-G
133+
source "https://gem.repo3"
134+
gem "ripe_gem"
135+
G
136+
137+
lockfile <<-L
138+
GEM
139+
remote: https://gem.repo3/
140+
specs:
141+
ripe_gem (2.0.0)
142+
143+
PLATFORMS
144+
#{lockfile_platforms}
145+
146+
DEPENDENCIES
147+
ripe_gem
148+
149+
BUNDLED WITH
150+
#{Bundler::VERSION}
151+
L
152+
153+
bundle "install --cooldown 7", artifice: "compact_index_cooldown"
154+
155+
expect(the_bundle).to include_gems("ripe_gem 2.0.0")
156+
end
157+
end
158+
end
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# frozen_string_literal: true
2+
3+
require_relative "helpers/compact_index_cooldown"
4+
require_relative "helpers/artifice"
5+
6+
Artifice.activate_with(CompactIndexCooldownAPI)
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# frozen_string_literal: true
2+
3+
require_relative "compact_index"
4+
5+
class CompactIndexCooldownAPI < CompactIndexAPI
6+
helpers do
7+
def build_gem_version(spec, deps, checksum)
8+
created_at = spec.date&.utc&.iso8601
9+
CompactIndex::GemVersionV2.new(spec.version.version, spec.platform.to_s, checksum, nil,
10+
deps, spec.required_ruby_version.to_s, spec.required_rubygems_version.to_s, created_at)
11+
end
12+
end
13+
end

spec/support/shards.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ module Shards
144144
],
145145
shard_d: [
146146
"spec/bundler/resolver/cooldown_spec.rb",
147+
"spec/install/cooldown_spec.rb",
147148
"spec/commands/outdated_spec.rb",
148149
"spec/commands/update_spec.rb",
149150
"spec/lock/lockfile_spec.rb",

0 commit comments

Comments
 (0)