Solargraph 0.56.2 not finding prism on Arch Linux
I package solargraph in the AUR; For some reason, solargraph fails to find prism.rb, which seems to be a part of the standard ruby package:
# pacman -F prism.rb
extra/ruby 3.4.5-1 [installed]
usr/lib/ruby/3.4.0/prism.rb
# solargraph
/usr/lib/ruby/3.4.0/rubygems/specification.rb:1421:in 'block in Gem::Specification#activate_dependencies': Could not find 'prism' (~> 1.4) among 93 total gem(s) (Gem::MissingSpecError)
Checked in 'GEM_PATH=/home/rubin/.local/share/gem/ruby/3.4.0:/usr/lib/ruby/gems/3.4.0' at: /usr/lib/ruby/gems/3.4.0/specifications/solargraph-0.56.2.gemspec, execute `gem env` for more information
from /usr/lib/ruby/3.4.0/rubygems/specification.rb:1407:in 'Array#each'
from /usr/lib/ruby/3.4.0/rubygems/specification.rb:1407:in 'Gem::Specification#activate_dependencies'
from /usr/lib/ruby/3.4.0/rubygems/specification.rb:1389:in 'Gem::Specification#activate'
from /usr/lib/ruby/3.4.0/rubygems.rb:290:in 'block in Gem.activate_bin_path'
from /usr/lib/ruby/3.4.0/rubygems.rb:289:in 'Thread::Mutex#synchronize'
from /usr/lib/ruby/3.4.0/rubygems.rb:289:in 'Gem.activate_bin_path'
from /usr/bin/solargraph:25:in '<main>'
It seems to me this happens because the packaged prism.rb is in /usr/lib/ruby/3.4.0 which is not in GEM_PATH (which contains $HOME/.local/share/gem/ruby/3.4.0 and /usr/lib/ruby/gems/3.4.0).
I've run into something similar before, but I can't for the life of me figure out why ruby is packaged this way. I previously filed a similar issue in the Arch Linux bug tracker, that one in relation to benchmark.rb, but that issue has not been acted on as far as I can tell. Maybe someone with more Ruby experience can chime in as to what's up here? Is this actually a packaging mistake? Or did ruby change something that gem is not aware of and should be?
@rubin55: By chance would you be able to put together a Dockerfile which reproduces this?
@apiology I think something similar like this needs to happen for solargraph; apparently, prism became a "default" gem with version 3.3 of ruby, which afaict means that you can't just include it as a dependency in the gemspec.
Hmmm, help me understand how that PR and issue are applicable? Either way a Dockerfile is worth 1,000 words :)
edit: Also, does this happen when you 'bundle install' and run solargraph under 'bundle exec'?
No it shouldn't, because afaik, bundle install would install the gems in a subdir locally, for solargraph to use, including prism, when you would use bundle exec to execute. This issue would only occur when solargraph is installed through a package manager like pacman or rpm.
The link to the PR from rubocop-ast illustrates that you don't need to specify prism in a gemspec anymore since ruby 3.3, because it is now a default/standard (?) gem that is a part of the ruby distribution. The PR further shows that they conditionally check if prism is require'able, and printing an error message if not, probably to deal with older versions of ruby which would require prism to be installed as a gem.
I tested solargraph in SublimeText, with a removed prism gemspec (and, coincedentally, an upgraded rbs, to 3.8.0) and stuff seems to work as expected, fwiw.
when solargraph is installed through a package manager like pacman or rpm
Aha! I missed that part. Can you point me to the package you are installing? Yeah, that makes sense - they probably swept through and removed the explicit prism package from their OS package collection.
The PR further shows that they conditionally check if prism is require'able, and printing an error message if not, probably to deal with older versions of ruby which would require prism to be installed as a gem.
FWIW, they added it back - there's more nuance in the issue than I'd want to try to express here, but take a look towards the lower parts of that issue you pointed to: https://github.com/rubocop/rubocop-ast/blob/master/rubocop-ast.gemspec#L37
Once I take a look at the Arch Linux package and compare how they packaged up rubocop we can figure out what the core issue is and what the Arch Linux way to resolve it is.
OS packages of gems are usually modified a bit for these types of reasons that things like 'gem' and 'bundler' handle more automatically for you. My guess is that their automated tests for rubocop are a little more robust than their tests for solargraph and so they forgot to patch their solargraph packaging to deal with this situation when they retired the prism package in favor of the stdlib/core version. But that's just a guess.
I'm the maintainer of the ruby-solargraph AUR package :-). It's here: https://aur.archlinux.org/packages/ruby-solargraph
Got it!
You can see how the current gem version of rubocop-ast /does/ require prism, with the same version constraint we do: https://rubygems.org/gems/rubocop-ast/versions/1.46.0
I see that the rubocop-ast arch package does not address this issue as it hasn't been upgraded past the first version which uses prism: https://gitlab.archlinux.org/archlinux/packaging/packages/ruby-rubocop-ast/-/blob/main/PKGBUILD?ref_type=heads
The version provided by Ruby 3.4.4 is "1.2", which doesn't meet this constraint. Maybe we don't need 1.4; maybe rubocop-ast doesn't need 1.4, I don't know - @castwide might have some insight. But even the upcoming RBS 4.0 release requires >=1.3.0:
$ gem info prism
*** LOCAL GEMS ***
prism (1.2.0)
Author: Shopify
Homepage: https://github.com/ruby/prism
License: MIT
Installed at (default): /Users/broz/.rbenv/versions/3.4.4/lib/ruby/gems/3.4.0
Prism Ruby parser
$ ruby --version
ruby 3.4.4 (2025-05-14 revision a38531fd3f) +PRISM [arm64-darwin24]
$ grep prism ../rbs/rbs.gemspec
spec.add_dependency "prism", ">= 1.3.0"
$
If you'd like to move forward with the remove-prism-gemspec.patch solution instead of adding a more modern prism package, just be aware that we are very likely to use RBS 4.x features when available and your users will miss out on those. I'd also be careful with some of the features/fixes introduced in Prism 1.3+.
https://github.com/ruby/prism/releases/tag/v1.4.0
We use the parser gem compatibility mode, so beware the Many, many compatibility fixes for the parser translation layer entry - maybe you could add a check() block like this to at least run our test suite against it?
Our biggest area of perf is Ruby parsing (why we moved to Prism), so I'd also be careful of perf differences.
Best of luck with your quest and appreciate you for keeping our package up to date! Teaching package managers to play nice with each other is never fun.
The problem with providing a more modern ruby-prism package (that, I suppose, would automagically override the ruby-provided prism), is that the ruby package in Arch Linux now provides, replaces and conflicts ruby-prism, effectively meaning that no package can be named ruby-prism that would not immediately run afoul with the ruby package :-( (this is due to the replaces and conflicts - the provides are fine)
Is/should it be technically "normal" and possible to install ruby-prism v1.4.x on a system that has ruby with a ruby-provided prism? How does ruby deal with that?
I am beginning to think that those replaces and conflicts entries of the ruby package of Arch Linux are wrong..
PS, see: https://archlinux.org/packages/extra/x86_64/ruby/
The problem with providing a more modern ruby-prism package (that, I suppose, would automagically override the ruby-provided prism), is that the ruby package in Arch Linux now provides, replaces and conflicts ruby-prism, effectively meaning that no package can be named ruby-prism that would not immediately run afoul with the ruby package :-( (this is due to the replaces and conflicts - the provides are fine)
Hmmm, yeah - if I'm understanding this right, the friction is that gem and bundler have the ability to manage multiple versions of the same package, whereas the OS packager's constraint is to find one set of versions that is least-worst for everyone :)
Disclaimer: I don't pretend to understand how replaces and conflicts work, so take the rest with a grain of salt.
Another potential solution would be to bodge a version into the name - e.g., ruby-prism-1-4 or something like that, and allow modern rubocop and solargraph to depend on that. You can see that (for slightly different reasons) with the aws-cli and aws-cli-v2 packages.
Is/should it be technically "normal" and possible to install ruby-prism v1.4.x on a system that has ruby with a ruby-provided prism? How does ruby deal with that?
Yep, that's pretty normal. The .gemspec file for the gem is used at ruby-start-time to determine the best mix of gems to "activate" recursively through all of the gems and their dependencies, so each program will use the best version it can without violating any "<=" constraints or the like.
The gem install command will install any dependencies which is not currently at its latest supported version. You can pass "--conservative" to avoid upgrading existing things which do meet the constraint but maybe aren't the very latest version.
Oh, yeah, for the status quo solution, one other thing to double check would be the rubocop dependency - you're providing it a version which doesn't meet our constraint. Again, not entirely sure the implications and would welcome thoughts from @castwide, but we use rubocop as part of the LSP.
For what it's worth, all of the current specs pass after forcing the use of the system prism:
broz@Mac:~/src/solargraph$ sed -i.bak "s/'rubocop', '~> 1.76'/'rubocop'/g" solargraph.gemspec # settle for any old version at runtime
broz@Mac:~/src/solargraph$ sed -i.bak "s/ s.add_development_dependency 'rubocop', '~> 1.80.0.0'//g" solargraph.gemspec # same at dev time, since we're in a dev checkout
broz@Mac:~/src/solargraph$ bundle update
Fetching gem metadata from https://rubygems.org/.........
Resolving dependencies...
Fetching prism 1.2.0 (was 1.4.0)
Fetching rubocop-ast 1.42.0 (was 1.46.0)
Installing rubocop-ast 1.42.0 (was 1.46.0)
Installing prism 1.2.0 (was 1.4.0) with native extensions
Fetching rubocop 1.74.0 (was 1.80.0)
Installing rubocop 1.74.0 (was 1.80.0)
Bundle updated!
1 installed gem you directly depend on is looking for funding.
Run `bundle fund` for details
broz@Mac:~/src/solargraph$ bundle info prism
* prism (1.2.0)
Summary: Prism Ruby parser
Homepage: https://github.com/ruby/prism
Source Code: https://github.com/ruby/prism
Changelog: https://github.com/ruby/prism/blob/main/CHANGELOG.md
Path: /Users/broz/.rbenv/versions/3.4.4/lib/ruby/gems/3.4.0/gems/prism-1.2.0
Reverse Dependencies:
solargraph (0.56.2.pre.post) depends on prism (= 1.2)
broz@Mac:~/src/solargraph$ rm .rubocop.yml && bundle exec rspec # don't let new config syntax confuse the older rubocop
[...]
Finished in 1 minute 37.94 seconds (files took 0.54743 seconds to load)
1428 examples, 0 failures, 39 pending
Coverage report generated for ad-hoc to /Users/broz/src/solargraph/coverage/ad-hoc.
Line Coverage: 94.25% (9318 / 9886)
broz@Mac:~/src/solargraph$
Anyway, all of these dilemmas are pretty common in the OS packaging world - any solutions that look perfect have swept something or other under the rug ;)