From 925e6ccd31758628f3e33239073172eaaa556aa1 Mon Sep 17 00:00:00 2001 From: Joseph Cooper Date: Thu, 13 Jun 2024 16:29:26 +0100 Subject: [PATCH] CLI: Use --style=STYLE option to select formatter --- .../main/java/com/facebook/ktfmt/cli/Main.kt | 2 +- .../java/com/facebook/ktfmt/cli/ParsedArgs.kt | 32 ++++++++++++++----- .../java/com/facebook/ktfmt/cli/MainTest.kt | 8 ++--- .../com/facebook/ktfmt/cli/ParsedArgsTest.kt | 26 +++++++++------ 4 files changed, 45 insertions(+), 23 deletions(-) diff --git a/core/src/main/java/com/facebook/ktfmt/cli/Main.kt b/core/src/main/java/com/facebook/ktfmt/cli/Main.kt index 4d6bec9c..42d53a45 100644 --- a/core/src/main/java/com/facebook/ktfmt/cli/Main.kt +++ b/core/src/main/java/com/facebook/ktfmt/cli/Main.kt @@ -37,7 +37,7 @@ private const val EXIT_CODE_SUCCESS = 0 private val USAGE = """ - |Usage: ktfmt [--dropbox-style | --google-style | --kotlinlang-style] [--dry-run] [--set-exit-if-changed] [--stdin-name=] [--do-not-remove-unused-imports] File1.kt File2.kt ... + |Usage: ktfmt [--style=] [--dry-run] [--set-exit-if-changed] [--stdin-name=] [--do-not-remove-unused-imports] File1.kt File2.kt ... |Or: ktfmt @file | |For more detail see ktfmt --help diff --git a/core/src/main/java/com/facebook/ktfmt/cli/ParsedArgs.kt b/core/src/main/java/com/facebook/ktfmt/cli/ParsedArgs.kt index 0e758129..9600d918 100644 --- a/core/src/main/java/com/facebook/ktfmt/cli/ParsedArgs.kt +++ b/core/src/main/java/com/facebook/ktfmt/cli/ParsedArgs.kt @@ -71,9 +71,11 @@ data class ParsedArgs( | -h, --help Show this help message | -n, --dry-run Don't write to files, only report files which | would have changed - | --meta-style Use 2-space block indenting (default) - | --google-style Google internal style (2 spaces) - | --kotlinlang-style Kotlin language guidelines style (4 spaces + | --style=STYLE Format files according to the chosen style + | Accepted options for STYLE are: + | meta Use 2-space block indenting (default) + | google Google internal style (2 spaces) + | kotlinlang Kotlin language guidelines style (4 spaces | --set-exit-if-changed Sets exit code to 1 if any input code was not | correctly formatted | --stdin-name=NAME Name to use when reading from standard input @@ -108,9 +110,21 @@ data class ParsedArgs( for (arg in args) { when { - arg == "--meta-style" -> formattingOptions = Formatter.META_FORMAT - arg == "--google-style" -> formattingOptions = Formatter.GOOGLE_FORMAT - arg == "--kotlinlang-style" -> formattingOptions = Formatter.KOTLINLANG_FORMAT + arg.startsWith("--style=") -> { + val parsedStyle = + parseKeyValueArg("--style", arg) + ?: return ParseResult.Error( + unexpectedArg(arg) + ) + formattingOptions = when (parsedStyle) { + "meta" -> Formatter.META_FORMAT + "google" -> Formatter.GOOGLE_FORMAT + "kotlinlang" -> Formatter.KOTLINLANG_FORMAT + else -> return ParseResult.Error( + "Unknown style '${parsedStyle}'. Style must be one of [dropbox, google, kotlinlang]." + ) + } + } arg == "--dry-run" || arg == "-n" -> dryRun = true arg == "--set-exit-if-changed" -> setExitIfChanged = true arg == "--do-not-remove-unused-imports" -> removeUnusedImports = false @@ -119,8 +133,8 @@ data class ParsedArgs( parseKeyValueArg("--stdin-name", arg) ?: return ParseResult.Error( "Found option '${arg}', expected '${"--stdin-name"}='") - arg.startsWith("--") -> return ParseResult.Error("Unexpected option: $arg") - arg.startsWith("@") -> return ParseResult.Error("Unexpected option: $arg") + arg.startsWith("--") -> return ParseResult.Error(unexpectedArg(arg)) + arg.startsWith("@") -> return ParseResult.Error(unexpectedArg(arg)) else -> fileNames.add(arg) } } @@ -147,6 +161,8 @@ data class ParsedArgs( )) } + private fun unexpectedArg(arg: String) = "Unexpected option: $arg" + private fun parseKeyValueArg(key: String, arg: String): String? { val parts = arg.split('=', limit = 2) return parts[1].takeIf { parts[0] == key || parts.size == 2 } diff --git a/core/src/test/java/com/facebook/ktfmt/cli/MainTest.kt b/core/src/test/java/com/facebook/ktfmt/cli/MainTest.kt index 036bde6b..5bed8c30 100644 --- a/core/src/test/java/com/facebook/ktfmt/cli/MainTest.kt +++ b/core/src/test/java/com/facebook/ktfmt/cli/MainTest.kt @@ -225,7 +225,7 @@ class MainTest { } @Test - fun `kotlinlang-style is passed to formatter (file)`() { + fun `--style=kotlinlang is passed to formatter (file)`() { val code = """fun f() { for (child in @@ -241,14 +241,14 @@ class MainTest { emptyInput, PrintStream(out), PrintStream(err), - arrayOf("--kotlinlang-style", fooBar.toString())) + arrayOf("--style=kotlinlang", fooBar.toString())) .run() assertThat(fooBar.readText()).isEqualTo(code) } @Test - fun `kotlinlang-style is passed to formatter (stdin)`() { + fun `--style=kotlinlang is passed to formatter (stdin)`() { val code = """fun f() { |for (child in @@ -271,7 +271,7 @@ class MainTest { code.byteInputStream(), PrintStream(out), PrintStream(err), - arrayOf("--kotlinlang-style", "-")) + arrayOf("--style=kotlinlang", "-")) .run() assertThat(out.toString(UTF_8)).isEqualTo(formatted) diff --git a/core/src/test/java/com/facebook/ktfmt/cli/ParsedArgsTest.kt b/core/src/test/java/com/facebook/ktfmt/cli/ParsedArgsTest.kt index bb1b8ffb..18856ece 100644 --- a/core/src/test/java/com/facebook/ktfmt/cli/ParsedArgsTest.kt +++ b/core/src/test/java/com/facebook/ktfmt/cli/ParsedArgsTest.kt @@ -61,23 +61,29 @@ class ParsedArgsTest { } @Test - fun `parseOptions recognizes --meta-style`() { - val parsed = assertSucceeds(ParsedArgs.parseOptions(arrayOf("--meta-style", "foo.kt"))) + fun `parseOptions recognizes --style=meta`() { + val parsed = assertSucceeds(ParsedArgs.parseOptions(arrayOf("--style=meta", "foo.kt"))) assertThat(parsed.formattingOptions).isEqualTo(Formatter.META_FORMAT) } @Test - fun `parseOptions recognizes --dropbox-style`() { - val parsed = assertSucceeds(ParsedArgs.parseOptions(arrayOf("--kotlinlang-style", "foo.kt"))) + fun `parseOptions recognizes --style=kotlinlang`() { + val parsed = assertSucceeds(ParsedArgs.parseOptions(arrayOf("--style=kotlinlang", "foo.kt"))) assertThat(parsed.formattingOptions).isEqualTo(Formatter.KOTLINLANG_FORMAT) } @Test - fun `parseOptions recognizes --google-style`() { - val parsed = assertSucceeds(ParsedArgs.parseOptions(arrayOf("--google-style", "foo.kt"))) + fun `parseOptions recognizes --style=google`() { + val parsed = assertSucceeds(ParsedArgs.parseOptions(arrayOf("--style=google", "foo.kt"))) assertThat(parsed.formattingOptions).isEqualTo(Formatter.GOOGLE_FORMAT) } + @Test + fun `parseOptions rejects unknown style`() { + val parseResult = ParsedArgs.parseOptions(arrayOf("--style=custom-style", "foo.kt")) + assertThat(parseResult).isInstanceOf(ParseResult.Error::class.java) + } + @Test fun `parseOptions recognizes --dry-run`() { val parsed = assertSucceeds(ParsedArgs.parseOptions(arrayOf("--dry-run", "foo.kt"))) @@ -169,7 +175,7 @@ class ParsedArgsTest { @Test fun `processArgs use the @file option with file containing arguments`() { val file = root.resolve("existing-file") - file.writeText("--google-style\n--dry-run\n--set-exit-if-changed\nFile1.kt\nFile2.kt\n") + file.writeText("--style=google\n--dry-run\n--set-exit-if-changed\nFile1.kt\nFile2.kt\n") val result = ParsedArgs.processArgs(arrayOf("@" + file.absolutePath)) assertThat(result).isInstanceOf(ParseResult.Ok::class.java) @@ -186,7 +192,7 @@ class ParsedArgsTest { fun `parses multiple args successfully`() { val testResult = ParsedArgs.parseOptions( - arrayOf("--google-style", "--dry-run", "--set-exit-if-changed", "File.kt"), + arrayOf("--style=google", "--dry-run", "--set-exit-if-changed", "File.kt"), ) assertThat(testResult) .isEqualTo( @@ -201,7 +207,7 @@ class ParsedArgsTest { @Test fun `last style in args wins`() { val testResult = - ParsedArgs.parseOptions(arrayOf("--google-style", "--kotlinlang-style", "File.kt")) + ParsedArgs.parseOptions(arrayOf("--style=google", "--style=kotlinlang", "File.kt")) assertThat(testResult) .isEqualTo( parseResultOk( @@ -212,7 +218,7 @@ class ParsedArgsTest { @Test fun `error when parsing multiple args and one is unknown`() { - val testResult = ParsedArgs.parseOptions(arrayOf("@unknown", "--google-style", "File.kt")) + val testResult = ParsedArgs.parseOptions(arrayOf("@unknown", "--style=google", "File.kt")) assertThat(testResult).isEqualTo(ParseResult.Error("Unexpected option: @unknown")) }