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

ai.starlake.utils.CliConfig.scala Maven / Gradle / Ivy

package ai.starlake.utils

import better.files.File
import org.fusesource.scalate.TemplateEngine
import scopt.{DefaultOParserSetup, OParser, OParserSetup, OptionDef}

trait CommandConfig {
  def command: String
  def markdown(pageIndex: Int): String
}

trait CliConfig[T] extends CommandConfig {
  def parser: OParser[Unit, T]
  def usage(): String = OParser.usage(parser)
  def parse(args: Seq[String]): Option[T]
  val engine: TemplateEngine = new TemplateEngine
  def command: String

  val setup: OParserSetup = new DefaultOParserSetup {
    override def showUsageOnError: Option[Boolean] = Some(false)
  }

  def markdown(pageIndex: Int): String = {
    val optionDefs = parser.toList
    val programNameOptionDef = optionDefs.headOption
    val synopsisOptionDef = programNameOptionDef.flatMap(_ => optionDefs.drop(1).headOption)
    val descriptionOptionDef = synopsisOptionDef.flatMap(_ => optionDefs.drop(2).headOption)
    val options = descriptionOptionDef.map(_ => optionDefs.drop(3)).getOrElse(Nil)

    val programName = programNameOptionDef.map(_.desc.substring("starlake ".length)).getOrElse("")
    val synopsis = synopsisOptionDef.map(_.desc).getOrElse("")
    val rawDescription = descriptionOptionDef
      .map(_.desc)
      .getOrElse("")

    val description = {
      val indexExample = rawDescription.indexOf("example:")
      val (rawText, example) =
        if (indexExample >= 0) {
          (rawDescription.substring(0, indexExample), rawDescription.substring(indexExample))
        } else {
          (rawDescription, "")
        }
      val mdExample = example.replace("example:", "\n\n")
      val mdDescription = rawText
      if (mdExample.trim.nonEmpty)
        mdDescription + "````shell\n" + mdExample.trim + "\n````\n"
      else
        mdDescription
    }

    val mdExtraDescriptionFile =
      File(getClass.getResource("/")) / s"../../../docs/merge/cli/$programName.md"
    val extra =
      if (mdExtraDescriptionFile.exists())
        mdExtraDescriptionFile.lines().mkString("\n")
      else
        ""

    case class MarkdownOption(
      name: String,
      value: String,
      description: String,
      required: String,
      unbounded: String
    ) {
      def toMap(): Map[String, String] =
        Map(
          "name"        -> name,
          "value"       -> value,
          "description" -> description,
          "required"    -> required,
          "unbounded"   -> unbounded
        )
    }
    def option(opt: OptionDef[_, T]): MarkdownOption = {
      MarkdownOption(
        opt.name,
        opt.valueName.getOrElse(""),
        opt.desc.replaceAll("\n", "
"), if (opt.getMinOccurs > 0) "Required" else "Optional", if (opt.getMaxOccurs == Int.MaxValue) ", Unbounded" else "" ) } val templateMap = Map( "programName" -> programName, "synopsis" -> synopsis, "description" -> description, "options" -> options.map(opt => option(opt).toMap()), "index" -> (pageIndex * 10).toString, "extra" -> extra ) // TODO keep the lines below until we depreciate Scala 2.11 // We'll replace it by --> val template = Source.fromResource("templates/cli/md-cli.mustache").mkString val stream = getClass.getResourceAsStream("/templates/cli/md-cli.mustache") val template = scala.io.Source .fromInputStream(stream) .mkString engine.layout( "md-cli.mustache", engine.compileMoustache(template), templateMap ) } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy