3

I have a base Config case class which is used as a common part of the Configs of several different scripts. I'd like to be able to stop copy-pasting code for OptionParsers which parse this base Config (e.g. every single script needs --cluster and --port so I'd like a single base OptionParser to always take care of that), and let a minimal custom OptionParser take care of the options that are unique to each script (e.g. --asdf).

The problem is that if I ask the base parser to parse arguments containing --asdf, Scopt complains:

[error] Error: Unknown option --asdf
[error] Usage: Config [options]
[error]
[error]   -c <value> | --cluster <value>
[error]         Cluster the machine is part of
[error]   -p <value> | --port <value>
[error]         Port to listen on
...
[error] Exception in thread "main" java.util.NoSuchElementException: None.get

Is there a way to get it to ignore unknown arguments?

wrongusername
  • 18,564
  • 40
  • 130
  • 214

2 Answers2

10

When defining the custom OptionParser, simply put an extra

override def errorOnUnknownArgument = false

into the definition. For example,

def optionParser = new OptionParser[CustomConfig]("Config") {
    override def errorOnUnknownArgument = false

    opt[String]('a', "asdf") optional () action { (x, c) =>
      c.copy(asdf = x)
    } text "Do something custom"
    ...
  }
wrongusername
  • 18,564
  • 40
  • 130
  • 214
  • 1
    There is also a reportWarning method that you can override to get rid of the warnings that are still output; e.g. `override def reportWarning(msg: String): Unit = {}`. This will of course suppress any other warnings that might be generated. – Eric Pohl Sep 05 '18 at 13:47
1

Just in case you are using OParser

// define a setup
val setup: OParserSetup = new DefaultOParserSetup {
  override def errorOnUnknownArgument: Boolean = false
}
// then pass setup to parse function
OParser.parse(parser, args, YourConfig(), setup)
John Joker
  • 72
  • 6