@@ -308,7 +308,11 @@ def install
308308
309309 say clean_text ( spec . post_install_message . to_s ) if options [ :post_install_message ] && !spec . post_install_message . nil?
310310
311- Gem ::Specification . add_spec ( spec ) unless @install_dir
311+ if incompatible_abi_install?
312+ say "#{ spec . full_name } is scoped to Ruby ABI #{ spec . ruby_abi } and will not be visible to the running Ruby (ABI #{ Gem . ruby_abi } )"
313+ else
314+ Gem ::Specification . add_spec ( spec ) unless @install_dir
315+ end
312316
313317 load_plugin unless options [ :install_plugin ] == false
314318
@@ -357,9 +361,11 @@ def installed_specs
357361 @installed_specs ||= begin
358362 specs = [ ]
359363
360- Gem ::Util . glob_files_in_dir ( "*.gemspec" , File . join ( gem_home , "specifications" ) ) . each do |path |
361- spec = Gem ::Specification . load path
362- specs << spec if spec
364+ Gem ::SpecificationRecord . dirs_from ( [ gem_home ] ) . each do |dir |
365+ Gem ::Util . glob_files_in_dir ( "*.gemspec" , dir ) . each do |path |
366+ spec = Gem ::Specification . load path
367+ specs << spec if spec
368+ end
363369 end
364370
365371 specs
@@ -395,7 +401,7 @@ def installation_satisfies_dependency?(dependency)
395401 #
396402
397403 def spec_file
398- File . join gem_home , "specifications" , "#{ spec . full_name } .gemspec"
404+ File . join Gem :: SpecificationRecord . specification_dir_for ( spec , gem_home ) , "#{ spec . full_name } .gemspec"
399405 end
400406
401407 def default_spec_dir
@@ -419,7 +425,24 @@ def default_spec_file
419425 def write_spec
420426 spec . installed_by_version = Gem . rubygems_version
421427
422- Gem . write_binary ( spec_file , spec . to_ruby_for_cache )
428+ spec_file = self . spec_file
429+ spec_dir = File . dirname spec_file
430+ dir_mode = options [ :dir_mode ]
431+ content_addressed = Gem ::ContentAddress . content_addressed? ( spec )
432+
433+ if File . directory? spec_dir
434+ if content_addressed && dir_mode && !File . writable? ( spec_dir )
435+ File . chmod ( 0o755 , spec_dir )
436+ end
437+ else
438+ ensure_writable_dir spec_dir
439+ end
440+
441+ begin
442+ Gem . write_binary ( spec_file , spec . to_ruby_for_cache )
443+ ensure
444+ File . chmod ( dir_mode , spec_dir ) if dir_mode && content_addressed
445+ end
423446 end
424447
425448 ##
@@ -973,6 +996,10 @@ def ensure_writable_dir(dir) # :nodoc:
973996
974997 private
975998
999+ def incompatible_abi_install?
1000+ Gem ::ContentAddress . content_addressed? ( spec ) && spec . ruby_abi != Gem . ruby_abi
1001+ end
1002+
9761003 def assign_content_address
9771004 address = @package . content_address
9781005 expected = options [ :content_address ]
0 commit comments