about summary refs log tree commit diff
diff options
context:
space:
mode:
authorWilliam Carroll <wpcarro@gmail.com>2020-02-11T17·02+0000
committerWilliam Carroll <wpcarro@gmail.com>2020-02-11T17·11+0000
commita50153c1419dd7dd1a7e3e79a016fa84e42accbb (patch)
tree7292d6d2ba4314b7f278d7e0b4b6c927b97cee6c
parentb3b343ebf97998b9ec9035ac528a9bd20d1cca29 (diff)
Support utils.Resolve/2
Supporting a function that resolves a file name checking for the nearest
occurrence of the file from the CWD until it traverses beyond the user's home
directory, after which point it checks in backupPaths.
-rw-r--r--gopkgs/utils/utils.go39
1 files changed, 39 insertions, 0 deletions
diff --git a/gopkgs/utils/utils.go b/gopkgs/utils/utils.go
index 24121ed44c75..53136878dea3 100644
--- a/gopkgs/utils/utils.go
+++ b/gopkgs/utils/utils.go
@@ -9,6 +9,7 @@ import (
 	"net/http/httputil"
 	"os"
 	"os/user"
+	"path/filepath"
 )
 
 // Return the absolute path to the current uesr's home directory.
@@ -29,6 +30,44 @@ func FileExists(path string) bool {
 	}
 }
 
+// Return the absolute file path of `file` using the following resolution
+// strategy:
+// - Traverse and search upwards until you reach the user's home directory
+// - Return the first path in `backupPaths` that exists
+// - Fail
+func Resolve(fileName string, backupPaths []string) string {
+	// TODO(wpcarro): Drop hardcoding when whoami behaves as expected.
+	boundary := "/home"
+	cwd := "."
+	files, _ := ioutil.ReadDir(cwd)
+
+	for {
+		fullCwd, _ := filepath.Abs(cwd)
+		if fullCwd == boundary {
+			break
+		}
+		for _, file := range files {
+			if file.Name() == fileName {
+				path, _ := filepath.Abs(cwd + "/" + file.Name())
+				return path
+			}
+		}
+		cwd += "/.."
+		files, _ = ioutil.ReadDir(cwd)
+	}
+
+	// TODO(wpcarro): Support expanding these paths to allow the consumer to
+	// pass in relative paths, and paths with "~" in them.
+	for _, backup := range backupPaths {
+		if FileExists(backup) {
+			return backup
+		}
+	}
+	log.Fatal("Cannot find a run.json to use.")
+	// This code should be unreachable.
+	return ""
+}
+
 // Call log.Fatal with `err` when it's not nil.
 func FailOn(err error) {
 	if err != nil {