build.sc
author Tomas Zeman <tomas@functionals.cz>
Tue, 24 Nov 2020 11:17:26 +0100
changeset 31 5c4364d6e726
parent 30 12cda49d6c84
child 32 2d14f02ba3bd
permissions -rw-r--r--
SQWL#2003 Studie -> Projekt

import ammonite.ops._
import mill._
import mill.api.Loose
import mill.define.{Input, Sources, Target}
import mill.scalajslib._
import mill.scalalib._
import mill.scalalib.publish._

val appVersion = "20.12-SNAPSHOT"

val scalaJsVer = "0.6.33"
val scalaVer = "2.12.12"
val akkaVer = "2.6.10"
val akkaHttp = "10.2.1"

trait Common extends ScalaModule with PublishModule {
  val scalaVersion = scalaVer

  def publishVersion: Target[String] = appVersion

  def pomSettings = PomSettings(
    description = "Content management system for SQWL",
    organization = "cz.functionals",
    url = "http://kvalitapracovnihozivota.vubp.cz",
    licenses = Seq(License.`Apache-2.0`),
    versionControl = VersionControl(developerConnection = Some(
      "ssh://tzeman@hg.functionals.cz/repos/public/sqwl-cms")),
    developers = Seq(
      Developer("tzeman", "Tomas Zeman", "")
    )
  )

  override def artifactName: Target[String] = T{
    super.artifactName().flatMap(c =>
      if (c.isUpper) Seq('-', c.toLower) else Seq(c)).mkString
  }

  override def scalacOptions = T{Seq(
    "-deprecation",                      // Emit warning and location for usages of deprecated APIs.
    "-encoding", "utf-8",                // Specify character encoding used by source files.
    "-explaintypes",                     // Explain type errors in more detail.
    "-feature",                          // Emit warning and location for usages of features that should be imported explicitly.
    "-language:higherKinds",             // Allow higher-kinded types
    "-language:implicitConversions",     // Allow definition of implicit functions called views
    "-language:reflectiveCalls",
    "-language:postfixOps",
    "-unchecked",                        // Enable additional warnings where generated code depends on assumptions.
    "-Xcheckinit",                       // Wrap field accessors to throw an exception on uninitialized access.
    "-Xfuture",                          // Turn on future language features.
    "-target:jvm-1.8"
  )}

  def hgId: Input[String] = T.input {
    os.proc("hg", "id", "-i").call().out.trim
  }

  def hgNum: Input[String] = T.input {
    os.proc("hg", "id", "-n").call().out.trim
  }

  def hgTag: Input[Option[String]] = T.input {
    os.proc("hg", "id", "-t").call().out.trim.split(' ').headOption
  }

}

trait Versions {
  //val bootstrap = "4.1.3"
  val bootstrap = "3.3.7"
  val fontAwesome = "5.5.0"
  val jquery = "3.3.1-1"
}

object base extends Common with Versions {
  override def scalacPluginIvyDeps: Target[Loose.Agg[Dep]] =
    super.scalacPluginIvyDeps() ++ Agg(
      ivy"org.scalamacros:::paradise:2.1.1"
    )

  override def ivyDeps = Agg(
    ivy"com.wacai::config-annotation:0.3.6",
    ivy"com.typesafe.akka::akka-http:$akkaHttp",
    ivy"com.typesafe.akka::akka-slf4j:$akkaVer",
    ivy"com.typesafe.akka::akka-stream:$akkaVer",
    ivy"org.json4s::json4s-native:3.6.2",
    ivy"ch.qos.logback:logback-classic:1.2.3",
    ivy"com.lihaoyi::scalatags:0.6.7",
    ivy"org.webjars:bootstrap:$bootstrap",
    ivy"org.webjars:font-awesome:$fontAwesome",
    ivy"org.webjars:jquery:$jquery",
    ivy"com.lihaoyi::scalatex-api:0.3.12"
  )

  override def scalacOptions = T{super.scalacOptions.map(_ :+
    "-Xmacro-settings:conf.output.dir=base/resources"
  )}

  override def generatedSources: Target[Seq[PathRef]] = T{
    val dir = T.ctx().dest
    write(dir / "buildInfo.scala",
      s"""
        | package sqwl.cms
        | object BuildInfo {
        |   object versions {
        |     val bootstrap = "$bootstrap"
        |     val fontAwesome = "$fontAwesome"
        |     val jquery = "$jquery"
        |   }
        |
        |   val hgId = "${hgId()}"
        | }
      """.stripMargin)
    Seq(PathRef(dir))
  }

}

trait Content extends Common {

  override def moduleDeps = Seq(base)

  def contentSources: Sources

  override def generatedSources: Target[Seq[PathRef]] = T{
    val dir = T.ctx().dest
    val src = contentSources() map(_.path)
    val ids = src flatMap(ls! _ filter(_.ext endsWith "scalatex") map { p =>
      val id = p.last replaceAllLiterally (".scalatex", "")
      val aid = s"article-$id"
      write(dir / s"$id.scala",
        s"""
          | package sqwl.cms
          | import scalatags.Text.all._
          | import scalatex._
          | import sqwl.cms.Category._
          | import sqwl.cms.Tag._
          | import sqwl.cms.Articles.article
          | object `$aid` {
          |   implicit val id = Articles.Id("$id")
          |   twf("${p.toString}")
          | }
          |
          |/*
          |${os.read(p)}
          |*/
        """.stripMargin)
      aid
    })

    write(dir / "initializer.scala",
      s"""
        | package sqwl.cms
        | object InitializeContent {
        |   def apply(): Unit = {
        |     Seq(${ids mkString("`", "`, `", "`")})
        |   }
        | }
      """.stripMargin)

    write(dir / "main.scala",
      """
        | package sqwl.cms
        | object Main extends Server {
        |   override def content: iContent = Content
        | }
      """.stripMargin)

    Seq(PathRef(dir))
  }

  override def mainClass: T[Option[String]] = Some("sqwl.cms.Main")

  override def ivyDeps = Agg(
    ivy"com.beachape::enumeratum:1.5.13"
  )

  def assemblyName: Target[String] = T{
    val tg = hgTag().map(v => s"-${v.replace(".patch", "")}") getOrElse ""
    val ver = publishVersion().replace("SNAPSHOT", s"${hgNum()}-${hgId()}$tg")
    s"cms-$ver"
  }

  override def assembly: Target[PathRef] = T{
    val out = T.ctx().dest / s"${assemblyName()}.jar"
    os.move(super.assembly().path, out)
    PathRef(out)
  }

}

object example extends Content {
  def contentSources: Sources =
    T.sources{ millSourcePath / up / 'example / 'content }
}

object production extends Content {
  def contentSources: Sources =
    T.sources{ millSourcePath / up / 'production / 'content }

  def hgProdId: Input[String] = T.input {
    os.proc("hg", "id", "-i", "--cwd", "production").call().out.trim
  }

  override def assemblyName: Target[String] = T{
    s"${super.assemblyName()}-${hgProdId()}"
  }
}


object js extends Common with ScalaJSModule {
  def scalaJSVersion: Target[String] = scalaJsVer
}

// vim: et ts=2 sw=2 syn=scala