Modularizing and distributing bash script via Homebrew - homebrew

Context
I have some functions defined in my ~/.bashrc which I'd like to turn into a Homebrew package. Currently, these functions act as custom commands on my command line:
# .bashrc
function foo() {
# do something interesting
}
# at terminal
$ foo
# => does the interesting thing
Approach
I've created a homebrew formula using brew create. My current approach is as follows:
Move the function definitions into a separate file, script, within a directory, brew-script
Make brew-script downloadable as a tarball, brew-script.tar.gz
Have my brew formula append text to the end of ~/.bash_profile to include script when terminal session starts
Concerns
Is modifying .bash_profile in a brew formula bad practice? (eg. when uninstalling with brew uninstall script, brew should somehow remove the text that was appended to .bash_profile... Parsing .bash_profile doesn't seem very fun.)
Is there a convention already established for including functions in bash scripts so that they are available from the command line?
Is it common to simply ask the user to add some text to their .bash_profile or .bashrc?
Desired result
Should be able to install cleanly with brew and then run foo as a command:
$ brew install script
$ foo
# => does the interesting thing
(Assume the brew formula is already installed locally. I'll worry about auditing and pushing the formula to homebrew later)

Refer https://github.com/Homebrew/homebrew/issues/50232 and https://github.com/Homebrew/homebrew/issues/50231.
I have a script that safely‡ modifies ~/.bash_profile as part of a homebrew install process. https://github.com/paul-hammant/homebrew-tap/blob/master/switchjdk.rb
‡ allegedly

Without using homebrew:
to put your bash scripts in some file such as bashrc or any other name works, then put the following line:
source "path/to/brew-script/script"
somewhere in your bash profile.
Then you just have to make sure you refresh or reload your bash profile by running . ~/.bash_profile or source ~/.bash_profile.
How homebrew installs work:
When you installed homebrew it added a line to your bash_profile that modifies your $PATH variable to include the path to the homebrew install repo, so that whenever brew installs something it becomes findable through your PATH.
If you use brew create you must have your script uploaded somewhere on the internet, because the argument brew install takes is a URL. I.e if I create my script at my_bash_function.tar.gz then I would do
brew create http://web.mit.edu/dianah13/www/my_bash_function.tar.gz
It also templates a pull request to include your package in homebrew's main repo.

Related

Anyone else get this error "Error: invalid option: --with-passenger"

Can not get NGINX to install with passenger
Following the steps you are supposed to...
brew install passenger
Then you run the following command...
brew install nginx --with-passenger
But I get:
Error: invalid option: --with-passenger
Could not find any resources about this online, so asking here.
$ brew install nginx --with-passenger
Usage: brew install [options] formula
Install formula.
formula is usually the name of the formula to install, but it can be specified
in several different ways.
-d, --debug If brewing fails, open an interactive
debugging session with access to IRB or a
shell inside the temporary build directory
--env If std is passed, use the standard build
environment instead of superenv.If super
is passed, use superenv even if the formula
specifies the standard build environment.
--ignore-dependencies Skip installing any dependencies of any
kind. If they are not already present, the
formula will probably fail to install.
--only-dependencies Install the dependencies with specified
options but do not install the specified
formula.
--cc Attempt to compile using provided
compiler. compiler should be the name
of the compiler's executable, for instance
gcc-7 for GCC 7. In order to use LLVM's
clang, use llvm_clang. To specify the
Apple-provided clang, use clang. This
parameter will only accept compilers that
are provided by Homebrew or bundled with
macOS. Please do not file issues if you
encounter errors while using this flag.
-s, --build-from-source Compile the specified formula from source
even if a bottle is provided. Dependencies
will still be installed from bottles if
they are available.
--force-bottle Install from a bottle if it exists for the
current or newest version of macOS, even if
it would not normally be used for
installation.
--include-test Install testing dependencies required to
run brew test.
--devel If formula defines it, install the
development version.
--HEAD If formula defines it, install the HEAD
version, aka. master, trunk, unstable.
--fetch-HEAD Fetch the upstream repository to detect if
the HEAD installation of the formula is
outdated. Otherwise, the repository's HEAD
will be checked for updates when a new
stable or development version has been
released.
--keep-tmp Don't delete the temporary files created
during installation.
--build-bottle Prepare the formula for eventual bottling
during installation.
-f, --force Install without checking for previously
installed keg-only or non-migrated
versions.
-v, --verbose Print the verification and postinstall
steps.
--display-times Print install times for each formula at the
end of the run.
-i, --interactive Download and patch formula, then open a
shell. This allows the user to run
./configure --help and otherwise
determine how to turn the software package
into a Homebrew package.
-g, --git Create a Git repository, useful for
creating patches to the software.
-h, --help Show this message.
Error: invalid option: --with-passenger
This is supposed to work... so yeah.
A late answer. Obviously the documentation on the passenger site is outdated at time of this writing.
According to phusion's github site
https://github.com/phusion/passenger/issues/2187#issue-416881033
the config option --nginx-with-passenger is not valid anymore.
Instead do:
brew install nginx passenger
Addendum:
When using google search for results currently the old page comes up at the top of the list. Here's the currently maintained page with the accurate information:
https://www.phusionpassenger.com/docs/advanced_guides/install_and_upgrade/nginx/install/oss/osx.html

Can I brew link only files without conflicts?

Is there a way to brew link just those files without conflicts?
As near as I can tell, the only options are to force an overwrite of all conflicting roles, or to link no files at all. For example I have an existing compare that I need to keep, but need ImageMagick's convert. When I brew install imagemagick I get
Error: The `brew link` step did not complete successfully
The formula built, but is not symlinked into /usr/local
Could not symlink bin/compare
Target /usr/local/bin/compare
already exists. You may want to remove it:
rm '/usr/local/bin/compare'
To force the link and overwrite all conflicting files:
brew link --overwrite imagemagick
To list all files that would be deleted:
brew link --overwrite --dry-run imagemagick
Possible conflicting files are:
/usr/local/bin/compare -> /Applications/Araxis Merge.app/Contents/Utilities/compare
But the only way offered to proceed is either to leave all of ImageMagick unlinked, or to overwrite my existing compare.
How do I brew link everything but the existing compare? Is there a way to install only convert perhaps?
Here's a shell function I wrote to do this (for the zsh that's now standard on macOS, but it will run on Bash with small adjustments 1):
local targetdir
targetdir=($(brew --cellar $1)/*/bin) || return
local linksdir=$(brew --repo)/bin
for ex in "$targetdir"/*(^/) # files (and symlinks), not subdirectories
do
local exname=${ex##*/}
if builtin which "$exname" &>/dev/null
then
echo " $exname already available in the path - skipped"
else
ln -s "$ex" "$linksdir/" && echo "$exname linked from $linksdir"
fi
done
I saved it as a shell function called blink and when I call it with a package name, like
blink binutils
it symlinks only the binaries whose names aren't already available in the $PATH.
1The adjustments to make it work on Bash: remove the final (^/) form the for ex... line, and the builtin 3 lines further down.

'Zsh: command not found: valet' - unable to install Valet

I just tried installing valet for a very long time, - and I couldn't find any help anywhere. No matter what I tried, then it kept saying:
Zsh: command not found: valet
I'm running Zshell (instead of Bash) and OSX. I've had Brew installed for quite a while.
I'll answer this myself, - so hopefully people in the same situation can find this in the future.
I had a very similar problem under Zsh, but my solution was easier. Rather than adding ~/.composer/vendor/bin to my $PATH, I needed to use the full directory name; i.e., /Users/[your-user-name]/.composer/vendor/bin.
Everywhere it says to 'Check that your path is right'. And yup - if you haven't done that, then you should start there. The easiest way is to go to your terminal and write:
echo $PATH
... And then you should see ~/.composer/vendor/bin in between two colons in there. If that isn't there, then you should go to your ~/.bashrc-file (or ~/.zshrc-file) and add this line:
export $PATH=~/.composer/vendor/bin:$PATH
And then it may be fixed.
My problem had deeper roots, though. Even though my path was right, then I still got the error:
Zsh: command not found: valet
And if I wrote: which valet - then it (obviously) just responded with valet not found.
Removal of Composer
What fixed it was to remove all my composer-installations. Composer can be located in several different locations (and installed by brew). So in order to remove it, then do this (inspired by this post, but it lacks a couple of steps):
Remove your composer- or -composer.phar-file. You can find them by running which composer and/or which composer.phar.
Remove your .composer-folder (usually located here: ~/.composer).
Then make sure that there isn't an installation done with Homebrew (this was what I think made the collision for me). You do it by running brew unlink composer followed by brew remove composer.
Then, - if you want to be 100% sure that it's all gone, then go to your root (cd /) and run this command: find ./* -name 'composer.phar' and this find ./* -name 'composer'. That should tell you of all the locations where the Composer-installation can be installed.
When all that's removed, then you should be rid of Composer (entirely).
... Then install it again, - and see if you can get valet to work (it did for me).
The solution was adding composer bin to the path. You can use the following commands
From the terminal
export PATH="$PATH:$HOME/.composer/vendor/bin"
echo 'export PATH="$PATH:$HOME/.composer/vendor/bin"' >> ~/.bash_profile
source ~/.bash_profile
valet install
Issue Ubuntu: no command valet
Valet on Ubuntu:
sudo apt install libnss3-tools jq xsel
composer global require cpriego/valet-linux
.composer/vendor/cpriego/valet-linux/valet install
Now command valet should work, but if still not:
sudo cp .composer/vendor/cpriego/valet-linux/valet /usr/local/bin/

Can I change Homebrew's prefix?

Somehow, my Homebrew install has a prefix of ~/.rvm. I'd like to set it to the default of /usr/local.
Is this possible?
For the benefit of anyone who's had to do a manual install of Homebrew.
Taking a look at the actual brew file is the line:
HOMEBREW_PREFIX="${HOMEBREW_BREW_FILE%/*/*}"
It turns out it gets the prefix automatically from the parent directory of the install location, unless;
# Try to find a /usr/local HOMEBREW_PREFIX where possible (for bottles)
if [[ -L "/usr/local/bin/brew" ]]
then
USR_LOCAL_BREW_FILE_DIRECTORY="$(symlink_target_directory "/usr/local/bin/brew" "/usr/local/bin")"
USR_LOCAL_HOMEBREW_REPOSITORY="${USR_LOCAL_BREW_FILE_DIRECTORY%/*}"
if [[ "$HOMEBREW_REPOSITORY" = "$USR_LOCAL_HOMEBREW_REPOSITORY" ]]
then
HOMEBREW_PREFIX="/usr/local"
fi
fi
This'll grab the prefix value from the parent directory of any symlink to the brew executable so long as the Homebrew install directory is down stream from that directory (like /usr/local/Homebrew)
If you've manually installed directly into the usr/local/ directory, you'll still want to go and put a symlink in the usr/local/bin folder to your Homebrew/bin/brew executable to get the correct prefix path. That'll also avoid you needing to add the Homebrew/bin folder directly to your $PATH as well.
Some of Homebrew's bottles (binary packages) can only be used with the default
prefix (/usr/local) like e.g. rust. But if you still want to install it with a different prefix, then use:
arch -arm64 brew install rust
If you want to know, which prefix you already using:
brew config | grep HOMEBREW_PREFIX
In my case it is HOMEBREW_PREFIX: /opt/homebrew
Looks like I need to
Uninstall Homebrew. Here's a script to help
Reinstall it, using the desired prefix
Reinstall all my formulae
I got a list of my current formulae with brew list.
Can you not set it with brew --prefix <prefix> ?
Running just brew --prefix will return the current prefix. I am assuming you are getting the common warning about the prefix in brew doctor.

How to remove the existing environment variable in Linux?

This is my machine path :
~$ echo $PATH
/home/sam/.rvm/gems/ruby-2.1.2/bin:/home/sam/.rvm/gems/ruby-2.1.2#global/bin:/home/sam/.rvm/rubies/ruby-2.1.2/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/home/sams/.rvm/bin:/usr/local/bin
Here, I want to remove all the paths related to rvm
I removed all the above lines from .bashrc and .bash_profile but still it exists in the GEM_PATH where else it is erased from the common PATH
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
check:
echo $PATH
you can add the export code inside .bashrc
The first place to look for alternations in the $PATH variable would be your .bashrc file. Look for something like:
export PATH=/your/homefolder/.rvm:$PATH
Another thing worth asking, do you have this behaviour on startup of the system or is it just in one local shell window? If it's only in the current shell session (and not in the .bashrc or something similar), it will not stick/be permanent.
You can manually overwrite your PATH through exporting it again, but that only affects the current session.
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
If you want the change to last, you have to find where the rvm parts are added to the PATH variable. That's probably at the end of the ~/.bashrc (or ~/.profile, or ~/.bash_profile, or /etc/profile, .. it depends on how you installed rvm) file. You can safely remove those lines that add rvm to the path.
In case you also want to uninstall rvm (which I suspect if you go the second route), do a
rvm implode
To remove Rvm, run
$ rvm implode
Are you SURE you wish for rvm to implode?
This will recursively remove /Users/gaurish/.rvm and other rvm traces?
(anything other than 'yes' will cancel) > yes
Removing rvm-shipped binaries (rvm-prompt, rvm, rvm-sudo rvm-shell and rvm-auto-ruby)
Removing rvm wrappers in /Users/gaurish/.rvm/bin
Hai! Removing /Users/gaurish/.rvm
This will remove RVM & its entire from your path.
ANd if you want to keep rvm or have already removed it manually. Now, just want to get rid of the rvm related entries from PATH. find this line which is responsible for adding rvm to your path:
PATH=$PATH:$HOME/.rvm/bin # Add RVM to PATH for scripting
using grep
$ grep -nr 'PATH=$PATH:$HOME/.rvm/bin # Add RVM to PATH for scripting' ~
Now, you will have the list of files along with line number that contain this line. you can ignore any entries in history. Mainly focus on entires in ~/.bashrc, ~/.profile, ~/.zshrc and other config files. And remove each of those

Resources