Skip to content

Commit

Permalink
Improve gradleParser
Browse files Browse the repository at this point in the history
  • Loading branch information
fthomas committed Jan 10, 2025
1 parent d24afc7 commit 094188a
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 55 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
package org.scalasteward.core.buildtool.gradle

import better.files.File
import cats.MonadThrow
import cats.Monad
import cats.syntax.all.*
import org.scalasteward.core.buildtool.{BuildRoot, BuildToolAlg}
import org.scalasteward.core.data.Scope.Dependencies
Expand All @@ -29,7 +29,7 @@ final class GradleAlg[F[_]](defaultResolver: Resolver)(implicit
fileAlg: FileAlg[F],
override protected val logger: Logger[F],
workspaceAlg: WorkspaceAlg[F],
F: MonadThrow[F]
F: Monad[F]
) extends BuildToolAlg[F] {
override def name: String = "Gradle"

Expand All @@ -40,7 +40,7 @@ final class GradleAlg[F[_]](defaultResolver: Resolver)(implicit
libsVersionsToml(buildRoot)
.flatMap(fileAlg.readFile)
.map(_.getOrElse(""))
.flatMap(s => F.fromTry(gradleParser.parseDependenciesAndPlugins(s)))
.map(gradleParser.parseDependenciesAndPlugins)
.map { case (dependencies, plugins) =>
val ds = Option.when(dependencies.nonEmpty)(Scope(dependencies, List(defaultResolver)))
val ps = Option.when(plugins.nonEmpty)(Scope(plugins, List(GradleAlg.pluginsResolver)))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,23 +20,21 @@ import cats.implicits.*
import org.scalasteward.core.data.{ArtifactId, Dependency, GroupId, Version}
import org.tomlj.{Toml, TomlTable}
import scala.jdk.CollectionConverters.*
import scala.util.Try

object gradleParser {
def parseDependenciesAndPlugins(s: String): Try[(List[Dependency], List[Dependency])] =
Try {
val parsed = Toml.parse(s)
val versionsTable = parsed.getTableOrEmpty(key.versions)
val librariesTable = parsed.getTableOrEmpty(key.libraries)
val pluginsTable = parsed.getTableOrEmpty(key.plugins)
def parseDependenciesAndPlugins(s: String): (List[Dependency], List[Dependency]) = {
val parsed = Toml.parse(s)
val versionsTable = parsed.getTableOrEmpty("versions")
val librariesTable = parsed.getTableOrEmpty("libraries")
val pluginsTable = parsed.getTableOrEmpty("plugins")

val dependencies = parseEntries(librariesTable, parseDependency(_, versionsTable))
val plugins = parseEntries(pluginsTable, parsePlugin(_, versionsTable))
val dependencies = collectEntries(librariesTable, parseDependency(_, versionsTable))
val plugins = collectEntries(pluginsTable, parsePlugin(_, versionsTable))

(dependencies, plugins)
}
(dependencies, plugins)
}

private def parseEntries(table: TomlTable, f: TomlTable => Option[Dependency]): List[Dependency] =
private def collectEntries[A: Ordering](table: TomlTable, f: TomlTable => Option[A]): List[A] =
table
.entrySet()
.asScala
Expand All @@ -50,49 +48,41 @@ object gradleParser {

private def parseDependency(lib: TomlTable, versions: TomlTable): Option[Dependency] =
parseVersion(lib, versions).flatMap { version =>
if (lib.contains(key.module)) {
val module = lib.getString(key.module)
module.split(':') match {
case Array(g, a) =>
val groupId = GroupId(g)
val artifactId = ArtifactId(a)
Some(Dependency(groupId, artifactId, version))
case _ => None
}
} else if (lib.contains(key.group)) {
val groupId = GroupId(lib.getString(key.group))
val artifactId = ArtifactId(lib.getString(key.name))
Some(Dependency(groupId, artifactId, version))
} else None
parseSimpleLib(lib, version).orElse(parseModuleLib(lib, version))
}

private def parsePlugin(plugin: TomlTable, versions: TomlTable): Option[Dependency] =
parseVersion(plugin, versions).flatMap { version =>
Option.when(plugin.contains(key.id)) {
val groupId = GroupId(plugin.getString(key.id))
val artifactId = ArtifactId(groupId.value + ".gradle.plugin")
Dependency(groupId, artifactId, version)
private def parseSimpleLib(lib: TomlTable, version: Version): Option[Dependency] =
for {
groupId <- getStringSafe(lib, "group").map(GroupId(_))
artifactId <- getStringSafe(lib, "name").map(ArtifactId(_))
} yield Dependency(groupId, artifactId, version)

private def parseModuleLib(lib: TomlTable, version: Version): Option[Dependency] =
for {
module <- getStringSafe(lib, "module")
(groupId, artifactId) <- module.split(':') match {
case Array(g, a) => Some((GroupId(g), ArtifactId(a)))
case _ => None
}
}
} yield Dependency(groupId, artifactId, version)

private def parsePlugin(plugin: TomlTable, versions: TomlTable): Option[Dependency] =
for {
id <- getStringSafe(plugin, "id")
groupId = GroupId(id)
artifactId = ArtifactId(s"$id.gradle.plugin")
version <- parseVersion(plugin, versions)
} yield Dependency(groupId, artifactId, version)

private def parseVersion(table: TomlTable, versions: TomlTable): Option[Version] =
if (table.isTable(key.version) && table.contains(key.versionRef)) {
val ref = table.getString(key.versionRef)
Option.when(versions.isString(ref))(Version(versions.getString(ref)))
} else if (table.isString(key.version))
Some(Version(table.getString(key.version)))
else
None
parseVersionString(table).orElse(parseVersionRef(table, versions)).map(Version.apply)

object key {
val group = "group"
val id = "id"
val libraries = "libraries"
val module = "module"
val name = "name"
val plugins = "plugins"
val version = "version"
val versions = "versions"
val versionRef = "version.ref"
}
private def parseVersionString(table: TomlTable): Option[String] =
getStringSafe(table, "version")

private def parseVersionRef(table: TomlTable, versions: TomlTable): Option[String] =
getStringSafe(table, "version.ref").flatMap(ref => getStringSafe(versions, ref))

private def getStringSafe(table: TomlTable, key: String): Option[String] =
Option.when(table.contains(key) && table.isString(key))(table.getString(key))
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class gradleParserTest extends FunSuite {
|[plugins]
|versions = { id = "com.github.ben-manes.versions", version = "0.45.0" }
|""".stripMargin
val obtained = gradleParser.parseDependenciesAndPlugins(input).get
val obtained = gradleParser.parseDependenciesAndPlugins(input)
val expected = (
List(
"org.codehaus.groovy".g % "groovy".a % "3.0.5",
Expand Down

0 comments on commit 094188a

Please sign in to comment.