How `lib` folder of plugins are added to the `$LOAD_PATH`

AI-generated summary

The discussion revolves around how Discourse adds the lib folder of plugins to the $LOAD_PATH. AhmedLoud noticed that when a plugin has a lib folder, its contents can be required in the Rails console. He investigated and found that commenting out a line in instance.rb breaks this functionality.

david explained that many plugin.rb files initialize a Rails Engine, which adds paths to the load path. He suggested that the instance_eval line in instance.rb executes the plugin.rb file, creating the Rails engine and adding the extra paths.

AhmedLoud thanked david for the explanation and shared that he was implementing a similar plugin system. He noted that activating plugins outside of application.rb, such as in an initializer, prevents the lib folders from being added to the load path.

I noticed that when creating a plugin, if I add a lib folder and some files in this lib folder then I can use require because it is added to the $LOAD_PATH.

For instance the docker_manager plugin has a lib/docker_manager/git_repo.rb file . Then running the rails console rails c I can write require 'docker_manager/git_repo'

I am curious to know how discourse makes all this paths available ?

I noticed that in the file /lib/plugin/instance.rb if I comment line 671 self.instance_eval File.read(path), path then the require does not work. However I don’t understand how instance_eval would add directories to the load_path.

Many plugin.rb files initialize a Rails Engine, which adds various things to the load path.

When we don’t have a rails engine, you’ll see lots of require_relative calls at the top of the plugin.rb file to compensate.

I think this is because the instance_eval is executing the plugin.rb file. If the plugin.rb is not executed, then the rails engine is never created, and the extra paths don’t added to the load_path.

Thank you ! That helped me understand.

I was trying to implement the same plugin system and my issue was that I was activating them later outside application.rb, in an initializer for example. Then the lib (and probably other folders) of the plugins are not added to the load path.