fxn/zeitwerk

Autoloading not working in rake task

anand-membean opened this issue · 4 comments

I have a namespaced class Ci::MyClass in a lib at lib/ci/my_class.rb
I have a rake task which is calling Ci::MyClass
I have configured to load lib as

config.paths.add Rails.root.join('lib').to_s, auto_load: true, eager_load: true

It is loading with Zeitwerk properly when checked with rails runner

dark_coder zeitwerk-rake [main]$ rails runner 'p Ci::MyClass'
Running via Spring preloader in process 97073
------Ci::MyClass--------------------------------
Ci::MyClass

Also rails zeitwerk:check

dark_coder zeitwerk-rake [main]$ rails zeitwerk:check
Hold on, I am eager loading the application.
------Ci::MyClass--------------------------------
All is good!

But when actually Ci::MyClass is called from inside of a rake task it is not working.
The implicit namespacing does not seem to be working here.

dark_coder zeitwerk-rake [main]$ rails custom_task:call_lib_class
rails aborted!
NameError: uninitialized constant Ci
/Users/dark_coder/projects/zeitwerk-rake/lib/tasks/custom_task.rake:4:in `block (2 levels) in <main>'
/Users/dark_coder/projects/zeitwerk-rake/bin/rails:5:in `<top (required)>'
/Users/dark_coder/projects/zeitwerk-rake/bin/spring:10:in `block in <top (required)>'
/Users/dark_coder/projects/zeitwerk-rake/bin/spring:7:in `tap'
/Users/dark_coder/projects/zeitwerk-rake/bin/spring:7:in `<top (required)>'
Tasks: TOP => custom_task:call_lib_class
(See full trace by running task with --trace)

Am I doing or expecting something wrong here?
This is reproducible in the demo app at https://github.com/anand-membean/zeitwerk-rake
Please help

fxn commented

Great issue description, thank you!

Loaders are defined when applications boot, but Rake tasks do not load the application by default. You can do so by depending on :environment:

desc 'This is a custom task that calls a class from lib'
namespace :custom_task do
  task call_lib_class: :environment do
    puts "===========#{Ci::MyClass.class}================================================="
  end
end
fxn commented

That fix above is most surely all you need. I am going to close to keep issues in check, but please feel free to followup if you need further help!

@fxn That was a great catch. I was just wondering that for other tasks even the models are accessible that means they get loaded but why this isn't loading.
Thanks for pointing it out.
Many thanks!!

To anyone who visit this issue, I confirm that adding :environment loads the application and also loads the intended class via Zeitwerk.