diff --git a/cli/pom.xml b/cli/pom.xml
index 32020dac..105ac15e 100644
--- a/cli/pom.xml
+++ b/cli/pom.xml
@@ -71,7 +71,7 @@
com.github.ajalt.clikt
clikt-jvm
- 3.5.4
+ 4.2.0
diff --git a/cli/src/main/kotlin/com/github/zeldigas/text2confl/cli/CliOptions.kt b/cli/src/main/kotlin/com/github/zeldigas/text2confl/cli/CliOptions.kt
index 4de3fb98..1008770b 100644
--- a/cli/src/main/kotlin/com/github/zeldigas/text2confl/cli/CliOptions.kt
+++ b/cli/src/main/kotlin/com/github/zeldigas/text2confl/cli/CliOptions.kt
@@ -63,7 +63,7 @@ internal interface WithConfluenceServerOptions {
accessToken != null && confluenceUser != null -> throw PrintMessage("Both access token and username/password specified, but only one of them allowed")
accessToken != null -> TokenAuth(accessToken!!)
confluenceUser != null -> passwordAuth(confluenceUser!!, confluencePassword)
- else -> throw PrintMessage("Either access token or username/password should be specified", error = true)
+ else -> throw PrintMessage("Either access token or username/password should be specified", printError = true)
}
private fun passwordAuth(username: String, password: String?): PasswordAuth {
diff --git a/cli/src/main/kotlin/com/github/zeldigas/text2confl/cli/ClicktExt.kt b/cli/src/main/kotlin/com/github/zeldigas/text2confl/cli/ClicktExt.kt
index a1498eeb..b09e8336 100644
--- a/cli/src/main/kotlin/com/github/zeldigas/text2confl/cli/ClicktExt.kt
+++ b/cli/src/main/kotlin/com/github/zeldigas/text2confl/cli/ClicktExt.kt
@@ -1,31 +1,34 @@
package com.github.zeldigas.text2confl.cli
+import com.github.ajalt.clikt.core.CliktCommand
import com.github.ajalt.clikt.core.PrintMessage
-import com.github.ajalt.clikt.parameters.options.FlagOption
+import com.github.ajalt.clikt.core.terminal
+import com.github.ajalt.clikt.parameters.options.NullableOption
import com.github.ajalt.clikt.parameters.options.RawOption
-import com.github.ajalt.clikt.parameters.options.switch
+import com.github.ajalt.clikt.parameters.options.nullableFlag
+import com.github.ajalt.mordant.terminal.ConfirmationPrompt
+import com.github.ajalt.mordant.terminal.StringPrompt
import com.github.zeldigas.text2confl.cli.upload.InvalidTenantException
import com.github.zeldigas.text2confl.convert.ConversionFailedException
import com.github.zeldigas.text2confl.convert.FileDoesNotExistException
fun parameterMissing(what: String, cliOption: String, fileOption: String): Nothing {
- throw PrintMessage("$what is not specified. Use `$cliOption` option or `$fileOption` in config file", error = true)
+ throw PrintMessage("$what is not specified. Use `$cliOption` option or `$fileOption` in config file", printError = true)
}
fun parameterMissing(what: String, cliOption: String): Nothing {
- throw PrintMessage("$what is not specified. Use `$cliOption` option", error = true)
+ throw PrintMessage("$what is not specified. Use `$cliOption` option", printError = true)
}
-fun RawOption.optionalFlag(vararg secondaryNames: String): FlagOption {
- val allOptions = names.map { it to true } + secondaryNames.map { it to false }
- return switch(allOptions.toMap())
+fun RawOption.optionalFlag(vararg secondaryNames: String): NullableOption {
+ return nullableFlag(*secondaryNames)
}
fun tryHandleException(ex: Exception) : Nothing {
when (ex) {
- is InvalidTenantException -> throw PrintMessage(ex.message!!, error = true)
- is FileDoesNotExistException -> throw PrintMessage(ex.message!!, error = true)
+ is InvalidTenantException -> throw PrintMessage(ex.message!!, printError = true)
+ is FileDoesNotExistException -> throw PrintMessage(ex.message!!, printError = true)
is ConversionFailedException -> {
val reason = buildString {
append(ex.message)
@@ -33,12 +36,22 @@ fun tryHandleException(ex: Exception) : Nothing {
append(" (cause: ${ex.cause})")
}
}
- throw PrintMessage("Failed to convert ${ex.file}: $reason", error = true)
+ throw PrintMessage("Failed to convert ${ex.file}: $reason", printError = true)
}
is ContentValidationFailedException -> {
val issues = ex.errors.mapIndexed { index, error -> "${index + 1}. $error"}.joinToString(separator = "\n")
- throw PrintMessage("Some pages content is invalid:\n${issues}", error = true)
+ throw PrintMessage("Some pages content is invalid:\n${issues}", printError = true)
}
else -> throw ex
}
}
+
+fun CliktCommand.promptForSecret(prompt:String, requireConfirmation: Boolean): String? {
+ return if(requireConfirmation) {
+ ConfirmationPrompt.create(prompt, "Repeat for confirmation: ") {
+ StringPrompt(it, terminal, hideInput = true)
+ }.ask()
+ }else{
+ return terminal.prompt(prompt, hideInput = true)
+ }
+}
diff --git a/cli/src/main/kotlin/com/github/zeldigas/text2confl/cli/DumpToMarkdown.kt b/cli/src/main/kotlin/com/github/zeldigas/text2confl/cli/DumpToMarkdown.kt
index 6858ac2e..5d525608 100644
--- a/cli/src/main/kotlin/com/github/zeldigas/text2confl/cli/DumpToMarkdown.kt
+++ b/cli/src/main/kotlin/com/github/zeldigas/text2confl/cli/DumpToMarkdown.kt
@@ -63,5 +63,5 @@ class DumpToMarkdown : CliktCommand(name = "export-to-md", help = "Exports confl
}
override fun askForSecret(prompt: String, requireConfirmation: Boolean): String? =
- prompt(prompt, hideInput = true, requireConfirmation = true)
+ promptForSecret(prompt, requireConfirmation)
}
diff --git a/cli/src/main/kotlin/com/github/zeldigas/text2confl/cli/Upload.kt b/cli/src/main/kotlin/com/github/zeldigas/text2confl/cli/Upload.kt
index cc4c0086..cb0a54b9 100644
--- a/cli/src/main/kotlin/com/github/zeldigas/text2confl/cli/Upload.kt
+++ b/cli/src/main/kotlin/com/github/zeldigas/text2confl/cli/Upload.kt
@@ -117,13 +117,13 @@ class Upload : CliktCommand(name = "upload", help = "Converts source files and u
private fun passwordAuth(username: String, password: String?): PasswordAuth {
val effectivePassword = password
- ?: prompt("Enter password: ", hideInput = true, requireConfirmation = true)
+ ?: promptForSecret("Enter password: ", requireConfirmation = true)
?: throw PrintMessage("Password can't be null")
return PasswordAuth(username, effectivePassword)
}
override fun askForSecret(prompt: String, requireConfirmation: Boolean): String? =
- prompt(prompt, hideInput = true, requireConfirmation = requireConfirmation)
+ promptForSecret(prompt, requireConfirmation = requireConfirmation)
private suspend fun resolveParent(
confluenceClient: ConfluenceClient,
diff --git a/cli/src/test/kotlin/com/github/zeldigas/text2confl/cli/ConvertTest.kt b/cli/src/test/kotlin/com/github/zeldigas/text2confl/cli/ConvertTest.kt
index f8d6eac8..f61b3930 100644
--- a/cli/src/test/kotlin/com/github/zeldigas/text2confl/cli/ConvertTest.kt
+++ b/cli/src/test/kotlin/com/github/zeldigas/text2confl/cli/ConvertTest.kt
@@ -3,7 +3,7 @@ package com.github.zeldigas.text2confl.cli
import assertk.assertThat
import assertk.assertions.exists
import assertk.assertions.isFalse
-import com.github.ajalt.clikt.core.Context
+import com.github.ajalt.clikt.core.context
import com.github.zeldigas.text2confl.convert.Attachment
import com.github.zeldigas.text2confl.convert.Converter
import com.github.zeldigas.text2confl.convert.Page
@@ -23,14 +23,13 @@ import kotlin.io.path.div
import kotlin.io.path.exists
@ExtendWith(MockKExtension::class)
-class ConvertTest (
+class ConvertTest(
@MockK private val serviceProvider: ServiceProvider,
@MockK private val converter: Converter,
@MockK private val contentValidator: ContentValidator
) {
private val command = Convert()
- private val parentContext = Context.build(command) {}
@BeforeEach
internal fun setUp() {
@@ -38,7 +37,9 @@ class ConvertTest (
every { serviceProvider.createContentValidator() } returns contentValidator
every { contentValidator.validate(any()) } just Runs
- parentContext.obj = serviceProvider
+ command.context {
+ obj = serviceProvider
+ }
}
@Test
@@ -51,8 +52,7 @@ class ConvertTest (
listOf(
"--docs", tempDir.toString(),
"--out", outDir.toString()
- ),
- parentContext
+ )
)
assertThat(outDir / "a.html").exists()
@@ -71,8 +71,7 @@ class ConvertTest (
"--copy-attachments",
"--docs", tempDir.toString(),
"--out", outDir.toString()
- ),
- parentContext
+ )
)
assertThat(outDir / "a.html").exists()
@@ -92,8 +91,7 @@ class ConvertTest (
"--use-title",
"--docs", tempDir.toString(),
"--out", outDir.toString()
- ),
- parentContext
+ )
)
assertThat(outDir / "Special_name_ with _.html").exists()
diff --git a/cli/src/test/kotlin/com/github/zeldigas/text2confl/cli/UploadTest.kt b/cli/src/test/kotlin/com/github/zeldigas/text2confl/cli/UploadTest.kt
index 7f28bec3..c94a58ef 100644
--- a/cli/src/test/kotlin/com/github/zeldigas/text2confl/cli/UploadTest.kt
+++ b/cli/src/test/kotlin/com/github/zeldigas/text2confl/cli/UploadTest.kt
@@ -8,8 +8,8 @@ import assertk.assertions.isTrue
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory
import com.fasterxml.jackson.module.kotlin.registerKotlinModule
-import com.github.ajalt.clikt.core.Context
import com.github.ajalt.clikt.core.PrintMessage
+import com.github.ajalt.clikt.core.context
import com.github.zeldigas.confclient.ConfluenceClient
import com.github.zeldigas.confclient.ConfluenceClientConfig
import com.github.zeldigas.confclient.PasswordAuth
@@ -44,7 +44,6 @@ internal class UploadTest(
@MockK private val converter: Converter
) {
private val command = Upload()
- private val parentContext = Context.build(command) {}
@BeforeEach
internal fun setUp() {
@@ -52,7 +51,10 @@ internal class UploadTest(
every { serviceProvider.createConfluenceClient(any(), any()) } returns confluenceClient
every { serviceProvider.createUploader(confluenceClient, any(), any()) } returns contentUploader
every { serviceProvider.createContentValidator() } returns contentValidator
- parentContext.obj = serviceProvider
+
+ command.context {
+ obj = serviceProvider
+ }
}
@Test
@@ -72,8 +74,7 @@ internal class UploadTest(
"--remove-orphans", "all",
"--tenant", "test",
"--docs", tempDir.toString()
- ),
- parentContext
+ )
)
verify {
@@ -118,8 +119,7 @@ internal class UploadTest(
"--message", "custom upload message",
"--docs", tempDir.toString(),
"--dry"
- ),
- parentContext
+ )
)
verify {
@@ -163,11 +163,10 @@ internal class UploadTest(
"--space", "TR",
"--confluence-url", "https://wiki.example.org",
"--docs", tempDir.toString()
- ),
- parentContext
+ )
)
}.isInstanceOf(PrintMessage::class).all {
- transform { it.error }.isTrue()
+ transform { it.printError }.isTrue()
hasMessage("Either access token or username/password should be specified")
}
}
@@ -178,11 +177,10 @@ internal class UploadTest(
command.parse(
listOf(
"--docs", tempDir.toString()
- ),
- parentContext
+ )
)
}.isInstanceOf(PrintMessage::class).all {
- transform { it.error }.isTrue()
+ transform { it.printError }.isTrue()
hasMessage("Space is not specified. Use `--space` option or `space` in config file")
}
}
@@ -194,11 +192,10 @@ internal class UploadTest(
listOf(
"--space", "TR",
"--docs", tempDir.toString()
- ),
- parentContext
+ )
)
}.isInstanceOf(PrintMessage::class).all {
- transform { it.error }.isTrue()
+ transform { it.printError }.isTrue()
hasMessage("Confluence url is not specified. Use `--confluence-url` option or `server` in config file")
}
}
@@ -217,8 +214,7 @@ internal class UploadTest(
"--access-token", "test",
"--parent", "Test page",
"--docs", tempDir.toString()
- ),
- parentContext
+ )
)
coVerify {
@@ -239,8 +235,7 @@ internal class UploadTest(
"--space", "TR",
"--access-token", "test",
"--docs", tempDir.toString()
- ),
- parentContext
+ )
)
coVerify {
@@ -260,8 +255,7 @@ internal class UploadTest(
"--space", "TR",
"--access-token", "test",
"--docs", tempDir.toString()
- ),
- parentContext
+ )
)
}.isInstanceOf(PrintMessage::class).hasMessage("File does not exist: $tempDir")
}
@@ -281,8 +275,7 @@ internal class UploadTest(
"--space", "TR",
"--access-token", "test",
"--docs", tempDir.toString()
- ),
- parentContext
+ )
)
}.isInstanceOf(PrintMessage::class)
.hasMessage("Failed to convert $tempDir: Conversion error message (cause: java.lang.RuntimeException: cause)")
@@ -306,8 +299,7 @@ internal class UploadTest(
"--space", "TR",
"--access-token", "test",
"--docs", tempDir.toString()
- ),
- parentContext
+ )
)
}.isInstanceOf(PrintMessage::class)
.hasMessage("Some pages content is invalid:\n1. error message1\n2. error message2")
diff --git a/confluence-client/src/main/kotlin/com/github/zeldigas/confclient/ConfluenceClientImpl.kt b/confluence-client/src/main/kotlin/com/github/zeldigas/confclient/ConfluenceClientImpl.kt
index 4c55463e..26f23afd 100644
--- a/confluence-client/src/main/kotlin/com/github/zeldigas/confclient/ConfluenceClientImpl.kt
+++ b/confluence-client/src/main/kotlin/com/github/zeldigas/confclient/ConfluenceClientImpl.kt
@@ -209,7 +209,7 @@ class ConfluenceClientImpl(
val result = mutableListOf()
var start = 0
var limit = PAGE_SIZE
- var completed = false
+ var completed: Boolean
do {
val page = httpClient.get("$apiBase/content/$pageId/child/page") {
addExpansions(expansions ?: emptyList())
diff --git a/convert/src/main/kotlin/com/github/zeldigas/text2confl/convert/markdown/AttachmentCollector.kt b/convert/src/main/kotlin/com/github/zeldigas/text2confl/convert/markdown/AttachmentCollector.kt
index c9801cf1..a88681b9 100644
--- a/convert/src/main/kotlin/com/github/zeldigas/text2confl/convert/markdown/AttachmentCollector.kt
+++ b/convert/src/main/kotlin/com/github/zeldigas/text2confl/convert/markdown/AttachmentCollector.kt
@@ -33,7 +33,7 @@ class AttachmentCollector(
VisitHandler(LinkRef::class.java) { tryCollect(it, ast as Document) },
VisitHandler(Image::class.java) { tryCollect(it) },
VisitHandler(ImageRef::class.java) { tryCollect(it, ast as Document) },
- VisitHandler(Reference::class.java) { tryCollect(it, ast as Document) }
+ VisitHandler(Reference::class.java) { tryCollect(it) }
)).visit(ast)
}
@@ -63,7 +63,7 @@ class AttachmentCollector(
addFileIfExists(referenceNode.url.unescape(), referenceNode.reference.toString())
}
- private fun tryCollect(reference: Reference, ast: Document) {
+ private fun tryCollect(reference: Reference) {
addFileIfExists(reference.url.unescape(), reference.reference.toString())
}