tebako 0.10.0 → 0.12.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 +4 -4
- data/CMakeLists.txt +5 -15
- data/README.adoc +241 -78
- data/common.env +2 -2
- data/include/tebako/tebako-prism.h +51 -0
- data/lib/tebako/cli.rb +34 -11
- data/lib/tebako/cli_helpers.rb +25 -9
- data/lib/tebako/codegen.rb +95 -10
- data/lib/tebako/deploy_helper.rb +1 -1
- data/lib/tebako/options_manager.rb +89 -12
- data/lib/tebako/package_descriptor.rb +143 -0
- data/lib/tebako/packager/pass1_patch.rb +301 -0
- data/lib/tebako/packager/pass1a_patch.rb +55 -0
- data/lib/tebako/packager/pass2.rb +4 -3
- data/lib/tebako/packager/{pass1a.rb → patch.rb} +5 -13
- data/lib/tebako/packager/patch_literals.rb +39 -15
- data/lib/tebako/packager.rb +18 -23
- data/lib/tebako/packager_lite.rb +78 -0
- data/lib/tebako/ruby_version.rb +9 -3
- data/lib/tebako/scenario_manager.rb +1 -1
- data/lib/tebako/version.rb +1 -1
- data/src/tebako-main.cpp +46 -30
- metadata +8 -4
- data/lib/tebako/packager/pass1.rb +0 -242
data/lib/tebako/cli.rb
CHANGED
@@ -43,7 +43,7 @@ require_relative "version"
|
|
43
43
|
module Tebako
|
44
44
|
DEFAULT_TEBAFILE = ".tebako.yml"
|
45
45
|
# Tebako packager front-end
|
46
|
-
class Cli < Thor
|
46
|
+
class Cli < Thor # rubocop:disable Metrics/ClassLength
|
47
47
|
package_name "Tebako"
|
48
48
|
class_option :prefix, type: :string, aliases: "-p", required: false,
|
49
49
|
desc: "A path to tebako packaging environment, '~/.tebako' ('$HOME/.tebako') by default"
|
@@ -82,28 +82,35 @@ module Tebako
|
|
82
82
|
#{" " * 65}# If this parameter is not set, the application will start in the current directory of the host file system.
|
83
83
|
DESC
|
84
84
|
|
85
|
+
REF_DESCRIPTION = <<~DESC
|
86
|
+
"Referenced tebako run-time package; 'tebako-runtime' by default".
|
87
|
+
#{" " * 65}# This option specifies the tebako runtime to be used by the application on Windows and if mode is 'application' only .
|
88
|
+
DESC
|
89
|
+
|
85
90
|
RGP_DESCRIPTION = <<~DESC
|
86
|
-
|
87
|
-
#{" " * 65}#
|
88
|
-
#{" " * 65}# Gnu toolchain only (not for LLVM/clang). The feature is exeprimental, we may consider other approach in the future.
|
91
|
+
Current working directory for packaged application. This directory shall be specified relative to root.
|
92
|
+
#{" " * 65}# If this parameter is not set, the application will start in the current directory of the host file system.
|
89
93
|
DESC
|
90
94
|
|
91
95
|
desc "press", "Press tebako image"
|
92
|
-
method_option :cwd, type: :string, aliases: "-c", required: false,
|
93
|
-
desc: CWD_DESCRIPTION
|
94
|
-
method_option :"entry-point", type: :string, aliases: ["-e", "--entry"], required: true,
|
95
|
-
desc: "Ruby application entry point"
|
96
|
+
method_option :cwd, type: :string, aliases: "-c", required: false, desc: CWD_DESCRIPTION
|
96
97
|
method_option :"log-level", type: :string, aliases: "-l", required: false, enum: %w[error warn debug trace],
|
97
98
|
desc: "Tebako memfs logging level, 'error' by default"
|
98
99
|
method_option :output, type: :string, aliases: "-o", required: false,
|
99
100
|
desc: "Tebako package file name, entry point base file name in the current folder by default"
|
100
|
-
method_option :
|
101
|
+
method_option :"entry-point", type: :string, aliases: ["-e", "--entry"], required: false,
|
102
|
+
desc: "Ruby application entry point"
|
103
|
+
method_option :root, type: :string, aliases: "-r", required: false, desc: "Root folder of the Ruby application"
|
101
104
|
method_option :Ruby, type: :string, aliases: "-R", required: false,
|
102
105
|
enum: Tebako::RubyVersion::RUBY_VERSIONS.keys,
|
103
106
|
desc: "Tebako package Ruby version, #{Tebako::RubyVersion::DEFAULT_RUBY_VERSION} by default"
|
104
|
-
method_option :patchelf, aliases: "-P", type: :boolean,
|
105
|
-
|
107
|
+
method_option :patchelf, aliases: "-P", type: :boolean, desc: RGP_DESCRIPTION
|
108
|
+
method_option :mode, type: :string, aliases: "-m", required: false, enum: %w[bundle both runtime application],
|
109
|
+
desc: "Tebako press mode, 'bundle' by default"
|
110
|
+
method_option :ref, type: :string, aliases: "-u", required: false, desc: REF_DESCRIPTION
|
111
|
+
|
106
112
|
def press
|
113
|
+
validate_press_options
|
107
114
|
(om, cm) = bootstrap
|
108
115
|
|
109
116
|
do_press(om)
|
@@ -159,6 +166,22 @@ module Tebako
|
|
159
166
|
end
|
160
167
|
end
|
161
168
|
|
169
|
+
no_commands do
|
170
|
+
def source
|
171
|
+
c_path = Pathname.new(__FILE__).realpath
|
172
|
+
@source ||= File.expand_path("../../..", c_path)
|
173
|
+
end
|
174
|
+
|
175
|
+
def validate_press_options
|
176
|
+
return unless options["mode"] != "runtime"
|
177
|
+
|
178
|
+
opts = ""
|
179
|
+
opts += " '--root'" if options["root"].nil?
|
180
|
+
opts += " '--entry-point'" if options["entry-point"].nil?
|
181
|
+
raise Thor::Error, "No value provided for required options #{opts}" unless opts.empty?
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
162
185
|
no_commands do
|
163
186
|
include Tebako::CliHelpers
|
164
187
|
end
|
data/lib/tebako/cli_helpers.rb
CHANGED
@@ -34,6 +34,7 @@ require_relative "codegen"
|
|
34
34
|
require_relative "error"
|
35
35
|
require_relative "options_manager"
|
36
36
|
require_relative "scenario_manager"
|
37
|
+
require_relative "packager_lite"
|
37
38
|
|
38
39
|
# Tebako - an executable packager
|
39
40
|
# Command-line interface methods
|
@@ -41,10 +42,27 @@ module Tebako
|
|
41
42
|
# Cli helpers
|
42
43
|
module CliHelpers
|
43
44
|
def do_press(options_manager)
|
44
|
-
|
45
|
+
scenario_manager = Tebako::ScenarioManager.new(options_manager.root, options_manager.fs_entrance)
|
46
|
+
puts options_manager.press_announce(scenario_manager.msys?)
|
47
|
+
|
48
|
+
if options_manager.mode == "both" || options_manager.mode == "runtime" || options_manager.mode == "bundle"
|
49
|
+
do_press_runtime(options_manager, scenario_manager)
|
50
|
+
end
|
51
|
+
|
52
|
+
if options_manager.mode == "both" || options_manager.mode == "application"
|
53
|
+
do_press_application(options_manager, scenario_manager)
|
54
|
+
end
|
55
|
+
|
56
|
+
true
|
57
|
+
end
|
45
58
|
|
46
|
-
|
59
|
+
def do_press_application(options_manager, scenario_manager)
|
60
|
+
packager = Tebako::PackagerLite.new(options_manager, scenario_manager)
|
61
|
+
packager.create_package
|
62
|
+
end
|
47
63
|
|
64
|
+
def do_press_runtime(options_manager, scenario_manager)
|
65
|
+
generate_files(options_manager, scenario_manager)
|
48
66
|
cfg_cmd = "cmake -DSETUP_MODE:BOOLEAN=OFF #{options_manager.cfg_options} #{options_manager.press_options}"
|
49
67
|
build_cmd = "cmake --build #{options_manager.output_folder} --target tebako --parallel #{Etc.nprocessors}"
|
50
68
|
merged_env = ENV.to_h.merge(options_manager.b_env)
|
@@ -64,20 +82,18 @@ module Tebako
|
|
64
82
|
true
|
65
83
|
end
|
66
84
|
|
67
|
-
def generate_files(options_manager)
|
85
|
+
def generate_files(options_manager, scenario_manager)
|
68
86
|
puts "-- Generating files"
|
69
|
-
scenario_manager = Tebako::ScenarioManager.new(options_manager.root, options_manager.fs_entrance)
|
70
87
|
scenario_manager.configure_scenario
|
71
88
|
|
72
|
-
puts " ... tebako-version.h"
|
73
89
|
v_parts = Tebako::VERSION.split(".")
|
74
90
|
Tebako::Codegen.generate_tebako_version_h(options_manager, v_parts)
|
75
|
-
|
76
|
-
puts " ... tebako-fs.cpp"
|
77
91
|
Tebako::Codegen.generate_tebako_fs_cpp(options_manager, scenario_manager)
|
78
|
-
|
79
|
-
puts " ... deploy.rb"
|
80
92
|
Tebako::Codegen.generate_deploy_rb(options_manager, scenario_manager)
|
93
|
+
|
94
|
+
return unless options_manager.mode == "both" || options_manager.mode == "runtime"
|
95
|
+
|
96
|
+
Tebako::Codegen.generate_stub_rb(options_manager)
|
81
97
|
end
|
82
98
|
|
83
99
|
def options_from_tebafile(tebafile)
|
data/lib/tebako/codegen.rb
CHANGED
@@ -28,6 +28,8 @@
|
|
28
28
|
require "pathname"
|
29
29
|
require "fileutils"
|
30
30
|
|
31
|
+
require_relative "package_descriptor"
|
32
|
+
|
31
33
|
# Tebako - an executable packager
|
32
34
|
module Tebako
|
33
35
|
# Code geberation
|
@@ -47,20 +49,42 @@ module Tebako
|
|
47
49
|
|
48
50
|
SUBST
|
49
51
|
|
50
|
-
class << self
|
52
|
+
class << self # rubocop:disable Metrics/ClassLength
|
51
53
|
def deploy_crt_implib(opt, scm)
|
52
54
|
crt = ""
|
53
55
|
if scm.msys?
|
54
56
|
crt = <<~SUBST
|
55
57
|
Tebako::Packager.create_implib("#{opt.ruby_src_dir}", "#{opt.data_src_dir}",
|
56
|
-
"#{
|
58
|
+
"#{opt.package}", rv)
|
57
59
|
SUBST
|
58
60
|
end
|
59
61
|
crt
|
60
62
|
end
|
61
63
|
|
62
|
-
def
|
63
|
-
|
64
|
+
def deploy_mk(opt, scm)
|
65
|
+
case opt.mode
|
66
|
+
when "bundle"
|
67
|
+
deploy_mk_bundle(opt, scm)
|
68
|
+
when /runtime|both/
|
69
|
+
deploy_mk_stub(opt)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def deploy_mk_bundle(opt, scm)
|
74
|
+
<<~SUBST
|
75
|
+
Tebako::Packager.deploy("#{opt.data_src_dir}", "#{opt.data_pre_dir}",
|
76
|
+
rv , "#{opt.root}", "#{scm.fs_entrance}", "#{opt.cwd}")
|
77
|
+
Tebako::Packager.mkdwarfs("#{opt.deps_bin_dir}", "#{opt.data_bundle_file}",
|
78
|
+
"#{opt.data_src_dir}")
|
79
|
+
SUBST
|
80
|
+
end
|
81
|
+
|
82
|
+
def deploy_mk_stub(opt)
|
83
|
+
<<~SUBST
|
84
|
+
Tebako::Packager.deploy("#{opt.data_src_dir}", "#{opt.data_pre_dir}",
|
85
|
+
rv, "#{File.join(opt.deps, "src", "tebako", "local")}", "stub.rb", nil)
|
86
|
+
Tebako::Packager.mkdwarfs("#{opt.deps_bin_dir}", "#{opt.data_stub_file}", "#{opt.data_src_dir}")
|
87
|
+
SUBST
|
64
88
|
end
|
65
89
|
|
66
90
|
def deploy_rb(opt, scm)
|
@@ -71,22 +95,41 @@ module Tebako
|
|
71
95
|
Tebako::Packager::init("#{opt.stash_dir}", "#{opt.data_src_dir}",
|
72
96
|
"#{opt.data_pre_dir}", "#{opt.data_bin_dir}")
|
73
97
|
#{deploy_crt_implib(opt, scm)}
|
74
|
-
|
75
|
-
rv , "#{opt.root}",
|
76
|
-
"#{scm.fs_entrance}", #{deploy_cwd(opt)})
|
77
|
-
Tebako::Packager.mkdwarfs("#{opt.deps_bin_dir}", "#{opt.data_bin_file}",
|
78
|
-
"#{opt.data_src_dir}")
|
98
|
+
#{deploy_mk(opt, scm)}
|
79
99
|
SUBST
|
80
100
|
end
|
81
101
|
|
82
102
|
def deploy_rq
|
83
103
|
<<~SUBST
|
104
|
+
require "#{File.join(__dir__, "package_descriptor.rb")}"
|
84
105
|
require "#{File.join(__dir__, "packager.rb")}"
|
85
106
|
require "#{File.join(__dir__, "ruby_version.rb")}"
|
86
107
|
SUBST
|
87
108
|
end
|
88
109
|
|
110
|
+
def stub_rb(opt)
|
111
|
+
<<~SUBST
|
112
|
+
puts "Copyright (c) 2024 Ribose Inc (https://www.ribose.com)"
|
113
|
+
puts "Tebako runtime stub v#{Tebako::VERSION}"
|
114
|
+
puts "To run your application please call #{File.basename(opt.package)} --tebako-run <your tebako package>"
|
115
|
+
SUBST
|
116
|
+
end
|
117
|
+
|
118
|
+
def generate_stub_rb(options_manager)
|
119
|
+
puts " ... stub.rb"
|
120
|
+
|
121
|
+
fname = File.join(options_manager.deps, "src", "tebako", "local", "stub.rb")
|
122
|
+
FileUtils.mkdir_p(File.dirname(fname))
|
123
|
+
|
124
|
+
File.open(fname, "w") do |file|
|
125
|
+
file.write(COMMON_RUBY_HEADER)
|
126
|
+
file.write(stub_rb(options_manager))
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
89
130
|
def generate_deploy_rb(options_manager, scenario_manager)
|
131
|
+
puts " ... deploy.rb"
|
132
|
+
|
90
133
|
fname = File.join(options_manager.deps, "bin", "deploy.rb")
|
91
134
|
FileUtils.mkdir_p(File.dirname(fname))
|
92
135
|
|
@@ -96,7 +139,20 @@ module Tebako
|
|
96
139
|
end
|
97
140
|
end
|
98
141
|
|
142
|
+
def generate_package_descriptor(options_manager, scenario_manager)
|
143
|
+
puts " ... package_descriptor"
|
144
|
+
fname = File.join(options_manager.deps, "src", "tebako", "package_descriptor")
|
145
|
+
FileUtils.mkdir_p(File.dirname(fname))
|
146
|
+
descriptor = Tebako::PackageDescriptor.new(options_manager.ruby_ver, Tebako::VERSION,
|
147
|
+
scenario_manager.fs_mount_point, scenario_manager.fs_entry_point,
|
148
|
+
options_manager.cwd)
|
149
|
+
File.binwrite(fname, descriptor.serialize)
|
150
|
+
fname
|
151
|
+
end
|
152
|
+
|
99
153
|
def generate_tebako_fs_cpp(options_manager, scenario_manager)
|
154
|
+
puts " ... tebako-fs.cpp"
|
155
|
+
|
100
156
|
fname = File.join(options_manager.deps, "src", "tebako", "tebako-fs.cpp")
|
101
157
|
FileUtils.mkdir_p(File.dirname(fname))
|
102
158
|
|
@@ -107,6 +163,8 @@ module Tebako
|
|
107
163
|
end
|
108
164
|
|
109
165
|
def generate_tebako_version_h(options_manager, v_parts)
|
166
|
+
puts " ... tebako-version.h"
|
167
|
+
|
110
168
|
fname = File.join(options_manager.deps, "include", "tebako", "tebako-version.h")
|
111
169
|
FileUtils.mkdir_p(File.dirname(fname))
|
112
170
|
|
@@ -125,7 +183,17 @@ module Tebako
|
|
125
183
|
end
|
126
184
|
|
127
185
|
def tebako_fs_cpp(options_manager, scenario_manager)
|
186
|
+
case options_manager.mode
|
187
|
+
when "bundle"
|
188
|
+
tebako_fs_cpp_bundle(options_manager, scenario_manager)
|
189
|
+
when /runtime|both/
|
190
|
+
tebako_fs_cpp_stub(options_manager, scenario_manager)
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
def tebako_fs_cpp_bundle(options_manager, scenario_manager)
|
128
195
|
<<~SUBST
|
196
|
+
#include <limits.h>
|
129
197
|
#include <incbin/incbin.h>
|
130
198
|
|
131
199
|
namespace tebako {
|
@@ -135,7 +203,24 @@ module Tebako
|
|
135
203
|
const char * package_cwd = #{package_cwd(options_manager, scenario_manager)};
|
136
204
|
char original_cwd[PATH_MAX];
|
137
205
|
|
138
|
-
INCBIN(fs, "#{options_manager.
|
206
|
+
INCBIN(fs, "#{options_manager.data_bundle_file}");
|
207
|
+
}
|
208
|
+
SUBST
|
209
|
+
end
|
210
|
+
|
211
|
+
def tebako_fs_cpp_stub(options_manager, scenario_manager)
|
212
|
+
<<~SUBST
|
213
|
+
#include <limits.h>
|
214
|
+
#include <incbin/incbin.h>
|
215
|
+
|
216
|
+
namespace tebako {
|
217
|
+
const char * fs_log_level = "#{options_manager.l_level}";
|
218
|
+
const char * fs_mount_point = "#{scenario_manager.fs_mount_point}";
|
219
|
+
const char * fs_entry_point = "/local/stub.rb";
|
220
|
+
const char * package_cwd = nullptr;
|
221
|
+
char original_cwd[PATH_MAX];
|
222
|
+
|
223
|
+
INCBIN(fs, "#{options_manager.data_stub_file}");
|
139
224
|
}
|
140
225
|
SUBST
|
141
226
|
end
|
data/lib/tebako/deploy_helper.rb
CHANGED
@@ -70,7 +70,7 @@ module Tebako
|
|
70
70
|
def deploy
|
71
71
|
BuildHelpers.with_env(deploy_env) do
|
72
72
|
update_rubygems
|
73
|
-
system("#{gem_command} env")
|
73
|
+
system("#{gem_command} env") if @verbose
|
74
74
|
install_gem("tebako-runtime")
|
75
75
|
install_gem("bundler", BUNDLER_VERSION) if needs_bundler?
|
76
76
|
deploy_solution
|
@@ -73,16 +73,32 @@ module Tebako
|
|
73
73
|
@cwd ||= f_cwd
|
74
74
|
end
|
75
75
|
|
76
|
+
def cwd_announce
|
77
|
+
@cwd_announce ||= cwd.nil? ? "<Host current directory>" : cwd
|
78
|
+
end
|
79
|
+
|
76
80
|
# DATA_BIN_DIR folder is used to create packaged filesystem
|
77
81
|
# set(DATA_BIN_DIR ${CMAKE_CURRENT_BINARY_DIR}/p)
|
78
82
|
def data_bin_dir
|
79
83
|
@data_bin_dir ||= File.join(output_folder, "p")
|
80
84
|
end
|
81
85
|
|
82
|
-
#
|
83
|
-
#
|
84
|
-
|
85
|
-
|
86
|
+
# Mode File(s) Content
|
87
|
+
# bundle fs.bin Application
|
88
|
+
# both fs.bin, fs2.bin Stub, application respectively
|
89
|
+
# runtime fs.bin Stub
|
90
|
+
# app fs2.bin Application
|
91
|
+
|
92
|
+
def data_bundle_file
|
93
|
+
@data_bundle_file ||= File.join(data_bin_dir, "fs.bin")
|
94
|
+
end
|
95
|
+
|
96
|
+
def data_stub_file
|
97
|
+
@data_stub_file ||= File.join(data_bin_dir, "fs.bin")
|
98
|
+
end
|
99
|
+
|
100
|
+
def data_app_file
|
101
|
+
@data_app_file ||= File.join(data_bin_dir, "fs2.bin")
|
86
102
|
end
|
87
103
|
|
88
104
|
# DATA_PRE_DIR folder is used to build gems that need to be packaged
|
@@ -131,11 +147,11 @@ module Tebako
|
|
131
147
|
end
|
132
148
|
|
133
149
|
def l_level
|
134
|
-
@l_level ||=
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
150
|
+
@l_level ||= @options["log-level"].nil? ? "error" : @options["log-level"]
|
151
|
+
end
|
152
|
+
|
153
|
+
def mode
|
154
|
+
@mode ||= @options["mode"].nil? ? "bundle" : @options["mode"]
|
139
155
|
end
|
140
156
|
|
141
157
|
def m_files
|
@@ -179,10 +195,57 @@ module Tebako
|
|
179
195
|
end
|
180
196
|
end
|
181
197
|
|
182
|
-
def press_announce
|
183
|
-
|
184
|
-
|
198
|
+
def press_announce(is_msys)
|
199
|
+
case mode
|
200
|
+
when "application"
|
201
|
+
press_announce_application(is_msys)
|
202
|
+
when "both"
|
203
|
+
press_announce_both
|
204
|
+
when "bundle"
|
205
|
+
press_announce_bundle
|
206
|
+
when "runtime"
|
207
|
+
press_announce_runtime
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
def press_announce_ref(is_msys)
|
212
|
+
if is_msys
|
213
|
+
" referencing runtime at '#{ref}'"
|
214
|
+
else
|
215
|
+
""
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
def press_announce_application(is_msys)
|
220
|
+
<<~ANN
|
185
221
|
Running tebako press at #{prefix}
|
222
|
+
Mode: 'application'
|
223
|
+
Ruby version: '#{@ruby_ver}'
|
224
|
+
Project root: '#{root}'
|
225
|
+
Application entry point: '#{fs_entrance}'
|
226
|
+
Package file name: '#{package}.tebako'#{press_announce_ref(is_msys)}
|
227
|
+
Package working directory: '#{cwd_announce}'
|
228
|
+
ANN
|
229
|
+
end
|
230
|
+
|
231
|
+
def press_announce_both
|
232
|
+
<<~ANN
|
233
|
+
Running tebako press at #{prefix}
|
234
|
+
Mode: 'both'
|
235
|
+
Ruby version: '#{@ruby_ver}'
|
236
|
+
Project root: '#{root}'
|
237
|
+
Application entry point: '#{fs_entrance}'
|
238
|
+
Runtime file name: '#{package}'
|
239
|
+
Package file name: '#{package}.tebako'
|
240
|
+
Loging level: '#{l_level}'
|
241
|
+
Package working directory: '#{cwd_announce}'
|
242
|
+
ANN
|
243
|
+
end
|
244
|
+
|
245
|
+
def press_announce_bundle
|
246
|
+
<<~ANN
|
247
|
+
Running tebako press at #{prefix}
|
248
|
+
Mode: 'bundle'
|
186
249
|
Ruby version: '#{@ruby_ver}'
|
187
250
|
Project root: '#{root}'
|
188
251
|
Application entry point: '#{fs_entrance}'
|
@@ -192,6 +255,16 @@ module Tebako
|
|
192
255
|
ANN
|
193
256
|
end
|
194
257
|
|
258
|
+
def press_announce_runtime
|
259
|
+
<<~ANN
|
260
|
+
Running tebako press at #{prefix}
|
261
|
+
Mode: 'runtime'
|
262
|
+
Ruby version: '#{@ruby_ver}'
|
263
|
+
Runtime file name: '#{package}'
|
264
|
+
Loging level: '#{l_level}'
|
265
|
+
ANN
|
266
|
+
end
|
267
|
+
|
195
268
|
def press_options
|
196
269
|
@press_options ||= "-DPCKG:STRING='#{package}' -DLOG_LEVEL:STRING='#{l_level}' " \
|
197
270
|
end
|
@@ -200,6 +273,10 @@ module Tebako
|
|
200
273
|
Pathname.new(path).relative?
|
201
274
|
end
|
202
275
|
|
276
|
+
def ref
|
277
|
+
@ref ||= @options["ref"].nil? ? "tebako-runtime" : @options["ref"].gsub("\\", "/")
|
278
|
+
end
|
279
|
+
|
203
280
|
def remove_glibc_private
|
204
281
|
@remove_glibc_private ||= if RUBY_PLATFORM.end_with?("linux") || RUBY_PLATFORM.end_with?("linux-gnu")
|
205
282
|
"-DREMOVE_GLIBC_PRIVATE=#{@options["patchelf"] ? "ON" : "OFF"}"
|
@@ -0,0 +1,143 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright (c) 2023-2024 [Ribose Inc](https://www.ribose.com).
|
4
|
+
# All rights reserved.
|
5
|
+
# This file is a part of tebako
|
6
|
+
#
|
7
|
+
# Redistribution and use in source and binary forms, with or without
|
8
|
+
# modification, are permitted provided that the following conditions
|
9
|
+
# are met:
|
10
|
+
# 1. Redistributions of source code must retain the above copyright
|
11
|
+
# notice, this list of conditions and the following disclaimer.
|
12
|
+
# 2. Redistributions in binary form must reproduce the above copyright
|
13
|
+
# notice, this list of conditions and the following disclaimer in the
|
14
|
+
# documentation and/or other materials provided with the distribution.
|
15
|
+
#
|
16
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
17
|
+
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
18
|
+
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
19
|
+
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS
|
20
|
+
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
21
|
+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
22
|
+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
23
|
+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
24
|
+
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
25
|
+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
26
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
27
|
+
|
28
|
+
require "stringio"
|
29
|
+
|
30
|
+
module Tebako
|
31
|
+
# Tebako application package descriptor
|
32
|
+
class PackageDescriptor
|
33
|
+
SIGNATURE = "TAMATEBAKO"
|
34
|
+
|
35
|
+
attr_reader :ruby_version_major, :ruby_version_minor, :ruby_version_patch, :tebako_version_major,
|
36
|
+
:tebako_version_minor, :tebako_version_patch, :mount_point, :entry_point, :cwd
|
37
|
+
|
38
|
+
def initialize(*args)
|
39
|
+
if args.size == 1 && args[0].is_a?(Array)
|
40
|
+
deserialize(args[0])
|
41
|
+
elsif args.size == 5
|
42
|
+
construct_from_params(*args)
|
43
|
+
else
|
44
|
+
raise ArgumentError, "Invalid arguments"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def serialize
|
49
|
+
buffer = StringIO.new
|
50
|
+
|
51
|
+
buffer.write(SIGNATURE)
|
52
|
+
serialize_versions(buffer)
|
53
|
+
|
54
|
+
write_string(buffer, @mount_point)
|
55
|
+
write_string(buffer, @entry_point)
|
56
|
+
|
57
|
+
serialize_cwd(buffer)
|
58
|
+
buffer.string
|
59
|
+
end
|
60
|
+
|
61
|
+
private
|
62
|
+
|
63
|
+
def deserialize(buffer)
|
64
|
+
stream = StringIO.new(buffer.pack("C*"))
|
65
|
+
|
66
|
+
signature = stream.read(SIGNATURE.size)
|
67
|
+
raise ArgumentError, "Invalid or missing signature" if signature != SIGNATURE
|
68
|
+
|
69
|
+
deserialize_versions(stream)
|
70
|
+
@mount_point = read_string(stream)
|
71
|
+
@entry_point = read_string(stream)
|
72
|
+
|
73
|
+
cwd_present = stream.read(1).unpack1("C")
|
74
|
+
@cwd = cwd_present == 1 ? read_string(stream) : nil
|
75
|
+
end
|
76
|
+
|
77
|
+
def construct_from_params(ruby_version, tebako_version, mount_point, entry_point, cwd)
|
78
|
+
parse_version(ruby_version, :@ruby_version_major, :@ruby_version_minor, :@ruby_version_patch)
|
79
|
+
parse_version(tebako_version, :@tebako_version_major, :@tebako_version_minor, :@tebako_version_patch)
|
80
|
+
|
81
|
+
@mount_point = mount_point
|
82
|
+
@entry_point = entry_point
|
83
|
+
@cwd = cwd
|
84
|
+
end
|
85
|
+
|
86
|
+
def deserialize_versions(stream)
|
87
|
+
@ruby_version_major = read_uint16(stream)
|
88
|
+
@ruby_version_minor = read_uint16(stream)
|
89
|
+
@ruby_version_patch = read_uint16(stream)
|
90
|
+
@tebako_version_major = read_uint16(stream)
|
91
|
+
@tebako_version_minor = read_uint16(stream)
|
92
|
+
@tebako_version_patch = read_uint16(stream)
|
93
|
+
end
|
94
|
+
|
95
|
+
def parse_version(version, major_sym, minor_sym, patch_sym)
|
96
|
+
major, minor, patch = version.split(".").map(&:to_i)
|
97
|
+
raise ArgumentError, "Invalid version format" unless major && minor && patch
|
98
|
+
|
99
|
+
instance_variable_set(major_sym, major)
|
100
|
+
instance_variable_set(minor_sym, minor)
|
101
|
+
instance_variable_set(patch_sym, patch)
|
102
|
+
end
|
103
|
+
|
104
|
+
def write_uint16(buffer, value)
|
105
|
+
buffer.write([value].pack("v"))
|
106
|
+
end
|
107
|
+
|
108
|
+
def read_uint16(stream)
|
109
|
+
data = stream.read(2)
|
110
|
+
raise ArgumentError, "Unexpected end of stream" if data.nil?
|
111
|
+
|
112
|
+
data.unpack1("v")
|
113
|
+
end
|
114
|
+
|
115
|
+
def serialize_cwd(buffer)
|
116
|
+
if @cwd
|
117
|
+
buffer.write([1].pack("C"))
|
118
|
+
write_string(buffer, @cwd)
|
119
|
+
else
|
120
|
+
buffer.write([0].pack("C"))
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
def serialize_versions(buffer)
|
125
|
+
write_uint16(buffer, @ruby_version_major)
|
126
|
+
write_uint16(buffer, @ruby_version_minor)
|
127
|
+
write_uint16(buffer, @ruby_version_patch)
|
128
|
+
write_uint16(buffer, @tebako_version_major)
|
129
|
+
write_uint16(buffer, @tebako_version_minor)
|
130
|
+
write_uint16(buffer, @tebako_version_patch)
|
131
|
+
end
|
132
|
+
|
133
|
+
def write_string(buffer, str)
|
134
|
+
write_uint16(buffer, str.size)
|
135
|
+
buffer.write(str)
|
136
|
+
end
|
137
|
+
|
138
|
+
def read_string(stream)
|
139
|
+
size = read_uint16(stream)
|
140
|
+
stream.read(size)
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|