Merge "Name the resulting file $BUILD_NUMBER.kzip, drop revision.txt"
diff --git a/android/hooks.go b/android/hooks.go
index 5810996..64ffd52 100644
--- a/android/hooks.go
+++ b/android/hooks.go
@@ -30,7 +30,7 @@
BaseModuleContext
AppendProperties(...interface{})
PrependProperties(...interface{})
- CreateModule(blueprint.ModuleFactory, ...interface{})
+ CreateModule(ModuleFactory, ...interface{})
}
// Arch hooks are run after the module has been split into architecture variants, and can be used
diff --git a/android/mutator.go b/android/mutator.go
index e76f847..7b7859c 100644
--- a/android/mutator.go
+++ b/android/mutator.go
@@ -121,7 +121,7 @@
Rename(name string)
- CreateModule(blueprint.ModuleFactory, ...interface{})
+ CreateModule(ModuleFactory, ...interface{})
}
type topDownMutatorContext struct {
@@ -243,9 +243,9 @@
t.Module().base().commonProperties.DebugName = name
}
-func (t *topDownMutatorContext) CreateModule(factory blueprint.ModuleFactory, props ...interface{}) {
+func (t *topDownMutatorContext) CreateModule(factory ModuleFactory, props ...interface{}) {
inherited := []interface{}{&t.Module().base().commonProperties, &t.Module().base().variableProperties}
- t.bp.CreateModule(factory, append(inherited, props...)...)
+ t.bp.CreateModule(ModuleFactoryAdaptor(factory), append(inherited, props...)...)
}
func (b *bottomUpMutatorContext) MutatorName() string {
diff --git a/cc/test.go b/cc/test.go
index ba0b7e4..0e66e28 100644
--- a/cc/test.go
+++ b/cc/test.go
@@ -80,6 +80,11 @@
// Add MinApiLevelModuleController to auto generated test config. If the device property of
// "ro.build.version.sdk" < Test_min_sdk_version, then skip this module.
Test_min_sdk_version *int64
+
+ // Flag to indicate whether or not to create test config automatically. If AndroidTest.xml
+ // doesn't exist next to the Android.bp, this attribute doesn't need to be set to true
+ // explicitly.
+ Auto_gen_config *bool
}
func init() {
@@ -362,7 +367,7 @@
}
test.testConfig = tradefed.AutoGenNativeTestConfig(ctx, test.Properties.Test_config,
- test.Properties.Test_config_template, test.Properties.Test_suites, configs)
+ test.Properties.Test_config_template, test.Properties.Test_suites, configs, test.Properties.Auto_gen_config)
test.binaryDecorator.baseInstaller.dir = "nativetest"
test.binaryDecorator.baseInstaller.dir64 = "nativetest64"
@@ -453,6 +458,11 @@
// Add RootTargetPreparer to auto generated test config. This guarantees the test to run
// with root permission.
Require_root *bool
+
+ // Flag to indicate whether or not to create test config automatically. If AndroidTest.xml
+ // doesn't exist next to the Android.bp, this attribute doesn't need to be set to true
+ // explicitly.
+ Auto_gen_config *bool
}
type benchmarkDecorator struct {
@@ -490,7 +500,7 @@
configs = append(configs, tradefed.Object{"target_preparer", "com.android.tradefed.targetprep.RootTargetPreparer", nil})
}
benchmark.testConfig = tradefed.AutoGenNativeBenchmarkTestConfig(ctx, benchmark.Properties.Test_config,
- benchmark.Properties.Test_config_template, benchmark.Properties.Test_suites, configs)
+ benchmark.Properties.Test_config_template, benchmark.Properties.Test_suites, configs, benchmark.Properties.Auto_gen_config)
benchmark.binaryDecorator.baseInstaller.dir = filepath.Join("benchmarktest", ctx.ModuleName())
benchmark.binaryDecorator.baseInstaller.dir64 = filepath.Join("benchmarktest64", ctx.ModuleName())
diff --git a/cmd/multiproduct_kati/main.go b/cmd/multiproduct_kati/main.go
index 1171a65..2800ade 100644
--- a/cmd/multiproduct_kati/main.go
+++ b/cmd/multiproduct_kati/main.go
@@ -158,7 +158,7 @@
func main() {
stdio := terminal.StdioImpl{}
- output := terminal.NewStatusOutput(stdio.Stdout(), "",
+ output := terminal.NewStatusOutput(stdio.Stdout(), "", false,
build.OsEnvironment().IsEnvTrue("ANDROID_QUIET_BUILD"))
log := logger.New(output)
@@ -391,7 +391,7 @@
Thread: mpctx.Tracer.NewThread(product),
Status: &status.Status{},
}}
- ctx.Status.AddOutput(terminal.NewStatusOutput(ctx.Writer, "",
+ ctx.Status.AddOutput(terminal.NewStatusOutput(ctx.Writer, "", false,
build.OsEnvironment().IsEnvTrue("ANDROID_QUIET_BUILD")))
config := build.NewConfig(ctx, flag.Args()...)
diff --git a/cmd/soong_ui/main.go b/cmd/soong_ui/main.go
index ec4f90e..974c644 100644
--- a/cmd/soong_ui/main.go
+++ b/cmd/soong_ui/main.go
@@ -41,6 +41,12 @@
// description for the flag (to display when running help)
description string
+ // Forces the status output into dumb terminal mode.
+ forceDumbOutput bool
+
+ // Sets a prefix string to use for filenames of log files.
+ logsPrefix string
+
// Creates the build configuration based on the args and build context.
config func(ctx build.Context, args ...string) build.Config
@@ -64,17 +70,21 @@
stdio: stdio,
run: make,
}, {
- flag: "--dumpvar-mode",
- description: "print the value of the legacy make variable VAR to stdout",
- config: dumpVarConfig,
- stdio: customStdio,
- run: dumpVar,
+ flag: "--dumpvar-mode",
+ description: "print the value of the legacy make variable VAR to stdout",
+ forceDumbOutput: true,
+ logsPrefix: "dumpvars-",
+ config: dumpVarConfig,
+ stdio: customStdio,
+ run: dumpVar,
}, {
- flag: "--dumpvars-mode",
- description: "dump the values of one or more legacy make variables, in shell syntax",
- config: dumpVarConfig,
- stdio: customStdio,
- run: dumpVars,
+ flag: "--dumpvars-mode",
+ description: "dump the values of one or more legacy make variables, in shell syntax",
+ forceDumbOutput: true,
+ logsPrefix: "dumpvars-",
+ config: dumpVarConfig,
+ stdio: customStdio,
+ run: dumpVars,
}, {
flag: "--build-mode",
description: "build modules based on the specified build action",
@@ -113,7 +123,7 @@
os.Exit(1)
}
- output := terminal.NewStatusOutput(c.stdio().Stdout(), os.Getenv("NINJA_STATUS"),
+ output := terminal.NewStatusOutput(c.stdio().Stdout(), os.Getenv("NINJA_STATUS"), c.forceDumbOutput,
build.OsEnvironment().IsEnvTrue("ANDROID_QUIET_BUILD"))
log := logger.New(output)
@@ -157,14 +167,14 @@
}
os.MkdirAll(logsDir, 0777)
- log.SetOutput(filepath.Join(logsDir, "soong.log"))
- trace.SetOutput(filepath.Join(logsDir, "build.trace"))
- stat.AddOutput(status.NewVerboseLog(log, filepath.Join(logsDir, "verbose.log")))
- stat.AddOutput(status.NewErrorLog(log, filepath.Join(logsDir, "error.log")))
- stat.AddOutput(status.NewProtoErrorLog(log, filepath.Join(logsDir, "build_error")))
+ log.SetOutput(filepath.Join(logsDir, c.logsPrefix+"soong.log"))
+ trace.SetOutput(filepath.Join(logsDir, c.logsPrefix+"build.trace"))
+ stat.AddOutput(status.NewVerboseLog(log, filepath.Join(logsDir, c.logsPrefix+"verbose.log")))
+ stat.AddOutput(status.NewErrorLog(log, filepath.Join(logsDir, c.logsPrefix+"error.log")))
+ stat.AddOutput(status.NewProtoErrorLog(log, filepath.Join(logsDir, c.logsPrefix+"build_error")))
stat.AddOutput(status.NewCriticalPath(log))
- defer met.Dump(filepath.Join(logsDir, "soong_metrics"))
+ defer met.Dump(filepath.Join(logsDir, c.logsPrefix+"soong_metrics"))
if start, ok := os.LookupEnv("TRACE_BEGIN_SOONG"); ok {
if !strings.HasSuffix(start, "N") {
diff --git a/java/app.go b/java/app.go
index d00c4c0..afddb6a 100644
--- a/java/app.go
+++ b/java/app.go
@@ -608,7 +608,8 @@
}
a.generateAndroidBuildActions(ctx)
- a.testConfig = tradefed.AutoGenInstrumentationTestConfig(ctx, a.testProperties.Test_config, a.testProperties.Test_config_template, a.manifestPath, a.testProperties.Test_suites)
+ a.testConfig = tradefed.AutoGenInstrumentationTestConfig(ctx, a.testProperties.Test_config,
+ a.testProperties.Test_config_template, a.manifestPath, a.testProperties.Test_suites, a.testProperties.Auto_gen_config)
a.data = android.PathsForModuleSrc(ctx, a.testProperties.Data)
}
@@ -656,6 +657,11 @@
// list of compatibility suites (for example "cts", "vts") that the module should be
// installed into.
Test_suites []string `android:"arch_variant"`
+
+ // Flag to indicate whether or not to create test config automatically. If AndroidTest.xml
+ // doesn't exist next to the Android.bp, this attribute doesn't need to be set to true
+ // explicitly.
+ Auto_gen_config *bool
}
type AndroidTestHelperApp struct {
diff --git a/java/java.go b/java/java.go
index 4dd6a49..ce72c27 100644
--- a/java/java.go
+++ b/java/java.go
@@ -1685,6 +1685,11 @@
// list of files or filegroup modules that provide data that should be installed alongside
// the test
Data []string `android:"path"`
+
+ // Flag to indicate whether or not to create test config automatically. If AndroidTest.xml
+ // doesn't exist next to the Android.bp, this attribute doesn't need to be set to true
+ // explicitly.
+ Auto_gen_config *bool
}
type testHelperLibraryProperties struct {
@@ -1709,7 +1714,8 @@
}
func (j *Test) GenerateAndroidBuildActions(ctx android.ModuleContext) {
- j.testConfig = tradefed.AutoGenJavaTestConfig(ctx, j.testProperties.Test_config, j.testProperties.Test_config_template, j.testProperties.Test_suites)
+ j.testConfig = tradefed.AutoGenJavaTestConfig(ctx, j.testProperties.Test_config, j.testProperties.Test_config_template,
+ j.testProperties.Test_suites, j.testProperties.Auto_gen_config)
j.data = android.PathsForModuleSrc(ctx, j.testProperties.Data)
j.Library.GenerateAndroidBuildActions(ctx)
diff --git a/java/prebuilt_apis.go b/java/prebuilt_apis.go
index c370811..0d5e31f 100644
--- a/java/prebuilt_apis.go
+++ b/java/prebuilt_apis.go
@@ -82,7 +82,7 @@
props.Sdk_version = proptools.StringPtr("current")
props.Installable = proptools.BoolPtr(false)
- mctx.CreateModule(android.ModuleFactoryAdaptor(ImportFactory), &props)
+ mctx.CreateModule(ImportFactory, &props)
}
func createFilegroup(mctx android.TopDownMutatorContext, module string, scope string, apiver string, path string) {
@@ -93,7 +93,7 @@
}{}
filegroupProps.Name = proptools.StringPtr(fgName)
filegroupProps.Srcs = []string{path}
- mctx.CreateModule(android.ModuleFactoryAdaptor(android.FileGroupFactory), &filegroupProps)
+ mctx.CreateModule(android.FileGroupFactory, &filegroupProps)
}
func getPrebuiltFiles(mctx android.TopDownMutatorContext, name string) []string {
diff --git a/java/sdk_library.go b/java/sdk_library.go
index 30fd1c4..cc7256b 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -422,7 +422,7 @@
props.Product_specific = proptools.BoolPtr(true)
}
- mctx.CreateModule(android.ModuleFactoryAdaptor(LibraryFactory), &props)
+ mctx.CreateModule(LibraryFactory, &props)
}
// Creates a droiddoc module that creates stubs source files from the given full source
@@ -522,7 +522,7 @@
module.latestRemovedApiFilegroupName(apiScope))
props.Check_api.Ignore_missing_latest_api = proptools.BoolPtr(true)
- mctx.CreateModule(android.ModuleFactoryAdaptor(DroidstubsFactory), &props)
+ mctx.CreateModule(DroidstubsFactory, &props)
}
// Creates the xml file that publicizes the runtime library
@@ -560,7 +560,7 @@
genruleProps.Name = proptools.StringPtr(module.xmlFileName() + "-gen")
genruleProps.Cmd = proptools.StringPtr("echo '" + xmlContent + "' > $(out)")
genruleProps.Out = []string{module.xmlFileName()}
- mctx.CreateModule(android.ModuleFactoryAdaptor(genrule.GenRuleFactory), &genruleProps)
+ mctx.CreateModule(genrule.GenRuleFactory, &genruleProps)
// creates a prebuilt_etc module to actually place the xml file under
// <partition>/etc/permissions
@@ -582,7 +582,7 @@
} else if module.ProductSpecific() {
etcProps.Product_specific = proptools.BoolPtr(true)
}
- mctx.CreateModule(android.ModuleFactoryAdaptor(android.PrebuiltEtcFactory), &etcProps)
+ mctx.CreateModule(android.PrebuiltEtcFactory, &etcProps)
}
func (module *SdkLibrary) PrebuiltJars(ctx android.BaseModuleContext, sdkVersion string) android.Paths {
@@ -815,7 +815,7 @@
props.Product_specific = proptools.BoolPtr(true)
}
- mctx.CreateModule(android.ModuleFactoryAdaptor(ImportFactory), &props, &module.properties)
+ mctx.CreateModule(ImportFactory, &props, &module.properties)
javaSdkLibraries := javaSdkLibraries(mctx.Config())
javaSdkLibrariesLock.Lock()
diff --git a/python/binary.go b/python/binary.go
index 140f07a..695fa12 100644
--- a/python/binary.go
+++ b/python/binary.go
@@ -47,6 +47,11 @@
// false it will act much like the normal `python` executable, but with the sources and
// libraries automatically included in the PYTHONPATH.
Autorun *bool `android:"arch_variant"`
+
+ // Flag to indicate whether or not to create test config automatically. If AndroidTest.xml
+ // doesn't exist next to the Android.bp, this attribute doesn't need to be set to true
+ // explicitly.
+ Auto_gen_config *bool
}
type binaryDecorator struct {
diff --git a/python/test.go b/python/test.go
index 55b0ab5..f684fd5 100644
--- a/python/test.go
+++ b/python/test.go
@@ -50,7 +50,8 @@
func (test *testDecorator) install(ctx android.ModuleContext, file android.Path) {
test.testConfig = tradefed.AutoGenPythonBinaryHostTestConfig(ctx, test.testProperties.Test_config,
- test.testProperties.Test_config_template, test.binaryDecorator.binaryProperties.Test_suites)
+ test.testProperties.Test_config_template, test.binaryDecorator.binaryProperties.Test_suites,
+ test.binaryDecorator.binaryProperties.Auto_gen_config)
test.binaryDecorator.pythonInstaller.dir = "nativetest"
test.binaryDecorator.pythonInstaller.dir64 = "nativetest64"
diff --git a/sysprop/sysprop_library.go b/sysprop/sysprop_library.go
index 5eb7fa9..a876341 100644
--- a/sysprop/sysprop_library.go
+++ b/sysprop/sysprop_library.go
@@ -362,7 +362,7 @@
ccProps.Recovery_available = m.properties.Recovery_available
ccProps.Vendor_available = m.properties.Vendor_available
- ctx.CreateModule(android.ModuleFactoryAdaptor(cc.LibraryFactory), &ccProps)
+ ctx.CreateModule(cc.LibraryFactory, &ccProps)
// internal scope contains all properties
// public scope only contains public properties
@@ -390,7 +390,7 @@
Name: proptools.StringPtr(m.javaGenModuleName()),
}
- ctx.CreateModule(android.ModuleFactoryAdaptor(syspropJavaGenFactory), &javaGenProps)
+ ctx.CreateModule(syspropJavaGenFactory, &javaGenProps)
javaProps := struct {
Name *string
@@ -413,7 +413,7 @@
javaProps.Sdk_version = proptools.StringPtr("core_current")
javaProps.Libs = []string{stub}
- ctx.CreateModule(android.ModuleFactoryAdaptor(java.LibraryFactory), &javaProps)
+ ctx.CreateModule(java.LibraryFactory, &javaProps)
}
func syspropDepsMutator(ctx android.BottomUpMutatorContext) {
diff --git a/tradefed/autogen.go b/tradefed/autogen.go
index 1400345..3d30cfa 100644
--- a/tradefed/autogen.go
+++ b/tradefed/autogen.go
@@ -44,10 +44,11 @@
CommandDeps: []string{"$template"},
}, "name", "template", "extraConfigs")
-func testConfigPath(ctx android.ModuleContext, prop *string, testSuites []string) (path android.Path, autogenPath android.WritablePath) {
- if p := getTestConfig(ctx, prop); p != nil {
+func testConfigPath(ctx android.ModuleContext, prop *string, testSuites []string, autoGenConfig *bool) (path android.Path, autogenPath android.WritablePath) {
+ p := getTestConfig(ctx, prop)
+ if !Bool(autoGenConfig) && p != nil {
return p, nil
- } else if !android.InList("cts", testSuites) {
+ } else if !android.InList("cts", testSuites) && BoolDefault(autoGenConfig, true) {
outputFile := android.PathForModuleOut(ctx, ctx.ModuleName()+".config")
return nil, outputFile
} else {
@@ -124,8 +125,8 @@
}
func AutoGenNativeTestConfig(ctx android.ModuleContext, testConfigProp *string,
- testConfigTemplateProp *string, testSuites []string, config []Config) android.Path {
- path, autogenPath := testConfigPath(ctx, testConfigProp, testSuites)
+ testConfigTemplateProp *string, testSuites []string, config []Config, autoGenConfig *bool) android.Path {
+ path, autogenPath := testConfigPath(ctx, testConfigProp, testSuites, autoGenConfig)
if autogenPath != nil {
templatePath := getTestConfigTemplate(ctx, testConfigTemplateProp)
if templatePath.Valid() {
@@ -143,8 +144,8 @@
}
func AutoGenNativeBenchmarkTestConfig(ctx android.ModuleContext, testConfigProp *string,
- testConfigTemplateProp *string, testSuites []string, configs []Config) android.Path {
- path, autogenPath := testConfigPath(ctx, testConfigProp, testSuites)
+ testConfigTemplateProp *string, testSuites []string, configs []Config, autoGenConfig *bool) android.Path {
+ path, autogenPath := testConfigPath(ctx, testConfigProp, testSuites, autoGenConfig)
if autogenPath != nil {
templatePath := getTestConfigTemplate(ctx, testConfigTemplateProp)
if templatePath.Valid() {
@@ -157,8 +158,9 @@
return path
}
-func AutoGenJavaTestConfig(ctx android.ModuleContext, testConfigProp *string, testConfigTemplateProp *string, testSuites []string) android.Path {
- path, autogenPath := testConfigPath(ctx, testConfigProp, testSuites)
+func AutoGenJavaTestConfig(ctx android.ModuleContext, testConfigProp *string, testConfigTemplateProp *string,
+ testSuites []string, autoGenConfig *bool) android.Path {
+ path, autogenPath := testConfigPath(ctx, testConfigProp, testSuites, autoGenConfig)
if autogenPath != nil {
templatePath := getTestConfigTemplate(ctx, testConfigTemplateProp)
if templatePath.Valid() {
@@ -176,9 +178,9 @@
}
func AutoGenPythonBinaryHostTestConfig(ctx android.ModuleContext, testConfigProp *string,
- testConfigTemplateProp *string, testSuites []string) android.Path {
+ testConfigTemplateProp *string, testSuites []string, autoGenConfig *bool) android.Path {
- path, autogenPath := testConfigPath(ctx, testConfigProp, testSuites)
+ path, autogenPath := testConfigPath(ctx, testConfigProp, testSuites, autoGenConfig)
if autogenPath != nil {
templatePath := getTestConfigTemplate(ctx, testConfigTemplateProp)
if templatePath.Valid() {
@@ -200,8 +202,9 @@
},
}, "name", "template")
-func AutoGenInstrumentationTestConfig(ctx android.ModuleContext, testConfigProp *string, testConfigTemplateProp *string, manifest android.Path, testSuites []string) android.Path {
- path, autogenPath := testConfigPath(ctx, testConfigProp, testSuites)
+func AutoGenInstrumentationTestConfig(ctx android.ModuleContext, testConfigProp *string,
+ testConfigTemplateProp *string, manifest android.Path, testSuites []string, autoGenConfig *bool) android.Path {
+ path, autogenPath := testConfigPath(ctx, testConfigProp, testSuites, autoGenConfig)
if autogenPath != nil {
template := "${InstrumentationTestConfigTemplate}"
moduleTemplate := getTestConfigTemplate(ctx, testConfigTemplateProp)
@@ -222,3 +225,6 @@
}
return path
}
+
+var Bool = proptools.Bool
+var BoolDefault = proptools.BoolDefault
diff --git a/ui/build/config.go b/ui/build/config.go
index 665d2f0..def3345 100644
--- a/ui/build/config.go
+++ b/ui/build/config.go
@@ -16,7 +16,6 @@
import (
"io/ioutil"
- "log"
"os"
"path/filepath"
"runtime"
@@ -189,27 +188,27 @@
checkTopDir(ctx)
if srcDir := absPath(ctx, "."); strings.ContainsRune(srcDir, ' ') {
- log.Println("You are building in a directory whose absolute path contains a space character:")
- log.Println()
- log.Printf("%q\n", srcDir)
- log.Println()
- log.Fatalln("Directory names containing spaces are not supported")
+ ctx.Println("You are building in a directory whose absolute path contains a space character:")
+ ctx.Println()
+ ctx.Printf("%q\n", srcDir)
+ ctx.Println()
+ ctx.Fatalln("Directory names containing spaces are not supported")
}
if outDir := ret.OutDir(); strings.ContainsRune(outDir, ' ') {
- log.Println("The absolute path of your output directory ($OUT_DIR) contains a space character:")
- log.Println()
- log.Printf("%q\n", outDir)
- log.Println()
- log.Fatalln("Directory names containing spaces are not supported")
+ ctx.Println("The absolute path of your output directory ($OUT_DIR) contains a space character:")
+ ctx.Println()
+ ctx.Printf("%q\n", outDir)
+ ctx.Println()
+ ctx.Fatalln("Directory names containing spaces are not supported")
}
if distDir := ret.DistDir(); strings.ContainsRune(distDir, ' ') {
- log.Println("The absolute path of your dist directory ($DIST_DIR) contains a space character:")
- log.Println()
- log.Printf("%q\n", distDir)
- log.Println()
- log.Fatalln("Directory names containing spaces are not supported")
+ ctx.Println("The absolute path of your dist directory ($DIST_DIR) contains a space character:")
+ ctx.Println()
+ ctx.Printf("%q\n", distDir)
+ ctx.Println()
+ ctx.Fatalln("Directory names containing spaces are not supported")
}
// Configure Java-related variables, including adding it to $PATH
diff --git a/ui/terminal/smart_status.go b/ui/terminal/smart_status.go
index 57f71ab..efcfd43 100644
--- a/ui/terminal/smart_status.go
+++ b/ui/terminal/smart_status.go
@@ -189,7 +189,7 @@
fmt.Fprintf(s.writer, ansi.resetScrollingMargins())
_, height, _ := termSize(s.writer)
// Move the cursor to the top of the now-blank, previously non-scrolling region
- fmt.Fprintf(s.writer, ansi.setCursor(height-s.tableHeight, 0))
+ fmt.Fprintf(s.writer, ansi.setCursor(height-s.tableHeight, 1))
// Turn the cursor back on
fmt.Fprintf(s.writer, ansi.showCursor())
}
@@ -334,52 +334,44 @@
scrollingHeight := s.termHeight - s.tableHeight
// Update the scrolling region in case the height of the terminal changed
- fmt.Fprint(s.writer, ansi.setScrollingMargins(0, scrollingHeight))
- // Move the cursor to the first line of the non-scrolling region
- fmt.Fprint(s.writer, ansi.setCursor(scrollingHeight+1, 0))
+
+ fmt.Fprint(s.writer, ansi.setScrollingMargins(1, scrollingHeight))
// Write as many status lines as fit in the table
- var tableLine int
- var runningAction actionTableEntry
- for tableLine, runningAction = range s.runningActions {
+ for tableLine := 0; tableLine < s.tableHeight; tableLine++ {
if tableLine >= s.tableHeight {
break
}
+ // Move the cursor to the correct line of the non-scrolling region
+ fmt.Fprint(s.writer, ansi.setCursor(scrollingHeight+1+tableLine, 1))
- seconds := int(time.Since(runningAction.startTime).Round(time.Second).Seconds())
+ if tableLine < len(s.runningActions) {
+ runningAction := s.runningActions[tableLine]
- desc := runningAction.action.Description
- if desc == "" {
- desc = runningAction.action.Command
+ seconds := int(time.Since(runningAction.startTime).Round(time.Second).Seconds())
+
+ desc := runningAction.action.Description
+ if desc == "" {
+ desc = runningAction.action.Command
+ }
+
+ color := ""
+ if seconds >= 60 {
+ color = ansi.red() + ansi.bold()
+ } else if seconds >= 30 {
+ color = ansi.yellow() + ansi.bold()
+ }
+
+ durationStr := fmt.Sprintf(" %2d:%02d ", seconds/60, seconds%60)
+ desc = elide(desc, s.termWidth-len(durationStr))
+ durationStr = color + durationStr + ansi.regular()
+ fmt.Fprint(s.writer, durationStr, desc)
}
-
- color := ""
- if seconds >= 60 {
- color = ansi.red() + ansi.bold()
- } else if seconds >= 30 {
- color = ansi.yellow() + ansi.bold()
- }
-
- durationStr := fmt.Sprintf(" %2d:%02d ", seconds/60, seconds%60)
- desc = elide(desc, s.termWidth-len(durationStr))
- durationStr = color + durationStr + ansi.regular()
-
- fmt.Fprint(s.writer, durationStr, desc, ansi.clearToEndOfLine())
- if tableLine < s.tableHeight-1 {
- fmt.Fprint(s.writer, "\n")
- }
- }
-
- // Clear any remaining lines in the table
- for ; tableLine < s.tableHeight; tableLine++ {
fmt.Fprint(s.writer, ansi.clearToEndOfLine())
- if tableLine < s.tableHeight-1 {
- fmt.Fprint(s.writer, "\n")
- }
}
// Move the cursor back to the last line of the scrolling region
- fmt.Fprint(s.writer, ansi.setCursor(scrollingHeight, 0))
+ fmt.Fprint(s.writer, ansi.setCursor(scrollingHeight, 1))
}
var ansi = ansiImpl{}
diff --git a/ui/terminal/status.go b/ui/terminal/status.go
index 69a2a09..60dfc70 100644
--- a/ui/terminal/status.go
+++ b/ui/terminal/status.go
@@ -26,10 +26,10 @@
//
// statusFormat takes nearly all the same options as NINJA_STATUS.
// %c is currently unsupported.
-func NewStatusOutput(w io.Writer, statusFormat string, quietBuild bool) status.StatusOutput {
+func NewStatusOutput(w io.Writer, statusFormat string, forceDumbOutput, quietBuild bool) status.StatusOutput {
formatter := newFormatter(statusFormat, quietBuild)
- if isSmartTerminal(w) {
+ if !forceDumbOutput && isSmartTerminal(w) {
return NewSmartStatusOutput(w, formatter)
} else {
return NewDumbStatusOutput(w, formatter)
diff --git a/ui/terminal/status_test.go b/ui/terminal/status_test.go
index 81aa238..9f60829 100644
--- a/ui/terminal/status_test.go
+++ b/ui/terminal/status_test.go
@@ -94,7 +94,7 @@
t.Run("smart", func(t *testing.T) {
smart := &fakeSmartTerminal{termWidth: 40}
- stat := NewStatusOutput(smart, "", false)
+ stat := NewStatusOutput(smart, "", false, false)
tt.calls(stat)
stat.Flush()
@@ -105,7 +105,7 @@
t.Run("dumb", func(t *testing.T) {
dumb := &bytes.Buffer{}
- stat := NewStatusOutput(dumb, "", false)
+ stat := NewStatusOutput(dumb, "", false, false)
tt.calls(stat)
stat.Flush()
@@ -113,6 +113,17 @@
t.Errorf("want:\n%q\ngot:\n%q", w, g)
}
})
+
+ t.Run("force dumb", func(t *testing.T) {
+ smart := &fakeSmartTerminal{termWidth: 40}
+ stat := NewStatusOutput(smart, "", true, false)
+ tt.calls(stat)
+ stat.Flush()
+
+ if g, w := smart.String(), tt.dumb; g != w {
+ t.Errorf("want:\n%q\ngot:\n%q", w, g)
+ }
+ })
})
}
}
@@ -258,7 +269,7 @@
os.Setenv(tableHeightEnVar, "")
smart := &fakeSmartTerminal{termWidth: 40}
- stat := NewStatusOutput(smart, "", false)
+ stat := NewStatusOutput(smart, "", false, false)
smartStat := stat.(*smartStatusOutput)
smartStat.sigwinchHandled = make(chan bool)