org.pantsbuild.zinc.options.OptionSet.scala Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of zinc-options_2.11 Show documentation
Show all versions of zinc-options_2.11 Show documentation
The SBT incremental compiler for nailgun
The newest version!
/**
* Copyright (C) 2017 Pants project contributors (see CONTRIBUTORS.md).
* Licensed under the Apache License, Version 2.0 (see LICENSE).
*/
package org.pantsbuild.zinc.options
import java.io.File
///
/// TODO Remove uses of this in favor of scopt
/// A reference way to do this is described in #6487
///
trait OptionSet[T] {
/** An empty set of options. */
def empty: T
/** Apply any residual entries to an instance of T and return a new T. */
def applyResidual(t: T, residualArgs: Seq[String]): T =
if (residualArgs.nonEmpty) {
throw new RuntimeException(
s"Unexpected residual arguments: ${residualArgs.mkString("[", ", ", "]")}"
)
} else {
t
}
/** All available command-line options. */
def options: Seq[OptionDef[T]]
private def allOptions: Set[OptionDef[T]] = options.toSet
/**
* Print out the usage message.
*/
def printUsage(cmdName: String, residualArgs: String = ""): Unit = {
val column = options.map(_.length).max + 2
println(s"Usage: ${cmdName} ${residualArgs}")
options foreach { opt => if (opt.extraline) println(); println(opt.usage(column)) }
println()
}
/**
* Anything starting with '-' is considered an option, not a source file.
*/
private def isOpt(s: String) = s startsWith "-"
/**
* Parse all args into a T.
* Residual args are either unknown options or applied.
*/
def parse(args: Seq[String]): Parsed[T] = {
val Parsed(instance, remaining, errors) = Options.parse(empty, allOptions, args, stopOnError = false)
val (unknown, residual) = remaining partition isOpt
val unknownErrors = unknown map ("Unknown option: " + _)
Parsed(applyResidual(instance, residual), Seq.empty, errors ++ unknownErrors)
}
// helpers for creating options
def boolean(opt: String, desc: String, action: T => T) = new BooleanOption[T](Seq(opt), desc, action)
def boolean(opts: (String, String), desc: String, action: T => T) = new BooleanOption[T](Seq(opts._1, opts._2), desc, action)
def string(opt: String, arg: String, desc: String, action: (T, String) => T) = new StringOption[T](Seq(opt), arg, desc, action)
def int(opt: String, arg: String, desc: String, action: (T, Int) => T) = new IntOption[T](Seq(opt), arg, desc, action)
def long(opt: String, arg: String, desc: String, action: (T, Long) => T) = new LongOption[T](Seq(opt), arg, desc, action)
def double(opt: String, arg: String, desc: String, action: (T, Double) => T) = new DoubleOption[T](Seq(opt), arg, desc, action)
def fraction(opt: String, arg: String, desc: String, action: (T, Double) => T) = new FractionOption[T](Seq(opt), arg, desc, action)
def file(opt: String, arg: String, desc: String, action: (T, File) => T) = new FileOption[T](Seq(opt), arg, desc, action)
def path(opt: String, arg: String, desc: String, action: (T, Seq[File]) => T) = new PathOption[T](Seq(opt), arg, desc, action)
def path(opts: (String, String), arg: String, desc: String, action: (T, Seq[File]) => T) = new PathOption[T](Seq(opts._1, opts._2), arg, desc, action)
def prefix(pre: String, arg: String, desc: String, action: (T, String) => T) = new PrefixOption[T](pre, arg, desc, action)
def filePair(opt: String, arg: String, desc: String, action: (T, (File, File)) => T) = new FilePairOption[T](Seq(opt), arg, desc, action)
def fileMap(opt: String, desc: String, action: (T, Map[File, File]) => T) = new FileMapOption[T](Seq(opt), desc, action)
def fileSeqMap(opt: String, desc: String, action: (T, Map[Seq[File], File]) => T) = new FileSeqMapOption[T](Seq(opt), desc, action)
def header(label: String) = new HeaderOption[T](label)
def dummy(opt: String, desc: String) = new DummyOption[T](opt, desc)
}