diaspora/diaspora

Loading `database.yml` fails in `config/bundler_helper.rb` fails with Ruby 3.1

denschub opened this issue · 2 comments

Using Ruby 3.1 with its internal Psych 4.x YAML parser, starting diaspora* fails with

Unable to load application: Psych::BadAlias: Unknown alias: postgresql
! Unable to load application: Psych::BadAlias: Unknown alias: postgresql
/usr/lib/ruby/3.0.0/psych/visitors/to_ruby.rb:432:in `visit_Psych_Nodes_Alias': Unknown alias: postgresql (Psych::BadAlias)
        from /usr/lib/ruby/3.0.0/psych/visitors/visitor.rb:30:in `visit'
        from /usr/lib/ruby/3.0.0/psych/visitors/visitor.rb:6:in `accept'
        from /usr/lib/ruby/3.0.0/psych/visitors/to_ruby.rb:35:in `accept'
        from /usr/lib/ruby/3.0.0/psych/visitors/to_ruby.rb:347:in `block in revive_hash'
        from /usr/lib/ruby/3.0.0/psych/visitors/to_ruby.rb:345:in `each'
        from /usr/lib/ruby/3.0.0/psych/visitors/to_ruby.rb:345:in `each_slice'
        from /usr/lib/ruby/3.0.0/psych/visitors/to_ruby.rb:345:in `revive_hash'
        from /usr/lib/ruby/3.0.0/psych/visitors/to_ruby.rb:169:in `visit_Psych_Nodes_Mapping'
        from /usr/lib/ruby/3.0.0/psych/visitors/visitor.rb:30:in `visit'
        from /usr/lib/ruby/3.0.0/psych/visitors/visitor.rb:6:in `accept'
        from /usr/lib/ruby/3.0.0/psych/visitors/to_ruby.rb:35:in `accept'
        from /usr/lib/ruby/3.0.0/psych/visitors/to_ruby.rb:347:in `block in revive_hash'
        from /usr/lib/ruby/3.0.0/psych/visitors/to_ruby.rb:345:in `each'
        from /usr/lib/ruby/3.0.0/psych/visitors/to_ruby.rb:345:in `each_slice'
        from /usr/lib/ruby/3.0.0/psych/visitors/to_ruby.rb:345:in `revive_hash'
        from /usr/lib/ruby/3.0.0/psych/visitors/to_ruby.rb:169:in `visit_Psych_Nodes_Mapping'
        from /usr/lib/ruby/3.0.0/psych/visitors/visitor.rb:30:in `visit'
        from /usr/lib/ruby/3.0.0/psych/visitors/visitor.rb:6:in `accept'
        from /usr/lib/ruby/3.0.0/psych/visitors/to_ruby.rb:35:in `accept'
        from /usr/lib/ruby/3.0.0/psych/visitors/to_ruby.rb:320:in `visit_Psych_Nodes_Document'
        from /usr/lib/ruby/3.0.0/psych/visitors/visitor.rb:30:in `visit'
        from /usr/lib/ruby/3.0.0/psych/visitors/visitor.rb:6:in `accept'
        from /usr/lib/ruby/3.0.0/psych/visitors/to_ruby.rb:35:in `accept'
        from /usr/lib/ruby/3.0.0/psych.rb:334:in `safe_load'
        from /usr/lib/ruby/3.0.0/psych.rb:369:in `load'
        from /usr/lib/ruby/3.0.0/psych.rb:671:in `block in load_file'
        from /usr/lib/ruby/3.0.0/psych.rb:670:in `open'
        from /usr/lib/ruby/3.0.0/psych.rb:670:in `load_file'
        from /srv/diaspora/config/bundler_helper.rb:23:in `parse_value_from_yaml_file'
        from /srv/diaspora/config/bundler_helper.rb:14:in `database'
        from /srv/diaspora/config/application.rb:11:in `<top (required)>'
        from /srv/diaspora/config/environment.rb:4:in `require_relative'
        from /srv/diaspora/config/environment.rb:4:in `<top (required)>'
        from config.ru:9:in `require_relative'
        from config.ru:9:in `block in <main>'
        from /srv/diaspora/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/builder.rb:116:in `eval'
        from /srv/diaspora/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/builder.rb:116:in `new_from_string'
        from /srv/diaspora/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/builder.rb:105:in `load_file'
        from /srv/diaspora/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/builder.rb:66:in `parse_file'
        from /srv/diaspora/vendor/bundle/ruby/3.0.0/gems/puma-5.6.5/lib/puma/configuration.rb:348:in `load_rackup'
        from /srv/diaspora/vendor/bundle/ruby/3.0.0/gems/puma-5.6.5/lib/puma/configuration.rb:270:in `app'
        from /srv/diaspora/vendor/bundle/ruby/3.0.0/gems/puma-5.6.5/lib/puma/runner.rb:150:in `load_and_bind'
        from /srv/diaspora/vendor/bundle/ruby/3.0.0/gems/puma-5.6.5/lib/puma/single.rb:44:in `run'
        from /srv/diaspora/vendor/bundle/ruby/3.0.0/gems/puma-5.6.5/lib/puma/launcher.rb:193:in `run'
        from /srv/diaspora/vendor/bundle/ruby/3.0.0/gems/puma-5.6.5/lib/puma/cli.rb:81:in `run'
        from /srv/diaspora/vendor/bundle/ruby/3.0.0/gems/puma-5.6.5/bin/puma:10:in `<top (required)>'
        from /srv/diaspora/bin/puma:27:in `load'
        from /srv/diaspora/bin/puma:27:in `<main>'

Cause is at

YAML.load_file(path).dig(*keys) if File.file?(path)

This is due to the update to Psych 4.x in this Ruby release, where load and load_file are effectively aliases for safe_load and safe_load_file. To fix this,

diff --git a/config/bundler_helper.rb b/config/bundler_helper.rb
index 29d3a6d3e..ae721eb7c 100644
--- a/config/bundler_helper.rb
+++ b/config/bundler_helper.rb
@@ -20,7 +20,7 @@ module BundlerHelper

   private_class_method def self.parse_value_from_yaml_file(file, *keys)
     path = File.join(__dir__, file)
-    YAML.load_file(path).dig(*keys) if File.file?(path)
+    YAML.unsafe_load_file(path).dig(*keys) if File.file?(path)
   end

   private_class_method def self.parse_value_from_toml_file(file, key)

works. Alternatively, YAML.load_file(path, aliases: true) would also work in this case. Unfortunately, we can't make this change right now, and would have to wait until we officially drop Ruby 2.7.

Oh dear, nevermind.

This is actually a setup-issue. Archlinux' Ruby package skips stdlib-Gems if they're already packages, and as it turns out, the ruby-psych package for Archlinux is newer than the Psych version included in 3.0. In Ruby 3.0.x, the Psych version is 3.3.2, which is not affected by this.

However, Ruby 3.1 is using Psych 4, and then this script explodes. I'll leave this issue open in relation to #8369 as we'd have to fix that anyway, but I'll adjust it accordingly.

This is actually a setup-issue.

I was very surprised, as I tested 3.0 a lot and didn't get this problem. I only had this problem with 3.1 (but I didn't have the time yet to dig into it and closer analyze it, so thanks for that 🍪 ).

Alternatively, YAML.load_file(path, aliases: true) would also work in this case. Unfortunately, we can't make this change right now, and would have to wait until we officially drop Ruby 2.7.

That's not true, aliases: true also doesn't work with ruby 3.0, so dropping 2.7 isn't enough to do that. But what we can do after we dropped 2.7 is: YAML.safe_load_file(path, aliases: true), so just use the safe_ variant explicitly.