Feature request: Hint at new location of migrated formulae
==========================================================
*I'm simply copying the proposal from https://github.com/Homebrew/brew-evolution/pull/15, since [brew-evolution is being deprecated](https://github.com/Homebrew/brew-evolution/pull/25).*
## Hint at new location of migrated formulae
### Introduction
Users are confused when trying to install formulae known to have existed [1], yet getting the "No available formula" error due to said formulae having been migrated to another tap that has not been tapped. This proposal attempts to make the experience less confusing.
### Motivation
When a formula `foo` is migrated to another tap, subsequent attempts to show info or install it produce the unhelpful error
```
Error: No available formula with the name "foo"
```
This error is particularly confusing when it is known to the user that the formula once existed.
Meanwhile, knowledge about where `foo` was migrated to is already preserved in `tap_migrations.json` of the former home of `foo`, so we can encourage the user to look for `foo` in its new home.
Note that currently `install` (but not `info`) follows up the "No available formula" error with a search, but the experience is bad for several reasons:
- `brew search` does not search in homebrew/boneyard, which accounts for half of the migrations from core;
- `brew search` is slow, especially for connections with high latency;
- Without GitHub credentials in system keychain or `HOMEBREW_GITHUB_API_TOKEN`, a user can only search for three or four times before they hit the hourly API rate limit.
### Proposed solution
When a formula is not found when running `brew info` or `brew install`, search `tap_migrations.json` in installed taps and if a matching entry is found, hint at the new location.
### Detailed design
Suppose a formula `foo` was migrated from the `alice/tap` tap to the `bob/pat` tap and hence there is an entry `"foo": "bob/pat"` in `Library/Taps/alice/tap/tap_migrations.json`, the "No available formula" error message could instead be
```
Error: No currently available formula with the name "foo".
A "foo" formula was migrated from alice/tap to bob/pat. You may want to try
brew install bob/pat/foo
```
Note that the suggested command(s) should match the user's action, so if the user was attempting `brew info`, the command(s) should instead be
```
brew tap bob/pat
brew info foo
```
When matches are found in `tap_migrations.json` of multiple taps, multiple hints may be printed.
When a match indicates migration to `homebrew/boneyard`, we may want to print a special warning.
In all cases where a match is found in the migration records, `install` should not initiate a search.
### Alternatives considered
1. One could point a user to http://braumeister.org/formula/foo which documents the history of a core formula even if it was migrated. Even better, it links to each relevant commit which is especially helpful for finding out why a formula was boneyarded. However, there are three major issues with this approach:
- Most "No available formula" errors are for legitimately never-existent formulae;
- braumeister.org only indexes core formulae;
- braumeister.org is operated by a third party.
2. One could also ask a user to try `brew log foo`, which is also capable of turning up relevant commits, but this approach suffers from two problems:
- Again, most "No available formula" errors are legit;
- `brew log foo` may not turn up useful information on a shallow clone, which is what most users have on their system.
### References
[1] http://community.brew.sh/t/there-is-no-longer-a-clang-omp-formula-for-macos-sierra/47
1. `time` is not a builtin, it's a reserved word used to form a complex command. Meanwhile, `times` is a very different builtin defined by POSIX (called a special built-in utility by POSIX, see [doc](http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_27)), which doesn't take any argument and prints the accumulated times in the shell.
2. There's a POSIX utility `time` (see [doc](http://pubs.opengroup.org/onlinepubs/9699919799/utilities/time.html)), fulfilled by `/usr/bin/time` on macOS. `gnu-time` duplicates this role, just like `coreutils` duplicates most other POSIX utilities.
3. `time` as a shell keyword/reserved word (different jargon for different shells) is very widespread, because timing implemented in the shell is more accurate and versatile. For instance, `time` is a reserved word in `zsh` and `mksh`, and a keyword in `bash` and `ksh93`. It's certainly not limited to `zsh`, and `time` as a shell reserved word masking the external utility `time(1)` is extremely common. If you really want to use the `time` executable (not sure why), probably the "correct" way is `command time` (you can alias `time` to `command time` if you want to), as opposed to disabling a reserved word.
In summary, reserved word `time` masking external `time(1)` is a common in most modern interactive shell usage; certainly not Homebrew specific. It doesn't deserve a mention in caveats.
Implemented in 00fd37eefdc06da4176f062360002d6b2546e587. Site refreshed in fd76fedaa6047ca6904d2cd38609b373a148b5b3. Released in say 0.4.0 62ebf82b2e1b55e80e91875fcc7bc947b3849547.