diff --git a/pkl-cli/src/main/kotlin/org/pkl/cli/Main.kt b/pkl-cli/src/main/kotlin/org/pkl/cli/Main.kt index 155d4c5a..5173e7dc 100644 --- a/pkl-cli/src/main/kotlin/org/pkl/cli/Main.kt +++ b/pkl-cli/src/main/kotlin/org/pkl/cli/Main.kt @@ -22,5 +22,5 @@ import org.pkl.commons.cli.cliMain /** Main method of the Pkl CLI (command-line evaluator and REPL). */ internal fun main(args: Array) { - cliMain { RootCommand.main(args) } + cliMain { RootCommand().main(args) } } diff --git a/pkl-cli/src/main/kotlin/org/pkl/cli/commands/AnalyzeCommand.kt b/pkl-cli/src/main/kotlin/org/pkl/cli/commands/AnalyzeCommand.kt index 312b8ce3..d7248051 100644 --- a/pkl-cli/src/main/kotlin/org/pkl/cli/commands/AnalyzeCommand.kt +++ b/pkl-cli/src/main/kotlin/org/pkl/cli/commands/AnalyzeCommand.kt @@ -25,7 +25,7 @@ import org.pkl.cli.CliImportAnalyzerOptions import org.pkl.commons.cli.commands.ModulesCommand import org.pkl.commons.cli.commands.single -object AnalyzeCommand : +class AnalyzeCommand : NoOpCliktCommand( name = "analyze", help = "Commands related to static analysis", diff --git a/pkl-cli/src/main/kotlin/org/pkl/cli/commands/DownloadPackageCommand.kt b/pkl-cli/src/main/kotlin/org/pkl/cli/commands/DownloadPackageCommand.kt index 3f1846d0..d509e3c3 100644 --- a/pkl-cli/src/main/kotlin/org/pkl/cli/commands/DownloadPackageCommand.kt +++ b/pkl-cli/src/main/kotlin/org/pkl/cli/commands/DownloadPackageCommand.kt @@ -27,7 +27,7 @@ import org.pkl.commons.cli.commands.ProjectOptions import org.pkl.commons.cli.commands.single import org.pkl.core.packages.PackageUri -object DownloadPackageCommand : +class DownloadPackageCommand : BaseCommand( name = "download-package", helpLink = helpLink, diff --git a/pkl-cli/src/main/kotlin/org/pkl/cli/commands/EvalCommand.kt b/pkl-cli/src/main/kotlin/org/pkl/cli/commands/EvalCommand.kt index d73a69b0..d94198a2 100644 --- a/pkl-cli/src/main/kotlin/org/pkl/cli/commands/EvalCommand.kt +++ b/pkl-cli/src/main/kotlin/org/pkl/cli/commands/EvalCommand.kt @@ -24,7 +24,7 @@ import org.pkl.cli.CliEvaluatorOptions import org.pkl.commons.cli.commands.ModulesCommand import org.pkl.commons.cli.commands.single -object EvalCommand : +class EvalCommand : ModulesCommand(name = "eval", help = "Render pkl module(s)", helpLink = helpLink) { private val outputPath: String? by option( diff --git a/pkl-cli/src/main/kotlin/org/pkl/cli/commands/ProjectCommand.kt b/pkl-cli/src/main/kotlin/org/pkl/cli/commands/ProjectCommand.kt index 53039546..b21d9ad8 100644 --- a/pkl-cli/src/main/kotlin/org/pkl/cli/commands/ProjectCommand.kt +++ b/pkl-cli/src/main/kotlin/org/pkl/cli/commands/ProjectCommand.kt @@ -33,18 +33,18 @@ import org.pkl.commons.cli.commands.single private const val NEWLINE = '\u0085' -object ProjectCommand : +class ProjectCommand : NoOpCliktCommand( name = "project", help = "Run commands related to projects", epilog = "For more information, visit $helpLink", ) { init { - subcommands(ResolveCommand, PackageCommand) + subcommands(ResolveCommand(), PackageCommand()) } } -object ResolveCommand : +class ResolveCommand : BaseCommand( name = "resolve", helpLink = helpLink, @@ -74,7 +74,7 @@ object ResolveCommand : } } -object PackageCommand : +class PackageCommand : BaseCommand( name = "package", helpLink = helpLink, diff --git a/pkl-cli/src/main/kotlin/org/pkl/cli/commands/ReplCommand.kt b/pkl-cli/src/main/kotlin/org/pkl/cli/commands/ReplCommand.kt index 301ff323..3e03f349 100644 --- a/pkl-cli/src/main/kotlin/org/pkl/cli/commands/ReplCommand.kt +++ b/pkl-cli/src/main/kotlin/org/pkl/cli/commands/ReplCommand.kt @@ -21,8 +21,7 @@ import org.pkl.cli.CliRepl import org.pkl.commons.cli.commands.BaseCommand import org.pkl.commons.cli.commands.ProjectOptions -object ReplCommand : - BaseCommand(name = "repl", help = "Start a REPL session", helpLink = helpLink) { +class ReplCommand : BaseCommand(name = "repl", help = "Start a REPL session", helpLink = helpLink) { private val projectOptions by ProjectOptions() override fun run() { diff --git a/pkl-cli/src/main/kotlin/org/pkl/cli/commands/RootCommand.kt b/pkl-cli/src/main/kotlin/org/pkl/cli/commands/RootCommand.kt index 5041504c..d5291ea1 100644 --- a/pkl-cli/src/main/kotlin/org/pkl/cli/commands/RootCommand.kt +++ b/pkl-cli/src/main/kotlin/org/pkl/cli/commands/RootCommand.kt @@ -23,7 +23,7 @@ import org.pkl.core.Release internal val helpLink = "${Release.current().documentation.homepage}pkl-cli/index.html#usage" -object RootCommand : +class RootCommand : NoOpCliktCommand( name = "pkl", printHelpOnEmptyArgs = true, @@ -41,13 +41,13 @@ object RootCommand : } subcommands( - EvalCommand, - ReplCommand, - ServerCommand, - TestCommand, - ProjectCommand, - DownloadPackageCommand, - AnalyzeCommand, + EvalCommand(), + ReplCommand(), + ServerCommand(), + TestCommand(), + ProjectCommand(), + DownloadPackageCommand(), + AnalyzeCommand(), ) } } diff --git a/pkl-cli/src/main/kotlin/org/pkl/cli/commands/ServerCommand.kt b/pkl-cli/src/main/kotlin/org/pkl/cli/commands/ServerCommand.kt index 86941b0f..fe68fde7 100644 --- a/pkl-cli/src/main/kotlin/org/pkl/cli/commands/ServerCommand.kt +++ b/pkl-cli/src/main/kotlin/org/pkl/cli/commands/ServerCommand.kt @@ -19,7 +19,7 @@ import com.github.ajalt.clikt.core.CliktCommand import org.pkl.cli.CliServer import org.pkl.commons.cli.CliBaseOptions -object ServerCommand : +class ServerCommand : CliktCommand( name = "server", help = "Run as a server that communicates over standard input/output", diff --git a/pkl-cli/src/main/kotlin/org/pkl/cli/commands/TestCommand.kt b/pkl-cli/src/main/kotlin/org/pkl/cli/commands/TestCommand.kt index b4111ab8..0cb7fcd4 100644 --- a/pkl-cli/src/main/kotlin/org/pkl/cli/commands/TestCommand.kt +++ b/pkl-cli/src/main/kotlin/org/pkl/cli/commands/TestCommand.kt @@ -26,7 +26,7 @@ import org.pkl.commons.cli.commands.BaseOptions import org.pkl.commons.cli.commands.ProjectOptions import org.pkl.commons.cli.commands.TestOptions -object TestCommand : +class TestCommand : BaseCommand(name = "test", help = "Run tests within the given module(s)", helpLink = helpLink) { val modules: List by argument(name = "", help = "Module paths or URIs to evaluate.") diff --git a/pkl-cli/src/test/kotlin/org/pkl/cli/CliMainTest.kt b/pkl-cli/src/test/kotlin/org/pkl/cli/CliMainTest.kt index f9cf1a7f..011bd6c0 100644 --- a/pkl-cli/src/test/kotlin/org/pkl/cli/CliMainTest.kt +++ b/pkl-cli/src/test/kotlin/org/pkl/cli/CliMainTest.kt @@ -32,28 +32,28 @@ import org.pkl.commons.writeString import org.pkl.core.Release class CliMainTest { + private val rootCmd = RootCommand() @Test fun `duplicate CLI option produces meaningful error message`(@TempDir tempDir: Path) { val inputFile = tempDir.resolve("test.pkl").writeString("").toString() assertThatCode { - RootCommand.parse( + rootCmd.parse( arrayOf("eval", "--output-path", "path1", "--output-path", "path2", inputFile) ) } .hasMessage("Invalid value for \"--output-path\": Option cannot be repeated") assertThatCode { - RootCommand.parse(arrayOf("eval", "-o", "path1", "--output-path", "path2", inputFile)) + rootCmd.parse(arrayOf("eval", "-o", "path1", "--output-path", "path2", inputFile)) } .hasMessage("Invalid value for \"--output-path\": Option cannot be repeated") } @Test fun `eval requires at least one file`() { - assertThatCode { RootCommand.parse(arrayOf("eval")) } - .hasMessage("""Missing argument """"") + assertThatCode { rootCmd.parse(arrayOf("eval")) }.hasMessage("""Missing argument """"") } // Can't reliably create symlinks on Windows. @@ -74,7 +74,7 @@ class CliMainTest { val inputFile = tempDir.resolve("test.pkl").writeString(code).toString() val outputFile = makeSymdir(tempDir, "out", "linkOut").resolve("test.pkl").toString() - assertThatCode { RootCommand.parse(arrayOf("eval", inputFile, "-o", outputFile)) } + assertThatCode { rootCmd.parse(arrayOf("eval", inputFile, "-o", outputFile)) } .doesNotThrowAnyException() } @@ -85,24 +85,24 @@ class CliMainTest { val error = """Invalid value for "--multiple-file-output-path": Option is mutually exclusive with -o, --output-path and -x, --expression.""" - assertThatCode { RootCommand.parse(arrayOf("eval", "-m", testOut, "-x", "x", testIn)) } + assertThatCode { rootCmd.parse(arrayOf("eval", "-m", testOut, "-x", "x", testIn)) } .hasMessage(error) - assertThatCode { RootCommand.parse(arrayOf("eval", "-m", testOut, "-o", "/tmp/test", testIn)) } + assertThatCode { rootCmd.parse(arrayOf("eval", "-m", testOut, "-o", "/tmp/test", testIn)) } .hasMessage(error) } @Test fun `showing version works`() { - assertThatCode { RootCommand.parse(arrayOf("--version")) } - .hasMessage(Release.current().versionInfo) + assertThatCode { rootCmd.parse(arrayOf("--version")) }.hasMessage(Release.current().versionInfo) } @Test fun `file paths get parsed into URIs`(@TempDir tempDir: Path) { - RootCommand.parse(arrayOf("eval", makeInput(tempDir, "my file.txt"))) + val cmd = RootCommand() + cmd.parse(arrayOf("eval", makeInput(tempDir, "my file.txt"))) - val evalCmd = RootCommand.registeredSubcommands().filterIsInstance().first() + val evalCmd = cmd.registeredSubcommands().filterIsInstance().first() val modules = evalCmd.baseOptions.baseOptions(evalCmd.modules).normalizedSourceModules assertThat(modules).hasSize(1) assertThat(modules[0].path).endsWith("my file.txt") @@ -110,8 +110,7 @@ class CliMainTest { @Test fun `invalid URIs are not accepted`() { - val ex = - assertThrows { RootCommand.parse(arrayOf("eval", "file:my file.txt")) } + val ex = assertThrows { rootCmd.parse(arrayOf("eval", "file:my file.txt")) } assertThat(ex.message).contains("URI `file:my file.txt` has invalid syntax") } diff --git a/pkl-cli/src/test/kotlin/org/pkl/cli/CliTestRunnerTest.kt b/pkl-cli/src/test/kotlin/org/pkl/cli/CliTestRunnerTest.kt index 00211639..911c85e8 100644 --- a/pkl-cli/src/test/kotlin/org/pkl/cli/CliTestRunnerTest.kt +++ b/pkl-cli/src/test/kotlin/org/pkl/cli/CliTestRunnerTest.kt @@ -388,7 +388,7 @@ class CliTestRunnerTest { @Test fun `no source modules specified has same message as pkl eval`() { val e1 = assertThrows { CliTestRunner(CliBaseOptions(), CliTestOptions()).run() } - val e2 = assertThrows { RootCommand.parse(listOf("eval")) } + val e2 = assertThrows { RootCommand().parse(listOf("eval")) } assertThat(e1).hasMessageContaining("Missing argument \"\"") assertThat(e1.message!!.replace("test", "eval")).isEqualTo(e2.helpMessage()) } diff --git a/pkl-doc/src/main/kotlin/org/pkl/doc/Main.kt b/pkl-doc/src/main/kotlin/org/pkl/doc/Main.kt index 44485a15..6743b0fe 100644 --- a/pkl-doc/src/main/kotlin/org/pkl/doc/Main.kt +++ b/pkl-doc/src/main/kotlin/org/pkl/doc/Main.kt @@ -34,10 +34,10 @@ import org.pkl.core.Release /** Main method for the Pkldoc CLI. */ internal fun main(args: Array) { - cliMain { DocCommand.main(args) } + cliMain { DocCommand().main(args) } } -object DocCommand : +class DocCommand : BaseCommand(name = "pkldoc", helpLink = Release.current().documentation().homepage()) { private val modules: List by diff --git a/pkl-doc/src/test/kotlin/org/pkl/doc/CliMainTest.kt b/pkl-doc/src/test/kotlin/org/pkl/doc/CliMainTest.kt index 868d93a6..0beda712 100644 --- a/pkl-doc/src/test/kotlin/org/pkl/doc/CliMainTest.kt +++ b/pkl-doc/src/test/kotlin/org/pkl/doc/CliMainTest.kt @@ -23,7 +23,8 @@ import org.pkl.commons.cli.CliException class CliMainTest { @Test fun `CLI run test`() { - val e = assertThrows { DocCommand.parse(arrayOf("foo", "--output-dir", "/tmp")) } + val e = + assertThrows { DocCommand().parse(arrayOf("foo", "--output-dir", "/tmp")) } assertThat(e) .hasMessageContaining("must contain at least one module named `doc-package-info.pkl`") }