Describe the bug
Installing ruby3.4, ruby3.4-rubygems, and ruby3.4-rubygem-bundler together in a single dnf install transaction does not create /usr/bin/gem, /usr/bin/bundle, or /usr/bin/bundler. Only the versioned binaries (ruby3.4-gem, ruby3.4-bundle, ruby3.4-bundler) exist afterwards. ruby itself works fine.
This looks similar to #1073, but is a different root cause. That issue was a master/slave path mismatch in the alternatives --add-slave calls (/usr/bin/ruby3.4 vs /usr/bin/ruby3.4-mri), which is now fixed — both ruby3.4-rubygems and ruby3.4-rubygem-bundler's scriptlets correctly use /usr/bin/ruby3.4-mri as of this build. The bug reproduces anyway, for an unrelated reason: %posttrans scriptlet ordering.
To Reproduce
$ docker run --rm -it public.ecr.aws/amazonlinux/amazonlinux:2023.12.20260909.0
bash-5.2# dnf install -y ruby3.4 ruby3.4-devel ruby3.4-rubygems ruby3.4-rubygem-bundler
...
Complete!
bash-5.2# ls /usr/bin/gem /usr/bin/bundle /usr/bin/bundler
ls: cannot access '/usr/bin/gem': No such file or directory
ls: cannot access '/usr/bin/bundle': No such file or directory
ls: cannot access '/usr/bin/bundler': No such file or directory
bash-5.2# alternatives --display ruby
ruby - status is auto.
link currently points to /usr/bin/ruby3.4-mri
/usr/bin/ruby3.4-mri - priority 34
slave ruby.1.gz: /usr/share/man/man1/ruby3.4.1.gz
Current `best' version is /usr/bin/ruby3.4-mri.
Installing ruby3.4 alone first (with weak deps disabled, since a plain install otherwise pulls rubygems/bundler into the same transaction), then ruby3.4-rubygems/ruby3.4-rubygem-bundler in a second, separate dnf install, works around it:
bash-5.2# dnf install -y --setopt=install_weak_deps=False ruby3.4
bash-5.2# dnf install -y ruby3.4-rubygems ruby3.4-rubygem-bundler
bash-5.2# gem --version
3.6.9
bash-5.2# bundle --version
Bundler version 2.6.9
Expected behavior
gem, bundle, and bundler should be usable regardless of whether ruby3.4, ruby3.4-rubygems, and ruby3.4-rubygem-bundler are installed in one transaction or several.
Additional context
Root cause: %posttrans scriptlets in RPM are only guaranteed to run after every package's %pre/%post in the transaction has completed — RPM does not apply Requires-based ordering across different packages' %posttrans scriptlets. ruby3.4's own %posttrans registers the ruby alternatives master group via:
/usr/sbin/alternatives --install /usr/bin/ruby ruby /usr/bin/ruby3.4-mri 34
ruby3.4-rubygems and ruby3.4-rubygem-bundler's %posttrans scriptlets add slaves to that same group:
/usr/sbin/alternatives --add-slave ruby /usr/bin/ruby3.4-mri /usr/bin/gem gem /usr/bin/ruby3.4-gem || :
In this transaction, the %posttrans scriptlets run in this order:
%posttrans(ruby3.4-rubygem-bundler)
%posttrans(ruby3.4-rubygem-rdoc)
%posttrans(ruby3.4-rubygems)
%posttrans(ruby3.4) <- registers the master group, but runs LAST
So --add-slave runs before the ruby master group exists, fails silently (each call is suffixed || :), and no symlinks are created. I confirmed the identical alternatives --add-slave ... command succeeds (rc=0) when run manually immediately after the transaction completes — same paths, same arguments, the only difference being that ruby3.4's %posttrans has by then registered the master group.
Per the Fedora Alternatives packaging guidance, alternatives --install/--add-slave calls are conventionally placed in %post rather than %posttrans, specifically because %post is ordered according to Requires — ruby3.4-rubygems/ruby3.4-rubygem-bundler both Requires: ruby3.4, which would guarantee ruby3.4's %post (and thus the master registration) runs first. Moving these alternatives calls from %posttrans to %post in ruby3.4, ruby3.4-rubygems, and ruby3.4-rubygem-bundler would fix this at the source, without relying on transaction-order luck or a two-step install workaround.
Describe the bug
Installing
ruby3.4,ruby3.4-rubygems, andruby3.4-rubygem-bundlertogether in a singlednf installtransaction does not create/usr/bin/gem,/usr/bin/bundle, or/usr/bin/bundler. Only the versioned binaries (ruby3.4-gem,ruby3.4-bundle,ruby3.4-bundler) exist afterwards.rubyitself works fine.This looks similar to #1073, but is a different root cause. That issue was a master/slave path mismatch in the
alternatives --add-slavecalls (/usr/bin/ruby3.4vs/usr/bin/ruby3.4-mri), which is now fixed — bothruby3.4-rubygemsandruby3.4-rubygem-bundler's scriptlets correctly use/usr/bin/ruby3.4-mrias of this build. The bug reproduces anyway, for an unrelated reason:%posttransscriptlet ordering.To Reproduce
Installing
ruby3.4alone first (with weak deps disabled, since a plain install otherwise pullsrubygems/bundlerinto the same transaction), thenruby3.4-rubygems/ruby3.4-rubygem-bundlerin a second, separatednf install, works around it:Expected behavior
gem,bundle, andbundlershould be usable regardless of whetherruby3.4,ruby3.4-rubygems, andruby3.4-rubygem-bundlerare installed in one transaction or several.Additional context
Root cause:
%posttransscriptlets in RPM are only guaranteed to run after every package's%pre/%postin the transaction has completed — RPM does not applyRequires-based ordering across different packages'%posttransscriptlets.ruby3.4's own%posttransregisters therubyalternatives master group via:ruby3.4-rubygemsandruby3.4-rubygem-bundler's%posttransscriptlets add slaves to that same group:In this transaction, the
%posttransscriptlets run in this order:So
--add-slaveruns before therubymaster group exists, fails silently (each call is suffixed|| :), and no symlinks are created. I confirmed the identicalalternatives --add-slave ...command succeeds (rc=0) when run manually immediately after the transaction completes — same paths, same arguments, the only difference being thatruby3.4's%posttranshas by then registered the master group.Per the Fedora Alternatives packaging guidance,
alternatives --install/--add-slavecalls are conventionally placed in%postrather than%posttrans, specifically because%postis ordered according toRequires—ruby3.4-rubygems/ruby3.4-rubygem-bundlerbothRequires: ruby3.4, which would guaranteeruby3.4's%post(and thus the master registration) runs first. Moving thesealternativescalls from%posttransto%postinruby3.4,ruby3.4-rubygems, andruby3.4-rubygem-bundlerwould fix this at the source, without relying on transaction-order luck or a two-step install workaround.