prebake 0.2.3 → 0.2.5
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/prebake/async_publisher.rb +2 -27
- data/lib/prebake/backends/base.rb +30 -6
- data/lib/prebake/backends/gemstash.rb +1 -7
- data/lib/prebake/backends/http.rb +1 -7
- data/lib/prebake/backends/s3.rb +4 -18
- data/lib/prebake/ext_builder_patch.rb +21 -8
- data/lib/prebake/extractor.rb +2 -0
- data/lib/prebake/logger.rb +2 -13
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 31185ad0841776ec02da2cd5c8009dc58902aa55e19c4a99709a24e1cde477b7
|
|
4
|
+
data.tar.gz: d394286a0464cabe3f925edb48b964a902675581dc9f36e3e486819f7f7560d0
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ba38a6ef9217ce6c9273db4a2c284b991c7406f24837a98278dd9faf19905216a96b3bcb4e46b977523fb63b7d1bc5d94e1f1de1933414625978ed1d73adcd9b
|
|
7
|
+
data.tar.gz: cebd97cda589821cd1eb4df1ed4b71b39134d9d3e9e1433ab34f70acf7585d4568c900559631b640d3e1dce869f4b15d230a21b3e4a6587eba7fab9beeba9942
|
|
@@ -9,39 +9,17 @@ require_relative "logger"
|
|
|
9
9
|
module Prebake
|
|
10
10
|
module AsyncPublisher
|
|
11
11
|
@pending_specs = []
|
|
12
|
-
@threads = []
|
|
13
12
|
@mutex = Mutex.new
|
|
14
13
|
|
|
15
14
|
def self.reset!
|
|
16
|
-
@mutex.synchronize
|
|
17
|
-
@pending_specs.clear
|
|
18
|
-
@threads.clear
|
|
19
|
-
end
|
|
15
|
+
@mutex.synchronize { @pending_specs.clear }
|
|
20
16
|
end
|
|
21
17
|
|
|
22
|
-
# Queue a spec for later processing (no threads, no chdir)
|
|
23
18
|
def self.enqueue(spec, backend)
|
|
24
19
|
@mutex.synchronize { @pending_specs << [spec, backend] }
|
|
25
20
|
end
|
|
26
21
|
|
|
27
|
-
# For testing - enqueue a raw block for async execution
|
|
28
|
-
def self.enqueue_block(&block)
|
|
29
|
-
thread = Thread.new do
|
|
30
|
-
block.call
|
|
31
|
-
rescue StandardError => e
|
|
32
|
-
Logger.warn "Error in background task: #{e.message}"
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
@mutex.synchronize { @threads << thread }
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
# Build all queued gems (serial, safe for Dir.chdir) then push in parallel
|
|
39
22
|
def self.wait_for_completion(timeout: 120)
|
|
40
|
-
# First, wait for any raw block threads (from tests)
|
|
41
|
-
block_threads = @mutex.synchronize { @threads.dup }
|
|
42
|
-
block_threads.each { |t| t.join(timeout) }
|
|
43
|
-
|
|
44
|
-
# Then process queued specs
|
|
45
23
|
specs = @mutex.synchronize { @pending_specs.dup }
|
|
46
24
|
return if specs.empty?
|
|
47
25
|
|
|
@@ -71,10 +49,7 @@ module Prebake
|
|
|
71
49
|
|
|
72
50
|
Logger.info "All pushes complete."
|
|
73
51
|
|
|
74
|
-
@mutex.synchronize
|
|
75
|
-
@pending_specs.clear
|
|
76
|
-
@threads.clear
|
|
77
|
-
end
|
|
52
|
+
@mutex.synchronize { @pending_specs.clear }
|
|
78
53
|
end
|
|
79
54
|
|
|
80
55
|
def self.build_gem(spec, backend)
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require_relative "../logger"
|
|
4
|
+
|
|
3
5
|
module Prebake
|
|
4
6
|
module Backends
|
|
5
7
|
class Base
|
|
@@ -7,25 +9,47 @@ module Prebake
|
|
|
7
9
|
raise NotImplementedError, "#{self.class}#fetch not implemented"
|
|
8
10
|
end
|
|
9
11
|
|
|
10
|
-
def fetch_checksum(
|
|
11
|
-
|
|
12
|
+
def fetch_checksum(_cache_key)
|
|
13
|
+
nil
|
|
12
14
|
end
|
|
13
15
|
|
|
14
16
|
def push(gem_path, cache_key, checksum)
|
|
15
17
|
raise NotImplementedError, "#{self.class}#push not implemented"
|
|
16
18
|
end
|
|
17
19
|
|
|
18
|
-
def exists?(
|
|
19
|
-
|
|
20
|
+
def exists?(_cache_key)
|
|
21
|
+
false
|
|
20
22
|
end
|
|
21
23
|
|
|
22
|
-
def delete(
|
|
23
|
-
|
|
24
|
+
def delete(_cache_key)
|
|
25
|
+
false
|
|
24
26
|
end
|
|
25
27
|
|
|
26
28
|
def checksums_supported?
|
|
27
29
|
true
|
|
28
30
|
end
|
|
31
|
+
|
|
32
|
+
protected
|
|
33
|
+
|
|
34
|
+
def warn_if_insecure_http(url)
|
|
35
|
+
return if url.start_with?("https://")
|
|
36
|
+
return if ENV.fetch("PREBAKE_ALLOW_INSECURE", "false") == "true"
|
|
37
|
+
return unless url.start_with?("http://")
|
|
38
|
+
return if darwin_with_default_host?(url)
|
|
39
|
+
|
|
40
|
+
Logger.warn(
|
|
41
|
+
"Using insecure HTTP connection to #{url}. " \
|
|
42
|
+
"Set PREBAKE_ALLOW_INSECURE=true to suppress this warning."
|
|
43
|
+
)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
private
|
|
47
|
+
|
|
48
|
+
def darwin_with_default_host?(url)
|
|
49
|
+
RUBY_PLATFORM.include?("darwin") &&
|
|
50
|
+
Prebake.backend_type == "http" &&
|
|
51
|
+
url.chomp("/") == Prebake::DEFAULT_HTTP_URL
|
|
52
|
+
end
|
|
29
53
|
end
|
|
30
54
|
end
|
|
31
55
|
end
|
|
@@ -27,13 +27,7 @@ module Prebake
|
|
|
27
27
|
@url = url.chomp("/")
|
|
28
28
|
@key = key
|
|
29
29
|
|
|
30
|
-
|
|
31
|
-
return unless @url.start_with?("http://")
|
|
32
|
-
|
|
33
|
-
Logger.warn(
|
|
34
|
-
"Using insecure HTTP connection to #{@url}. " \
|
|
35
|
-
"Set PREBAKE_ALLOW_INSECURE=true to suppress this warning."
|
|
36
|
-
)
|
|
30
|
+
warn_if_insecure_http(@url)
|
|
37
31
|
end
|
|
38
32
|
|
|
39
33
|
def fetch(cache_key)
|
|
@@ -15,13 +15,7 @@ module Prebake
|
|
|
15
15
|
@url = url.chomp("/")
|
|
16
16
|
@token = token
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
return unless @url.start_with?("http://")
|
|
20
|
-
|
|
21
|
-
Logger.warn(
|
|
22
|
-
"Using insecure HTTP connection to #{@url}. " \
|
|
23
|
-
"Set PREBAKE_ALLOW_INSECURE=true to suppress this warning."
|
|
24
|
-
)
|
|
18
|
+
warn_if_insecure_http(@url)
|
|
25
19
|
end
|
|
26
20
|
|
|
27
21
|
def fetch(cache_key)
|
data/lib/prebake/backends/s3.rb
CHANGED
|
@@ -12,11 +12,13 @@ module Prebake
|
|
|
12
12
|
@bucket = bucket
|
|
13
13
|
@region = region
|
|
14
14
|
@prefix = prefix
|
|
15
|
+
|
|
16
|
+
require "aws-sdk-s3"
|
|
17
|
+
rescue LoadError
|
|
18
|
+
raise Prebake::Error, "aws-sdk-s3 gem is required for S3 backend"
|
|
15
19
|
end
|
|
16
20
|
|
|
17
21
|
def fetch(cache_key)
|
|
18
|
-
return nil unless sdk_available?
|
|
19
|
-
|
|
20
22
|
response = client.get_object(bucket: @bucket, key: object_key(cache_key))
|
|
21
23
|
path = File.join(Dir.tmpdir, "prebake-#{SecureRandom.hex(16)}.gem")
|
|
22
24
|
File.binwrite(path, response.body.read)
|
|
@@ -27,8 +29,6 @@ module Prebake
|
|
|
27
29
|
end
|
|
28
30
|
|
|
29
31
|
def fetch_checksum(cache_key)
|
|
30
|
-
return nil unless sdk_available?
|
|
31
|
-
|
|
32
32
|
response = client.get_object(bucket: @bucket, key: checksum_key(cache_key))
|
|
33
33
|
response.body.read.strip
|
|
34
34
|
rescue StandardError => e
|
|
@@ -37,8 +37,6 @@ module Prebake
|
|
|
37
37
|
end
|
|
38
38
|
|
|
39
39
|
def push(gem_path, cache_key, checksum)
|
|
40
|
-
return false unless sdk_available?
|
|
41
|
-
|
|
42
40
|
gem_key = object_key(cache_key)
|
|
43
41
|
File.open(gem_path, "rb") do |file|
|
|
44
42
|
client.put_object(bucket: @bucket, key: gem_key, body: file)
|
|
@@ -60,8 +58,6 @@ module Prebake
|
|
|
60
58
|
end
|
|
61
59
|
|
|
62
60
|
def exists?(cache_key)
|
|
63
|
-
return false unless sdk_available?
|
|
64
|
-
|
|
65
61
|
client.head_object(bucket: @bucket, key: object_key(cache_key))
|
|
66
62
|
true
|
|
67
63
|
rescue StandardError
|
|
@@ -69,8 +65,6 @@ module Prebake
|
|
|
69
65
|
end
|
|
70
66
|
|
|
71
67
|
def delete(cache_key)
|
|
72
|
-
return false unless sdk_available?
|
|
73
|
-
|
|
74
68
|
client.delete_object(bucket: @bucket, key: object_key(cache_key))
|
|
75
69
|
client.delete_object(bucket: @bucket, key: checksum_key(cache_key))
|
|
76
70
|
Logger.info "Deleted #{cache_key} from S3"
|
|
@@ -90,14 +84,6 @@ module Prebake
|
|
|
90
84
|
"#{object_key(cache_key)}.sha256"
|
|
91
85
|
end
|
|
92
86
|
|
|
93
|
-
def sdk_available?
|
|
94
|
-
require "aws-sdk-s3"
|
|
95
|
-
true
|
|
96
|
-
rescue LoadError
|
|
97
|
-
Logger.warn "aws-sdk-s3 not available. Install it to use S3 backend."
|
|
98
|
-
false
|
|
99
|
-
end
|
|
100
|
-
|
|
101
87
|
def client
|
|
102
88
|
@client ||= Aws::S3::Client.new(region: @region)
|
|
103
89
|
end
|
|
@@ -21,11 +21,7 @@ module Prebake
|
|
|
21
21
|
expected_checksum = Prebake.backend.fetch_checksum(cache_key)
|
|
22
22
|
|
|
23
23
|
if expected_checksum.nil? && Prebake.backend.checksums_supported?
|
|
24
|
-
|
|
25
|
-
Prebake.backend.delete(cache_key)
|
|
26
|
-
# GET triggers the worker to dispatch a rebuild via GH Actions on cache miss
|
|
27
|
-
trigger_path = Prebake.backend.fetch(cache_key)
|
|
28
|
-
FileUtils.rm_f(trigger_path) if trigger_path
|
|
24
|
+
trigger_rebuild(cache_key)
|
|
29
25
|
return super
|
|
30
26
|
end
|
|
31
27
|
|
|
@@ -42,7 +38,10 @@ module Prebake
|
|
|
42
38
|
end
|
|
43
39
|
|
|
44
40
|
if verify_checksum(cache_key, expected_checksum, cached_gem)
|
|
45
|
-
install_from_cache(cached_gem)
|
|
41
|
+
unless install_from_cache(cached_gem)
|
|
42
|
+
Prebake.backend.delete(cache_key)
|
|
43
|
+
return super
|
|
44
|
+
end
|
|
46
45
|
else
|
|
47
46
|
super
|
|
48
47
|
end
|
|
@@ -52,6 +51,14 @@ module Prebake
|
|
|
52
51
|
|
|
53
52
|
private
|
|
54
53
|
|
|
54
|
+
def trigger_rebuild(cache_key)
|
|
55
|
+
Logger.warn "No checksum available for #{cache_key}, removing cached gem"
|
|
56
|
+
Prebake.backend.delete(cache_key)
|
|
57
|
+
# GET triggers the worker to dispatch a rebuild via GH Actions on cache miss
|
|
58
|
+
trigger_path = Prebake.backend.fetch(cache_key)
|
|
59
|
+
FileUtils.rm_f(trigger_path) if trigger_path
|
|
60
|
+
end
|
|
61
|
+
|
|
55
62
|
def verify_checksum(cache_key, expected, gem_path)
|
|
56
63
|
return true if expected.nil?
|
|
57
64
|
|
|
@@ -65,10 +72,16 @@ module Prebake
|
|
|
65
72
|
end
|
|
66
73
|
|
|
67
74
|
def install_from_cache(gem_path)
|
|
68
|
-
|
|
69
|
-
|
|
75
|
+
count = Extractor.install(gem_path, @spec)
|
|
76
|
+
|
|
77
|
+
if count.zero?
|
|
78
|
+
Logger.warn "No binaries found in cached gem for #{@spec.name}, falling back to source build"
|
|
79
|
+
return false
|
|
80
|
+
end
|
|
81
|
+
|
|
70
82
|
FileUtils.mkdir_p(File.dirname(@spec.gem_build_complete_path))
|
|
71
83
|
FileUtils.touch(@spec.gem_build_complete_path)
|
|
84
|
+
true
|
|
72
85
|
end
|
|
73
86
|
end
|
|
74
87
|
end
|
data/lib/prebake/extractor.rb
CHANGED
|
@@ -45,6 +45,8 @@ module Prebake
|
|
|
45
45
|
|
|
46
46
|
Logger.info "Installed precompiled #{File.basename(gem_path)} " \
|
|
47
47
|
"(#{extracted_count} binary files)"
|
|
48
|
+
|
|
49
|
+
extracted_count
|
|
48
50
|
rescue StandardError => e
|
|
49
51
|
Logger.warn "Extraction failed for #{File.basename(gem_path)}: #{e.message}"
|
|
50
52
|
raise
|
data/lib/prebake/logger.rb
CHANGED
|
@@ -5,7 +5,7 @@ module Prebake
|
|
|
5
5
|
LEVELS = { debug: 0, info: 1, warn: 2 }.freeze
|
|
6
6
|
|
|
7
7
|
def self.level
|
|
8
|
-
LEVELS.fetch(ENV.fetch("PREBAKE_LOG_LEVEL", "warn").to_sym, 1)
|
|
8
|
+
@level ||= LEVELS.fetch(ENV.fetch("PREBAKE_LOG_LEVEL", "warn").to_sym, 1)
|
|
9
9
|
end
|
|
10
10
|
|
|
11
11
|
def self.debug(msg)
|
|
@@ -22,23 +22,12 @@ module Prebake
|
|
|
22
22
|
|
|
23
23
|
def self.warn(msg)
|
|
24
24
|
return unless level <= 2
|
|
25
|
-
return if darwin_with_default_host?
|
|
26
25
|
|
|
27
26
|
output " [prebake] WARN: #{msg}"
|
|
28
27
|
end
|
|
29
28
|
|
|
30
29
|
def self.reset!
|
|
31
|
-
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
private_class_method def self.darwin_with_default_host?
|
|
35
|
-
return @darwin_with_default_host if defined?(@darwin_with_default_host)
|
|
36
|
-
|
|
37
|
-
@darwin_with_default_host =
|
|
38
|
-
RUBY_PLATFORM.include?("darwin") &&
|
|
39
|
-
Prebake.backend_type == "http" &&
|
|
40
|
-
(url = ENV.fetch("PREBAKE_HTTP_URL", nil)
|
|
41
|
-
url.nil? || url.chomp("/") == Prebake::DEFAULT_HTTP_URL)
|
|
30
|
+
@level = nil
|
|
42
31
|
end
|
|
43
32
|
|
|
44
33
|
def self.output(msg)
|