From eeefce7f789f2d5fda0d2672904657b97c6cd928 Mon Sep 17 00:00:00 2001 From: Jorge Braz Date: Mon, 9 Feb 2026 10:18:39 +0000 Subject: [PATCH 1/3] Use batching instead of individual runs per file Somewhere along Codacy's lifetime swiflint was changed to run individually for each file which was resulting in constant an prevasive timeouts at 15 minutes (from testing, the tool would take close to 2 hours to be able to analyse a frequent workload -- under version `0.61.0`). This was happening because starting up all the swiflint machinery was quite expensive and time consuming (~1 minute) and was being done for each indivitual file. Seemingly, with a bump to version `0.63.2` this problem basically all but vanishes, as a workload that was takin 1:55:33 to be performed under `0.61.0` would take 00:01:29 under `0.63.2` therefore greatly mitigating the original issue. Still, batching (giving the tool a list of all the files to be analysed) significan performance improvemnts, reducing the analysis time from 90 seconds to 10 seconds. Assuming the same workload (100 files): 0.61.0 sequential: `01:55:33` (~2 hours) 0.63.2 sequential: `00:01:26` (~1:30 minutes) 0.63.2 batch: `00:00:09` (~10 seconds) The generated results accross versions and approaches seem to be similar, so the change is apparently a net positive. Unfortunately it was not really possible to fully confirm the motivations that originally had moved swiflint from batch to sequential. TAROT-3633 --- .../scala/codacy/swiftlint/SwiftLint.scala | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/src/main/scala/codacy/swiftlint/SwiftLint.scala b/src/main/scala/codacy/swiftlint/SwiftLint.scala index 78610ba..763ed79 100755 --- a/src/main/scala/codacy/swiftlint/SwiftLint.scala +++ b/src/main/scala/codacy/swiftlint/SwiftLint.scala @@ -57,7 +57,7 @@ object SwiftLint extends Tool { } } - private def commandToRun(configOpt: Option[String], file: String): List[String] = { + private def commandToRun(configOpt: Option[String], files: List[String]): List[String] = { val baseCmd = List("swiftlint", "lint", "--quiet", "--reporter", "json") val configCmd = configOpt match { @@ -65,7 +65,8 @@ object SwiftLint extends Tool { baseCmd ++ List("--config", opt) case None => baseCmd } - configCmd :+ file + + configCmd ++ files } private def runToolCommand( @@ -107,17 +108,17 @@ object SwiftLint extends Tool { val cfgOpt = configsFromCodacyConfiguration(configuration) - filesToLint.flatMap { file => - val command: List[String] = commandToRun(cfgOpt, file) + val command: List[String] = commandToRun(cfgOpt, filesToLint) - val fileCommandAnalysisResult = runToolCommand(command, source, cfgOpt) - fileCommandAnalysisResult match { - case Success(res) => res - case Failure(exception) => - List( - FileError(Source.File(file), Some(ErrorMessage(s"Failed to analyse file $file: ${exception.getMessage}"))) + runToolCommand(command, source, cfgOpt) match { + case Success(res) => res + case Failure(exception) => + List( + FileError( + Source.File(source.path), + Some(ErrorMessage(s"Failed to analyse source ${source.path}: ${exception.getMessage}")) ) - } + ) } } } From bcda60caab5d699a2b9765139e42d26fc8eea3e4 Mon Sep 17 00:00:00 2001 From: Lorenzo Gabriele Date: Tue, 17 Feb 2026 10:01:28 +0100 Subject: [PATCH 2/3] fix: Replace file error with tool error Now that we run files all together, we can't return a FileError, since we don't know which file caused the error. We return a global error instead. --- src/main/scala/codacy/swiftlint/SwiftLint.scala | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/src/main/scala/codacy/swiftlint/SwiftLint.scala b/src/main/scala/codacy/swiftlint/SwiftLint.scala index 763ed79..7522ff4 100755 --- a/src/main/scala/codacy/swiftlint/SwiftLint.scala +++ b/src/main/scala/codacy/swiftlint/SwiftLint.scala @@ -3,12 +3,11 @@ package codacy.swiftlint import java.nio.file.{Path, Paths} import com.codacy.plugins.api.results.{Pattern, Result, Tool} -import com.codacy.plugins.api.{ErrorMessage, Options, Source} +import com.codacy.plugins.api.{Options, Source} import com.codacy.tools.scala.seed.utils.{CommandRunner, FileHelper} import com.codacy.tools.scala.seed.utils.ToolHelper._ import play.api.libs.json._ import better.files._ -import com.codacy.plugins.api.results.Result.FileError import scala.util.{Failure, Properties, Success, Try} @@ -103,24 +102,14 @@ object SwiftLint extends Tool { options: Map[Options.Key, Options.Value] )(implicit specification: Tool.Specification): Try[List[Result]] = { Try { - val filesToLint = listOfFilesToLint(files, source) val cfgOpt = configsFromCodacyConfiguration(configuration) val command: List[String] = commandToRun(cfgOpt, filesToLint) - runToolCommand(command, source, cfgOpt) match { - case Success(res) => res - case Failure(exception) => - List( - FileError( - Source.File(source.path), - Some(ErrorMessage(s"Failed to analyse source ${source.path}: ${exception.getMessage}")) - ) - ) - } - } + runToolCommand(command, source, cfgOpt) + }.flatten } private def writeConfigFile(patternsToLint: List[Pattern.Definition]): Path = { From 82af191420b8579be9d31ef8bf30324e8e1cea8a Mon Sep 17 00:00:00 2001 From: Lorenzo Gabriele Date: Tue, 17 Feb 2026 11:29:17 +0100 Subject: [PATCH 3/3] fix: remove scala file --- docs/tests/scriptFile.scala | 1 - 1 file changed, 1 deletion(-) delete mode 100644 docs/tests/scriptFile.scala diff --git a/docs/tests/scriptFile.scala b/docs/tests/scriptFile.scala deleted file mode 100644 index 6ce71f7..0000000 --- a/docs/tests/scriptFile.scala +++ /dev/null @@ -1 +0,0 @@ -closure_end_indentation \ No newline at end of file