rb_sys 0.9.64 → 0.9.65
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/exe/rb-sys-dock +222 -125
- data/lib/rb_sys/cargo/metadata.rb +13 -2
- data/lib/rb_sys/extensiontask.rb +35 -3
- data/lib/rb_sys/mkmf.rb +0 -1
- data/lib/rb_sys/util/logger.rb +73 -0
- data/lib/rb_sys/version.rb +1 -1
- data.tar.gz.sig +0 -0
- metadata +4 -3
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5dc9ecb59d4b2cc130afff772c740063ee2bdbf5bdf15fb866aa6dcbb501d396
|
4
|
+
data.tar.gz: b9c2c65ef48e0c5400ea857bb75ad9ec85ffac300a4290bc6f20ef00ca5e8163
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3c4acd2a28480da0b8adb18a48a806354afae12d963b9394f6ce9bd41f89c703a27dbe9a6bc52136f897ad7e64ccba70c9bbfd4231a9b209964d130dc703d8ad
|
7
|
+
data.tar.gz: 849c5b3fd8209dfe41b6a5efc0dbd06d6760e849b32cd0182915f9e1d5e011885ba64d56ef7c8f8ed286094ba4efaaec2ad5ffa1134690579223ae826e81ba54
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data/exe/rb-sys-dock
CHANGED
@@ -1,82 +1,61 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
+
$LOAD_PATH.unshift File.expand_path("../lib", __dir__)
|
4
|
+
|
3
5
|
require "optparse"
|
6
|
+
require "open3"
|
4
7
|
require "rb_sys/version"
|
5
8
|
require "rb_sys/toolchain_info"
|
9
|
+
require "rb_sys/cargo/metadata"
|
10
|
+
require "rb_sys/util/logger"
|
6
11
|
require "fileutils"
|
7
12
|
require "tmpdir"
|
8
13
|
|
9
|
-
|
10
|
-
|
14
|
+
OPTIONS = {
|
15
|
+
docker_platform: "linux/amd64",
|
16
|
+
version: RbSys::VERSION,
|
17
|
+
directory: Dir.pwd
|
11
18
|
}
|
12
19
|
|
13
|
-
def
|
14
|
-
|
15
|
-
|
16
|
-
["❌", "\e[1;31m"]
|
17
|
-
when :warn
|
18
|
-
["⚠️", "\e[1;33m"]
|
19
|
-
when :info
|
20
|
-
["ℹ️", "\e[1;37m"]
|
21
|
-
when :notice
|
22
|
-
["🐳", "\e[1;34m"]
|
23
|
-
when :trace
|
24
|
-
return unless ENV["LOG_LEVEL"] == "trace"
|
25
|
-
|
26
|
-
["🔍", "\e[1;2m"]
|
27
|
-
else raise "Unknown log level: #{level.inspect}"
|
28
|
-
end
|
29
|
-
|
30
|
-
emoji_opt = if emoji.is_a?(String)
|
31
|
-
emoji + " "
|
32
|
-
elsif emoji
|
33
|
-
emoji_opt + " "
|
34
|
-
end
|
20
|
+
def cargo_metadata
|
21
|
+
@cargo_metadata ||= RbSys::Cargo::Metadata.new("rb-sys-dock", deps: true)
|
22
|
+
end
|
35
23
|
|
36
|
-
|
37
|
-
|
24
|
+
def logger
|
25
|
+
return @logger if @logger
|
38
26
|
|
39
|
-
io.
|
27
|
+
io = ARGV.include?("--quiet") ? File.open(File::NULL, "w") : $stderr
|
28
|
+
@logger ||= RbSys::Util::Logger.new(io: io)
|
40
29
|
end
|
41
30
|
|
42
|
-
|
43
|
-
|
31
|
+
OptionParser.new do |opts|
|
32
|
+
opts.banner = <<~MSG
|
33
|
+
Usage: rb-sys-dock [OPTIONS] [COMMAND]
|
44
34
|
|
45
|
-
|
46
|
-
end
|
35
|
+
A CLI to facillitate building Ruby on Rust extensions using Docker.
|
47
36
|
|
48
|
-
|
49
|
-
log(:trace, "Running command: $ #{cmd}")
|
50
|
-
stdout, stderr, status = Open3.capture3(cmd)
|
37
|
+
Examples:
|
51
38
|
|
52
|
-
|
53
|
-
|
54
|
-
else
|
55
|
-
log(:error, "Error running command: $ #{cmd}")
|
56
|
-
warn(stderr)
|
57
|
-
exit(status.exitstatus)
|
58
|
-
end
|
59
|
-
end
|
39
|
+
Build for Linux (x86_64)
|
40
|
+
$ rb-sys-dock --platform x86_64-linux --build
|
60
41
|
|
61
|
-
|
62
|
-
|
42
|
+
Build for macOS (Ruby 3.1 and 3.2)
|
43
|
+
$ rb-sys-dock -p arm64-darwin --ruby-versions 3.1,3.2 --build
|
63
44
|
|
64
|
-
|
65
|
-
|
66
|
-
log(:trace, "Could not find docker command, trying podman")
|
45
|
+
Enter a shell
|
46
|
+
$ rb-sys-dock --list-platforms
|
67
47
|
|
68
|
-
|
69
|
-
|
70
|
-
@default_docker_command = "podman"
|
71
|
-
stdout
|
72
|
-
rescue Errno::ENOENT
|
73
|
-
log(:error, "Could not find docker or podman command, please install one of them")
|
74
|
-
exit(1)
|
75
|
-
end
|
76
|
-
end
|
48
|
+
Run a command in the container with a specific directory mounted
|
49
|
+
$ rb-sys-dock -p x64-mingw-ucrt -d /tmp/mygem -- "env | grep RUBY"
|
77
50
|
|
78
|
-
|
79
|
-
|
51
|
+
List all supported platforms
|
52
|
+
$ rb-sys-dock --list-platforms
|
53
|
+
|
54
|
+
Options:
|
55
|
+
MSG
|
56
|
+
|
57
|
+
opts.on("--quiet", "Prints no logging output") do
|
58
|
+
end
|
80
59
|
|
81
60
|
opts.on("-v", "--version", "Prints version") do
|
82
61
|
require "rb_sys/version"
|
@@ -84,6 +63,10 @@ OptionParser.new do |opts|
|
|
84
63
|
exit
|
85
64
|
end
|
86
65
|
|
66
|
+
opts.on("--build", "Run the default command to cross-compile a gem") do
|
67
|
+
OPTIONS[:build] = true
|
68
|
+
end
|
69
|
+
|
87
70
|
opts.on("-p", "--platform PLATFORM", "Platform to build for (i.e. x86_64-linux)") do |p|
|
88
71
|
toolchain_info = begin
|
89
72
|
RbSys::ToolchainInfo.new(p)
|
@@ -91,42 +74,40 @@ OptionParser.new do |opts|
|
|
91
74
|
supported_list = RbSys::ToolchainInfo.all
|
92
75
|
supported_list.select!(&:supported?)
|
93
76
|
list = supported_list.map { |p| "- #{p} (#{p.rust_target})" }.join("\n")
|
94
|
-
|
77
|
+
logger.error("Platform #{p} is not supported, please use one of:\n\n#{list}")
|
95
78
|
exit(1)
|
96
79
|
end
|
97
80
|
|
98
|
-
|
99
|
-
|
100
|
-
end
|
101
|
-
|
102
|
-
opts.on("--latest", "Use the latest version of the Docker image") do
|
103
|
-
log(:notice, "Using latest version of the Docker image", emoji: "🆕")
|
104
|
-
options[:version] = "latest"
|
105
|
-
options[:no_cache] = true
|
106
|
-
end
|
107
|
-
|
108
|
-
opts.on("--list-platforms", "--list", "List all supported platforms") do
|
109
|
-
log(:notice, "Supported platforms listed below:")
|
110
|
-
|
111
|
-
RbSys::ToolchainInfo.supported.each do |p|
|
112
|
-
log(:info, "- #{p} (#{p.rust_target})", emoji: false, io: $stdout)
|
113
|
-
end
|
114
|
-
|
115
|
-
exit(0)
|
81
|
+
OPTIONS[:platform] = p
|
82
|
+
OPTIONS[:toolchain_info] = toolchain_info
|
116
83
|
end
|
117
84
|
|
118
|
-
opts.on("--ruby-versions LIST", "List all supported Ruby versions") do |arg|
|
119
|
-
log(:notice, "Requested Ruby versions: #{arg}")
|
120
|
-
|
85
|
+
opts.on("-r", "--ruby-versions LIST", "List all supported Ruby versions") do |arg|
|
121
86
|
vers = arg.split(/[^0-9.]/).map do |v|
|
122
87
|
parts = v.split(".")
|
123
88
|
parts[2] = "0" if parts[2].nil?
|
124
89
|
parts.join(".")
|
125
90
|
end
|
126
91
|
|
92
|
+
OPTIONS[:ruby_versions] = vers
|
93
|
+
|
94
|
+
logger.info("Building for Ruby requested versions: #{vers}")
|
95
|
+
|
127
96
|
ENV["RUBY_CC_VERSION"] = vers.join(":")
|
128
97
|
end
|
129
98
|
|
99
|
+
opts.on("--tag TAG", "Use a specific version of the Docker image") do |tag|
|
100
|
+
logger.info("Using version #{tag} of the Docker image")
|
101
|
+
OPTIONS[:version] = tag
|
102
|
+
OPTIONS[:no_cache] = tag == "latest"
|
103
|
+
end
|
104
|
+
|
105
|
+
opts.on("--list-platforms", "--list", "List all supported platforms") do
|
106
|
+
logger.info("Supported platforms listed below:")
|
107
|
+
list_platforms
|
108
|
+
exit(0)
|
109
|
+
end
|
110
|
+
|
130
111
|
opts.on("-h", "--help", "Prints this help") do
|
131
112
|
puts opts
|
132
113
|
exit
|
@@ -135,14 +116,60 @@ OptionParser.new do |opts|
|
|
135
116
|
opts.on("-V", "--verbose", "Prints verbose output") do
|
136
117
|
ENV["LOG_LEVEL"] = "trace"
|
137
118
|
ENV["VERBOSE"] = "1"
|
138
|
-
|
119
|
+
logger.level = :trace
|
120
|
+
OPTIONS[:verbose] = true
|
139
121
|
end
|
140
122
|
|
141
|
-
opts.on("--
|
142
|
-
|
123
|
+
opts.on("--mount-toolchains", "Mount local Rustup toolchain (instead of pre-installed from Docker container)") do
|
124
|
+
OPTIONS[:mount_rustup_toolchains] = true
|
125
|
+
end
|
126
|
+
|
127
|
+
opts.on("-d", "--directory DIR", "Directory to run the command in") do |val|
|
128
|
+
OPTIONS[:directory] = File.expand_path(val)
|
143
129
|
end
|
144
130
|
end.parse!
|
145
131
|
|
132
|
+
def list_platforms
|
133
|
+
RbSys::ToolchainInfo.supported.each do |p|
|
134
|
+
old = logger.io
|
135
|
+
logger.io = $stdout
|
136
|
+
puts "- #{p.platform}"
|
137
|
+
ensure
|
138
|
+
logger.io = old
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
def default_docker_command
|
143
|
+
return @default_docker_command if defined?(@default_docker_command)
|
144
|
+
|
145
|
+
@default_docker_command = ENV.fetch("DOCKER") do
|
146
|
+
if !(docker = `which docker`).empty?
|
147
|
+
docker.strip
|
148
|
+
elsif !(podman = `which podman`).empty?
|
149
|
+
podman.strip
|
150
|
+
else
|
151
|
+
logger.fatal("Could not find docker or podman command, please install one of them")
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
def run_command!(*cmd)
|
157
|
+
logger.trace("Running command:\n\t$ #{cmd.join(" ")}")
|
158
|
+
stdout, stderr, status = Open3.capture3(*cmd)
|
159
|
+
|
160
|
+
if status.success?
|
161
|
+
stdout
|
162
|
+
else
|
163
|
+
logger.error("Error running command: $ #{cmd}")
|
164
|
+
warn(stderr)
|
165
|
+
exit(status.exitstatus)
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
def docker(cmd)
|
170
|
+
run_command!("#{default_docker_command} #{cmd}")
|
171
|
+
end
|
172
|
+
|
146
173
|
def determine_cache_dir
|
147
174
|
return ENV["RB_SYS_DOCK_CACHE_DIR"] if ENV["RB_SYS_DOCK_CACHE_DIR"]
|
148
175
|
return File.join(ENV["XDG_CACHE_HOME"], "rb-sys-dock") if ENV["XDG_CACHE_HOME"]
|
@@ -172,53 +199,93 @@ def mount_cargo_registry
|
|
172
199
|
end
|
173
200
|
|
174
201
|
dir = File.join("registry")
|
175
|
-
|
202
|
+
logger.trace("Mounting cargo registry dir: #{dir}")
|
176
203
|
FileUtils.mkdir_p(dir)
|
177
204
|
|
178
|
-
|
205
|
+
mount_shared_bind_dir(File.join(local_registry_dir, dir), File.join("/usr/local/cargo", dir))
|
206
|
+
end
|
207
|
+
|
208
|
+
def mount_rustup_toolchains
|
209
|
+
return unless OPTIONS[:mount_rustup_toolchains]
|
210
|
+
|
211
|
+
local_rustup_dir = if OPTIONS[:mount_rustup_toolchains].is_a?(String)
|
212
|
+
OPTIONS[:mount_rustup_toolchains]
|
213
|
+
elsif ENV["RUSTUP_HOME"]
|
214
|
+
ENV["RUSTUP_HOME"]
|
215
|
+
elsif File.exist?(rustup_home = File.join(ENV["HOME"], ".rustup"))
|
216
|
+
rustup_home
|
217
|
+
else
|
218
|
+
logger.fatal("Could not find Rustup home directory, please set RUSTUP_HOME")
|
219
|
+
end
|
220
|
+
|
221
|
+
logger.info("Mounting rustup toolchains from #{local_rustup_dir}")
|
222
|
+
|
223
|
+
target_triple = OPTIONS[:toolchain_info].rust_target
|
224
|
+
dkr_triple = "x86_64-unknown-linux-gnu"
|
225
|
+
dkr_toolchain = "stable-#{dkr_triple}"
|
226
|
+
dkr_toolchain_dir = "/usr/local/rustup/toolchains/#{dkr_toolchain}"
|
227
|
+
installed_toolchains = Dir.glob(File.join(local_rustup_dir, "toolchains", "*")).map { |f| File.basename(f) }
|
228
|
+
has_host_toolchain = installed_toolchains.any? { |t| t.end_with?(dkr_toolchain) }
|
229
|
+
|
230
|
+
if !has_host_toolchain
|
231
|
+
logger.info("Installing default toolchain for docker image (#{dkr_toolchain})")
|
232
|
+
run_command!("rustup", "toolchain", "add", dkr_toolchain, "--force-non-host")
|
233
|
+
end
|
234
|
+
|
235
|
+
has_target = run_command!("rustup target list --installed --toolchain #{dkr_toolchain}").include?(target_triple)
|
236
|
+
|
237
|
+
if !has_target
|
238
|
+
logger.info("Installing target for docker image (#{target_triple})")
|
239
|
+
run_command!("rustup", "target", "add", target_triple, "--toolchain", dkr_toolchain)
|
240
|
+
end
|
241
|
+
|
242
|
+
volume("#{local_rustup_dir}/toolchains/#{dkr_toolchain}", dkr_toolchain_dir, mode: "z,ro")
|
179
243
|
end
|
180
244
|
|
181
245
|
def volume(src, dest, mode: "rw")
|
182
246
|
"--volume #{src}:#{dest}:rw"
|
183
247
|
end
|
184
248
|
|
185
|
-
def mount_bundle_cache
|
186
|
-
dir = File.join(cache_dir,
|
249
|
+
def mount_bundle_cache
|
250
|
+
dir = File.join(cache_dir, ruby_platform, "bundle")
|
187
251
|
bundle_path = File.join(docker_tmp, "bundle")
|
188
252
|
FileUtils.mkdir_p(dir)
|
189
|
-
|
253
|
+
logger.trace("Mounting bundle cache: #{dir}")
|
190
254
|
|
191
255
|
"#{volume(dir, bundle_path)} -e BUNDLE_PATH=#{bundle_path.inspect}"
|
192
256
|
end
|
193
257
|
|
194
|
-
def tmp_target_dir
|
258
|
+
def tmp_target_dir
|
195
259
|
return @tmp_target_dir if defined?(@tmp_target_dir)
|
196
260
|
|
197
|
-
dir = File.join(
|
261
|
+
dir = File.join(working_directory, "tmp", "rb-sys-dock", ruby_platform, "target")
|
198
262
|
FileUtils.mkdir_p(dir)
|
199
263
|
@tmp_target_dir = dir
|
200
264
|
end
|
201
265
|
|
202
|
-
def
|
203
|
-
|
266
|
+
def working_directory
|
267
|
+
OPTIONS.fetch(:directory)
|
204
268
|
end
|
205
269
|
|
206
|
-
def
|
270
|
+
def mount_target_dir
|
271
|
+
"-v #{tmp_target_dir}:#{File.join(working_directory, "target")}"
|
272
|
+
end
|
273
|
+
|
274
|
+
def mount_command_history
|
207
275
|
return unless $stdin.tty?
|
208
276
|
|
209
|
-
history_dir = File.join(cache_dir,
|
277
|
+
history_dir = File.join(cache_dir, OPTIONS.fetch(:platform), "commandhistory")
|
210
278
|
FileUtils.mkdir_p(history_dir)
|
211
279
|
"-v #{history_dir}:#{File.join(docker_tmp, "commandhistory")}"
|
212
280
|
end
|
213
281
|
|
214
|
-
def default_command_to_run(input_args
|
282
|
+
def default_command_to_run(input_args)
|
215
283
|
input_cmd = input_args.empty? ? "true" : input_args.join(" ")
|
216
284
|
|
217
|
-
if
|
285
|
+
if OPTIONS[:build]
|
218
286
|
with_bundle = +"test -f Gemfile && bundle install && #{input_cmd} && bundle exec rake native:$RUBY_TARGET gem"
|
219
287
|
without_bundle = "#{input_cmd} && rake native:$RUBY_TARGET gem"
|
220
|
-
|
221
|
-
log(:notice, " $ rake native:#{options[:toolchain_info].platform} gem")
|
288
|
+
logger.info("Running default build command (rake native:#{ruby_platform} gem)")
|
222
289
|
"bash -c '(#{with_bundle}) || (#{without_bundle})'"
|
223
290
|
else
|
224
291
|
input_args.empty? ? "bash" : "bash -c '#{input_args.join(" ")}'"
|
@@ -242,11 +309,27 @@ def interactive?(input_args)
|
|
242
309
|
$stdin.tty?
|
243
310
|
end
|
244
311
|
|
245
|
-
def
|
246
|
-
"--mount type=bind,source=#{
|
312
|
+
def mount_shared_bind_dir(src, dest)
|
313
|
+
"--mount type=bind,source=#{src},destination=#{dest},readonly=false"
|
314
|
+
end
|
315
|
+
|
316
|
+
def mount_tmp_dir
|
317
|
+
"--mount type=bind,source=#{Dir.mktmpdir},destination=#{working_directory}/tmp/#{ruby_platform},readonly=false"
|
318
|
+
end
|
319
|
+
|
320
|
+
def toolchain_info
|
321
|
+
@toolchain_info ||= OPTIONS.fetch(:toolchain_info) do
|
322
|
+
logger.error("Could not determine ruby platform, please set ruby platform with --platform to one of:")
|
323
|
+
list_platforms
|
324
|
+
logger.fatal("Exiting...")
|
325
|
+
end
|
247
326
|
end
|
248
327
|
|
249
|
-
def
|
328
|
+
def ruby_platform
|
329
|
+
@ruby_platform ||= toolchain_info.platform
|
330
|
+
end
|
331
|
+
|
332
|
+
def rcd(input_args)
|
250
333
|
wrapper_command = []
|
251
334
|
wrapper_command << "sigfw" unless interactive?(input_args)
|
252
335
|
wrapper_command << "runas"
|
@@ -256,12 +339,14 @@ def rcd(input_args, options)
|
|
256
339
|
|
257
340
|
cmd = <<~SH
|
258
341
|
#{default_docker_command} run \
|
259
|
-
|
260
|
-
#{
|
261
|
-
#{
|
342
|
+
--platform #{OPTIONS.fetch(:docker_platform)} \
|
343
|
+
-v #{working_directory}:#{working_directory} \
|
344
|
+
#{mount_tmp_dir} \
|
345
|
+
#{mount_target_dir} \
|
262
346
|
#{mount_cargo_registry} \
|
263
|
-
#{
|
264
|
-
#{
|
347
|
+
#{mount_rustup_toolchains} \
|
348
|
+
#{mount_bundle_cache} \
|
349
|
+
#{mount_command_history} \
|
265
350
|
#{user_mapping} \
|
266
351
|
-e GEM_PRIVATE_KEY_PASSPHRASE \
|
267
352
|
-e ftp_proxy \
|
@@ -269,52 +354,64 @@ def rcd(input_args, options)
|
|
269
354
|
-e https_proxy \
|
270
355
|
-e RCD_HOST_RUBY_PLATFORM=#{RbConfig::CONFIG["arch"]} \
|
271
356
|
-e RCD_HOST_RUBY_VERSION=#{RUBY_VERSION} \
|
357
|
+
-e RUSTUP_PERMIT_COPY_RENAME=true \
|
272
358
|
-e RCD_IMAGE \
|
273
359
|
-e RB_SYS_DOCK_TMPDIR="/tmp/rb-sys-dock" \
|
274
|
-
-e RB_SYS_CARGO_TARGET_DIR=#{tmp_target_dir
|
360
|
+
-e RB_SYS_CARGO_TARGET_DIR=#{tmp_target_dir.inspect} \
|
275
361
|
#{ENV["RUBY_CC_VERSION"] ? "-e RUBY_CC_VERSION=#{ENV["RUBY_CC_VERSION"]}" : ""} \
|
276
362
|
-e RAKEOPT \
|
277
363
|
-e TERM \
|
278
|
-
-
|
279
|
-
-w #{Dir.pwd} \
|
364
|
+
-w #{working_directory} \
|
280
365
|
--rm \
|
281
366
|
--interactive \
|
282
367
|
#{docker_options.join(" ")} \
|
283
368
|
#{ENV.fetch("RCD_IMAGE")} \
|
284
369
|
#{wrapper_command.join(" ")} \
|
285
|
-
#{default_command_to_run(input_args
|
370
|
+
#{default_command_to_run(input_args)}
|
286
371
|
SH
|
287
372
|
|
288
|
-
|
373
|
+
cmd.gsub!(/\s+/, " ")
|
374
|
+
|
375
|
+
logger.trace("Running command:\n\t$ #{cmd}")
|
289
376
|
|
290
377
|
exec(cmd)
|
291
378
|
end
|
292
379
|
|
293
|
-
def download_image
|
380
|
+
def download_image
|
294
381
|
image = ENV.fetch("RCD_IMAGE")
|
295
382
|
|
296
|
-
if docker("images -q #{image}").strip.empty? ||
|
383
|
+
if docker("images -q #{image}").strip.empty? || OPTIONS[:no_cache]
|
297
384
|
# Nicely formatted message that we are downloading the image which might take awhile
|
298
|
-
|
299
|
-
docker("pull #{image} --quiet > /dev/null")
|
385
|
+
logger.info("Downloading container #{image.inspect}, this might take awhile...")
|
386
|
+
docker("pull #{image} --platform #{OPTIONS[:docker_platform]} --quiet > /dev/null")
|
300
387
|
end
|
301
388
|
end
|
302
389
|
|
303
|
-
def log_some_useful_info
|
304
|
-
return if
|
390
|
+
def log_some_useful_info
|
391
|
+
return if OPTIONS[:build]
|
305
392
|
|
306
393
|
if ARGV.empty?
|
307
|
-
|
394
|
+
logger.info("Entering shell in Docker container #{ENV["RCD_IMAGE"].inspect}")
|
308
395
|
else
|
309
|
-
|
396
|
+
logger.info("Running command #{ARGV.inspect} in Docker container #{ENV["RCD_IMAGE"].inspect}")
|
310
397
|
end
|
311
398
|
end
|
312
399
|
|
313
|
-
def set_env
|
314
|
-
ENV["RCD_IMAGE"] ||= "rbsys/#{
|
400
|
+
def set_env
|
401
|
+
ENV["RCD_IMAGE"] ||= "rbsys/#{ruby_platform}:#{OPTIONS[:version]}"
|
402
|
+
end
|
403
|
+
|
404
|
+
def lint_rb_sys
|
405
|
+
cargo_version = cargo_metadata.rb_sys_version
|
406
|
+
return if cargo_version == RbSys::VERSION
|
407
|
+
logger.warn("Cargo rb-sys version (#{cargo_version}) does not match Ruby gem version (#{RbSys::VERSION})")
|
408
|
+
rescue => e
|
409
|
+
logger.warn("Could not determine Cargo rb-sys version")
|
410
|
+
logger.trace("Error was: #{e.inspect}")
|
315
411
|
end
|
316
412
|
|
317
|
-
set_env
|
318
|
-
|
319
|
-
|
320
|
-
|
413
|
+
set_env
|
414
|
+
lint_rb_sys
|
415
|
+
download_image
|
416
|
+
log_some_useful_info
|
417
|
+
rcd(ARGV)
|
@@ -12,10 +12,13 @@ module RbSys
|
|
12
12
|
# Initializes a new Cargo::Metadata instance.
|
13
13
|
#
|
14
14
|
# @param name [String] the name of the Cargo project
|
15
|
-
def initialize(name)
|
15
|
+
def initialize(name, deps: false)
|
16
16
|
raise ArgumentError, "name must be a String" unless name.is_a?(String)
|
17
17
|
|
18
18
|
@name = name
|
19
|
+
@cargo_metadata = nil
|
20
|
+
@package_metadata = nil
|
21
|
+
@deps = deps
|
19
22
|
end
|
20
23
|
|
21
24
|
# Returns the path where the Cargo project's Cargo.toml is located.
|
@@ -88,6 +91,13 @@ module RbSys
|
|
88
91
|
package_metadata.fetch("metadata")
|
89
92
|
end
|
90
93
|
|
94
|
+
# Returns the rb-sys version, if any.
|
95
|
+
def rb_sys_version
|
96
|
+
pkg = packages.find { |p| p.fetch("name") == "rb-sys" }
|
97
|
+
return unless pkg
|
98
|
+
pkg["version"]
|
99
|
+
end
|
100
|
+
|
91
101
|
private
|
92
102
|
|
93
103
|
def package_metadata
|
@@ -103,7 +113,8 @@ module RbSys
|
|
103
113
|
|
104
114
|
::Gem.load_yaml
|
105
115
|
cargo = ENV["CARGO"] || "cargo"
|
106
|
-
args = ["metadata", "--
|
116
|
+
args = ["metadata", "--format-version", "1"]
|
117
|
+
args << "--no-deps" unless @deps
|
107
118
|
out, stderr, status = Open3.capture3(cargo, *args)
|
108
119
|
raise "exited with non-zero status (#{status})" unless status.success?
|
109
120
|
data = Gem::SafeYAML.safe_load(out)
|
data/lib/rb_sys/extensiontask.rb
CHANGED
@@ -4,7 +4,7 @@ require_relative "error"
|
|
4
4
|
begin
|
5
5
|
require "rake/extensiontask"
|
6
6
|
rescue LoadError
|
7
|
-
abort "Please install rake-compiler to use this
|
7
|
+
abort "Please install rake-compiler to use this feature"
|
8
8
|
end
|
9
9
|
|
10
10
|
module RbSys
|
@@ -22,8 +22,9 @@ module RbSys
|
|
22
22
|
# @param gem_spec [Gem::Specification] the gem specification to build (needed for cross-compiling)
|
23
23
|
# @return [Rake::ExtensionTask]
|
24
24
|
class ExtensionTask < Rake::ExtensionTask
|
25
|
-
def init(name = nil, gem_spec =
|
26
|
-
super
|
25
|
+
def init(name = nil, gem_spec = :undefined)
|
26
|
+
super(name, lint_gem_spec(name, gem_spec))
|
27
|
+
|
27
28
|
@orginal_ext_dir = @ext_dir
|
28
29
|
@ext_dir = cargo_metadata.manifest_directory
|
29
30
|
@source_pattern = nil
|
@@ -46,6 +47,8 @@ module RbSys
|
|
46
47
|
def define
|
47
48
|
super
|
48
49
|
define_env_tasks
|
50
|
+
|
51
|
+
CLEAN.include(target_directory) if defined?(CLEAN)
|
49
52
|
end
|
50
53
|
|
51
54
|
def cargo_metadata
|
@@ -118,5 +121,34 @@ module RbSys
|
|
118
121
|
desc 'Compile the native Rust extension with the "release" profile'
|
119
122
|
task "compile:release" => ["rb_sys:env:release", "compile"]
|
120
123
|
end
|
124
|
+
|
125
|
+
private
|
126
|
+
|
127
|
+
def lint_gem_spec(name, gs)
|
128
|
+
gem_spec = case gs
|
129
|
+
when :undefined
|
130
|
+
return
|
131
|
+
when Gem::Specification
|
132
|
+
gs
|
133
|
+
when String
|
134
|
+
Gem::Specification.load(gem_spec) || raise(ArgumentError, "Unable to load gemspec from file #{gs.inspect}")
|
135
|
+
else
|
136
|
+
raise ArgumentError, "gem_spec must be a Gem::Specification, got #{gs.class}"
|
137
|
+
end
|
138
|
+
|
139
|
+
gem_spec.files.each do |f|
|
140
|
+
if /\.(dll|so|dylib|lib|bundle)$/.match?(f)
|
141
|
+
warn "⚠️ gemspec includes native artifact (#{f}), please remove it."
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
if (gem_crate_name = gem_spec.metadata["cargo_crate_name"])
|
146
|
+
if name != gem_crate_name
|
147
|
+
warn "⚠️ cargo_crate_name (#{gem_crate_name}) does not match extension task crate name (#{name})"
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
gem_spec
|
152
|
+
end
|
121
153
|
end
|
122
154
|
end
|
data/lib/rb_sys/mkmf.rb
CHANGED
@@ -246,7 +246,6 @@ module RbSys
|
|
246
246
|
\t$(Q) curl --proto '=https' --tlsv1.2 --retry 10 --retry-connrefused -fsSL "https://sh.rustup.rs" | sh -s -- --no-modify-path --profile $(RB_SYS_RUSTUP_PROFILE) --default-toolchain none -y
|
247
247
|
\t$(Q) rustup toolchain install $(RB_SYS_DEFAULT_TOOLCHAIN) --profile $(RB_SYS_RUSTUP_PROFILE)
|
248
248
|
\t$(Q) rustup default $(RB_SYS_DEFAULT_TOOLCHAIN)
|
249
|
-
\t$(Q) rustup component add rustfmt
|
250
249
|
|
251
250
|
$(RUSTLIB): $(CARGO)
|
252
251
|
#{endif_stmt}
|
@@ -0,0 +1,73 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RbSys
|
4
|
+
module Util
|
5
|
+
class Logger
|
6
|
+
attr_accessor :io, :level
|
7
|
+
|
8
|
+
def initialize(io: $stderr, level: :info)
|
9
|
+
@io = ENV["GITHUB_ACTIONS"] ? $stdout : io
|
10
|
+
@level = level
|
11
|
+
end
|
12
|
+
|
13
|
+
def error(message, **opts)
|
14
|
+
add(:error, message, **opts)
|
15
|
+
end
|
16
|
+
|
17
|
+
def warn(message, **opts)
|
18
|
+
add(:warn, message, **opts)
|
19
|
+
end
|
20
|
+
|
21
|
+
def info(message, **opts)
|
22
|
+
add(:info, message, **opts)
|
23
|
+
end
|
24
|
+
|
25
|
+
def notice(message, **opts)
|
26
|
+
add(:notice, message, **opts)
|
27
|
+
end
|
28
|
+
|
29
|
+
def trace(message, **opts)
|
30
|
+
return unless level == :trace
|
31
|
+
|
32
|
+
add(:trace, message, **opts)
|
33
|
+
end
|
34
|
+
|
35
|
+
def fatal(message, **opts)
|
36
|
+
error(message, **opts)
|
37
|
+
abort
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
LEVEL_STYLES = {
|
43
|
+
warn: ["⚠️", "\e[1;33m"],
|
44
|
+
error: ["❌", "\e[1;31m"],
|
45
|
+
notice: ["👋", "\e[1;37m"],
|
46
|
+
info: ["🐳", "\e[1;34m"],
|
47
|
+
trace: ["🔍", "\e[1;2m"]
|
48
|
+
}
|
49
|
+
|
50
|
+
if ENV["GITHUB_ACTIONS"]
|
51
|
+
def add(level, message, emoji: true)
|
52
|
+
emote, _ = LEVEL_STYLES.fetch(level.to_sym)
|
53
|
+
io.puts "::#{level}::#{emote} #{message}"
|
54
|
+
end
|
55
|
+
else
|
56
|
+
def add(level, message, emoji: true)
|
57
|
+
emoji_opt, shellcode = LEVEL_STYLES.fetch(level.to_sym)
|
58
|
+
|
59
|
+
emoji_opt = if emoji.is_a?(String)
|
60
|
+
emoji + " "
|
61
|
+
elsif emoji
|
62
|
+
emoji_opt + " "
|
63
|
+
end
|
64
|
+
|
65
|
+
# Escape the message for bash shell codes (e.g. \033[1;31m)
|
66
|
+
escaped = message.gsub("\\", "\\\\\\").gsub("\033", "\\033")
|
67
|
+
|
68
|
+
io.puts "#{shellcode}#{emoji_opt}#{escaped}\033[0m"
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
data/lib/rb_sys/version.rb
CHANGED
data.tar.gz.sig
CHANGED
Binary file
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rb_sys
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.
|
4
|
+
version: 0.9.65
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ian Ker-Seymer
|
@@ -30,7 +30,7 @@ cert_chain:
|
|
30
30
|
Rl+ASkq2/1i07TkBpCf+2hq66+h/hx+/Y/KrUzXfe0jtvil0WESkJT2kqRqHWNhD
|
31
31
|
9GKBxaQlXokNDtWCm1/gl6cD8WRZ0N5S4ZGJT1FLLsA=
|
32
32
|
-----END CERTIFICATE-----
|
33
|
-
date: 2023-02-
|
33
|
+
date: 2023-02-13 00:00:00.000000000 Z
|
34
34
|
dependencies: []
|
35
35
|
description:
|
36
36
|
email:
|
@@ -57,6 +57,7 @@ files:
|
|
57
57
|
- lib/rb_sys/mkmf/config.rb
|
58
58
|
- lib/rb_sys/toolchain_info.rb
|
59
59
|
- lib/rb_sys/toolchain_info/data.rb
|
60
|
+
- lib/rb_sys/util/logger.rb
|
60
61
|
- lib/rb_sys/version.rb
|
61
62
|
homepage: https://oxidize-rb.github.io/rb-sys/
|
62
63
|
licenses:
|
@@ -79,7 +80,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
79
80
|
- !ruby/object:Gem::Version
|
80
81
|
version: '0'
|
81
82
|
requirements: []
|
82
|
-
rubygems_version: 3.4.
|
83
|
+
rubygems_version: 3.4.6
|
83
84
|
signing_key:
|
84
85
|
specification_version: 4
|
85
86
|
summary: Helpers for compiling Rust extensions for ruby
|
metadata.gz.sig
CHANGED
Binary file
|