Skip to content

Instantly share code, notes, and snippets.

@er1c
Created December 28, 2021 18:40
Show Gist options
  • Select an option

  • Save er1c/f149b74673e4a1e2120c7f5b06483e91 to your computer and use it in GitHub Desktop.

Select an option

Save er1c/f149b74673e4a1e2120c7f5b06483e91 to your computer and use it in GitHub Desktop.

Revisions

  1. er1c created this gist Dec 28, 2021.
    153 changes: 153 additions & 0 deletions build.sbt
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,153 @@
    import coursier.cache.{Cache, CacheLogger, CachePolicy, CacheUrl}
    import coursier.util.Task
    import coursier.core.{Authentication, Module, Repository}
    import coursier.maven.MavenRepository
    import java.net.MalformedURLException
    import lmcoursier.definitions.{CachePolicy => LMCachePolicy, Module => LMModule}
    import lmcoursier.credentials.{Credentials => LMCredentials, DirectCredentials => LMDirectCredentials, FileCredentials => LMFileCredentials}
    import lmcoursier.{CoursierConfiguration, FromSbt}
    import sbt.util.Logger

    enablePlugins(SbtPlugin)

    scalaVersion := "2.12.15"

    val s3PluginVersion =
    Option(System.getProperty("plugin.version")) getOrElse {
    throw new RuntimeException("The system property 'plugin.version' is not defined. Specify this property using the scriptedLaunchOpts -D.")
    }

    val s3Plugin = "com.frugalmechanic" %% "fm-sbt-s3-resolver-coursier-handler" % s3PluginVersion

    resolvers += "Custom Releases" at "s3://maven.custom/releases/"
    csrConfiguration := csrConfiguration.value.withProtocolHandlerDependencies(Seq(s3Plugin))

    libraryDependencies ++= Seq(
    s3Plugin % Test // we use the Test / testLoader to sneak it into coursier
    )

    def listVersions(cache: Cache[Task], repositories: Seq[Repository], mod: Module): Set[String] = {
    repositories.foldLeft(Set.empty[String])((acc, r) => acc ++ listVersions(cache, r, mod))
    }

    def listVersions(cache: Cache[Task], repo: Repository, mod: Module): Set[String] = {
    val logger = cache.loggerOpt.getOrElse(CacheLogger.nop)
    val t = for {
    _ <- Task.delay(logger.init())
    a <- repo.versions(mod, cache.fetch).run.attempt
    _ <- Task.delay(logger.stop())
    res <- Task.fromEither(a)
    } yield res

    t.unsafeRun()(cache.ec) match {
    case Left(err) =>
    // FIXME Trapped error
    Set.empty
    case Right((v, _)) =>
    v.available.toSet
    }
    }

    TaskKey[Unit]("check") := {
    val conf: CoursierConfiguration = csrConfiguration.value

    val cache = coursier.cache.FileCache[Task]()
    .withLocation(csrCacheDirectory.value)
    .withCachePolicies(conf.cachePolicies.map(toCoursier))
    .withTtl(conf.ttl)
    .withChecksums(conf.checksums)
    .withCredentials(conf.credentials.map(toCoursier))
    .withFollowHttpToHttpsRedirections(conf.followHttpToHttpsRedirections.getOrElse(true))

    val s3Resolver: sbt.librarymanagement.MavenRepository = "Custom Releases" at "s3://maven.custom/releases/"

    val s3Respository: Option[MavenRepository] = getMavenRepository(
    s3Resolver.root,
    streams.value.log,
    None,
    Seq((Test / testLoader).value)
    )
    assert(s3Respository.isDefined, "s3Respository is None")

    // sbtPluginExtra(
    // m = "com.untyped" % "sbt-less" % "0.4", // Plugin module name and version
    // sbtV = "0.11.3", // SBT version
    // scalaV = "2.9.1" // Scala version compiled the plugin
    //)

    //val sbtModule = Defaults.sbtPluginExtra("com.example" % "cross-platform-example" % "0.1.0", "1.0", "2.12")
    val sbtModule = Defaults.sbtPluginExtra("com.example" % "sbt-plugin-example" % "0.1.0", "1.0", "2.12")

    val (csModule, _) = FromSbt.moduleVersion(sbtModule, scalaVersion.value, scalaBinaryVersion.value)

    println(s"sbtModule: ${sbtModule.extraAttributes}, csModule.attributes: ${csModule.attributes}")
    val versions = listVersions(
    cache,
    s3Respository.get,
    toCoursier(csModule)
    )
    assert(versions == Set("0.1.0"), s"$versions != List(0.1.0)")
    }

    def getMavenRepository(
    root: String,
    log: Logger,
    authentication: Option[Authentication],
    classLoaders: Seq[ClassLoader]
    ): Option[MavenRepository] =
    try {
    CacheUrl.url(root, classLoaders) // ensure root is a URL whose protocol can be handled here
    val root0 = if (root.endsWith("/")) root else root + "/"
    Some(
    coursier.maven.MavenRepository(
    root0,
    authentication = authentication
    )
    )
    } catch {
    case e: MalformedURLException =>
    log.warn(
    "Error parsing Maven repository base " +
    root +
    Option(e.getMessage).fold("")(" (" + _ + ")") +
    ", ignoring it"
    )

    None
    }


    def toCoursier(module: LMModule): coursier.core.Module = {
    coursier.core.Module(
    coursier.core.Organization(module.organization.value),
    coursier.core.ModuleName(module.name.value),
    module.attributes
    )
    }

    def toCoursier(policy: LMCachePolicy): CachePolicy = policy match {
    case LMCachePolicy.LocalOnly => CachePolicy.LocalOnly
    case LMCachePolicy.LocalOnlyIfValid => CachePolicy.LocalOnlyIfValid
    case LMCachePolicy.LocalUpdateChanging => CachePolicy.LocalUpdateChanging
    case LMCachePolicy.LocalUpdate => CachePolicy.LocalUpdate
    case LMCachePolicy.UpdateChanging => CachePolicy.UpdateChanging
    case LMCachePolicy.Update => CachePolicy.Update
    case LMCachePolicy.FetchMissing => CachePolicy.FetchMissing
    case LMCachePolicy.ForceDownload => CachePolicy.ForceDownload
    }

    def toCoursier(credentials: LMCredentials): coursier.credentials.Credentials =
    credentials match {
    case d: LMDirectCredentials =>
    coursier.credentials.DirectCredentials()
    .withHost(d.host)
    .withUsername(d.username)
    .withPassword(d.password)
    .withRealm(d.realm)
    .withOptional(d.optional)
    .withMatchHost(d.matchHost)
    .withHttpsOnly(d.httpsOnly)
    case f: LMFileCredentials =>
    coursier.credentials.FileCredentials(f.path)
    .withOptional(f.optional)
    }