From a291f9662370b9762f38e8854e43518413970210 Mon Sep 17 00:00:00 2001 From: "Maxim [maxirmx] Samsonov" Date: Wed, 15 Jan 2025 19:40:12 +0300 Subject: [PATCH 1/2] fix: extend FILES_TO_RESTORE; restore all files before pass1 (potential fix for https://github.com/tamatebako/tebako-ci-containers/issues/39) --- .gitignore | 3 +- lib/tebako/packager.rb | 44 +++---- lib/tebako/packager/patch_helpers.rb | 12 +- lib/tebako/version.rb | 2 +- spec/packager/patch_helpers_spec.rb | 178 +++++++++++++++++++++++++++ spec/packager_spec.rb | 22 +--- tests/scripts/functional-tests.sh | 1 + tests/test-01/tebako-test-run.rb | 1 + tests/test-09/tebako-test-0.0.2.gem | Bin 5120 -> 0 bytes 9 files changed, 214 insertions(+), 49 deletions(-) create mode 100644 spec/packager/patch_helpers_spec.rb delete mode 100644 tests/test-09/tebako-test-0.0.2.gem diff --git a/.gitignore b/.gitignore index df358dbc..a34f7dc2 100644 --- a/.gitignore +++ b/.gitignore @@ -56,8 +56,7 @@ tests/shunit2 tests-2/Gemfile.lock *-package metanorma-package -tests/test-11/tebako-test-0.0.1.gem -tests/test-15/tebako-bundle-test-0.0.1.gem +tests/**/*.gem packed-mn .package-ready extract/ diff --git a/lib/tebako/packager.rb b/lib/tebako/packager.rb index 2d2d5d64..2a6b5cb0 100644 --- a/lib/tebako/packager.rb +++ b/lib/tebako/packager.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -# Copyright (c) 2021-2024 [Ribose Inc](https://www.ribose.com). +# Copyright (c) 2021-2025 [Ribose Inc](https://www.ribose.com). # All rights reserved. # This file is a part of tebako # @@ -43,25 +43,29 @@ module Tebako # Tebako packaging support (internal) module Packager FILES_TO_RESTORE = %w[ - main.c + common.mk + configure + config.status dir.c dln.c file.c - io.c - tool/mkconfig.rb gem_prelude.rb - ].freeze - - FILES_TO_RESTORE_MSYS = %w[ + io.c + main.c + Makefile ruby.c - win32/file.c - ].freeze - # Do not need to restore cygwin/GNUmakefile.in - # because it is patched (differently) both on pass 1 and pass2 - # cygwin/GNUmakefile.in - - FILES_TO_RESTORE_MUSL = %w[ thread_pthread.c + util.c + ext/bigdecimal/bigdecimal.h + ext/Setup + cygwin/GNUmakefile.in + include/ruby/onigmo.h + lib/rubygems/openssl.rb + lib/rubygems/path_support.rb + template/Makefile.in + tool/mkconfig.rb + win32/winmain.c + win32/file.c ].freeze class << self @@ -118,16 +122,14 @@ def mkdwarfs(deps_bin_dir, data_bin_file, data_src_dir, descriptor = nil) # Executed before Ruby build, patching ensures that Ruby itself is linked statically def pass1(ostype, ruby_source_dir, mount_point, src_dir, ruby_ver) puts "-- Running pass1 script" - PatchHelpers.recreate(src_dir) - patch = crt_pass1_patch(ostype, mount_point, ruby_ver) - do_patch(patch.patch_map, ruby_source_dir) - # Roll back pass1a, pass2 patches + # Roll all known patches # Just in case we are recovering after some error - PatchHelpers.restore_and_save_files(FILES_TO_RESTORE, ruby_source_dir) - PatchHelpers.restore_and_save_files(FILES_TO_RESTORE_MUSL, ruby_source_dir) if ostype =~ /linux-musl/ - PatchHelpers.restore_and_save_files(FILES_TO_RESTORE_MSYS, ruby_source_dir) if ostype =~ /msys/ + PatchHelpers.restore_and_save_files(FILES_TO_RESTORE, ruby_source_dir, strict: false) + + patch = crt_pass1_patch(ostype, mount_point, ruby_ver) + do_patch(patch.patch_map, ruby_source_dir) end # Pass1A diff --git a/lib/tebako/packager/patch_helpers.rb b/lib/tebako/packager/patch_helpers.rb index f9cb12f2..081ecf79 100755 --- a/lib/tebako/packager/patch_helpers.rb +++ b/lib/tebako/packager/patch_helpers.rb @@ -91,8 +91,12 @@ def recreate(dirname) FileUtils.mkdir(dirname) end - def restore_and_save(fname) - raise Tebako::Error, "Could not save #{fname} because it does not exist." unless File.exist?(fname) + def restore_and_save(fname, strict: true) + unless File.exist?(fname) + return unless strict + + raise Tebako::Error, "Could not save #{fname} because it does not exist." + end old_fname = "#{fname}.old" if File.exist?(old_fname) @@ -102,9 +106,9 @@ def restore_and_save(fname) FileUtils.cp(fname, old_fname) end - def restore_and_save_files(files, ruby_source_dir) + def restore_and_save_files(files, ruby_source_dir, strict: true) files.each do |fname| - restore_and_save "#{ruby_source_dir}/#{fname}" + restore_and_save("#{ruby_source_dir}/#{fname}", strict: strict) end end diff --git a/lib/tebako/version.rb b/lib/tebako/version.rb index 130ada0c..fc1aaba1 100644 --- a/lib/tebako/version.rb +++ b/lib/tebako/version.rb @@ -26,5 +26,5 @@ # POSSIBILITY OF SUCH DAMAGE. module Tebako - VERSION = "0.12.1" + VERSION = "0.12.2.rc1" end diff --git a/spec/packager/patch_helpers_spec.rb b/spec/packager/patch_helpers_spec.rb new file mode 100644 index 00000000..c5319da4 --- /dev/null +++ b/spec/packager/patch_helpers_spec.rb @@ -0,0 +1,178 @@ +# frozen_string_literal: true + +# Copyright (c) 2025 [Ribose Inc](https://www.ribose.com). +# All rights reserved. +# This file is a part of tebako +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. + +require "fileutils" +require_relative "../../lib/tebako/packager/patch_helpers" + +RSpec.describe Tebako::Packager::PatchHelpers do # rubocop:disable Metrics/BlockLength + let(:temp_dir) { File.join(Dir.tmpdir, "tebako_patch_helpers_test") } + + before do + FileUtils.mkdir_p(temp_dir) + end + + after do + FileUtils.rm_rf(temp_dir) + end + + describe "#patch_file" do + let(:temp_dir) { Dir.mktmpdir } + let(:temp_file) { File.join(temp_dir, "sample.txt") } + + after do + FileUtils.remove_entry_secure(temp_dir) + end + + context "when the file does not exist" do + it "raises an error" do + expect do + Tebako::Packager::PatchHelpers.patch_file(File.join(temp_dir, "missing.txt"), { /old/ => "new" }) + end.to raise_error(Tebako::Error, /Could not patch/) + end + end + + context "when the file exists" do + before do + File.write(temp_file, "old content") + end + + it "patches the file content" do + expect do + Tebako::Packager::PatchHelpers.patch_file(temp_file, { /old/ => "new" }) + end.not_to raise_error + expect(File.read(temp_file)).to eq("new content") + end + end + end + + describe "#get_prefix_macos" do + it "returns brew prefix when brew command succeeds" do + allow(Open3).to receive(:capture2).with("brew --prefix mypackage") + .and_return(["/usr/local/Cellar/mypackage", double(exitstatus: 0)]) + + expect(Tebako::Packager::PatchHelpers.get_prefix_macos("mypackage")).to eq("/usr/local/Cellar/mypackage") + end + + it "raises an error if brew command fails" do + allow(Open3).to receive(:capture2).with("brew --prefix mypackage") + .and_return(["", double(exitstatus: 1)]) + + expect do + Tebako::Packager::PatchHelpers.get_prefix_macos("mypackage") + end.to raise_error(Tebako::Error, /brew --prefix mypackage failed/) + end + end + + describe "#get_prefix_linux" do + it "returns pkg-config libdir when pkg-config command succeeds" do + allow(Open3).to receive(:capture2).with("pkg-config --variable=libdir mypackage") + .and_return(["/usr/lib/mypackage", double(exitstatus: 0)]) + + expect(Tebako::Packager::PatchHelpers.get_prefix_linux("mypackage")).to eq("/usr/lib/mypackage") + end + + it "raises an error if pkg-config command fails" do + allow(Open3).to receive(:capture2).with("pkg-config --variable=libdir mypackage") + .and_return(["", double(exitstatus: 1)]) + + expect do + Tebako::Packager::PatchHelpers.get_prefix_linux("mypackage") + end.to raise_error(Tebako::Error, /pkg-config --variable=libdir mypackage failed/) + end + end + + describe "#exe_suffix" do + it "returns '.exe' for msys-based platforms" do + expect(Tebako::Packager::PatchHelpers.exe_suffix("msys2")).to eq(".exe") + expect(Tebako::Packager::PatchHelpers.exe_suffix("mingw32")).to eq(".exe") + expect(Tebako::Packager::PatchHelpers.exe_suffix("cygwin")).to eq(".exe") + end + + it "returns an empty string for non-msys platforms" do + expect(Tebako::Packager::PatchHelpers.exe_suffix("darwin")).to eq("") + expect(Tebako::Packager::PatchHelpers.exe_suffix("linux")).to eq("") + end + end + + describe "#restore_and_save_files" do # rubocop:disable Metrics/BlockLength + let(:ruby_source_dir) { File.join(temp_dir, "ruby_source") } + let(:test_files) { ["test1.rb", "test2.rb"] } + + before do + FileUtils.mkdir_p(ruby_source_dir) + test_files.each do |f| + File.write(File.join(ruby_source_dir, f), "original content") + File.write(File.join(ruby_source_dir, "#{f}.old"), "backup content") + end + end + + it "restores files from backups and saves existing ones" do + expect do + Tebako::Packager::PatchHelpers.restore_and_save_files(test_files, ruby_source_dir) + end.not_to raise_error + + test_files.each do |f| + target = File.join(ruby_source_dir, f) + old_file = File.join(ruby_source_dir, "#{f}.old") + expect(File.read(target)).to eq("backup content") + expect(File.read(old_file)).to eq("backup content") + end + end + + it "raises an error in strict mode if afile is missing" do + FileUtils.rm(File.join(ruby_source_dir, "test1.rb")) + expect do + Tebako::Packager::PatchHelpers.restore_and_save_files(test_files, ruby_source_dir, strict: true) + end.to raise_error(Tebako::Error) + end + + it "does not raise an error in non-strict mode if a file is missing" do + FileUtils.rm(File.join(ruby_source_dir, "test1.rb")) + expect do + Tebako::Packager::PatchHelpers.restore_and_save_files(test_files, ruby_source_dir, strict: false) + end.not_to raise_error + end + end + + describe "#yaml_reference" do + let(:ruby_version_double) { double("RubyVersion") } + + context "when Ruby 3.2" do + it "returns '-l:libyaml.a'" do + allow(ruby_version_double).to receive(:ruby32?).and_return(true) + expect(Tebako::Packager::PatchHelpers.yaml_reference(ruby_version_double)).to eq("-l:libyaml.a") + end + end + + context "otherwise" do + it "returns an empty string" do + allow(ruby_version_double).to receive(:ruby32?).and_return(false) + expect(Tebako::Packager::PatchHelpers.yaml_reference(ruby_version_double)).to eq("") + end + end + end +end diff --git a/spec/packager_spec.rb b/spec/packager_spec.rb index 0b148e42..5a87a2fb 100644 --- a/spec/packager_spec.rb +++ b/spec/packager_spec.rb @@ -214,29 +214,9 @@ it "restores and saves files for FILES_TO_RESTORE" do expect(Tebako::Packager::PatchHelpers).to receive(:restore_and_save_files) - .with(Tebako::Packager::FILES_TO_RESTORE, ruby_source_dir) + .with(Tebako::Packager::FILES_TO_RESTORE, ruby_source_dir, strict: false) described_class.pass1(ostype, ruby_source_dir, mount_point, src_dir, ruby_ver) end - - context "when ostype is linux-musl" do - let(:ostype) { "linux-musl" } - - it "restores and saves files for FILES_TO_RESTORE_MUSL" do - expect(Tebako::Packager::PatchHelpers).to receive(:restore_and_save_files) - .with(Tebako::Packager::FILES_TO_RESTORE_MUSL, ruby_source_dir) - described_class.pass1(ostype, ruby_source_dir, mount_point, src_dir, ruby_ver) - end - end - - context "when ostype is msys" do - let(:ostype) { "msys" } - - it "restores and saves files for FILES_TO_RESTORE_MSYS" do - expect(Tebako::Packager::PatchHelpers).to receive(:restore_and_save_files) - .with(Tebako::Packager::FILES_TO_RESTORE_MSYS, ruby_source_dir) - described_class.pass1(ostype, ruby_source_dir, mount_point, src_dir, ruby_ver) - end - end end describe "#pass1a" do diff --git a/tests/scripts/functional-tests.sh b/tests/scripts/functional-tests.sh index cea9daf1..a59d5e87 100755 --- a/tests/scripts/functional-tests.sh +++ b/tests/scripts/functional-tests.sh @@ -253,6 +253,7 @@ test_tebako_press_09() { # Use test-11 gemspec to build a test gem pushd "${DIR_TESTS}/test-11" > /dev/null || fail "pushd ${DIR_TESTS}/test-11 failed" + mkdir -p "${DIR_TESTS}/test-09" gem build tebako-test.gemspec -o "${DIR_TESTS}/test-09/tebako-test-0.0.2.gem" popd > /dev/null || fail "popd failed" diff --git a/tests/test-01/tebako-test-run.rb b/tests/test-01/tebako-test-run.rb index c2b5051d..d79a06b5 100755 --- a/tests/test-01/tebako-test-run.rb +++ b/tests/test-01/tebako-test-run.rb @@ -3,6 +3,7 @@ puts "Hello! This is test-01 talking from inside DwarFS" puts "Gem path: #{Gem.path}" + puts "Rubygems version: #{Gem.rubygems_version}" if defined?(TebakoRuntime::VERSION) puts "Using tebako-runtime v#{TebakoRuntime::VERSION}" diff --git a/tests/test-09/tebako-test-0.0.2.gem b/tests/test-09/tebako-test-0.0.2.gem deleted file mode 100644 index c4d25c52e65ce42f50b75069329a2e12297cdc9a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5120 zcmc~zElEsCEJ@T$uVSDTFaQD*6B7my4Fu@4p@ESRgQ1DJiGh*1si}!6gMp#3iHRA5 zf&r}@glukUaY8f@({lvJcp)zuyWUojBa z`#XHb-Y+TnX1T2?om?s^?_3KQ7M>_fGhen*_6_GNu7mmMZ{DcKhR#vwobsd6=JTI> zN1QnRDfzuElf1P)Az&}_@+-dudt##(Ut~MKr)+_R(`xx92agl`oPA6d>*@Tp@Hafi z?>Kc$%GqO%kF8vmSHvCu(o);uX?XB`uC!2!ipvkPn;usqvTM^9Kl;FN#^K1ZFSmj= zosW-LK2hn_s(qqYz1C>Og|4#MbSwUk@aqJY`;F#eUQ?Hc+<&LM?MT`FlkOrbZZmS+ znppVY<0ZfM{g*{*#Qa!|m0raC*%dv-QO-{NdX210^vS4u0zJ1UR;;wB+@iNxO4&ui zLA~jEl}EvpU6zYK%-1NN;IlyU-dym#-8DCV*N`KChv!PAmEUW#GyB(GezH?WK{{J|+S1~cU*2$Kqw|R78_5M#* z?MiwsJ6E*Y>3P(>Q@>`Z?*4c!e-`_VNta%JVX;1TZ-a^Da^==N4^QqYWbnIbA?vgI z-s7FN8vLiyr|BcNJM$3QN#5k&{ zi1Po~dn@x4?(#Y%lJ$3)@qW_&y{8pJ}(cc}^pKV(F z>Br{VO`WIqE$G=27~`jWkXK8MEg__D-R}=?PkwOyQfFbMwDXGQe2I#qtU@v8X8J6$ zG=8bvKcVlz#_uePG#+Yo$?fK{e;T7$v31(#nCafX1)oSflCt0US>}Jr7n8@Rre=x#e?c2P{_V+!vbsJdJ4K80U;tlv0Y{@t6 zsD;M7Q=S3Eo?SW{71_H#E86V8u_(Ne>WZkGd`&H*elv%gSJner26H`O9^54YF$Z)j$r$ey{tk;Pc z@G$(gJsOuVasS4@R#sJh0>}A8d2e-HPLAV@U1Bj=a(~?VC{xJdHsz%J}HcDVMIVlU|T|^VP%JP4|9ZS6@GO z>E42SODaDl$}w5)C~!VD=ennT!I4=OH?Jh7DQ%TZ`1>_v$$uNw%w=mnro7YOS|RFu z{+@Em?k9J4^u4SKYWlfol}yjn%ZD5VcK1)cs&=QMQS0rBrkxh)jsAZg7R_|n&V1wW zQlCcFU4QSN>lHPPFY(l!cdsOQ`XWC0_Nm{Gbup}MX1#E1qhYCO+^03WN^;jNvYN~G zWZlHl^;(zrnN*9dk31)vKK1tN7apG3%Qx+^`^WHOGNZ{AMtVfWs2!srFd71*Awbs< F003<(`P2Xa From f9f3239db12054fe2c3419b17d1ec2a56b75e1ac Mon Sep 17 00:00:00 2001 From: "Maxim [maxirmx] Samsonov" Date: Wed, 15 Jan 2025 23:53:20 +0300 Subject: [PATCH 2/2] chore: version bump to v0.12.2 --- lib/tebako/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/tebako/version.rb b/lib/tebako/version.rb index fc1aaba1..8df71fee 100644 --- a/lib/tebako/version.rb +++ b/lib/tebako/version.rb @@ -26,5 +26,5 @@ # POSSIBILITY OF SUCH DAMAGE. module Tebako - VERSION = "0.12.2.rc1" + VERSION = "0.12.2" end