Make symlink_forest.go prefer generated files.

Now, if the same file exists in the generated tree and the source tree,
it symlinks in the generated file instead of failing outright.

Drive-by fix: print errors for all conflicts instead of bailing out on
the first one.

Test: Presubmits (including the two new tests)
Change-Id: Ifb5b3fc89b5454d231966bfa4e61c22cd69834f3
This commit is contained in:
Lukacs T. Berki
2021-04-21 11:58:36 +02:00
parent c7985f6c92
commit b21166e236
2 changed files with 70 additions and 7 deletions

View File

@@ -94,7 +94,7 @@ func symlinkIntoForest(topdir, dst, src string) {
// contain every file in buildFilesDir and srcDir excluding the files in
// exclude. Collects every directory encountered during the traversal of srcDir
// into acc.
func plantSymlinkForestRecursive(topdir string, forestDir string, buildFilesDir string, srcDir string, exclude *node, acc *[]string) {
func plantSymlinkForestRecursive(topdir string, forestDir string, buildFilesDir string, srcDir string, exclude *node, acc *[]string, okay *bool) {
if exclude != nil && exclude.excluded {
// This directory is not needed, bail out
return
@@ -149,7 +149,7 @@ func plantSymlinkForestRecursive(topdir string, forestDir string, buildFilesDir
if buildFilesChildEntry.IsDir() && excludeChild != nil {
// Not in the source tree, but we have to exclude something from under
// this subtree, so descend
plantSymlinkForestRecursive(topdir, forestChild, buildFilesChild, srcChild, excludeChild, acc)
plantSymlinkForestRecursive(topdir, forestChild, buildFilesChild, srcChild, excludeChild, acc, okay)
} else {
// Not in the source tree, symlink BUILD file
symlinkIntoForest(topdir, forestChild, buildFilesChild)
@@ -158,20 +158,26 @@ func plantSymlinkForestRecursive(topdir string, forestDir string, buildFilesDir
if srcChildEntry.IsDir() && excludeChild != nil {
// Not in the build file tree, but we have to exclude something from
// under this subtree, so descend
plantSymlinkForestRecursive(topdir, forestChild, buildFilesChild, srcChild, excludeChild, acc)
plantSymlinkForestRecursive(topdir, forestChild, buildFilesChild, srcChild, excludeChild, acc, okay)
} else {
// Not in the build file tree, symlink source tree, carry on
symlinkIntoForest(topdir, forestChild, srcChild)
}
} else if srcChildEntry.IsDir() && buildFilesChildEntry.IsDir() {
// Both are directories. Descend.
plantSymlinkForestRecursive(topdir, forestChild, buildFilesChild, srcChild, excludeChild, acc)
plantSymlinkForestRecursive(topdir, forestChild, buildFilesChild, srcChild, excludeChild, acc, okay)
} else if !srcChildEntry.IsDir() && !buildFilesChildEntry.IsDir() {
// Neither is a directory. Prioritize BUILD files generated by bp2build
// over any BUILD file imported into external/.
fmt.Fprintf(os.Stderr, "Both '%s' and '%s' exist, symlinking the former to '%s'\n",
buildFilesChild, srcChild, forestChild)
symlinkIntoForest(topdir, forestChild, buildFilesChild)
} else {
// Both exist and one is a file. This is an error.
fmt.Fprintf(os.Stderr,
"Conflict in workspace symlink tree creation: both '%s' and '%s' exist and at least one of them is a file\n",
"Conflict in workspace symlink tree creation: both '%s' and '%s' exist and exactly one is a directory\n",
srcChild, buildFilesChild)
os.Exit(1)
*okay = false
}
}
}
@@ -184,6 +190,10 @@ func PlantSymlinkForest(topdir string, forest string, buildFiles string, srcDir
deps := make([]string, 0)
os.RemoveAll(shared.JoinPath(topdir, forest))
excludeTree := treeFromExcludePathList(exclude)
plantSymlinkForestRecursive(topdir, forest, buildFiles, srcDir, excludeTree, &deps)
okay := true
plantSymlinkForestRecursive(topdir, forest, buildFiles, srcDir, excludeTree, &deps, &okay)
if !okay {
os.Exit(1)
}
return deps
}