diff --git a/src/main/scala/com/fulcrumgenomics/sopt/cmdline/CommandLineProgramParser.scala b/src/main/scala/com/fulcrumgenomics/sopt/cmdline/CommandLineProgramParser.scala index 546554b..0628d75 100644 --- a/src/main/scala/com/fulcrumgenomics/sopt/cmdline/CommandLineProgramParser.scala +++ b/src/main/scala/com/fulcrumgenomics/sopt/cmdline/CommandLineProgramParser.scala @@ -166,11 +166,16 @@ class CommandLineProgramParser[T](val targetClass: Class[T], val includeSpecialA */ private def parseArgs(args: Seq[String]): ParseResult = { val parser: OptionParser = new OptionParser(argFilePrefix=Some("@")) + val alternateFlagNames = scala.collection.mutable.HashMap[String, String]() try { // Add to the option parsers this.argumentLookup.ordered.filterNot(_.hidden).foreach { - case arg if arg.isFlag => parser.acceptFlag( arg.names: _*) + case arg if arg.isFlag => + parser.acceptFlag( arg.names: _*) + val noName = f"no-${arg.longName}" + parser.acceptFlag(noName) + alternateFlagNames.addOne(noName -> arg.names.head) case arg if !arg.isCollection => parser.acceptSingleValue( arg.names: _*) case arg => parser.acceptMultipleValues(arg.names: _*) } @@ -181,7 +186,16 @@ class CommandLineProgramParser[T](val targetClass: Class[T], val includeSpecialA // set the values val parseResults: Iterable[ParseResult] = parser.map { case (name: String, values: List[String]) => - this.argumentLookup.forArg(name).foreach(arg => arg.setArgument(values:_*)) + alternateFlagNames.get(name) match { + case Some(_name) => + this.argumentLookup.forArg(_name).foreach { arg => + arg.setArgument(values: _*) + arg.value = !arg.value.contains(true) + } + case None => + this.argumentLookup.forArg(name).foreach(arg => arg.setArgument(values:_*)) + } + ParseSuccess() case _ => ParseFailure(ex=new IllegalStateException("Parser returned an unexpected set of values"), parser.remaining) diff --git a/src/test/scala/com/fulcrumgenomics/sopt/cmdline/CommandLineProgramParserTest.scala b/src/test/scala/com/fulcrumgenomics/sopt/cmdline/CommandLineProgramParserTest.scala index 31d8271..be76283 100644 --- a/src/test/scala/com/fulcrumgenomics/sopt/cmdline/CommandLineProgramParserTest.scala +++ b/src/test/scala/com/fulcrumgenomics/sopt/cmdline/CommandLineProgramParserTest.scala @@ -978,12 +978,25 @@ with CommandLineParserStrings with CaptureSystemStreams with BeforeAndAfterAll { } it should "accept flags with a combination of arguments and no arguments" in { - val args = Seq[String]("--flag1", "T", "--flag2") - val p = parser(classOf[FlagClass]) - inside (p.parseAndBuild(args=args)) { case ParseSuccess() => } - val task = p.instance.get - task.flag1 shouldBe true - task.flag2 shouldBe true + Seq("T", "F").foreach { flag1Value => + val args = Seq[String]("--flag1", flag1Value, "--flag2") + val p = parser(classOf[FlagClass]) + inside(p.parseAndBuild(args = args)) { case ParseSuccess() => } + val task = p.instance.get + task.flag1 shouldBe flag1Value == "T" + task.flag2 shouldBe true + } + } + + it should "accept flags with --no-" in { + Seq("T", "F").foreach { flag1Value => + val args = Seq[String]("--no-flag1", flag1Value, "--no-flag2") + val p = parser(classOf[FlagClass]) + inside(p.parseAndBuild(args = args)) { case ParseSuccess() => } + val task = p.instance.get + task.flag1 shouldBe flag1Value == "F" + task.flag2 shouldBe false + } } it should "accept setting private arguments" in {