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..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.1"
+  VERSION = "0.12.2"
 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 c4d25c52..00000000
Binary files a/tests/test-09/tebako-test-0.0.2.gem and /dev/null differ