From c6b40796221c0a29b09b4bdeda5fcdf7c5a8e549 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20Lilleb=C3=B8?= Date: Fri, 14 Nov 2025 12:42:28 +0100 Subject: [PATCH] Allow Herb to be installed from source Previously Herb could only be installed if there was a precompiled gem available. This changes this by vendoring Prism on compile time. --- ext/herb/extconf.rb | 46 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/ext/herb/extconf.rb b/ext/herb/extconf.rb index cb215e568..037c7ab37 100644 --- a/ext/herb/extconf.rb +++ b/ext/herb/extconf.rb @@ -1,9 +1,53 @@ # frozen_string_literal: true require "mkmf" +require "bundler" +require "fileutils" + +def vendor_prism(prism_vendor_path) + prism_header = File.join(prism_vendor_path, "include", "prism.h") + return if File.exist?(prism_header) + + prism_spec = Gem::Specification.find_by_name("prism") +rescue Gem::LoadError + abort <<~MSG + Prism could not be found. + Herb requires Prism when building from source. Please add `gem "prism"` to your Gemfile. + MSG +else + prism_bundle_path = prism_spec.full_gem_path + + files = %w[ + config.yml + Rakefile + src + include + templates + ] + + FileUtils.mkdir_p(prism_vendor_path) + + files.each do |file| + source = File.join(prism_bundle_path, file) + next unless File.exist?(source) + + destination = File.join(prism_vendor_path, file) + + if File.directory?(source) + FileUtils.mkdir_p(destination) + FileUtils.cp_r(File.join(source, "."), destination, remove_destination: true) + else + FileUtils.mkdir_p(File.dirname(destination)) + FileUtils.cp(source, destination) + end + end +end Dir.chdir(File.expand_path("../..", __dir__)) do - system("rake templates", exception: true) + Bundler.with_unbundled_env do + vendor_prism(File.expand_path("../../vendor/prism", __dir__)) + system("rake templates", exception: true) + end end extension_name = "herb"