gem_server_conformance 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cc996f39ef2b36f10b6888858981fff19bb5a06e547981643d3a8486a24b2aeb
4
- data.tar.gz: da7ab819c31d6e1d1c6915f91cc2b31148a7cd19747ad45d9fa0d4905bfef38f
3
+ metadata.gz: e786fdd6d0c53669a1dae6ada4c2944a8ef76b3eefc9b1d063a7b028cd74794c
4
+ data.tar.gz: 73bd34809a32bcacfda221a7fa0def504ae0c6b84e032230ec281e8265adf496
5
5
  SHA512:
6
- metadata.gz: 1ce259e3b57721291668320ecf6f547809aceb5f41d7f5dce41624724d38fad03011c839e749cc4b369630a435683d65e91d0d3b07e277a7a9c2dc4806930ea4
7
- data.tar.gz: 14ba296d864bebcdb5b4d0d5f857def2d33d3285b76f74816e2736afd828a1117660829e87bd5a8fc11917c58e4223d5062b5667c18b8592da94b786bc1f3d24
6
+ metadata.gz: 5af656dcb9dd845788e1b19a6b6260a05e7b4c80cfc8574562f6f05e4b3d8e1fc580faaf266df8354943be60a955e416ad45812457853ad711db5f1bc17a5ba3
7
+ data.tar.gz: 9518b5752df1559976fc7a7ebd8a2b8f933a2e1d4654e1f2dec406e80fd606b40ab9b70c44971b6ba58a5f6611a35f8242d237094689e173bac59c8ff41825c3
@@ -112,6 +112,11 @@ module GemServerConformance
112
112
 
113
113
  def push(gem)
114
114
  package = Gem::Package.new(StringIO.new(gem))
115
+ begin
116
+ package.spec
117
+ rescue Gem::Package::FormatError, Psych::SyntaxError => e
118
+ return [400, {}, ["Invalid gem: #{e.message}"]]
119
+ end
115
120
  log "Pushed #{package.spec.full_name}"
116
121
  if @versions.any? { |v| v.package.spec.full_name == package.spec.full_name }
117
122
  return [409, {}, ["Conflict: #{package.spec.full_name} already exists"]]
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module GemServerConformance
4
- VERSION = "0.1.0"
4
+ VERSION = "0.1.1"
5
5
  end
@@ -7,6 +7,7 @@ RSpec.describe GemServerConformance do # rubocop:disable RSpec/EmptyExampleGroup
7
7
 
8
8
  before(:all) do
9
9
  Gem.configuration.verbose = false
10
+ Gem::DefaultUserInteraction.ui = Gem::SilentUI.new
10
11
  ENV["SOURCE_DATE_EPOCH"] = "0"
11
12
  end
12
13
 
@@ -61,12 +62,162 @@ RSpec.describe GemServerConformance do # rubocop:disable RSpec/EmptyExampleGroup
61
62
  } do
62
63
  pushed_gem("a-1.0.0")
63
64
 
65
+ @ctx.it "has the exact contents as expected" do
66
+ allow(RSpec::Support::ObjectFormatter.default_instance).to receive(:prepare_for_inspection).and_call_original
67
+ allow(RSpec::Support::ObjectFormatter.default_instance)
68
+ .to receive(:prepare_for_inspection).with(an_instance_of(String)) { |s| s }
69
+ io = StringIO.new(@gem_a_1_0_0.contents)
70
+ io.binmode
71
+ package = Gem::Package.new(io)
72
+ actual = []
73
+
74
+ presence = proc do |x|
75
+ x if x && !x.empty?
76
+ end
77
+
78
+ dump_tar = proc do |tar_io, into = actual|
79
+ Gem::Package::TarReader.new(tar_io) do |gem|
80
+ gem.each do |entry|
81
+ body = entry.read
82
+ extra = nil
83
+ if entry.full_name.end_with?(".gz")
84
+ extra = Zlib::GzipReader.wrap(StringIO.new(body)) do |gz|
85
+ magic, compression_method, flags, mtime, compression, os_id = body.unpack("H4ccVcC")
86
+ {
87
+ magic: magic, compression_method: compression_method, flags: flags, mtime: mtime,
88
+ compression: compression, os_id: os_id, comment: presence[gz.comment], crc: gz.crc,
89
+ orig_name: presence[gz.orig_name]
90
+ }.compact
91
+ end
92
+ body = Zlib.gunzip(body)
93
+ end
94
+ body = dump_tar[StringIO.new(body), []] if entry.full_name.end_with?(".tar.gz")
95
+
96
+ into << {
97
+ header: entry.header.instance_variables.to_h do |ivar|
98
+ [ivar.to_s.tr("@", "").to_sym, entry.header.instance_variable_get(ivar)]
99
+ end,
100
+ body: body,
101
+ extra: extra
102
+ }.compact
103
+ end
104
+ end
105
+ into
106
+ end
107
+ package.gem.with_read_io(&dump_tar)
108
+ expected_gz_extra = { compression: 2, compression_method: 8, crc: 0, flags: 0, magic: "1f8b", mtime: 0,
109
+ os_id: 3 }
110
+ expect(actual).to eq(
111
+ [{ body: <<~YAML,
112
+ --- !ruby/object:Gem::Specification
113
+ name: a
114
+ version: !ruby/object:Gem::Version
115
+ version: 1.0.0
116
+ platform: ruby
117
+ authors:
118
+ - Conformance
119
+ bindir: bin
120
+ cert_chain: []
121
+ date: 2024-07-09 00:00:00.000000000 Z
122
+ dependencies: []
123
+ executables: []
124
+ extensions: []
125
+ extra_rdoc_files: []
126
+ files: []
127
+ licenses: []
128
+ metadata: {}
129
+ rdoc_options: []
130
+ require_paths:
131
+ - lib
132
+ required_ruby_version: !ruby/object:Gem::Requirement
133
+ requirements:
134
+ - - ">="
135
+ - !ruby/object:Gem::Version
136
+ version: '0'
137
+ required_rubygems_version: !ruby/object:Gem::Requirement
138
+ requirements:
139
+ - - ">="
140
+ - !ruby/object:Gem::Version
141
+ version: '0'
142
+ requirements: []
143
+ rubygems_version: 3.5.11
144
+ specification_version: 4
145
+ summary: Conformance test
146
+ test_files: []
147
+ YAML
148
+ header: { checksum: 5894,
149
+ devmajor: 0,
150
+ devminor: 0,
151
+ empty: false,
152
+ gid: 0,
153
+ gname: "wheel",
154
+ linkname: "",
155
+ magic: "ustar",
156
+ mode: 292,
157
+ mtime: 0,
158
+ name: "metadata.gz",
159
+ prefix: "",
160
+ size: 318,
161
+ typeflag: "0",
162
+ uid: 0,
163
+ uname: "wheel",
164
+ version: 0 },
165
+ extra: expected_gz_extra },
166
+ { body: [],
167
+ header: { checksum: 5834,
168
+ devmajor: 0,
169
+ devminor: 0,
170
+ empty: false,
171
+ gid: 0,
172
+ gname: "wheel",
173
+ linkname: "",
174
+ magic: "ustar",
175
+ mode: 292,
176
+ mtime: 0,
177
+ name: "data.tar.gz",
178
+ prefix: "",
179
+ size: 35,
180
+ typeflag: "0",
181
+ uid: 0,
182
+ uname: "wheel",
183
+ version: 0 },
184
+ extra: expected_gz_extra },
185
+ { body: <<~YAML,
186
+ ---
187
+ SHA256:
188
+ metadata.gz: 5a1eb70f836c830856bd6ff54ae48916e6f5f297608012575884131c74089b36
189
+ data.tar.gz: 6578c1623326a8b876f84c946634f7208ce54f23a75fa5775b44469ddb08a8e7
190
+ SHA512:
191
+ metadata.gz: 26dbf51d174890d592f13c0bccc6638e02e34f603684e9df7320508f777bf9da5061dd13f8262eef47ddcc0d975e33a9eead945de9544bbb4fd9358cfda0f026
192
+ data.tar.gz: ea28bfbb44a5ca539ed7b50c492c0a5aa6cce60f7babad5c65cb2aca5c100ac350fb28eeb1c4ae32c8cf22c2724595b946e1cb12f521eeaf0a7246a26aad00a0
193
+ YAML
194
+ header: { checksum: 6506,
195
+ devmajor: 0,
196
+ devminor: 0,
197
+ empty: false,
198
+ gid: 0,
199
+ gname: "wheel",
200
+ linkname: "",
201
+ magic: "ustar",
202
+ mode: 292,
203
+ mtime: 0,
204
+ name: "checksums.yaml.gz",
205
+ prefix: "",
206
+ size: 295,
207
+ typeflag: "0",
208
+ uid: 0,
209
+ uname: "wheel",
210
+ version: 0 },
211
+ extra: expected_gz_extra }]
212
+ )
213
+ end
214
+
64
215
  request :get_versions, compact_index: true do
65
216
  it { is_expected.to be_valid_compact_index_reponse }
66
217
 
67
218
  it {
68
219
  is_expected.to have_body(
69
- parent_response.body + "a 1.0.0 8761412e66a014fe80723e251d96be29\n"
220
+ parent_response.body + "a 1.0.0 443730449deef440bd299e19554793f0\n"
70
221
  )
71
222
  }
72
223
  end
@@ -75,7 +226,7 @@ RSpec.describe GemServerConformance do # rubocop:disable RSpec/EmptyExampleGroup
75
226
  it { is_expected.to be_ok }
76
227
  it { is_expected.to have_body(<<~INFO) }
77
228
  ---
78
- 1.0.0 |checksum:2dfc054a348d36faae6e98e8c0222a76c07cfa0620b3c47acb154cb3d2de149b
229
+ 1.0.0 |checksum:9bc2cb93a200173fcd556c6c674bb4cdbce9b284e5dea0be9c21ee801f38b821
79
230
  INFO
80
231
  it { is_expected.to have_header("content-type").with_value("text/plain; charset=utf-8") }
81
232
  end
@@ -152,15 +303,15 @@ RSpec.describe GemServerConformance do # rubocop:disable RSpec/EmptyExampleGroup
152
303
  request :get_versions, compact_index: true do
153
304
  it { is_expected.to be_valid_compact_index_reponse }
154
305
  it { is_expected.to have_body(parent_response.body + <<~BODY) }
155
- a 0.0.1 22428c91ad748146bec818307104ed33
156
- b 1.0.0.pre 688f5cdf79887aff5d87c86f36cfe063
306
+ a 0.0.1 8ffe0a0dda27362c6f916d3941a5726e
307
+ b 1.0.0.pre f0d229a9323895e2e1c85f496b5f10b5
157
308
  BODY
158
309
  end
159
310
 
160
311
  request :get_info, "a", compact_index: true do
161
312
  it { is_expected.to be_valid_compact_index_reponse }
162
313
  it { is_expected.to have_body(parent_response.body + <<~INFO) }
163
- 0.0.1 |checksum:5e25d516b8c19c9d26ef95efad565c2097865a0d3dba5ef3fade650a2e690b35
314
+ 0.0.1 |checksum:a2bee9c1c6b2ab54a19c4d4644663eda25c2326bebe0eb9f9c097a2a11fd6203
164
315
  INFO
165
316
  end
166
317
 
@@ -168,7 +319,7 @@ RSpec.describe GemServerConformance do # rubocop:disable RSpec/EmptyExampleGroup
168
319
  it { is_expected.to be_valid_compact_index_reponse }
169
320
  it { is_expected.to have_body(<<~INFO) }
170
321
  ---
171
- 1.0.0.pre a:< 1.0.0&>= 0.1.0|checksum:3f97419b7c35257f7aab3ae37521ab64ef8ec7646ef55b9f6a5e41d479bc128c,ruby:>= 2.0,rubygems:>= 2.0
322
+ 1.0.0.pre a:< 1.0.0&>= 0.1.0|checksum:4096fbca288dcf4b4cea8bbebdea5d10d6b3f4fd2ff3c13124852854d5d7d24b,ruby:>= 2.0,rubygems:>= 2.0
172
323
  INFO
173
324
  end
174
325
 
@@ -268,18 +419,18 @@ RSpec.describe GemServerConformance do # rubocop:disable RSpec/EmptyExampleGroup
268
419
  request :get_versions, compact_index: true do
269
420
  it { is_expected.to be_valid_compact_index_reponse }
270
421
  it { is_expected.to have_body(parent_response.body + <<~BODY) }
271
- a 0.2.0 7a7528379bbd1e0420ea7f1305ba526a
272
- a 0.2.0-x86-mingw32 17f9c2882d6f0a244f8bba2df1d14107
273
- a 0.2.0-java ca5c12bc8ba4457ada41c71bee282bfb
422
+ a 0.2.0 66fab29417d3142772e0f2467b92d684
423
+ a 0.2.0-x86-mingw32 fd6d38ccbc3556b4426c65fceed9c717
424
+ a 0.2.0-java 704774b40118bdb16676deee38a99030
274
425
  BODY
275
426
  end
276
427
 
277
428
  request :get_info, "a", compact_index: true do
278
429
  it { is_expected.to be_valid_compact_index_reponse }
279
430
  it { is_expected.to have_body(parent_response.body + <<~INFO) }
280
- 0.2.0 |checksum:a1753a0e8b6f0515a15e9cfa4ea143e36de235525f6f68c4ff45c4ae70be072f
281
- 0.2.0-x86-mingw32 |checksum:e330e73d0dec030107c5656bbe89aecae738ba483471bf87f1bd943093fc9f27
282
- 0.2.0-java |checksum:897332272ac159bf200a690dae5039df1e60355124848f2a6f889563311421f4
431
+ 0.2.0 |checksum:6f2d3eb31a402d2be7c7d51d52e22ba9c86ca7b0641a3debfb3deadedc19301f
432
+ 0.2.0-x86-mingw32 |checksum:d2bb53926789434de893cf0a7a872bd887440f6e4edfec15626961d5431aad8a
433
+ 0.2.0-java |checksum:63ed6f9d68ebfea869389a9227c8c041b9ed7a0ea68dbe37ee12aaa17406c524
283
434
  INFO
284
435
  end
285
436
 
@@ -323,8 +474,8 @@ RSpec.describe GemServerConformance do # rubocop:disable RSpec/EmptyExampleGroup
323
474
  it { is_expected.to have_body(<<~BODY) }
324
475
  created_at: 1990-01-01T01:08:00Z
325
476
  ---
326
- a 0.0.1,0.2.0,0.2.0-x86-mingw32,0.2.0-java ca5c12bc8ba4457ada41c71bee282bfb
327
- b 1.0.0.pre 688f5cdf79887aff5d87c86f36cfe063
477
+ a 0.0.1,0.2.0,0.2.0-x86-mingw32,0.2.0-java 704774b40118bdb16676deee38a99030
478
+ b 1.0.0.pre f0d229a9323895e2e1c85f496b5f10b5
328
479
  BODY
329
480
  end
330
481
  end
@@ -334,14 +485,14 @@ RSpec.describe GemServerConformance do # rubocop:disable RSpec/EmptyExampleGroup
334
485
  request :get_versions, compact_index: true do
335
486
  it { is_expected.to be_valid_compact_index_reponse }
336
487
  it { is_expected.to have_body(parent_response.body + <<~BODY) }
337
- a 0.3.0 6263c53d5a23dfe0339a3ebae0fed8da
488
+ a 0.3.0 6d832e39a3fcc2e49f17db8023b3db31
338
489
  BODY
339
490
  end
340
491
 
341
492
  request :get_info, "a", compact_index: true do
342
493
  it { is_expected.to be_valid_compact_index_reponse }
343
494
  it { is_expected.to have_body(parent_response.body + <<~INFO) }
344
- 0.3.0 |checksum:40f19de3ce5c3fc5930fbc5dc3a08cd0b31572852d4885b37a19039bad7d9784
495
+ 0.3.0 |checksum:896df5352ce069a200e283d04bf2cbadcc5f779de5a0bb31074a406b3642a8a3
345
496
  INFO
346
497
  end
347
498
 
@@ -372,7 +523,7 @@ RSpec.describe GemServerConformance do # rubocop:disable RSpec/EmptyExampleGroup
372
523
 
373
524
  request :get_versions, compact_index: true do
374
525
  it { is_expected.to be_valid_compact_index_reponse }
375
- it { is_expected.to have_body(parent_response.body + "a -0.2.0 1fdcc4d621638a6ba75d8ed88b09f97a\n") }
526
+ it { is_expected.to have_body(parent_response.body + "a -0.2.0 474751e9d427e559781d7e222b368085\n") }
376
527
  end
377
528
 
378
529
  request :get_info, "a", compact_index: true do
@@ -381,7 +532,7 @@ RSpec.describe GemServerConformance do # rubocop:disable RSpec/EmptyExampleGroup
381
532
  it {
382
533
  is_expected.to have_body(
383
534
  parent_response.body.lines.tap do |lines|
384
- lines.delete("0.2.0 |checksum:a1753a0e8b6f0515a15e9cfa4ea143e36de235525f6f68c4ff45c4ae70be072f\n")
535
+ lines.delete("0.2.0 |checksum:6f2d3eb31a402d2be7c7d51d52e22ba9c86ca7b0641a3debfb3deadedc19301f\n")
385
536
  end.join
386
537
  )
387
538
  }
@@ -409,15 +560,15 @@ RSpec.describe GemServerConformance do # rubocop:disable RSpec/EmptyExampleGroup
409
560
  it { is_expected.to have_body(<<~VERSIONS) }
410
561
  created_at: 1990-01-01T02:10:00Z
411
562
  ---
412
- a 0.0.1,0.2.0-x86-mingw32,0.2.0-java,0.3.0 1fdcc4d621638a6ba75d8ed88b09f97a
413
- b 1.0.0.pre 688f5cdf79887aff5d87c86f36cfe063
563
+ a 0.0.1,0.2.0-x86-mingw32,0.2.0-java,0.3.0 474751e9d427e559781d7e222b368085
564
+ b 1.0.0.pre f0d229a9323895e2e1c85f496b5f10b5
414
565
  VERSIONS
415
566
  end
416
567
  end
417
568
  .then "after yanking a missing gem", before:
418
569
  lambda { |_|
419
570
  yank_gem(RequestHelpers::MockGem.new(name: "missing", version: "1.0.0"), expected_to: be_not_found)
420
- } do
571
+ } do # rubocop:disable RSpec/ReturnFromStub
421
572
  nil
422
573
  end
423
574
  end
@@ -8,6 +8,49 @@ module RequestHelpers
8
8
  base.attr_reader :last_response
9
9
  end
10
10
 
11
+ module SpecificationToYamlNormalization
12
+ class CoderWrapper < SimpleDelegator
13
+ def add(key, value)
14
+ value = "3.5.11" if key == "rubygems_version"
15
+ return if value.nil?
16
+
17
+ super
18
+ end
19
+ end
20
+
21
+ def encode_with(coder)
22
+ super(CoderWrapper.new(coder))
23
+ end
24
+ end
25
+
26
+ module PackageGzipToConsistentOS
27
+ class IOWrapper < SimpleDelegator
28
+ def write(str)
29
+ str[9] = "\x03".b if str.size == 10 && str.start_with?("\x1f\x8b".b)
30
+ super
31
+ end
32
+ end
33
+
34
+ def gzip_to(io, &blk)
35
+ super(IOWrapper.new(io), &blk)
36
+ end
37
+ end
38
+
39
+ ::Gem::Dependency.class_eval do
40
+ if Gem::Dependency.method_defined?(:to_yaml_properties)
41
+ prepend(
42
+ Module.new do
43
+ def to_yaml_properties
44
+ expected = %i[@name @requirement @type @prerelease @version_requirements]
45
+ actual = super
46
+
47
+ (expected & actual) + (actual - expected)
48
+ end
49
+ end
50
+ )
51
+ end
52
+ end
53
+
11
54
  def build_gem(name, version, platform: nil)
12
55
  spec = Gem::Specification.new do |s|
13
56
  s.name = name
@@ -20,33 +63,20 @@ module RequestHelpers
20
63
  end
21
64
  yield spec if block_given?
22
65
 
66
+ spec.singleton_class.prepend(SpecificationToYamlNormalization) if Gem.rubygems_version < Gem::Version.new("3.6.0")
67
+
23
68
  package = Gem::Package.new(StringIO.new.binmode)
24
69
  package.build_time = Time.utc(1970)
25
70
  package.spec = spec
26
- package.setup_signer
27
- signer = package.instance_variable_get(:@signer)
28
- package.gem.with_write_io do |gem_io|
29
- Gem::Package::TarWriter.new gem_io do |gem|
30
- digests = gem.add_file_signed "metadata.gz", 0o444, signer do |io|
31
- package.gzip_to io do |gz_io|
32
- yaml = spec.to_yaml
33
- yaml.sub!(/^rubygems_version: .*/, "rubygems_version: 3.5.11")
34
- gz_io.write yaml
35
- end
36
- end
37
- checksums = package.instance_variable_get(:@checksums)
38
- checksums["metadata.gz"] = digests
71
+ package.singleton_class.prepend(PackageGzipToConsistentOS)
72
+ package.gem.singleton_class.send(:define_method, :path) { "" }
39
73
 
40
- digests = gem.add_file_signed "data.tar.gz", 0o444, signer do |io|
41
- package.gzip_to io do |gz_io|
42
- # no files
43
- Gem::Package::TarWriter.new gz_io
44
- end
45
- end
46
- checksums["data.tar.gz"] = digests
74
+ package.build
47
75
 
48
- package.add_checksums gem
49
- end
76
+ if ENV["DUMP_BUILD_GEM"]
77
+ tmp = "build_gem/#{RUBY_ENGINE}/rubygems-#{Gem::VERSION}/#{@time}"
78
+ FileUtils.mkdir_p(tmp)
79
+ File.binwrite("#{tmp}/#{spec.full_name}.gem", package.gem.io.string)
50
80
  end
51
81
 
52
82
  MockGem.new(
@@ -118,7 +148,7 @@ module RequestHelpers
118
148
  request["Content-Type"] = "application/octet-stream"
119
149
  request.add_field "Authorization", Pusher.api_key
120
150
  end.tap do
121
- expect(last_response).to expected_to
151
+ expect(last_response).to expected_to, last_response.body
122
152
  set_time @time + 60
123
153
  end
124
154
  end
@@ -224,7 +254,6 @@ module RequestHelpers
224
254
  attr_reader :response
225
255
 
226
256
  def initialize(response)
227
- response.body_encoding = Encoding::BINARY
228
257
  @response = response
229
258
  end
230
259
 
@@ -39,17 +39,6 @@ module StepHelpers
39
39
  end
40
40
  end
41
41
 
42
- # class NullReporter
43
- # def self.method_missing(...)
44
- # pp(...)
45
- # end
46
-
47
- # def self.example_failed(ex)
48
- # pp ex
49
- # puts ex.display_exception.full_message
50
- # end
51
- # end
52
-
53
42
  def request(method, *args, **kwargs, &blk)
54
43
  name = method.to_s
55
44
  name += "(#{args.map(&:inspect).join(", ")})" unless args.empty?
@@ -147,23 +136,38 @@ module StepHelpers
147
136
  before(:all) do
148
137
  @upstream = ENV.fetch("UPSTREAM", nil)
149
138
  unless upstream
139
+ @upstream_output = Tempfile.create("upstream.out").path
150
140
  Bundler.with_original_env do
151
141
  @upstream = "http://localhost:4567"
152
- @pid = spawn("ruby", "-rbundler/setup", "lib/gem_server_conformance/server.rb", out: "/dev/null",
153
- err: "/dev/null")
154
- sleep 1
142
+ @pid = spawn(Gem.ruby, "-rbundler/setup", "lib/gem_server_conformance/server.rb", out: @upstream_output,
143
+ err: @upstream_output)
144
+ raise "failed to start server" unless @pid
155
145
  end
156
146
  end
157
147
 
158
148
  @all_gems = []
159
- set_time Time.utc(1990)
149
+ retries = 150
150
+ loop do
151
+ set_time Time.utc(1990)
152
+ break
153
+ rescue Errno::ECONNREFUSED
154
+ retries -= 1
155
+ raise "Failed to boot gem_server_conformance/server in under 5 seconds" if retries.zero?
156
+
157
+ sleep 0.1
158
+ else
159
+ break
160
+ end
160
161
  end
161
162
 
162
163
  after(:all) do
163
164
  if @pid
164
165
  Process.kill "TERM", @pid
165
166
  Process.wait @pid
167
+ expect($?).to be_success, "Upstream server failed #{$?.inspect}:\n\n#{File.read(@upstream_output)}"
166
168
  end
169
+ ensure
170
+ File.unlink @upstream_output if @upstream_output
167
171
  end
168
172
  end
169
173
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gem_server_conformance
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Giddins
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-07-17 00:00:00.000000000 Z
11
+ date: 2024-07-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec