build/toolbase: init
In an effort to better the developer/CI experience, I'm moving some of
our presubmit checks into a Go tool. This is a helper library that will
be used to interact with a Monogon workspace checkout from Go, both in
the new presubmit tool but also any other future tools that would like
to operate on source code.
Change-Id: Ie5f1b1d0153a1c853c241e167d2d3a469c636c94
Reviewed-on: https://review.monogon.dev/c/monogon/+/328
Reviewed-by: Mateusz Zalega <mateusz@monogon.tech>
diff --git a/build/toolbase/workspace.go b/build/toolbase/workspace.go
new file mode 100644
index 0000000..0994ac5
--- /dev/null
+++ b/build/toolbase/workspace.go
@@ -0,0 +1,38 @@
+package toolbase
+
+import (
+ "fmt"
+ "os"
+ "path"
+)
+
+// isWorkspace returns whether a given string is a valid path pointing to a
+// Bazel workspace directory.
+func isWorkspace(dir string) bool {
+ w := path.Join(dir, "WORKSPACE")
+ if _, err := os.Stat(w); err == nil {
+ return true
+ }
+ return false
+}
+
+// WorkspaceDirectory returns the workspace directory from which a given
+// command line tool is running. This handles the following cases:
+//
+// 1. The command line tool was invoked via `bazel run`.
+// 2. The command line tool was started directly in a workspace directory (but
+// not a subdirectory).
+//
+// If the workspace directory path cannot be inferred based on the above
+// assumptions, an error is returned.
+func WorkspaceDirectory() (string, error) {
+ if p := os.Getenv("BUILD_WORKSPACE_DIRECTORY"); p != "" && isWorkspace(p) {
+ return p, nil
+ }
+
+ if p, err := os.Getwd(); err != nil && isWorkspace(p) {
+ return p, nil
+ }
+
+ return "", fmt.Errorf("not invoked from `bazel run` and not running in workspace directory")
+}