Skip to content

Commit cf8eac3

Browse files
Joseph Cooperfacebook-github-bot
authored andcommitted
Add CLI --help option (#477)
Summary: Intended to land on top of #476 Pull Request resolved: #477 Reviewed By: cortinico Differential Revision: D58448561 Pulled By: hick209 fbshipit-source-id: 28762cf9a9f40c88d981cb493b0c2f8299e9e622
1 parent 8f09ecb commit cf8eac3

File tree

6 files changed

+101
-6
lines changed

6 files changed

+101
-6
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/).
88

99
### Added
1010
- Created CHANGELOG.md
11+
- Added --help option to CLI (https://github.com/facebook/ktfmt/pull/477)
1112

1213
### Changed
1314
- Preserves blank spaces between when clauses (https://github.com/facebook/ktfmt/issues/342)

core/src/main/java/com/facebook/ktfmt/cli/Main.kt

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,13 @@ private const val EXIT_CODE_SUCCESS = 0
3737

3838
private val USAGE =
3939
"""
40-
Usage: ktfmt [--meta-style | --google-style | --kotlinlang-style] [--dry-run] [--set-exit-if-changed] [--stdin-name=<name>] [--do-not-remove-unused-imports] File1.kt File2.kt ...
41-
Or: ktfmt @file
42-
"""
43-
.trimIndent()
40+
|Usage:
41+
| ktfmt [OPTIONS] File1.kt File2.kt ...
42+
| ktfmt @ARGFILE
43+
|
44+
|For more details see `ktfmt --help`
45+
|"""
46+
.trimMargin()
4447

4548
class Main(
4649
private val input: InputStream,
@@ -80,6 +83,10 @@ class Main(
8083
val parsedArgs =
8184
when (processArgs) {
8285
is ParseResult.Ok -> processArgs.parsedValue
86+
is ParseResult.ShowMessage -> {
87+
out.println(processArgs.message)
88+
return EXIT_CODE_SUCCESS
89+
}
8390
is ParseResult.Error -> {
8491
err.println(processArgs.errorMessage)
8592
return EXIT_CODE_FAILURE

core/src/main/java/com/facebook/ktfmt/cli/ParsedArgs.kt

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,54 @@ data class ParsedArgs(
4848
return parseOptions(arguments)
4949
}
5050

51+
val HELP_TEXT =
52+
"""
53+
|ktfmt - command line Kotlin source code pretty-printer
54+
|
55+
|Usage:
56+
| ktfmt [OPTIONS] <File1.kt> <File2.kt> ...
57+
| ktfmt @ARGFILE
58+
|
59+
|ktfmt formats Kotlin source code files in-place, reporting for each file whether the
60+
|formatting succeeded or failed on standard error. If none of the style options are
61+
|passed, Meta's style is used.
62+
|
63+
|Alternatively, ktfmt can read Kotlin source code from standard input and write the
64+
|formatted result on standard output.
65+
|
66+
|Example:
67+
| $ ktfmt --kotlinlang-style Main.kt src/Parser.kt
68+
| Done formatting Main.kt
69+
| Error formatting src/Parser.kt: @@@ERROR@@@; skipping.
70+
|
71+
|Commands options:
72+
| -h, --help Show this help message
73+
| -n, --dry-run Don't write to files, only report files which
74+
| would have changed
75+
| --meta-style Use 2-space block indenting (default)
76+
| --google-style Google internal style (2 spaces)
77+
| --kotlinlang-style Kotlin language guidelines style (4 spaces)
78+
| --stdin-name=<name> Name to report when formatting code from stdin
79+
| --set-exit-if-changed Sets exit code to 1 if any input file was not
80+
| formatted/touched
81+
| --do-not-remove-unused-imports Leaves all imports in place, even if not used
82+
|
83+
|ARGFILE:
84+
| If the only argument begins with '@', the remainder of the argument is treated
85+
| as the name of a file to read options and arguments from, one per line.
86+
|
87+
| e.g.
88+
| $ cat arg-file.txt
89+
| --google-style
90+
| -n
91+
| File1.kt
92+
| File2.kt
93+
| $ ktfmt @arg-file1.txt
94+
| Done formatting File1.kt
95+
| Done formatting File2.kt
96+
|"""
97+
.trimMargin()
98+
5199
/** parseOptions parses command-line arguments passed to ktfmt. */
52100
fun parseOptions(args: Array<out String>): ParseResult {
53101
val fileNames = mutableListOf<String>()
@@ -57,6 +105,8 @@ data class ParsedArgs(
57105
var removeUnusedImports = true
58106
var stdinName: String? = null
59107

108+
if ("--help" in args || "-h" in args) return ParseResult.ShowMessage(HELP_TEXT)
109+
60110
for (arg in args) {
61111
when {
62112
arg == "--meta-style" -> formattingOptions = Formatter.META_FORMAT
@@ -108,5 +158,7 @@ data class ParsedArgs(
108158
sealed interface ParseResult {
109159
data class Ok(val parsedValue: ParsedArgs) : ParseResult
110160

161+
data class ShowMessage(val message: String) : ParseResult
162+
111163
data class Error(val errorMessage: String) : ParseResult
112164
}

core/src/test/java/com/facebook/ktfmt/cli/MainTest.kt

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -493,4 +493,18 @@ class MainTest {
493493
assertThat(exitCode).isEqualTo(0)
494494
assertThat(file.readText(UTF_8)).isEqualTo("""fun f() = println("hello, world")""" + "\n")
495495
}
496+
497+
@Test
498+
fun `--help gives return code of 0`() {
499+
val exitCode =
500+
Main(
501+
emptyInput,
502+
PrintStream(out),
503+
PrintStream(err),
504+
arrayOf("--help"),
505+
)
506+
.run()
507+
508+
assertThat(exitCode).isEqualTo(0)
509+
}
496510
}

core/src/test/java/com/facebook/ktfmt/cli/ParsedArgsTest.kt

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,25 @@ class ParsedArgsTest {
139139
assertThat(parseResult).isInstanceOf(ParseResult.Error::class.java)
140140
}
141141

142+
@Test
143+
fun `parseOptions recognises --help`() {
144+
val parseResult = ParsedArgs.parseOptions(arrayOf("--help"))
145+
assertThat(parseResult).isInstanceOf(ParseResult.ShowMessage::class.java)
146+
}
147+
148+
@Test
149+
fun `parseOptions recognises -h`() {
150+
val parseResult = ParsedArgs.parseOptions(arrayOf("-h"))
151+
assertThat(parseResult).isInstanceOf(ParseResult.ShowMessage::class.java)
152+
}
153+
154+
@Test
155+
fun `arg --help overrides all others`() {
156+
val parseResult =
157+
ParsedArgs.parseOptions(arrayOf("--style=google", "@unknown", "--help", "file.kt"))
158+
assertThat(parseResult).isInstanceOf(ParseResult.ShowMessage::class.java)
159+
}
160+
142161
@Test
143162
fun `processArgs use the @file option with non existing file`() {
144163
val e =

online_formatter/src/main/kotlin/main.kt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,7 @@ class Handler : RequestHandler<APIGatewayProxyRequestEvent, String> {
3535
try {
3636
val request = gson.fromJson(event.body, Request::class.java)
3737
val style = request.style
38-
val parseResult = ParsedArgs.parseOptions(listOfNotNull(style).toTypedArray())
39-
when (parseResult) {
38+
when (val parseResult = ParsedArgs.parseOptions(listOfNotNull(style).toTypedArray())) {
4039
is ParseResult.Ok -> {
4140
val parsedArgs = parseResult.parsedValue
4241
Response(
@@ -51,6 +50,9 @@ class Handler : RequestHandler<APIGatewayProxyRequestEvent, String> {
5150
is ParseResult.Error -> {
5251
Response(null, parseResult.errorMessage)
5352
}
53+
is ParseResult.ShowMessage -> {
54+
Response(null, parseResult.message)
55+
}
5456
}
5557
} catch (e: Exception) {
5658
Response(null, e.message)

0 commit comments

Comments
 (0)