Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Split markdown into separate module #549

Merged
merged 5 commits into from
Sep 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 5 additions & 7 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,8 @@ jobs:
with:
distribution: 'zulu'
java-version: 17
- uses: gradle/actions/setup-gradle@v3
with:
arguments: ${{matrix.TEST_TASK}} --stacktrace
- uses: gradle/actions/setup-gradle@v4
- run: ./gradlew ${{matrix.TEST_TASK}} --stacktrace
- name: Upload the build report
if: failure()
uses: actions/upload-artifact@master
Expand All @@ -53,10 +52,9 @@ jobs:
distribution: 'zulu'
java-version: 17
- name: Deploy to sonatype
uses: gradle/actions/setup-gradle@v3
with:
# disable configuration cache due to https://github.com/gradle/gradle/issues/22779
arguments: publishToMavenCentral -PsnapshotVersion=true --no-configuration-cache
uses: gradle/actions/setup-gradle@v4
# disable configuration cache due to https://github.com/gradle/gradle/issues/22779
- run: ./gradlew publishToMavenCentral -PsnapshotVersion=true --no-configuration-cache
env:
ORG_GRADLE_PROJECT_mavenCentralPassword: ${{ secrets.ORG_GRADLE_PROJECT_mavenCentralPassword }}
ORG_GRADLE_PROJECT_signingInMemoryKey: ${{ secrets.ORG_GRADLE_PROJECT_signingInMemoryKey }}
Expand Down
14 changes: 0 additions & 14 deletions .github/workflows/gradle-wrapper-validation.yml

This file was deleted.

2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
with:
distribution: 'zulu'
java-version: 17
- uses: gradle/actions/setup-gradle@v3
- uses: gradle/actions/setup-gradle@v4
with:
# disable configuration cache due to https://github.com/gradle/gradle/issues/22779
arguments: publishToMavenCentral --no-configuration-cache
Expand Down
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
- 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))
- Added support for aliasing options to other options. ([#535](https://github.com/ajalt/clikt/pull/535))
- Added `limit` and `ignoreCase` parameters to `option().split()`. ([#541](https://github.com/ajalt/clikt/pull/541))
- Support calling `--help` on subcommands when parents have required parameters.

### Changed
- 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.
Expand All @@ -39,8 +40,8 @@
- **Breaking Change:** `CliktCommand.main` and `CliktCommand.parse` are now extension functions rather than methods.
- **Breaking Change:** `Context.obj` and `Context.terminal`, and `OptionTransformContext.terminal` are now extension functions rather than properties.
- **Breaking Change:** The `RenderedSection` and `DefinitionRow` classes have moved to `AbstractHelpFormatter`.
- 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.
- Updated Kotlin to 2.0.0
- Support calling `--help` on subcommands when parents have required parameters.

### Fixed
- Fixed excess arguments not being reported when `allowMultipleSubcommands=true` and a subcommand has excess arguments followed by another subcommand.
Expand Down
11 changes: 11 additions & 0 deletions clikt-mordant-markdown/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Module clikt-mordant-markdown

This module provides the `MordantMarkdownHelpFormatter` that renders text as markdown.

## Installation

```kotlin
dependencies {
implementation("com.github.ajalt.clikt:clikt-markdown:$cliktVersion")
}
```
10 changes: 10 additions & 0 deletions clikt-mordant-markdown/api/clikt-mordant-markdown.api
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
public final class com/github/ajalt/clikt/core/MordantMarkdownContextKt {
public static final fun installMordantMarkdown (Lcom/github/ajalt/clikt/core/BaseCliktCommand;)V
}

public class com/github/ajalt/clikt/output/MordantMarkdownHelpFormatter : com/github/ajalt/clikt/output/MordantHelpFormatter {
public fun <init> (Lcom/github/ajalt/clikt/core/Context;Ljava/lang/String;ZZ)V
public synthetic fun <init> (Lcom/github/ajalt/clikt/core/Context;Ljava/lang/String;ZZILkotlin/jvm/internal/DefaultConstructorMarker;)V
public fun renderWrappedText (Ljava/lang/String;)Lcom/github/ajalt/mordant/rendering/Widget;
}

50 changes: 50 additions & 0 deletions clikt-mordant-markdown/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import org.jetbrains.kotlin.gradle.targets.js.dsl.ExperimentalWasmDsl


plugins {
kotlin("multiplatform")
}

kotlin {
jvm()

js { nodejs() }
@OptIn(ExperimentalWasmDsl::class)
wasmJs { nodejs() }

linuxX64()
linuxArm64()
mingwX64()
macosX64()
macosArm64()

iosArm64()
iosX64()

sourceSets {
val commonMain by getting {
dependencies {
api(project(":clikt"))
api(project(":clikt-mordant"))
api(libs.mordant)
api(libs.mordant.markdown)
}
}

val commonTest by getting {
dependencies {
api(kotlin("test"))
api(libs.kotest)
api(libs.coroutines.core)
api(libs.coroutines.test)
}
}

val jvmTest by getting {
dependencies {
api(libs.systemrules)
api(libs.jimfs)
}
}
}
}
2 changes: 2 additions & 0 deletions clikt-mordant-markdown/gradle.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
POM_ARTIFACT_ID=clikt-markdown
POM_NAME=Clikt Markdown Support
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.github.ajalt.clikt.core

import com.github.ajalt.clikt.output.MordantMarkdownHelpFormatter

/**
* Set up this command's context to use Mordant for rendering output as Markdown.
*/
fun BaseCliktCommand<*>.installMordantMarkdown() {
installMordant(force = true)
configureContext {
helpFormatter = { MordantMarkdownHelpFormatter(it) }
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package com.github.ajalt.clikt.output

import com.github.ajalt.clikt.core.Context
import com.github.ajalt.clikt.core.UsageError
import com.github.ajalt.clikt.core.terminal
import com.github.ajalt.clikt.output.HelpFormatter.ParameterHelp
import com.github.ajalt.mordant.markdown.Markdown
import com.github.ajalt.mordant.rendering.Theme
import com.github.ajalt.mordant.rendering.Whitespace
import com.github.ajalt.mordant.rendering.Widget
import com.github.ajalt.mordant.table.verticalLayout
import com.github.ajalt.mordant.widgets.Text
import com.github.ajalt.mordant.widgets.definitionList
import com.github.ajalt.mordant.widgets.withPadding

/**
* A [HelpFormatter] that uses Mordant to render its output as GitHub Flavored Markdown.
*
* To customize help text, you can create a subclass and set it as the `helpFormatter` on your
* command's context.
*/
open class MordantMarkdownHelpFormatter(
/**
* The current command's context.
*/
context: Context,
/**
* The string to show before the names of required options, or null to not show a mark.
*/
requiredOptionMarker: String? = null,
/**
* If true, the default values will be shown in the help text for parameters that have them.
*/
showDefaultValues: Boolean = false,
/**
* If true, a tag indicating the parameter is required will be shown after the description of
* required parameters.
*/
showRequiredTag: Boolean = false,
) : MordantHelpFormatter(
context,
requiredOptionMarker,
showDefaultValues,
showRequiredTag
) {
override fun renderWrappedText(text: String): Widget = Markdown(text, showHtml = true)
}
4 changes: 3 additions & 1 deletion clikt-mordant/api/clikt-mordant.api
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ public final class com/github/ajalt/clikt/core/MordantContextKt {
public static final fun getTerminal (Lcom/github/ajalt/clikt/core/Context$Builder;)Lcom/github/ajalt/mordant/terminal/Terminal;
public static final fun getTerminal (Lcom/github/ajalt/clikt/core/Context;)Lcom/github/ajalt/mordant/terminal/Terminal;
public static final fun getTheme (Lcom/github/ajalt/clikt/core/Context;)Lcom/github/ajalt/mordant/rendering/Theme;
public static final fun installMordant (Lcom/github/ajalt/clikt/core/BaseCliktCommand;)V
public static final fun installMordant (Lcom/github/ajalt/clikt/core/BaseCliktCommand;Z)V
public static synthetic fun installMordant$default (Lcom/github/ajalt/clikt/core/BaseCliktCommand;ZILjava/lang/Object;)V
public static final fun setTerminal (Lcom/github/ajalt/clikt/core/Context$Builder;Lcom/github/ajalt/mordant/terminal/Terminal;)V
}

Expand Down Expand Up @@ -74,6 +75,7 @@ public class com/github/ajalt/clikt/output/MordantHelpFormatter : com/github/aja
public synthetic fun renderProlog (Ljava/lang/String;)Ljava/lang/Object;
protected fun renderUsage (Ljava/util/List;Ljava/lang/String;)Lcom/github/ajalt/mordant/rendering/Widget;
public synthetic fun renderUsage (Ljava/util/List;Ljava/lang/String;)Ljava/lang/Object;
public fun renderWrappedText (Ljava/lang/String;)Lcom/github/ajalt/mordant/rendering/Widget;
protected fun styleArgumentName (Ljava/lang/String;)Ljava/lang/String;
protected fun styleError (Ljava/lang/String;)Ljava/lang/String;
protected fun styleHelpTag (Ljava/lang/String;)Ljava/lang/String;
Expand Down
36 changes: 12 additions & 24 deletions clikt-mordant/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -9,45 +9,33 @@ plugins {

kotlin {
jvm()
js {
nodejs()
browser()
}

js { nodejs() }
@OptIn(ExperimentalWasmDsl::class)
wasmJs {
nodejs()
}
wasmJs { nodejs() }

linuxX64()
linuxArm64()
mingwX64()
macosX64()
macosArm64()

iosArm64()
iosX64()
iosSimulatorArm64()
watchosX64()
watchosArm32()
watchosArm64()
watchosSimulatorArm64()
tvosX64()
tvosArm64()
tvosSimulatorArm64()

sourceSets {
val commonMain by getting {
dependencies {
api(project(":clikt"))
api(libs.mordant)
api(libs.mordant.markdown)
}
}

val commonTest by getting {
dependencies {
api(kotlin("test"))
api(libs.kotest)
api(libs.coroutines.core)
api(libs.coroutines.test)
}
}

val jvmTest by getting {
dependencies {
api(libs.systemrules)
api(libs.jimfs)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,15 @@ val BaseCliktCommand<*>.terminal: Terminal
*
* This is done automatically for [CliktCommand]s, but you can call this if you are making a custom
* command class.
*
* @param force If true, install mordant even if the parent command has already installed a help
* formatter.
*/
fun BaseCliktCommand<*>.installMordant() {
fun BaseCliktCommand<*>.installMordant(force: Boolean = false) {
configureContext {
// Only install mordant if we're the parent command so that we don't override inherited
// settings.
if (parent != null) return@configureContext
if (!force && parent != null) return@configureContext
helpFormatter = { MordantHelpFormatter(it) }
readEnvvar = { MultiplatformSystem.readEnvironmentVariable(it) }
readArgumentFile = { MultiplatformSystem.readFileAsUtf8(it) ?: throw FileNotFound(it) }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import com.github.ajalt.clikt.core.Context
import com.github.ajalt.clikt.core.UsageError
import com.github.ajalt.clikt.core.terminal
import com.github.ajalt.clikt.output.HelpFormatter.ParameterHelp
import com.github.ajalt.mordant.markdown.Markdown
import com.github.ajalt.mordant.rendering.Theme
import com.github.ajalt.mordant.rendering.Whitespace
import com.github.ajalt.mordant.rendering.Widget
Expand Down Expand Up @@ -83,11 +82,11 @@ open class MordantHelpFormatter(
}

override fun renderProlog(prolog: String): Widget {
return Markdown(prolog, showHtml = true).withPadding(padEmptyLines = false) { left = 2 }
return renderWrappedText(prolog).withPadding(padEmptyLines = false) { left = 2 }
}

override fun renderEpilog(epilog: String): Widget {
return Markdown(epilog, showHtml = true)
return renderWrappedText(epilog)
}

override fun renderParameters(
Expand All @@ -97,13 +96,14 @@ open class MordantHelpFormatter(
entry(section.title, section.content)
}
}

override fun renderOptionGroup(
help: String?,
parameters: List<ParameterHelp.Option>,
): Widget {
val options = parameters.map(::renderOptionDefinition)
if (help == null) return buildParameterList(options)
val markdown = Markdown(help, showHtml = true).withPadding(padEmptyLines = false) {
val markdown = renderWrappedText(help).withPadding(padEmptyLines = false) {
top = 1
left = 2
bottom = 1
Expand Down Expand Up @@ -141,7 +141,7 @@ open class MordantHelpFormatter(

override fun renderDefinitionDescription(row: DefinitionRow): Widget {
return if (row.description.isBlank()) Text("")
else (Markdown(row.description, showHtml = true))
else renderWrappedText(row.description)
}

override fun buildParameterList(rows: List<DefinitionRow>): Widget {
Expand All @@ -152,4 +152,10 @@ open class MordantHelpFormatter(
}
}
}

open fun renderWrappedText(text: String): Widget {
// Replace double newlines with a hard line break since there's no Whitespace equivalent for
// markdown's paragraph behavior.
return Text(text.replace("\n\n", "\u0085\u0085"), whitespace = Whitespace.NORMAL)
}
}
17 changes: 5 additions & 12 deletions clikt/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,19 @@ plugins {

kotlin {
jvm()
js {
nodejs()
browser()
}

js { nodejs() }
@OptIn(ExperimentalWasmDsl::class)
wasmJs {
nodejs()
}
wasmJs { nodejs() }
@OptIn(ExperimentalWasmDsl::class)
wasmWasi { nodejs() }

linuxX64()
linuxArm64()
mingwX64()
macosX64()
macosArm64()

// these targets are only supported in the core module
iosArm64()
iosX64()
iosSimulatorArm64()
Expand All @@ -37,10 +34,6 @@ kotlin {
tvosX64()
tvosArm64()
tvosSimulatorArm64()
@OptIn(ExperimentalWasmDsl::class)
wasmWasi {
nodejs()
}
}

// https://youtrack.jetbrains.com/issue/KT-63014
Expand Down
Loading