summaryrefslogblamecommitdiff
path: root/contrib/tut/src/TutModule.scala
blob: e51a8d7b03c41ca27bc1cb070f0157fde62eb6c5 (plain) (tree)
1
2
3


                   
















































                                                                                                                                                                                                            
                                                         






























































                                                                                                                                                                                                       
                                    





                                                                                               
            



                                                                                                  
                          

   
package mill
package contrib.tut

import coursier.MavenRepository
import mill.scalalib._
import scala.util.matching.Regex

/**
  * Tut is a documentation tool which compiles and evaluates Scala code in documentation files and provides various options for configuring how the results will be displayed in the compiled documentation.
  *
  * Extending this trait declares a Scala module which compiles markdown, HTML and `.txt` files in the `tut` folder of the module with Tut.
  *
  * By default the resulting documents are simply placed in the Mill build output folder but they can be placed elsewhere by overriding the [[mill.contrib.tut.TutModule#tutTargetDirectory]] task.
  *
  * For example:
  *
  * {{{
  * // build.sc
  * import mill._, scalalib._, contrib.tut.__
  *
  * object example extends TutModule {
  *   def scalaVersion = "2.12.6"
  *   def tutVersion = "0.6.7"
  * }
  * }}}
  *
  * This defines a project with the following layout:
  *
  * {{{
  * build.sc
  * example/
  *     src/
  *     tut/
  *     resources/
  * }}}
  *
  * In order to compile documentation we can execute the `tut` task in the module:
  *
  * {{{
  * sh> mill example.tut
  * }}}
  */
trait TutModule extends ScalaModule {
  /**
    * This task determines where documentation files must be placed in order to be compiled with Tut. By default this is the `tut` folder at the root of the module.
    */
  def tutSourceDirectory = T.sources { millSourcePath / 'tut }

  /**
    * A task which determines where the compiled documentation files will be placed. By default this is simply the Mill build's output folder for this task,
    * but this can be reconfigured so that documentation goes to the root of the module (e.g. `millSourcePath`) or to a dedicated folder (e.g. `millSourcePath / 'docs`)
    */
  def tutTargetDirectory: T[os.Path] = T { T.ctx().dest }

  /**
    * A task which determines what classpath is used when compiling documentation. By default this is configured to use the same inputs as the [[mill.contrib.tut.TutModule#runClasspath]],
    * except for using [[mill.contrib.tut.TutModule#tutIvyDeps]] rather than the module's [[mill.contrib.tut.TutModule#runIvyDeps]].
    */
  def tutClasspath: T[Agg[PathRef]] = T {
    // Same as runClasspath but with tut added to ivyDeps from the start
    // This prevents duplicate, differently versioned copies of scala-library ending up on the classpath which can happen when resolving separately
    transitiveLocalClasspath() ++
    resources() ++
    localClasspath() ++
    unmanagedClasspath() ++
    tutIvyDeps()
  }

  /**
    * A task which determines the scalac plugins which will be used when compiling code examples with Tut. The default is to use the [[mill.contrib.tut.TutModule#scalacPluginIvyDeps]] for the module.
    */
  def tutScalacPluginIvyDeps: T[Agg[Dep]] = scalacPluginIvyDeps()

  /**
    * A [[scala.util.matching.Regex]] task which will be used to determine which files should be compiled with tut. The default pattern is as follows: `.*\.(md|markdown|txt|htm|html)`.
    */
  def tutNameFilter: T[Regex] = T { """.*\.(md|markdown|txt|htm|html)""".r }

  /**
    * The scalac options which will be used when compiling code examples with Tut. The default is to use the [[mill.contrib.tut.TutModule#scalacOptions]] for the module,
    * but filtering out options which are problematic in the REPL, e.g. `-Xfatal-warnings`, `-Ywarn-unused-imports`.
    */
  def tutScalacOptions: T[Seq[String]] =
    scalacOptions().filterNot(Set(
      "-Ywarn-unused:imports",
      "-Ywarn-unused-import",
      "-Ywarn-dead-code",
      "-Xfatal-warnings"
    ))

  /**
    * The version of Tut to use.
    */
  def tutVersion: T[String]

  /**
    * A task which determines how to fetch the Tut jar file and all of the dependencies required to compile documentation for the module and returns the resulting files.
    */
  def tutIvyDeps: T[Agg[PathRef]] = T {
    Lib.resolveDependencies(
      repositories :+ MavenRepository(s"https://dl.bintray.com/tpolecat/maven"),
      Lib.depToDependency(_, scalaVersion()),
      compileIvyDeps() ++ transitiveIvyDeps() ++ Seq(
        ivy"org.tpolecat::tut-core:${tutVersion()}"
      )
    )
  }

  /**
    * A task which performs the dependency resolution for the scalac plugins to be used with Tut.
    */
  def tutPluginJars: T[Agg[PathRef]] = resolveDeps(tutScalacPluginIvyDeps)()

  /**
    * Run Tut using the configuration specified in this module. The working directory used is the [[mill.contrib.tut.TutModule#millSourcePath]].
    */
  def tut: T[os.CommandResult] = T {
    val in = tutSourceDirectory().head.path.toIO.getAbsolutePath
    val out = tutTargetDirectory().toIO.getAbsolutePath
    val re = tutNameFilter()
    val opts = tutScalacOptions()
    val pOpts = tutPluginJars().map(pathRef => "-Xplugin:" + pathRef.path.toIO.getAbsolutePath)
    val tutArgs = List(in, out, re.pattern.toString) ++ opts ++ pOpts
    os.proc(
      'java,
      "-cp", tutClasspath().map(_.path.toIO.getAbsolutePath).mkString(java.io.File.pathSeparator),
      "tut.TutMain",
      tutArgs
    ).call(millSourcePath)
  }
}