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

com.twitter.scalding.ArgHelp.scala Maven / Gradle / Ivy

There is a newer version: 0.16.1-RC3
Show newest version
package com.twitter.scalding

sealed trait DescribedArg {
  def key: String
  def description: String
}

case class RequiredArg(key: String, description: String) extends DescribedArg
case class OptionalArg(key: String, description: String) extends DescribedArg
case class ListArg(key: String, description: String) extends DescribedArg
case class BooleanArg(key: String, description: String) extends DescribedArg

class HelpException extends RuntimeException("User asked for help")
class DescriptionValidationException(msg: String) extends RuntimeException(msg)

trait ArgHelper {
  /**
   * Similar to describe but validate all args are described
   *
   * @param describedArgs List of Argument Descriptions
   * @param ex Input Execution
   * @return Output Execution
   */
  def validatedDescribe[T](describedArgs: Seq[DescribedArg], ex: Execution[T]): Execution[T] = {
    Execution.getArgs.flatMap { args =>
      validatedDescribe(describedArgs, args)
      ex
    }
  }

  /**
   * Describe a set of Args given Descriptions and validate all Args are described
   * @param describedArgs List of Argument Descriptions
   * @param args Job Arguments
   */
  def validatedDescribe(describedArgs: Seq[DescribedArg], args: Args): Unit = {
    describe(describedArgs, args)

    val describedKeys = describedArgs.map(_.key).toSet
    val missingKeys = args.m.keySet.filter(_.nonEmpty).diff(describedKeys)

    if (missingKeys.nonEmpty) {
      val msg = missingKeys.mkString(", ")
      throw new DescriptionValidationException(s"Must describe missing keys : $msg")
    }
  }

  /**
   * Describe the Arguments of this Execution.  By running --help the args will output
   * and the execution will end
   *
   * @param describedArgs List of Argument Descriptions
   * @param ex Input Execution
   * @return Output Execution
   */
  def describe[T](describedArgs: Seq[DescribedArg], ex: Execution[T]): Execution[T] = {
    Execution.getArgs.flatMap { args =>
      describe(describedArgs, args)
      ex
    }
  }

  /**
   * Describe a set of Args given Descriptions
   *
   * @param describedArgs List of Argument Descriptions
   * @param args Job Arguments
   */
  def describe(describedArgs: Seq[DescribedArg], args: Args): Unit =
    if (args.boolean("help")) helpRequest(describedArgs)
    else ()

  def helpRequest(describedArgs: Seq[DescribedArg]): Nothing = {
    val top = "\n###########################################################################\n\n"
    val usage = s"Command Line Args :: ${argString(describedArgs)}\n\n\n"
    val bottom = "\n\n###########################################################################\n"

    println(top + usage + help(describedArgs) + bottom)

    throw new HelpException()
  }

  /**
   * Command line arg string given the Described Args
   *
   * @param describedArgs List of Argument Descriptions
   * @return Command Line Parameters
   */
  private[this] def argString(describedArgs: Seq[DescribedArg]): String = {
    describedArgs.foldLeft("") {
      case (str, describedArg) =>
        val msg = describedArg match {
          case RequiredArg(key, _) => s"--$key VALUE "
          case OptionalArg(key, _) => s"[--$key VALUE] "
          case ListArg(key, _) => s"[--$key VALUE VALUE2] "
          case BooleanArg(key, _) => s"[--$key] "
        }
        str + msg
    } + "[--help]"
  }

  /**
   * More detailed help command for these described arguments
   *
   * @param describedArgs List of Argument Descriptions
   * @return Detailed Help for the Args
   */
  private[this] def help(describedArgs: Seq[DescribedArg]): String = {
    describedArgs.foldLeft("") {
      case (str, describedArg) =>
        val msg = describedArg match {
          case RequiredArg(key, description) => s"--$key(Required) :: $description \n"
          case OptionalArg(key, description) => s"--$key(Optional) :: $description \n"
          case ListArg(key, description) => s"--$key(List) :: $description \n"
          case BooleanArg(key, description) => s"--$key(Boolean) :: $description \n"
        }
        str + msg
    } + "--help :: Show this help message."
  }
}

object ArgHelp extends ArgHelper




© 2015 - 2025 Weber Informatics LLC | Privacy Policy