Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 647b8518 authored by Christopher Parsons's avatar Christopher Parsons Committed by Gerrit Code Review
Browse files

Merge "Avoid deleting bp2build directory"

parents cec8b2c0 520e88b7
Loading
Loading
Loading
Loading
+45 −4
Original line number Diff line number Diff line
@@ -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
}

+62 −0
Original line number Diff line number Diff line
@@ -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