tebako 0.9.3 → 0.10.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.
@@ -0,0 +1,154 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright (c) 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 "pathname"
29
+ require "fileutils"
30
+
31
+ # Tebako - an executable packager
32
+ module Tebako
33
+ # Code geberation
34
+ module Codegen
35
+ COMMON_C_HEADER = <<~SUBST
36
+ /**
37
+ * THIS FILE WAS GENERATED AUTOMATICALLY BY TEBAKO. DO NOT CHANGE IT, PLEASE
38
+ **/
39
+
40
+ SUBST
41
+
42
+ COMMON_RUBY_HEADER = <<~SUBST
43
+ #!/usr/bin/env ruby
44
+ # frozen_string_literal: true
45
+
46
+ # THIS FILE WAS GENERATED AUTOMATICALLY BY TEBAKO. DO NOT CHANGE IT, PLEASE
47
+
48
+ SUBST
49
+
50
+ class << self
51
+ def deploy_crt_implib(opt, scm)
52
+ crt = ""
53
+ if scm.msys?
54
+ crt = <<~SUBST
55
+ Tebako::Packager.create_implib("#{opt.ruby_src_dir}", "#{opt.data_src_dir}",
56
+ "#{File.basename(opt.package)}", rv)
57
+ SUBST
58
+ end
59
+ crt
60
+ end
61
+
62
+ def deploy_cwd(opt)
63
+ opt.cwd.nil? ? "nil" : "\"#{opt.cwd}\""
64
+ end
65
+
66
+ def deploy_rb(opt, scm)
67
+ <<~SUBST
68
+ #{deploy_rq}
69
+
70
+ rv = Tebako::RubyVersion.new("#{opt.ruby_ver}")
71
+ Tebako::Packager::init("#{opt.stash_dir}", "#{opt.data_src_dir}",
72
+ "#{opt.data_pre_dir}", "#{opt.data_bin_dir}")
73
+ #{deploy_crt_implib(opt, scm)}
74
+ Tebako::Packager.deploy("#{opt.data_src_dir}", "#{opt.data_pre_dir}",
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}")
79
+ SUBST
80
+ end
81
+
82
+ def deploy_rq
83
+ <<~SUBST
84
+ require "#{File.join(__dir__, "packager.rb")}"
85
+ require "#{File.join(__dir__, "ruby_version.rb")}"
86
+ SUBST
87
+ end
88
+
89
+ def generate_deploy_rb(options_manager, scenario_manager)
90
+ fname = File.join(options_manager.deps, "bin", "deploy.rb")
91
+ FileUtils.mkdir_p(File.dirname(fname))
92
+
93
+ File.open(fname, "w") do |file|
94
+ file.write(COMMON_RUBY_HEADER)
95
+ file.write(deploy_rb(options_manager, scenario_manager))
96
+ end
97
+ end
98
+
99
+ def generate_tebako_fs_cpp(options_manager, scenario_manager)
100
+ fname = File.join(options_manager.deps, "src", "tebako", "tebako-fs.cpp")
101
+ FileUtils.mkdir_p(File.dirname(fname))
102
+
103
+ File.open(fname, "w") do |file|
104
+ file.write(COMMON_C_HEADER)
105
+ file.write(tebako_fs_cpp(options_manager, scenario_manager))
106
+ end
107
+ end
108
+
109
+ def generate_tebako_version_h(options_manager, v_parts)
110
+ fname = File.join(options_manager.deps, "include", "tebako", "tebako-version.h")
111
+ FileUtils.mkdir_p(File.dirname(fname))
112
+
113
+ File.open(fname, "w") do |file|
114
+ file.write(COMMON_C_HEADER)
115
+ file.write(tebako_version_h(v_parts))
116
+ end
117
+ end
118
+
119
+ def package_cwd(options_manager, scenario_manager)
120
+ if options_manager.cwd.nil?
121
+ "nullptr"
122
+ else
123
+ "\"#{scenario_manager.fs_mount_point}/#{options_manager.cwd}\""
124
+ end
125
+ end
126
+
127
+ def tebako_fs_cpp(options_manager, scenario_manager)
128
+ <<~SUBST
129
+ #include <incbin/incbin.h>
130
+
131
+ namespace tebako {
132
+ const char * fs_log_level = "#{options_manager.l_level}";
133
+ const char * fs_mount_point = "#{scenario_manager.fs_mount_point}";
134
+ const char * fs_entry_point = "#{scenario_manager.fs_entry_point}";
135
+ const char * package_cwd = #{package_cwd(options_manager, scenario_manager)};
136
+ char original_cwd[PATH_MAX];
137
+
138
+ INCBIN(fs, "#{options_manager.output_folder}/p/fs.bin");
139
+ }
140
+ SUBST
141
+ end
142
+
143
+ def tebako_version_h(v_parts)
144
+ <<~SUBST
145
+ #pragma once
146
+
147
+ const unsigned int tebako_version_major = #{v_parts[0]};
148
+ const unsigned int tebako_version_minor = #{v_parts[1]};
149
+ const unsigned int tebako_version_teeny = #{v_parts[2]};
150
+ SUBST
151
+ end
152
+ end
153
+ end
154
+ end
@@ -31,6 +31,7 @@ require "find"
31
31
  require_relative "error"
32
32
  require_relative "build_helpers"
33
33
  require_relative "packager/patch_helpers"
34
+ require_relative "scenario_manager"
34
35
 
35
36
  # Tebako - an executable packager
36
37
  module Tebako
@@ -41,11 +42,11 @@ module Tebako
41
42
  RUBYGEMS_VERSION = "3.4.22"
42
43
 
43
44
  # Tebako packaging support (deployer)
44
- class DeployHelper # rubocop:disable Metrics/ClassLength
45
- def initialize(fs_root, fs_entrance, fs_mount_point, target_dir, pre_dir)
45
+ class DeployHelper < ScenarioManager # rubocop:disable Metrics/ClassLength
46
+ def initialize(fs_root, fs_entrance, target_dir, pre_dir)
47
+ super(fs_root, fs_entrance)
46
48
  @fs_root = fs_root
47
49
  @fs_entrance = fs_entrance
48
- @fs_mount_point = fs_mount_point
49
50
  @target_dir = target_dir
50
51
  @pre_dir = pre_dir
51
52
  @verbose = ENV["VERBOSE"] == "yes" || ENV["VERBOSE"] == "true"
@@ -54,16 +55,14 @@ module Tebako
54
55
 
55
56
  attr_reader :bundler_command, :gem_command, :gem_home
56
57
 
57
- def config(os_type, ruby_ver, cwd)
58
+ def configure(ruby_ver, cwd)
58
59
  @ruby_ver = ruby_ver
59
- @os_type = os_type
60
60
  @cwd = cwd
61
61
 
62
62
  @tbd = File.join(@target_dir, "bin")
63
63
  @tgd = @gem_home = File.join(@target_dir, "lib", "ruby", "gems", @ruby_ver.api_version)
64
64
  @tld = File.join(@target_dir, "local")
65
65
 
66
- lookup_files
67
66
  configure_scenario
68
67
  configure_commands
69
68
  end
@@ -171,7 +170,7 @@ module Tebako
171
170
  end
172
171
 
173
172
  def configure_commands
174
- if @os_type =~ /msys/
173
+ if msys?
175
174
  configure_commands_msys
176
175
  else
177
176
  configure_commands_not_msys
@@ -195,27 +194,6 @@ module Tebako
195
194
  @nokogiri_option = "--no-use-system-libraries"
196
195
  end
197
196
 
198
- def configure_scenario
199
- case @gs_length
200
- when 0
201
- configure_scenario_no_gemspec
202
- when 1
203
- @scenario = @gf_length.positive? ? :gemspec_and_gemfile : :gemspec
204
- else
205
- raise Tebako::Error, "Multiple Ruby gemspecs found in #{@fs_root}"
206
- end
207
- end
208
-
209
- def configure_scenario_no_gemspec
210
- @scenario = if @gf_length.positive?
211
- :gemfile
212
- elsif @g_length.positive?
213
- :gem
214
- else
215
- :simple_script
216
- end
217
- end
218
-
219
197
  def copy_files(dest)
220
198
  FileUtils.mkdir_p(dest)
221
199
  if Dir.exist?(@fs_root) && File.readable?(@fs_root)
@@ -277,12 +255,6 @@ module Tebako
277
255
  gem_files.each { |gem_file| install_gem(gem_file) }
278
256
  end
279
257
 
280
- def lookup_files
281
- @gs_length = Dir.glob(File.join(@fs_root, "*.gemspec")).length
282
- @gf_length = Dir.glob(File.join(@fs_root, "Gemfile")).length
283
- @g_length = Dir.glob(File.join(@fs_root, "*.gem")).length
284
- end
285
-
286
258
  def patch_after_rubygems_update(target_dir, ruby_api_ver)
287
259
  # Autoload cannot handle statically linked openssl extension
288
260
  # Changing it to require seems to be the simplest solution
data/lib/tebako/error.rb CHANGED
@@ -35,7 +35,14 @@ module Tebako
35
35
  105 => "Failed to map MSys path to Windows",
36
36
  106 => "Entry point does not exist or is not accessible",
37
37
  107 => "Project root does not exist or is not accessible",
38
- 108 => "Package working directory does not exist"
38
+ 108 => "Package working directory does not exist",
39
+ 109 => "Invalid Ruby version format",
40
+ 110 => "Ruby version is not supported",
41
+ 111 => "Ruby version is not supported on Windows",
42
+ 112 => "OS is not supported",
43
+ 113 => "Path to root shall be absolute. Relative path is not allowed",
44
+ 114 => "Entry point is not within the project root",
45
+ 201 => "Warning. Could not create cache version file"
39
46
  }.freeze
40
47
 
41
48
  class << self
@@ -0,0 +1,237 @@
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 "etc"
29
+ require "fileutils"
30
+ require "pathname"
31
+ require "rbconfig"
32
+
33
+ require_relative "codegen"
34
+ require_relative "error"
35
+ require_relative "ruby_version"
36
+ require_relative "version"
37
+
38
+ # Tebako - an executable packager
39
+ # Command-line interface methods
40
+ module Tebako
41
+ # Cli helpers
42
+ class OptionsManager # rubocop:disable Metrics/ClassLength
43
+ def initialize(options)
44
+ @options = options
45
+ @rv = Tebako::RubyVersion.new(@options["Ruby"])
46
+ @ruby_ver, @ruby_hash = @rv.extend_ruby_version
47
+ end
48
+
49
+ attr_reader :ruby_ver, :rv
50
+
51
+ def b_env
52
+ u_flags = if RbConfig::CONFIG["host_os"] =~ /darwin/
53
+ "-DTARGET_OS_SIMULATOR=0 -DTARGET_OS_IPHONE=0 #{ENV.fetch("CXXFLAGS", nil)}"
54
+ else
55
+ ENV.fetch("CXXFLAGS", nil)
56
+ end
57
+ @b_env ||= { "CXXFLAGS" => u_flags }
58
+ end
59
+
60
+ def cfg_options
61
+ ## {v_parts[3]} may be something like rc1 that won't work with CMake
62
+ v_parts = Tebako::VERSION.split(".")
63
+ # Cannot use 'xxx' as parameters because it does not work in Windows shells
64
+ # So we have to use \"xxx\"
65
+ @cfg_options ||=
66
+ "-DCMAKE_BUILD_TYPE=Release -DRUBY_VER:STRING=\"#{@ruby_ver}\" -DRUBY_HASH:STRING=\"#{@ruby_hash}\" " \
67
+ "-DDEPS:STRING=\"#{deps}\" -G \"#{m_files}\" -B \"#{output_folder}\" -S \"#{source}\" " \
68
+ "#{remove_glibc_private} -DTEBAKO_VERSION:STRING=\"#{v_parts[0]}.#{v_parts[1]}.#{v_parts[2]}\""
69
+ end
70
+
71
+ def cwd
72
+ f_cwd = @options["cwd"]&.gsub("\\", "/")
73
+ @cwd ||= f_cwd
74
+ end
75
+
76
+ # DATA_BIN_DIR folder is used to create packaged filesystem
77
+ # set(DATA_BIN_DIR ${CMAKE_CURRENT_BINARY_DIR}/p)
78
+ def data_bin_dir
79
+ @data_bin_dir ||= File.join(output_folder, "p")
80
+ end
81
+
82
+ # DATA_BIN_FILE is packaged filesystem itself
83
+ # set(DATA_BIN_FILE ${DATA_BIN_DIR}/fs.bin)
84
+ def data_bin_file
85
+ @data_bin_file ||= File.join(data_bin_dir, "fs.bin")
86
+ end
87
+
88
+ # DATA_PRE_DIR folder is used to build gems that need to be packaged
89
+ # set(DATA_PRE_DIR ${CMAKE_CURRENT_BINARY_DIR}/r)
90
+ def data_pre_dir
91
+ @data_pre_dir ||= File.join(output_folder, "r")
92
+ end
93
+
94
+ # DATA_SRC_DIR folder is used to collect all files that need to be packaged
95
+ # set(DATA_SRC_DIR ${CMAKE_CURRENT_BINARY_DIR}/s)
96
+ def data_src_dir
97
+ @data_src_dir ||= File.join(output_folder, "s")
98
+ end
99
+
100
+ def deps
101
+ @deps ||= File.join(prefix, "deps")
102
+ end
103
+
104
+ def deps_bin_dir
105
+ @deps_bin_dir ||= File.join(deps, "bin")
106
+ end
107
+
108
+ def fs_current
109
+ fs_current = Dir.pwd
110
+ if RUBY_PLATFORM =~ /msys|mingw|cygwin/
111
+ fs_current, cygpath_res = Open3.capture2e("cygpath", "-w", fs_current)
112
+ Tebako.packaging_error(101) unless cygpath_res.success?
113
+ fs_current.strip!
114
+ end
115
+ @fs_current ||= fs_current&.gsub("\\", "/")
116
+ end
117
+
118
+ def fs_entrance
119
+ @fs_entrance ||= @options["entry-point"]&.gsub("\\", "/")
120
+ end
121
+
122
+ def handle_nil_prefix
123
+ env_prefix = ENV.fetch("TEBAKO_PREFIX", nil)
124
+ if env_prefix.nil?
125
+ puts "No prefix specified, using ~/.tebako"
126
+ File.expand_path("~/.tebako")
127
+ else
128
+ puts "Using TEBAKO_PREFIX environment variable as prefix"
129
+ File.expand_path(env_prefix.gsub("\\", "/"))
130
+ end
131
+ end
132
+
133
+ def l_level
134
+ @l_level ||= if @options["log-level"].nil?
135
+ "error"
136
+ else
137
+ @options["log-level"]
138
+ end
139
+ end
140
+
141
+ def m_files
142
+ # [TODO]
143
+ # Ninja generates incorrect script for tebako press target -- gets lost in a chain custom targets
144
+ # Using makefiles has negative performance impact so it needs to be fixed
145
+ @m_files ||= case RUBY_PLATFORM
146
+ when /linux/, /darwin/
147
+ "Unix Makefiles"
148
+ when /msys|mingw|cygwin/
149
+ "MinGW Makefiles"
150
+ else
151
+ raise Tebako::Error.new("#{RUBY_PLATFORM} is not supported.", 112)
152
+ end
153
+ end
154
+
155
+ def output_folder
156
+ @output_folder ||= File.join(prefix, "o")
157
+ end
158
+
159
+ def package
160
+ package = if @options["output"].nil?
161
+ File.join(Dir.pwd, File.basename(fs_entrance, ".*"))
162
+ else
163
+ @options["output"]&.gsub("\\", "/")
164
+ end
165
+ @package ||= if relative?(package)
166
+ File.join(fs_current, package)
167
+ else
168
+ package
169
+ end
170
+ end
171
+
172
+ def prefix
173
+ @prefix ||= if @options["prefix"].nil?
174
+ handle_nil_prefix
175
+ elsif @options["prefix"] == "PWD"
176
+ Dir.pwd
177
+ else
178
+ File.expand_path(@options["prefix"]&.gsub("\\", "/"))
179
+ end
180
+ end
181
+
182
+ def press_announce
183
+ cwd_announce = cwd.nil? ? "<Host current directory>" : cwd
184
+ @press_announce ||= <<~ANN
185
+ Running tebako press at #{prefix}
186
+ Ruby version: '#{@ruby_ver}'
187
+ Project root: '#{root}'
188
+ Application entry point: '#{fs_entrance}'
189
+ Package file name: '#{package}'
190
+ Loging level: '#{l_level}'
191
+ Package working directory: '#{cwd_announce}'
192
+ ANN
193
+ end
194
+
195
+ def press_options
196
+ @press_options ||= "-DPCKG:STRING='#{package}' -DLOG_LEVEL:STRING='#{l_level}' " \
197
+ end
198
+
199
+ def relative?(path)
200
+ Pathname.new(path).relative?
201
+ end
202
+
203
+ def remove_glibc_private
204
+ @remove_glibc_private ||= if RUBY_PLATFORM.end_with?("linux") || RUBY_PLATFORM.end_with?("linux-gnu")
205
+ "-DREMOVE_GLIBC_PRIVATE=#{@options["patchelf"] ? "ON" : "OFF"}"
206
+ else
207
+ ""
208
+ end
209
+ end
210
+
211
+ def root
212
+ f_root = @options["root"].nil? ? "" : @options["root"].gsub("\\", "/")
213
+ @root ||= if relative?(f_root)
214
+ File.join(fs_current, f_root)
215
+ else
216
+ File.join(f_root, "")
217
+ end
218
+ end
219
+
220
+ def ruby_src_dir
221
+ @ruby_src_dir ||= File.join(deps, "src", "_ruby_#{@ruby_ver}")
222
+ end
223
+
224
+ def source
225
+ c_path = Pathname.new(__FILE__).realpath
226
+ @source ||= File.expand_path("../../..", c_path)
227
+ end
228
+
229
+ def stash_dir
230
+ @stash_dir ||= "#{stash_dir_all}_#{@ruby_ver}"
231
+ end
232
+
233
+ def stash_dir_all
234
+ @stash_dir_all ||= File.join(deps, "stash")
235
+ end
236
+ end
237
+ end
@@ -69,19 +69,19 @@ module Tebako
69
69
  def create_implib(src_dir, package_src_dir, app_name, ruby_ver)
70
70
  create_def(src_dir, app_name)
71
71
  puts " ... creating Windows import library"
72
- params = ["dlltool", "-d", def_fname(src_dir, app_name), "-D", out_fname(app_name),
73
- "--output-lib", lib_fname(package_src_dir, ruby_ver)]
72
+ params = ["dlltool", "-d", def_fname(src_dir, app_name), "-D", out_fname(app_name), "--output-lib",
73
+ lib_fname(package_src_dir, ruby_ver)]
74
74
  BuildHelpers.run_with_capture(params)
75
75
  end
76
76
 
77
77
  # Deploy
78
- def deploy(os_type, target_dir, pre_dir, ruby_ver, fs_root, fs_entrance, fs_mount_point, cwd) # rubocop:disable Metrics/ParameterLists
78
+ def deploy(target_dir, pre_dir, ruby_ver, fs_root, fs_entrance, cwd) # rubocop:disable Metrics/ParameterLists
79
79
  puts "-- Running deploy script"
80
80
 
81
- deploy_helper = Tebako::DeployHelper.new(fs_root, fs_entrance, fs_mount_point, target_dir, pre_dir)
82
- deploy_helper.config(os_type, ruby_ver, cwd)
81
+ deploy_helper = Tebako::DeployHelper.new(fs_root, fs_entrance, target_dir, pre_dir)
82
+ deploy_helper.configure(ruby_ver, cwd)
83
83
  deploy_helper.deploy
84
- Tebako::Stripper.strip(os_type, target_dir)
84
+ Tebako::Stripper.strip(deploy_helper, target_dir)
85
85
  end
86
86
 
87
87
  def finalize(os_type, src_dir, app_name, ruby_ver, patchelf)
@@ -106,6 +106,12 @@ module Tebako
106
106
  FileUtils.cp_r "#{stash_dir}/.", src_dir
107
107
  end
108
108
 
109
+ def mkdwarfs(deps_bin_dir, data_bin_file, data_src_dir)
110
+ puts "-- Running mkdwarfs script"
111
+ params = [File.join(deps_bin_dir, "mkdwarfs"), "-o", data_bin_file, "-i", data_src_dir, "--no-progress"]
112
+ BuildHelpers.run_with_capture_v(params)
113
+ end
114
+
109
115
  # Pass1
110
116
  # Executed before Ruby build, patching ensures that Ruby itself is linked statically
111
117
  def pass1(ostype, ruby_source_dir, mount_point, src_dir, ruby_ver)
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Copyright (c) 2024 [Ribose Inc](https://www.ribose.com).
3
+ # Copyright (c) 2023-2024 [Ribose Inc](https://www.ribose.com).
4
4
  # All rights reserved.
5
5
  # This file is a part of tebako
6
6
  #
@@ -25,18 +25,12 @@
25
25
  # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26
26
  # POSSIBILITY OF SUCH DAMAGE.
27
27
 
28
- require "fileutils"
29
- require "pathname"
30
- require "rbconfig"
31
-
32
28
  require_relative "error"
33
- require_relative "version"
34
29
 
35
30
  # Tebako - an executable packager
36
- # Command-line interface methods
37
31
  module Tebako
38
- # Ruby version helpers
39
- module CliRubies
32
+ # Ruby version checks
33
+ class RubyVersion
40
34
  RUBY_VERSIONS = {
41
35
  "2.7.8" => "c2dab63cbc8f2a05526108ad419efa63a67ed4074dbbcf9fc2b1ca664cb45ba0",
42
36
  "3.0.7" => "2a3411977f2850431136b0fab8ad53af09fb74df2ee2f4fb7f11b378fe034388",
@@ -51,29 +45,69 @@ module Tebako
51
45
  MIN_RUBY_VERSION_WINDOWS = "3.1.6"
52
46
  DEFAULT_RUBY_VERSION = "3.2.5"
53
47
 
54
- def version_check(version)
55
- return if RUBY_VERSIONS.key?(version)
48
+ # rub_ver version = options["Ruby"].nil? ? DEFAULT_RUBY_VERSION : options["Ruby"]
49
+ def initialize(ruby_version)
50
+ @ruby_version = ruby_version.nil? ? DEFAULT_RUBY_VERSION : ruby_version
51
+
52
+ version_check_format
53
+ version_check
54
+ version_check_msys
55
+ end
56
+
57
+ attr_reader :ruby_version
58
+
59
+ def ruby3x?
60
+ @ruby3x ||= @ruby_version[0] == "3"
61
+ end
62
+
63
+ def ruby31?
64
+ @ruby31 ||= ruby3x? && @ruby_version[2].to_i >= 1
65
+ end
66
+
67
+ def ruby32?
68
+ @ruby32 ||= ruby3x? && @ruby_version[2].to_i >= 2
69
+ end
70
+
71
+ def ruby32only?
72
+ @ruby32only ||= ruby3x? && @ruby_version[2] == "2"
73
+ end
74
+
75
+ def ruby33?
76
+ @ruby33 ||= ruby3x? && @ruby_version[2].to_i >= 3
77
+ end
78
+
79
+ def api_version
80
+ @api_version ||= "#{@ruby_version.split(".")[0..1].join(".")}.0"
81
+ end
82
+
83
+ def lib_version
84
+ @lib_version ||= "#{@ruby_version.split(".")[0..1].join}0"
85
+ end
86
+
87
+ def version_check
88
+ return if RUBY_VERSIONS.key?(@ruby_version)
56
89
 
57
90
  raise Tebako::Error.new(
58
- "Ruby version #{version} is not supported, exiting",
59
- 253
91
+ "Ruby version #{@ruby_version} is not supported",
92
+ 110
60
93
  )
61
94
  end
62
95
 
63
- def version_check_msys(version)
64
- if Gem::Version.new(version) < Gem::Version.new(MIN_RUBY_VERSION_WINDOWS) && RUBY_PLATFORM =~ /msys|mingw|cygwin/
65
- raise Tebako::Error.new(
66
- "Windows packaging works for Ruby #{MIN_RUBY_VERSION_WINDOWS} or above, version #{version} is not supported",
67
- 252
68
- )
96
+ def version_check_format
97
+ return if @ruby_version =~ /^\d+\.\d+\.\d+$/
98
+
99
+ raise Tebako::Error.new("Invalid Ruby version format '#{@ruby_version}'. Expected format: x.y.z", 109)
100
+ end
101
+
102
+ def version_check_msys
103
+ if Gem::Version.new(@ruby_version) < Gem::Version.new(MIN_RUBY_VERSION_WINDOWS) &&
104
+ RUBY_PLATFORM =~ /msys|mingw|cygwin/
105
+ raise Tebako::Error.new("Ruby version #{@ruby_version} is not supported on Windows", 111)
69
106
  end
70
107
  end
71
108
 
72
109
  def extend_ruby_version
73
- version = options["Ruby"].nil? ? DEFAULT_RUBY_VERSION : options["Ruby"]
74
- version_check(version)
75
- version_check_msys(version)
76
- @extend_ruby_version ||= [version, RUBY_VERSIONS[version]]
110
+ @extend_ruby_version ||= [@ruby_version, RUBY_VERSIONS[@ruby_version]]
77
111
  end
78
112
  end
79
113
  end