From e689734a17effd2d5e14957bedf928860f4bec9a Mon Sep 17 00:00:00 2001 From: Piotr Chabelski Date: Fri, 24 Feb 2023 15:08:44 +0800 Subject: [PATCH] NIT Use enums for help groups and help command groups (#1880) --- .../scala/scala/cli/ScalaCliCommands.scala | 6 +- .../scala/cli/commands/clean/Clean.scala | 3 +- .../scala/cli/commands/compile/Compile.scala | 18 ++++-- .../cli/commands/compile/CompileOptions.scala | 5 +- .../scala/cli/commands/config/Config.scala | 7 ++- .../cli/commands/config/ConfigOptions.scala | 21 +++---- .../scala/cli/commands/default/Default.scala | 4 +- .../commands/default/DefaultFileOptions.scala | 10 ++-- .../commands/default/LegacyScalaOptions.scala | 13 ++-- .../dependencyupdate/DependencyUpdate.scala | 11 ++-- .../DependencyUpdateOptions.scala | 4 +- .../scala/scala/cli/commands/doc/Doc.scala | 10 ++-- .../scala/cli/commands/doc/DocOptions.scala | 8 +-- .../scala/cli/commands/export0/Export.scala | 9 +-- .../cli/commands/export0/ExportOptions.scala | 22 ++++--- .../scala/scala/cli/commands/fmt/Fmt.scala | 24 +++++--- .../scala/cli/commands/fmt/FmtOptions.scala | 28 ++++----- .../cli/commands/github/SecretCreate.scala | 5 +- .../commands/github/SecretCreateOptions.scala | 6 +- .../cli/commands/github/SecretList.scala | 7 ++- .../commands/github/SharedSecretOptions.scala | 6 +- .../InstallCompletions.scala | 8 ++- .../InstallCompletionsOptions.scala | 14 ++--- .../commands/installhome/InstallHome.scala | 15 +++-- .../installhome/InstallHomeOptions.scala | 12 ++-- .../scala/cli/commands/package0/Package.scala | 32 +++++----- .../commands/package0/PackageOptions.scala | 38 ++++++------ .../commands/package0/PackagerOptions.scala | 51 ++++++++-------- .../cli/commands/pgp/PgpPullOptions.scala | 4 +- .../cli/commands/pgp/PgpPushOptions.scala | 7 ++- .../commands/pgp/PgpScalaSigningOptions.scala | 8 +-- .../pgp/SharedPgpPushPullOptions.scala | 4 +- .../scala/cli/commands/publish/Publish.scala | 22 ++++--- .../cli/commands/publish/PublishLocal.scala | 6 +- .../cli/commands/publish/PublishOptions.scala | 4 +- .../publish/PublishParamsOptions.scala | 27 +++++---- .../publish/PublishRepositoryOptions.scala | 9 +-- .../cli/commands/publish/PublishSetup.scala | 10 ++-- .../publish/PublishSetupOptions.scala | 16 ++--- .../publish/SharedPublishOptions.scala | 25 ++++---- .../scala/scala/cli/commands/repl/Repl.scala | 8 +-- .../cli/commands/repl/SharedReplOptions.scala | 9 +-- .../scala/scala/cli/commands/run/Run.scala | 13 ++-- .../cli/commands/run/SharedRunOptions.scala | 23 +++---- .../commands/shared/BenchmarkingOptions.scala | 4 +- .../cli/commands/shared/CoursierOptions.scala | 6 +- .../commands/shared/HelpGroupOptions.scala | 14 ++--- .../cli/commands/shared/HelpGroups.scala | 36 +++++++++++ .../cli/commands/shared/JavaPropOptions.scala | 2 +- .../cli/commands/shared/LoggingOptions.scala | 4 +- .../commands/shared/MainClassOptions.scala | 4 +- .../cli/commands/shared/MarkdownOptions.scala | 2 +- .../cli/commands/shared/ScalaCliHelp.scala | 60 ++++++++----------- .../cli/commands/shared/ScalaJsOptions.scala | 38 ++++++------ .../commands/shared/ScalaNativeOptions.scala | 22 +++---- .../commands/shared/ScalacExtraOptions.scala | 4 +- .../cli/commands/shared/ScalacOptions.scala | 2 +- .../shared/SharedBspFileOptions.scala | 4 +- .../SharedCompilationServerOptions.scala | 30 +++++----- .../commands/shared/SharedDebugOptions.scala | 6 +- .../shared/SharedDependencyOptions.scala | 6 +- .../commands/shared/SharedJavaOptions.scala | 2 +- .../commands/shared/SharedJvmOptions.scala | 16 ++--- .../cli/commands/shared/SharedOptions.scala | 25 ++++---- .../commands/shared/SharedWatchOptions.scala | 4 +- .../cli/commands/shared/SnippetOptions.scala | 16 ++--- .../commands/shared/VerbosityOptions.scala | 6 +- .../scala/cli/commands/shebang/Shebang.scala | 6 +- .../scala/scala/cli/commands/test/Test.scala | 11 ++-- .../scala/cli/commands/test/TestOptions.scala | 15 ++--- .../commands/uninstall/UninstallOptions.scala | 7 ++- .../SharedUninstallCompletionsOptions.scala | 7 ++- .../UninstallCompletions.scala | 8 ++- .../scala/cli/commands/update/Update.scala | 7 ++- .../cli/commands/update/UpdateOptions.scala | 7 ++- .../scala/cli/commands/version/Version.scala | 18 +++--- .../cli/commands/version/VersionOptions.scala | 8 +-- .../scala/cli/launcher/LauncherOptions.scala | 7 ++- .../scala/scala/cli/util/ArgHelpers.scala | 24 ++++++-- 79 files changed, 561 insertions(+), 469 deletions(-) create mode 100644 modules/cli/src/main/scala/scala/cli/commands/shared/HelpGroups.scala diff --git a/modules/cli/src/main/scala/scala/cli/ScalaCliCommands.scala b/modules/cli/src/main/scala/scala/cli/ScalaCliCommands.scala index 68beaf459f..53ea8167b4 100644 --- a/modules/cli/src/main/scala/scala/cli/ScalaCliCommands.scala +++ b/modules/cli/src/main/scala/scala/cli/ScalaCliCommands.scala @@ -1,11 +1,11 @@ package scala.cli import caseapp.core.app.CommandsEntryPoint -import caseapp.core.help.{Help, RuntimeCommandsHelp} +import caseapp.core.help.{Help, HelpFormat, RuntimeCommandsHelp} import java.nio.file.InvalidPathException -import scala.cli.commands._ +import scala.cli.commands.* import scala.cli.commands.shared.ScalaCliHelp class ScalaCliCommands( @@ -91,7 +91,7 @@ class ScalaCliCommands( override def enableCompleteCommand = true override def enableCompletionsCommand = true - override def helpFormat = ScalaCliHelp.helpFormat + override def helpFormat: HelpFormat = ScalaCliHelp.helpFormat private def isShebangFile(arg: String): Boolean = { val pathOpt = diff --git a/modules/cli/src/main/scala/scala/cli/commands/clean/Clean.scala b/modules/cli/src/main/scala/scala/cli/commands/clean/Clean.scala index 4b14250816..5c4408db45 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/clean/Clean.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/clean/Clean.scala @@ -7,10 +7,11 @@ import scala.build.internal.Constants import scala.build.{Logger, Os} import scala.cli.commands.ScalaCommand import scala.cli.commands.setupide.SetupIde +import scala.cli.commands.shared.HelpCommandGroup import scala.cli.{CurrentParams, ScalaCli} object Clean extends ScalaCommand[CleanOptions] { - override def group = "Main" + override def group: String = HelpCommandGroup.Main.toString override def scalaSpecificationLevel = SpecificationLevel.IMPLEMENTATION diff --git a/modules/cli/src/main/scala/scala/cli/commands/compile/Compile.scala b/modules/cli/src/main/scala/scala/cli/commands/compile/Compile.scala index dd2d318c3d..489376e667 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/compile/Compile.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/compile/Compile.scala @@ -10,21 +10,27 @@ import scala.build.{Build, BuildThreads, Builds, Logger, Os} import scala.cli.CurrentParams import scala.cli.commands.publish.ConfigUtil.* import scala.cli.commands.setupide.SetupIde -import scala.cli.commands.shared.SharedOptions +import scala.cli.commands.shared.{HelpCommandGroup, HelpGroup, SharedOptions} import scala.cli.commands.update.Update import scala.cli.commands.util.BuildCommandHelpers -import scala.cli.commands.{CommandUtils, ScalaCommand, WatchUtil} +import scala.cli.commands.{CommandUtils, ScalaCommand, SpecificationLevel, WatchUtil} import scala.cli.config.{ConfigDb, Keys} import scala.cli.util.ArgHelpers.* object Compile extends ScalaCommand[CompileOptions] with BuildCommandHelpers { - override def group = "Main" + override def group: String = HelpCommandGroup.Main.toString override def sharedOptions(options: CompileOptions): Option[SharedOptions] = Some(options.shared) - override def scalaSpecificationLevel = SpecificationLevel.MUST - val primaryHelpGroups: Seq[String] = - Seq("Compilation", "Scala", "Java", "Watch", "Compilation server") + override def scalaSpecificationLevel: SpecificationLevel = SpecificationLevel.MUST + val primaryHelpGroups: Seq[HelpGroup] = + Seq( + HelpGroup.Compilation, + HelpGroup.Scala, + HelpGroup.Java, + HelpGroup.Watch, + HelpGroup.CompilationServer + ) override def helpFormat: HelpFormat = super.helpFormat.withPrimaryGroups(primaryHelpGroups) diff --git a/modules/cli/src/main/scala/scala/cli/commands/compile/CompileOptions.scala b/modules/cli/src/main/scala/scala/cli/commands/compile/CompileOptions.scala index a5ca8bc42f..b9751fda95 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/compile/CompileOptions.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/compile/CompileOptions.scala @@ -6,6 +6,7 @@ import caseapp.core.help.Help import scala.cli.commands.shared.{ CrossOptions, HasSharedOptions, + HelpGroup, HelpMessages, SharedOptions, SharedWatchOptions @@ -22,7 +23,7 @@ final case class CompileOptions( @Recurse cross: CrossOptions = CrossOptions(), - @Group("Compilation") + @Group(HelpGroup.Compilation.toString) @Name("p") @Name("printClasspath") @HelpMessage("Print the resulting class path") @@ -30,7 +31,7 @@ final case class CompileOptions( @Tag(tags.inShortHelp) printClassPath: Boolean = false, - @Group("Compilation") + @Group(HelpGroup.Compilation.toString) @HelpMessage("Compile test scope") @Tag(tags.should) @Tag(tags.inShortHelp) diff --git a/modules/cli/src/main/scala/scala/cli/commands/config/Config.scala b/modules/cli/src/main/scala/scala/cli/commands/config/Config.scala index f34765e4b3..8d44578289 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/config/Config.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/config/Config.scala @@ -11,6 +11,7 @@ import scala.build.errors.{BuildException, CompositeBuildException, MalformedCli import scala.build.{Directories, Logger} import scala.cli.commands.pgp.PgpScalaSigningOptions import scala.cli.commands.publish.ConfigUtil.* +import scala.cli.commands.shared.HelpGroup import scala.cli.commands.util.JvmUtils import scala.cli.commands.{ScalaCommand, SpecificationLevel} import scala.cli.config.{ @@ -23,11 +24,11 @@ import scala.cli.config.{ } import scala.cli.util.ArgHelpers.* object Config extends ScalaCommand[ConfigOptions] { - override def scalaSpecificationLevel = SpecificationLevel.MUST + override def scalaSpecificationLevel: SpecificationLevel = SpecificationLevel.MUST override def helpFormat: HelpFormat = super.helpFormat - .copy(hiddenGroups = Some(Seq("Java"))) - .withPrimaryGroup("Config") + .withHiddenGroup(HelpGroup.Java) + .withPrimaryGroup(HelpGroup.Config) override def runCommand(options: ConfigOptions, args: RemainingArgs, logger: Logger): Unit = { val directories = Directories.directories diff --git a/modules/cli/src/main/scala/scala/cli/commands/config/ConfigOptions.scala b/modules/cli/src/main/scala/scala/cli/commands/config/ConfigOptions.scala index c9e79d80b7..c660c31b09 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/config/ConfigOptions.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/config/ConfigOptions.scala @@ -7,6 +7,7 @@ import scala.cli.commands.pgp.PgpScalaSigningOptions import scala.cli.commands.shared.{ CoursierOptions, HasLoggingOptions, + HelpGroup, HelpMessages, LoggingOptions, SharedJvmOptions @@ -25,54 +26,54 @@ final case class ConfigOptions( @Recurse @Tag(tags.restricted) scalaSigning: PgpScalaSigningOptions = PgpScalaSigningOptions(), - @Group("Config") + @Group(HelpGroup.Config.toString) @HelpMessage("Dump config DB as JSON") @Hidden @Tag(tags.implementation) @Tag(tags.inShortHelp) dump: Boolean = false, - @Group("Config") + @Group(HelpGroup.Config.toString) @HelpMessage("Create PGP key in config") @Tag(tags.inShortHelp) @Tag(tags.restricted) createPgpKey: Boolean = false, - @Group("Config") + @Group(HelpGroup.Config.toString) @HelpMessage("Email to use to create PGP key in config") @Tag(tags.restricted) @Tag(tags.inShortHelp) email: Option[String] = None, - @Group("Config") + @Group(HelpGroup.Config.toString) @HelpMessage("If the entry is a password, print the password value rather than how to get the password") @Tag(tags.restricted) @Tag(tags.inShortHelp) password: Boolean = false, - @Group("Config") + @Group(HelpGroup.Config.toString) @HelpMessage("If the entry is a password, save the password value rather than how to get the password") @Tag(tags.restricted) @Tag(tags.inShortHelp) passwordValue: Boolean = false, - @Group("Config") + @Group(HelpGroup.Config.toString) @HelpMessage("Remove an entry from config") @Tag(tags.inShortHelp) @Tag(tags.should) @ExtraName("remove") unset: Boolean = false, - @Group("Config") + @Group(HelpGroup.Config.toString) @HelpMessage("For repository.credentials and publish.credentials, whether these credentials should be HTTPS only (default: true)") @Tag(tags.restricted) @Tag(tags.inShortHelp) httpsOnly: Option[Boolean] = None, - @Group("Config") + @Group(HelpGroup.Config.toString) @HelpMessage("For repository.credentials, whether to use these credentials automatically based on the host") @Tag(tags.restricted) @Tag(tags.inShortHelp) matchHost: Option[Boolean] = None, - @Group("Config") + @Group(HelpGroup.Config.toString) @HelpMessage("For repository.credentials, whether to use these credentials are optional") @Tag(tags.restricted) @Tag(tags.inShortHelp) optional: Option[Boolean] = None, - @Group("Config") + @Group(HelpGroup.Config.toString) @HelpMessage("For repository.credentials, whether to use these credentials should be passed upon redirection") @Tag(tags.restricted) @Tag(tags.inShortHelp) diff --git a/modules/cli/src/main/scala/scala/cli/commands/default/Default.scala b/modules/cli/src/main/scala/scala/cli/commands/default/Default.scala index 2519fef853..590c45af7b 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/default/Default.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/default/Default.scala @@ -11,7 +11,7 @@ import scala.cli.CurrentParams import scala.cli.commands.repl.{Repl, ReplOptions} import scala.cli.commands.run.{Run, RunOptions} import scala.cli.commands.shared.ScalaCliHelp.helpFormat -import scala.cli.commands.shared.SharedOptions +import scala.cli.commands.shared.{HelpCommandGroup, SharedOptions} import scala.cli.commands.version.{Version, VersionOptions} import scala.cli.commands.{ScalaCommand, ScalaCommandWithCustomHelp} import scala.cli.launcher.LauncherOptions @@ -36,7 +36,7 @@ class Default( override def scalaSpecificationLevel = SpecificationLevel.MUST - override def group = "Main" + override def group: String = HelpCommandGroup.Main.toString override def sharedOptions(options: DefaultOptions): Option[SharedOptions] = Some(options.shared) diff --git a/modules/cli/src/main/scala/scala/cli/commands/default/DefaultFileOptions.scala b/modules/cli/src/main/scala/scala/cli/commands/default/DefaultFileOptions.scala index c0239a9041..c05b32ee23 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/default/DefaultFileOptions.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/default/DefaultFileOptions.scala @@ -3,7 +3,7 @@ package scala.cli.commands.default import caseapp.* import scala.cli.ScalaCli.fullRunnerName -import scala.cli.commands.shared.{HasLoggingOptions, HelpMessages, LoggingOptions} +import scala.cli.commands.shared.{HasLoggingOptions, HelpGroup, HelpMessages, LoggingOptions} import scala.cli.commands.tags // format: off @@ -14,19 +14,19 @@ import scala.cli.commands.tags final case class DefaultFileOptions( @Recurse logging: LoggingOptions = LoggingOptions(), - @Group("Default") + @Group(HelpGroup.Default.toString) @HelpMessage("Write result to files rather than to stdout") @Tag(tags.restricted) write: Boolean = false, - @Group("Default") + @Group(HelpGroup.Default.toString) @HelpMessage("List available default files") @Tag(tags.restricted) list: Boolean = false, - @Group("Default") + @Group(HelpGroup.Default.toString) @HelpMessage("List available default file ids") @Tag(tags.restricted) listIds: Boolean = false, - @Group("Default") + @Group(HelpGroup.Default.toString) @HelpMessage("Force overwriting destination files") @ExtraName("f") @Tag(tags.restricted) diff --git a/modules/cli/src/main/scala/scala/cli/commands/default/LegacyScalaOptions.scala b/modules/cli/src/main/scala/scala/cli/commands/default/LegacyScalaOptions.scala index c7708f9ca8..074f0320cf 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/default/LegacyScalaOptions.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/default/LegacyScalaOptions.scala @@ -9,6 +9,7 @@ import scala.cli.ScalaCli.{fullRunnerName, progName} import scala.cli.commands.bloop.BloopExit import scala.cli.commands.default.LegacyScalaOptions.* import scala.cli.commands.package0.Package +import scala.cli.commands.shared.HelpGroup import scala.cli.commands.shared.HelpMessages.PowerString import scala.cli.commands.shared.ScalacOptions.YScriptRunnerOption import scala.cli.commands.tags @@ -17,39 +18,39 @@ import scala.cli.commands.tags */ // format: off case class LegacyScalaOptions( - @Group("Legacy Scala runner") + @Group(HelpGroup.LegacyScalaRunner.toString) @HelpMessage(s"Ignored legacy option. Deprecated equivalent of running a subsequent `$PowerString${Package.name}` command.") @Tag(tags.must) @Hidden @Name("-save") save: Option[Indexed[Boolean]] = None, - @Group("Legacy Scala runner") + @Group(HelpGroup.LegacyScalaRunner.toString) @HelpMessage("Ignored legacy option. Deprecated override canceling the `-nosave` option.") @Tag(tags.must) @Hidden @Name("-nosave") nosave: Option[Indexed[Boolean]] = None, - @Group("Legacy Scala runner") + @Group(HelpGroup.LegacyScalaRunner.toString) @HelpMessage("Ignored legacy option. Deprecated override defining how the runner should treat the input. Use the appropriate sub-command instead.") @Tag(tags.must) @Hidden @ValueDescription("object|script|jar|repl|guess") @Name("-howtorun") howToRun: Option[Indexed[String]] = None, - @Group("Legacy Scala runner") + @Group(HelpGroup.LegacyScalaRunner.toString) @HelpMessage("Ignored legacy option. Deprecated option allowing to preload inputs for the repl or command execution.") @Tag(tags.must) @Hidden @ValueDescription("file") I: Option[Indexed[List[String]]] = None, - @Group("Legacy Scala runner") + @Group(HelpGroup.LegacyScalaRunner.toString) @HelpMessage("Ignored legacy option. Deprecated option allowing to prevent the use of the legacy fsc compilation daemon.") @Tag(tags.must) @Hidden @Name("-nc") @Name("-nocompdaemon") noCompilationDaemon: Option[Indexed[Boolean]] = None, - @Group("Legacy Scala runner") + @Group(HelpGroup.LegacyScalaRunner.toString) @HelpMessage("Ignored legacy option. Deprecated option allowing to force the `run` mode on an input.") @Tag(tags.must) @Hidden diff --git a/modules/cli/src/main/scala/scala/cli/commands/dependencyupdate/DependencyUpdate.scala b/modules/cli/src/main/scala/scala/cli/commands/dependencyupdate/DependencyUpdate.scala index 63d47bcd81..37bd84211b 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/dependencyupdate/DependencyUpdate.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/dependencyupdate/DependencyUpdate.scala @@ -9,14 +9,15 @@ import scala.build.internal.CustomCodeWrapper import scala.build.options.{BuildOptions, Scope} import scala.build.{CrossSources, Logger, Position, Sources} import scala.cli.CurrentParams -import scala.cli.commands.ScalaCommand -import scala.cli.commands.shared.SharedOptions +import scala.cli.commands.shared.{HelpCommandGroup, HelpGroup, SharedOptions} +import scala.cli.commands.{ScalaCommand, SpecificationLevel} import scala.cli.util.ArgHelpers.* object DependencyUpdate extends ScalaCommand[DependencyUpdateOptions] { - override def group = "Main" - override def scalaSpecificationLevel = SpecificationLevel.RESTRICTED - override def helpFormat: HelpFormat = super.helpFormat.withPrimaryGroup("Dependency") + override def group: String = HelpCommandGroup.Main.toString + override def scalaSpecificationLevel: SpecificationLevel = SpecificationLevel.RESTRICTED + override def helpFormat: HelpFormat = + super.helpFormat.withPrimaryGroup(HelpGroup.Dependency) override def sharedOptions(options: DependencyUpdateOptions): Option[SharedOptions] = Some(options.shared) override def runCommand( diff --git a/modules/cli/src/main/scala/scala/cli/commands/dependencyupdate/DependencyUpdateOptions.scala b/modules/cli/src/main/scala/scala/cli/commands/dependencyupdate/DependencyUpdateOptions.scala index 1963db90d2..6a8ff9cf8f 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/dependencyupdate/DependencyUpdateOptions.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/dependencyupdate/DependencyUpdateOptions.scala @@ -3,7 +3,7 @@ package scala.cli.commands.dependencyupdate import caseapp.* import caseapp.core.help.Help -import scala.cli.commands.shared.{HasSharedOptions, SharedOptions} +import scala.cli.commands.shared.{HasSharedOptions, HelpGroup, SharedOptions} import scala.cli.commands.tags // format: off @@ -11,7 +11,7 @@ import scala.cli.commands.tags final case class DependencyUpdateOptions( @Recurse shared: SharedOptions = SharedOptions(), - @Group("Dependency") + @Group(HelpGroup.Dependency.toString) @HelpMessage("Update all dependencies if a newer version was released") @Tag(tags.restricted) @Tag(tags.inShortHelp) diff --git a/modules/cli/src/main/scala/scala/cli/commands/doc/Doc.scala b/modules/cli/src/main/scala/scala/cli/commands/doc/Doc.scala index 80a9f2ad99..b658b8a477 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/doc/Doc.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/doc/Doc.scala @@ -15,21 +15,21 @@ import scala.build.internal.Runner import scala.build.options.BuildOptions import scala.cli.CurrentParams import scala.cli.commands.publish.ConfigUtil.* -import scala.cli.commands.shared.SharedOptions -import scala.cli.commands.{CommandUtils, ScalaCommand} +import scala.cli.commands.shared.{HelpCommandGroup, HelpGroup, SharedOptions} +import scala.cli.commands.{CommandUtils, ScalaCommand, SpecificationLevel} import scala.cli.config.{ConfigDb, Keys} import scala.cli.errors.ScaladocGenerationFailedError import scala.cli.util.ArgHelpers.* import scala.util.Properties object Doc extends ScalaCommand[DocOptions] { - override def group = "Main" + override def group: String = HelpCommandGroup.Main.toString override def sharedOptions(options: DocOptions): Option[SharedOptions] = Some(options.shared) - override def helpFormat: HelpFormat = super.helpFormat.withPrimaryGroup("Doc") + override def helpFormat: HelpFormat = super.helpFormat.withPrimaryGroup(HelpGroup.Doc) - override def scalaSpecificationLevel = SpecificationLevel.MUST + override def scalaSpecificationLevel: SpecificationLevel = SpecificationLevel.MUST override def runCommand(options: DocOptions, args: RemainingArgs, logger: Logger): Unit = { val initialBuildOptions = buildOptionsOrExit(options) diff --git a/modules/cli/src/main/scala/scala/cli/commands/doc/DocOptions.scala b/modules/cli/src/main/scala/scala/cli/commands/doc/DocOptions.scala index 4b95e8b747..aceaebeda9 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/doc/DocOptions.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/doc/DocOptions.scala @@ -4,7 +4,7 @@ import caseapp.* import caseapp.core.help.Help import scala.cli.ScalaCli.fullRunnerName -import scala.cli.commands.shared.{HasSharedOptions, HelpMessages, SharedOptions} +import scala.cli.commands.shared.{HasSharedOptions, HelpGroup, HelpMessages, SharedOptions} import scala.cli.commands.tags // format: off @@ -12,17 +12,17 @@ import scala.cli.commands.tags final case class DocOptions( @Recurse shared: SharedOptions = SharedOptions(), - @Group("Doc") + @Group(HelpGroup.Doc.toString) @Tag(tags.must) @HelpMessage("Set the destination path") @Name("o") output: Option[String] = None, - @Group("Doc") + @Group(HelpGroup.Doc.toString) @HelpMessage("Overwrite the destination directory, if it exists") @Tag(tags.must) @Name("f") force: Boolean = false, - @Group("Doc") + @Group(HelpGroup.Doc.toString) @HelpMessage(s"Control if $fullRunnerName should use default options for scaladoc, true by default. Use `--default-scaladoc-opts:false` to not include default options.") @Tag(tags.should) @ExtraName("defaultScaladocOpts") diff --git a/modules/cli/src/main/scala/scala/cli/commands/export0/Export.scala b/modules/cli/src/main/scala/scala/cli/commands/export0/Export.scala index 3d4ec44b78..ad5549a5b8 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/export0/Export.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/export0/Export.scala @@ -18,16 +18,17 @@ import scala.build.input.Inputs import scala.build.internal.{Constants, CustomCodeWrapper} import scala.build.options.{BuildOptions, Platform, Scope} import scala.cli.CurrentParams -import scala.cli.commands.ScalaCommand -import scala.cli.commands.shared.SharedOptions +import scala.cli.commands.shared.{HelpGroup, SharedOptions} +import scala.cli.commands.{ScalaCommand, SpecificationLevel} import scala.cli.exportCmd.* import scala.cli.util.ArgHelpers.* import scala.util.Using object Export extends ScalaCommand[ExportOptions] { - override def scalaSpecificationLevel = SpecificationLevel.RESTRICTED + override def scalaSpecificationLevel: SpecificationLevel = SpecificationLevel.RESTRICTED - override def helpFormat: HelpFormat = super.helpFormat.withPrimaryGroup("Build Tool export") + override def helpFormat: HelpFormat = + super.helpFormat.withPrimaryGroup(HelpGroup.BuildToolExport) private def prepareBuild( inputs: Inputs, diff --git a/modules/cli/src/main/scala/scala/cli/commands/export0/ExportOptions.scala b/modules/cli/src/main/scala/scala/cli/commands/export0/ExportOptions.scala index a18cc19f0e..c9c6543cdd 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/export0/ExportOptions.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/export0/ExportOptions.scala @@ -3,7 +3,13 @@ package scala.cli.commands.export0 import caseapp.* import scala.cli.ScalaCli.fullRunnerName -import scala.cli.commands.shared.{HasSharedOptions, HelpMessages, MainClassOptions, SharedOptions} +import scala.cli.commands.shared.{ + HasSharedOptions, + HelpGroup, + HelpMessages, + MainClassOptions, + SharedOptions +} import scala.cli.commands.tags // format: off @@ -15,37 +21,37 @@ final case class ExportOptions( @Recurse mainClass: MainClassOptions = MainClassOptions(), - @Group("Build Tool export") + @Group(HelpGroup.BuildToolExport.toString) @Tag(tags.restricted) @Tag(tags.inShortHelp) @HelpMessage("Sets the export format to SBT") sbt: Option[Boolean] = None, - @Group("Build Tool export") + @Group(HelpGroup.BuildToolExport.toString) @Tag(tags.restricted) @Tag(tags.inShortHelp) @HelpMessage("Sets the export format to Mill") mill: Option[Boolean] = None, @Tag(tags.restricted) @Tag(tags.inShortHelp) - @Group("Build Tool export") + @Group(HelpGroup.BuildToolExport.toString) @HelpMessage("Sets the export format to Json") json: Option[Boolean] = None, @Name("setting") - @Group("Build Tool export") + @Group(HelpGroup.BuildToolExport.toString) @Tag(tags.restricted) sbtSetting: List[String] = Nil, @Name("p") - @Group("Build Tool export") + @Group(HelpGroup.BuildToolExport.toString) @Tag(tags.restricted) @HelpMessage("Project name to be used on Mill build file") project: Option[String] = None, - @Group("Build Tool export") + @Group(HelpGroup.BuildToolExport.toString) @Tag(tags.restricted) @HelpMessage("Version of SBT to be used for the export") sbtVersion: Option[String] = None, @Name("o") - @Group("Build Tool export") + @Group(HelpGroup.BuildToolExport.toString) @Tag(tags.restricted) output: Option[String] = None ) extends HasSharedOptions diff --git a/modules/cli/src/main/scala/scala/cli/commands/fmt/Fmt.scala b/modules/cli/src/main/scala/scala/cli/commands/fmt/Fmt.scala index 08136b0cc6..ecc3fe7749 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/fmt/Fmt.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/fmt/Fmt.scala @@ -11,22 +11,28 @@ import scala.build.{Logger, Sources} import scala.cli.CurrentParams import scala.cli.commands.ScalaCommand import scala.cli.commands.fmt.FmtUtil.* -import scala.cli.commands.shared.SharedOptions +import scala.cli.commands.shared.{HelpCommandGroup, HelpGroup, SharedOptions} import scala.cli.util.ArgHelpers.* object Fmt extends ScalaCommand[FmtOptions] { - override def group: String = "Main" + override def group: String = HelpCommandGroup.Main.toString override def sharedOptions(options: FmtOptions): Option[SharedOptions] = Some(options.shared) override def scalaSpecificationLevel = SpecificationLevel.SHOULD - val hiddenHelpGroups: Seq[String] = - Seq("Scala", "Java", "Dependency", "Scala.js", "Scala Native", "Compilation server", "Debug") - override def helpFormat: HelpFormat = super.helpFormat - .copy( - hiddenGroups = Some(hiddenHelpGroups), - hiddenGroupsWhenShowHidden = Some(hiddenHelpGroups) + val hiddenHelpGroups: Seq[HelpGroup] = + Seq( + HelpGroup.Scala, + HelpGroup.Java, + HelpGroup.Dependency, + HelpGroup.ScalaJs, + HelpGroup.ScalaNative, + HelpGroup.CompilationServer, + HelpGroup.Debug ) - .withPrimaryGroup("Format") + override def helpFormat: HelpFormat = super.helpFormat + .withHiddenGroups(hiddenHelpGroups) + .withHiddenGroupsWhenShowHidden(hiddenHelpGroups) + .withPrimaryGroup(HelpGroup.Format) override def names: List[List[String]] = List( List("fmt"), List("format"), diff --git a/modules/cli/src/main/scala/scala/cli/commands/fmt/FmtOptions.scala b/modules/cli/src/main/scala/scala/cli/commands/fmt/FmtOptions.scala index 66a2265666..b91629a3e5 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/fmt/FmtOptions.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/fmt/FmtOptions.scala @@ -8,7 +8,7 @@ import scala.build.errors.BuildException import scala.build.internal.FetchExternalBinary import scala.build.options.BuildOptions import scala.cli.ScalaCli.fullRunnerName -import scala.cli.commands.shared.{HasSharedOptions, HelpMessages, SharedOptions} +import scala.cli.commands.shared.{HasSharedOptions, HelpGroup, HelpMessages, SharedOptions} import scala.cli.commands.{Constants, tags} import scala.util.Properties @@ -18,72 +18,72 @@ final case class FmtOptions( @Recurse shared: SharedOptions = SharedOptions(), - @Group("Format") + @Group(HelpGroup.Format.toString) @Tag(tags.should) @Tag(tags.inShortHelp) @HelpMessage("Check if sources are well formatted") check: Boolean = false, - @Group("Format") + @Group(HelpGroup.Format.toString) @Tag(tags.implementation) @HelpMessage("Use project filters defined in the configuration. Turned on by default, use `--respect-project-filters:false` to disable it.") respectProjectFilters: Boolean = true, - @Group("Format") + @Group(HelpGroup.Format.toString) @Tag(tags.implementation) @Tag(tags.inShortHelp) @HelpMessage("Saves .scalafmt.conf file if it was created or overwritten") saveScalafmtConf: Boolean = false, - @Group("Format") + @Group(HelpGroup.Format.toString) @Tag(tags.implementation) @Hidden osArchSuffix: Option[String] = None, - @Group("Format") + @Group(HelpGroup.Format.toString) @Tag(tags.implementation) @Hidden scalafmtTag: Option[String] = None, - @Group("Format") + @Group(HelpGroup.Format.toString) @Tag(tags.implementation) @Hidden scalafmtGithubOrgName: Option[String] = None, - @Group("Format") + @Group(HelpGroup.Format.toString) @Tag(tags.implementation) @Hidden scalafmtExtension: Option[String] = None, - @Group("Format") + @Group(HelpGroup.Format.toString) @Tag(tags.implementation) @Hidden scalafmtLauncher: Option[String] = None, - @Group("Format") + @Group(HelpGroup.Format.toString) @Name("F") @Tag(tags.implementation) @HelpMessage("Pass an argument to scalafmt.") @Tag(tags.inShortHelp) scalafmtArg: List[String] = Nil, - @Group("Format") + @Group(HelpGroup.Format.toString) @HelpMessage("Custom path to the scalafmt configuration file.") @Tag(tags.implementation) @Tag(tags.inShortHelp) @Name("scalafmtConfig") scalafmtConf: Option[String] = None, - @Group("Format") + @Group(HelpGroup.Format.toString) @Tag(tags.implementation) @HelpMessage("Pass configuration as a string.") @Name("scalafmtConfigStr") @Name("scalafmtConfSnippet") scalafmtConfStr: Option[String] = None, @Tag(tags.implementation) - @Group("Format") + @Group(HelpGroup.Format.toString) @HelpMessage("Pass a global dialect for scalafmt. This overrides whatever value is configured in the .scalafmt.conf file or inferred based on Scala version used.") @Tag(tags.implementation) @Name("dialect") @Tag(tags.inShortHelp) scalafmtDialect: Option[String] = None, @Tag(tags.implementation) - @Group("Format") + @Group(HelpGroup.Format.toString) @HelpMessage(s"Pass scalafmt version before running it (${Constants.defaultScalafmtVersion} by default). If passed, this overrides whatever value is configured in the .scalafmt.conf file.") @Name("fmtVersion") @Tag(tags.inShortHelp) diff --git a/modules/cli/src/main/scala/scala/cli/commands/github/SecretCreate.scala b/modules/cli/src/main/scala/scala/cli/commands/github/SecretCreate.scala index 2bff90998c..7dbe06fd7e 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/github/SecretCreate.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/github/SecretCreate.scala @@ -12,6 +12,7 @@ import java.util.Base64 import scala.build.EitherCps.{either, value} import scala.build.Logger import scala.cli.commands.publish.ConfigUtil.* +import scala.cli.commands.shared.HelpGroup import scala.cli.commands.util.ScalaCliSttpBackend import scala.cli.commands.{ScalaCommand, SpecificationLevel} import scala.cli.config.{PasswordOption, Secret} @@ -20,8 +21,8 @@ import scala.cli.util.ArgHelpers.* object SecretCreate extends ScalaCommand[SecretCreateOptions] { - override def scalaSpecificationLevel = SpecificationLevel.RESTRICTED - override def helpFormat: HelpFormat = super.helpFormat.withPrimaryGroup("Secret") + override def scalaSpecificationLevel: SpecificationLevel = SpecificationLevel.RESTRICTED + override def helpFormat: HelpFormat = super.helpFormat.withPrimaryGroup(HelpGroup.Secret) override def names = List( List("github", "secret", "create"), List("gh", "secret", "create") diff --git a/modules/cli/src/main/scala/scala/cli/commands/github/SecretCreateOptions.scala b/modules/cli/src/main/scala/scala/cli/commands/github/SecretCreateOptions.scala index 5eb6c8a227..5375bfde3a 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/github/SecretCreateOptions.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/github/SecretCreateOptions.scala @@ -3,7 +3,7 @@ package scala.cli.commands.github import caseapp.* import scala.cli.ScalaCli.progName -import scala.cli.commands.shared.{CoursierOptions, HelpMessages} +import scala.cli.commands.shared.{CoursierOptions, HelpGroup, HelpMessages} import scala.cli.commands.tags // format: off @@ -16,7 +16,7 @@ final case class SecretCreateOptions( shared: SharedSecretOptions = SharedSecretOptions(), @Recurse coursier: CoursierOptions = CoursierOptions(), - @Group("Secret") + @Group(HelpGroup.Secret.toString) @Tag(tags.restricted) @Tag(tags.inShortHelp) @ExtraName("pubKey") @@ -26,7 +26,7 @@ final case class SecretCreateOptions( dummy: Boolean = false, @Hidden @Tag(tags.implementation) - @Group("Secret") + @Group(HelpGroup.Secret.toString) printRequest: Boolean = false ) extends HasSharedSecretOptions // format: on diff --git a/modules/cli/src/main/scala/scala/cli/commands/github/SecretList.scala b/modules/cli/src/main/scala/scala/cli/commands/github/SecretList.scala index 462cc2730a..030acdc1f2 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/github/SecretList.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/github/SecretList.scala @@ -7,18 +7,19 @@ import sttp.client3.* import scala.build.EitherCps.{either, value} import scala.build.Logger -import scala.cli.commands.ScalaCommand import scala.cli.commands.publish.ConfigUtil.* +import scala.cli.commands.shared.HelpGroup import scala.cli.commands.util.ScalaCliSttpBackend +import scala.cli.commands.{ScalaCommand, SpecificationLevel} import scala.cli.config.Secret import scala.cli.errors.GitHubApiError import scala.cli.util.ArgHelpers.* object SecretList extends ScalaCommand[SecretListOptions] { - override def scalaSpecificationLevel = SpecificationLevel.RESTRICTED + override def scalaSpecificationLevel: SpecificationLevel = SpecificationLevel.RESTRICTED - override def helpFormat: HelpFormat = super.helpFormat.withPrimaryGroup("Secret") + override def helpFormat: HelpFormat = super.helpFormat.withPrimaryGroup(HelpGroup.Secret) override def names = List( List("github", "secret", "list"), List("gh", "secret", "list") diff --git a/modules/cli/src/main/scala/scala/cli/commands/github/SharedSecretOptions.scala b/modules/cli/src/main/scala/scala/cli/commands/github/SharedSecretOptions.scala index 0c5d831915..32d9484390 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/github/SharedSecretOptions.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/github/SharedSecretOptions.scala @@ -2,7 +2,7 @@ package scala.cli.commands.github import caseapp.* -import scala.cli.commands.shared.{HasLoggingOptions, LoggingOptions} +import scala.cli.commands.shared.{HasLoggingOptions, HelpGroup, LoggingOptions} import scala.cli.commands.tags import scala.cli.signing.shared.{PasswordOption, Secret} import scala.cli.signing.util.ArgParsers.* @@ -11,12 +11,12 @@ import scala.cli.signing.util.ArgParsers.* final case class SharedSecretOptions( @Recurse logging: LoggingOptions = LoggingOptions(), - @Group("Secret") + @Group(HelpGroup.Secret.toString) @Tag(tags.restricted) @Tag(tags.inShortHelp) token: PasswordOption = PasswordOption.Value(Secret("")), @ExtraName("repo") - @Group("Secret") + @Group(HelpGroup.Secret.toString) @Tag(tags.restricted) @Tag(tags.inShortHelp) repository: String = "" diff --git a/modules/cli/src/main/scala/scala/cli/commands/installcompletions/InstallCompletions.scala b/modules/cli/src/main/scala/scala/cli/commands/installcompletions/InstallCompletions.scala index 55f4d738b2..6c504924ea 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/installcompletions/InstallCompletions.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/installcompletions/InstallCompletions.scala @@ -10,7 +10,8 @@ import java.nio.file.Paths import java.util import scala.build.{Directories, Logger} -import scala.cli.commands.ScalaCommand +import scala.cli.commands.shared.HelpGroup +import scala.cli.commands.{ScalaCommand, SpecificationLevel} import scala.cli.internal.{Argv0, ProfileFileUpdater} import scala.cli.util.ArgHelpers.* import scala.cli.{CurrentParams, ScalaCli} @@ -20,9 +21,10 @@ object InstallCompletions extends ScalaCommand[InstallCompletionsOptions] { List("install-completions") ) - override def helpFormat: HelpFormat = super.helpFormat.withPrimaryGroup("Install") + override def helpFormat: HelpFormat = + super.helpFormat.withPrimaryGroup(HelpGroup.Install) - override def scalaSpecificationLevel = SpecificationLevel.IMPLEMENTATION + override def scalaSpecificationLevel: SpecificationLevel = SpecificationLevel.IMPLEMENTATION override def runCommand( options: InstallCompletionsOptions, diff --git a/modules/cli/src/main/scala/scala/cli/commands/installcompletions/InstallCompletionsOptions.scala b/modules/cli/src/main/scala/scala/cli/commands/installcompletions/InstallCompletionsOptions.scala index 267795cb9d..08fac6343f 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/installcompletions/InstallCompletionsOptions.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/installcompletions/InstallCompletionsOptions.scala @@ -3,7 +3,7 @@ package scala.cli.commands.installcompletions import caseapp.* import scala.cli.ScalaCli.fullRunnerName -import scala.cli.commands.shared.{HasLoggingOptions, HelpMessages, LoggingOptions} +import scala.cli.commands.shared.{HasLoggingOptions, HelpGroup, HelpMessages, LoggingOptions} import scala.cli.commands.tags // format: off @@ -11,7 +11,7 @@ import scala.cli.commands.tags final case class InstallCompletionsOptions( @Recurse logging: LoggingOptions = LoggingOptions(), - @Group("Install") + @Group(HelpGroup.Install.toString) @Name("shell") @Tag(tags.implementation) @Tag(tags.inShortHelp) @@ -19,32 +19,32 @@ final case class InstallCompletionsOptions( format: Option[String] = None, @Tag(tags.implementation) - @Group("Install") + @Group(HelpGroup.Install.toString) @Tag(tags.inShortHelp) @HelpMessage("Path to `*rc` file, defaults to `.bashrc` or `.zshrc` depending on shell") rcFile: Option[String] = None, @Tag(tags.implementation) @HelpMessage("Completions output directory") - @Group("Install") + @Group(HelpGroup.Install.toString) @Name("o") output: Option[String] = None, @Hidden @Tag(tags.implementation) @HelpMessage("Custom banner in comment placed in rc file") - @Group("Install") + @Group(HelpGroup.Install.toString) banner: String = "{NAME} completions", @Hidden @Tag(tags.implementation) @HelpMessage("Custom completions name") - @Group("Install") + @Group(HelpGroup.Install.toString) name: Option[String] = None, @Tag(tags.implementation) @HelpMessage("Print completions to stdout") - @Group("Install") + @Group(HelpGroup.Install.toString) env: Boolean = false, ) extends HasLoggingOptions // format: on diff --git a/modules/cli/src/main/scala/scala/cli/commands/installhome/InstallHome.scala b/modules/cli/src/main/scala/scala/cli/commands/installhome/InstallHome.scala index bccfd4691e..0e5153679a 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/installhome/InstallHome.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/installhome/InstallHome.scala @@ -6,16 +6,23 @@ import coursier.env.{EnvironmentUpdate, ProfileUpdater} import scala.build.Logger import scala.cli.CurrentParams -import scala.cli.commands.{CommandUtils, CustomWindowsEnvVarUpdater, ScalaCommand} +import scala.cli.commands.shared.HelpGroup +import scala.cli.commands.{ + CommandUtils, + CustomWindowsEnvVarUpdater, + ScalaCommand, + SpecificationLevel +} import scala.cli.util.ArgHelpers.* import scala.io.StdIn.readLine import scala.util.Properties object InstallHome extends ScalaCommand[InstallHomeOptions] { - override def hidden: Boolean = true - override def scalaSpecificationLevel = SpecificationLevel.IMPLEMENTATION + override def hidden: Boolean = true + override def scalaSpecificationLevel: SpecificationLevel = SpecificationLevel.IMPLEMENTATION - override def helpFormat: HelpFormat = super.helpFormat.withPrimaryGroup("Install") + override def helpFormat: HelpFormat = + super.helpFormat.withPrimaryGroup(HelpGroup.Install) private def logEqual(version: String, logger: Logger) = { logger.message(s"$fullRunnerName $version is already installed and up-to-date.") diff --git a/modules/cli/src/main/scala/scala/cli/commands/installhome/InstallHomeOptions.scala b/modules/cli/src/main/scala/scala/cli/commands/installhome/InstallHomeOptions.scala index eb327a3cb4..2ddac60c13 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/installhome/InstallHomeOptions.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/installhome/InstallHomeOptions.scala @@ -3,7 +3,7 @@ package scala.cli.commands.installhome import caseapp.* import scala.cli.ScalaCli.{baseRunnerName, fullRunnerName} -import scala.cli.commands.shared.{HasLoggingOptions, LoggingOptions} +import scala.cli.commands.shared.{HasLoggingOptions, HelpGroup, LoggingOptions} import scala.cli.commands.tags // format: off @@ -11,24 +11,24 @@ import scala.cli.commands.tags final case class InstallHomeOptions( @Recurse logging: LoggingOptions = LoggingOptions(), - @Group("Install") + @Group(HelpGroup.Install.toString) @Tag(tags.implementation) scalaCliBinaryPath: String, - @Group("Install") + @Group(HelpGroup.Install.toString) @Name("f") @Tag(tags.implementation) @HelpMessage("Overwrite if it exists") force: Boolean = false, - @Group("Install") + @Group(HelpGroup.Install.toString) @Hidden @Tag(tags.implementation) @HelpMessage("Binary name") binaryName: String = baseRunnerName, - @Group("Install") + @Group(HelpGroup.Install.toString) @Tag(tags.implementation) @HelpMessage("Print the update to `env` variable") env: Boolean = false, - @Group("Install") + @Group(HelpGroup.Install.toString) @Hidden @Tag(tags.implementation) @HelpMessage("Binary directory") diff --git a/modules/cli/src/main/scala/scala/cli/commands/package0/Package.scala b/modules/cli/src/main/scala/scala/cli/commands/package0/Package.scala index dfb1d5f964..9607985f74 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/package0/Package.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/package0/Package.scala @@ -33,7 +33,7 @@ import scala.cli.commands.doc.Doc import scala.cli.commands.packaging.Spark import scala.cli.commands.publish.ConfigUtil.* import scala.cli.commands.run.Run.orPythonDetectionError -import scala.cli.commands.shared.{MainClassOptions, SharedOptions} +import scala.cli.commands.shared.{HelpCommandGroup, HelpGroup, MainClassOptions, SharedOptions} import scala.cli.commands.util.BuildCommandHelpers import scala.cli.commands.{CommandUtils, ScalaCommand, WatchUtil} import scala.cli.config.{ConfigDb, Keys} @@ -44,23 +44,23 @@ import scala.cli.util.ArgHelpers.* import scala.util.Properties object Package extends ScalaCommand[PackageOptions] with BuildCommandHelpers { - override def name = "package" - override def group = "Main" - - val primaryHelpGroups: Seq[String] = Seq( - "Package", - "Scala", - "Java", - "Debian", - "MacOS", - "RedHat", - "Windows", - "Docker", - "Native image" + override def name = "package" + override def group: String = HelpCommandGroup.Main.toString + + val primaryHelpGroups: Seq[HelpGroup] = Seq( + HelpGroup.Package, + HelpGroup.Scala, + HelpGroup.Java, + HelpGroup.Debian, + HelpGroup.MacOS, + HelpGroup.RedHat, + HelpGroup.Windows, + HelpGroup.Docker, + HelpGroup.NativeImage ) - val hiddenHelpGroups: Seq[String] = Seq("Entrypoint", "Watch") + val hiddenHelpGroups: Seq[HelpGroup] = Seq(HelpGroup.Entrypoint, HelpGroup.Watch) override def helpFormat: HelpFormat = super.helpFormat - .copy(hiddenGroups = Some(hiddenHelpGroups)) + .withHiddenGroups(hiddenHelpGroups) .withPrimaryGroups(primaryHelpGroups) override def sharedOptions(options: PackageOptions): Option[SharedOptions] = Some(options.shared) override def scalaSpecificationLevel = SpecificationLevel.RESTRICTED diff --git a/modules/cli/src/main/scala/scala/cli/commands/package0/PackageOptions.scala b/modules/cli/src/main/scala/scala/cli/commands/package0/PackageOptions.scala index f7882ec1da..22142fa6cb 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/package0/PackageOptions.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/package0/PackageOptions.scala @@ -28,95 +28,95 @@ final case class PackageOptions( @Recurse mainClass: MainClassOptions = MainClassOptions(), - @Group("Package") + @Group(HelpGroup.Package.toString) @HelpMessage("Set the destination path") @Name("o") @Tag(tags.restricted) @Tag(tags.inShortHelp) output: Option[String] = None, - @Group("Package") + @Group(HelpGroup.Package.toString) @HelpMessage("Overwrite the destination file, if it exists") @Name("f") @Tag(tags.restricted) @Tag(tags.inShortHelp) force: Boolean = false, - @Group("Package") + @Group(HelpGroup.Package.toString) @HelpMessage("Generate a library JAR rather than an executable JAR") @Tag(tags.restricted) @Tag(tags.inShortHelp) library: Boolean = false, - @Group("Package") + @Group(HelpGroup.Package.toString) @HelpMessage("Generate a source JAR rather than an executable JAR") @Tag(tags.restricted) @Tag(tags.inShortHelp) source: Boolean = false, - @Group("Package") + @Group(HelpGroup.Package.toString) @HelpMessage("Generate a scaladoc JAR rather than an executable JAR") @ExtraName("scaladoc") @ExtraName("javadoc") @Tag(tags.restricted) @Tag(tags.inShortHelp) doc: Boolean = false, - @Group("Package") + @Group(HelpGroup.Package.toString) @HelpMessage("Generate an assembly JAR") @Tag(tags.restricted) @Tag(tags.inShortHelp) assembly: Boolean = false, - @Group("Package") + @Group(HelpGroup.Package.toString) @HelpMessage("For assembly JAR, whether to add a bash / bat preamble") @Tag(tags.restricted) @Tag(tags.inShortHelp) preamble: Boolean = true, - @Group("Package") + @Group(HelpGroup.Package.toString) @Hidden @HelpMessage("For assembly JAR, whether to specify a main class in the JAR manifest") @Tag(tags.restricted) mainClassInManifest: Option[Boolean] = None, - @Group("Package") + @Group(HelpGroup.Package.toString) @Hidden @HelpMessage("Generate an assembly JAR for Spark (assembly that doesn't contain Spark, nor any of its dependencies)") @Tag(tags.experimental) spark: Boolean = false, - @Group("Package") + @Group(HelpGroup.Package.toString) @HelpMessage("Package standalone JARs") @Tag(tags.restricted) @Tag(tags.inShortHelp) standalone: Option[Boolean] = None, @Recurse packager: PackagerOptions = PackagerOptions(), - @Group("Package") + @Group(HelpGroup.Package.toString) @HelpMessage("Build Debian package, available only on Linux") @Tag(tags.restricted) @Tag(tags.inShortHelp) deb: Boolean = false, - @Group("Package") + @Group(HelpGroup.Package.toString) @HelpMessage("Build dmg package, available only on macOS") @Tag(tags.restricted) @Tag(tags.inShortHelp) dmg: Boolean = false, - @Group("Package") + @Group(HelpGroup.Package.toString) @HelpMessage("Build rpm package, available only on Linux") @Tag(tags.restricted) @Tag(tags.inShortHelp) rpm: Boolean = false, - @Group("Package") + @Group(HelpGroup.Package.toString) @HelpMessage("Build msi package, available only on Windows") @Tag(tags.restricted) @Tag(tags.inShortHelp) msi: Boolean = false, - @Group("Package") + @Group(HelpGroup.Package.toString) @HelpMessage("Build pkg package, available only on macOS") @Tag(tags.restricted) @Tag(tags.inShortHelp) pkg: Boolean = false, - @Group("Package") + @Group(HelpGroup.Package.toString) @HelpMessage("Build Docker image") @Tag(tags.restricted) @Tag(tags.inShortHelp) docker: Boolean = false, - @Group("Package") + @Group(HelpGroup.Package.toString) @Hidden @HelpMessage("Exclude modules *and their transitive dependencies* from the JAR to be packaged") @ValueDescription("org:name") @@ -124,13 +124,13 @@ final case class PackageOptions( @Tag(tags.inShortHelp) provided: List[String] = Nil, - @Group("Package") + @Group(HelpGroup.Package.toString) @HelpMessage("Use default scaladoc options") @ExtraName("defaultScaladocOpts") @Tag(tags.implementation) defaultScaladocOptions: Option[Boolean] = None, - @Group("Package") + @Group(HelpGroup.Package.toString) @HelpMessage("Build GraalVM native image") @ExtraName("graal") @Tag(tags.restricted) diff --git a/modules/cli/src/main/scala/scala/cli/commands/package0/PackagerOptions.scala b/modules/cli/src/main/scala/scala/cli/commands/package0/PackagerOptions.scala index 2f5a7fba86..9688143f28 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/package0/PackagerOptions.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/package0/PackagerOptions.scala @@ -1,7 +1,8 @@ package scala.cli.commands.package0 -import caseapp._ +import caseapp.* +import scala.cli.commands.shared.HelpGroup import scala.cli.commands.{Constants, tags} // format: off @@ -22,49 +23,49 @@ final case class PackagerOptions( @HelpMessage("This should contain names and email addresses of co-maintainers of the package") @Name("m") maintainer: Option[String] = None, - @Group("Debian") + @Group(HelpGroup.Debian.toString) @HelpMessage( "The list of Debian package that this package is not compatible with" ) @ValueDescription("Debian dependencies conflicts") @Tag(tags.restricted) debianConflicts: List[String] = Nil, - @Group("Debian") + @Group(HelpGroup.Debian.toString) @HelpMessage("The list of Debian packages that this package depends on") @ValueDescription("Debian dependencies") @Tag(tags.restricted) debianDependencies: List[String] = Nil, - @Group("Debian") + @Group(HelpGroup.Debian.toString) @HelpMessage( "Architectures that are supported by the repository (default: all)" ) @Tag(tags.restricted) debArchitecture: String = "all", - @Group("Debian") + @Group(HelpGroup.Debian.toString) @HelpMessage( "This field represents how important it is that the user have the package installed" ) @Tag(tags.restricted) priority: Option[String] = None, - @Group("Debian") + @Group(HelpGroup.Debian.toString) @HelpMessage( "This field specifies an application area into which the package has been classified" ) @Tag(tags.restricted) section: Option[String] = None, - @Group("MacOS") + @Group(HelpGroup.MacOS.toString) @HelpMessage( "CF Bundle Identifier" ) @Tag(tags.restricted) identifier: Option[String] = None, - @Group("RedHat") + @Group(HelpGroup.RedHat.toString) @HelpMessage( "Licenses that are supported by the repository (list of licenses: https://fedoraproject.org/wiki/Licensing:Main?rd=Licensing)" ) @Tag(tags.restricted) license: Option[String] = None, - @Group("RedHat") + @Group(HelpGroup.RedHat.toString) @HelpMessage( "The number of times this version of the software was released (default: 1)" ) @@ -73,82 +74,82 @@ final case class PackagerOptions( @HelpMessage("Architectures that are supported by the repository (default: noarch)") @Tag(tags.restricted) rpmArchitecture: String = "noarch", - @Group("Windows") + @Group(HelpGroup.Windows.toString) @HelpMessage("Path to the license file") @Tag(tags.restricted) licensePath: Option[String] = None, - @Group("Windows") + @Group(HelpGroup.Windows.toString) @HelpMessage("Name of product (default: Scala packager)") @Tag(tags.restricted) productName: String = "Scala packager", - @Group("Windows") + @Group(HelpGroup.Windows.toString) @HelpMessage("Text that will be displayed on the exit dialog") @Tag(tags.restricted) exitDialog: Option[String] = None, - @Group("Windows") + @Group(HelpGroup.Windows.toString) @Tag(tags.restricted) @HelpMessage("Suppress Wix ICE validation (required for users that are neither interactive, not local administrators)") suppressValidation: Option[Boolean] = None, - @Group("Windows") + @Group(HelpGroup.Windows.toString) @Tag(tags.restricted) @HelpMessage("Path to extra WIX configuration content") @ValueDescription("path") extraConfig: List[String] = Nil, - @Group("Windows") + @Group(HelpGroup.Windows.toString) @Tag(tags.restricted) @HelpMessage("Whether a 64-bit executable is being packaged") @Name("64") is64Bits: Boolean = true, - @Group("Windows") + @Group(HelpGroup.Windows.toString) @HelpMessage("WIX installer version") @Tag(tags.restricted) installerVersion: Option[String] = None, - @Group("Windows") + @Group(HelpGroup.Windows.toString) @HelpMessage("The GUID to identify that the windows package can be upgraded.") @Tag(tags.restricted) wixUpgradeCodeGuid: Option[String] = None, - @Group("Docker") + @Group(HelpGroup.Docker.toString) @HelpMessage( "Building the container from base image" ) @Tag(tags.restricted) dockerFrom: Option[String] = None, - @Group("Docker") + @Group(HelpGroup.Docker.toString) @HelpMessage( "The image registry; if empty, it will use the default registry" ) @Tag(tags.restricted) dockerImageRegistry: Option[String] = None, - @Group("Docker") + @Group(HelpGroup.Docker.toString) @HelpMessage( "The image repository" ) @Tag(tags.restricted) dockerImageRepository: Option[String] = None, - @Group("Docker") + @Group(HelpGroup.Docker.toString) @HelpMessage( "The image tag; the default tag is `latest`" ) @Tag(tags.restricted) dockerImageTag: Option[String] = None, - @Group("Native image") + @Group(HelpGroup.NativeImage.toString) @HelpMessage(s"GraalVM Java major version to use to build GraalVM native images (${Constants.defaultGraalVMJavaVersion} by default)") @ValueDescription("java-major-version") @Tag(tags.restricted) @Tag(tags.inShortHelp) graalvmJavaVersion: Option[Int] = None, - @Group("Native image") + @Group(HelpGroup.NativeImage.toString) @HelpMessage(s"GraalVM version to use to build GraalVM native images (${Constants.defaultGraalVMVersion} by default)") @ValueDescription("version") @Tag(tags.inShortHelp) graalvmVersion: Option[String] = None, - @Group("Native image") + @Group(HelpGroup.NativeImage.toString) @HelpMessage("JVM id of GraalVM distribution to build GraalVM native images (like \"graalvm-java17:22.0.0\")") @ValueDescription("jvm-id") @Tag(tags.restricted) graalvmJvmId: Option[String] = None, - @Group("Native image") + @Group(HelpGroup.NativeImage.toString) @HelpMessage("Pass args to GraalVM") @Tag(tags.restricted) graalvmArgs: List[String] = Nil diff --git a/modules/cli/src/main/scala/scala/cli/commands/pgp/PgpPullOptions.scala b/modules/cli/src/main/scala/scala/cli/commands/pgp/PgpPullOptions.scala index b5608c1309..6d19a31dd7 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/pgp/PgpPullOptions.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/pgp/PgpPullOptions.scala @@ -2,7 +2,7 @@ package scala.cli.commands.pgp import caseapp.* -import scala.cli.commands.shared.{HasLoggingOptions, LoggingOptions} +import scala.cli.commands.shared.{HasLoggingOptions, HelpGroup, LoggingOptions} // format: off final case class PgpPullOptions( @@ -10,7 +10,7 @@ final case class PgpPullOptions( logging: LoggingOptions = LoggingOptions(), @Recurse shared: SharedPgpPushPullOptions = SharedPgpPushPullOptions(), - @Group("PGP") + @Group(HelpGroup.PGP.toString) @HelpMessage("Whether to exit with code 0 if no key is passed") allowEmpty: Boolean = false ) extends HasLoggingOptions diff --git a/modules/cli/src/main/scala/scala/cli/commands/pgp/PgpPushOptions.scala b/modules/cli/src/main/scala/scala/cli/commands/pgp/PgpPushOptions.scala index 59397fbb78..31a2e5ab09 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/pgp/PgpPushOptions.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/pgp/PgpPushOptions.scala @@ -5,6 +5,7 @@ import caseapp.* import scala.cli.commands.shared.{ CoursierOptions, HasLoggingOptions, + HelpGroup, LoggingOptions, SharedJvmOptions } @@ -22,14 +23,14 @@ final case class PgpPushOptions( @Recurse scalaSigning: PgpScalaSigningOptions = PgpScalaSigningOptions(), - @Group("PGP") + @Group(HelpGroup.PGP.toString) @HelpMessage("Try to push the key even if Scala CLI thinks it's not a public key") @ExtraName("f") force: Boolean = false, - @Group("PGP") + @Group(HelpGroup.PGP.toString) @HelpMessage("Whether to exit with code 0 if no key is passed") allowEmpty: Boolean = false, - @Group("PGP") + @Group(HelpGroup.PGP.toString) @Hidden forceSigningBinary: Boolean = false ) extends HasLoggingOptions diff --git a/modules/cli/src/main/scala/scala/cli/commands/pgp/PgpScalaSigningOptions.scala b/modules/cli/src/main/scala/scala/cli/commands/pgp/PgpScalaSigningOptions.scala index aacae7c832..4777c9e2ab 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/pgp/PgpScalaSigningOptions.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/pgp/PgpScalaSigningOptions.scala @@ -3,21 +3,21 @@ package scala.cli.commands.pgp import caseapp.* import scala.build.options as bo -import scala.cli.commands.shared.{CoursierOptions, LoggingOptions, SharedJvmOptions} +import scala.cli.commands.shared.{CoursierOptions, HelpGroup, LoggingOptions, SharedJvmOptions} import scala.cli.commands.tags // format: off final case class PgpScalaSigningOptions( - @Group("Signing") + @Group(HelpGroup.Signing.toString) @Tag(tags.restricted) @Hidden signingCliVersion: Option[String] = None, - @Group("Signing") + @Group(HelpGroup.Signing.toString) @Tag(tags.restricted) @ValueDescription("option") @Hidden signingCliJavaArg: List[String] = Nil, - @Group("Signing") + @Group(HelpGroup.Signing.toString) @Tag(tags.restricted) @HelpMessage("Whether to run the Scala Signing CLI on the JVM or using a native executable") @Hidden diff --git a/modules/cli/src/main/scala/scala/cli/commands/pgp/SharedPgpPushPullOptions.scala b/modules/cli/src/main/scala/scala/cli/commands/pgp/SharedPgpPushPullOptions.scala index 60363c58ce..1db1b3189d 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/pgp/SharedPgpPushPullOptions.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/pgp/SharedPgpPushPullOptions.scala @@ -4,12 +4,12 @@ import caseapp.* import sttp.model.Uri import scala.build.Logger -import scala.cli.commands.shared.LoggingOptions +import scala.cli.commands.shared.{HelpGroup, LoggingOptions} import scala.cli.commands.tags // format: off final case class SharedPgpPushPullOptions( - @Group("PGP") + @Group(HelpGroup.PGP.toString) @HelpMessage("Key server to push / pull keys from") @ValueDescription("URL") @Tag(tags.restricted) diff --git a/modules/cli/src/main/scala/scala/cli/commands/publish/Publish.scala b/modules/cli/src/main/scala/scala/cli/commands/publish/Publish.scala index f4765e79e5..9f933cb449 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/publish/Publish.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/publish/Publish.scala @@ -44,9 +44,15 @@ import scala.cli.commands.package0.Package as PackageCmd import scala.cli.commands.pgp.{PgpExternalCommand, PgpScalaSigningOptions} import scala.cli.commands.publish.ConfigUtil.* import scala.cli.commands.publish.{PublishParamsOptions, PublishRepositoryOptions} -import scala.cli.commands.shared.{MainClassOptions, SharedOptions, SharedPythonOptions} +import scala.cli.commands.shared.{ + HelpCommandGroup, + HelpGroup, + MainClassOptions, + SharedOptions, + SharedPythonOptions +} import scala.cli.commands.util.{BuildCommandHelpers, ScalaCliSttpBackend} -import scala.cli.commands.{ScalaCommand, WatchUtil} +import scala.cli.commands.{ScalaCommand, SpecificationLevel, WatchUtil} import scala.cli.config.{ConfigDb, Keys, PublishCredentials} import scala.cli.errors.{ FailedToSignFileError, @@ -62,13 +68,15 @@ import scala.util.control.NonFatal object Publish extends ScalaCommand[PublishOptions] with BuildCommandHelpers { - override def scalaSpecificationLevel = SpecificationLevel.RESTRICTED - val primaryHelpGroups: Seq[String] = Seq("Publishing", "Signing", "PGP") - val hiddenHelpGroups: Seq[String] = Seq("Scala", "Java", "Entrypoint", "Dependency", "Watch") + override def scalaSpecificationLevel: SpecificationLevel = SpecificationLevel.RESTRICTED + + import scala.cli.commands.shared.HelpGroup.* + val primaryHelpGroups: Seq[HelpGroup] = Seq(Publishing, Signing, PGP) + val hiddenHelpGroups: Seq[HelpGroup] = Seq(Scala, Java, Entrypoint, Dependency, Watch) override def helpFormat: HelpFormat = super.helpFormat - .copy(hiddenGroups = Some(hiddenHelpGroups)) + .withHiddenGroups(hiddenHelpGroups) .withPrimaryGroups(primaryHelpGroups) - override def group: String = "Main" + override def group: String = HelpCommandGroup.Main.toString override def sharedOptions(options: PublishOptions): Option[SharedOptions] = Some(options.shared) diff --git a/modules/cli/src/main/scala/scala/cli/commands/publish/PublishLocal.scala b/modules/cli/src/main/scala/scala/cli/commands/publish/PublishLocal.scala index dbc2af3ce6..82776808e4 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/publish/PublishLocal.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/publish/PublishLocal.scala @@ -7,17 +7,17 @@ import scala.build.options.BuildOptions import scala.build.{BuildThreads, Logger} import scala.cli.CurrentParams import scala.cli.commands.ScalaCommand -import scala.cli.commands.shared.SharedOptions +import scala.cli.commands.shared.{HelpCommandGroup, SharedOptions} import scala.cli.config.ConfigDb import scala.cli.util.ArgHelpers.* object PublishLocal extends ScalaCommand[PublishLocalOptions] { - override def group: String = "Main" + override def group: String = HelpCommandGroup.Main.toString override def scalaSpecificationLevel = SpecificationLevel.RESTRICTED override def helpFormat: HelpFormat = super.helpFormat - .copy(hiddenGroups = Some(Publish.hiddenHelpGroups)) + .withHiddenGroups(Publish.hiddenHelpGroups) .withPrimaryGroups(Publish.primaryHelpGroups) override def sharedOptions(options: PublishLocalOptions): Option[SharedOptions] = Some(options.shared) diff --git a/modules/cli/src/main/scala/scala/cli/commands/publish/PublishOptions.scala b/modules/cli/src/main/scala/scala/cli/commands/publish/PublishOptions.scala index a72c99753b..6095ddb803 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/publish/PublishOptions.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/publish/PublishOptions.scala @@ -27,12 +27,12 @@ final case class PublishOptions( @Recurse signingCli: PgpScalaSigningOptions = PgpScalaSigningOptions(), - @Group("Publishing") + @Group(HelpGroup.Publishing.toString) @Tag(tags.restricted) @Hidden ivy2LocalLike: Option[Boolean] = None, - @Group("Publishing") + @Group(HelpGroup.Publishing.toString) @Tag(tags.restricted) @Hidden parallelUpload: Option[Boolean] = None diff --git a/modules/cli/src/main/scala/scala/cli/commands/publish/PublishParamsOptions.scala b/modules/cli/src/main/scala/scala/cli/commands/publish/PublishParamsOptions.scala index fb5ec8db48..1326d0b558 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/publish/PublishParamsOptions.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/publish/PublishParamsOptions.scala @@ -2,6 +2,7 @@ package scala.cli.commands.publish import caseapp.* +import scala.cli.commands.shared.HelpGroup import scala.cli.commands.tags import scala.cli.signing.shared.PasswordOption import scala.cli.signing.util.ArgParsers.* @@ -11,65 +12,65 @@ import scala.cli.util.MaybeConfigPasswordOption // format: off final case class PublishParamsOptions( - @Group("Publishing") + @Group(HelpGroup.Publishing.toString) @HelpMessage("Organization to publish artifacts under") @Tag(tags.restricted) @Tag(tags.inShortHelp) organization: Option[String] = None, - @Group("Publishing") + @Group(HelpGroup.Publishing.toString) @HelpMessage("Name to publish artifacts as") @Tag(tags.restricted) @Tag(tags.inShortHelp) name: Option[String] = None, - @Group("Publishing") + @Group(HelpGroup.Publishing.toString) @HelpMessage("Final name to publish artifacts as, including Scala version and platform suffixes if any") @Tag(tags.restricted) @Tag(tags.inShortHelp) moduleName: Option[String] = None, - @Group("Publishing") + @Group(HelpGroup.Publishing.toString) @HelpMessage("Version to publish artifacts as") @Tag(tags.restricted) @Tag(tags.inShortHelp) version: Option[String] = None, - @Group("Publishing") + @Group(HelpGroup.Publishing.toString) @HelpMessage("How to compute the version to publish artifacts as") @Tag(tags.restricted) computeVersion: Option[String] = None, - @Group("Publishing") + @Group(HelpGroup.Publishing.toString) @HelpMessage("URL to put in publishing metadata") @Tag(tags.restricted) @Tag(tags.inShortHelp) url: Option[String] = None, - @Group("Publishing") + @Group(HelpGroup.Publishing.toString) @HelpMessage("License to put in publishing metadata") @Tag(tags.restricted) @Tag(tags.inShortHelp) @ValueDescription("name:URL") license: Option[String] = None, - @Group("Publishing") + @Group(HelpGroup.Publishing.toString) @HelpMessage("VCS information to put in publishing metadata") @Tag(tags.restricted) @Tag(tags.inShortHelp) vcs: Option[String] = None, - @Group("Publishing") + @Group(HelpGroup.Publishing.toString) @HelpMessage("Description to put in publishing metadata") @Tag(tags.restricted) @Tag(tags.inShortHelp) description: Option[String] = None, - @Group("Publishing") + @Group(HelpGroup.Publishing.toString) @HelpMessage("Developer(s) to add in publishing metadata, like \"alex|Alex|https://alex.info\" or \"alex|Alex|https://alex.info|alex@alex.me\"") @ValueDescription("id|name|URL|email") @Tag(tags.restricted) @Tag(tags.inShortHelp) developer: List[String] = Nil, - @Group("Publishing") + @Group(HelpGroup.Publishing.toString) @HelpMessage("Secret key to use to sign artifacts with Bouncy Castle") @Tag(tags.restricted) @Tag(tags.inShortHelp) secretKey: Option[MaybeConfigPasswordOption] = None, - @Group("Publishing") + @Group(HelpGroup.Publishing.toString) @HelpMessage("Password of secret key to use to sign artifacts with Bouncy Castle") @ValueDescription("value:…") @ExtraName("secretKeyPass") @@ -77,7 +78,7 @@ final case class PublishParamsOptions( @Tag(tags.inShortHelp) secretKeyPassword: Option[MaybeConfigPasswordOption] = None, - @Group("Publishing") + @Group(HelpGroup.Publishing.toString) @HelpMessage("Use or setup publish parameters meant to be used on continuous integration") @Tag(tags.restricted) @Tag(tags.inShortHelp) diff --git a/modules/cli/src/main/scala/scala/cli/commands/publish/PublishRepositoryOptions.scala b/modules/cli/src/main/scala/scala/cli/commands/publish/PublishRepositoryOptions.scala index 03d737c212..2e22ebd687 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/publish/PublishRepositoryOptions.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/publish/PublishRepositoryOptions.scala @@ -2,6 +2,7 @@ package scala.cli.commands.publish import caseapp.* +import scala.cli.commands.shared.HelpGroup import scala.cli.commands.tags import scala.cli.signing.shared.PasswordOption import scala.cli.signing.util.ArgParsers.* @@ -9,7 +10,7 @@ import scala.cli.signing.util.ArgParsers.* // format: off final case class PublishRepositoryOptions( - @Group("Publishing") + @Group(HelpGroup.Publishing.toString) @HelpMessage("Repository to publish to") @ValueDescription("URL or path") @ExtraName("R") @@ -18,21 +19,21 @@ final case class PublishRepositoryOptions( @Tag(tags.inShortHelp) publishRepository: Option[String] = None, - @Group("Publishing") + @Group(HelpGroup.Publishing.toString) @HelpMessage("User to use with publishing repository") @ValueDescription("user") @Tag(tags.restricted) @Tag(tags.inShortHelp) user: Option[PasswordOption] = None, - @Group("Publishing") + @Group(HelpGroup.Publishing.toString) @HelpMessage("Password to use with publishing repository") @ValueDescription("value:…") @Tag(tags.restricted) @Tag(tags.inShortHelp) password: Option[PasswordOption] = None, - @Group("Publishing") + @Group(HelpGroup.Publishing.toString) @HelpMessage("Realm to use when passing credentials to publishing repository") @ValueDescription("realm") @Tag(tags.restricted) diff --git a/modules/cli/src/main/scala/scala/cli/commands/publish/PublishSetup.scala b/modules/cli/src/main/scala/scala/cli/commands/publish/PublishSetup.scala index 9fe762515b..0e57e5af5c 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/publish/PublishSetup.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/publish/PublishSetup.scala @@ -14,21 +14,21 @@ import scala.build.{CrossSources, Directories, Logger, Sources} import scala.cli.ScalaCli import scala.cli.commands.github.{LibSodiumJni, SecretCreate, SecretList} import scala.cli.commands.publish.ConfigUtil.* -import scala.cli.commands.shared.SharedOptions +import scala.cli.commands.shared.{HelpCommandGroup, SharedOptions} import scala.cli.commands.util.ScalaCliSttpBackend -import scala.cli.commands.{CommandUtils, ScalaCommand} +import scala.cli.commands.{CommandUtils, ScalaCommand, SpecificationLevel} import scala.cli.config.{ConfigDb, Keys} import scala.cli.internal.Constants import scala.cli.util.ArgHelpers.* object PublishSetup extends ScalaCommand[PublishSetupOptions] { - override def group = "Main" - override def scalaSpecificationLevel = SpecificationLevel.RESTRICTED + override def group: String = HelpCommandGroup.Main.toString + override def scalaSpecificationLevel: SpecificationLevel = SpecificationLevel.RESTRICTED override def helpFormat: HelpFormat = super.helpFormat - .copy(hiddenGroups = Some(Publish.hiddenHelpGroups)) + .withHiddenGroups(Publish.hiddenHelpGroups) .withPrimaryGroups(Publish.primaryHelpGroups) override def names = List( diff --git a/modules/cli/src/main/scala/scala/cli/commands/publish/PublishSetupOptions.scala b/modules/cli/src/main/scala/scala/cli/commands/publish/PublishSetupOptions.scala index 43279eddfc..0c019a5deb 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/publish/PublishSetupOptions.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/publish/PublishSetupOptions.scala @@ -31,41 +31,41 @@ final case class PublishSetupOptions( scalaSigning: PgpScalaSigningOptions = PgpScalaSigningOptions(), - @Group("Publishing") + @Group(HelpGroup.Publishing.toString) @Tag(tags.restricted) @Tag(tags.inShortHelp) @HelpMessage("Public key to use to verify artifacts (to be uploaded to a key server)") publicKey: Option[PasswordOption] = None, - @Group("Publishing") + @Group(HelpGroup.Publishing.toString) @Tag(tags.restricted) @Tag(tags.inShortHelp) @HelpMessage("Check if some options for publishing are missing, and exit with non-zero return code if that's the case") check: Boolean = false, - @Group("Publishing") + @Group(HelpGroup.Publishing.toString) @Tag(tags.restricted) @Tag(tags.inShortHelp) @HelpMessage("GitHub token to use to upload secrets to GitHub - password encoded") token: Option[PasswordOption] = None, - @Group("Publishing") + @Group(HelpGroup.Publishing.toString) @Tag(tags.restricted) @Tag(tags.inShortHelp) @HelpMessage("Generate a random key pair for publishing, with a secret key protected by a random password") randomSecretKey: Option[Boolean] = None, - @Group("Publishing") + @Group(HelpGroup.Publishing.toString) @Tag(tags.restricted) @Tag(tags.inShortHelp) @HelpMessage("When generating a random key pair, the mail to associate to it") randomSecretKeyMail: Option[String] = None, - @Group("Publishing") + @Group(HelpGroup.Publishing.toString) @Tag(tags.restricted) @HelpMessage("The option groups to check - can be \"all\", or a comma-separated list of \"core\", \"signing\", \"repo\", \"extra\"") checks: Option[String] = None, - @Group("Publishing") + @Group(HelpGroup.Publishing.toString) @Tag(tags.restricted) @HelpMessage("Whether to check if a GitHub workflow already exists (one for publishing is written if none is found)") checkWorkflow: Option[Boolean] = None, - @Group("Publishing") + @Group(HelpGroup.Publishing.toString) @Tag(tags.implementation) @HelpMessage("Dummy mode - don't upload any secret to GitHub") dummy: Boolean = false diff --git a/modules/cli/src/main/scala/scala/cli/commands/publish/SharedPublishOptions.scala b/modules/cli/src/main/scala/scala/cli/commands/publish/SharedPublishOptions.scala index 4a5a7e1405..2b9b39300c 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/publish/SharedPublishOptions.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/publish/SharedPublishOptions.scala @@ -2,38 +2,39 @@ package scala.cli.commands.publish import caseapp.* +import scala.cli.commands.shared.HelpGroup import scala.cli.commands.tags // format: off final case class SharedPublishOptions( - @Group("Publishing") + @Group(HelpGroup.Publishing.toString) @HelpMessage("Directory where temporary files for publishing should be written") @Tag(tags.restricted) @Tag(tags.inShortHelp) @Hidden workingDir: Option[String] = None, - @Group("Publishing") + @Group(HelpGroup.Publishing.toString) @Hidden @HelpMessage("Scala version suffix to append to the module name, like \"_2.13\" or \"_3\"") @ValueDescription("suffix") @Tag(tags.restricted) scalaVersionSuffix: Option[String] = None, - @Group("Publishing") + @Group(HelpGroup.Publishing.toString) @Hidden @HelpMessage("Scala platform suffix to append to the module name, like \"_sjs1\" or \"_native0.4\"") @ValueDescription("suffix") @Tag(tags.restricted) scalaPlatformSuffix: Option[String] = None, - @Group("Publishing") + @Group(HelpGroup.Publishing.toString) @HelpMessage("Whether to build and publish source JARs") @Tag(tags.restricted) @Tag(tags.inShortHelp) sources: Option[Boolean] = None, - @Group("Publishing") + @Group(HelpGroup.Publishing.toString) @HelpMessage("Whether to build and publish doc JARs") @ExtraName("scaladoc") @ExtraName("javadoc") @@ -41,7 +42,7 @@ final case class SharedPublishOptions( @Tag(tags.inShortHelp) doc: Option[Boolean] = None, - @Group("Publishing") + @Group(HelpGroup.Publishing.toString) @HelpMessage("ID of the GPG key to use to sign artifacts") @ValueDescription("key-id") @ExtraName("K") @@ -49,14 +50,14 @@ final case class SharedPublishOptions( @Tag(tags.inShortHelp) gpgKey: Option[String] = None, - @Group("Publishing") + @Group(HelpGroup.Publishing.toString) @HelpMessage("Method to use to sign artifacts") @ValueDescription("gpg|bc|none") @Tag(tags.restricted) @Tag(tags.inShortHelp) signer: Option[String] = None, - @Group("Publishing") + @Group(HelpGroup.Publishing.toString) @HelpMessage("gpg command-line options") @ValueDescription("argument") @ExtraName("G") @@ -65,23 +66,23 @@ final case class SharedPublishOptions( @Tag(tags.inShortHelp) gpgOption: List[String] = Nil, - @Group("Publishing") + @Group(HelpGroup.Publishing.toString) @HelpMessage("Set Ivy 2 home directory") @ValueDescription("path") @Tag(tags.restricted) ivy2Home: Option[String] = None, - @Group("Publishing") + @Group(HelpGroup.Publishing.toString) @Hidden @Tag(tags.restricted) forceSigningBinary: Boolean = false, - @Group("Publishing") + @Group(HelpGroup.Publishing.toString) @Hidden @Tag(tags.restricted) checksum: List[String] = Nil, - @Group("Publishing") + @Group(HelpGroup.Publishing.toString) @HelpMessage("Proceed as if publishing, but do not upload / write artifacts to the remote repository") @Tag(tags.implementation) dummy: Boolean = false diff --git a/modules/cli/src/main/scala/scala/cli/commands/repl/Repl.scala b/modules/cli/src/main/scala/scala/cli/commands/repl/Repl.scala index 4b40009d7e..5b964e15b8 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/repl/Repl.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/repl/Repl.scala @@ -21,18 +21,18 @@ import scala.cli.commands.run.Run.{ pythonPathEnv } import scala.cli.commands.run.RunMode -import scala.cli.commands.shared.SharedOptions +import scala.cli.commands.shared.{HelpCommandGroup, HelpGroup, SharedOptions} import scala.cli.commands.{ScalaCommand, WatchUtil} import scala.cli.config.{ConfigDb, Keys} import scala.cli.util.ArgHelpers.* import scala.util.Properties object Repl extends ScalaCommand[ReplOptions] { - override def group = "Main" + override def group: String = HelpCommandGroup.Main.toString override def scalaSpecificationLevel = SpecificationLevel.MUST override def helpFormat: HelpFormat = super.helpFormat - .copy(hiddenGroups = Some(Seq("Watch"))) - .withPrimaryGroup("Repl") + .withHiddenGroup(HelpGroup.Watch) + .withPrimaryGroup(HelpGroup.Repl) override def names: List[List[String]] = List( List("repl"), List("console") diff --git a/modules/cli/src/main/scala/scala/cli/commands/repl/SharedReplOptions.scala b/modules/cli/src/main/scala/scala/cli/commands/repl/SharedReplOptions.scala index 68e1eabf7f..74631f5947 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/repl/SharedReplOptions.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/repl/SharedReplOptions.scala @@ -5,6 +5,7 @@ import caseapp.core.help.Help import scala.cli.commands.shared.{ CrossOptions, + HelpGroup, SharedJavaOptions, SharedPythonOptions, SharedWatchOptions @@ -20,7 +21,7 @@ final case class SharedReplOptions( @Recurse compileCross: CrossOptions = CrossOptions(), - @Group("Repl") + @Group(HelpGroup.Repl.toString) @Tag(tags.restricted) @Tag(tags.inShortHelp) @HelpMessage("Use Ammonite (instead of the default Scala REPL)") @@ -28,14 +29,14 @@ final case class SharedReplOptions( @Name("amm") ammonite: Option[Boolean] = None, - @Group("Repl") + @Group(HelpGroup.Repl.toString) @Tag(tags.restricted) @HelpMessage(s"Set the Ammonite version (${Constants.ammoniteVersion} by default)") @Name("ammoniteVer") @Tag(tags.inShortHelp) ammoniteVersion: Option[String] = None, - @Group("Repl") + @Group(HelpGroup.Repl.toString) @Name("a") @Tag(tags.restricted) @Tag(tags.inShortHelp) @@ -43,7 +44,7 @@ final case class SharedReplOptions( @Hidden ammoniteArg: List[String] = Nil, - @Group("Repl") + @Group(HelpGroup.Repl.toString) @Hidden @Tag(tags.implementation) @HelpMessage("Don't actually run the REPL, just fetch it") diff --git a/modules/cli/src/main/scala/scala/cli/commands/run/Run.scala b/modules/cli/src/main/scala/scala/cli/commands/run/Run.scala index 292f5cebd7..09043f8ded 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/run/Run.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/run/Run.scala @@ -19,20 +19,21 @@ import scala.cli.commands.package0.Package import scala.cli.commands.publish.ConfigUtil.* import scala.cli.commands.run.RunMode import scala.cli.commands.setupide.SetupIde -import scala.cli.commands.shared.SharedOptions +import scala.cli.commands.shared.{HelpCommandGroup, HelpGroup, SharedOptions} import scala.cli.commands.update.Update import scala.cli.commands.util.{BuildCommandHelpers, RunHadoop, RunSpark} -import scala.cli.commands.{CommandUtils, ScalaCommand, WatchUtil} +import scala.cli.commands.{CommandUtils, ScalaCommand, SpecificationLevel, WatchUtil} import scala.cli.config.{ConfigDb, Keys} import scala.cli.internal.ProcUtil import scala.cli.util.ArgHelpers.* import scala.util.{Properties, Try} object Run extends ScalaCommand[RunOptions] with BuildCommandHelpers { - override def group = "Main" - override def scalaSpecificationLevel = SpecificationLevel.MUST - val primaryHelpGroups: Seq[String] = Seq("Run", "Entrypoint", "Watch") - override def helpFormat: HelpFormat = super.helpFormat.withPrimaryGroups(primaryHelpGroups) + override def group: String = HelpCommandGroup.Main.toString + override def scalaSpecificationLevel: SpecificationLevel = SpecificationLevel.MUST + + val primaryHelpGroups: Seq[HelpGroup] = Seq(HelpGroup.Run, HelpGroup.Entrypoint, HelpGroup.Watch) + override def helpFormat: HelpFormat = super.helpFormat.withPrimaryGroups(primaryHelpGroups) override def sharedOptions(options: RunOptions): Option[SharedOptions] = Some(options.shared) private def runMode(options: RunOptions): RunMode = diff --git a/modules/cli/src/main/scala/scala/cli/commands/run/SharedRunOptions.scala b/modules/cli/src/main/scala/scala/cli/commands/run/SharedRunOptions.scala index 975bb79d6b..d9591f83c3 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/run/SharedRunOptions.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/run/SharedRunOptions.scala @@ -3,14 +3,7 @@ package scala.cli.commands.run import caseapp.* import caseapp.core.help.Help -import scala.cli.commands.shared.{ - BenchmarkingOptions, - CrossOptions, - MainClassOptions, - SharedJavaOptions, - SharedPythonOptions, - SharedWatchOptions -} +import scala.cli.commands.shared._ import scala.cli.commands.tags // format: off @@ -25,38 +18,38 @@ final case class SharedRunOptions( compileCross: CrossOptions = CrossOptions(), @Recurse mainClass: MainClassOptions = MainClassOptions(), - @Group("Run") + @Group(HelpGroup.Run.toString) @Hidden @Tag(tags.experimental) @Tag(tags.inShortHelp) @HelpMessage("Run as a Spark job, using the spark-submit command") @ExtraName("spark") sparkSubmit: Option[Boolean] = None, - @Group("Run") + @Group(HelpGroup.Run.toString) @Hidden @Tag(tags.experimental) @HelpMessage("Spark-submit arguments") @ExtraName("submitArg") submitArgument: List[String] = Nil, - @Group("Run") + @Group(HelpGroup.Run.toString) @Tag(tags.experimental) @HelpMessage("Run as a Spark job, using a vanilla Spark distribution downloaded by Scala CLI") @ExtraName("sparkStandalone") standaloneSpark: Option[Boolean] = None, - @Group("Run") + @Group(HelpGroup.Run.toString) @Tag(tags.experimental) @HelpMessage("Run as a Hadoop job, using the \"hadoop jar\" command") @ExtraName("hadoop") hadoopJar: Boolean = false, - @Group("Run") + @Group(HelpGroup.Run.toString) @Tag(tags.should) @Tag(tags.inShortHelp) @HelpMessage("Print the command that would have been run (one argument per line), rather than running it") command: Boolean = false, - @Group("Run") + @Group(HelpGroup.Run.toString) @HelpMessage("Temporary / working directory where to write generated launchers") scratchDir: Option[String] = None, - @Group("Run") + @Group(HelpGroup.Run.toString) @Hidden @Tag(tags.implementation) @HelpMessage("Run Java commands using a manifest-based class path (shortens command length)") diff --git a/modules/cli/src/main/scala/scala/cli/commands/shared/BenchmarkingOptions.scala b/modules/cli/src/main/scala/scala/cli/commands/shared/BenchmarkingOptions.scala index 88f8bf62f4..fe0649fc1a 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/shared/BenchmarkingOptions.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/shared/BenchmarkingOptions.scala @@ -6,11 +6,11 @@ import scala.cli.commands.tags // format: off final case class BenchmarkingOptions( - @Group("Benchmarking") + @Group(HelpGroup.Benchmarking.toString) @Tag(tags.experimental) @HelpMessage("Run JMH benchmarks") jmh: Option[Boolean] = None, - @Group("Benchmarking") + @Group(HelpGroup.Benchmarking.toString) @Tag(tags.experimental) @HelpMessage("Set JMH version") @ValueDescription("version") diff --git a/modules/cli/src/main/scala/scala/cli/commands/shared/CoursierOptions.scala b/modules/cli/src/main/scala/scala/cli/commands/shared/CoursierOptions.scala index 17c21d98db..1ecfb5d9f7 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/shared/CoursierOptions.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/shared/CoursierOptions.scala @@ -10,19 +10,19 @@ import scala.concurrent.duration.Duration // format: off final case class CoursierOptions( - @Group("Dependency") + @Group(HelpGroup.Dependency.toString) @HelpMessage("Specify a TTL for changing dependencies, such as snapshots") @ValueDescription("duration|Inf") @Tag(tags.implementation) @Hidden ttl: Option[String] = None, - @Group("Dependency") + @Group(HelpGroup.Dependency.toString) @HelpMessage("Set the coursier cache location") @ValueDescription("path") @Tag(tags.implementation) @Hidden cache: Option[String] = None, - @Group("Dependency") + @Group(HelpGroup.Dependency.toString) @HelpMessage("Enable checksum validation of artifacts downloaded by coursier") @Tag(tags.implementation) @Hidden diff --git a/modules/cli/src/main/scala/scala/cli/commands/shared/HelpGroupOptions.scala b/modules/cli/src/main/scala/scala/cli/commands/shared/HelpGroupOptions.scala index aa1fd19890..5915578717 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/shared/HelpGroupOptions.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/shared/HelpGroupOptions.scala @@ -10,17 +10,17 @@ import scala.cli.commands.tags @HelpMessage("Print help message") case class HelpGroupOptions( - @Group("Help") + @Group(HelpGroup.Help.toString) @HelpMessage("Show options for ScalaJS") @Tag(tags.implementation) @Tag(tags.inShortHelp) helpJs: Boolean = false, - @Group("Help") + @Group(HelpGroup.Help.toString) @HelpMessage("Show options for ScalaNative") @Tag(tags.implementation) @Tag(tags.inShortHelp) helpNative: Boolean = false, - @Group("Help") + @Group(HelpGroup.Help.toString) @HelpMessage("Show options for Scaladoc") @Name("scaladocHelp") @Name("docHelp") @@ -28,13 +28,13 @@ case class HelpGroupOptions( @Tag(tags.implementation) @Tag(tags.inShortHelp) helpScaladoc: Boolean = false, - @Group("Help") + @Group(HelpGroup.Help.toString) @HelpMessage("Show options for Scala REPL") @Name("replHelp") @Tag(tags.implementation) @Tag(tags.inShortHelp) helpRepl: Boolean = false, - @Group("Help") + @Group(HelpGroup.Help.toString) @HelpMessage("Show options for Scalafmt") @Name("scalafmtHelp") @Name("fmtHelp") @@ -58,8 +58,8 @@ case class HelpGroupOptions( } def maybePrintGroupHelp(help: Help[_], helpFormat: HelpFormat): Unit = { - if (helpJs) printHelpWithGroup(help, helpFormat, "Scala.js") - else if (helpNative) printHelpWithGroup(help, helpFormat, "Scala Native") + if (helpJs) printHelpWithGroup(help, helpFormat, HelpGroup.ScalaJs.toString) + else if (helpNative) printHelpWithGroup(help, helpFormat, HelpGroup.ScalaNative.toString) } } diff --git a/modules/cli/src/main/scala/scala/cli/commands/shared/HelpGroups.scala b/modules/cli/src/main/scala/scala/cli/commands/shared/HelpGroups.scala new file mode 100644 index 0000000000..e3c1be4d04 --- /dev/null +++ b/modules/cli/src/main/scala/scala/cli/commands/shared/HelpGroups.scala @@ -0,0 +1,36 @@ +package scala.cli.commands.shared + +enum HelpGroup: + case Benchmarking, BSP, BuildToolExport, + Config, Compilation, CompilationServer, + Debian, Debug, Default, Dependency, Doc, Docker, + Entrypoint, + Format, + Help, + Install, + Java, + Launcher, LegacyScalaRunner, Logging, + MacOS, Markdown, + NativeImage, + Package, PGP, Publishing, + RedHat, Repl, Run, Runner, + Scala, ScalaJs, ScalaNative, Secret, Signing, + Test, + Uninstall, Update, + Watch, Windows, + Version + + override def toString: String = this match + case BuildToolExport => "Build Tool export" + case CompilationServer => "Compilation server" + case LegacyScalaRunner => "Legacy Scala runner" + case NativeImage => "Native image" + case ScalaJs => "Scala.js" + case ScalaNative => "Scala Native" + case e => e.productPrefix + +enum HelpCommandGroup: + case Main, Miscellaneous, Undefined + override def toString: String = this match + case Undefined => "" + case e => e.productPrefix diff --git a/modules/cli/src/main/scala/scala/cli/commands/shared/JavaPropOptions.scala b/modules/cli/src/main/scala/scala/cli/commands/shared/JavaPropOptions.scala index fd357a9c7f..dfb55b2ddb 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/shared/JavaPropOptions.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/shared/JavaPropOptions.scala @@ -12,7 +12,7 @@ import scala.cli.commands.tags // format: off final case class JavaPropOptions( - @Group("Java") + @Group(HelpGroup.Java.toString) @HelpMessage("Set java properties") @ValueDescription("key=value|key") @Tag(tags.must) diff --git a/modules/cli/src/main/scala/scala/cli/commands/shared/LoggingOptions.scala b/modules/cli/src/main/scala/scala/cli/commands/shared/LoggingOptions.scala index 6ff5dfd12b..47a7834f5c 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/shared/LoggingOptions.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/shared/LoggingOptions.scala @@ -12,12 +12,12 @@ import scala.cli.internal.CliLogger final case class LoggingOptions( @Recurse verbosityOptions: VerbosityOptions = VerbosityOptions(), - @Group("Logging") + @Group(HelpGroup.Logging.toString) @HelpMessage("Decrease logging verbosity") @Tag(tags.implementation) @Name("q") quiet: Boolean = false, - @Group("Logging") + @Group(HelpGroup.Logging.toString) @Tag(tags.implementation) @HelpMessage("Use progress bars") progress: Option[Boolean] = None diff --git a/modules/cli/src/main/scala/scala/cli/commands/shared/MainClassOptions.scala b/modules/cli/src/main/scala/scala/cli/commands/shared/MainClassOptions.scala index 74e80d1c37..f944a6869e 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/shared/MainClassOptions.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/shared/MainClassOptions.scala @@ -7,14 +7,14 @@ import scala.cli.commands.tags // format: off final case class MainClassOptions( - @Group("Entrypoint") + @Group(HelpGroup.Entrypoint.toString) @HelpMessage("Specify which main class to run") @ValueDescription("main-class") @Tag(tags.must) @Name("M") mainClass: Option[String] = None, - @Group("Entrypoint") + @Group(HelpGroup.Entrypoint.toString) @HelpMessage("List main classes available in the current context") @Name("mainClassList") @Name("listMainClass") diff --git a/modules/cli/src/main/scala/scala/cli/commands/shared/MarkdownOptions.scala b/modules/cli/src/main/scala/scala/cli/commands/shared/MarkdownOptions.scala index cd3e3b6ec1..0e93863653 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/shared/MarkdownOptions.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/shared/MarkdownOptions.scala @@ -6,7 +6,7 @@ import scala.cli.commands.tags // format: off final case class MarkdownOptions( - @Group("Markdown") + @Group(HelpGroup.Markdown.toString) @Tag(tags.experimental) @HelpMessage("Enable markdown support.") @Name("md") diff --git a/modules/cli/src/main/scala/scala/cli/commands/shared/ScalaCliHelp.scala b/modules/cli/src/main/scala/scala/cli/commands/shared/ScalaCliHelp.scala index 1d0ef342bd..d1ad7caa36 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/shared/ScalaCliHelp.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/shared/ScalaCliHelp.scala @@ -4,48 +4,37 @@ import caseapp.core.Arg import caseapp.core.help.HelpFormat import scala.cli.ScalaCli.allowRestrictedFeatures +import scala.cli.commands.shared.HelpGroup import scala.cli.util.ArgHelpers.* import scala.util.{Properties, Try} object ScalaCliHelp { + private val sortedHelpGroups = Seq( + HelpGroup.Scala, + HelpGroup.Java, + HelpGroup.Watch, + HelpGroup.Dependency, + HelpGroup.Entrypoint, + HelpGroup.Debug, + HelpGroup.Repl, + HelpGroup.Run, + HelpGroup.Package, + HelpGroup.CompilationServer, + HelpGroup.Logging, + HelpGroup.Runner, + HelpGroup.Launcher, + HelpGroup.LegacyScalaRunner, + HelpGroup.ScalaJs, + HelpGroup.ScalaNative, + HelpGroup.Help + ) + private val hiddenHelpGroups = Seq(HelpGroup.ScalaJs, HelpGroup.ScalaNative) + private val sortedCommandGroups = + Seq(HelpCommandGroup.Main, HelpCommandGroup.Miscellaneous, HelpCommandGroup.Undefined) val helpFormat: HelpFormat = HelpFormat.default() .copy( filterArgs = Some(arg => arg.isSupported && (arg.isMust || arg.isImportant)), filterArgsWhenShowHidden = Some(_.isSupported), - sortedGroups = Some( - Seq( - "Scala", - "Java", - "Watch", - "Dependency", - "Entrypoint", - "Debug", - "Repl", - "Run", - "Package", - "Compilation server", - "Logging", - "Runner", - "Launcher", - "Legacy Scala runner", - "Scala.js", - "Scala Native", - "Help" - ) - ), - sortedCommandGroups = Some( - Seq( - "Main", - "Miscellaneous", - "" - ) - ), - hiddenGroups = Some( - Seq( - "Scala.js", - "Scala Native" - ) - ), terminalWidthOpt = if (Properties.isWin) if (coursier.paths.Util.useJni()) @@ -68,4 +57,7 @@ object ScalaCliHelp { // This requires writing our own minimal JNI library, that publishes '.a' files too for static linking in the executable of Scala CLI. None ) + .withSortedCommandGroups(sortedCommandGroups) + .withSortedGroups(sortedHelpGroups) + .withHiddenGroups(hiddenHelpGroups) } diff --git a/modules/cli/src/main/scala/scala/cli/commands/shared/ScalaJsOptions.scala b/modules/cli/src/main/scala/scala/cli/commands/shared/ScalaJsOptions.scala index a95a916567..20447053d8 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/shared/ScalaJsOptions.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/shared/ScalaJsOptions.scala @@ -9,89 +9,89 @@ import scala.cli.commands.{Constants, tags} // format: off final case class ScalaJsOptions( - @Group("Scala") + @Group(HelpGroup.Scala.toString) @Tag(tags.should) @HelpMessage("Enable Scala.js. To show more options for Scala.js pass `--help-js`") js: Boolean = false, - @Group("Scala.js") + @Group(HelpGroup.ScalaJs.toString) @Tag(tags.should) @HelpMessage(s"The Scala.js version (${Constants.scalaJsVersion} by default).") jsVersion: Option[String] = None, - @Group("Scala.js") + @Group(HelpGroup.ScalaJs.toString) @Tag(tags.should) @HelpMessage("The Scala.js mode, either `dev` or `release`") jsMode: Option[String] = None, @HelpMessage("The Scala.js module kind: commonjs/common, esmodule/es, nomodule/none") - @Group("Scala.js") + @Group(HelpGroup.ScalaJs.toString) @Tag(tags.should) jsModuleKind: Option[String] = None, - @Group("Scala.js") + @Group(HelpGroup.ScalaJs.toString) @Tag(tags.should) jsCheckIr: Option[Boolean] = None, - @Group("Scala.js") + @Group(HelpGroup.ScalaJs.toString) @HelpMessage("Emit source maps") @Tag(tags.should) jsEmitSourceMaps: Boolean = false, - @Group("Scala.js") + @Group(HelpGroup.ScalaJs.toString) @HelpMessage("Set the destination path of source maps") @Tag(tags.should) jsSourceMapsPath: Option[String] = None, - @Group("Scala.js") + @Group(HelpGroup.ScalaJs.toString) @Tag(tags.should) @HelpMessage("Enable jsdom") jsDom: Option[Boolean] = None, - @Group("Scala.js") + @Group(HelpGroup.ScalaJs.toString) @Tag(tags.should) @HelpMessage("A header that will be added at the top of generated .js files") jsHeader: Option[String] = None, - @Group("Scala.js") + @Group(HelpGroup.ScalaJs.toString) @Tag(tags.implementation) @HelpMessage("Primitive Longs *may* be compiled as primitive JavaScript bigints") jsAllowBigIntsForLongs: Option[Boolean] = None, - @Group("Scala.js") + @Group(HelpGroup.ScalaJs.toString) @Tag(tags.implementation) @HelpMessage("Avoid class'es when using functions and prototypes has the same observable semantics.") jsAvoidClasses: Option[Boolean] = None, - @Group("Scala.js") + @Group(HelpGroup.ScalaJs.toString) @Tag(tags.implementation) @HelpMessage("Avoid lets and consts when using vars has the same observable semantics.") jsAvoidLetsAndConsts: Option[Boolean] = None, - @Group("Scala.js") + @Group(HelpGroup.ScalaJs.toString) @Tag(tags.implementation) @HelpMessage("The Scala.js module split style: fewestmodules, smallestmodules, smallmodulesfor") jsModuleSplitStyle: Option[String] = None, - @Group("Scala.js") + @Group(HelpGroup.ScalaJs.toString) @Tag(tags.implementation) @HelpMessage("Create as many small modules as possible for the classes in the passed packages and their subpackages.") jsSmallModuleForPackage: List[String] = Nil, - @Group("Scala.js") + @Group(HelpGroup.ScalaJs.toString) @Tag(tags.should) @HelpMessage("The Scala.js ECMA Script version: es5_1, es2015, es2016, es2017, es2018, es2019, es2020, es2021") jsEsVersion: Option[String] = None, - @Group("Scala.js") + @Group(HelpGroup.ScalaJs.toString) @HelpMessage("Path to the Scala.js linker") @ValueDescription("path") @Tag(tags.implementation) @Hidden jsLinkerPath: Option[String] = None, - @Group("Scala.js") + @Group(HelpGroup.ScalaJs.toString) @HelpMessage(s"Scala.js CLI version to use for linking (${Constants.scalaJsCliVersion} by default).") @ValueDescription("version") @Tag(tags.implementation) @Hidden jsCliVersion: Option[String] = None, - @Group("Scala.js") + @Group(HelpGroup.ScalaJs.toString) @HelpMessage("Scala.js CLI Java options") @Tag(tags.implementation) @ValueDescription("option") @Hidden jsCliJavaArg: List[String] = Nil, - @Group("Scala.js") + @Group(HelpGroup.ScalaJs.toString) @HelpMessage("Whether to run the Scala.js CLI on the JVM or using a native executable") @Tag(tags.implementation) @Hidden diff --git a/modules/cli/src/main/scala/scala/cli/commands/shared/ScalaNativeOptions.scala b/modules/cli/src/main/scala/scala/cli/commands/shared/ScalaNativeOptions.scala index 3317251110..eaf89821c8 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/shared/ScalaNativeOptions.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/shared/ScalaNativeOptions.scala @@ -9,55 +9,55 @@ import scala.cli.commands.{Constants, tags} // format: off final case class ScalaNativeOptions( - @Group("Scala") + @Group(HelpGroup.Scala.toString) @HelpMessage("Enable Scala Native. To show more options for Scala Native pass `--help-native`") @Tag(tags.should) native: Boolean = false, - @Group("Scala Native") + @Group(HelpGroup.ScalaNative.toString) @Tag(tags.should) @HelpMessage(s"Set the Scala Native version (${Constants.scalaNativeVersion} by default).") nativeVersion: Option[String] = None, - @Group("Scala Native") + @Group(HelpGroup.ScalaNative.toString) @HelpMessage("Set Scala Native compilation mode") @Tag(tags.should) nativeMode: Option[String] = None, - @Group("Scala Native") + @Group(HelpGroup.ScalaNative.toString) @HelpMessage("Set the Scala Native garbage collector") @Tag(tags.should) nativeGc: Option[String] = None, - @Group("Scala Native") + @Group(HelpGroup.ScalaNative.toString) @HelpMessage("Path to the Clang command") @Tag(tags.implementation) nativeClang: Option[String] = None, - @Group("Scala Native") + @Group(HelpGroup.ScalaNative.toString) @HelpMessage("Path to the Clang++ command") @Tag(tags.implementation) nativeClangpp: Option[String] = None, - @Group("Scala Native") + @Group(HelpGroup.ScalaNative.toString) @HelpMessage("Extra options passed to `clang` verbatim during linking") @Tag(tags.should) nativeLinking: List[String] = Nil, - @Group("Scala Native") + @Group(HelpGroup.ScalaNative.toString) @HelpMessage("Use default linking settings") @Hidden @Tag(tags.implementation) nativeLinkingDefaults: Option[Boolean] = None, //TODO does it even work when we default it to true while handling? - @Group("Scala Native") + @Group(HelpGroup.ScalaNative.toString) @HelpMessage("List of compile options") @Tag(tags.should) nativeCompile: List[String] = Nil, - @Group("Scala Native") + @Group(HelpGroup.ScalaNative.toString) @Hidden @HelpMessage("Use default compile options") @Tag(tags.implementation) nativeCompileDefaults: Option[Boolean] = None, //TODO does it even work when we default it to true while handling? - @Group("Scala Native") + @Group(HelpGroup.ScalaNative.toString) @HelpMessage("Embed resources into the Scala Native binary (can be read with the Java resources API)") @Tag(tags.should) embedResources: Option[Boolean] = None diff --git a/modules/cli/src/main/scala/scala/cli/commands/shared/ScalacExtraOptions.scala b/modules/cli/src/main/scala/scala/cli/commands/shared/ScalacExtraOptions.scala index 23497ebc85..4cac594505 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/shared/ScalacExtraOptions.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/shared/ScalacExtraOptions.scala @@ -9,12 +9,12 @@ import com.github.plokhotnyuk.jsoniter_scala.macros.* */ // format: off final case class ScalacExtraOptions( - @Group("Scala") + @Group(HelpGroup.Scala.toString) @HelpMessage("Show help for scalac. This is an alias for --scalac-option -help") @Name("helpScalac") scalacHelp: Boolean = false, - @Group("Scala") + @Group(HelpGroup.Scala.toString) @HelpMessage("Turn verbosity on for scalac. This is an alias for --scalac-option -verbose") @Name("verboseScalac") scalacVerbose: Boolean = false, diff --git a/modules/cli/src/main/scala/scala/cli/commands/shared/ScalacOptions.scala b/modules/cli/src/main/scala/scala/cli/commands/shared/ScalacOptions.scala index 06f842675f..de995f5f19 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/shared/ScalacOptions.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/shared/ScalacOptions.scala @@ -12,7 +12,7 @@ import scala.cli.commands.tags // format: off final case class ScalacOptions( - @Group("Scala") + @Group(HelpGroup.Scala.toString) @HelpMessage("Add a scalac option") @ValueDescription("option") @Name("scala-opt") diff --git a/modules/cli/src/main/scala/scala/cli/commands/shared/SharedBspFileOptions.scala b/modules/cli/src/main/scala/scala/cli/commands/shared/SharedBspFileOptions.scala index f293d17a8c..35c3a67e32 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/shared/SharedBspFileOptions.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/shared/SharedBspFileOptions.scala @@ -6,13 +6,13 @@ import scala.cli.commands.tags // format: off final case class SharedBspFileOptions( - @Group("BSP") + @Group(HelpGroup.BSP.toString) @Name("bspDir") @HelpMessage("Custom BSP configuration location") @Tag(tags.implementation) @Hidden bspDirectory: Option[String] = None, - @Group("BSP") + @Group(HelpGroup.BSP.toString) @Name("name") @HelpMessage("Name of BSP") @Hidden diff --git a/modules/cli/src/main/scala/scala/cli/commands/shared/SharedCompilationServerOptions.scala b/modules/cli/src/main/scala/scala/cli/commands/shared/SharedCompilationServerOptions.scala index 65a26e612a..65ab273b2c 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/shared/SharedCompilationServerOptions.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/shared/SharedCompilationServerOptions.scala @@ -23,79 +23,79 @@ import scala.util.Properties // format: off final case class SharedCompilationServerOptions( - @Group("Compilation server") + @Group(HelpGroup.CompilationServer.toString) @HelpMessage("Protocol to use to open a BSP connection with Bloop") @ValueDescription("tcp|local|default") @Hidden bloopBspProtocol: Option[String] = None, - @Group("Compilation server") + @Group(HelpGroup.CompilationServer.toString) @HelpMessage("Socket file to use to open a BSP connection with Bloop") @ValueDescription("path") @Hidden bloopBspSocket: Option[String] = None, - @Group("Compilation server") + @Group(HelpGroup.CompilationServer.toString) @HelpMessage("Host the compilation server should bind to") @ValueDescription("host") @Hidden bloopHost: Option[String] = None, - @Group("Compilation server") + @Group(HelpGroup.CompilationServer.toString) @HelpMessage("Port the compilation server should bind to (pass `-1` to pick a random port)") @ValueDescription("port|-1") @Hidden bloopPort: Option[Int] = None, - @Group("Compilation server") + @Group(HelpGroup.CompilationServer.toString) @HelpMessage("Daemon directory of the Bloop daemon (directory with lock, pid, and socket files)") @ValueDescription("path") @Hidden bloopDaemonDir: Option[String] = None, - @Group("Compilation server") + @Group(HelpGroup.CompilationServer.toString) @HelpMessage("If Bloop isn't already running, the version we should start") @ValueDescription("version") @Hidden bloopVersion: Option[String] = None, @Hidden - @Group("Compilation server") + @Group(HelpGroup.CompilationServer.toString) @HelpMessage("Maximum duration to wait for the BSP connection to be opened") @ValueDescription("duration") bloopBspTimeout: Option[String] = None, @Hidden - @Group("Compilation server") + @Group(HelpGroup.CompilationServer.toString) @HelpMessage("Duration between checks of the BSP connection state") @ValueDescription("duration") bloopBspCheckPeriod: Option[String] = None, @Hidden - @Group("Compilation server") + @Group(HelpGroup.CompilationServer.toString) @HelpMessage("Maximum duration to wait for the compilation server to start up") @ValueDescription("duration") bloopStartupTimeout: Option[String] = None, - @Group("Compilation server") + @Group(HelpGroup.CompilationServer.toString) @HelpMessage("Include default JVM options for Bloop") @Hidden bloopDefaultJavaOpts: Boolean = true, - @Group("Compilation server") + @Group(HelpGroup.CompilationServer.toString) @HelpMessage("Pass java options to use by Bloop server") @Hidden bloopJavaOpt: List[String] = Nil, - @Group("Compilation server") + @Group(HelpGroup.CompilationServer.toString) @HelpMessage("Bloop global options file") @Hidden bloopGlobalOptionsFile: Option[String] = None, - @Group("Compilation server") + @Group(HelpGroup.CompilationServer.toString) @HelpMessage("JVM to use to start Bloop (e.g. 'system|11', 'temurin:17', …)") @Hidden bloopJvm: Option[String] = None, - @Group("Compilation server") + @Group(HelpGroup.CompilationServer.toString) @HelpMessage("Working directory for Bloop, if it needs to be started") @Hidden bloopWorkingDir: Option[String] = None, - @Group("Compilation server") + @Group(HelpGroup.CompilationServer.toString) @HelpMessage("Enable / disable usage of Bloop compilation server. Bloop is used by default so use `--server=false` to disable it. Disabling compilation server allows to test compilation in more controlled mannter (no caching or incremental compiler) but has a detrimental effect of performance.") server: Option[Boolean] = None ) { diff --git a/modules/cli/src/main/scala/scala/cli/commands/shared/SharedDebugOptions.scala b/modules/cli/src/main/scala/scala/cli/commands/shared/SharedDebugOptions.scala index d47e6bac44..b5b7e3c2f1 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/shared/SharedDebugOptions.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/shared/SharedDebugOptions.scala @@ -7,15 +7,15 @@ import scala.cli.commands.tags // format: off final case class SharedDebugOptions( - @Group("Debug") + @Group(HelpGroup.Debug.toString) @HelpMessage("Turn debugging on") @Tag(tags.should) debug: Boolean = false, - @Group("Debug") + @Group(HelpGroup.Debug.toString) @HelpMessage("Debug port (5005 by default)") @Tag(tags.should) debugPort: Option[String] = None, - @Group("Debug") + @Group(HelpGroup.Debug.toString) @Tag(tags.should) @HelpMessage("Debug mode (attach by default)") @ValueDescription("attach|a|listen|l") diff --git a/modules/cli/src/main/scala/scala/cli/commands/shared/SharedDependencyOptions.scala b/modules/cli/src/main/scala/scala/cli/commands/shared/SharedDependencyOptions.scala index 51f9a7b556..e8abe559a0 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/shared/SharedDependencyOptions.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/shared/SharedDependencyOptions.scala @@ -8,20 +8,20 @@ import scala.cli.commands.tags // format: off final case class SharedDependencyOptions( - @Group("Dependency") + @Group(HelpGroup.Dependency.toString) @HelpMessage("Add dependencies") @Tag(tags.must) @Name("dep") dependency: List[String] = Nil, - @Group("Dependency") + @Group(HelpGroup.Dependency.toString) @Tag(tags.should) @Tag(tags.inShortHelp) @HelpMessage("Add repositories") @Name("repo") @Name("r") repository: List[String] = Nil, - @Group("Scala") + @Group(HelpGroup.Scala.toString) @Name("P") @Name("plugin") @Tag(tags.must) diff --git a/modules/cli/src/main/scala/scala/cli/commands/shared/SharedJavaOptions.scala b/modules/cli/src/main/scala/scala/cli/commands/shared/SharedJavaOptions.scala index b56272f7d6..aae21c7893 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/shared/SharedJavaOptions.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/shared/SharedJavaOptions.scala @@ -6,7 +6,7 @@ import scala.cli.commands.tags // format: off final case class SharedJavaOptions( - @Group("Java") + @Group(HelpGroup.Java.toString) @HelpMessage("Set Java options, such as `-Xmx1g`") @ValueDescription("java-options") @Tag(tags.must) diff --git a/modules/cli/src/main/scala/scala/cli/commands/shared/SharedJvmOptions.scala b/modules/cli/src/main/scala/scala/cli/commands/shared/SharedJvmOptions.scala index 239597bcab..b8d8b7ebdf 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/shared/SharedJvmOptions.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/shared/SharedJvmOptions.scala @@ -11,45 +11,45 @@ final case class SharedJvmOptions( @Recurse sharedDebug: SharedDebugOptions = SharedDebugOptions(), - @Group("Java") + @Group(HelpGroup.Java.toString) @HelpMessage("Set the Java home directory") @Tag(tags.should) @ValueDescription("path") javaHome: Option[String] = None, - @Group("Java") + @Group(HelpGroup.Java.toString) @HelpMessage("Use a specific JVM, such as `14`, `adopt:11`, or `graalvm:21`, or `system`") @ValueDescription("jvm-name") @Tag(tags.should) @Name("j") @Tag(tags.inShortHelp) jvm: Option[String] = None, - @Group("Java") + @Group(HelpGroup.Java.toString) @HelpMessage("JVM index URL") @ValueDescription("url") @Tag(tags.implementation) @Hidden jvmIndex: Option[String] = None, - @Group("Java") + @Group(HelpGroup.Java.toString) @HelpMessage("Operating system to use when looking up in the JVM index") @ValueDescription("linux|linux-musl|darwin|windows|…") @Tag(tags.implementation) @Hidden jvmIndexOs: Option[String] = None, - @Group("Java") + @Group(HelpGroup.Java.toString) @HelpMessage("CPU architecture to use when looking up in the JVM index") @ValueDescription("amd64|arm64|arm|…") @Tag(tags.implementation) @Hidden jvmIndexArch: Option[String] = None, - @Group("Java") + @Group(HelpGroup.Java.toString) @HelpMessage("Javac plugin dependencies or files") @Tag(tags.should) @Hidden javacPlugin: List[String] = Nil, - @Group("Java") + @Group(HelpGroup.Java.toString) @HelpMessage("Javac options") @Name("javacOpt") @Tag(tags.should) @@ -57,7 +57,7 @@ final case class SharedJvmOptions( @Hidden javacOption: List[String] = Nil, - @Group("Java") + @Group(HelpGroup.Java.toString) @Tag(tags.implementation) @HelpMessage("Port for BSP debugging") @Hidden diff --git a/modules/cli/src/main/scala/scala/cli/commands/shared/SharedOptions.scala b/modules/cli/src/main/scala/scala/cli/commands/shared/SharedOptions.scala index 89adf14944..7d8b4a16ef 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/shared/SharedOptions.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/shared/SharedOptions.scala @@ -70,14 +70,14 @@ final case class SharedOptions( @Recurse sharedPython: SharedPythonOptions = SharedPythonOptions(), - @Group("Scala") + @Group(HelpGroup.Scala.toString) @HelpMessage(s"Set the Scala version (${Constants.defaultScalaVersion} by default)") @ValueDescription("version") @Name("scala") @Name("S") @Tag(tags.must) scalaVersion: Option[String] = None, - @Group("Scala") + @Group(HelpGroup.Scala.toString) @HelpMessage("Set the Scala binary version") @ValueDescription("version") @Hidden @@ -96,7 +96,7 @@ final case class SharedOptions( @Recurse markdown: MarkdownOptions = MarkdownOptions(), - @Group("Java") + @Group(HelpGroup.Java.toString) @HelpMessage("Add extra JARs and compiled classes to the class path") @ValueDescription("paths") @Name("jar") @@ -114,7 +114,7 @@ final case class SharedOptions( @Tag(tags.must) extraJars: List[String] = Nil, - @Group("Java") + @Group(HelpGroup.Java.toString) @HelpMessage("Add extra JARs in the compilaion class path. Mainly using to run code in managed environments like Spark not to include certain depenencies on runtime ClassPath.") @ValueDescription("paths") @Name("compileOnlyJar") @@ -123,7 +123,7 @@ final case class SharedOptions( @Tag(tags.should) extraCompileOnlyJars: List[String] = Nil, - @Group("Java") + @Group(HelpGroup.Java.toString) @HelpMessage("Add extra source JARs") @ValueDescription("paths") @Name("sourceJar") @@ -132,35 +132,36 @@ final case class SharedOptions( @Tag(tags.should) extraSourceJars: List[String] = Nil, - @Group("Java") + @Group(HelpGroup.Java.toString) @HelpMessage("Add a resource directory") @ValueDescription("paths") @Name("resourceDir") @Tag(tags.must) resourceDirs: List[String] = Nil, - @Group("Scala") + @Group(HelpGroup.Scala.toString) @HelpMessage("Specify platform") @ValueDescription("scala-js|scala-native|jvm") @Tag(tags.should) @Tag(tags.inShortHelp) platform: Option[String] = None, - @Group("Scala") + @Group(HelpGroup.Scala.toString) @Tag(tags.implementation) @Hidden scalaLibrary: Option[Boolean] = None, - @Group("Scala") + @Group(HelpGroup.Scala.toString) @HelpMessage("Allows to include the Scala compiler artifacts on the classpath.") @Tag(tags.must) @Name("withScalaCompiler") @Name("-with-compiler") withCompiler: Option[Boolean] = None, - @Group("Java") + @Group(HelpGroup.Java.toString) @HelpMessage("Do not add dependency to Scala Standard library. This is useful, when Scala CLI works with pure Java projects.") @Tag(tags.implementation) @Hidden java: Option[Boolean] = None, + @Group(HelpGroup.Scala.toString) @HelpMessage("Should include Scala CLI runner on the runtime ClassPath. Runner is added by default for application running on JVM using standard Scala versions. Runner is used to make stack traces more readable in case of application failure.") @Tag(tags.implementation) @Hidden @@ -183,7 +184,7 @@ final case class SharedOptions( @Hidden strictBloopJsonCheck: Option[Boolean] = None, - @Group("Scala") + @Group(HelpGroup.Scala.toString) @Name("output-directory") @Name("d") @Name("destination") @@ -193,7 +194,7 @@ final case class SharedOptions( @ValueDescription("/example/path") @Tag(tags.must) compilationOutput: Option[String] = None, - @Group("Scala") + @Group(HelpGroup.Scala.toString) @HelpMessage("Add toolkit to classPath") @ValueDescription("version|latest") @Name("toolkit") diff --git a/modules/cli/src/main/scala/scala/cli/commands/shared/SharedWatchOptions.scala b/modules/cli/src/main/scala/scala/cli/commands/shared/SharedWatchOptions.scala index a473150acd..df4e28ec7e 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/shared/SharedWatchOptions.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/shared/SharedWatchOptions.scala @@ -7,13 +7,13 @@ import scala.cli.commands.tags // format: off final case class SharedWatchOptions( - @Group("Watch") + @Group(HelpGroup.Watch.toString) @HelpMessage("Run the application in the background, automatically wake the thread and re-run if sources have been changed") @Tag(tags.should) @Tag(tags.inShortHelp) @Name("w") watch: Boolean = false, - @Group("Watch") + @Group(HelpGroup.Watch.toString) @HelpMessage("Run the application in the background, automatically kill the process and restart if sources have been changed") @Tag(tags.should) @Tag(tags.inShortHelp) diff --git a/modules/cli/src/main/scala/scala/cli/commands/shared/SnippetOptions.scala b/modules/cli/src/main/scala/scala/cli/commands/shared/SnippetOptions.scala index 7de49c295c..c704573804 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/shared/SnippetOptions.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/shared/SnippetOptions.scala @@ -6,12 +6,12 @@ import scala.cli.commands.tags // format: off final case class SnippetOptions( - @Group("Scala") + @Group(HelpGroup.Scala.toString) @HelpMessage("Allows to execute a passed string as a Scala script") @Tag(tags.should) scriptSnippet: List[String] = List.empty, - @Group("Scala") + @Group(HelpGroup.Scala.toString) @HelpMessage("A synonym to --script-snippet, which defaults the sub-command to `run` when no sub-command is passed explicitly") @Hidden @Name("executeScalaScript") @@ -20,34 +20,34 @@ final case class SnippetOptions( @Tag(tags.should) executeScript: List[String] = List.empty, - @Group("Scala") + @Group(HelpGroup.Scala.toString) @HelpMessage("Allows to execute a passed string as Scala code") @Tag(tags.should) scalaSnippet: List[String] = List.empty, - @Group("Scala") + @Group(HelpGroup.Scala.toString) @HelpMessage("A synonym to --scala-snippet, which defaults the sub-command to `run` when no sub-command is passed explicitly") @Hidden @Tag(tags.implementation) executeScala: List[String] = List.empty, - @Group("Java") + @Group(HelpGroup.Java.toString) @HelpMessage("Allows to execute a passed string as Java code") @Tag(tags.implementation) javaSnippet: List[String] = List.empty, - @Group("Java") + @Group(HelpGroup.Java.toString) @Tag(tags.implementation) @HelpMessage("A synonym to --scala-snippet, which defaults the sub-command to `run` when no sub-command is passed explicitly") executeJava: List[String] = List.empty, - @Group("Markdown") + @Group(HelpGroup.Markdown.toString) @HelpMessage("Allows to execute a passed string as Markdown code") @Name("mdSnippet") @Tag(tags.experimental) markdownSnippet: List[String] = List.empty, - @Group("Markdown") + @Group(HelpGroup.Markdown.toString) @HelpMessage("A synonym to --markdown-snippet, which defaults the sub-command to `run` when no sub-command is passed explicitly") @Name("executeMd") @Tag(tags.experimental) diff --git a/modules/cli/src/main/scala/scala/cli/commands/shared/VerbosityOptions.scala b/modules/cli/src/main/scala/scala/cli/commands/shared/VerbosityOptions.scala index 48cedcdf2c..5159273687 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/shared/VerbosityOptions.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/shared/VerbosityOptions.scala @@ -9,18 +9,18 @@ import scala.cli.commands.tags // format: off final case class VerbosityOptions( - @Group("Logging") + @Group(HelpGroup.Logging.toString) @HelpMessage("Increase verbosity (can be specified multiple times)") @Tag(tags.implementation) @Name("v") @Name("-verbose") verbose: Int @@ Counter = Tag.of(0), - @Group("Logging") + @Group(HelpGroup.Logging.toString) @HelpMessage("Interactive mode") @Name("i") @Tag(tags.implementation) interactive: Option[Boolean] = None, - @Group("Logging") + @Group(HelpGroup.Logging.toString) @HelpMessage("Enable actionable diagnostics") @Tag(tags.implementation) actions: Option[Boolean] = None diff --git a/modules/cli/src/main/scala/scala/cli/commands/shebang/Shebang.scala b/modules/cli/src/main/scala/scala/cli/commands/shebang/Shebang.scala index f12d7d3bb7..231b2a7ee6 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/shebang/Shebang.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/shebang/Shebang.scala @@ -7,16 +7,16 @@ import scala.build.Logger import scala.build.input.{ScalaCliInvokeData, SubCommand} import scala.build.options.BuildOptions import scala.cli.CurrentParams -import scala.cli.commands.ScalaCommand import scala.cli.commands.run.Run import scala.cli.commands.shared.SharedOptions +import scala.cli.commands.{ScalaCommand, SpecificationLevel} import scala.cli.util.ArgHelpers.* object Shebang extends ScalaCommand[ShebangOptions] { override def stopAtFirstUnrecognized: Boolean = true - override def scalaSpecificationLevel = SpecificationLevel.MUST - override def helpFormat: HelpFormat = super.helpFormat.withPrimaryGroups(Run.primaryHelpGroups) + override def scalaSpecificationLevel: SpecificationLevel = SpecificationLevel.MUST + override def helpFormat: HelpFormat = super.helpFormat.withPrimaryGroups(Run.primaryHelpGroups) override def sharedOptions(options: ShebangOptions): Option[SharedOptions] = Run.sharedOptions(options.runOptions) diff --git a/modules/cli/src/main/scala/scala/cli/commands/test/Test.scala b/modules/cli/src/main/scala/scala/cli/commands/test/Test.scala index 00c765ae5a..8bc950e4c5 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/test/Test.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/test/Test.scala @@ -16,18 +16,19 @@ import scala.cli.CurrentParams import scala.cli.commands.publish.ConfigUtil.* import scala.cli.commands.run.Run import scala.cli.commands.setupide.SetupIde -import scala.cli.commands.shared.SharedOptions +import scala.cli.commands.shared.{HelpCommandGroup, HelpGroup, SharedOptions} import scala.cli.commands.update.Update -import scala.cli.commands.{CommandUtils, ScalaCommand, WatchUtil} +import scala.cli.commands.{CommandUtils, ScalaCommand, SpecificationLevel, WatchUtil} import scala.cli.config.{ConfigDb, Keys} import scala.cli.util.ArgHelpers.* object Test extends ScalaCommand[TestOptions] { - override def group = "Main" + override def group: String = HelpCommandGroup.Main.toString override def sharedOptions(options: TestOptions): Option[SharedOptions] = Some(options.shared) - override def scalaSpecificationLevel = SpecificationLevel.SHOULD + override def scalaSpecificationLevel: SpecificationLevel = SpecificationLevel.SHOULD - override def helpFormat: HelpFormat = super.helpFormat.withPrimaryGroups(Seq("Test", "Watch")) + override def helpFormat: HelpFormat = + super.helpFormat.withPrimaryGroups(Seq(HelpGroup.Test, HelpGroup.Watch)) private def gray = "\u001b[90m" private def reset = Console.RESET diff --git a/modules/cli/src/main/scala/scala/cli/commands/test/TestOptions.scala b/modules/cli/src/main/scala/scala/cli/commands/test/TestOptions.scala index 740cc849d9..c1ae990c6d 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/test/TestOptions.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/test/TestOptions.scala @@ -3,14 +3,7 @@ package scala.cli.commands.test import caseapp.* import caseapp.core.help.Help -import scala.cli.commands.shared.{ - CrossOptions, - HasSharedOptions, - HelpMessages, - SharedJavaOptions, - SharedOptions, - SharedWatchOptions -} +import scala.cli.commands.shared._ import scala.cli.commands.tags @HelpMessage(TestOptions.helpMessage, "", TestOptions.detailedHelpMessage) @@ -25,19 +18,19 @@ final case class TestOptions( @Recurse compileCross: CrossOptions = CrossOptions(), - @Group("Test") + @Group(HelpGroup.Test.toString) @HelpMessage("Name of the test framework's runner class to use while running tests") @ValueDescription("class-name") @Tag(tags.should) @Tag(tags.inShortHelp) testFramework: Option[String] = None, - @Group("Test") + @Group(HelpGroup.Test.toString) @Tag(tags.should) @Tag(tags.inShortHelp) @HelpMessage("Fail if no test suites were run") requireTests: Boolean = false, - @Group("Test") + @Group(HelpGroup.Test.toString) @Tag(tags.should) @Tag(tags.inShortHelp) @HelpMessage("Specify a glob pattern to filter the tests suite to be run.") diff --git a/modules/cli/src/main/scala/scala/cli/commands/uninstall/UninstallOptions.scala b/modules/cli/src/main/scala/scala/cli/commands/uninstall/UninstallOptions.scala index b70b68b810..75eba649d2 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/uninstall/UninstallOptions.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/uninstall/UninstallOptions.scala @@ -6,7 +6,7 @@ import java.nio.file.Path import scala.cli.ScalaCli.{baseRunnerName, fullRunnerName} import scala.cli.commands.bloop.BloopExitOptions -import scala.cli.commands.shared.{HasLoggingOptions, HelpMessages, LoggingOptions} +import scala.cli.commands.shared.{HasLoggingOptions, HelpGroup, HelpMessages, LoggingOptions} import scala.cli.commands.tags import scala.cli.commands.uninstallcompletions.SharedUninstallCompletionsOptions @@ -20,20 +20,23 @@ final case class UninstallOptions( bloopExit: BloopExitOptions = BloopExitOptions(), @Recurse sharedUninstallCompletions: SharedUninstallCompletionsOptions = SharedUninstallCompletionsOptions(), - @Group("Uninstall") + @Group(HelpGroup.Uninstall.toString) @Name("f") @HelpMessage(s"Force $baseRunnerName uninstall") @Tag(tags.implementation) force: Boolean = false, @Hidden + @Group(HelpGroup.Uninstall.toString) @HelpMessage(s"Don't clear $fullRunnerName cache") @Tag(tags.implementation) skipCache: Boolean = false, @Hidden + @Group(HelpGroup.Uninstall.toString) @HelpMessage("Binary name") @Tag(tags.implementation) binaryName: String = baseRunnerName, @Hidden + @Group(HelpGroup.Uninstall.toString) @HelpMessage("Binary directory") @Tag(tags.implementation) binDir: Option[String] = None diff --git a/modules/cli/src/main/scala/scala/cli/commands/uninstallcompletions/SharedUninstallCompletionsOptions.scala b/modules/cli/src/main/scala/scala/cli/commands/uninstallcompletions/SharedUninstallCompletionsOptions.scala index f5dbf20695..6a3452eb3b 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/uninstallcompletions/SharedUninstallCompletionsOptions.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/uninstallcompletions/SharedUninstallCompletionsOptions.scala @@ -2,21 +2,22 @@ package scala.cli.commands.uninstallcompletions import caseapp.* +import scala.cli.commands.shared.HelpGroup import scala.cli.commands.tags // format: off final case class SharedUninstallCompletionsOptions( - @Group("Uninstall") + @Group(HelpGroup.Uninstall.toString) @HelpMessage("Path to `*rc` file, defaults to `.bashrc` or `.zshrc` depending on shell") @Tag(tags.implementation) @Tag(tags.inShortHelp) rcFile: Option[String] = None, - @Group("Uninstall") + @Group(HelpGroup.Uninstall.toString) @Hidden @HelpMessage("Custom banner in comment placed in rc file") @Tag(tags.implementation) banner: String = "{NAME} completions", - @Group("Uninstall") + @Group(HelpGroup.Uninstall.toString) @Hidden @HelpMessage("Custom completions name") @Tag(tags.implementation) diff --git a/modules/cli/src/main/scala/scala/cli/commands/uninstallcompletions/UninstallCompletions.scala b/modules/cli/src/main/scala/scala/cli/commands/uninstallcompletions/UninstallCompletions.scala index 1db52b1938..41a3e193b1 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/uninstallcompletions/UninstallCompletions.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/uninstallcompletions/UninstallCompletions.scala @@ -7,16 +7,18 @@ import java.nio.charset.Charset import scala.build.Logger import scala.cli.CurrentParams -import scala.cli.commands.ScalaCommand import scala.cli.commands.installcompletions.InstallCompletions +import scala.cli.commands.shared.HelpGroup +import scala.cli.commands.{ScalaCommand, SpecificationLevel} import scala.cli.internal.ProfileFileUpdater import scala.cli.util.ArgHelpers.* object UninstallCompletions extends ScalaCommand[UninstallCompletionsOptions] { - override def scalaSpecificationLevel = SpecificationLevel.IMPLEMENTATION + override def scalaSpecificationLevel: SpecificationLevel = SpecificationLevel.IMPLEMENTATION - override def helpFormat: HelpFormat = super.helpFormat.withPrimaryGroup("Uninstall") + override def helpFormat: HelpFormat = + super.helpFormat.withPrimaryGroup(HelpGroup.Uninstall) override def names = List( List("uninstall", "completions"), diff --git a/modules/cli/src/main/scala/scala/cli/commands/update/Update.scala b/modules/cli/src/main/scala/scala/cli/commands/update/Update.scala index 121289f721..d61fb5a3ee 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/update/Update.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/update/Update.scala @@ -10,7 +10,8 @@ import scala.build.Logger import scala.build.errors.CheckScalaCliVersionError import scala.build.internal.Constants.{ghName, ghOrg, version as scalaCliVersion} import scala.cli.CurrentParams -import scala.cli.commands.{CommandUtils, ScalaCommand} +import scala.cli.commands.shared.HelpGroup +import scala.cli.commands.{CommandUtils, ScalaCommand, SpecificationLevel} import scala.cli.internal.ProcUtil import scala.cli.signing.shared.Secret import scala.cli.util.ArgHelpers.* @@ -19,9 +20,9 @@ import scala.util.control.NonFatal object Update extends ScalaCommand[UpdateOptions] { - override def scalaSpecificationLevel = SpecificationLevel.IMPLEMENTATION + override def scalaSpecificationLevel: SpecificationLevel = SpecificationLevel.IMPLEMENTATION - override def helpFormat: HelpFormat = super.helpFormat.withPrimaryGroup("Update") + override def helpFormat: HelpFormat = super.helpFormat.withPrimaryGroup(HelpGroup.Update) private final case class Release( draft: Boolean, diff --git a/modules/cli/src/main/scala/scala/cli/commands/update/UpdateOptions.scala b/modules/cli/src/main/scala/scala/cli/commands/update/UpdateOptions.scala index 4d0d0a9e21..1c7cd89f15 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/update/UpdateOptions.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/update/UpdateOptions.scala @@ -3,7 +3,7 @@ package scala.cli.commands.update import caseapp.* import scala.cli.ScalaCli.{baseRunnerName, fullRunnerName} -import scala.cli.commands.shared.{HasLoggingOptions, HelpMessages, LoggingOptions} +import scala.cli.commands.shared.{HasLoggingOptions, HelpGroup, HelpMessages, LoggingOptions} import scala.cli.commands.tags import scala.cli.signing.shared.PasswordOption import scala.cli.signing.util.ArgParsers.* @@ -14,16 +14,17 @@ final case class UpdateOptions( @Recurse logging: LoggingOptions = LoggingOptions(), @Hidden - @Group("Update") + @Group(HelpGroup.Update.toString) @HelpMessage("Binary name") @Tag(tags.implementation) binaryName: String = baseRunnerName, @Hidden - @Group("Update") + @Group(HelpGroup.Update.toString) @HelpMessage("Binary directory") @Tag(tags.implementation) binDir: Option[String] = None, @Name("f") + @Group(HelpGroup.Update.toString) @HelpMessage(s"Force update $fullRunnerName if it is outdated") @Tag(tags.implementation) @Tag(tags.inShortHelp) diff --git a/modules/cli/src/main/scala/scala/cli/commands/version/Version.scala b/modules/cli/src/main/scala/scala/cli/commands/version/Version.scala index dbd560ab17..79104e783d 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/version/Version.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/version/Version.scala @@ -6,21 +6,21 @@ import caseapp.core.help.HelpFormat import scala.build.Logger import scala.build.internal.Constants import scala.cli.CurrentParams +import scala.cli.commands.shared.{HelpCommandGroup, HelpGroup} import scala.cli.commands.update.Update -import scala.cli.commands.{CommandUtils, ScalaCommand} +import scala.cli.commands.{CommandUtils, ScalaCommand, SpecificationLevel} import scala.cli.config.PasswordOption import scala.cli.util.ArgHelpers.* object Version extends ScalaCommand[VersionOptions] { - override def group = "Miscellaneous" + override def group: String = HelpCommandGroup.Miscellaneous.toString - override def scalaSpecificationLevel = SpecificationLevel.SHOULD - override def helpFormat: HelpFormat = super.helpFormat - .copy( - hiddenGroups = Some(Seq("Logging")), - hiddenGroupsWhenShowHidden = Some(Seq("Logging")) - ) - .withPrimaryGroup("Version") + override def scalaSpecificationLevel: SpecificationLevel = SpecificationLevel.SHOULD + override def helpFormat: HelpFormat = + super.helpFormat + .withHiddenGroup(HelpGroup.Logging) + .withHiddenGroupWhenShowHidden(HelpGroup.Logging) + .withPrimaryGroup(HelpGroup.Version) override def runCommand(options: VersionOptions, args: RemainingArgs, logger: Logger): Unit = { lazy val maybeNewerScalaCliVersion: Option[String] = diff --git a/modules/cli/src/main/scala/scala/cli/commands/version/VersionOptions.scala b/modules/cli/src/main/scala/scala/cli/commands/version/VersionOptions.scala index 23f722c568..b25924535d 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/version/VersionOptions.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/version/VersionOptions.scala @@ -3,7 +3,7 @@ package scala.cli.commands.version import caseapp.* import scala.cli.ScalaCli.fullRunnerName -import scala.cli.commands.shared.{HasLoggingOptions, HelpMessages, LoggingOptions} +import scala.cli.commands.shared.{HasLoggingOptions, HelpGroup, HelpMessages, LoggingOptions} import scala.cli.commands.tags import scala.cli.signing.shared.PasswordOption import scala.cli.signing.util.ArgParsers.* @@ -15,11 +15,11 @@ final case class VersionOptions( logging: LoggingOptions = LoggingOptions(), @Tag(tags.implementation) @Tag(tags.inShortHelp) - @Group("Version") + @Group(HelpGroup.Version.toString) @HelpMessage(s"Show plain $fullRunnerName version only") @Name("cli") cliVersion: Boolean = false, - @Group("Version") + @Group(HelpGroup.Version.toString) @HelpMessage("Show plain Scala version only") @Tag(tags.implementation) @Tag(tags.inShortHelp) @@ -29,7 +29,7 @@ final case class VersionOptions( @HelpMessage(HelpMessages.passwordOption) @Tag(tags.implementation) ghToken: Option[PasswordOption] = None, - @Group("Version") + @Group(HelpGroup.Version.toString) @Tag(tags.implementation) @Tag(tags.inShortHelp) @HelpMessage(s"Don't check for the newest available $fullRunnerName version upstream") diff --git a/modules/cli/src/main/scala/scala/cli/launcher/LauncherOptions.scala b/modules/cli/src/main/scala/scala/cli/launcher/LauncherOptions.scala index 185bddf3fb..169eaa4ecd 100644 --- a/modules/cli/src/main/scala/scala/cli/launcher/LauncherOptions.scala +++ b/modules/cli/src/main/scala/scala/cli/launcher/LauncherOptions.scala @@ -2,23 +2,24 @@ package scala.cli.launcher import caseapp.* +import scala.cli.commands.shared.HelpGroup import scala.cli.commands.tags @HelpMessage("Run another Scala CLI version") final case class LauncherOptions( - @Group("Launcher") + @Group(HelpGroup.Launcher.toString) @HelpMessage("Set the Scala CLI version") @ValueDescription("nightly|version") @Tag(tags.implementation) @Tag(tags.inShortHelp) cliVersion: Option[String] = None, - @Group("Launcher") + @Group(HelpGroup.Launcher.toString) @HelpMessage("The version of Scala on which Scala CLI was published") @ValueDescription("2.12|2.13|3") @Hidden @Tag(tags.implementation) cliScalaVersion: Option[String] = None, - @Group("Launcher") + @Group(HelpGroup.Launcher.toString) @HelpMessage("When called as 'scala', allow to use power commands too") @Tag(tags.must) power: Boolean = false diff --git a/modules/cli/src/main/scala/scala/cli/util/ArgHelpers.scala b/modules/cli/src/main/scala/scala/cli/util/ArgHelpers.scala index 6370437925..5aa094aa5f 100644 --- a/modules/cli/src/main/scala/scala/cli/util/ArgHelpers.scala +++ b/modules/cli/src/main/scala/scala/cli/util/ArgHelpers.scala @@ -4,6 +4,7 @@ import caseapp.core.Arg import caseapp.core.help.HelpFormat import scala.cli.ScalaCli.allowRestrictedFeatures +import scala.cli.commands.shared.{HelpCommandGroup, HelpGroup} import scala.cli.commands.{SpecificationLevel, tags} object ArgHelpers { @@ -23,12 +24,27 @@ object ArgHelpers { } extension (helpFormat: HelpFormat) { - def withPrimaryGroup(primaryGroup: String): HelpFormat = + def withPrimaryGroup(primaryGroup: HelpGroup): HelpFormat = helpFormat.withPrimaryGroups(Seq(primaryGroup)) - def withPrimaryGroups(primaryGroups: Seq[String]): HelpFormat = { + def withPrimaryGroups(primaryGroups: Seq[HelpGroup]): HelpFormat = { + val primaryStringGroups = primaryGroups.map(_.toString) val oldSortedGroups = helpFormat.sortedGroups.getOrElse(Seq.empty) - val filteredOldSortedGroups = oldSortedGroups.filterNot(primaryGroups.contains) - helpFormat.copy(sortedGroups = Some(primaryGroups ++ filteredOldSortedGroups)) + val filteredOldSortedGroups = oldSortedGroups.filterNot(primaryStringGroups.contains) + helpFormat.copy(sortedGroups = Some(primaryStringGroups ++ filteredOldSortedGroups)) } + def withHiddenGroups(hiddenGroups: Seq[HelpGroup]): HelpFormat = + helpFormat.copy(hiddenGroups = Some(hiddenGroups.map(_.toString))) + + def withHiddenGroup(hiddenGroup: HelpGroup): HelpFormat = + helpFormat.withHiddenGroups(Seq(hiddenGroup)) + def withHiddenGroupsWhenShowHidden(hiddenGroups: Seq[HelpGroup]): HelpFormat = + helpFormat.copy(hiddenGroupsWhenShowHidden = Some(hiddenGroups.map(_.toString))) + def withHiddenGroupWhenShowHidden(hiddenGroup: HelpGroup): HelpFormat = + helpFormat.withHiddenGroupsWhenShowHidden(Seq(hiddenGroup)) + def withSortedGroups(sortedGroups: Seq[HelpGroup]): HelpFormat = + helpFormat.copy(sortedGroups = Some(sortedGroups.map(_.toString))) + def withSortedCommandGroups(sortedGroups: Seq[HelpCommandGroup]): HelpFormat = + helpFormat.copy(sortedCommandGroups = Some(sortedGroups.map(_.toString))) + } }