Install block to copy the runtime source code dependency


(Ahmet) #1

Hello, I have a formula that installs two executables (both are bash scripts, call them kubectx and kubens). These both depend on another script called utils.bash. They also have bash/zsh completion scripts. The executables live in my bin/ directory in the GitHub repository, and the utils.bash dependency is in include/ directory (am I doing this right?). So the file structure looks like this:

bin/
  - kubectx
  - kubens
include/
  - utils.bash
Formula/
  - kubectx.rb (installs both kubectx and kubens)

I load the utils.bash dependency as follows in my executables:

SCRIPT_DIR="$( cd "$( dirname $( readlink -f "${BASH_SOURCE[0]}" ) )" && pwd )"
source "${SCRIPT_DIR}/../include/utils.bash"

Now I will try creating the def install block.

You would be surprised how much lack of documentation there is out there to figure this out. Let me start just attempting because I don’t know Ruby (do I have to?):

  def install
    bin.install "bin/kubectx"
    bin.install "bin/kubens"
    include.install "include/utils.bash"
    bash_completion.install "completion/kubectx.bash" => "kubectx"
    bash_completion.install "completion/kubens.bash" => "kubens"
    zsh_completion.install "completion/kubectx.zsh" => "_kubectx"
    zsh_completion.install "completion/kubens.zsh" => "_kubens"
  end

I run brew install --build-from-source Formula/kubectx.rb, it fails wail with:

Error: No such file or directory - bin/kubectx`

Really? This file is literally there. So I guess that didn’t work… So I decided to remove bin/ prefix and now have:

    bin.install "kubectx"
    bin.install "kubens"

Now it fails with Error: No such file or directory - kubens how the hell? How could kubectx work and kubens fail? They’re literally in the same directory.

Now I will try just installing everything in bin/* altogether with bin.install Dir["bin/*"]:

Warning: tried to install empty array to /usr/local/Cellar/kubectx/0.2.0/bin

Whoops, didn’t work. How about just:

    bin.install Dir["*"]
    include.install "utils.bash"

Hah, no error about bin/ stuff. I guess I’m getting close. But I now have the error:

 Error: No such file or directory - utils.bash

Wait, so removing bin/ path prefix in bin.install worked and removing include/ prefix in include.install doesn’t work? So let’s put it back: Guess what same error with include.install "include/utils.bash".

What is going on here? Can someone please show me how to do this properly. Installing literally 2 scripts shouldn’t be this complicated. I read the entire Formula Cookbook and there are no samples of this anywhere I can find.


#2

Try running your current failing install with the addition of the flag --keep-tmp. As part of the error output should be the path to the temporary directory that the forumla was built in, and whose structure the different install steps/targets need to match.


(Ahmet) #3

I must say --keep-tmp is nice, but it’s not helpful. I observed so many weird things happening I decided to move everything to a flat structure, so I have files kubectx, kubens, utils.bash files in the root of my repository and now I have this in Formula/kubectx.rb:

  def install
    bin.install "kubectx"
    bin.install "kubens"
    include.install "utils.bash"
    ...
$  brew install --build-from-source --keep-tmp Formula/kubectx.rb
[...]
Temporary files retained at /tmp/kubectx-20170516-11463-1t6ctq4
Error: No such file or directory - kubens

When I got o the retained folder, what I see is the tree structure below, note that:

  • kubectx is gone
  • kubens is gone (and the error says it’s not found, so I guess it’s gone somehow)
  • utils.bash is gone.

I have no idea where this files went to. This is completely unintuitive.

$ tree /tmp/kubectx-20170516-11463-1t6ctq4/kubectx-0.2.0
.
├── CONTRIBUTING.md
├── Formula
│   └── kubectx.rb
├── LICENSE
├── README.md
└── completion
    ├── README.md
    ├── kubectx.bash
    └── kubectx.zsh

(Ahmet) #4

I think I figured the problem. It’s partly Homebrew’s fault

Turns out even though I was using brew install --build-from-source, it was still downloading the package from GitHub and I haven’t pushed the latest changes.

I would expect --build-from-source to actually build from my local machine and not download the package:

$ brew install --build-from-source Formula/kubectx.rb
Uninstalling kubectx... (11 files, 22.8KB)
==> Downloading https://github.com/ahmetb/kubectx/archive/v0.2.0.tar.gz
==> Downloading from https://codeload.github.com/ahmetb/kubectx/tar.gz/v0.2.0
######################################################################## 100.0%
Error: No such file or directory - kubens

Weird.


#5

The resources that a formula will use are specified in the rb file. Specifying a source build, or in the absence of bottles, brew will install the formula using those resources in combination with the install block (and postinstall block if it exists).


(Mike McQuaid) #6

You would be surprised how much lack of documentation there is out there to figure this out. Let me start just attempting because I don’t know Ruby (do I have to?)
Really? This file is literally there.
how the hell?
Installing literally 2 scripts shouldn’t be this complicated.
This is completely unintuitive.
It’s partly Homebrew’s fault

Just a heads up that your tone here will make fewer people willing to help you. Please remember you’re using a project run by volunteers almost entirely in their free time.


(Amine Zghidi) #7

Try cleaning the cache
sudo rm -rf /Users/<user_name>/Library/Caches/Homebrew/kubectx–git