prebake 0.1.0 → 0.2.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: dab6849310807672ec24350dbd6343e3adb1875ffd5a84912d3279fcdf4a455d
4
- data.tar.gz: be4d4d24fee4c87d755eaa85175204772a10e2ba0a1c81047b342f6593a4cab2
3
+ metadata.gz: 9f5c4b69adf22b366fb77141cb413b34df42d095349d8cd87daef343b0651711
4
+ data.tar.gz: cb0433ad9ed89f37840c4ebce4c1468853f2f16067f2a0f38f84eafc4ec6c04f
5
5
  SHA512:
6
- metadata.gz: 1cd47249386725f821a1c9e497c1fc5a9c27aa872255a0b745147d96a697f69ca9a648171aa13067c40fe3994882d81cab31cb73a063e7928de88e59c624d4d3
7
- data.tar.gz: 7997b12e900e9122114ea31539e4e8a448ca898fe4e559abbb4957baa7634277d50e24aa731021eb73c659e66ff39f84f49180c312bd1dceadf445297bf1ab93
6
+ metadata.gz: 84df05e82f7ef086192333d326d9441cd0146c1ebcc64f4d56a6c780f34d25fdb00e5a255acdaf55354f132f8a5b070284d55a2aeff824635d1c3ef81129fbed
7
+ data.tar.gz: 44f1bed2b2af9fc20200253783a01a0d915b9ce5afea9743662c3fba5e6bec2d8d54f1cd9f8d159098830b71cc6194a4215b6925dc6b8e3203e2a956bac6afe4
@@ -18,6 +18,14 @@ module Prebake
18
18
  def exists?(cache_key)
19
19
  raise NotImplementedError, "#{self.class}#exists? not implemented"
20
20
  end
21
+
22
+ def delete(cache_key)
23
+ raise NotImplementedError, "#{self.class}#delete not implemented"
24
+ end
25
+
26
+ def checksums_supported?
27
+ true
28
+ end
21
29
  end
22
30
  end
23
31
  end
@@ -56,6 +56,14 @@ module Prebake
56
56
  nil
57
57
  end
58
58
 
59
+ def checksums_supported?
60
+ false
61
+ end
62
+
63
+ def delete(_cache_key)
64
+ false
65
+ end
66
+
59
67
  def push(gem_path, cache_key, _checksum)
60
68
  uri = URI("#{@url}/private/api/v1/gems")
61
69
  gem_content = File.binread(gem_path)
@@ -25,8 +25,7 @@ module Prebake
25
25
  end
26
26
 
27
27
  def fetch(cache_key)
28
- uri = URI("#{@url}/gems/#{cache_key}")
29
- response = http_request(:get, uri)
28
+ response = http_request(:get, gem_uri(cache_key))
30
29
  return nil unless response.is_a?(Net::HTTPSuccess)
31
30
 
32
31
  path = File.join(Dir.tmpdir, "prebake-#{SecureRandom.hex(16)}.gem")
@@ -38,8 +37,7 @@ module Prebake
38
37
  end
39
38
 
40
39
  def fetch_checksum(cache_key)
41
- uri = URI("#{@url}/gems/#{cache_key}.sha256")
42
- response = http_request(:get, uri)
40
+ response = http_request(:get, checksum_uri(cache_key))
43
41
  return nil unless response.is_a?(Net::HTTPSuccess)
44
42
 
45
43
  response.body.strip
@@ -49,21 +47,19 @@ module Prebake
49
47
  end
50
48
 
51
49
  def push(gem_path, cache_key, checksum)
52
- gem_uri = URI("#{@url}/gems/#{cache_key}")
53
- gem_response = http_request(:put, gem_uri, body: File.binread(gem_path))
50
+ gem_response = http_request(:put, gem_uri(cache_key), body: File.binread(gem_path))
54
51
 
55
52
  unless gem_response.is_a?(Net::HTTPSuccess)
56
53
  Logger.warn "Failed to push #{cache_key}: #{gem_response.code}"
57
54
  return false
58
55
  end
59
56
 
60
- # Checksum is a secondary artifact - log failure but don't fail the push.
61
- # The gem itself was pushed successfully; missing checksums can be backfilled.
62
- checksum_uri = URI("#{@url}/gems/#{cache_key}.sha256")
63
- checksum_response = http_request(:put, checksum_uri, body: checksum)
57
+ checksum_response = http_request(:put, checksum_uri(cache_key), body: checksum)
64
58
 
65
59
  unless checksum_response.is_a?(Net::HTTPSuccess)
66
- Logger.warn "Checksum push failed for #{cache_key}: #{checksum_response.code}"
60
+ Logger.warn "Checksum push failed for #{cache_key}: #{checksum_response.code}, removing gem"
61
+ http_request(:delete, gem_uri(cache_key))
62
+ return false
67
63
  end
68
64
 
69
65
  Logger.info "Pushed #{cache_key}"
@@ -74,15 +70,32 @@ module Prebake
74
70
  end
75
71
 
76
72
  def exists?(cache_key)
77
- uri = URI("#{@url}/gems/#{cache_key}")
78
- response = http_request(:head, uri)
73
+ response = http_request(:head, gem_uri(cache_key))
79
74
  response.is_a?(Net::HTTPSuccess)
80
75
  rescue StandardError
81
76
  false
82
77
  end
83
78
 
79
+ def delete(cache_key)
80
+ gem_response = http_request(:delete, gem_uri(cache_key))
81
+ http_request(:delete, checksum_uri(cache_key))
82
+
83
+ gem_response.is_a?(Net::HTTPSuccess)
84
+ rescue StandardError => e
85
+ Logger.debug "Delete failed for #{cache_key}: #{e.message}"
86
+ false
87
+ end
88
+
84
89
  private
85
90
 
91
+ def gem_uri(cache_key)
92
+ URI("#{@url}/gems/#{cache_key}")
93
+ end
94
+
95
+ def checksum_uri(cache_key)
96
+ URI("#{@url}/gems/#{cache_key}.sha256")
97
+ end
98
+
86
99
  def apply_auth_header(request)
87
100
  request["Authorization"] = "Bearer #{@token}" if @token
88
101
  end
@@ -7,7 +7,8 @@ module Prebake
7
7
  module HttpClient
8
8
  TIMEOUT = 30
9
9
  HTTP_METHODS = { get: Net::HTTP::Get, head: Net::HTTP::Head,
10
- post: Net::HTTP::Post, put: Net::HTTP::Put }.freeze
10
+ post: Net::HTTP::Post, put: Net::HTTP::Put,
11
+ delete: Net::HTTP::Delete }.freeze
11
12
 
12
13
  private
13
14
 
@@ -29,7 +29,7 @@ module Prebake
29
29
  def fetch_checksum(cache_key)
30
30
  return nil unless sdk_available?
31
31
 
32
- response = client.get_object(bucket: @bucket, key: "#{object_key(cache_key)}.sha256")
32
+ response = client.get_object(bucket: @bucket, key: checksum_key(cache_key))
33
33
  response.body.read.strip
34
34
  rescue StandardError => e
35
35
  Logger.debug "S3 checksum fetch failed for #{cache_key}: #{e.message}"
@@ -39,10 +39,19 @@ module Prebake
39
39
  def push(gem_path, cache_key, checksum)
40
40
  return false unless sdk_available?
41
41
 
42
+ gem_key = object_key(cache_key)
42
43
  File.open(gem_path, "rb") do |file|
43
- client.put_object(bucket: @bucket, key: object_key(cache_key), body: file)
44
+ client.put_object(bucket: @bucket, key: gem_key, body: file)
44
45
  end
45
- client.put_object(bucket: @bucket, key: "#{object_key(cache_key)}.sha256", body: checksum)
46
+
47
+ begin
48
+ client.put_object(bucket: @bucket, key: checksum_key(cache_key), body: checksum)
49
+ rescue StandardError => e
50
+ Logger.warn "S3 checksum push failed for #{cache_key}: #{e.message}, removing gem"
51
+ client.delete_object(bucket: @bucket, key: gem_key)
52
+ return false
53
+ end
54
+
46
55
  Logger.info "Pushed #{cache_key} to S3"
47
56
  true
48
57
  rescue StandardError => e
@@ -59,12 +68,28 @@ module Prebake
59
68
  false
60
69
  end
61
70
 
71
+ def delete(cache_key)
72
+ return false unless sdk_available?
73
+
74
+ client.delete_object(bucket: @bucket, key: object_key(cache_key))
75
+ client.delete_object(bucket: @bucket, key: checksum_key(cache_key))
76
+ Logger.info "Deleted #{cache_key} from S3"
77
+ true
78
+ rescue StandardError => e
79
+ Logger.debug "S3 delete failed for #{cache_key}: #{e.message}"
80
+ false
81
+ end
82
+
62
83
  private
63
84
 
64
85
  def object_key(cache_key)
65
86
  "#{@prefix}/#{cache_key}"
66
87
  end
67
88
 
89
+ def checksum_key(cache_key)
90
+ "#{object_key(cache_key)}.sha256"
91
+ end
92
+
68
93
  def sdk_available?
69
94
  require "aws-sdk-s3"
70
95
  true
@@ -18,6 +18,14 @@ module Prebake
18
18
  platform = Platform.generalized
19
19
  cache_key = CacheKey.for(@spec.name, @spec.version.to_s, platform)
20
20
 
21
+ expected_checksum = Prebake.backend.fetch_checksum(cache_key)
22
+
23
+ if expected_checksum.nil? && Prebake.backend.checksums_supported?
24
+ Logger.warn "No checksum available for #{cache_key}, removing cached gem"
25
+ Prebake.backend.delete(cache_key)
26
+ return super
27
+ end
28
+
21
29
  begin
22
30
  cached_gem = Prebake.backend.fetch(cache_key)
23
31
  rescue StandardError => e
@@ -30,30 +38,19 @@ module Prebake
30
38
  return super
31
39
  end
32
40
 
33
- # Verify checksum if available
34
- if verify_checksum(cache_key, cached_gem)
41
+ if verify_checksum(cache_key, expected_checksum, cached_gem)
35
42
  install_from_cache(cached_gem)
36
43
  else
37
- Logger.warn "Checksum mismatch for #{cache_key}, compiling from source"
38
44
  super
39
45
  end
40
46
  ensure
41
- FileUtils.rm_f(cached_gem) if cached_gem && File.exist?(cached_gem.to_s)
47
+ FileUtils.rm_f(cached_gem) if cached_gem
42
48
  end
43
49
 
44
50
  private
45
51
 
46
- def verify_checksum(cache_key, gem_path)
47
- expected = Prebake.backend.fetch_checksum(cache_key)
48
-
49
- if expected.nil?
50
- if ENV.fetch("PREBAKE_REQUIRE_CHECKSUM", "false") == "true"
51
- Logger.warn "No checksum available for #{cache_key} and PREBAKE_REQUIRE_CHECKSUM=true, rejecting"
52
- return false
53
- end
54
- Logger.warn "No checksum available for #{cache_key}, skipping verification"
55
- return true
56
- end
52
+ def verify_checksum(cache_key, expected, gem_path)
53
+ return true if expected.nil?
57
54
 
58
55
  actual = Digest::SHA256.file(gem_path).hexdigest
59
56
  if actual == expected
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: prebake
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Thejus Paul
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-03-22 00:00:00.000000000 Z
11
+ date: 2026-03-23 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Prebake speeds up bundle install by skipping native gem compilation.
14
14
  It fetches precompiled binaries for gems like puma, nokogiri, pg, grpc, and bootsnap