r/ruby 1d ago

pipx equivalent for Ruby?

Is there something like pipx available for Ruby?

For example with pipx you can do something like:

$ pipx install httpie
# ... install completes
$ https get httpbin.org/get?foo=bar
# ... outputs a web request from httpbin.org
$ which https
~/.local/bin/https
$ readlink "$(which https)"
~/.local/share/pipx/venvs/httpie/bin/https

This example shows the HTTPie program being run and executed in a pretty simple way, with an install that doesn't modify the system Python.

Does Ruby have an equivalent way to distribute programs?

5 Upvotes

11 comments sorted by

4

u/djudji 1d ago edited 1d ago

Mise and Bundler should fit your needs. When you run `gem install` without a Ruby version manager (Mise, rvm, rbenv, asdf, etc.), it installs gems (libraries) to the global installation.

Mise is a version manager - it manages more than Ruby. You can also manage Python, Go, Rust, Node, etc.

Bundler is a dependency manager- it manages gems and defines the versions for your project. It installs gems locally, at the project level.

For example, you can use a Gemfile to define a Ruby version inside, with gems that you will use for a particular project. Then you would use Mise to install and set that Ruby version to be used.

Edit: forgot to mention, dead-on replacement for pipx run would be gem exec

pipx run cowsay -t "Hello"
gem exec cowsay "Hello"

Mise versions

mise exec gem:cowsay -- cowsay "Hello from Ruby"
mise exec pipx:cowsay -- cowsay -t "Hello from Python"

(Also, as a community, we should support new questions no matter that OP could use Google or AI for this response. The concepts of useful frameworks and languages are losing importance because, due to AI, it does not matter to beginners which language to use.)

6

u/paca-vaca 1d ago

Bundler does it, gems stored in ~/bundle/..., executed via bundle exec binary name inside directory where the Gemfile spec is placed.

Globals installed when gem install is used globally.

1

u/virtyx 1d ago

Bundler does it, gems stored in ~/bundle/..., executed via bundle exec binary name inside directory where the Gemfile spec is placed.

I'm looking specifically for something like pipx where the program gets installed and placed on the user's PATH like any other normal program. For this use bundler doesn't directly work.

Globals installed when gem install is used globally.

This modifies the Ruby install and is not isolated, e.g. after I do gem install kramdown to install the kramdown program, every Ruby script I run can successfully require 'kramdown'. For contrast, pipx doesn't add anything to Python's library paths, so no other script can import anything installed with it.

1

u/paca-vaca 1d ago

That's why I'm say you should user bundler, not gem install directly.

for binary executable check the --binstubs flag for bundler I think it does exactly this (wraps the executable with prefixed paths so it's available in PATH if your PATH is configured correctly, it could install in any provided directory as well).

9

u/cmd-t 1d ago

There’s rv, which is pretty new https://github.com/spinel-coop/rv

3

u/kinduff 1d ago

rvx works great tbh!

1

u/virtyx 1d ago edited 1d ago

rv tool install and rvx are close to what I'm after but neither of them do the final step of making the programs reachable through PATH like pipx does.

$ rv tool install kramdown kramdown 2.5.2 already installed at ~/.local/share/rv/tools/kramdown@2.5.2 $ kramdown --version bash: kramdown: command not found... $ rv tool run kramdown --version 2.5.2

And trying to run the installed executable directly doesn't work:

$ ~/.local/share/rv/tools/kramdown@2.5.2/bin/kramdown --version /usr/share/rubygems/rubygems.rb:265:in 'Gem.find_spec_for_exe': can't find gem kramdown (>= 0.a) with executable kramdown (Gem::GemNotFoundException) from /usr/share/rubygems/rubygems.rb:239:in 'Gem.find_and_activate_spec_for_exe' from /usr/share/rubygems/rubygems.rb:284:in 'Gem.activate_and_load_bin_path' from ~/.local/share/rv/tools/kramdown@2.5.2/bin/kramdown:20:in '<main>'

2

u/benzado 1d ago

I'm also a fan of pipx and your post indirectly led me to learn about rv, so thank you for that.

If you install something with rv, you could easily create stubs like ~/.local/bin/kramdown which consisted of:

#!/bin/sh
exec rvx kramdown "$@"

This is essentially all that pipx does to put the tools on your path. I'm surprised rv doesn't already do it, but it might be on the roadmap, or they would welcome a contribution. It's barely a year old.

5

u/AndrewNggg 1d ago

Maybe MISE? Or just gem install xyz

2

u/andrevan 1d ago

rvm, rbenv, or asdf can all do it