Skip to content

Commit

Permalink
fix: extend FILES_TO_RESTORE; restore all files before pass1
Browse files Browse the repository at this point in the history
  • Loading branch information
maxirmx committed Jan 15, 2025
1 parent bbdf3d3 commit a291f96
Show file tree
Hide file tree
Showing 9 changed files with 214 additions and 49 deletions.
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.rc1"
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.

0 comments on commit a291f96

Please sign in to comment.