Private Tap - Noob question about accessing directories copied over in formula

(Tom Yates) #1

Hello, I’ve created a private tap so I can distribute a collection of bash scripts and files to other developers in our organisation.

I’ve got the script company-script installing fine using the following formula:

class CompanyTools < Formula
  desc "Company Tools"
  homepage "<project url>"
  url "", :using => :git
  version "0.04"
def install
    bin.install "company-script"
    prefix.install "include" 

Once it’s installed, I can run company-script from any directory as expected as I assume it’s been sym-linked to /usr/local/bin

But, how can I now access installed files in the include folder from within the company-script?
Do I trust that they will always exist in: /usr/local/Cellar/company-tools/0.04/include/ or should I be somehow setting an environment variable for accessing the include folder during the install process?

Thanks for any help.

(Mike McQuaid) #2

Use /usr/local/opt/company-tools/include or a relative path within the script based on the company-script location.

(Tom Yates) #3

Thanks Mike!

Also used DIRECTORY="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

(Paulo Zenida) #4

Hello there.

I’m trying something similar too but I could not find the appropriate way to refer to the files that go into /usr/local/opt/…

How did you DIRECTORY in your bash script?

By the way, in my case, I’m trying to make the script work not only in brew but also in a regular shell script way, in Linux.

My project’s structure is the following:

  • folder1
    • file1
    • file2
  • folder2

Can you help, please?


(Tom Yates) #5

Hi PZ,

I use it the following way:
DIRECTORY="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

This gives you the director of where your script lives, so you could access other files in your package in the following way:

Then in the script you can access a file from your bash script $DIRECTORY/folder1/file2

(Paulo Zenida) #6

Hi Tom,

Ok, I’ll give it a try as soon as I can :slight_smile:

Thanks and take care,
Paulo Zenida

(Paulo Zenida) #7

Hi Tom,

echo $DIRECTORY as it was defined, points to /usr/local/bin so, something like $DIRECTORY/folder1/file1 will try to access /usr/local/bin/folder1/file1 which does not exist.

Installing with prefix.install “folder” will result in the script in /usr/local/opt/…/folder1/file1

Did you use prefix.install or did you do something else?


(Paulo Zenida) #8

I have implemented this a little bit differently. Namely, I have followed more or less this formulae (, which ended in an install step like the following:

def install
    # Create a folder named cli in /usr/local/opt/myproject-cli
    cli_subdir_path = (prefix / "cli")

    # Copy all folders containing the code into /usr/local/opt/myproject-cli/cli
    # Copy the to /usr/local/opt/myproject-cli/cli (this way, we mimic the project in the brew installation and so, relative paths just work as expected)
    cli_subdir_path.install("myscript" => "myscript")

    # Make a link to the previously installed file
    bin.install_symlink Dir["#{cli_subdir_path}/myscript"]

and the trick for me was to make sure DIRECTORY always points to the real path of each file so that, in the end, the folder where the script is being executed is in the target folder, like so:

while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
    BASE_PATH="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
    SOURCE="$(readlink "$SOURCE")"
    [[ $SOURCE != /* ]] && SOURCE="$BASE_PATH/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
BASE_PATH="$( cd -P "$( dirname "$SOURCE" )" && pwd )"

and then, anytime I need to access some file, I prefixed it with $BASE_PATH. E.g.,

source $BASE_PATH/folder1/file1