Skip to content
This repository has been archived by the owner on Jun 20, 2024. It is now read-only.

Commit

Permalink
The # of elements for a collection are shown in the usage.
Browse files Browse the repository at this point in the history
  • Loading branch information
nh13 committed Aug 27, 2016
1 parent fea6a40 commit c03982f
Show file tree
Hide file tree
Showing 2 changed files with 102 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ import dagr.commons.util.StringUtil

import scala.util.{Success, Failure}

// TODO: incorporate strings from other classes?
object ClpArgumentDefinitionPrinting {

/** Strings for printing enum options */
Expand All @@ -45,6 +44,7 @@ object ClpArgumentDefinitionPrinting {
argumentDefinition.longName,
argumentDefinition.shortName,
argumentDefinition.typeDescription,
makeCollectionDescription(argumentDefinition),
makeArgumentDescription(argumentDefinition, argumentLookup))
}

Expand Down Expand Up @@ -74,14 +74,25 @@ object ClpArgumentDefinitionPrinting {
sb.toString
}

private def makeCollectionDescription(argumentDefinition: ClpArgument): Option[String] = {
if (!argumentDefinition.isCollection) return None

val desciption = (argumentDefinition.minElements, argumentDefinition.maxElements) match {
case (0, Integer.MAX_VALUE) => "*"
case (1, Integer.MAX_VALUE) => "+"
case (m, n) => s"{$m, $n}"
}
Some(desciption)
}

/**
* Intelligently decides whether or not to print a default value. Values are not printed if
* a) There is no default
* b) There is a default, but it is 'None'
* c) There is a default, but it's an empty list
* d) There is a default, but it's an empty set
*/
private def makeDefaultValueString(value : Option[_]) : String = {
private[cmdline] def makeDefaultValueString(value : Option[_]) : String = {
val v = value match {
case None => ""
case Some(None) => ""
Expand All @@ -99,12 +110,14 @@ object ClpArgumentDefinitionPrinting {
private val DescriptionColumnWidth: Int = 90

/** Prints the usage for a given argument given its various elements */
private def printArgumentUsage(stringBuilder: StringBuilder, name: String, shortName: String, theType: String, argumentDescription: String): Unit = {
private[cmdline] def printArgumentUsage(stringBuilder: StringBuilder, name: String, shortName: String, theType: String,
collectionDescription: Option[String], argumentDescription: String): Unit = {
// Desired output: "-f Foo, --foo=Foo" and for Booleans, "-f [true|false] --foo=[true|false]"
val collectionDesc = collectionDescription.getOrElse("")
val (shortType, longType) = if (theType == "Boolean") ("[true|false]","[=true|false]") else (theType, "=" + theType)
val label = new StringBuilder()
if (shortName.nonEmpty) label.append("-" + shortName + " " + shortType + ", ")
label.append("--" + name + longType)
if (shortName.nonEmpty) label.append("-" + shortName + " " + shortType + collectionDesc + ", ")
label.append("--" + name + longType + collectionDesc)
stringBuilder.append(KGRN(label.toString()))

// If the label is short enough, just pad out the column, otherwise wrap to the next line for the description
Expand All @@ -126,14 +139,6 @@ object ClpArgumentDefinitionPrinting {
stringBuilder.append(KCYN(wrappedDescriptionBuilder.toString()))
}

/**
* enumConstants.map(_.name).mkString(EnumOptionDocPrefix, ", ", EnumOptionDocSuffix)
// Also used for Boolean Options
private[reflect] val EnumOptionDocPrefix: String = "Options: "
private[reflect] val EnumOptionDocSuffix: String = "."
*/

/**
* Returns the help string with details about valid options for the given argument class.
*
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/*
* The MIT License
*
* Copyright (c) 2016 Fulcrum Genomics LLC
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/

package dagr.sopt.cmdline

import java.util

import dagr.commons.util.UnitSpec
import dagr.sopt.util.TermCode
import org.scalatest.BeforeAndAfterAll

/**
* Tests for ClpArgumentDefinitionPrinting.
*/
class ClpArgumentDefinitionPrintingTest extends UnitSpec with BeforeAndAfterAll {

import ClpArgumentDefinitionPrinting.makeDefaultValueString

private var printColor = true

override protected def beforeAll(): Unit = {
printColor = TermCode.printColor
TermCode.printColor = false
}

override protected def afterAll(): Unit = {
TermCode.printColor = printColor
}

"ClpArgumentDefinitionPrinting.makeDefaultValueString" should "print the default value" in {
makeDefaultValueString(None) shouldBe ""
makeDefaultValueString(Some(None)) shouldBe ""
makeDefaultValueString(Some(Nil)) shouldBe ""
makeDefaultValueString(Some(Set.empty)) shouldBe ""
makeDefaultValueString(Some(new util.ArrayList[java.lang.Integer]())) shouldBe ""
makeDefaultValueString(Some(Some("Value"))) shouldBe "[Default: Value]. "
makeDefaultValueString(Some("Value")) shouldBe "[Default: Value]. "
makeDefaultValueString(Some(Some(Some("Value")))) shouldBe "[Default: Some(Value)]. "
makeDefaultValueString(Some(List("A", "B", "C"))) shouldBe "[Default: List(A, B, C)]. "
}

private def printArgumentUsage(name: String, shortName: String, theType: String,
collectionDescription: Option[String], argumentDescription: String): String = {
val stringBuilder = new StringBuilder
ClpArgumentDefinitionPrinting.printArgumentUsage(stringBuilder=stringBuilder, name, shortName, theType, collectionDescription, argumentDescription)
stringBuilder.toString
}

// NB: does not test column wrapping
"ClpArgumentDefinitionPrinting.printArgumentUsage" should "print usages" in {
val longName = "long-name"
val shortName = "s"
val theType = "TheType"
val description = "Some description"

printArgumentUsage(longName, shortName, theType, None, description).startsWith(s"-$shortName $theType, --$longName=$theType") shouldBe true
printArgumentUsage(longName, shortName, "Boolean", None, description).startsWith(s"-$shortName [true|false], --$longName[=true|false]") shouldBe true
printArgumentUsage(longName, "", theType, None, description).startsWith(s"--$longName=$theType") shouldBe true
printArgumentUsage(longName, shortName, theType, Some("+"), description).startsWith(s"-$shortName $theType+, --$longName=$theType+") shouldBe true
printArgumentUsage(longName, shortName, theType, Some("{0,20}"), description).startsWith(s"-$shortName $theType{0,20}, --$longName=$theType{0,20}") shouldBe true
}
}

0 comments on commit c03982f

Please sign in to comment.