Support exclusions in inputs (#4066)
### Description
- Support exclusion globs (`!some-glob`) in `inputs` specifications
- Modify file hashing for a package to only consider `git status` in the
case where we aren't using `inputs`. `inputs` already uses `git
hash-object` which operates on the state of the working tree, as opposed
to `git ls-tree` which operates on a particular commit. This
additionally fixes an issue where a dirty file not included in `inputs`
could get included in the hash.
- Fix manual file hashing to use the correct prefix on globs (and to
support exclusions)
- Modify globby to allow excluding individual files, not just
directories
We have behavior to force excludes in globby to apply to directories,
but AFAICT we don't document this behavior. Our existing documentation
of excludes in `outputs` uses `**`. My preference would be to drop it so
that we have a unified globbing syntax. However, my code here
special-cases user input that ends in `**` to maintain both behaviors.
### Testing Instructions
A new integration test uses `inputs` with an exclusion to exclude a file
from the hash. The excluded file is modified in the test, then hash
matching and full turbo are verified.
Globby has a new test as well for excluding a single file, vs a
directory.
`taskhash_test.go` has an additional edge case to handle excluding files
in `inputs` specifications that fall back to manual file hashing.
Fixes #1407