All Downloads are FREE. Search and download functionalities are using the official Maven repository.

scala.coursier.maven.MavenComplete.scala Maven / Gradle / Ivy

There is a newer version: 2.1.13
Show newest version
package coursier.maven

import coursier.core.{Module, Organization, Repository}
import coursier.util.Monad
import dataclass.data

@data class MavenComplete[F[_]](
  repo: MavenRepositoryLike,
  fetch: Repository.Fetch[F],
  F: Monad[F]
) extends Repository.Complete[F] {

  private def fromDirListing(dirUrl: String, prefix: String): F[Either[Throwable, Seq[String]]] =
    F.map(fetch(repo.artifactFor(dirUrl + ".links", changing = true)).run) {
      case Left(e) =>
        Left(new Exception(e))
      case Right(rawLinks) =>
        val entries = MavenComplete.split0(rawLinks, '\n', prefix)
        Right(entries)
    }

  def organization(prefix: String): F[Either[Throwable, Seq[String]]] = {

    val idx = prefix.lastIndexOf('.')
    val (base, dir, prefix0) =
      if (idx < 0)
        ("", Nil, prefix)
      else
        (prefix.take(idx + 1), prefix.take(idx).split('.').toSeq, prefix.drop(idx + 1))

    val dirUrl = repo.urlFor(dir, isDir = true)

    F.map(fromDirListing(dirUrl, prefix0))(_.map(_.map(base + _)))
  }
  def moduleName(organization: Organization, prefix: String): F[Either[Throwable, Seq[String]]] = {

    val dir    = organization.value.split('.').toSeq
    val dirUrl = repo.urlFor(dir, isDir = true)

    fromDirListing(dirUrl, prefix)
  }

  override protected def moduleDirectory(module: Module): String =
    repo.moduleDirectory(module)

  def versions(module: Module, prefix: String): F[Either[Throwable, Seq[String]]] =
    F.map(repo.versions(module, fetch)(F).run) {
      case Left(e) =>
        Left(new Exception(e))
      case Right((v, _)) =>
        Right(v.available.filter(_.startsWith(prefix)))
    }
}

object MavenComplete {

  private[coursier] def split0(s: String, sep: Char, prefix: String): Vector[String] = {

    var idx = 0
    val b   = Vector.newBuilder[String]

    while (idx < s.length) {
      var nextIdx = idx
      while (nextIdx < s.length && s.charAt(nextIdx) != sep)
        nextIdx += 1
      val matches = nextIdx - idx > prefix.length &&
        s.regionMatches(idx, prefix, 0, prefix.length) &&
        s.charAt(nextIdx - 1) == '/'
      if (matches)
        b += s.substring(idx, nextIdx - 1)
      idx = nextIdx + 1
    }

    b.result()
  }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy