Make it possible to pass an error message with an invalid optional path.
This is useful to delay errors until the paths need to be used.
Test: m nothing
Change-Id: I464e6ebd04b06c5e17617e8ee4e65a3320f1168f
diff --git a/android/paths.go b/android/paths.go
index 5eeb6e5..2e378ba 100644
--- a/android/paths.go
+++ b/android/paths.go
@@ -263,7 +263,8 @@
// OptionalPath is a container that may or may not contain a valid Path.
type OptionalPath struct {
- path Path // nil if invalid.
+ path Path // nil if invalid.
+ invalidReason string // Not applicable if path != nil. "" if the reason is unknown.
}
// OptionalPathForPath returns an OptionalPath containing the path.
@@ -271,6 +272,12 @@
return OptionalPath{path: path}
}
+// InvalidOptionalPath returns an OptionalPath that is invalid with the given reason.
+func InvalidOptionalPath(reason string) OptionalPath {
+
+ return OptionalPath{invalidReason: reason}
+}
+
// Valid returns whether there is a valid path
func (p OptionalPath) Valid() bool {
return p.path != nil
@@ -280,11 +287,26 @@
// there is a valid path, since this method will panic if there is not.
func (p OptionalPath) Path() Path {
if p.path == nil {
- panic("Requesting an invalid path")
+ msg := "Requesting an invalid path"
+ if p.invalidReason != "" {
+ msg += ": " + p.invalidReason
+ }
+ panic(msg)
}
return p.path
}
+// InvalidReason returns the reason that the optional path is invalid, or "" if it is valid.
+func (p OptionalPath) InvalidReason() string {
+ if p.path != nil {
+ return ""
+ }
+ if p.invalidReason == "" {
+ return "unknown"
+ }
+ return p.invalidReason
+}
+
// AsPaths converts the OptionalPath into Paths.
//
// It returns nil if this is not valid, or a single length slice containing the Path embedded in
@@ -1073,6 +1095,7 @@
path, err := pathForSource(ctx, pathComponents...)
if err != nil {
reportPathError(ctx, err)
+ // No need to put the error message into the returned path since it has been reported already.
return OptionalPath{}
}
@@ -1087,7 +1110,7 @@
return OptionalPath{}
}
if !exists {
- return OptionalPath{}
+ return InvalidOptionalPath(path.String() + " does not exist")
}
return OptionalPathForPath(path)
}
@@ -1123,6 +1146,7 @@
relDir = srcPath.path
} else {
ReportPathErrorf(ctx, "Cannot find relative path for %s(%s)", reflect.TypeOf(path).Name(), path)
+ // No need to put the error message into the returned path since it has been reported already.
return OptionalPath{}
}
dir := filepath.Join(p.srcDir, p.path, relDir)
@@ -1136,7 +1160,7 @@
return OptionalPath{}
}
if len(paths) == 0 {
- return OptionalPath{}
+ return InvalidOptionalPath(dir + " does not exist")
}
relPath := Rel(ctx, p.srcDir, paths[0])
return OptionalPathForPath(PathForSource(ctx, relPath))
diff --git a/android/paths_test.go b/android/paths_test.go
index f4e4ce1..3f4625d 100644
--- a/android/paths_test.go
+++ b/android/paths_test.go
@@ -137,26 +137,35 @@
func TestOptionalPath(t *testing.T) {
var path OptionalPath
- checkInvalidOptionalPath(t, path)
+ checkInvalidOptionalPath(t, path, "unknown")
path = OptionalPathForPath(nil)
- checkInvalidOptionalPath(t, path)
+ checkInvalidOptionalPath(t, path, "unknown")
+
+ path = InvalidOptionalPath("foo")
+ checkInvalidOptionalPath(t, path, "foo")
+
+ path = InvalidOptionalPath("")
+ checkInvalidOptionalPath(t, path, "unknown")
path = OptionalPathForPath(PathForTesting("path"))
checkValidOptionalPath(t, path, "path")
}
-func checkInvalidOptionalPath(t *testing.T, path OptionalPath) {
+func checkInvalidOptionalPath(t *testing.T, path OptionalPath, expectedInvalidReason string) {
t.Helper()
if path.Valid() {
- t.Errorf("Uninitialized OptionalPath should not be valid")
+ t.Errorf("Invalid OptionalPath should not be valid")
+ }
+ if path.InvalidReason() != expectedInvalidReason {
+ t.Errorf("Wrong invalid reason: expected %q, got %q", expectedInvalidReason, path.InvalidReason())
}
if path.String() != "" {
- t.Errorf("Uninitialized OptionalPath String() should return \"\", not %q", path.String())
+ t.Errorf("Invalid OptionalPath String() should return \"\", not %q", path.String())
}
paths := path.AsPaths()
if len(paths) != 0 {
- t.Errorf("Uninitialized OptionalPath AsPaths() should return empty Paths, not %q", paths)
+ t.Errorf("Invalid OptionalPath AsPaths() should return empty Paths, not %q", paths)
}
defer func() {
if r := recover(); r == nil {
@@ -171,6 +180,9 @@
if !path.Valid() {
t.Errorf("Initialized OptionalPath should not be invalid")
}
+ if path.InvalidReason() != "" {
+ t.Errorf("Initialized OptionalPath should not have an invalid reason, got: %q", path.InvalidReason())
+ }
if path.String() != expectedString {
t.Errorf("Initialized OptionalPath String() should return %q, not %q", expectedString, path.String())
}