Requiring external gems

For a plugin that I am writing, I would like to use some external gem files that are not present in the default discourse gemfile.

What is the standard way of doing this without being able to modify the discourse gemfile?

Also a similar question reqarding user-defined rake tasks.

Keep in mind you have to declare the gems AND dependencies.

Thanks, didn’t realize that all dependencies needed to be included as well.

How can I also do this for rake tasks?

Have you tried “LOAD_PLUGINS=1 rake your:rake:task”?

oxford_dictionary という Ruby gem を使おうとしています。

gem 'oxford_dictionary', '2.0.1', { require: false }

コンソールには以下のような出力が表示されます。

/bin/bash -c "env RBENV_VERSION=2.6.2 /usr/local/Cellar/rbenv/1.1.2/libexec/rbenv exec ruby /Users/faiz/discenv/discourse/bin/rails server -b 0.0.0.0 -p 3000 -e development"
I, [2019-08-08T14:01:24.177008 #5867]  INFO -- : Refreshing Gem list
Traceback (most recent call last):
	30: from /Users/faiz/discenv/discourse/bin/unicorn:49:in `<main>'
	29: from /Users/faiz/discenv/discourse/bin/unicorn:49:in `load'
	28: from /Users/faiz/.rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/gems/unicorn-5.5.1/bin/unicorn:128:in `<top (required)>'
	27: from /Users/faiz/.rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/gems/unicorn-5.5.1/lib/unicorn/http_server.rb:141:in `start'
	26: from /Users/faiz/.rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/gems/unicorn-5.5.1/lib/unicorn/http_server.rb:794:in `build_app!'
	25: from /Users/faiz/.rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/gems/unicorn-5.5.1/lib/unicorn.rb:54:in `block in builder'
	24: from /Users/faiz/.rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/gems/unicorn-5.5.1/lib/unicorn.rb:54:in `eval'
	23: from config.ru:1:in `<main>'
	22: from config.ru:1:in `new'
	21: from /Users/faiz/.rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/gems/rack-2.0.7/lib/rack/builder.rb:55:in `initialize'
	20: from /Users/faiz/.rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/gems/rack-2.0.7/lib/rack/builder.rb:55:in `instance_eval'
	19: from config.ru:7:in `block in <main>'
	18: from config.ru:7:in `require'
	17: from /Users/faiz/discenv/discourse/config/environment.rb:4:in `<top (required)>'
	16: from /Users/faiz/discenv/discourse/config/environment.rb:4:in `require'
	15: from /Users/faiz/discenv/discourse/config/application.rb:57:in `<top (required)>'
	14: from /Users/faiz/discenv/discourse/config/application.rb:58:in `<module:Discourse>'
	13: from /Users/faiz/discenv/discourse/config/application.rb:261:in `<class:Application>'
	12: from lib/discourse.rb:168:in `activate_plugins!'
	11: from lib/discourse.rb:168:in `each'
	10: from lib/discourse.rb:171:in `block in activate_plugins!'
	 9: from /Users/faiz/discenv/discourse/lib/plugin/instance.rb:486:in `activate!'
	 8: from /Users/faiz/discenv/discourse/lib/plugin/instance.rb:486:in `instance_eval'
	 7: from /Users/faiz/discenv/discourse/plugins/discourse-dictionary/plugin.rb:7:in `activate!'
	 6: from /Users/faiz/discenv/discourse/lib/plugin/instance.rb:560:in `gem'
	 5: from /Users/faiz/discenv/discourse/lib/plugin_gem.rb:20:in `load'
	 4: from /Users/faiz/.rbenv/versions/2.6.2/lib/ruby/2.6.0/rubygems/specification.rb:1420:in `activate'
	 3: from /Users/faiz/.rbenv/versions/2.6.2/lib/ruby/2.6.0/rubygems/specification.rb:1438:in `activate_dependencies'
	 2: from /Users/faiz/.rbenv/versions/2.6.2/lib/ruby/2.6.0/rubygems/specification.rb:1438:in `each'
	 1: from /Users/faiz/.rbenv/versions/2.6.2/lib/ruby/2.6.0/rubygems/specification.rb:1449:in `block in activate_dependencies'
/Users/faiz/.rbenv/versions/2.6.2/lib/ruby/2.6.0/rubygems/dependency.rb:311:in `to_specs': Could not find 'plissken' (~> 0.1.0) among 285 total gem(s) (Gem::MissingSpecError)
Checked in 'GEM_PATH=/Users/faiz/.rbenv/versions/2.6.2/lib/ruby/gems/2.6.0:/Users/faiz/.gem/ruby/2.6.0', execute `gem env` for more information

Process finished with exit code 1

おそらく、gem 自体が依存するものを Discourse がインストールできていないことが原因だと思います。どうすれば直せますか?

更新
解決しました。依存関係にある plissken を別途明記する必要がありました。
なぜそうなるのでしょうか?

ターゲットの gem には、メインの Gemfile に含まれていない依存関係があるため、plugin.rb に含める必要があります。

これは、時間がかかる反復的なプロセスになることもあります!

私は「長い再帰的なプロセス」と言いたいですね :rofl:

また、そこでは require: false を使用できません。動作させるには true に設定し、明示的に require する必要があります。

いつかはその再帰処理をコンピュータが処理してくれるといいですね :stuck_out_tongue_winking_eye:

私の経験に基づいた更新情報です:

  • バージョン番号は必須です。
  • これらの依存関係を取得するには、お使いのローカルマシンに Ruby 2.6.5(現在 Discourse で使用されているバージョン)をインストールし、必要な gem を含む Gemfile を作成してください。
  • ターミナルで「bundle install」を実行して Gemfile.lock を生成します。
  • これにより、すべての gem、gem の依存関係、およびバージョン番号が一覧表示されます。
  • Rafael が plugin.rb で指摘している通りに行ってください。

「required」の正確な意味はわかりませんが、true に設定しました。

すみません、これはしばらく前のことですが、eth gem をインストールしようとしていて、依存関係でこのエラーが発生しています。

I, [2023-08-28T15:00:23.737246 #1]  INFO -- : cd /var/www/discourse & su discourse -c 'bundle exec rake db:migrate'
rake aborted!
Gem::MissingSpecError: Could not find 'forwardable' (>= 1.3) among 231 total gem(s)
Checked in 'GEM_PATH=/var/www/discourse/vendor/bundle/ruby/3.2.0:/var/www/discourse/plugins/discourse-radiant-member/gems/3.2.2' at: /var/www/discourse/plugins/discourse-radiant-member/gems/3.2.2/specifications/eth-0.5.11.gemspec, execute `gem env` for more information
/var/www/discourse/lib/plugin_gem.rb:25:in `load'
/var/www/discourse/lib/plugin/instance.rb:825:in `gem'
/var/www/discourse/plugins/discourse-radiant-member/plugin.rb:10:in `activate!'
/var/www/discourse/lib/plugin/instance.rb:722:in `instance_eval'
/var/www/discourse/lib/plugin/instance.rb:722:in `activate!'
/var/www/discourse/lib/discourse.rb:346:in `block in activate_plugins!'
/var/www/discourse/lib/discourse.rb:343:in `each'
/var/www/discourse/lib/discourse.rb:343:in `activate_plugins!'
/var/www/discourse/config/application.rb:218:in `block in <class:Application>'
/var/www/discourse/lib/plugin.rb:6:in `initialization_guard'
/var/www/discourse/config/application.rb:218:in `<class:Application>'
/var/www/discourse/config/application.rb:75:in `<module:Discourse>'
/var/www/discourse/config/application.rb:74:in `<top (required)>'
internal:/usr/local/lib/ruby/site_ruby/3.2.0/rubygems/core_ext/kernel_require.rb:37:in `require'
internal:/usr/local/lib/ruby/site_ruby/3.2.0/rubygems/core_ext/kernel_require.rb:37:in `require'
/var/www/discourse/Rakefile:7:in `<top (required)>'
/var/www/discourse/vendor/bundle/ruby/3.2.0/gems/rake-13.0.6/exe/rake:27:in `<top (required)>'
/usr/local/bin/bundle:25:in `load'
/usr/local/bin/bundle:25:in `<main>'

Caused by:
Gem::MissingSpecError: Could not find 'forwardable' (>= 1.3) among 231 total gem(s)
Checked in 'GEM_PATH=/var/www/discourse/vendor/bundle/ruby/3.2.0:/var/www/discourse/plugins/discourse-radiant-member/gems/3.2.2' , execute `gem env` for more information
/var/www/discourse/lib/plugin_gem.rb:25:in `load'
/var/www/discourse/lib/plugin/instance.rb:825:in `gem'
/var/www/discourse/plugins/discourse-radiant-member/plugin.rb:10:in `activate!'
/var/www/discourse/lib/plugin/instance.rb:722:in `instance_eval'
/var/www/discourse/lib/plugin/instance.rb:722:in `activate!'
/var/www/discourse/lib/discourse.rb:346:in `block in activate_plugins!'
/var/www/discourse/lib/discourse.rb:343:in `each'
/var/www/discourse/lib/discourse.rb:343:in `activate_plugins!'
/var/www/discourse/config/application.rb:218:in `block in <class:Application>'
/var/www/discourse/lib/plugin.rb:6:in `initialization_guard'
/var/www/discourse/config/application.rb:218:in `<class:Application>'
/var/www/discourse/config/application.rb:75:in `<module:Discourse>'
/var/www/discourse/config/application.rb:74:in `<top (required)>'
internal:/usr/local/lib/ruby/site_ruby/3.2.0/rubygems/core_ext/kernel_require.rb:37:in `require'
internal:/usr/local/lib/ruby/site_ruby/3.2.0/rubygems/core_ext/kernel_require.rb:37:in `require'
/var/www/discourse/Rakefile:7:in `<top (required)>'
/var/www/discourse/vendor/bundle/ruby/3.2.0/gems/rake-13.0.6/exe/rake:27:in `<top (required)>'
/usr/local/bin/bundle:25:in `load'
/usr/local/bin/bundle:25:in `<main>'

(See full trace by running task with --trace)
I, [2023-08-28T15:00:26.013232 #1]  INFO -- : gem install eth -v 0.5.11 -i /var/www/discourse/plugins/discourse-radiant-member/gems/3.2.2 --no-document --ignore-dependencies --no-user-install
Successfully installed eth-0.5.11
1 gem installed

I, [2023-08-28T15:00:26.014015 #1]  INFO -- : Terminating async processes
I, [2023-08-28T15:00:26.014342 #1]  INFO -- : Sending INT to HOME=/var/lib/postgresql USER=postgres exec chpst -u postgres:postgres:ssl-cert -U postgres:postgres:ssl-cert /usr/lib/postgresql/13/bin/postmaster -D /etc/postgresql/13/main pid: 42
I, [2023-08-28T15:00:26.014700 #1]  INFO -- : Sending TERM to exec chpst -u redis -U redis /usr/bin/redis-server /etc/redis/redis.conf pid: 111
2023-08-28 15:00:26.015 UTC [42] LOG:  received fast shutdown request
111:signal-handler (1693234826) Received SIGTERM scheduling shutdown...
2023-08-28 15:00:26.027 UTC [42] LOG:  aborting any active transactions
111:M 28 Aug 2023 15:00:26.030 # User requested shutdown...
111:M 28 Aug 2023 15:00:26.031 * Saving the final RDB snapshot before exiting.
2023-08-28 15:00:26.034 UTC [42] LOG:  background worker "logical replication launcher" (PID 51) exited with exit code 1
2023-08-28 15:00:26.035 UTC [46] LOG:  shutting down
111:M 28 Aug 2023 15:00:26.074 * DB saved on disk
111:M 28 Aug 2023 15:00:26.074 # Redis is now ready to exit, bye bye...
2023-08-28 15:00:26.087 UTC [42] LOG:  database system is shut down

FAILED
--------------------
Pups::ExecError: cd /var/www/discourse & su discourse -c 'bundle exec rake db:migrate' failed with return #<Process::Status: pid 1002 exit 1>
Location of failure: /usr/local/lib/ruby/gems/3.2.0/gems/pups-1.1.1/lib/pups/exec_command.rb:117:in `spawn'
exec failed with the params {"cd"=>"$home", "hook"=>"db_migrate", "cmd"=>["su discourse -c 'bundle exec rake db:migrate'"]}
bootstrap failed with exit code 1
** FAILED TO BOOTSTRAP ** please scroll up and look for earlier error messages, there may be more than one.
./discourse-doctor may help diagnose the problem.
32dfbed48cf5bbb8f9a2d25b0d75388e296cd78ce7f56d37fb7a59c543888ad1

私のリポジトリはこちらです - GitHub - JD0x2e/discourse-radiant-member: Get member status and update group membership

Gemfile.lockから取得した他のいくつかの依存関係とともに、forwardable依存関係を要求しましたが、アプリはビルド時にこのエラーを発生させずに失敗します。何かアイデアはありますか?