Support remapping of source paths

This can be used to rewrite the source location.

Change-Id: Ic0e4a7fb0eb9ea115e9976bc3274e3aebd2b6770
Reviewed-on: https://fuchsia-review.googlesource.com/c/tools/+/406165
Commit-Queue: Petr Hosek <phosek@google.com>
Reviewed-by: Scott Graham <scottmg@google.com>
diff --git a/godepfile/cmd/godepfile.go b/godepfile/cmd/godepfile.go
index 1b94b68..4c35172 100644
--- a/godepfile/cmd/godepfile.go
+++ b/godepfile/cmd/godepfile.go
@@ -6,6 +6,7 @@
 package main
 
 import (
+	"errors"
 	"flag"
 	"fmt"
 	"go/build"
@@ -29,16 +30,41 @@
 	return nil
 }
 
+type mapFlag map[string]string
+
+func (v *mapFlag) String() string {
+	var s []string
+	for from, to := range *v {
+		s = append(s, fmt.Sprintf("%s=%s", from, to))
+	}
+	return strings.Join(s, " ")
+}
+
+func (v *mapFlag) Set(s string) error {
+	if strings.Count(s, "=") != 1 {
+		return errors.New("argument must be of the form from=to")
+	}
+	i := strings.Index(s, "=")
+	from, to := s[:i], s[i+1:]
+	if from == "" || to == "" {
+		return errors.New("from and to must be non-empty")
+	}
+	(*v)[from] = to
+	return nil
+}
+
 var (
-	ctx    = build.Default
-	output string
-	test   bool
+	ctx       = build.Default
+	output    string
+	test      bool
+	prefixmap = mapFlag{}
 )
 
 func init() {
 	flag.Var((*stringsFlag)(&ctx.BuildTags), "tags", "build tags")
 	flag.StringVar(&output, "o", "", "name of the resulting executable")
 	flag.BoolVar(&test, "test", false, "whether this is a test target")
+	flag.Var(&prefixmap, "prefixmap", "path prefix mapping in the from=to format")
 
 	flag.Usage = func() {
 		fmt.Fprintf(os.Stderr, "usage: godepfile [packages]\n")
@@ -46,6 +72,13 @@
 	}
 }
 
+func appendAndPrefix(slice []string, prefix string, src []string) []string {
+	for _, s := range src {
+		slice = append(slice, prefix+s)
+	}
+	return slice
+}
+
 func main() {
 	flag.Parse()
 
@@ -89,6 +122,12 @@
 
 		var files []string
 		srcdir := pkg.Dir + "/"
+		for from, to := range prefixmap {
+			if strings.HasPrefix(srcdir, from) {
+				srcdir = to + srcdir[len(from):]
+			}
+		}
+
 		files = appendAndPrefix(files, srcdir, pkg.GoFiles)
 		files = appendAndPrefix(files, srcdir, pkg.CgoFiles)
 		files = appendAndPrefix(files, srcdir, pkg.CFiles)
@@ -155,10 +194,3 @@
 	}
 	fmt.Printf("\n")
 }
-
-func appendAndPrefix(slice []string, prefix string, src []string) []string {
-	for _, s := range src {
-		slice = append(slice, prefix+s)
-	}
-	return slice
-}