Merge "Avoid deleting bp2build directory"

This commit is contained in:
Christopher Parsons
2023-03-02 14:22:13 +00:00
committed by Gerrit Code Review
2 changed files with 107 additions and 4 deletions

View File

@@ -17,21 +17,57 @@ package bp2build
import (
"fmt"
"os"
"path/filepath"
"strings"
"android/soong/android"
"android/soong/bazel"
"android/soong/shared"
)
func deleteFilesExcept(ctx *CodegenContext, rootOutputPath android.OutputPath, except []BazelFile) {
// Delete files that should no longer be present.
bp2buildDirAbs := shared.JoinPath(ctx.topDir, rootOutputPath.String())
filesToDelete := make(map[string]struct{})
err := filepath.Walk(bp2buildDirAbs,
func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if !info.IsDir() {
relPath, err := filepath.Rel(bp2buildDirAbs, path)
if err != nil {
return err
}
filesToDelete[relPath] = struct{}{}
}
return nil
})
if err != nil {
fmt.Printf("ERROR reading %s: %s", bp2buildDirAbs, err)
os.Exit(1)
}
for _, bazelFile := range except {
filePath := filepath.Join(bazelFile.Dir, bazelFile.Basename)
delete(filesToDelete, filePath)
}
for f, _ := range filesToDelete {
absPath := shared.JoinPath(bp2buildDirAbs, f)
if err := os.RemoveAll(absPath); err != nil {
fmt.Printf("ERROR deleting %s: %s", absPath, err)
os.Exit(1)
}
}
}
// Codegen is the backend of bp2build. The code generator is responsible for
// writing .bzl files that are equivalent to Android.bp files that are capable
// of being built with Bazel.
func Codegen(ctx *CodegenContext) *CodegenMetrics {
// This directory stores BUILD files that could be eventually checked-in.
bp2buildDir := android.PathForOutput(ctx, "bp2build")
if err := android.RemoveAllOutputDir(bp2buildDir); err != nil {
fmt.Printf("ERROR: Encountered error while cleaning %s: %s", bp2buildDir, err.Error())
}
res, errs := GenerateBazelTargets(ctx, true)
if len(errs) > 0 {
@@ -44,6 +80,12 @@ func Codegen(ctx *CodegenContext) *CodegenMetrics {
}
bp2buildFiles := CreateBazelFiles(ctx.Config(), nil, res.buildFileToTargets, ctx.mode)
writeFiles(ctx, bp2buildDir, bp2buildFiles)
// Delete files under the bp2build root which weren't just written. An
// alternative would have been to delete the whole directory and write these
// files. However, this would regenerate files which were otherwise unchanged
// since the last bp2build run, which would have negative incremental
// performance implications.
deleteFilesExcept(ctx, bp2buildDir, bp2buildFiles)
injectionFiles, err := CreateSoongInjectionDirFiles(ctx, res.metrics)
if err != nil {
@@ -51,7 +93,6 @@ func Codegen(ctx *CodegenContext) *CodegenMetrics {
os.Exit(1)
}
writeFiles(ctx, android.PathForOutput(ctx, bazel.SoongInjectionDirName), injectionFiles)
return &res.metrics
}

View File

@@ -21,6 +21,68 @@ function test_bp2build_null_build {
fi
}
# Tests that, if bp2build reruns due to a blueprint file changing, that
# BUILD files whose contents are unchanged are not regenerated.
function test_bp2build_unchanged {
setup
mkdir -p pkg
touch pkg/x.txt
cat > pkg/Android.bp <<'EOF'
filegroup {
name: "x",
srcs: ["x.txt"],
bazel_module: {bp2build_available: true},
}
EOF
run_soong bp2build
local -r buildfile_mtime1=$(stat -c "%y" out/soong/bp2build/pkg/BUILD.bazel)
local -r marker_mtime1=$(stat -c "%y" out/soong/bp2build_workspace_marker)
# Force bp2build to rerun by updating the timestamp of a blueprint file.
touch pkg/Android.bp
run_soong bp2build
local -r buildfile_mtime2=$(stat -c "%y" out/soong/bp2build/pkg/BUILD.bazel)
local -r marker_mtime2=$(stat -c "%y" out/soong/bp2build_workspace_marker)
if [[ "$marker_mtime1" == "$marker_mtime2" ]]; then
fail "Expected bp2build marker file to change"
fi
if [[ "$buildfile_mtime1" != "$buildfile_mtime2" ]]; then
fail "BUILD.bazel was updated even though contents are same"
fi
}
# Tests that blueprint files that are deleted are not present when the
# bp2build tree is regenerated.
function test_bp2build_deleted_blueprint {
setup
mkdir -p pkg
touch pkg/x.txt
cat > pkg/Android.bp <<'EOF'
filegroup {
name: "x",
srcs: ["x.txt"],
bazel_module: {bp2build_available: true},
}
EOF
run_soong bp2build
if [[ ! -e "./out/soong/bp2build/pkg/BUILD.bazel" ]]; then
fail "Expected pkg/BUILD.bazel to be generated"
fi
rm pkg/Android.bp
run_soong bp2build
if [[ -e "./out/soong/bp2build/pkg/BUILD.bazel" ]]; then
fail "Expected pkg/BUILD.bazel to be deleted"
fi
}
function test_bp2build_null_build_with_globs {
setup