Authoring a formula: installing manpage & completions

I would like modify the formula for lf to also install the manpage and zsh shell completion files that are present in the project’s repository. From what I understand, the default installation for this formula is from a bottle, which is only the binary. Is there any way to modify the formula to also install the manpage and completion files during brew install?

(for some reason I can only put 2 links in the post, here’s the zsh completion file that I’d also like to add)

The bottle contains not only binaries, but also other files (e.g. libraries, manpages, completions, etc.). Think of it more as a compiled software release that is ready to run, as opposed to, for example, a distribution of source code.

We can add the manpage and shell completions relatively easily with the addition of something like the following two lines into the install block, between lines 22-23:

man1.install "lf.1"
zsh_completion.install "etc/lf.zsh" => "_lf"

This instructs Homebrew to include lf.1 in the bottle and to symlink it into the appropriate directory for man to find. Similarly, the latter line includes lf.zsh and instructs Homebrew to symlink it into the zsh completion directory as _lf. There are similar directives for bash_completion.install ... as well, if needed.

Alright. How do I know which files from the source repository will be present in the bottle? Can I generally assume that all files present in the original project will also be in the bottle, or are only some types included?

I’ve tried what you suggested, but I’m having issues when testing it locally. When I run brew reinstall lf and try man lf, the manpage does not seem to have been copied, and the zsh completions do not work either. In particular, it seems that the install block does not run at all. However, when I do brew reinstall --build-from-source lf, everything works as expected.

It seems to me that, since Homebrew pours the bottle by default, whatever is specified in the install block doesn’t run (and I guess this is expected behavior). Is there any way to install the extra files when pouring from a bottle?

For reference, my install block contains:

def install
  ENV["GOPATH"] = buildpath
  ENV["version"] = version
  (buildpath/"src/github.com/gokcehan/lf").install buildpath.children
  cd "src/github.com/gokcehan/lf" do
    system "./gen/build.sh", "-o", bin/"lf"
    prefix.install_metafiles
    man1.install "lf.1"
    zsh_completion.install "etc/lf.zsh" => "_lf"
  end
end

Everything that something like make install would install is included in the bottle. brew reinstall reinstalls the formula in the same way that you originally installed it so that’s from a bottle in this case.

If you make a pull request for https://github.com/Homebrew/homebrew-core/ that makes this change and adds a revision 1 to the block with sha256 all users will be provided with a bottle that uses your change on their next brew upgrade

1 Like

I see. The main issues I have are:

  1. Making sure the required files (lf.zsh and the manpage) are present in the bottle. When I check the current bottle, the files are not there. Do I understand correctly that if I submit a PR with the install block above (and a revision), which requires both of those files, the files will also be in the generated bottle?

  2. Moving the files to the appropriate folders during installation (even from a bottle), e.g. using man1.install and zsh_completion.install. Similarly, if these steps are present in the install block and I create a PR, will they also be executed when installing from the generated bottle?

My aim is to install the manpage and completions file without the user needing to --build-from-source. Everything works when building from source, but my uncertainty comes from the fact that the default installation method for this formula is from a bottle, and I’m not sure how to make it work with a bottle.

As @alebcay mentioned before about bottles:

Think of it more as a compiled software release that is ready to run, as opposed to, for example, a distribution of source code.

This means that without rebuilding the bottles the content won’t change. This rebuild is done once a pull request changing the formula gets merged. The bottles are just a shortcut to bypass the source build for the way the formula is in the homebrew repo. That means they will always represent the state of the repo, no matter what you change locally. And that in turn means that if you make a local change, using the bottle won’t show your change.

Yes, I understand that. I wasn’t sure if the rebuilt bottle will ‘automatically’ also contain the manpage and completion files.

In the meantime, I dug around a bit more to see if I could test this locally. After adding a revision number, then installing with --build-bottle, and running brew bottle lf, I could see that the produced bottle does indeed contain the other files. So I will do an audit/test, and I’ll submit a PR.

Thank you very much for your help!

1 Like