how to distribute a ruby script via homebrew
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’s require_relative
:
#!/usr/bin/env ruby
require_relative './lib/libfile1.rb'
puts "came here"
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 called Pathname#write_exec_script
. It lets you install everything you need under one single directory, then create an executable under bin/
that calls your script.
Your formula now looks like this:
class Foo < Formula
desc "A command line tool"
url "https://github.com/foo/foo/archive/master.zip"
version "5.0.1"
def install
libexec.install Dir["*"]
bin.write_exec_script (libexec/"foo")
end
end
It installs everything under libexec/
(lib/
is usually reserved for lib files), then add an executable under bin/
that calls your libexec/foo
script.
Creating a Homebrew formula for standalone application
You can either modify your script at install time to use the correct location of the resource or just assume it’s in the same directory and let Homebrew do the magic for you. I wrote an example formula for the latter case in another answer.
Here’s how it looks like for your needs:
class Foo < Formula
desc "Blah blah"
url "https://github.com/foo/foo/archive/master.zip"
version "1.2.3"
def install
man1.install "myapp.1"
libexec.install Dir["*"]
bin.write_exec_script (libexec/"myapp.py")
end
end
It installs myapp.1
in the correct directory. You can also use man2
, man3
, etc for other man
directories.
It then installs all the remaining files under libexec
then create an exec
script in bin/myapp.py
. This will be a simple shell script that exec
s your script in libexec
. That way, your script will executes from libexec
and thus will be able to find resource.txt
that’s located in the same directory.
If you’d like to call it myapp
and not myapp.py
it’d look like that:
def install
man1.install "myapp.1"
libexec.install "resource.txt"
libexec.install "myapp.py" => "myapp"
bin.write_exec_script (libexec/"myapp")
end
How to create homebrew formula with only scripts
There are two cases here:
Standalone Scripts
Install them under bin
using bin.install
. You can optionally rename them, e.g. to strip the extension:
class MyFormula < Formula
# ...
def install
# move 'myscript.sh' under #{prefix}/bin/
bin.install "myscript.sh"
# OR move 'myscript.sh' to #{prefix}/bin/mybettername
bin.install "myscript.sh" => "mybettername"
# OR move *.sh under bin/
bin.install Dir["*.sh"]
end
end
Scripts with Support Files
This case is tricky because you need to get all the paths right. The simplest way is to install everything under #{libexec}/
then write exec
scripts under #{bin}/
. That’s a very common pattern in Homebrew formulae.
class MyFormula < Formula
# ...
def install
# Move everything under #{libexec}/
libexec.install Dir["*"]
# Then write executables under #{bin}/
bin.write_exec_script (libexec/"myscript.sh")
end
end
Given a tarball (or a git repo) that contains the following content:
script.sh
supportfile.txt
The above formula will create the following hierarchy:
#{prefix}/
libexec/
script.sh
supportfile.txt
bin/
script.sh
Homebrew creates that #{prefix}/bin/script.sh
with the following content:
#!/bin/bash
exec "#{libexec}/script.sh" "$@"
This means that your script can expect to have a support file in its own directory while not polluting bin/
and not making any assumption regarding the install path (e.g. you don’t need to use things like ../libexec/supportfile.txt
in your script).
See this answer of mine for an example with a Ruby script and that one for an example with manpages.
Note Homebrew also have other helpers to e.g. not only write an exec
script but also set environment variables or execute a .jar
.
Installing Ruby with Homebrew
in ~/.bash_profile
add the following line
export PATH=/usr/local/Cellar/ruby/1.9.3-p194/bin:$PATH
When you're done, close your terminal and re-open it. You should be fine.
Alternatively, you can execute the follwing in each open shell instead of closing/re-opening:
source ~/.bash_profile
Note:
I highly recommend installing ruby via rvm or rbenv so you can manage multiple ruby versions and use gemsets.
Java Homebrew installation
I encountered this error. The fix is to run the command sudo chown -R $USER:admin /usr/local/*
as described on the Tech Stacker blog post that solves this issue.
Related Topics
Instance_Eval Does Not Work with Do/End Block, Only with {}-Blocks
Http.Post_Form in Ruby with Custom Headers
How to Iterate Through This JSON Document Using Ruby
"/#Action" Route in Routes.Rb in Ruby on Rails
Open-Uri Is Not Redirecing Http to Https
How to Turn Off Bigint Primary Keys in Rails 5.1
How to Http Post Stream Data from Memory in Ruby
Chrome Asks to "Select a Certificate" for Ssl on My Rails App Using Thin
How to Use Multiple Models for Tag_Cloud
Fresh Rails App Defaulting to Postgres Instead of SQLite3
What Is a More Ruby-Like Way of Doing This Command
How to Serialize a Ruby Digest::Sha1 Instance Object
How to Deal with a Page Which Fails to Load and Continue Testing in Watir-Webdriver
Actionmailer Smtp "Certificate Verify Failed"
Accessing a Ruby Hash with a Variable as the Key
Permanently Switching User in Capistrano 3 (Separate Authorization & Deploy)
Ruby Syntax Question: Rational(A, B) and Rational.New!(A, B)