in util-app/src/main/scala/com/twitter/app/Flags.scala [116:206]
private[this] def hasFlag(f: String) = resolveFlag(f).isDefined
private[this] def flag(f: String) = resolveFlag(f).get
/**
* Parse an array of flag strings.
*
* @param args The array of strings to parse.
* @param allowUndefinedFlags If true, undefined flags (i.e. those that are
* not defined in the application via a `flag.apply` invocation) are allowed.
* If false, undefined flags will result in a FlagParseException being thrown.
* @return A [[com.twitter.app.Flags.FlagParseResult]] representing the
* result of parsing `args`.
*/
def parseArgs(args: Array[String], allowUndefinedFlags: Boolean = false): FlagParseResult =
synchronized {
reset()
val remaining = new ArrayBuffer[String]
val errors = new ArrayBuffer[Error]
var i = 0
while (i < args.length) {
val a = args(i)
i += 1
if (a == "--") {
remaining ++= args.slice(i, args.length)
i = args.length
} else if (a startsWith "-") {
a drop 1 split ("=", 2) match {
// There seems to be a bug Scala's pattern matching
// optimizer that leaves `v' dangling in the last case if
// we make this a wildcard (Array(k, _@_*))
case Array(k) if !hasFlag(k) =>
if (allowUndefinedFlags)
remaining += a
else
errors += Error(
"Error parsing flag \"%s\": %s".format(k, FlagUndefinedMessage)
)
// Flag isn't defined
case Array(k, _) if !hasFlag(k) =>
if (allowUndefinedFlags)
remaining += a
else
errors += Error(
"Error parsing flag \"%s\": %s".format(k, FlagUndefinedMessage)
)
// Optional argument without a value
case Array(k) if flag(k).noArgumentOk =>
flag(k).parse()
// Mandatory argument without a value and with no more arguments.
case Array(k) if i == args.length =>
errors += Error(
"Error parsing flag \"%s\": %s".format(k, FlagValueRequiredMessage)
)
// Mandatory argument with another argument
case Array(k) =>
i += 1
try flag(k).parse(args(i - 1))
catch {
case NonFatal(e) =>
errors += Error(
"Error parsing flag \"%s\": %s".format(k, e.getMessage)
)
}
// Mandatory k=v
case Array(k, v) =>
try flag(k).parse(v)
catch {
case NonFatal(e) =>
errors += Error(
"Error parsing flag \"%s\": %s".format(k, e.getMessage)
)
}
}
} else {
remaining += a
}
}
finishParsing()
if (helpFlag())
Help(usage)
else if (errors.nonEmpty)
Error(s"Error parsing flags: ${errors.mkString("[\n ", ",\n ", "\n]")}\n\n$usage")
else
Ok(remaining.toSeq)
}