Skip to content

Commit

Permalink
CLI: Use --style=STYLE option to select formatter
Browse files Browse the repository at this point in the history
  • Loading branch information
Joseph Cooper committed Jun 13, 2024
1 parent 57a3979 commit 925e6cc
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 23 deletions.
2 changes: 1 addition & 1 deletion core/src/main/java/com/facebook/ktfmt/cli/Main.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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=<name>] [--do-not-remove-unused-imports] File1.kt File2.kt ...
|Usage: ktfmt [--style=<meta | google | kotlinlang>] [--dry-run] [--set-exit-if-changed] [--stdin-name=<name>] [--do-not-remove-unused-imports] File1.kt File2.kt ...
|Or: ktfmt @file
|
|For more detail see ktfmt --help
Expand Down
32 changes: 24 additions & 8 deletions core/src/main/java/com/facebook/ktfmt/cli/ParsedArgs.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -119,8 +133,8 @@ data class ParsedArgs(
parseKeyValueArg("--stdin-name", arg)
?: return ParseResult.Error(
"Found option '${arg}', expected '${"--stdin-name"}=<value>'")
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)
}
}
Expand All @@ -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 }
Expand Down
8 changes: 4 additions & 4 deletions core/src/test/java/com/facebook/ktfmt/cli/MainTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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)
Expand Down
26 changes: 16 additions & 10 deletions core/src/test/java/com/facebook/ktfmt/cli/ParsedArgsTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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")))
Expand Down Expand Up @@ -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)
Expand All @@ -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(
Expand All @@ -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(
Expand All @@ -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"))
}

Expand Down

0 comments on commit 925e6cc

Please sign in to comment.