Skip to content

Commit

Permalink
Assign a file extension at the last possible second
Browse files Browse the repository at this point in the history
  • Loading branch information
jzbrooks committed Oct 12, 2024
1 parent 05fbd7d commit 46c13d2
Showing 1 changed file with 70 additions and 74 deletions.
144 changes: 70 additions & 74 deletions vgo/src/main/kotlin/com/jzbrooks/vgo/Vgo.kt
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,13 @@ import org.w3c.dom.Document
import java.io.ByteArrayInputStream
import java.io.ByteArrayOutputStream
import java.io.File
import java.nio.file.Path
import java.nio.file.Paths
import javax.xml.parsers.DocumentBuilderFactory
import kotlin.io.path.exists
import kotlin.io.path.isDirectory
import kotlin.io.path.isRegularFile
import kotlin.io.path.isSameFileAs
import kotlin.math.absoluteValue
import kotlin.math.roundToInt

Expand Down Expand Up @@ -53,85 +58,29 @@ class Vgo(
inputs = standardInPaths
}

val inputOutputMap =
if (options.output.isNotEmpty()) {
inputs.zip(options.output) { a, b ->
Pair(File(a), File(b))
}
} else {
inputs.zip(inputs) { a, b ->

}
}.toMap()

val inputOutputMap = pairOutputs()
val files = inputOutputMap.count { (input, _) -> input.isFile }
val containsDirectory = inputOutputMap.any { (input, _) -> input.isDirectory }
printFileNames = options.printStats && (files > 1 || containsDirectory)

return handleFiles(inputOutputMap, writerOptions)
}

private fun pairOutputs(): Map<File, File> {
val inputFiles = options.input.map(::File)
private fun pairOutputs(): Map<File, Path> {
return if (options.output.isNotEmpty()) {
inputFiles.zip(options.output.map(::File)).toMap()
options.input.zip(options.output) { a, b ->
Pair(File(a), Paths.get(b))
}
} else {
inputFiles.mapIndexed { index, input ->
if (!input.isDirectory) {
val outputExtension = when (options.format) {
"svg" -> "svg"
"vd" -> "xml"
else -> input.extension
}
val outputFilePath = options.output.dropLastWhile { it != '.' } + outputExtension
}
}.toMap()
}
}

private fun handleFiles(
inputOutputMap: Map<File, File>,
writerOptions: Set<Writer.Option>,
): Int {
for (entry in inputOutputMap) {
val (input, output) = entry

when {
entry.isFilePair -> handleFile(input, output, writerOptions)
entry.isDirectoryPair -> handleDirectory(input, output, writerOptions)
!entry.inputExists -> {
System.err.println("${input.path} does not exist.")
return 65
}
else -> {
System.err.println(
"""
A given input and output pair (grouped positionally)
must be either files or directories.
Input is a ${if (input.isFile) "file" else "directory"}
path: ${input.absolutePath}
exists: ${input.exists()}
isWritable: ${input.canWrite()}
Output is a ${if (output.isFile) "file" else "directory"}
path: ${output.absolutePath}
exists: ${input.exists()}
isWritable: ${input.canWrite()}
Storage: ${output.usableSpace} / ${output.totalSpace} is usable.
""".trimIndent(),
)

return 65
}
options.input.zip(options.input) { a, b ->
Pair(File(a), Paths.get(b))
}
}

return 0
}.toMap()
}

private fun handleFile(
input: File,
output: File,
outputPath: Path,
options: Set<Writer.Option>,
) {
input.inputStream().use { inputStream ->
Expand Down Expand Up @@ -186,7 +135,7 @@ class Vgo(
com.jzbrooks.vgo.vd
.parse(rootNodes.first())
}
else -> if (input == output) return else null
else -> if (outputPath.isSameFileAs(input.toPath())) return else null
}

if (graphic is VectorDrawable && this.options.format == "svg") {
Expand All @@ -204,6 +153,12 @@ class Vgo(
optimizationRegistry?.apply(graphic)
}

val output = when(this.options.format) {
"vd" -> outputPath.resolveSibling("${outputPath.fileName}.xml")
"svg" -> outputPath.resolveSibling("${outputPath.fileName}.svg")
else -> outputPath
}.toFile()

if (output.parentFile?.exists() == false) output.parentFile.mkdirs()
if (!output.exists()) output.createNewFile()

Expand Down Expand Up @@ -239,16 +194,57 @@ class Vgo(
}
}

private fun handleFiles(
inputOutputMap: Map<File, Path>,
writerOptions: Set<Writer.Option>,
): Int {
for (entry in inputOutputMap) {
val (input, output) = entry

when {
entry.isFilePair -> handleFile(input, output, writerOptions)
entry.isDirectoryPair -> handleDirectory(input, output, writerOptions)
!entry.inputExists -> {
System.err.println("${input.path} does not exist.")
return 65
}
else -> {
val output = output.toFile()
System.err.println(
"""
A given input and output pair (grouped positionally)
must be either files or directories.
Input is a ${if (input.isFile) "file" else "directory"}
path: ${input.absolutePath}
exists: ${input.exists()}
isWritable: ${input.canWrite()}
Output is a ${if (output.isFile) "file" else "directory"}
path: ${output.absolutePath}
exists: ${input.exists()}
isWritable: ${input.canWrite()}
Storage: ${output.usableSpace} / ${output.totalSpace} is usable.
""".trimIndent(),
)

return 65
}
}
}

return 0
}

private fun handleDirectory(
input: File,
output: File,
output: Path,
options: Set<Writer.Option>,
) {
assert(input.isDirectory)
assert(output.isDirectory || !output.exists())
assert(output.isDirectory() || !output.exists())

for (file in input.walkTopDown().filter { file -> !file.isHidden && !file.isDirectory }) {
handleFile(file, File(output, file.name), options)
handleFile(file, output.resolve(file.name), options)
}

if (this.options.printStats) {
Expand Down Expand Up @@ -282,14 +278,14 @@ class Vgo(
else -> "$bytes B"
}

private val Map.Entry<File, File>.inputExists
private val Map.Entry<File, Path>.inputExists
get() = key.exists()

private val Map.Entry<File, File>.isFilePair
get() = key.isFile && (value.isFile || !value.exists())
private val Map.Entry<File, Path>.isFilePair
get() = key.isFile && (value.isRegularFile() || !value.exists())

private val Map.Entry<File, File>.isDirectoryPair
get() = key.isDirectory && (value.isDirectory || !value.exists())
private val Map.Entry<File, Path>.isDirectoryPair
get() = key.isDirectory && (value.isDirectory() || !value.exists())

data class Options(
val printVersion: Boolean = false,
Expand Down

0 comments on commit 46c13d2

Please sign in to comment.