From b5255950a5d4c4f59db13e83b38349f8987350a0 Mon Sep 17 00:00:00 2001 From: Li Haoyi Date: Fri, 6 Dec 2024 17:53:17 +0800 Subject: [PATCH] More improvements for prompt logger (#4080) * Skip the two blank spaces at the left side of the header, since it looks weird on terminates with a line cursor rather than a block cursor (e.g. on Windows Terminal) * Remove the `===` footer in non-interactive mode, since usually the end of the prompt is clear enough from context and it can be very verbose --- build.mill | 13 ++-- .../full-run-logs/src/FullRunLogsTests.scala | 4 +- main/util/src/mill/util/PromptLogger.scala | 3 +- .../util/src/mill/util/PromptLoggerUtil.scala | 19 ++---- .../src/mill/util/PromptLoggerTests.scala | 26 ++++---- .../src/mill/util/PromptLoggerUtilTests.scala | 63 +++++++++---------- 6 files changed, 53 insertions(+), 75 deletions(-) diff --git a/build.mill b/build.mill index 0aba00bee69..c3cb65ff74d 100644 --- a/build.mill +++ b/build.mill @@ -571,15 +571,10 @@ trait MillStableScalaModule extends MillPublishScalaModule with Mima { "mill.scalalib.ScalaModule#ScalaTests.mill$scalalib$ScalaModule$ScalaTests$$super$mandatoryScalacOptions" ), // Not sure why Mima is complaining when these are internal and private - ProblemFilter.exclude[Problem]( - "*.bspJvmBuildTarget" - ), - ProblemFilter.exclude[Problem]( - "mill.scalalib.RunModule#RunnerImpl.*" - ), - ProblemFilter.exclude[Problem]( - "mill.util.PromptLogger#*" - ) + ProblemFilter.exclude[Problem]("*.bspJvmBuildTarget"), + ProblemFilter.exclude[Problem]("mill.scalalib.RunModule#RunnerImpl.*"), + ProblemFilter.exclude[Problem]("mill.util.PromptLogger#*"), + ProblemFilter.exclude[Problem]("mill.util.PromptLoggerUtil.*") ) def mimaPreviousVersions: T[Seq[String]] = Settings.mimaBaseVersions diff --git a/integration/feature/full-run-logs/src/FullRunLogsTests.scala b/integration/feature/full-run-logs/src/FullRunLogsTests.scala index f9c677a012c..9aa27126e16 100644 --- a/integration/feature/full-run-logs/src/FullRunLogsTests.scala +++ b/integration/feature/full-run-logs/src/FullRunLogsTests.scala @@ -34,7 +34,6 @@ object FullRunLogsTests extends UtestIntegrationTestSuite { val expectedErrorRegex = java.util.regex.Pattern .quote( s""" run --text hello - | |[build.mill-/] compile |[build.mill-] [info] compiling 1 Scala source to ${tester.workspacePath}/out/mill-build/compile.dest/classes ... |[build.mill-] [info] done compiling @@ -42,8 +41,7 @@ object FullRunLogsTests extends UtestIntegrationTestSuite { |[] [info] compiling 1 Java source to ${tester.workspacePath}/out/compile.dest/classes ... |[] [info] done compiling |[/] run - |[/] run --text hello s - |""" + |[/] run --text hello s""" .stripMargin .replaceAll("(\r\n)|\r", "\n") .replace('\\', '/') diff --git a/main/util/src/mill/util/PromptLogger.scala b/main/util/src/mill/util/PromptLogger.scala index 4c06142ffc7..c55e9dc73f0 100644 --- a/main/util/src/mill/util/PromptLogger.scala +++ b/main/util/src/mill/util/PromptLogger.scala @@ -367,8 +367,7 @@ private[mill] object PromptLogger { titleText, statuses.toSeq.map { case (k, v) => (k.mkString("-"), v) }, interactive = interactive, - infoColor = infoColor, - ending = ending + infoColor = infoColor ) val oldPromptBytes = currentPromptBytes diff --git a/main/util/src/mill/util/PromptLoggerUtil.scala b/main/util/src/mill/util/PromptLoggerUtil.scala index 92fbd3b592c..071ad9b985f 100644 --- a/main/util/src/mill/util/PromptLoggerUtil.scala +++ b/main/util/src/mill/util/PromptLoggerUtil.scala @@ -91,8 +91,7 @@ private object PromptLoggerUtil { titleText: String, statuses: Iterable[(String, Status)], interactive: Boolean, - infoColor: fansi.Attrs, - ending: Boolean = false + infoColor: fansi.Attrs ): List[String] = { // -1 to leave a bit of buffer val maxWidth = consoleWidth - 1 @@ -100,7 +99,7 @@ private object PromptLoggerUtil { val maxHeight = math.max(1, consoleHeight / 3 - 1) val headerSuffix = renderSecondsSuffix(now - startTimeMillis) - val header = renderHeader(headerPrefix, titleText, headerSuffix, maxWidth, ending, interactive) + val header = renderHeader(headerPrefix, titleText, headerSuffix, maxWidth) val body0 = statuses .flatMap { @@ -147,12 +146,7 @@ private object PromptLoggerUtil { s"... and ${nonEmptyBodyCount - maxHeight + 1} more threads" ) - // For non-interactive jobs, the prompt won't be at the bottom of the terminal but - // will instead be in the middle of a big log file with logs above and below, so we - // need some kind of footer to tell the reader when the prompt ends and logs begin - val footer = Option.when(!interactive)("=" * header.length).toList - - header :: body ::: footer + header :: body } // Wrap the prompt in the necessary clear-screens/newlines/move-cursors @@ -181,12 +175,9 @@ private object PromptLoggerUtil { headerPrefix0: String, titleText0: String, headerSuffix0: String, - maxWidth: Int, - ending: Boolean = false, - interactive: Boolean = true + maxWidth: Int ): String = { - val headerPrefix = if (headerPrefix0.isEmpty) "" else s"$headerPrefix0 " - val headerPrefixStr = if (!interactive || ending) headerPrefix else s" $headerPrefix" + val headerPrefixStr = if (headerPrefix0.isEmpty) "" else s"$headerPrefix0 " val headerSuffixStr = headerSuffix0 val titleText = s" $titleText0 " diff --git a/main/util/test/src/mill/util/PromptLoggerTests.scala b/main/util/test/src/mill/util/PromptLoggerTests.scala index 1d34702a88f..c9c51205af9 100644 --- a/main/util/test/src/mill/util/PromptLoggerTests.scala +++ b/main/util/test/src/mill/util/PromptLoggerTests.scala @@ -77,7 +77,6 @@ object PromptLoggerTests extends TestSuite { check(promptLogger, baos, width = 999 /*log file has no line wrapping*/ )( "============================== TITLE ==============================", - "===================================================================", // Make sure that the first time a prefix is reported, // we print the verbose prefix along with the ticker string "[1/456] my-task", @@ -89,15 +88,12 @@ object PromptLoggerTests extends TestSuite { // footer "[123/456] ============================== TITLE ============================== 10s", "[1] my-task 10s", - "=================================================================================", "[1] WORLD", // Calling `refreshPrompt()` after closing the ticker shows the prompt without // the ticker in the list, with an updated time elapsed "[123/456] ============================== TITLE ============================== 20s", - "=================================================================================", // Closing the prompt prints the prompt one last time with an updated time elapsed "[123/456] ============================== TITLE ============================== 30s", - "=================================================================================", "" ) @@ -111,7 +107,7 @@ object PromptLoggerTests extends TestSuite { promptLogger.setPromptHeaderPrefix("123/456") promptLogger.refreshPrompt() check(promptLogger, baos)( - " [123/456] ============================== TITLE ==============================" + "[123/456] ============================== TITLE ==============================" ) promptLogger.setPromptLine(Seq("1"), "/456", "my-task") @@ -125,7 +121,7 @@ object PromptLoggerTests extends TestSuite { check(promptLogger, baos)( "[1/456] my-task", "[1] HELLO", - " [123/456] ============================ TITLE ============================ 10s", + "[123/456] ============================= TITLE ============================= 10s", "[1] my-task 10s" ) @@ -137,7 +133,7 @@ object PromptLoggerTests extends TestSuite { "[1/456] my-task", "[1] HELLO", "[1] WORLD", - " [123/456] ============================ TITLE ============================ 10s", + "[123/456] ============================= TITLE ============================= 10s", "[1] my-task 10s" ) @@ -168,7 +164,7 @@ object PromptLoggerTests extends TestSuite { "[3/456] my-task-short-lived", "[3] hello short lived", "[3] goodbye short lived", - " [123/456] ============================ TITLE ============================ 10s", + "[123/456] ============================= TITLE ============================= 10s", "[1] my-task 10s" ) @@ -188,7 +184,7 @@ object PromptLoggerTests extends TestSuite { "[3/456] my-task-short-lived", "[3] hello short lived", "[3] goodbye short lived", - " [123/456] ============================ TITLE ============================ 11s", + "[123/456] ============================= TITLE ============================= 11s", "[1] my-task 11s", "[2] my-task-new 1s" ) @@ -209,7 +205,7 @@ object PromptLoggerTests extends TestSuite { "[3/456] my-task-short-lived", "[3] hello short lived", "[3] goodbye short lived", - " [123/456] ============================ TITLE ============================ 11s", + "[123/456] ============================= TITLE ============================= 11s", "[1] my-task 11s", "[2] my-task-new 1s" ) @@ -229,7 +225,7 @@ object PromptLoggerTests extends TestSuite { "[3/456] my-task-short-lived", "[3] hello short lived", "[3] goodbye short lived", - " [123/456] ============================ TITLE ============================ 12s", + "[123/456] ============================= TITLE ============================= 12s", "[2] my-task-new 2s", "" ) @@ -248,7 +244,7 @@ object PromptLoggerTests extends TestSuite { "[3/456] my-task-short-lived", "[3] hello short lived", "[3] goodbye short lived", - " [123/456] ============================ TITLE ============================ 22s", + "[123/456] ============================= TITLE ============================= 22s", "[2] my-task-new 12s" ) now += 10000 @@ -284,20 +280,20 @@ object PromptLoggerTests extends TestSuite { now += 1000 promptLogger.refreshPrompt() check(promptLogger, baos)( - " [123/456] ============================= TITLE ============================ 1s", + "[123/456] ============================== TITLE ============================= 1s", "[1] my-task 1s detail" ) prefixLogger.ticker("detail-too-long-gets-truncated-abcdefghijklmnopqrstuvwxyz1234567890") promptLogger.refreshPrompt() check(promptLogger, baos)( - " [123/456] ============================= TITLE ============================ 1s", + "[123/456] ============================== TITLE ============================= 1s", "[1] my-task 1s detail-too-long-gets-truncated...fghijklmnopqrstuvwxyz1234567890" ) promptLogger.removePromptLine(Seq("1")) now += 10000 promptLogger.refreshPrompt() check(promptLogger, baos)( - " [123/456] ============================ TITLE ============================ 11s" + "[123/456] ============================= TITLE ============================= 11s" ) } } diff --git a/main/util/test/src/mill/util/PromptLoggerUtilTests.scala b/main/util/test/src/mill/util/PromptLoggerUtilTests.scala index fc4ae5ccf95..198c0655903 100644 --- a/main/util/test/src/mill/util/PromptLoggerUtilTests.scala +++ b/main/util/test/src/mill/util/PromptLoggerUtilTests.scala @@ -85,49 +85,49 @@ object PromptLoggerUtilTests extends TestSuite { check("PREFIX", "TITLE", " SUFFIX", maxWidth, expected) test("extra") - checkSimple( 200, - " PREFIX ============================== TITLE ============================== SUFFIX" + "PREFIX ============================== TITLE ============================== SUFFIX" ) test("exact") - checkSimple( - 83, - " PREFIX ============================== TITLE ============================== SUFFIX" + 81, + "PREFIX ============================== TITLE ============================== SUFFIX" ) test("short") - checkSimple( - 82, // One `=` is removed from the right - " PREFIX ============================== TITLE ============================= SUFFIX" + 80, // One `=` is removed from the right + "PREFIX ============================== TITLE ============================= SUFFIX" ) test("shorter") - checkSimple( - 81, // Next `=` is removed from the right - " PREFIX ============================= TITLE ============================= SUFFIX" + 79, // Next `=` is removed from the right + "PREFIX ============================= TITLE ============================= SUFFIX" ) test("shorter2") - checkSimple( 70, // Lots of `=`s removed from both left and right - " PREFIX ======================== TITLE ======================= SUFFIX" + "PREFIX ========================= TITLE ======================== SUFFIX" ) test("beforeShortenTitle") - checkSimple( - 53, // Minimum number of `=` on each side (15) before shortening title - " PREFIX =============== TITLE =============== SUFFIX" + 51, // Minimum number of `=` on each side (15) before shortening title + "PREFIX =============== TITLE =============== SUFFIX" ) test("shortenTitle") - checkSimple( - 52, // Begin shortening Title - " PREFIX =============== T... =============== SUFFIX" + 50, // Begin shortening Title + "PREFIX =============== T... =============== SUFFIX" ) test("shortenTitle2") - checkSimple( - 51, - " PREFIX =============== ... =============== SUFFIX" + 49, + "PREFIX =============== ... =============== SUFFIX" ) test("shortenTitle3") - checkSimple( - 50, // Title is already minimized, have to shorten other parts - " PREFIX =============== ...=============== SUFFIX" + 48, // Title is already minimized, have to shorten other parts + "PREFIX =============== ...=============== SUFFIX" ) test("titleEntirelyGone") - checkSimple( - 30, // Title section entirely removed - " PREFIX ============== SUFFIX" + 28, // Title section entirely removed + "PREFIX ============== SUFFIX" ) test("shortenTitle3") - checkSimple( - 10, // `=`s are all removed - " PR...FIX" + 8, // `=`s are all removed + "PRE...IX" ) } @@ -156,7 +156,7 @@ object PromptLoggerUtilTests extends TestSuite { 1 -> Status(Some(StatusEntry("world", now - 2000)), 0, None) ) val expected = List( - " 123/456 ======================= __.compile ====================== 1337s", + "123/456 ======================== __.compile ======================= 1337s", "hello 1s", "world 2s" ) @@ -181,7 +181,7 @@ object PromptLoggerUtilTests extends TestSuite { ) val expected = List( - " 123/456 =============== __.compile.abcdefghijklmn =============== 1337s", + "123/456 ================ __.compile.abcdefghijklmn ================ 1337s", "#1 hello1234567890abcefghijklmnopqrstuvwxyz1234567890123 1s", "#2 world 2s", "#3 i am cow 3s", @@ -192,7 +192,7 @@ object PromptLoggerUtilTests extends TestSuite { } test("minAfterTruncateHeader") { val rendered = - renderPromptTest(interactive = true, titleText = "__.compile.abcdefghijklmno")( + renderPromptTest(interactive = true, titleText = "__.compile.abcdefghijklmnopq")( 0 -> Status( Some(StatusEntry( "#1 hello1234567890abcefghijklmnopqrstuvwxyz12345678901234", @@ -213,7 +213,7 @@ object PromptLoggerUtilTests extends TestSuite { ) val expected = List( - " 123/456 =============== __.compile....efghijklmno =============== 1337s", + "123/456 =============== __.compile.a...fghijklmnopq =============== 1337s", "#1 hello1234567890abcefghijklmnopqrstuvwxyz12345678901234 1s", "#2 world 2s", "#3 i am cow 3s", @@ -224,7 +224,7 @@ object PromptLoggerUtilTests extends TestSuite { } test("minAfterTruncateRow") { val rendered = - renderPromptTest(interactive = true, titleText = "__.compile.abcdefghijklmno")( + renderPromptTest(interactive = true, titleText = "__.compile.abcdefghijklmnopq")( 0 -> Status( Some(StatusEntry( "#1 hello1234567890abcefghijklmnopqrstuvwxyz1234567890123456789012345678", @@ -245,7 +245,7 @@ object PromptLoggerUtilTests extends TestSuite { ) val expected = List( - " 123/456 =============== __.compile....efghijklmno =============== 1337s", + "123/456 =============== __.compile.a...fghijklmnopq =============== 1337s", "#1 hello1234567890abcefghijklmnopqr...wxyz1234567890123456789012345678 1s", "#2 world 2s", "#3 i am cow 3s", @@ -277,7 +277,7 @@ object PromptLoggerUtilTests extends TestSuite { ) ) val expected = List( - " 123/456 =============== __.compile....z1234567890 =============== 1337s", + "123/456 =============== __.compile.a...yz1234567890 =============== 1337s", "#1 hello1234567890abcefghijklmnopqr...4567890abcefghijklmnopqrstuvwxyz 1s", "#2 world 2s", "#3 i am cow 3s", @@ -311,7 +311,7 @@ object PromptLoggerUtilTests extends TestSuite { ) ) val expected = List( - " 123/456 ======================= __.compile ====================== 1337s", + "123/456 ======================== __.compile ======================= 1337s", "1 hello 1s", "2 world 2s HELLO", "3 truncated-detail 3s HELLO WORLD abcdefghijklmnopqrstuvwxyz1234567890", @@ -364,7 +364,7 @@ object PromptLoggerUtilTests extends TestSuite { ) val expected = List( - " 123/456 =============== __.compile....z1234567890 =============== 1337s", + "123/456 =============== __.compile.a...yz1234567890 =============== 1337s", "#1 hello1234567890abcefghijklmnopqr...4567890abcefghijklmnopqrstuvwxyz 1s", "#3 i am cow 3s", "", @@ -400,7 +400,7 @@ object PromptLoggerUtilTests extends TestSuite { ) val expected = List( - " 123/456 =============== __.compile....z1234567890 =============== 1337s", + "123/456 =============== __.compile.a...yz1234567890 =============== 1337s", "#1 hello1234567890abcefghijklmnopqr...4567890abcefghijklmnopqrstuvwxyz 1s", "#3 i am cow 3s" ) @@ -455,8 +455,7 @@ object PromptLoggerUtilTests extends TestSuite { "123/456 =============== __.compile.a...yz1234567890 =============== 1337s", "#1 hello1234567890abcefghijklmnopqr...4567890abcefghijklmnopqrstuvwxyz 1s", "#2 world 2s", - "#3 i am cow 3s", - "=========================================================================" + "#3 i am cow 3s" ) assert(rendered == expected) }