Write logs.zip + logs to the correct place.

I erroneously assumed that the continuous builds don't set DIST_DIR,
whereas they do.

The variable naming is quite questionable, but for now, the important
thing is that the code works and I wanted to do that with the least
amount of change possible.

Also add some more logging:
- Shell environment
- Command line arguments
- Location of logs.zip
- The logs directory

Test: Presubmits.
Change-Id: I651b1045eeef568aa860fd2457fa7799ad68ba38
diff --git a/cmd/multiproduct_kati/main.go b/cmd/multiproduct_kati/main.go
index 2846387..fa63b46 100644
--- a/cmd/multiproduct_kati/main.go
+++ b/cmd/multiproduct_kati/main.go
@@ -20,6 +20,7 @@
 	"flag"
 	"fmt"
 	"io"
+	"io/ioutil"
 	"log"
 	"os"
 	"os/exec"
@@ -76,6 +77,36 @@
 	return nil
 }
 
+const errorLeadingLines = 20
+const errorTrailingLines = 20
+
+func errMsgFromLog(filename string) string {
+	if filename == "" {
+		return ""
+	}
+
+	data, err := ioutil.ReadFile(filename)
+	if err != nil {
+		return ""
+	}
+
+	lines := strings.Split(strings.TrimSpace(string(data)), "\n")
+	if len(lines) > errorLeadingLines+errorTrailingLines+1 {
+		lines[errorLeadingLines] = fmt.Sprintf("... skipping %d lines ...",
+			len(lines)-errorLeadingLines-errorTrailingLines)
+
+		lines = append(lines[:errorLeadingLines+1],
+			lines[len(lines)-errorTrailingLines:]...)
+	}
+	var buf strings.Builder
+	for _, line := range lines {
+		buf.WriteString("> ")
+		buf.WriteString(line)
+		buf.WriteString("\n")
+	}
+	return buf.String()
+}
+
 // TODO(b/70370883): This tool uses a lot of open files -- over the default
 // soft limit of 1024 on some systems. So bump up to the hard limit until I fix
 // the algorithm.
@@ -170,6 +201,23 @@
 	}
 }
 
+func outDirBase() string {
+	outDirBase := os.Getenv("OUT_DIR")
+	if outDirBase == "" {
+		return "out"
+	} else {
+		return outDirBase
+	}
+}
+
+func distDir(outDir string) string {
+	if distDir := os.Getenv("DIST_DIR"); distDir != "" {
+		return filepath.Clean(distDir)
+	} else {
+		return filepath.Join(outDir, "dist")
+	}
+}
+
 func main() {
 	stdio := terminal.StdioImpl{}
 
@@ -177,6 +225,12 @@
 	log := logger.New(output)
 	defer log.Cleanup()
 
+	for _, v := range os.Environ() {
+		log.Println("Environment: " + v)
+	}
+
+	log.Printf("Argv: %v\n", os.Args)
+
 	flag.Parse()
 
 	_, cancel := context.WithCancel(context.Background())
@@ -208,13 +262,7 @@
 		if !*incremental {
 			name += "-" + time.Now().Format("20060102150405")
 		}
-
-		outDirBase := os.Getenv("OUT_DIR")
-		if outDirBase == "" {
-			outDirBase = "out"
-		}
-
-		outputDir = filepath.Join(outDirBase, name)
+		outputDir = filepath.Join(outDirBase(), name)
 	}
 
 	log.Println("Output directory:", outputDir)
@@ -231,11 +279,13 @@
 
 	var configLogsDir string
 	if *alternateResultDir {
-		configLogsDir = filepath.Join(outputDir, "dist/logs")
+		configLogsDir = filepath.Join(distDir(outDirBase()), "logs")
 	} else {
 		configLogsDir = outputDir
 	}
 
+	log.Println("Logs dir: " + configLogsDir)
+
 	os.MkdirAll(configLogsDir, 0777)
 	log.SetOutput(filepath.Join(configLogsDir, "soong.log"))
 	trace.SetOutput(filepath.Join(configLogsDir, "build.trace"))
@@ -348,10 +398,11 @@
 			FileArgs: []zip.FileArg{
 				{GlobDir: logsDir, SourcePrefixToStrip: logsDir},
 			},
-			OutputFilePath:   filepath.Join(outputDir, "dist/logs.zip"),
+			OutputFilePath:   filepath.Join(distDir(outDirBase()), "logs.zip"),
 			NumParallelJobs:  runtime.NumCPU(),
 			CompressionLevel: 5,
 		}
+		log.Printf("Logs zip: %v\n", args.OutputFilePath)
 		if err := zip.Zip(args); err != nil {
 			log.Fatalf("Error zipping logs: %v", err)
 		}
@@ -424,10 +475,6 @@
 		args = append(args, "--soong-only")
 	}
 
-	if *alternateResultDir {
-		args = append(args, "dist")
-	}
-
 	cmd := exec.Command(mpctx.SoongUi, args...)
 	cmd.Stdout = consoleLogWriter
 	cmd.Stderr = consoleLogWriter
@@ -439,6 +486,11 @@
 		"TARGET_BUILD_APPS=",
 		"TARGET_BUILD_UNBUNDLED=")
 
+	if *alternateResultDir {
+		cmd.Env = append(cmd.Env,
+			"DIST_DIR="+filepath.Join(distDir(outDirBase()), "products/"+product))
+	}
+
 	action := &status.Action{
 		Description: product,
 		Outputs:     []string{product},
@@ -459,9 +511,17 @@
 			}
 		}
 	}
+	var errOutput string
+	if err == nil {
+		errOutput = ""
+	} else {
+		errOutput = errMsgFromLog(consoleLogPath)
+	}
+
 	mpctx.Status.FinishAction(status.ActionResult{
 		Action: action,
 		Error:  err,
+		Output: errOutput,
 	})
 }