From da7860f49f4b16dd3e5ee385fb5a8dab0b09be1f Mon Sep 17 00:00:00 2001 From: Jerre van Veluw Date: Fri, 3 Jan 2025 17:05:56 +0100 Subject: [PATCH] exitcode 1 on error in cli --- .../community/flock/wirespec/plugin/Input.kt | 3 +- .../community/flock/wirespec/plugin/Output.kt | 4 + .../plugin/cli/CommandLineEntitiesParser.kt | 41 +++++++-- .../flock/wirespec/plugin/cli/Main.kt | 91 ++++++++++--------- .../flock/wirespec/plugin/cli/io/File.kt | 5 +- .../plugin/cli/CommandLineEntitiesTest.kt | 48 ++++++---- .../wirespec/plugin/cli/WirespecCliTest.kt | 10 +- .../flock/wirespec/plugin/cli/io/File.kt | 7 +- .../flock/wirespec/plugin/cli/io/File.kt | 7 +- .../flock/wirespec/plugin/cli/io/File.kt | 7 +- 10 files changed, 135 insertions(+), 88 deletions(-) diff --git a/src/plugin/arguments/src/commonMain/kotlin/community/flock/wirespec/plugin/Input.kt b/src/plugin/arguments/src/commonMain/kotlin/community/flock/wirespec/plugin/Input.kt index 953e3ddc..780c97c5 100644 --- a/src/plugin/arguments/src/commonMain/kotlin/community/flock/wirespec/plugin/Input.kt +++ b/src/plugin/arguments/src/commonMain/kotlin/community/flock/wirespec/plugin/Input.kt @@ -12,8 +12,7 @@ sealed interface Input data class FullDirPath(val path: String) : Input -data class FullFilePath(val directory: String, val fileName: FileName, val extension: FileExtension = Wirespec) : - Input { +data class FullFilePath(val directory: String, val fileName: FileName, val extension: FileExtension = Wirespec) : Input { companion object { fun parse(input: String): FullFilePath { val list = input.split("/").let { it.dropLast(1) + it.last().split(".") } diff --git a/src/plugin/arguments/src/commonMain/kotlin/community/flock/wirespec/plugin/Output.kt b/src/plugin/arguments/src/commonMain/kotlin/community/flock/wirespec/plugin/Output.kt index 03d52265..9d03b2da 100644 --- a/src/plugin/arguments/src/commonMain/kotlin/community/flock/wirespec/plugin/Output.kt +++ b/src/plugin/arguments/src/commonMain/kotlin/community/flock/wirespec/plugin/Output.kt @@ -3,6 +3,10 @@ package community.flock.wirespec.plugin import community.flock.wirespec.compiler.core.Value import kotlin.jvm.JvmInline +interface Writer { + fun write(string: String) +} + @JvmInline value class Output private constructor(override val value: String) : Value { diff --git a/src/plugin/cli/src/commonMain/kotlin/community/flock/wirespec/plugin/cli/CommandLineEntitiesParser.kt b/src/plugin/cli/src/commonMain/kotlin/community/flock/wirespec/plugin/cli/CommandLineEntitiesParser.kt index bcb4c761..3eb79b13 100644 --- a/src/plugin/cli/src/commonMain/kotlin/community/flock/wirespec/plugin/cli/CommandLineEntitiesParser.kt +++ b/src/plugin/cli/src/commonMain/kotlin/community/flock/wirespec/plugin/cli/CommandLineEntitiesParser.kt @@ -1,6 +1,9 @@ package community.flock.wirespec.plugin.cli +import arrow.core.Either +import arrow.core.EitherNel import com.github.ajalt.clikt.core.CliktCommand +import com.github.ajalt.clikt.core.CliktError import com.github.ajalt.clikt.core.NoOpCliktCommand import com.github.ajalt.clikt.core.subcommands import com.github.ajalt.clikt.parameters.arguments.argument @@ -11,6 +14,8 @@ import com.github.ajalt.clikt.parameters.options.option import com.github.ajalt.clikt.parameters.types.choice import com.github.ajalt.clikt.parameters.types.enum import community.flock.wirespec.compiler.core.emit.common.DEFAULT_GENERATED_PACKAGE_STRING +import community.flock.wirespec.compiler.core.emit.common.Emitted +import community.flock.wirespec.compiler.core.exceptions.WirespecException import community.flock.wirespec.compiler.utils.Logger.Level import community.flock.wirespec.compiler.utils.Logger.Level.DEBUG import community.flock.wirespec.compiler.utils.Logger.Level.ERROR @@ -27,6 +32,7 @@ import community.flock.wirespec.plugin.Language.Wirespec import community.flock.wirespec.plugin.Operation import community.flock.wirespec.plugin.Output import community.flock.wirespec.plugin.PackageName +import community.flock.wirespec.plugin.cli.io.File enum class Options(vararg val flags: String) { InputDir("-d", "--input-dir"), @@ -42,9 +48,10 @@ enum class Options(vararg val flags: String) { class WirespecCli : NoOpCliktCommand(name = "wirespec") { companion object { fun provide( - compile: (CompilerArguments) -> Unit, - convert: (CompilerArguments) -> Unit, - ): (Array) -> Unit = WirespecCli().subcommands(Compile(compile), Convert(convert))::main + compile: (CompilerArguments) -> List, File?>>>, + convert: (CompilerArguments) -> List, File?>>>, + write: List.(File?) -> Unit, + ): (Array) -> Unit = WirespecCli().subcommands(Compile(compile, write), Convert(convert, write))::main } } @@ -58,7 +65,7 @@ private abstract class CommonOptions : CliktCommand() { val strict by option(*Options.Strict.flags, help = "Strict mode").flag() fun getInput(inputDir: String? = null): Input = - if (inputDir != null && inputFile != null) error("Choose either a file or a directory. Not Both.") + if (inputDir != null && inputFile != null) throw CliktError("Choose either a file or a directory. Not Both.") else inputFile ?.let(FullFilePath.Companion::parse) ?: inputDir?.let(::FullDirPath) @@ -69,11 +76,14 @@ private abstract class CommonOptions : CliktCommand() { "INFO" -> INFO "WARN" -> WARN "ERROR" -> ERROR - else -> error("Choose one of these log levels: $Level") + else -> throw CliktError("Choose one of these log levels: $Level") } } -private class Compile(private val block: (CompilerArguments) -> Unit) : CommonOptions() { +private class Compile( + private val block: (CompilerArguments) -> List, File?>>>, + private val write: (List, File?) -> Unit, +) : CommonOptions() { private val languages by option(*Options.Language.flags, help = "Language") .choice(Language.toMap()) @@ -89,11 +99,19 @@ private class Compile(private val block: (CompilerArguments) -> Unit) : CommonOp logLevel = logLevel.toLogLevel(), shared = shared, strict = strict, - ).let(block) + ).let(block).forEach { + when (it) { + is Either.Right -> it.value.let { (result, file) -> write(result, file) } + is Either.Left -> throw CliktError(it.value.joinToString { e -> e.message ?: "" }) + } + } } } -private class Convert(private val block: (CompilerArguments) -> Unit) : CommonOptions() { +private class Convert( + private val block: (CompilerArguments) -> List, File?>>>, + private val write: (List, File?) -> Unit, +) : CommonOptions() { private val format by argument(help = "Input format").enum() private val languages by option(*Options.Language.flags, help = "Language") @@ -111,6 +129,11 @@ private class Convert(private val block: (CompilerArguments) -> Unit) : CommonOp logLevel = logLevel.toLogLevel(), shared = shared, strict = strict, - ).let(block) + ).let(block).forEach { + when (it) { + is Either.Right -> it.value.let { (result, file) -> write(result, file) } + is Either.Left -> echo(it.value, err = true) + } + } } } diff --git a/src/plugin/cli/src/commonMain/kotlin/community/flock/wirespec/plugin/cli/Main.kt b/src/plugin/cli/src/commonMain/kotlin/community/flock/wirespec/plugin/cli/Main.kt index 48a1ed0a..ac64593c 100644 --- a/src/plugin/cli/src/commonMain/kotlin/community/flock/wirespec/plugin/cli/Main.kt +++ b/src/plugin/cli/src/commonMain/kotlin/community/flock/wirespec/plugin/cli/Main.kt @@ -1,6 +1,10 @@ package community.flock.wirespec.plugin.cli import arrow.core.Either +import arrow.core.NonEmptyList +import arrow.core.left +import arrow.core.nel +import arrow.core.right import community.flock.wirespec.compiler.core.WirespecSpec import community.flock.wirespec.compiler.core.compile import community.flock.wirespec.compiler.core.component1 @@ -10,8 +14,9 @@ import community.flock.wirespec.compiler.core.emit.ScalaEmitter import community.flock.wirespec.compiler.core.emit.TypeScriptEmitter import community.flock.wirespec.compiler.core.emit.WirespecEmitter import community.flock.wirespec.compiler.core.emit.common.Emitted -import community.flock.wirespec.compiler.core.emit.common.Emitter import community.flock.wirespec.compiler.core.emit.common.Emitter.Companion.firstToUpper +import community.flock.wirespec.compiler.core.exceptions.WirespecException +import community.flock.wirespec.compiler.core.exceptions.WirespecException.IOException.FileReadException import community.flock.wirespec.compiler.utils.Logger import community.flock.wirespec.openapi.v2.OpenApiV2Emitter import community.flock.wirespec.openapi.v3.OpenApiV3Emitter @@ -50,12 +55,12 @@ fun main(args: Array) { (0..20) .mapNotNull(args::orNull) .toTypedArray() - .let(WirespecCli.provide(::compile, ::convert)) + .let(WirespecCli.provide(::compile, ::convert, ::write)) } -fun convert(arguments: CompilerArguments): Unit = compile(arguments) +fun convert(arguments: CompilerArguments): List, Pair, File?>>> = compile(arguments) -fun compile(arguments: CompilerArguments) { +fun compile(arguments: CompilerArguments): List, Pair, File?>>> { val input = arguments.input val output = arguments.output @@ -65,7 +70,7 @@ fun compile(arguments: CompilerArguments) { val logger = Logger(arguments.logLevel) - when (val operation = arguments.operation) { + return when (val operation = arguments.operation) { is Operation.Convert -> { val fullPath = input as FullFilePath @@ -86,7 +91,7 @@ fun compile(arguments: CompilerArguments) { ) ) to file else results to file - }.map { (results, file) -> write(results, file) } + }.map { it.right() } } is Operation.Compile -> when (input) { @@ -95,62 +100,58 @@ fun compile(arguments: CompilerArguments) { is FullDirPath -> Directory(input.path) .wirespecFiles() - .forEach { it.wirespec(languages, packageName, it.path.out(packageName, output), logger) } + .flatMap { it.wirespec(languages, packageName, it.path.out(packageName, output), logger) } is FullFilePath -> if (input.extension == FileExtension.Wirespec) WirespecFile(input) .let { it.wirespec(languages, packageName, it.path.out(packageName, output), logger) } - else error("Path $input is not a Wirespec file") + else FileReadException("Path $input is not a Wirespec file").nel().left().nel() } } } +fun write(output: List, file: File?) { + output.forEach { (name, result) -> file?.copy(FileName(name))?.write(result) ?: print(result) } +} + private fun Reader.wirespec( languages: Set, packageName: PackageName, path: (FileExtension) -> FullFilePath, logger: Logger -) { - read() - .let(WirespecSpec::compile)(logger) - .let { compiler -> - languages.emitters(packageName, path, logger).map { (emitter, file) -> - val results = compiler(emitter) - if (!emitter.split) results.map { - listOf( - Emitted( - path(FileExtension.Wirespec).fileName.value.firstToUpper(), - it.first().result - ) +) = read() + .let(WirespecSpec::compile)(logger) + .let { compiler -> + languages.emitters(packageName, path, logger).map { (emitter, file) -> + val results = compiler(emitter) + if (!emitter.split) results.map { + listOf( + Emitted( + path(FileExtension.Wirespec).fileName.value.firstToUpper(), + it.first().result ) - } to file - else results to file - } - } - .map { (results, file) -> - when (results) { - is Either.Right -> write(results.value, file) - is Either.Left -> println(results.value) - } - } -} - -private fun Set.emitters(packageName: PackageName, path: ((FileExtension) -> FullFilePath)?, logger: Logger): List> = - map { - val (packageString) = packageName - when (it) { - Java -> JavaEmitter(packageString, logger) to path?.let { JavaFile(it(FileExtension.Java)) } - Kotlin -> KotlinEmitter(packageString, logger) to path?.let { KotlinFile(it(FileExtension.Kotlin)) } - Scala -> ScalaEmitter(packageString, logger) to path?.let { ScalaFile(it(FileExtension.Scala)) } - TypeScript -> TypeScriptEmitter(logger) to path?.let { TypeScriptFile(it(FileExtension.TypeScript)) } - Wirespec -> WirespecEmitter(logger) to path?.let { WirespecFile(it(FileExtension.Wirespec)) } - OpenAPIV2 -> OpenApiV2Emitter to path?.let { JsonFile(it(FileExtension.Json)) } - OpenAPIV3 -> OpenApiV3Emitter to path?.let { JsonFile(it(FileExtension.Json)) } + ) + } to file + else results to file } } + .map { (results, file) -> results.map { it to file } } -private fun write(output: List, file: File?) { - output.forEach { (name, result) -> file?.copy(FileName(name))?.write(result) ?: print(result) } +private fun Set.emitters( + packageName: PackageName, + path: ((FileExtension) -> FullFilePath)?, + logger: Logger +) = map { + val (packageString) = packageName + when (it) { + Java -> JavaEmitter(packageString, logger) to path?.let { JavaFile(it(FileExtension.Java)) } + Kotlin -> KotlinEmitter(packageString, logger) to path?.let { KotlinFile(it(FileExtension.Kotlin)) } + Scala -> ScalaEmitter(packageString, logger) to path?.let { ScalaFile(it(FileExtension.Scala)) } + TypeScript -> TypeScriptEmitter(logger) to path?.let { TypeScriptFile(it(FileExtension.TypeScript)) } + Wirespec -> WirespecEmitter(logger) to path?.let { WirespecFile(it(FileExtension.Wirespec)) } + OpenAPIV2 -> OpenApiV2Emitter to path?.let { JsonFile(it(FileExtension.Json)) } + OpenAPIV3 -> OpenApiV3Emitter to path?.let { JsonFile(it(FileExtension.Json)) } + } } private fun FullFilePath.out(packageName: PackageName, output: Output?) = { extension: FileExtension -> diff --git a/src/plugin/cli/src/commonMain/kotlin/community/flock/wirespec/plugin/cli/io/File.kt b/src/plugin/cli/src/commonMain/kotlin/community/flock/wirespec/plugin/cli/io/File.kt index f24a7d6e..494b1112 100644 --- a/src/plugin/cli/src/commonMain/kotlin/community/flock/wirespec/plugin/cli/io/File.kt +++ b/src/plugin/cli/src/commonMain/kotlin/community/flock/wirespec/plugin/cli/io/File.kt @@ -3,17 +3,18 @@ package community.flock.wirespec.plugin.cli.io import community.flock.wirespec.plugin.FileName import community.flock.wirespec.plugin.FullFilePath import community.flock.wirespec.plugin.Reader +import community.flock.wirespec.plugin.Writer interface Copy { fun copy(fileName: FileName): File } -expect abstract class File(path: FullFilePath) : Reader, Copy { +expect abstract class File(path: FullFilePath) : Reader, Writer, Copy { val path: FullFilePath override fun read(): String - fun write(text: String) + override fun write(string: String) } diff --git a/src/plugin/cli/src/commonTest/kotlin/community/flock/wirespec/plugin/cli/CommandLineEntitiesTest.kt b/src/plugin/cli/src/commonTest/kotlin/community/flock/wirespec/plugin/cli/CommandLineEntitiesTest.kt index 6add33ca..f49cf376 100644 --- a/src/plugin/cli/src/commonTest/kotlin/community/flock/wirespec/plugin/cli/CommandLineEntitiesTest.kt +++ b/src/plugin/cli/src/commonTest/kotlin/community/flock/wirespec/plugin/cli/CommandLineEntitiesTest.kt @@ -1,7 +1,11 @@ package community.flock.wirespec.plugin.cli +import arrow.core.EitherNel import community.flock.wirespec.compiler.core.emit.common.DEFAULT_GENERATED_PACKAGE_STRING +import community.flock.wirespec.compiler.core.emit.common.Emitted +import community.flock.wirespec.compiler.core.exceptions.WirespecException import community.flock.wirespec.compiler.utils.Logger.Level.ERROR +import community.flock.wirespec.plugin.CompilerArguments import community.flock.wirespec.plugin.Console import community.flock.wirespec.plugin.FileExtension import community.flock.wirespec.plugin.Format @@ -10,6 +14,7 @@ import community.flock.wirespec.plugin.FullFilePath import community.flock.wirespec.plugin.Language.Kotlin import community.flock.wirespec.plugin.Language.Wirespec import community.flock.wirespec.plugin.Operation +import community.flock.wirespec.plugin.cli.io.File import io.kotest.matchers.nulls.shouldBeNull import io.kotest.matchers.shouldBe import io.kotest.matchers.types.shouldBeTypeOf @@ -34,21 +39,23 @@ class CommandLineEntitiesTest { } ) }.filterNot { it == "-f" }.toTypedArray() - WirespecCli.provide({ - it.input.shouldBeTypeOf().path shouldBe "input" - it.operation.shouldBeTypeOf() - it.output?.value shouldBe "output" - it.languages shouldBe setOf(Wirespec) - it.packageName.value shouldBe "packageName" - it.logLevel shouldBe ERROR - it.shared.also(::println) shouldBe true - it.strict shouldBe true - }, {})(arrayOf("compile") + opts) + WirespecCli.provide( + noopInput { + it.input.shouldBeTypeOf().path shouldBe "input" + it.operation.shouldBeTypeOf() + it.output?.value shouldBe "output" + it.languages shouldBe setOf(Wirespec) + it.packageName.value shouldBe "packageName" + it.logLevel shouldBe ERROR + it.shared.also(::println) shouldBe true + it.strict shouldBe true + }, noopInput {}, noopWriter + )(arrayOf("compile") + opts) } @Test fun testMinimumCliArgumentsForCompile() { - WirespecCli.provide({ + WirespecCli.provide(noopInput { it.operation.shouldBeTypeOf() it.input.shouldBeTypeOf() it.output.shouldBeNull() @@ -57,12 +64,12 @@ class CommandLineEntitiesTest { it.logLevel shouldBe ERROR it.shared shouldBe false it.strict shouldBe false - }, {})(arrayOf("compile", "-l", "Kotlin")) + }, noopInput { }, noopWriter)(arrayOf("compile", "-l", "Kotlin")) } @Test fun testMinimumCliArgumentsForConvert() { - WirespecCli.provide({ }, { + WirespecCli.provide(noopInput { }, noopInput { it.operation.shouldBeTypeOf() it.input.shouldBeTypeOf().run { fileName.value shouldBe "swagger" @@ -74,12 +81,12 @@ class CommandLineEntitiesTest { it.logLevel shouldBe ERROR it.shared shouldBe false it.strict shouldBe false - })(arrayOf("convert", "-f", "swagger.json", "openapiv2")) + }, noopWriter)(arrayOf("convert", "-f", "swagger.json", "openapiv2")) } @Test fun testCommandLineEntitiesParser() { - WirespecCli.provide({}, { + WirespecCli.provide(noopInput { }, noopInput { it.operation.shouldBeTypeOf().run { format shouldBe Format.OpenApiV2 } @@ -90,6 +97,15 @@ class CommandLineEntitiesTest { it.logLevel shouldBe ERROR it.shared shouldBe false it.strict shouldBe false - })(arrayOf("convert", "openapiv2", "-o", "output", "-l", "Kotlin")) + }, noopWriter)(arrayOf("convert", "openapiv2", "-o", "output", "-l", "Kotlin")) } + + private fun noopInput(block: (CompilerArguments) -> Unit): (CompilerArguments) -> List, File?>>> = + { + block(it) + emptyList() + } + + private val noopWriter: (List, File?) -> Unit = { _, _ -> } + } diff --git a/src/plugin/cli/src/commonTest/kotlin/community/flock/wirespec/plugin/cli/WirespecCliTest.kt b/src/plugin/cli/src/commonTest/kotlin/community/flock/wirespec/plugin/cli/WirespecCliTest.kt index 3a40988c..b3b325e6 100644 --- a/src/plugin/cli/src/commonTest/kotlin/community/flock/wirespec/plugin/cli/WirespecCliTest.kt +++ b/src/plugin/cli/src/commonTest/kotlin/community/flock/wirespec/plugin/cli/WirespecCliTest.kt @@ -21,7 +21,7 @@ class WirespecCliTest { val input = "${inputDir}/wirespec" val output = outputDir() - WirespecCli.provide(::compile, ::convert)(arrayOf("compile", "-d", input, "-o", output, "-l", "Kotlin")) + WirespecCli.provide(::compile, ::convert, ::write)(arrayOf("compile", "-d", input, "-o", output, "-l", "Kotlin")) val file = KotlinFile(FullFilePath("$output/$packageDir", FileName("Type"))).read() @@ -44,7 +44,7 @@ class WirespecCliTest { val input = "${inputDir}/wirespec" val output = outputDir() - WirespecCli.provide(::compile, ::convert)( + WirespecCli.provide(::compile, ::convert, ::write)( arrayOf( "compile", "-d", input, @@ -76,7 +76,7 @@ class WirespecCliTest { val input = "${inputDir}/openapi/petstore.json" val output = outputDir() - WirespecCli.provide(::compile, ::convert)( + WirespecCli.provide(::compile, ::convert, ::write)( arrayOf( "convert", "openapiv2", "-f", input, @@ -110,7 +110,7 @@ class WirespecCliTest { val input = "${inputDir}/openapi/keto.json" val output = outputDir() - WirespecCli.provide(::compile, ::convert)( + WirespecCli.provide(::compile, ::convert, ::write)( arrayOf( "convert", "openapiv3", "-f", input, @@ -143,7 +143,7 @@ class WirespecCliTest { val input = "${inputDir}/openapi/petstore.json" val output = outputDir() - WirespecCli.provide(::compile, ::convert)( + WirespecCli.provide(::compile, ::convert, ::write)( arrayOf( "convert", "openapiv2", "-f", input, diff --git a/src/plugin/cli/src/jsMain/kotlin/community/flock/wirespec/plugin/cli/io/File.kt b/src/plugin/cli/src/jsMain/kotlin/community/flock/wirespec/plugin/cli/io/File.kt index fa113ff4..e98c486c 100644 --- a/src/plugin/cli/src/jsMain/kotlin/community/flock/wirespec/plugin/cli/io/File.kt +++ b/src/plugin/cli/src/jsMain/kotlin/community/flock/wirespec/plugin/cli/io/File.kt @@ -2,18 +2,19 @@ package community.flock.wirespec.plugin.cli.io import community.flock.wirespec.plugin.FullFilePath import community.flock.wirespec.plugin.Reader +import community.flock.wirespec.plugin.Writer import community.flock.wirespec.plugin.cli.js.fs -actual abstract class File actual constructor(actual val path: FullFilePath) : Reader, Copy { +actual abstract class File actual constructor(actual val path: FullFilePath) : Reader, Writer, Copy { actual override fun read(): String = fs.readFileSync(path.toString(), "utf-8").unsafeCast() - actual fun write(text: String) { + actual override fun write(string: String) { path.copy(directory = path.directory.split("out").joinToString("out/node")).run { if (!fs.existsSync(directory).unsafeCast()) { fs.mkdirSync(directory, js("{ recursive: true }")) } - fs.writeFileSync(this.toString(), text) + fs.writeFileSync(this.toString(), string) } } diff --git a/src/plugin/cli/src/jvmMain/kotlin/community/flock/wirespec/plugin/cli/io/File.kt b/src/plugin/cli/src/jvmMain/kotlin/community/flock/wirespec/plugin/cli/io/File.kt index 1605dfdc..8a459057 100644 --- a/src/plugin/cli/src/jvmMain/kotlin/community/flock/wirespec/plugin/cli/io/File.kt +++ b/src/plugin/cli/src/jvmMain/kotlin/community/flock/wirespec/plugin/cli/io/File.kt @@ -2,16 +2,17 @@ package community.flock.wirespec.plugin.cli.io import community.flock.wirespec.plugin.FullFilePath import community.flock.wirespec.plugin.Reader +import community.flock.wirespec.plugin.Writer import kotlin.text.Charsets.UTF_8 import java.io.File as JavaFile -actual abstract class File actual constructor(actual val path: FullFilePath) : Reader, Copy { +actual abstract class File actual constructor(actual val path: FullFilePath) : Reader, Writer, Copy { actual override fun read(): String = JavaFile(path.toString()).readText(UTF_8) - actual fun write(text: String) = path.run { + actual override fun write(string: String) = path.run { JavaFile(directory).also { if (!it.exists()) it.mkdirs() } - JavaFile(this.toString()).writeText(text, UTF_8) + JavaFile(this.toString()).writeText(string, UTF_8) } } diff --git a/src/plugin/cli/src/nativeMain/kotlin/community/flock/wirespec/plugin/cli/io/File.kt b/src/plugin/cli/src/nativeMain/kotlin/community/flock/wirespec/plugin/cli/io/File.kt index f1cbc0eb..ca40805d 100644 --- a/src/plugin/cli/src/nativeMain/kotlin/community/flock/wirespec/plugin/cli/io/File.kt +++ b/src/plugin/cli/src/nativeMain/kotlin/community/flock/wirespec/plugin/cli/io/File.kt @@ -4,6 +4,7 @@ import community.flock.wirespec.compiler.core.exceptions.WirespecException.IOExc import community.flock.wirespec.compiler.core.exceptions.WirespecException.IOException.FileWriteException import community.flock.wirespec.plugin.FullFilePath import community.flock.wirespec.plugin.Reader +import community.flock.wirespec.plugin.Writer import kotlinx.cinterop.ByteVar import kotlinx.cinterop.ExperimentalForeignApi import kotlinx.cinterop.allocArray @@ -18,7 +19,7 @@ import platform.posix.mkdir import platform.posix.opendir @OptIn(ExperimentalForeignApi::class) -actual abstract class File actual constructor(actual val path: FullFilePath) : Reader, Copy { +actual abstract class File actual constructor(actual val path: FullFilePath) : Reader, Writer, Copy { actual override fun read() = StringBuilder().apply { fopen(path.toString(), "r")?.let { file -> @@ -37,7 +38,7 @@ actual abstract class File actual constructor(actual val path: FullFilePath) : R } ?: throw FileReadException("Cannot open input file $path") }.toString() - actual fun write(text: String) { + actual override fun write(string: String) { val directory = path.directory .apply { split("/").reduce { acc, cur -> "$acc/$cur".also { opendir(it) ?: makeDir(it) } } @@ -46,7 +47,7 @@ actual abstract class File actual constructor(actual val path: FullFilePath) : R val nativePath = path.copy(directory = directory) fopen(nativePath.toString(), "w")?.runCatching { - let { memScoped { if (fputs(text, it) == EOF) throw FileWriteException("File write error") } } + let { memScoped { if (fputs(string, it) == EOF) throw FileWriteException("File write error") } } fclose(this) } ?: throw FileReadException("Cannot open output file $nativePath") }