Skip to content
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
22 changes: 21 additions & 1 deletion lib/interscript.rb
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,28 @@ def detect(source, destination, **kwargs)
detector.call(source, destination)
end

# Locate the interscript-maps registry yaml(s) across installed gems.
#
# rubygems 4 removed StubSpecification#files, which
# Gem.find_latest_files relies on, so the fast path can raise there;
# the fallback globs the interscript-maps gems directly (there are
# only ever one or two of them, so this stays cheap).
def locate_map_gems_yaml
found = begin
Gem.find_latest_files("interscript-maps.yaml")
rescue
nil
end
return found if found.is_a?(Array) && found.any?

Gem::Specification.latest_specs
.select { |spec| spec.name == "interscript-maps" }
.flat_map { |spec| Dir.glob(File.join(spec.full_gem_path, "**", "interscript-maps.yaml")) }
.uniq
end

def map_gems
@map_gems ||= Gem.find_latest_files("interscript-maps.yaml").map do |i|
@map_gems ||= locate_map_gems_yaml.map do |i|
[i, YAML.load_file(i)]
end.to_h
end
Expand Down
37 changes: 37 additions & 0 deletions spec/interscript/map_gems_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# frozen_string_literal: true

require "interscript"
require "tmpdir"
require "fileutils"
require "yaml"

RSpec.describe Interscript do
describe ".locate_map_gems_yaml" do
it "finds the registry yaml via Gem.find_latest_files when available" do
Dir.mktmpdir do |dir|
gem_dir = File.join(dir, "gems", "interscript-maps-9.9.9")
FileUtils.mkdir_p(gem_dir)
yaml_path = File.join(gem_dir, "interscript-maps.yaml")
File.write(yaml_path, {"paths" => ["maps"]}.to_yaml)
spec = Struct.new(:name, :full_gem_path).new("interscript-maps", gem_dir)
allow(Gem::Specification).to receive(:latest_specs).and_return([spec])
allow(Gem).to receive(:find_latest_files).with("interscript-maps.yaml").and_return([yaml_path])
expect(Interscript.locate_map_gems_yaml).to include(yaml_path)
end
end

it "falls back to a direct gem-dir glob when Gem.find_latest_files is unavailable (rubygems 4)" do
Dir.mktmpdir do |dir|
gem_dir = File.join(dir, "gems", "interscript-maps-9.9.9")
FileUtils.mkdir_p(File.join(gem_dir, "maps"))
yaml_path = File.join(gem_dir, "interscript-maps.yaml")
File.write(yaml_path, {"paths" => ["maps"]}.to_yaml)
spec = Struct.new(:name, :full_gem_path).new("interscript-maps", gem_dir)
allow(Gem::Specification).to receive(:latest_specs).and_return([spec])
allow(Gem).to receive(:find_latest_files).with("interscript-maps.yaml")
.and_raise(RuntimeError, "undefined method 'files' for Gem::StubSpecification")
expect(Interscript.locate_map_gems_yaml).to include(yaml_path)
end
end
end
end
Loading