add task without requiring an explicit return value (ProvResult)
This commit is contained in:
parent
7eb7494fad
commit
efe158275b
15 changed files with 52 additions and 44 deletions
|
@ -12,13 +12,13 @@ fun Prov.installGopass(
|
||||||
version: String = "1.12.7",
|
version: String = "1.12.7",
|
||||||
enforceVersion: Boolean = false,
|
enforceVersion: Boolean = false,
|
||||||
sha256sum: String = "0824d5110ff1e68bff1ba10c1be63acb67cb1ad8e3bccddd6b6fc989608beca8" // checksum for sha256sum version 8.30 (e.g. ubuntu 20.04)
|
sha256sum: String = "0824d5110ff1e68bff1ba10c1be63acb67cb1ad8e3bccddd6b6fc989608beca8" // checksum for sha256sum version 8.30 (e.g. ubuntu 20.04)
|
||||||
) = task {
|
) = taskWithResult {
|
||||||
|
|
||||||
if (isPackageInstalled("gopass") && !enforceVersion) {
|
if (isPackageInstalled("gopass") && !enforceVersion) {
|
||||||
return@task ProvResult(true)
|
return@taskWithResult ProvResult(true)
|
||||||
}
|
}
|
||||||
if (checkGopassVersion(version)) {
|
if (checkGopassVersion(version)) {
|
||||||
return@task ProvResult(true, out = "Version $version of gopass is already installed.")
|
return@taskWithResult ProvResult(true, out = "Version $version of gopass is already installed.")
|
||||||
}
|
}
|
||||||
|
|
||||||
val path = "tmp"
|
val path = "tmp"
|
||||||
|
@ -41,17 +41,17 @@ fun Prov.installGopass(
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fun Prov.configureGopass(gopassRootFolder: String? = null) = task {
|
fun Prov.configureGopass(gopassRootFolder: String? = null) = taskWithResult() {
|
||||||
val configFile = ".config/gopass/config.yml"
|
val configFile = ".config/gopass/config.yml"
|
||||||
val defaultRootFolder = userHome() + ".password-store"
|
val defaultRootFolder = userHome() + ".password-store"
|
||||||
val rootFolder = gopassRootFolder ?: defaultRootFolder
|
val rootFolder = gopassRootFolder ?: defaultRootFolder
|
||||||
|
|
||||||
if (checkFile(configFile)) {
|
if (checkFile(configFile)) {
|
||||||
return@task ProvResult(true, out = "Gopass already configured in file $configFile")
|
return@taskWithResult ProvResult(true, out = "Gopass already configured in file $configFile")
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((gopassRootFolder != null) && (!gopassRootFolder.startsWith("/"))) {
|
if ((gopassRootFolder != null) && (!gopassRootFolder.startsWith("/"))) {
|
||||||
return@task ProvResult(false, err = "Gopass cannot be initialized with a relative path or path starting with ~")
|
return@taskWithResult ProvResult(false, err = "Gopass cannot be initialized with a relative path or path starting with ~")
|
||||||
}
|
}
|
||||||
// use default
|
// use default
|
||||||
createDir(rootFolder)
|
createDir(rootFolder)
|
||||||
|
|
|
@ -5,14 +5,14 @@ import org.domaindrivenarchitecture.provs.framework.core.ProvResult
|
||||||
import org.domaindrivenarchitecture.provs.framework.ubuntu.install.base.aptInstall
|
import org.domaindrivenarchitecture.provs.framework.ubuntu.install.base.aptInstall
|
||||||
import org.domaindrivenarchitecture.provs.framework.ubuntu.user.base.whoami
|
import org.domaindrivenarchitecture.provs.framework.ubuntu.user.base.whoami
|
||||||
|
|
||||||
fun Prov.installVirtualBoxGuestAdditions() = task {
|
fun Prov.installVirtualBoxGuestAdditions() = taskWithResult {
|
||||||
// if running in a VirtualBox vm
|
// if running in a VirtualBox vm
|
||||||
if (!chk("lspci | grep VirtualBox")) {
|
if (!chk("lspci | grep VirtualBox")) {
|
||||||
return@task ProvResult(true, "Not running in a VirtualBox")
|
return@taskWithResult ProvResult(true, "Not running in a VirtualBox")
|
||||||
}
|
}
|
||||||
|
|
||||||
if (chk("VBoxService --version")) {
|
if (chk("VBoxService --version")) {
|
||||||
return@task ProvResult(true, "VBoxService already installed")
|
return@taskWithResult ProvResult(true, "VBoxService already installed")
|
||||||
}
|
}
|
||||||
|
|
||||||
// install guest additions
|
// install guest additions
|
||||||
|
|
|
@ -67,11 +67,19 @@ open class Prov protected constructor(
|
||||||
private var runInContainerWithName: String? = null
|
private var runInContainerWithName: String? = null
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines a task with a custom name instead of the name of the calling function.
|
* A task is the base execution unit in provs. In the results overview it is represented by one line resp. result (of either success or failure).
|
||||||
* Returns success if all subtasks finished with success (same as requireAll).
|
* Returns success if no sub-tasks are called or if all subtasks finish with success.
|
||||||
*/
|
*/
|
||||||
fun task(name: String? = null, a: Prov.() -> ProvResult): ProvResult {
|
fun task(name: String? = null, taskLambda: Prov.() -> Unit): ProvResult {
|
||||||
return handle(ResultMode.ALL, name) { a() }
|
return handle(ResultMode.ALL, name) { taskLambda(); ProvResult(true) }
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Same as task but the provided lambda is explicitly required to provide a ProvResult to be returned.
|
||||||
|
* The returned result is included in the evaluation.
|
||||||
|
*/
|
||||||
|
fun taskWithResult(name: String? = null, taskLambda: Prov.() -> ProvResult): ProvResult {
|
||||||
|
return handle(ResultMode.ALL, name) { taskLambda() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -84,7 +92,7 @@ open class Prov protected constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* defines a task, which returns success if the the last subtasks or last value returns success
|
* defines a task, which returns the returned result, the results of sub-tasks are not considered
|
||||||
*/
|
*/
|
||||||
fun requireLast(a: Prov.() -> ProvResult): ProvResult {
|
fun requireLast(a: Prov.() -> ProvResult): ProvResult {
|
||||||
return handle(ResultMode.LAST) { a() }
|
return handle(ResultMode.LAST) { a() }
|
||||||
|
@ -100,7 +108,7 @@ open class Prov protected constructor(
|
||||||
/**
|
/**
|
||||||
* defines a task, which returns success if all subtasks finished with success
|
* defines a task, which returns success if all subtasks finished with success
|
||||||
*/
|
*/
|
||||||
@Suppress("unused")
|
@Deprecated("Use function task instead", replaceWith = ReplaceWith("task()"))
|
||||||
fun requireAll(a: Prov.() -> ProvResult): ProvResult {
|
fun requireAll(a: Prov.() -> ProvResult): ProvResult {
|
||||||
return handle(ResultMode.ALL) { a() }
|
return handle(ResultMode.ALL) { a() }
|
||||||
}
|
}
|
||||||
|
@ -218,7 +226,7 @@ open class Prov protected constructor(
|
||||||
* Adds a ProvResult to the overall success evaluation.
|
* Adds a ProvResult to the overall success evaluation.
|
||||||
* Intended for use in methods which do not automatically add results.
|
* Intended for use in methods which do not automatically add results.
|
||||||
*/
|
*/
|
||||||
fun addResultToEval(result: ProvResult) = task {
|
fun addResultToEval(result: ProvResult) = taskWithResult {
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -227,7 +235,7 @@ open class Prov protected constructor(
|
||||||
* Multi-line commands within the script are not supported.
|
* Multi-line commands within the script are not supported.
|
||||||
* Empty lines and comments (all text behind # in a line) are supported, i.e. they are ignored.
|
* Empty lines and comments (all text behind # in a line) are supported, i.e. they are ignored.
|
||||||
*/
|
*/
|
||||||
fun sh(script: String, dir: String? = null, sudo: Boolean = false) = task {
|
fun sh(script: String, dir: String? = null, sudo: Boolean = false) = taskWithResult {
|
||||||
val lines = script.trimIndent().replace("\\\n", "").replace("\r\n", "\n").split("\n")
|
val lines = script.trimIndent().replace("\\\n", "").replace("\r\n", "\n").split("\n")
|
||||||
val linesWithoutComments = lines.stream().map { it.split("#")[0] }
|
val linesWithoutComments = lines.stream().map { it.split("#")[0] }
|
||||||
val linesNonEmpty = linesWithoutComments.filter { it.trim().isNotEmpty() }
|
val linesNonEmpty = linesWithoutComments.filter { it.trim().isNotEmpty() }
|
||||||
|
|
|
@ -18,7 +18,7 @@ import java.net.InetAddress
|
||||||
*/
|
*/
|
||||||
internal fun getCallingMethodName(): String? {
|
internal fun getCallingMethodName(): String? {
|
||||||
val offsetVal = 1
|
val offsetVal = 1
|
||||||
val exclude = arrayOf("task", "def", "record", "invoke", "invoke0", "handle", "task\$default", "def\$default", "addResultToEval", "handle\$default")
|
val exclude = arrayOf("task", "task\$default", "taskWithResult\$default", "taskWithResult", "def", "def\$default", "record", "invoke", "invoke0", "handle", "handle\$default", )
|
||||||
// suffixes are also ignored as method names but will be added as suffix in the evaluation results
|
// suffixes are also ignored as method names but will be added as suffix in the evaluation results
|
||||||
val suffixes = arrayOf("optional", "requireAll", "requireLast", "inContainer")
|
val suffixes = arrayOf("optional", "requireAll", "requireLast", "inContainer")
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@ class UbuntuProv internal constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun cmd(cmd: String, dir: String?, sudo: Boolean): ProvResult = task {
|
override fun cmd(cmd: String, dir: String?, sudo: Boolean): ProvResult = taskWithResult {
|
||||||
exec(SHELL, "-c", commandWithDirAndSudo(cmd, dir, sudo))
|
exec(SHELL, "-c", commandWithDirAndSudo(cmd, dir, sudo))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -90,7 +90,7 @@ fun Prov.createFile(
|
||||||
posixFilePermission: String? = null,
|
posixFilePermission: String? = null,
|
||||||
sudo: Boolean = false,
|
sudo: Boolean = false,
|
||||||
overwriteIfExisting: Boolean = true
|
overwriteIfExisting: Boolean = true
|
||||||
): ProvResult = task {
|
): ProvResult = taskWithResult {
|
||||||
val maxBlockSize = 50000
|
val maxBlockSize = 50000
|
||||||
val withSudo = if (sudo) "sudo " else ""
|
val withSudo = if (sudo) "sudo " else ""
|
||||||
|
|
||||||
|
@ -98,7 +98,7 @@ fun Prov.createFile(
|
||||||
ensureValidPosixFilePermission(posixFilePermission)
|
ensureValidPosixFilePermission(posixFilePermission)
|
||||||
}
|
}
|
||||||
if (!overwriteIfExisting && checkFile(fullyQualifiedFilename, sudo)) {
|
if (!overwriteIfExisting && checkFile(fullyQualifiedFilename, sudo)) {
|
||||||
return@task ProvResult(true, "File $fullyQualifiedFilename already existing.")
|
return@taskWithResult ProvResult(true, "File $fullyQualifiedFilename already existing.")
|
||||||
}
|
}
|
||||||
|
|
||||||
val modeOption = posixFilePermission?.let { "-m $it" } ?: ""
|
val modeOption = posixFilePermission?.let { "-m $it" } ?: ""
|
||||||
|
@ -220,10 +220,10 @@ fun Prov.addTextToFile(
|
||||||
doNotAddIfExisting: Boolean = true,
|
doNotAddIfExisting: Boolean = true,
|
||||||
sudo: Boolean = false
|
sudo: Boolean = false
|
||||||
): ProvResult =
|
): ProvResult =
|
||||||
task {
|
taskWithResult {
|
||||||
val fileContainsText = fileContainsText(file.path, text, sudo = sudo)
|
val fileContainsText = fileContainsText(file.path, text, sudo = sudo)
|
||||||
if (fileContainsText && doNotAddIfExisting) {
|
if (fileContainsText && doNotAddIfExisting) {
|
||||||
return@task ProvResult(true, out = "Text already in file")
|
return@taskWithResult ProvResult(true, out = "Text already in file")
|
||||||
}
|
}
|
||||||
cmd(
|
cmd(
|
||||||
"printf '%s' " + text
|
"printf '%s' " + text
|
||||||
|
|
|
@ -17,11 +17,11 @@ fun Prov.gitClone(
|
||||||
targetPath: String = "",
|
targetPath: String = "",
|
||||||
pullIfExisting: Boolean = true,
|
pullIfExisting: Boolean = true,
|
||||||
targetFolderName: String? = null
|
targetFolderName: String? = null
|
||||||
): ProvResult = task {
|
): ProvResult = taskWithResult {
|
||||||
// if specified, use targetFolderName as basename or otherwise retrieve basename from repoSource
|
// if specified, use targetFolderName as basename or otherwise retrieve basename from repoSource
|
||||||
val basename = targetFolderName ?: cmdNoEval("basename $repoSource .git").out?.trim()
|
val basename = targetFolderName ?: cmdNoEval("basename $repoSource .git").out?.trim()
|
||||||
// return err if basename could not be retrieved from repoSource
|
// return err if basename could not be retrieved from repoSource
|
||||||
?: return@task ProvResult(false, err = "$repoSource is not a valid git repository source path.")
|
?: return@taskWithResult ProvResult(false, err = "$repoSource is not a valid git repository source path.")
|
||||||
|
|
||||||
val pathWithBasename = targetPath.normalizePath() + basename
|
val pathWithBasename = targetPath.normalizePath() + basename
|
||||||
if (checkDir(pathWithBasename + "/.git/")) {
|
if (checkDir(pathWithBasename + "/.git/")) {
|
||||||
|
|
|
@ -13,7 +13,7 @@ private var aptInit = false
|
||||||
* @param ignoreAlreadyInstalled if true, then for an already installed package no action will be taken,
|
* @param ignoreAlreadyInstalled if true, then for an already installed package no action will be taken,
|
||||||
* if "ignoreAlreadyInstalled" is false, then installation is always attempted, which normally results in an upgrade if package wa already installed
|
* if "ignoreAlreadyInstalled" is false, then installation is always attempted, which normally results in an upgrade if package wa already installed
|
||||||
*/
|
*/
|
||||||
fun Prov.aptInstall(packages: String, ignoreAlreadyInstalled: Boolean = true): ProvResult = task {
|
fun Prov.aptInstall(packages: String, ignoreAlreadyInstalled: Boolean = true): ProvResult = taskWithResult {
|
||||||
val packageList = packages.split(" ")
|
val packageList = packages.split(" ")
|
||||||
val allInstalled: Boolean = packageList.map { isPackageInstalled(it) }.fold(true, { a, b -> a && b })
|
val allInstalled: Boolean = packageList.map { isPackageInstalled(it) }.fold(true, { a, b -> a && b })
|
||||||
if (!allInstalled) {
|
if (!allInstalled) {
|
||||||
|
|
|
@ -38,9 +38,9 @@ fun Prov.isHostKnown(hostOrIp: String) : Boolean {
|
||||||
* Either add the specified rsaFingerprints or - if null - add automatically retrieved keys.
|
* Either add the specified rsaFingerprints or - if null - add automatically retrieved keys.
|
||||||
* Note: adding keys automatically is vulnerable to a man-in-the-middle attack, thus considered insecure and not recommended.
|
* Note: adding keys automatically is vulnerable to a man-in-the-middle attack, thus considered insecure and not recommended.
|
||||||
*/
|
*/
|
||||||
fun Prov.trustHost(host: String, fingerprintsOfKeysToBeAdded: Set<String>?) = task {
|
fun Prov.trustHost(host: String, fingerprintsOfKeysToBeAdded: Set<String>?) = taskWithResult {
|
||||||
if (isHostKnown(host)) {
|
if (isHostKnown(host)) {
|
||||||
return@task ProvResult(true, out = "Host already known")
|
return@taskWithResult ProvResult(true, out = "Host already known")
|
||||||
}
|
}
|
||||||
if (!checkFile(KNOWN_HOSTS_FILE)) {
|
if (!checkFile(KNOWN_HOSTS_FILE)) {
|
||||||
createDir(".ssh")
|
createDir(".ssh")
|
||||||
|
@ -53,7 +53,7 @@ fun Prov.trustHost(host: String, fingerprintsOfKeysToBeAdded: Set<String>?) = ta
|
||||||
// logic based on https://serverfault.com/questions/447028/non-interactive-git-clone-ssh-fingerprint-prompt
|
// logic based on https://serverfault.com/questions/447028/non-interactive-git-clone-ssh-fingerprint-prompt
|
||||||
val actualKeys = findSshKeys(host)
|
val actualKeys = findSshKeys(host)
|
||||||
if (actualKeys == null || actualKeys.size == 0) {
|
if (actualKeys == null || actualKeys.size == 0) {
|
||||||
return@task ProvResult(false, out = "No valid keys found for host: $host")
|
return@taskWithResult ProvResult(false, out = "No valid keys found for host: $host")
|
||||||
}
|
}
|
||||||
val actualFingerprints = getFingerprintsForKeys(actualKeys)
|
val actualFingerprints = getFingerprintsForKeys(actualKeys)
|
||||||
for (fingerprintToBeAdded in fingerprintsOfKeysToBeAdded) {
|
for (fingerprintToBeAdded in fingerprintsOfKeysToBeAdded) {
|
||||||
|
@ -67,7 +67,7 @@ fun Prov.trustHost(host: String, fingerprintsOfKeysToBeAdded: Set<String>?) = ta
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (indexOfKeyFound == -1) {
|
if (indexOfKeyFound == -1) {
|
||||||
return@task ProvResult(
|
return@taskWithResult ProvResult(
|
||||||
false,
|
false,
|
||||||
err = "Fingerprint ($fingerprintToBeAdded) could not be found in actual fingerprints: $actualFingerprints"
|
err = "Fingerprint ($fingerprintToBeAdded) could not be found in actual fingerprints: $actualFingerprints"
|
||||||
)
|
)
|
||||||
|
|
|
@ -22,13 +22,13 @@ fun Prov.downloadFromURL(
|
||||||
followRedirect: Boolean = true,
|
followRedirect: Boolean = true,
|
||||||
sha256sum: String? = null,
|
sha256sum: String? = null,
|
||||||
overwrite: Boolean = false
|
overwrite: Boolean = false
|
||||||
): ProvResult = task {
|
): ProvResult = taskWithResult {
|
||||||
|
|
||||||
val finalFilename: String = filename ?: url.substringAfterLast("/")
|
val finalFilename: String = filename ?: url.substringAfterLast("/")
|
||||||
val fqFilename: String = (path?.normalizePath() ?: "") + finalFilename
|
val fqFilename: String = (path?.normalizePath() ?: "") + finalFilename
|
||||||
|
|
||||||
if (!overwrite && checkFile(fqFilename, sudo = sudo)) {
|
if (!overwrite && checkFile(fqFilename, sudo = sudo)) {
|
||||||
return@task ProvResult(true, out = "File $fqFilename already exists.")
|
return@taskWithResult ProvResult(true, out = "File $fqFilename already exists.")
|
||||||
}
|
}
|
||||||
|
|
||||||
aptInstall("curl")
|
aptInstall("curl")
|
||||||
|
|
|
@ -51,9 +51,9 @@ fun Prov.deprovisionK3sInfra() = task {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fun Prov.installK3s(k3sConfig: K3sConfig) = task {
|
fun Prov.installK3s(k3sConfig: K3sConfig) = taskWithResult {
|
||||||
if (testConfigExists()) {
|
if (testConfigExists()) {
|
||||||
return@task ProvResult(true, out = "K3s config is already in place, so skip (re)provisioning.")
|
return@taskWithResult ProvResult(true, out = "K3s config is already in place, so skip (re)provisioning.")
|
||||||
}
|
}
|
||||||
|
|
||||||
createDirs(k8sCredentialsDir, sudo = true)
|
createDirs(k8sCredentialsDir, sudo = true)
|
||||||
|
|
|
@ -8,17 +8,17 @@ import org.domaindrivenarchitecture.provs.syspec.infrastructure.findSpecConfigFr
|
||||||
import org.domaindrivenarchitecture.provs.syspec.infrastructure.verifySpecConfig
|
import org.domaindrivenarchitecture.provs.syspec.infrastructure.verifySpecConfig
|
||||||
|
|
||||||
|
|
||||||
fun Prov.verifySpec(configFile: ConfigFileName? = null) = task {
|
fun Prov.verifySpec(configFile: ConfigFileName? = null) = taskWithResult {
|
||||||
val result = findSpecConfigFromFile(configFile)
|
val result = findSpecConfigFromFile(configFile)
|
||||||
val spec = result.getOrElse { return@task ProvResult(false, "Could not read file: ${configFile?.fileName} due to: ${result.exceptionOrNull()?.message}") }
|
val spec = result.getOrElse { return@taskWithResult ProvResult(false, "Could not read file: ${configFile?.fileName} due to: ${result.exceptionOrNull()?.message}") }
|
||||||
verifySpecConfig(spec)
|
verifySpecConfig(spec)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Suppress("unused") // Api
|
@Suppress("unused") // Api
|
||||||
fun Prov.verifySpecFromResource(resourceName: String) = task {
|
fun Prov.verifySpecFromResource(resourceName: String) = taskWithResult {
|
||||||
val result = findSpecConfigFromResource(resourceName)
|
val result = findSpecConfigFromResource(resourceName)
|
||||||
val spec = result.getOrElse { return@task ProvResult(false, "Could not read resource: $resourceName due to: ${result.exceptionOrNull()?.message}") }
|
val spec = result.getOrElse { return@taskWithResult ProvResult(false, "Could not read resource: $resourceName due to: ${result.exceptionOrNull()?.message}") }
|
||||||
verifySpecConfig(spec)
|
verifySpecConfig(spec)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -149,7 +149,7 @@ private fun <T> Prov.verify(success: Boolean, message: String, expected: T? = nu
|
||||||
val actualText = expected?.let { " | Actual value [$actual]" } ?: ""
|
val actualText = expected?.let { " | Actual value [$actual]" } ?: ""
|
||||||
val msg = ": $message $expectedText$actualText"
|
val msg = ": $message $expectedText$actualText"
|
||||||
|
|
||||||
return task("Verification") {
|
return taskWithResult("Verification") {
|
||||||
ProvResult(
|
ProvResult(
|
||||||
success,
|
success,
|
||||||
cmd = if (success) msg else null,
|
cmd = if (success) msg else null,
|
||||||
|
|
|
@ -489,7 +489,7 @@ internal class ProvTest {
|
||||||
addResultToEval(ProvResult(true))
|
addResultToEval(ProvResult(true))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Prov.outer() = task {
|
fun Prov.outer() = taskWithResult {
|
||||||
inner()
|
inner()
|
||||||
ProvResult(false)
|
ProvResult(false)
|
||||||
}
|
}
|
||||||
|
@ -504,11 +504,11 @@ internal class ProvTest {
|
||||||
@Test
|
@Test
|
||||||
fun task_with_failing_subtask_and_successful_result_fails() {
|
fun task_with_failing_subtask_and_successful_result_fails() {
|
||||||
// given
|
// given
|
||||||
fun Prov.inner() = task {
|
fun Prov.inner() = taskWithResult {
|
||||||
ProvResult(false)
|
ProvResult(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Prov.outer() = task {
|
fun Prov.outer() = taskWithResult {
|
||||||
inner()
|
inner()
|
||||||
ProvResult(true)
|
ProvResult(true)
|
||||||
}
|
}
|
||||||
|
@ -527,7 +527,7 @@ internal class ProvTest {
|
||||||
addResultToEval(ProvResult(false))
|
addResultToEval(ProvResult(false))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Prov.outer() = task {
|
fun Prov.outer() = taskWithResult {
|
||||||
inner()
|
inner()
|
||||||
ProvResult(true)
|
ProvResult(true)
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,7 @@ internal class TaskFunctionsKtTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
var count2 = 3
|
var count2 = 3
|
||||||
fun Prov.thirdTimeSuccess() = task {
|
fun Prov.thirdTimeSuccess() = taskWithResult {
|
||||||
if (count2 <= 1) {
|
if (count2 <= 1) {
|
||||||
count2 = 3
|
count2 = 3
|
||||||
ProvResult(true, out = "1")
|
ProvResult(true, out = "1")
|
||||||
|
|
Loading…
Reference in a new issue