[engine] Never evaluate executables relative to cwd

`exec.ErrDot` is the error that `exec.LookPath()` returns when it fails
to look up an executable on $PATH, but finds it in the current working
directory. Notably, the current working directory may be outside the
project root (if the "--root" flag is set), in which case the current
working directory lookup is undesirable, as shac checks should only
depend on tools in $PATH or in the checkout. Therefore, it should be
considered an error if an executable is not found on $PATH.

This means that commands like "foo.sh" that refer to a script in the
repository root must use "./foo.sh" or an absolute path. If that becomes
a pain for users, we could add a check to see if the file exists in the
repository root before falling back to looking it up on $PATH.

Change-Id: I6f3d5555c826c1492a3f40583cfd2ed04ed9b9ce
Reviewed-on: https://fuchsia-review.googlesource.com/c/shac-project/shac/+/909879
Reviewed-by: Marc-Antoine Ruel <maruel@google.com>
Commit-Queue: Auto-Submit <auto-submit@fuchsia-infra.iam.gserviceaccount.com>
Fuchsia-Auto-Submit: Oliver Newman <olivernewman@google.com>
diff --git a/internal/engine/runtime_ctx_os.go b/internal/engine/runtime_ctx_os.go
index 7c328b1..b3dfb3f 100644
--- a/internal/engine/runtime_ctx_os.go
+++ b/internal/engine/runtime_ctx_os.go
@@ -300,8 +300,12 @@
 			// unconditionally.
 			fullCmd[0] = filepath.Join(s.root, s.subdir, fullCmd[0])
 		} else {
+			// If the first element of the command is a single path element like
+			// "foo" or "foo.sh", use $PATH to evaluate it. Local executables in
+			// the root of the repository must use the "./foo.sh" form or
+			// absolute paths.
 			fullCmd[0], err = exec.LookPath(fullCmd[0])
-			if err != nil && !errors.Is(err, exec.ErrDot) {
+			if err != nil {
 				return nil, err
 			}
 		}