From 06724d1c4bd053ab6e91af446c0d65e3c2a0173d Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Thu, 15 Sep 2016 01:34:41 -0400 Subject: [PATCH 1/3] Rename early command to `early(command)` Fixes #2734, Ref #1041 e93c4450a1a06fe6c67df821c65fea302cecca84 added a feature called early command, which uses `--` as a prefix to denote some commands that runs ahead of session loading. While the feature might be useful especially for logging, `--` is too useful just for this purpose. --- .../src/main/scala/sbt/BasicCommandStrings.scala | 15 ++++++--------- .../src/main/scala/sbt/BasicCommands.scala | 5 ++++- sbt/src/sbt-test/actions/early-command/build.sbt | 1 + sbt/src/sbt-test/actions/early-command/test | 1 + 4 files changed, 12 insertions(+), 10 deletions(-) create mode 100644 sbt/src/sbt-test/actions/early-command/build.sbt create mode 100644 sbt/src/sbt-test/actions/early-command/test diff --git a/main-command/src/main/scala/sbt/BasicCommandStrings.scala b/main-command/src/main/scala/sbt/BasicCommandStrings.scala index 88ae4a2ca..f9be89146 100644 --- a/main-command/src/main/scala/sbt/BasicCommandStrings.scala +++ b/main-command/src/main/scala/sbt/BasicCommandStrings.scala @@ -60,21 +60,18 @@ ${runEarly(level.toString)} * if no other commands are passed, interactive mode is still entered """ - def runEarly(command: String) = { - val sep = if (command.isEmpty || Character.isLetter(command.charAt(0))) "" else " " - s"$EarlyCommand$sep$command" - } + def runEarly(command: String) = s"$EarlyCommand($command)" private[sbt] def isEarlyCommand(s: String): Boolean = { - s.startsWith(EarlyCommand) && s != Compat.FailureWall && s != Compat.ClearOnFailure + s.startsWith(EarlyCommand + "(") && s.endsWith(")") } - val EarlyCommand = "--" - val EarlyCommandBrief = (s"$EarlyCommand", "Schedules a command to run before other commands on startup.") + val EarlyCommand = "early" + val EarlyCommandBrief = (s"$EarlyCommand()", "Schedules a command to run before other commands on startup.") val EarlyCommandDetailed = - s"""$EarlyCommand + s"""$EarlyCommand() Schedules an early command, which will be run before other commands on the command line. - The order is preserved between all early commands, so `sbt --a --b` executes `a` and `b` in order. + The order is preserved between all early commands, so `sbt "early(a)" "early(b)"` executes `a` and `b` in order. """ def ReadCommand = "<" diff --git a/main-command/src/main/scala/sbt/BasicCommands.scala b/main-command/src/main/scala/sbt/BasicCommands.scala index 517e3a9dd..1a7e32f54 100644 --- a/main-command/src/main/scala/sbt/BasicCommands.scala +++ b/main-command/src/main/scala/sbt/BasicCommands.scala @@ -24,7 +24,10 @@ object BasicCommands { def ignore = Command.command(FailureWall)(idFun) def early = Command.arb(earlyParser, earlyHelp) { (s, other) => other :: s } - private[this] def earlyParser = (s: State) => token(EarlyCommand).flatMap(_ => otherCommandParser(s)) + private[this] def earlyParser = (s: State) => + token(EarlyCommand + "(") flatMap { _ => + otherCommandParser(s) <~ token(")") + } private[this] def earlyHelp = Help(EarlyCommand, EarlyCommandBrief, EarlyCommandDetailed) def help = Command.make(HelpCommand, helpBrief, helpDetailed)(helpParser) diff --git a/sbt/src/sbt-test/actions/early-command/build.sbt b/sbt/src/sbt-test/actions/early-command/build.sbt new file mode 100644 index 000000000..c128b140e --- /dev/null +++ b/sbt/src/sbt-test/actions/early-command/build.sbt @@ -0,0 +1 @@ +lazy val root = (project in file(".")) diff --git a/sbt/src/sbt-test/actions/early-command/test b/sbt/src/sbt-test/actions/early-command/test new file mode 100644 index 000000000..9dd08d035 --- /dev/null +++ b/sbt/src/sbt-test/actions/early-command/test @@ -0,0 +1 @@ +> early(error) From 9529f0c304ad7cae4798f0cd7b395f0e56a623d1 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Thu, 15 Sep 2016 02:23:37 -0400 Subject: [PATCH 2/3] Add `-error` etc for log levels with one hyphen --- .../src/main/scala/sbt/BasicCommandStrings.scala | 6 ++++-- main-command/src/main/scala/sbt/BasicCommands.scala | 12 +++++++++--- sbt/src/sbt-test/actions/early-command/test | 1 + 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/main-command/src/main/scala/sbt/BasicCommandStrings.scala b/main-command/src/main/scala/sbt/BasicCommandStrings.scala index f9be89146..032b51eda 100644 --- a/main-command/src/main/scala/sbt/BasicCommandStrings.scala +++ b/main-command/src/main/scala/sbt/BasicCommandStrings.scala @@ -52,7 +52,7 @@ object BasicCommandStrings { This will be used as the default level for logging from commands, settings, and tasks. Any explicit `logLevel` configuration in a project overrides this setting. -${runEarly(level.toString)} +-$level Sets the global logging level as described above, but does so before any other commands are executed on startup, including project loading. This is useful as a startup option: @@ -62,7 +62,9 @@ ${runEarly(level.toString)} def runEarly(command: String) = s"$EarlyCommand($command)" private[sbt] def isEarlyCommand(s: String): Boolean = { - s.startsWith(EarlyCommand + "(") && s.endsWith(")") + val levelOptions = Level.values.toSeq map { "-" + _ } + (s.startsWith(EarlyCommand + "(") && s.endsWith(")")) || + (levelOptions contains s) } val EarlyCommand = "early" diff --git a/main-command/src/main/scala/sbt/BasicCommands.scala b/main-command/src/main/scala/sbt/BasicCommands.scala index 1a7e32f54..68503fda4 100644 --- a/main-command/src/main/scala/sbt/BasicCommands.scala +++ b/main-command/src/main/scala/sbt/BasicCommands.scala @@ -1,5 +1,6 @@ package sbt +import sbt.util.Level import sbt.internal.util.{ AttributeKey, FullReader } import sbt.internal.util.complete.{ Completion, Completions, DefaultParsers, History => CHistory, HistoryCommands, Parser, TokenCompletions } import sbt.internal.util.Types.{ const, idFun } @@ -24,10 +25,15 @@ object BasicCommands { def ignore = Command.command(FailureWall)(idFun) def early = Command.arb(earlyParser, earlyHelp) { (s, other) => other :: s } - private[this] def earlyParser = (s: State) => - token(EarlyCommand + "(") flatMap { _ => + private[this] def levelParser: Parser[String] = + token(Level.Debug.toString) | token(Level.Info.toString) | token(Level.Warn.toString) | token(Level.Error.toString) + private[this] def earlyParser: State => Parser[String] = (s: State) => + (token(EarlyCommand + "(") flatMap { _ => otherCommandParser(s) <~ token(")") - } + }) | + (token("-") flatMap { _ => + levelParser + }) private[this] def earlyHelp = Help(EarlyCommand, EarlyCommandBrief, EarlyCommandDetailed) def help = Command.make(HelpCommand, helpBrief, helpDetailed)(helpParser) diff --git a/sbt/src/sbt-test/actions/early-command/test b/sbt/src/sbt-test/actions/early-command/test index 9dd08d035..532cef013 100644 --- a/sbt/src/sbt-test/actions/early-command/test +++ b/sbt/src/sbt-test/actions/early-command/test @@ -1 +1,2 @@ +> -error > early(error) From 9783ab176521a65eaa19b9013ea906a32c6f65b3 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Thu, 15 Sep 2016 03:13:08 -0400 Subject: [PATCH 3/3] Migration notes --- MIGRATION.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/MIGRATION.md b/MIGRATION.md index 0278371cf..6f7d67952 100644 --- a/MIGRATION.md +++ b/MIGRATION.md @@ -10,6 +10,8 @@ Migration notes - Removed the pre-0.13.7 *.sbt file parser (previously available under `-Dsbt.parser.simple=true`) - Removed old, hyphen-separated key names (use `publishLocal` instead of `publish-local`) - Removes no-longer-documented old operators `<<=`, `<+=`, and `<++=`. +- Renames early command feature from `--` to `early()`. +- Log options `-error`, `-warn`, `-info`, `-debug` are added as shorthand for `"early(error)"` etc. #### Additional import required