palkan / anyway_config

Configuration library for Ruby gems and applications
MIT License
778 stars 52 forks source link

Zeitwerk::Error when using autoload_static_config_path = "config/configs" #110

Closed wscourge closed 1 year ago

wscourge commented 1 year ago

What did you do?

I run the following:

rails new anyway_config -d postgresql
bundle add anyway_config
rails g anyway:install --configs-path=config/configs

then I uncommented config.anyway_config.autoload_static_config_path = "config/configs" in config/application.rb file and executed:

rails g anyway:config database username password

but it fails on the aforementioned uncommented line of code upon any rails process (console, server). It does work with app/config.

What did you expect to happen?

I expected it not to fail.

What actually happened?

I got the following Zeitwerk error.

$ rails g anyway:config database username password                                                            
/Users/me/.rbenv/versions/3.2.0/lib/ruby/gems/3.2.0/gems/zeitwerk-2.6.6/lib/zeitwerk/loader.rb:471:in `block (3 levels) in raise_if_conflicting_directory': loader (Zeitwerk::Error)

#<Zeitwerk::Loader:0x00000001103de120
 @autoloaded_dirs=[],
 @autoloads={},
 @collapse_dirs=#<Set: {}>,
 @collapse_glob_patterns=#<Set: {}>,
 @eager_load_exclusions=#<Set: {}>,
 @eager_loaded=false,
 @ignored_glob_patterns=#<Set: {}>,
 @ignored_paths=#<Set: {}>,
 @inflector=Rails::Autoloaders::Inflector,
 @initialized_at=2023-01-16 16:23:48.376379 +0100,
 @logger=nil,
 @mutex=#<Thread::Mutex:0x00000001121ca4b8>,
 @mutex2=#<Thread::Mutex:0x00000001121ca490>,
 @namespace_dirs={},
 @on_load_callbacks={},
 @on_setup_callbacks=[],
 @on_unload_callbacks={},
 @reloading_enabled=false,
 @roots={},
 @setup=false,
 @shadowed_files=#<Set: {}>,
 @tag="anyway.config",
 @to_unload={}>
wants to manage directory /Users/me/ws/tzif.io/hix/try/anyway_config/config/configs, which is already managed by

#<Zeitwerk::Loader:0x00000001103de260
 @autoloaded_dirs=[],
 @autoloads={},
 @collapse_dirs=#<Set: {}>,
 @collapse_glob_patterns=#<Set: {}>,
 @eager_load_exclusions=#<Set: {}>,
 @eager_loaded=false,
 @ignored_glob_patterns=#<Set: {}>,
 @ignored_paths=#<Set: {}>,
 @inflector=Rails::Autoloaders::Inflector,
 @initialized_at=2023-01-16 16:23:48.375365 +0100,
 @logger=nil,
 @mutex=#<Thread::Mutex:0x00000001124153a8>,
 @mutex2=#<Thread::Mutex:0x0000000112415380>,
 @namespace_dirs={},
 @on_load_callbacks={},
 @on_setup_callbacks=[],
 @on_unload_callbacks={},
 @reloading_enabled=false,
 @roots={"/Users/me/ws/tzif.io/hix/try/anyway_config/config/configs"=>Object},
 @setup=false,
 @shadowed_files=#<Set: {}>,
 @tag="anyway.config",
 @to_unload={}>

    from /Users/me/.rbenv/versions/3.2.0/lib/ruby/gems/3.2.0/gems/zeitwerk-2.6.6/lib/zeitwerk/loader.rb:465:in `each_key'
    from /Users/me/.rbenv/versions/3.2.0/lib/ruby/gems/3.2.0/gems/zeitwerk-2.6.6/lib/zeitwerk/loader.rb:465:in `block (2 levels) in raise_if_conflicting_directory'
    from /Users/me/.rbenv/versions/3.2.0/lib/ruby/gems/3.2.0/gems/zeitwerk-2.6.6/lib/zeitwerk/loader.rb:461:in `each'
    from /Users/me/.rbenv/versions/3.2.0/lib/ruby/gems/3.2.0/gems/zeitwerk-2.6.6/lib/zeitwerk/loader.rb:461:in `block in raise_if_conflicting_directory'
    from /Users/me/.rbenv/versions/3.2.0/lib/ruby/gems/3.2.0/gems/zeitwerk-2.6.6/lib/zeitwerk/loader.rb:458:in `synchronize'
    from /Users/me/.rbenv/versions/3.2.0/lib/ruby/gems/3.2.0/gems/zeitwerk-2.6.6/lib/zeitwerk/loader.rb:458:in `raise_if_conflicting_directory'
    from /Users/me/.rbenv/versions/3.2.0/lib/ruby/gems/3.2.0/gems/zeitwerk-2.6.6/lib/zeitwerk/loader/config.rb:123:in `push_dir'
    from /Users/me/.rbenv/versions/3.2.0/lib/ruby/gems/3.2.0/gems/anyway_config-2.3.0/lib/anyway/rails/settings.rb:30:in `block in autoload_static_config_path='
    from <internal:kernel>:90:in `tap'
    from /Users/me/.rbenv/versions/3.2.0/lib/ruby/gems/3.2.0/gems/anyway_config-2.3.0/lib/anyway/rails/settings.rb:27:in `autoload_static_config_path='
    from /Users/me/ws/tzif.io/hix/try/anyway_config/config/application.rb:13:in `<class:Application>'
    from /Users/me/ws/tzif.io/hix/try/anyway_config/config/application.rb:10:in `<module:AnywayConfig>'
    from /Users/me/ws/tzif.io/hix/try/anyway_config/config/application.rb:9:in `<main>'
    from /Users/me/.rbenv/versions/3.2.0/lib/ruby/gems/3.2.0/gems/bootsnap-1.15.0/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:32:in `require'
    from /Users/me/.rbenv/versions/3.2.0/lib/ruby/gems/3.2.0/gems/bootsnap-1.15.0/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:32:in `require'
    from /Users/me/.rbenv/versions/3.2.0/lib/ruby/gems/3.2.0/gems/railties-7.0.4/lib/rails/command/actions.rb:22:in `require_application!'
    from /Users/me/.rbenv/versions/3.2.0/lib/ruby/gems/3.2.0/gems/railties-7.0.4/lib/rails/command/actions.rb:14:in `require_application_and_environment!'
    from /Users/me/.rbenv/versions/3.2.0/lib/ruby/gems/3.2.0/gems/railties-7.0.4/lib/rails/commands/generate/generate_command.rb:21:in `perform'
    from /Users/me/.rbenv/versions/3.2.0/lib/ruby/gems/3.2.0/gems/thor-1.2.1/lib/thor/command.rb:27:in `run'
    from /Users/me/.rbenv/versions/3.2.0/lib/ruby/gems/3.2.0/gems/thor-1.2.1/lib/thor/invocation.rb:127:in `invoke_command'
    from /Users/me/.rbenv/versions/3.2.0/lib/ruby/gems/3.2.0/gems/thor-1.2.1/lib/thor.rb:392:in `dispatch'
    from /Users/me/.rbenv/versions/3.2.0/lib/ruby/gems/3.2.0/gems/railties-7.0.4/lib/rails/command/base.rb:87:in `perform'
    from /Users/me/.rbenv/versions/3.2.0/lib/ruby/gems/3.2.0/gems/railties-7.0.4/lib/rails/command.rb:48:in `invoke'
    from /Users/me/.rbenv/versions/3.2.0/lib/ruby/gems/3.2.0/gems/railties-7.0.4/lib/rails/commands.rb:18:in `<main>'
    from /Users/me/.rbenv/versions/3.2.0/lib/ruby/gems/3.2.0/gems/bootsnap-1.15.0/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:32:in `require'
    from /Users/me/.rbenv/versions/3.2.0/lib/ruby/gems/3.2.0/gems/bootsnap-1.15.0/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:32:in `require'
    from bin/rails:4:in `<main>'

Additional context

none

Environment

Ruby Version: 3.2.0

Framework Version (Rails, whatever): 7.0.4

Anyway Config Version: 2.3.0

palkan commented 1 year ago

Thanks for reporting.

Fixed and released in 2.3.1.

darkporpoise commented 5 months ago

I'm getting this error now as well. Am I right in thinking that this doesn't matter because config/configs is static autoloaded by default anyway?

Ruby Version: 3.1.4 Framework Version (Rails, whatever): 6.0.6.1 Anyway Config Version: 2.6.4

Error ```Ruby rails g anyway:config config_class config_value ``` ``` /app/vendor/ruby/3.1.0/gems/zeitwerk-2.6.13/lib/zeitwerk/loader.rb:542:in `block (3 levels) in raise_if_conflicting_directory': loader #, @collapse_glob_patterns=#, @dirs_autoload_monitor=#, @eager_load_exclusions=#, @eager_loaded=false, @ignored_glob_patterns=#, @ignored_paths=#, @inflector=ActiveSupport::Dependencies::ZeitwerkIntegration::Inflector, @initialized_at="2024-05-24T10:30:59.787+00:00", @logger=nil, @mutex=#, @namespace_dirs={}, @on_load_callbacks={}, @on_setup_callbacks=[], @on_unload_callbacks={}, @reloading_enabled=false, @roots={}, @setup=false, @shadowed_files=#, @tag="anyway.config", @to_unload={}> wants to manage directory /app/config/configs, which is already managed by #, @collapse_glob_patterns=#, @dirs_autoload_monitor=#, @eager_load_exclusions=#, @eager_loaded=false, @ignored_glob_patterns=#, @ignored_paths=#, @inflector=ActiveSupport::Dependencies::ZeitwerkIntegration::Inflector, @initialized_at="2024-05-24T10:30:59.785+00:00", @logger=nil, @mutex=#, @namespace_dirs={}, @on_load_callbacks={}, @on_setup_callbacks=[], @on_unload_callbacks={}, @reloading_enabled=false, @roots={"/app/config/configs"=>Object}, @setup=false, @shadowed_files=#, @tag="anyway.config", @to_unload={}> (Zeitwerk::Error) from /app/vendor/ruby/3.1.0/gems/zeitwerk-2.6.13/lib/zeitwerk/loader.rb:536:in `each_key' from /app/vendor/ruby/3.1.0/gems/zeitwerk-2.6.13/lib/zeitwerk/loader.rb:536:in `block (2 levels) in raise_if_conflicting_directory' from /app/vendor/ruby/3.1.0/gems/zeitwerk-2.6.13/lib/zeitwerk/loader.rb:532:in `each' from /app/vendor/ruby/3.1.0/gems/zeitwerk-2.6.13/lib/zeitwerk/loader.rb:532:in `block in raise_if_conflicting_directory' from /app/vendor/ruby/3.1.0/gems/zeitwerk-2.6.13/lib/zeitwerk/loader.rb:529:in `synchronize' from /app/vendor/ruby/3.1.0/gems/zeitwerk-2.6.13/lib/zeitwerk/loader.rb:529:in `raise_if_conflicting_directory' from /app/vendor/ruby/3.1.0/gems/zeitwerk-2.6.13/lib/zeitwerk/loader/config.rb:122:in `push_dir' from /app/vendor/ruby/3.1.0/gems/anyway_config-2.6.4/lib/anyway/rails/settings.rb:38:in `block in autoload_static_config_path=' from :90:in `tap' from /app/vendor/ruby/3.1.0/gems/anyway_config-2.6.4/lib/anyway/rails/settings.rb:30:in `autoload_static_config_path=' from /app/config/application.rb:28:in `' from /app/config/application.rb:10:in `' from /app/config/application.rb:9:in `' from /app/vendor/ruby/3.1.0/gems/spring-2.1.1/lib/spring/application.rb:92:in `require' from /app/vendor/ruby/3.1.0/gems/spring-2.1.1/lib/spring/application.rb:92:in `preload' from /app/vendor/ruby/3.1.0/gems/spring-2.1.1/lib/spring/application.rb:157:in `serve' from /app/vendor/ruby/3.1.0/gems/spring-2.1.1/lib/spring/application.rb:145:in `block in run' from /app/vendor/ruby/3.1.0/gems/spring-2.1.1/lib/spring/application.rb:139:in `loop' from /app/vendor/ruby/3.1.0/gems/spring-2.1.1/lib/spring/application.rb:139:in `run' from /app/vendor/ruby/3.1.0/gems/spring-2.1.1/lib/spring/application/boot.rb:19:in `' from :85:in `require' from :85:in `require' from -e:1:in `
' ```
palkan commented 5 months ago

/app/vendor/ruby/3.1.0/gems/spring-2.1.1/lib/spring/application.rb

I bet it's something related to Spring; could please run without Spring and see if it fails?

darkporpoise commented 5 months ago

Thanks for taking a look. I still get the error with Spring disabled:

DISABLE_SPRING=true rails s
error /app/vendor/ruby/3.1.0/gems/zeitwerk-2.6.13/lib/zeitwerk/loader.rb:542:in `block (3 levels) in raise_if_conflicting_directory': loader (Zeitwerk::Error) #, @collapse_glob_patterns=#, @dirs_autoload_monitor=#, @eager_load_exclusions=#, @eager_loaded=false, @ignored_glob_patterns=#, @ignored_paths=#, @inflector=ActiveSupport::Dependencies::ZeitwerkIntegration::Inflector, @initialized_at="2024-05-30T09:01:49.247+00:00", @logger=nil, @mutex=#, @namespace_dirs={}, @on_load_callbacks={}, @on_setup_callbacks=[], @on_unload_callbacks={}, @reloading_enabled=false, @roots={}, @setup=false, @shadowed_files=#, @tag="anyway.config", @to_unload={}> wants to manage directory /app/config/configs, which is already managed by #, @collapse_glob_patterns=#, @dirs_autoload_monitor=#, @eager_load_exclusions=#, @eager_loaded=false, @ignored_glob_patterns=#, @ignored_paths=#, @inflector=ActiveSupport::Dependencies::ZeitwerkIntegration::Inflector, @initialized_at="2024-05-30T09:01:49.245+00:00", @logger=nil, @mutex=#, @namespace_dirs={}, @on_load_callbacks={}, @on_setup_callbacks=[], @on_unload_callbacks={}, @reloading_enabled=false, @roots={"/app/config/configs"=>Object}, @setup=false, @shadowed_files=#, @tag="anyway.config", @to_unload={}> from /app/vendor/ruby/3.1.0/gems/zeitwerk-2.6.13/lib/zeitwerk/loader.rb:536:in `each_key' from /app/vendor/ruby/3.1.0/gems/zeitwerk-2.6.13/lib/zeitwerk/loader.rb:536:in `block (2 levels) in raise_if_conflicting_directory' from /app/vendor/ruby/3.1.0/gems/zeitwerk-2.6.13/lib/zeitwerk/loader.rb:532:in `each' from /app/vendor/ruby/3.1.0/gems/zeitwerk-2.6.13/lib/zeitwerk/loader.rb:532:in `block in raise_if_conflicting_directory' from /app/vendor/ruby/3.1.0/gems/zeitwerk-2.6.13/lib/zeitwerk/loader.rb:529:in `synchronize' from /app/vendor/ruby/3.1.0/gems/zeitwerk-2.6.13/lib/zeitwerk/loader.rb:529:in `raise_if_conflicting_directory' from /app/vendor/ruby/3.1.0/gems/zeitwerk-2.6.13/lib/zeitwerk/loader/config.rb:122:in `push_dir' from /app/vendor/ruby/3.1.0/gems/anyway_config-2.6.4/lib/anyway/rails/settings.rb:38:in `block in autoload_static_config_path=' from :90:in `tap' from /app/vendor/ruby/3.1.0/gems/anyway_config-2.6.4/lib/anyway/rails/settings.rb:30:in `autoload_static_config_path=' from /app/config/application.rb:28:in `' from /app/config/application.rb:10:in `' from /app/config/application.rb:9:in `
' from /app/vendor/ruby/3.1.0/gems/bootsnap-1.10.2/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `require' from /app/vendor/ruby/3.1.0/gems/bootsnap-1.10.2/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `require' from /app/vendor/ruby/3.1.0/gems/activesupport-6.0.6.1/lib/active_support/dependencies.rb:324:in `block in require' from /app/vendor/ruby/3.1.0/gems/activesupport-6.0.6.1/lib/active_support/dependencies.rb:291:in `load_dependency' from /app/vendor/ruby/3.1.0/gems/activesupport-6.0.6.1/lib/active_support/dependencies.rb:324:in `require' from /app/vendor/ruby/3.1.0/gems/railties-6.0.6.1/lib/rails/commands/server/server_command.rb:141:in `block in perform' from :90:in `tap' from /app/vendor/ruby/3.1.0/gems/railties-6.0.6.1/lib/rails/commands/server/server_command.rb:138:in `perform' from /app/vendor/ruby/3.1.0/gems/thor-0.20.3/lib/thor/command.rb:27:in `run' from /app/vendor/ruby/3.1.0/gems/thor-0.20.3/lib/thor/invocation.rb:126:in `invoke_command' from /app/vendor/ruby/3.1.0/gems/thor-0.20.3/lib/thor.rb:387:in `dispatch' from /app/vendor/ruby/3.1.0/gems/railties-6.0.6.1/lib/rails/command/base.rb:69:in `perform' from /app/vendor/ruby/3.1.0/gems/railties-6.0.6.1/lib/rails/command.rb:46:in `invoke' from /app/vendor/ruby/3.1.0/gems/railties-6.0.6.1/lib/rails/commands.rb:18:in `
' from /app/vendor/ruby/3.1.0/gems/bootsnap-1.10.2/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `require' from /app/vendor/ruby/3.1.0/gems/bootsnap-1.10.2/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `require' from bin/rails:9:in `
'
palkan commented 5 months ago

@darkporpoise Thanks for checking.

Can you please show the value you assign to the config.anyway_config.autoload_static_config_path (here config/application.rb:28) ?

darkporpoise commented 4 months ago

    ### AnyWayConfig
    ## https://github.com/palkan/anyway_config

    ### Defaut location to check for YML files
    config.anyway_config.default_config_path = Rails.root.join("config", "configs")
    ### Location of static config classes. These are available in Initializers but are not reloaded.
    config.anyway_config.autoload_static_config_path = Rails.root.join("config", "configs")
    ### Check for top level known environment keys in config files.
    ## If any value is environment specific they all have to be. You can't mix and match within a file.
    config.anyway_config.future.use :unwrap_known_environments
    config.anyway_config.known_environments.concat %w[staging demo]
    ### Name of top level key to apply to all environments. Similar to YML anchor but allows deep-merging
    config.anyway_config.default_environmental_key = "default"

Line 28 is the autoload_static_config_path

palkan commented 4 months ago

Thanks! Since you're using the absolute path, this line doesn't work as it should do: https://github.com/palkan/anyway_config/blob/233248947ff0f9e5bac4b7aaea9648ae2c464928/lib/anyway/rails/settings.rb#L22

We use config/configs as the default path.

For now, you can either remove this configuration line (since it's already the default) or replace with:

config.anyway_config.autoload_static_config_path = "config/configs"
darkporpoise commented 4 months ago

Thank you. That makes sense.