Fix issue merging bp2build files with handcrafted ones

It was possible for the merged content to end up back in the bp2build
generated file because there was a symlink from the symlink forest to
the bp2build generated file.

Remove the symlink if it exists.

Bug: 276349152
Test: m bp2build, add a handcrafted file in the same folder as a Android.bp file, m bp2build again, check that the symlink forest version is not a symlink
Change-Id: Id64aa3addebcf0c6b1728389f21ae246796aaf8d
diff --git a/bp2build/symlink_forest.go b/bp2build/symlink_forest.go
index aac5e7d..e3878b1 100644
--- a/bp2build/symlink_forest.go
+++ b/bp2build/symlink_forest.go
@@ -25,6 +25,7 @@
 	"sync/atomic"
 
 	"android/soong/shared"
+
 	"github.com/google/blueprint/pathtools"
 )
 
@@ -123,6 +124,34 @@
 	}
 	newContents = append(newContents, srcBuildFileContent...)
 
+	// Say you run bp2build 4 times:
+	// - The first time there's only an Android.bp file. bp2build will convert it to a build file
+	//   under out/soong/bp2build, then symlink from the forest to that generated file
+	// - Then you add a handcrafted BUILD file in the same directory. bp2build will merge this with
+	//   the generated one, and write the result to the output file in the forest. But the output
+	//   file was a symlink to out/soong/bp2build from the previous step! So we erroneously update
+	//   the file in out/soong/bp2build instead. So far this doesn't cause any problems...
+	// - You run a 3rd bp2build with no relevant changes. Everything continues to work.
+	// - You then add a comment to the handcrafted BUILD file. This causes a merge with the
+	//   generated file again. But since we wrote to the generated file in step 2, the generated
+	//   file has an old copy of the handcrafted file in it! This probably causes duplicate bazel
+	//   targets.
+	// To solve this, if we see that the output file is a symlink from a previous build, remove it.
+	stat, err := os.Lstat(output)
+	if err != nil && !os.IsNotExist(err) {
+		return err
+	} else if err == nil {
+		if stat.Mode()&os.ModeSymlink == os.ModeSymlink {
+			if verbose {
+				fmt.Fprintf(os.Stderr, "Removing symlink so that we can replace it with a merged file: %s\n", output)
+			}
+			err = os.Remove(output)
+			if err != nil {
+				return err
+			}
+		}
+	}
+
 	return pathtools.WriteFileIfChanged(output, newContents, 0666)
 }