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 5f46eb92..1a033ed5 100644 --- a/core/src/main/java/com/facebook/ktfmt/cli/Main.kt +++ b/core/src/main/java/com/facebook/ktfmt/cli/Main.kt @@ -36,7 +36,7 @@ class Main( private val input: InputStream, private val out: PrintStream, private val err: PrintStream, - args: Array + private val args: Array ) { companion object { @JvmStatic @@ -69,9 +69,13 @@ class Main( } } - private val parsedArgs: ParsedArgs = ParsedArgs.processArgs(err, args) + fun run(): Int { + val parsedArgs = when (val argParseResult = ParsedArgs.processArgs(err, args)) { + is ArgParseResult.Ok -> argParseResult.parsedArgs + is ArgParseResult.Error -> exitFatal(argParseResult.errorMessage, 1) + } if (parsedArgs.fileNames.isEmpty()) { err.println( "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 ...") @@ -81,7 +85,7 @@ class Main( if (parsedArgs.fileNames.size == 1 && parsedArgs.fileNames[0] == "-") { return try { - val alreadyFormatted = format(null) + val alreadyFormatted = format(null,parsedArgs) if (!alreadyFormatted && parsedArgs.setExitIfChanged) 1 else 0 } catch (e: Exception) { 1 @@ -107,7 +111,7 @@ class Main( val retval = AtomicInteger(0) files.parallelStream().forEach { try { - if (!format(it) && parsedArgs.setExitIfChanged) { + if (!format(it, parsedArgs) && parsedArgs.setExitIfChanged) { retval.set(1) } } catch (e: Exception) { @@ -126,17 +130,17 @@ class Main( * @param file The file to format. If null, the code is read from . * @return true iff input is valid and already formatted. */ - private fun format(file: File?): Boolean { - val fileName = file?.toString() ?: parsedArgs.stdinName ?: "" + private fun format(file: File?, args: ParsedArgs): Boolean { + val fileName = file?.toString() ?: args.stdinName ?: "" try { val bytes = if (file == null) input else FileInputStream(file) val code = BufferedReader(InputStreamReader(bytes, UTF_8)).readText() - val formattedCode = Formatter.format(parsedArgs.formattingOptions, code) + val formattedCode = Formatter.format(args.formattingOptions, code) val alreadyFormatted = code == formattedCode // stdin if (file == null) { - if (parsedArgs.dryRun) { + if (args.dryRun) { if (!alreadyFormatted) { out.println(fileName) } @@ -146,7 +150,7 @@ class Main( return alreadyFormatted } - if (parsedArgs.dryRun) { + if (args.dryRun) { if (!alreadyFormatted) { out.println(fileName) } @@ -173,4 +177,11 @@ class Main( throw e } } + + fun exitFatal(message: String, returnCode: Int): Nothing { + err.println(message) + exitProcess(returnCode) + } + } + 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 e0009f7b..6670c18b 100644 --- a/core/src/main/java/com/facebook/ktfmt/cli/ParsedArgs.kt +++ b/core/src/main/java/com/facebook/ktfmt/cli/ParsedArgs.kt @@ -39,11 +39,11 @@ data class ParsedArgs( ) { companion object { - fun processArgs(err: PrintStream, args: Array): ParsedArgs { + fun processArgs(err: PrintStream, args: Array): ArgParseResult { if (args.size == 1 && args[0].startsWith("@")) { - return parseOptions(err, File(args[0].substring(1)).readLines(UTF_8).toTypedArray()) + return ArgParseResult.Ok(parseOptions(err, File(args[0].substring(1)).readLines(UTF_8).toTypedArray())) } else { - return parseOptions(err, args) + return ArgParseResult.Ok(parseOptions(err, args)) } } @@ -90,3 +90,8 @@ data class ParsedArgs( } } } + +sealed interface ArgParseResult { + data class Ok(val parsedArgs: ParsedArgs): ArgParseResult + data class Error(val errorMessage: String): ArgParseResult +} 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 9f0919bf..77539663 100644 --- a/core/src/test/java/com/facebook/ktfmt/cli/ParsedArgsTest.kt +++ b/core/src/test/java/com/facebook/ktfmt/cli/ParsedArgsTest.kt @@ -177,7 +177,10 @@ class ParsedArgsTest { val file = root.resolve("existing-file") file.writeText("--google-style\n--dry-run\n--set-exit-if-changed\nFile1.kt\nFile2.kt\n") - val parsed = ParsedArgs.processArgs(PrintStream(out), arrayOf("@" + file.absolutePath)) + val result = ParsedArgs.processArgs(PrintStream(out), arrayOf("@" + file.absolutePath)) + assertThat(result).isInstanceOf(ArgParseResult.Ok::class.java) + + val parsed = (result as ArgParseResult.Ok).parsedArgs assertThat(parsed.formattingOptions).isEqualTo(Formatter.GOOGLE_FORMAT) assertThat(parsed.dryRun).isTrue()