How can I deploy a simple ruby script via homebrew?
Here's what I tried
Wrote formula in a GitHub repo named homebrew-foo
# file https://github.com/foo/homebrew-foo/blob/master/foo.rb
class Foo < Formula
desc "A command line tool"
url "https://github.com/foo/foo/archive/master.zip"
version "5.0.1"
def install
bin.install "foo"
lib.install Dir["lib/*"]
end
end
The other repository contains the ruby script. These are the files
./foo
./lib/libfile1.rb
here's what the script does
#!/usr/bin/env ruby
require './lib/libfile1.rb'
puts "came here"
The problem is that the require
fails.
$ brew install foo/foo/foo
$ foo
results in this error
/Users/user1/.rbenv/versions/2.4.1/lib/ruby/2.4.0/rubygems/core_ext/kernel_require.rb:55:in
require': cannot load such file -- ./lib/libfile1.rb (LoadError) from /Users/user1/.rbenv/versions/2.4.1/lib/ruby/2.4.0/rubygems/core_ext/kernel_require.rb:55:in
require' from /usr/local/bin/foo
$ which foo
/usr/local/bin/foo
I suspect it's because the .rb file is not there at /usr/local/bin/foo/lib/libfile1.rb
Any ideas whats the proper way to do this?
I found the answer to my own question, actually it's a technique used by someone on the net, basically do something like this
And the recipe can be like this:
There are two issues with your script:
The first one is you try to
require
some file relatively to the current directory; i.e. the one from which the script is run, not the one it’s located in. That issue can be fixed by using Ruby’srequire_relative
:The second issue is the script assumes the
lib/
directory is located in its directory; which it’s not because your formula installs the script under<prefix>/bin/
and the library files under<prefix>/lib/
. Homebrew has a helper for that use-case calledPathname#write_exec_script
. It lets you install everything you need under one single directory, then create an executable underbin/
that calls your script.Your formula now looks like this:
It installs everything under
libexec/
(lib/
is usually reserved for lib files), then add an executable underbin/
that calls yourlibexec/foo
script.