Add out/partitions_were_clean_at_start_of_build.txt
Test: Presubmits
Change-Id: I1c7025f2c7594ae84b740ccbae4dcbc933b8cdf6
diff --git a/ui/build/build.go b/ui/build/build.go
index 9d5c330..15cff5f 100644
--- a/ui/build/build.go
+++ b/ui/build/build.go
@@ -298,6 +298,8 @@
runMakeProductConfig(ctx, config)
}
+ checkForCleanPartitions(ctx, config)
+
// Everything below here depends on product config.
if inList("installclean", config.Arguments()) ||
diff --git a/ui/build/cleanbuild.go b/ui/build/cleanbuild.go
index 41cb5ab..7114963 100644
--- a/ui/build/cleanbuild.go
+++ b/ui/build/cleanbuild.go
@@ -218,6 +218,50 @@
writeConfig()
}
+// Writes out/partitions_were_clean_at_start_of_build.txt.
+// This file will contain "true" if there were no partition staging directories at the start of
+// the build (most likely from having just run `m installclean`) and "false" otherwise.
+// It's used to make a test that the staging directories are correct. That test can only be
+// correctly run directly after `m installclean`, and this is how we check for that.
+func checkForCleanPartitions(ctx Context, config Config) {
+ productOutPath := config.ProductOut()
+ productOut := func(path string) string {
+ return filepath.Join(productOutPath, path)
+ }
+
+ notExists := func(path string) bool {
+ _, err := os.Stat(path)
+ return os.IsNotExist(err)
+ }
+
+ clean := notExists(productOut("ramdisk")) &&
+ notExists(productOut("ramdisk_16k")) &&
+ notExists(productOut("debug_ramdisk")) &&
+ notExists(productOut("vendor_ramdisk")) &&
+ notExists(productOut("vendor_debug_ramdisk")) &&
+ notExists(productOut("vendor_kernel_ramdisk")) &&
+ notExists(productOut("test_harness_ramdisk")) &&
+ notExists(productOut("data")) &&
+ notExists(productOut("recovery")) &&
+ notExists(productOut("root")) &&
+ notExists(productOut("system")) &&
+ notExists(productOut("system_dlkm")) &&
+ notExists(productOut("system_other")) &&
+ notExists(productOut("vendor")) &&
+ notExists(productOut("vendor_dlkm")) &&
+ notExists(productOut("product")) &&
+ notExists(productOut("system_ext")) &&
+ notExists(productOut("oem")) &&
+ notExists(productOut("breakpad")) &&
+ notExists(productOut("cache")) &&
+ notExists(productOut("coverage")) &&
+ notExists(productOut("installer")) &&
+ notExists(productOut("odm")) &&
+ notExists(productOut("odm_dlkm"))
+
+ writeValueIfChanged(ctx, config, config.OutDir(), "partitions_were_clean_at_start_of_build.txt", fmt.Sprintf("%t\n", clean))
+}
+
// cleanOldFiles takes an input file (with all paths relative to basePath), and removes files from
// the filesystem if they were removed from the input file since the last execution.
func cleanOldFiles(ctx Context, basePath, newFile string) {
diff --git a/ui/build/kati.go b/ui/build/kati.go
index 31e7440..7f0ea24 100644
--- a/ui/build/kati.go
+++ b/ui/build/kati.go
@@ -102,6 +102,8 @@
"--use_ninja_phony_output",
// Support declaring symlink outputs in AOSP Ninja.
"--use_ninja_symlink_outputs",
+ // Support ninja validation actions with .KATI_VALIDATIONS: https://ninja-build.org/manual.html#validations
+ "--use_ninja_validations",
// Regenerate the Ninja file if environment inputs have changed. e.g.
// CLI flags, .mk file timestamps, env vars, $(wildcard ..) and some
// $(shell ..) results.
diff --git a/ui/build/test_build.go b/ui/build/test_build.go
index 2efc732..af60e0d 100644
--- a/ui/build/test_build.go
+++ b/ui/build/test_build.go
@@ -103,8 +103,10 @@
// treated as an source file.
dexpreoptConfigFilePath := filepath.Join(outDir, "soong", "dexpreopt.config")
- // out/build_date.txt is considered a "source file"
+ // These files are written by soong_ui at the beginning of every build.
+ // Ninja considers them "source files"
buildDatetimeFilePath := filepath.Join(outDir, "build_date.txt")
+ cleanPartitionsFilePath := filepath.Join(outDir, "partitions_were_clean_at_start_of_build.txt")
// bpglob is built explicitly using Microfactory
bpglob := filepath.Join(config.SoongOutDir(), "bpglob")
@@ -122,6 +124,7 @@
line == variablesFilePath ||
line == dexpreoptConfigFilePath ||
line == buildDatetimeFilePath ||
+ line == cleanPartitionsFilePath ||
line == bpglob {
// Leaf node is in one of Soong's bootstrap directories, which do not have
// full build rules in the primary build.ninja file.