Skip to content
This repository has been archived by the owner on Oct 15, 2024. It is now read-only.

Commit

Permalink
refactor(build): migrate to NIO
Browse files Browse the repository at this point in the history
  • Loading branch information
msfjarvis committed Jun 15, 2024
1 parent 445905b commit 7d7410b
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 21 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,16 @@
package app.passwordstore.gradle.crowdin

import java.io.File
import java.nio.file.Path
import javax.xml.parsers.DocumentBuilderFactory
import kotlin.io.path.ExperimentalPathApi
import kotlin.io.path.deleteIfExists
import kotlin.io.path.deleteRecursively
import kotlin.io.path.inputStream
import kotlin.io.path.isDirectory
import kotlin.io.path.listDirectoryEntries
import kotlin.io.path.name
import kotlin.io.path.pathString
import kotlin.io.path.walk
import org.gradle.api.DefaultTask
import org.gradle.api.GradleException
import org.gradle.api.file.DirectoryProperty
Expand All @@ -10,6 +19,7 @@ import org.gradle.api.tasks.TaskAction
import org.gradle.work.DisableCachingByDefault
import org.w3c.dom.Document

@OptIn(ExperimentalPathApi::class)
@DisableCachingByDefault(because = "The task runs quickly and has complicated semantics")
abstract class StringCleanupTask : DefaultTask() {

Expand All @@ -19,12 +29,12 @@ abstract class StringCleanupTask : DefaultTask() {
fun clean() {
val sourceSets = arrayOf("main", "nonFree")
for (sourceSet in sourceSets) {
val fileTreeWalk = sourceDirectory.dir("$sourceSet/res").get().asFile.walkTopDown()
val fileTreeWalk = sourceDirectory.dir("$sourceSet/res").get().asFile.toPath().walk()
val valuesDirectories =
fileTreeWalk.filter { it.isDirectory }.filter { it.name.startsWith("values") }
fileTreeWalk.filter { it.isDirectory() }.filter { it.name.startsWith("values") }
val stringFiles = fileTreeWalk.filter { it.name == "strings.xml" }
val sourceFile =
stringFiles.firstOrNull { it.path.endsWith("values/strings.xml") }
stringFiles.firstOrNull { it.pathString.endsWith("values/strings.xml") }
?: throw GradleException("No root strings.xml found in '$sourceSet' sourceSet")
val sourceDoc = parseDocument(sourceFile)
val baselineStringCount = countStrings(sourceDoc)
Expand All @@ -34,22 +44,22 @@ abstract class StringCleanupTask : DefaultTask() {
val doc = parseDocument(file)
val stringCount = countStrings(doc)
if (stringCount < threshold) {
file.delete()
file.deleteIfExists()
}
}
}
valuesDirectories.forEach { dir ->
if (dir.listFiles().isNullOrEmpty()) {
dir.delete()
if (dir.listDirectoryEntries().isEmpty()) {
dir.deleteRecursively()
}
}
}
}

private fun parseDocument(file: File): Document {
private fun parseDocument(path: Path): Document {
val dbFactory = DocumentBuilderFactory.newInstance()
val documentBuilder = dbFactory.newDocumentBuilder()
return documentBuilder.parse(file)
return documentBuilder.parse(path.inputStream())
}

private fun countStrings(document: Document): Int {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@ package app.passwordstore.gradle.ktfmt

import app.passwordstore.gradle.KtfmtPlugin
import com.facebook.ktfmt.format.Formatter
import java.io.File
import java.nio.file.Path
import kotlin.io.path.pathString
import kotlin.io.path.readText
import kotlin.io.path.relativeTo
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.async
Expand Down Expand Up @@ -35,7 +38,7 @@ abstract class KtfmtCheckTask : SourceTask() {
fun execute() {
runBlocking(Dispatchers.IO.limitedParallelism(PARALLEL_TASK_LIMIT)) {
coroutineScope {
val results = inputFiles.map { async { checkFile(it) } }.awaitAll()
val results = inputFiles.map { async { checkFile(it.toPath()) } }.awaitAll()
if (results.any { (notFormatted, _) -> notFormatted }) {
val prettyDiff =
results
Expand All @@ -48,10 +51,12 @@ abstract class KtfmtCheckTask : SourceTask() {
}
}

private fun checkFile(input: File): Pair<Boolean, List<KtfmtDiffEntry>> {
private fun checkFile(input: Path): Pair<Boolean, List<KtfmtDiffEntry>> {
val originCode = input.readText()
val formattedCode = Formatter.format(KtfmtPlugin.DEFAULT_FORMATTING_OPTIONS, originCode)
val pathNormalizer = { file: File -> file.toRelativeString(projectDirectory.asFile.get()) }
val pathNormalizer = { file: Path ->
file.relativeTo(projectDirectory.asFile.get().toPath()).pathString
}
return (originCode != formattedCode) to
KtfmtDiffer.computeDiff(input, formattedCode, pathNormalizer)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@ import com.github.difflib.DiffUtils
import com.github.difflib.patch.ChangeDelta
import com.github.difflib.patch.DeleteDelta
import com.github.difflib.patch.InsertDelta
import java.io.File
import java.nio.file.Path
import kotlin.io.path.readText

object KtfmtDiffer {
fun computeDiff(
inputFile: File,
inputFile: Path,
formattedCode: String,
pathNormalizer: (File) -> String,
pathNormalizer: (Path) -> String,
): List<KtfmtDiffEntry> {
val originCode = inputFile.readText()
return DiffUtils.diff(originCode, formattedCode, null).deltas.map {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@ package app.passwordstore.gradle.ktfmt

import app.passwordstore.gradle.KtfmtPlugin
import com.facebook.ktfmt.format.Formatter
import java.io.File
import java.nio.file.Path
import kotlin.io.path.pathString
import kotlin.io.path.readText
import kotlin.io.path.relativeTo
import kotlin.io.path.writeText
import org.gradle.api.logging.LogLevel
import org.gradle.api.logging.Logger
import org.gradle.api.logging.Logging
Expand All @@ -12,22 +16,22 @@ import org.gradle.workers.WorkAction
abstract class KtfmtWorkerAction : WorkAction<KtfmtWorkerParameters> {
private val logger: Logger =
DefaultContextAwareTaskLogger(Logging.getLogger(KtfmtFormatTask::class.java))
private val files: List<File> = parameters.files.toList()
private val projectDirectory: File = parameters.projectDirectory.asFile.get()
private val files: List<Path> = parameters.files.toList().map { it.toPath() }
private val projectDirectory: Path = parameters.projectDirectory.asFile.get().toPath()
private val name: String = parameters.name.get()

override fun execute() {
try {
files.forEach { file ->
val sourceText = file.readText()
val relativePath = file.toRelativeString(projectDirectory)
val relativePath = file.relativeTo(projectDirectory).pathString

logger.log(LogLevel.DEBUG, "$name checking format: $relativePath")

val formattedText = Formatter.format(KtfmtPlugin.DEFAULT_FORMATTING_OPTIONS, sourceText)

if (!formattedText.contentEquals(sourceText)) {
logger.log(LogLevel.QUIET, "${file.toRelativeString(projectDirectory)}: Format fixed")
logger.log(LogLevel.QUIET, "$relativePath: Format fixed")
file.writeText(formattedText)
}
}
Expand Down

0 comments on commit 7d7410b

Please sign in to comment.