Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: extend FILES_TO_RESTORE; restore all files before pass1 #235

Merged
merged 2 commits into from
Jan 15, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -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/
Expand Down
44 changes: 23 additions & 21 deletions lib/tebako/packager.rb
Original file line number Diff line number Diff line change
@@ -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
#
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
12 changes: 8 additions & 4 deletions lib/tebako/packager/patch_helpers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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

Expand Down
2 changes: 1 addition & 1 deletion lib/tebako/version.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,5 @@
# POSSIBILITY OF SUCH DAMAGE.

module Tebako
VERSION = "0.12.1"
VERSION = "0.12.2"
end
178 changes: 178 additions & 0 deletions spec/packager/patch_helpers_spec.rb
Original file line number Diff line number Diff line change
@@ -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
22 changes: 1 addition & 21 deletions spec/packager_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions tests/scripts/functional-tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand Down
1 change: 1 addition & 0 deletions tests/test-01/tebako-test-run.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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}"
Expand Down
Binary file removed tests/test-09/tebako-test-0.0.2.gem
Binary file not shown.
Loading