Skip to content

Commit 88fd5ea

Browse files
authored
Split markdown into separate module (#549)
1 parent becce2e commit 88fd5ea

File tree

67 files changed

+574
-137
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

67 files changed

+574
-137
lines changed

.github/workflows/build.yml

+5-7
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,8 @@ jobs:
3333
with:
3434
distribution: 'zulu'
3535
java-version: 17
36-
- uses: gradle/actions/setup-gradle@v3
37-
with:
38-
arguments: ${{matrix.TEST_TASK}} --stacktrace
36+
- uses: gradle/actions/setup-gradle@v4
37+
- run: ./gradlew ${{matrix.TEST_TASK}} --stacktrace
3938
- name: Upload the build report
4039
if: failure()
4140
uses: actions/upload-artifact@master
@@ -53,10 +52,9 @@ jobs:
5352
distribution: 'zulu'
5453
java-version: 17
5554
- name: Deploy to sonatype
56-
uses: gradle/actions/setup-gradle@v3
57-
with:
58-
# disable configuration cache due to https://github.com/gradle/gradle/issues/22779
59-
arguments: publishToMavenCentral -PsnapshotVersion=true --no-configuration-cache
55+
uses: gradle/actions/setup-gradle@v4
56+
# disable configuration cache due to https://github.com/gradle/gradle/issues/22779
57+
- run: ./gradlew publishToMavenCentral -PsnapshotVersion=true --no-configuration-cache
6058
env:
6159
ORG_GRADLE_PROJECT_mavenCentralPassword: ${{ secrets.ORG_GRADLE_PROJECT_mavenCentralPassword }}
6260
ORG_GRADLE_PROJECT_signingInMemoryKey: ${{ secrets.ORG_GRADLE_PROJECT_signingInMemoryKey }}

.github/workflows/gradle-wrapper-validation.yml

-14
This file was deleted.

.github/workflows/release.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ jobs:
1515
with:
1616
distribution: 'zulu'
1717
java-version: 17
18-
- uses: gradle/actions/setup-gradle@v3
18+
- uses: gradle/actions/setup-gradle@v4
1919
with:
2020
# disable configuration cache due to https://github.com/gradle/gradle/issues/22779
2121
arguments: publishToMavenCentral --no-configuration-cache

CHANGELOG.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
- Added `associate{}`, `associateBy{}`, and `associateWith{}` transforms for options that allow you to convert the keys and values of the map. ([#529](https://github.com/ajalt/clikt/pull/529))
1919
- Added support for aliasing options to other options. ([#535](https://github.com/ajalt/clikt/pull/535))
2020
- Added `limit` and `ignoreCase` parameters to `option().split()`. ([#541](https://github.com/ajalt/clikt/pull/541))
21+
- Support calling `--help` on subcommands when parents have required parameters.
2122

2223
### Changed
2324
- In a subcommand with and an `argument()` with `multiple()` or `optional()`, the behavior is now the same regardless of the value of `allowMultipleSubcommands`: if a token matches a subcommand name, it's now treated as a subcommand rather than a positional argument.
@@ -39,8 +40,8 @@
3940
- **Breaking Change:** `CliktCommand.main` and `CliktCommand.parse` are now extension functions rather than methods.
4041
- **Breaking Change:** `Context.obj` and `Context.terminal`, and `OptionTransformContext.terminal` are now extension functions rather than properties.
4142
- **Breaking Change:** The `RenderedSection` and `DefinitionRow` classes have moved to `AbstractHelpFormatter`.
43+
- Markdown support in the help formatter is no longer included by default. To enable it, include the `:clikt-markdown` dependency and call `yourCommand.installMordantMarkdown()` before parsing.
4244
- Updated Kotlin to 2.0.0
43-
- Support calling `--help` on subcommands when parents have required parameters.
4445

4546
### Fixed
4647
- Fixed excess arguments not being reported when `allowMultipleSubcommands=true` and a subcommand has excess arguments followed by another subcommand.

clikt-mordant-markdown/README.md

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Module clikt-mordant-markdown
2+
3+
This module provides the `MordantMarkdownHelpFormatter` that renders text as markdown.
4+
5+
## Installation
6+
7+
```kotlin
8+
dependencies {
9+
implementation("com.github.ajalt.clikt:clikt-markdown:$cliktVersion")
10+
}
11+
```
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
public final class com/github/ajalt/clikt/core/MordantMarkdownContextKt {
2+
public static final fun installMordantMarkdown (Lcom/github/ajalt/clikt/core/BaseCliktCommand;)V
3+
}
4+
5+
public class com/github/ajalt/clikt/output/MordantMarkdownHelpFormatter : com/github/ajalt/clikt/output/MordantHelpFormatter {
6+
public fun <init> (Lcom/github/ajalt/clikt/core/Context;Ljava/lang/String;ZZ)V
7+
public synthetic fun <init> (Lcom/github/ajalt/clikt/core/Context;Ljava/lang/String;ZZILkotlin/jvm/internal/DefaultConstructorMarker;)V
8+
public fun renderWrappedText (Ljava/lang/String;)Lcom/github/ajalt/mordant/rendering/Widget;
9+
}
10+
+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import org.jetbrains.kotlin.gradle.targets.js.dsl.ExperimentalWasmDsl
2+
3+
4+
plugins {
5+
kotlin("multiplatform")
6+
}
7+
8+
kotlin {
9+
jvm()
10+
11+
js { nodejs() }
12+
@OptIn(ExperimentalWasmDsl::class)
13+
wasmJs { nodejs() }
14+
15+
linuxX64()
16+
linuxArm64()
17+
mingwX64()
18+
macosX64()
19+
macosArm64()
20+
21+
iosArm64()
22+
iosX64()
23+
24+
sourceSets {
25+
val commonMain by getting {
26+
dependencies {
27+
api(project(":clikt"))
28+
api(project(":clikt-mordant"))
29+
api(libs.mordant)
30+
api(libs.mordant.markdown)
31+
}
32+
}
33+
34+
val commonTest by getting {
35+
dependencies {
36+
api(kotlin("test"))
37+
api(libs.kotest)
38+
api(libs.coroutines.core)
39+
api(libs.coroutines.test)
40+
}
41+
}
42+
43+
val jvmTest by getting {
44+
dependencies {
45+
api(libs.systemrules)
46+
api(libs.jimfs)
47+
}
48+
}
49+
}
50+
}
+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
POM_ARTIFACT_ID=clikt-markdown
2+
POM_NAME=Clikt Markdown Support
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package com.github.ajalt.clikt.core
2+
3+
import com.github.ajalt.clikt.output.MordantMarkdownHelpFormatter
4+
5+
/**
6+
* Set up this command's context to use Mordant for rendering output as Markdown.
7+
*/
8+
fun BaseCliktCommand<*>.installMordantMarkdown() {
9+
installMordant(force = true)
10+
configureContext {
11+
helpFormatter = { MordantMarkdownHelpFormatter(it) }
12+
}
13+
}
14+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package com.github.ajalt.clikt.output
2+
3+
import com.github.ajalt.clikt.core.Context
4+
import com.github.ajalt.clikt.core.UsageError
5+
import com.github.ajalt.clikt.core.terminal
6+
import com.github.ajalt.clikt.output.HelpFormatter.ParameterHelp
7+
import com.github.ajalt.mordant.markdown.Markdown
8+
import com.github.ajalt.mordant.rendering.Theme
9+
import com.github.ajalt.mordant.rendering.Whitespace
10+
import com.github.ajalt.mordant.rendering.Widget
11+
import com.github.ajalt.mordant.table.verticalLayout
12+
import com.github.ajalt.mordant.widgets.Text
13+
import com.github.ajalt.mordant.widgets.definitionList
14+
import com.github.ajalt.mordant.widgets.withPadding
15+
16+
/**
17+
* A [HelpFormatter] that uses Mordant to render its output as GitHub Flavored Markdown.
18+
*
19+
* To customize help text, you can create a subclass and set it as the `helpFormatter` on your
20+
* command's context.
21+
*/
22+
open class MordantMarkdownHelpFormatter(
23+
/**
24+
* The current command's context.
25+
*/
26+
context: Context,
27+
/**
28+
* The string to show before the names of required options, or null to not show a mark.
29+
*/
30+
requiredOptionMarker: String? = null,
31+
/**
32+
* If true, the default values will be shown in the help text for parameters that have them.
33+
*/
34+
showDefaultValues: Boolean = false,
35+
/**
36+
* If true, a tag indicating the parameter is required will be shown after the description of
37+
* required parameters.
38+
*/
39+
showRequiredTag: Boolean = false,
40+
) : MordantHelpFormatter(
41+
context,
42+
requiredOptionMarker,
43+
showDefaultValues,
44+
showRequiredTag
45+
) {
46+
override fun renderWrappedText(text: String): Widget = Markdown(text, showHtml = true)
47+
}

clikt-mordant/api/clikt-mordant.api

100644100755
+3-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@ public final class com/github/ajalt/clikt/core/MordantContextKt {
3939
public static final fun getTerminal (Lcom/github/ajalt/clikt/core/Context$Builder;)Lcom/github/ajalt/mordant/terminal/Terminal;
4040
public static final fun getTerminal (Lcom/github/ajalt/clikt/core/Context;)Lcom/github/ajalt/mordant/terminal/Terminal;
4141
public static final fun getTheme (Lcom/github/ajalt/clikt/core/Context;)Lcom/github/ajalt/mordant/rendering/Theme;
42-
public static final fun installMordant (Lcom/github/ajalt/clikt/core/BaseCliktCommand;)V
42+
public static final fun installMordant (Lcom/github/ajalt/clikt/core/BaseCliktCommand;Z)V
43+
public static synthetic fun installMordant$default (Lcom/github/ajalt/clikt/core/BaseCliktCommand;ZILjava/lang/Object;)V
4344
public static final fun setTerminal (Lcom/github/ajalt/clikt/core/Context$Builder;Lcom/github/ajalt/mordant/terminal/Terminal;)V
4445
}
4546

@@ -74,6 +75,7 @@ public class com/github/ajalt/clikt/output/MordantHelpFormatter : com/github/aja
7475
public synthetic fun renderProlog (Ljava/lang/String;)Ljava/lang/Object;
7576
protected fun renderUsage (Ljava/util/List;Ljava/lang/String;)Lcom/github/ajalt/mordant/rendering/Widget;
7677
public synthetic fun renderUsage (Ljava/util/List;Ljava/lang/String;)Ljava/lang/Object;
78+
public fun renderWrappedText (Ljava/lang/String;)Lcom/github/ajalt/mordant/rendering/Widget;
7779
protected fun styleArgumentName (Ljava/lang/String;)Ljava/lang/String;
7880
protected fun styleError (Ljava/lang/String;)Ljava/lang/String;
7981
protected fun styleHelpTag (Ljava/lang/String;)Ljava/lang/String;

clikt-mordant/build.gradle.kts

+12-24
Original file line numberDiff line numberDiff line change
@@ -9,45 +9,33 @@ plugins {
99

1010
kotlin {
1111
jvm()
12-
js {
13-
nodejs()
14-
browser()
15-
}
12+
13+
js { nodejs() }
1614
@OptIn(ExperimentalWasmDsl::class)
17-
wasmJs {
18-
nodejs()
19-
}
15+
wasmJs { nodejs() }
2016

2117
linuxX64()
2218
linuxArm64()
2319
mingwX64()
2420
macosX64()
2521
macosArm64()
22+
2623
iosArm64()
2724
iosX64()
25+
iosSimulatorArm64()
26+
watchosX64()
27+
watchosArm32()
28+
watchosArm64()
29+
watchosSimulatorArm64()
30+
tvosX64()
31+
tvosArm64()
32+
tvosSimulatorArm64()
2833

2934
sourceSets {
3035
val commonMain by getting {
3136
dependencies {
3237
api(project(":clikt"))
3338
api(libs.mordant)
34-
api(libs.mordant.markdown)
35-
}
36-
}
37-
38-
val commonTest by getting {
39-
dependencies {
40-
api(kotlin("test"))
41-
api(libs.kotest)
42-
api(libs.coroutines.core)
43-
api(libs.coroutines.test)
44-
}
45-
}
46-
47-
val jvmTest by getting {
48-
dependencies {
49-
api(libs.systemrules)
50-
api(libs.jimfs)
5139
}
5240
}
5341
}

clikt-mordant/src/commonMain/kotlin/com/github/ajalt/clikt/core/MordantContext.kt

+5-2
Original file line numberDiff line numberDiff line change
@@ -44,12 +44,15 @@ val BaseCliktCommand<*>.terminal: Terminal
4444
*
4545
* This is done automatically for [CliktCommand]s, but you can call this if you are making a custom
4646
* command class.
47+
*
48+
* @param force If true, install mordant even if the parent command has already installed a help
49+
* formatter.
4750
*/
48-
fun BaseCliktCommand<*>.installMordant() {
51+
fun BaseCliktCommand<*>.installMordant(force: Boolean = false) {
4952
configureContext {
5053
// Only install mordant if we're the parent command so that we don't override inherited
5154
// settings.
52-
if (parent != null) return@configureContext
55+
if (!force && parent != null) return@configureContext
5356
helpFormatter = { MordantHelpFormatter(it) }
5457
readEnvvar = { MultiplatformSystem.readEnvironmentVariable(it) }
5558
readArgumentFile = { MultiplatformSystem.readFileAsUtf8(it) ?: throw FileNotFound(it) }

clikt-mordant/src/commonMain/kotlin/com/github/ajalt/clikt/output/MordantHelpFormatter.kt

+11-5
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import com.github.ajalt.clikt.core.Context
44
import com.github.ajalt.clikt.core.UsageError
55
import com.github.ajalt.clikt.core.terminal
66
import com.github.ajalt.clikt.output.HelpFormatter.ParameterHelp
7-
import com.github.ajalt.mordant.markdown.Markdown
87
import com.github.ajalt.mordant.rendering.Theme
98
import com.github.ajalt.mordant.rendering.Whitespace
109
import com.github.ajalt.mordant.rendering.Widget
@@ -83,11 +82,11 @@ open class MordantHelpFormatter(
8382
}
8483

8584
override fun renderProlog(prolog: String): Widget {
86-
return Markdown(prolog, showHtml = true).withPadding(padEmptyLines = false) { left = 2 }
85+
return renderWrappedText(prolog).withPadding(padEmptyLines = false) { left = 2 }
8786
}
8887

8988
override fun renderEpilog(epilog: String): Widget {
90-
return Markdown(epilog, showHtml = true)
89+
return renderWrappedText(epilog)
9190
}
9291

9392
override fun renderParameters(
@@ -97,13 +96,14 @@ open class MordantHelpFormatter(
9796
entry(section.title, section.content)
9897
}
9998
}
99+
100100
override fun renderOptionGroup(
101101
help: String?,
102102
parameters: List<ParameterHelp.Option>,
103103
): Widget {
104104
val options = parameters.map(::renderOptionDefinition)
105105
if (help == null) return buildParameterList(options)
106-
val markdown = Markdown(help, showHtml = true).withPadding(padEmptyLines = false) {
106+
val markdown = renderWrappedText(help).withPadding(padEmptyLines = false) {
107107
top = 1
108108
left = 2
109109
bottom = 1
@@ -141,7 +141,7 @@ open class MordantHelpFormatter(
141141

142142
override fun renderDefinitionDescription(row: DefinitionRow): Widget {
143143
return if (row.description.isBlank()) Text("")
144-
else (Markdown(row.description, showHtml = true))
144+
else renderWrappedText(row.description)
145145
}
146146

147147
override fun buildParameterList(rows: List<DefinitionRow>): Widget {
@@ -152,4 +152,10 @@ open class MordantHelpFormatter(
152152
}
153153
}
154154
}
155+
156+
open fun renderWrappedText(text: String): Widget {
157+
// Replace double newlines with a hard line break since there's no Whitespace equivalent for
158+
// markdown's paragraph behavior.
159+
return Text(text.replace("\n\n", "\u0085\u0085"), whitespace = Whitespace.NORMAL)
160+
}
155161
}

clikt/build.gradle.kts

+5-12
Original file line numberDiff line numberDiff line change
@@ -11,22 +11,19 @@ plugins {
1111

1212
kotlin {
1313
jvm()
14-
js {
15-
nodejs()
16-
browser()
17-
}
14+
15+
js { nodejs() }
1816
@OptIn(ExperimentalWasmDsl::class)
19-
wasmJs {
20-
nodejs()
21-
}
17+
wasmJs { nodejs() }
18+
@OptIn(ExperimentalWasmDsl::class)
19+
wasmWasi { nodejs() }
2220

2321
linuxX64()
2422
linuxArm64()
2523
mingwX64()
2624
macosX64()
2725
macosArm64()
2826

29-
// these targets are only supported in the core module
3027
iosArm64()
3128
iosX64()
3229
iosSimulatorArm64()
@@ -37,10 +34,6 @@ kotlin {
3734
tvosX64()
3835
tvosArm64()
3936
tvosSimulatorArm64()
40-
@OptIn(ExperimentalWasmDsl::class)
41-
wasmWasi {
42-
nodejs()
43-
}
4437
}
4538

4639
// https://youtrack.jetbrains.com/issue/KT-63014

0 commit comments

Comments
 (0)