tebako 0.9.3 → 0.10.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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