8

I'm fairly new to Scala and need to build a really simple command line parser which provides something like the following which I created using JRuby in a few minutes:-

java -jar demo.jar --help

Command Line Example Application

Example: java -jar demo.jar --dn "CN=Test" --nde-url "http://www.example.com" --password "password"

For usage see below:

    -n http://www.example.com
    -p, --password             set the password
    -c, --capi                 set add to Windows key-store
    -h, --help                 Show this message
    -v, --version              Print version

Scallop looks like it will do the trick, but I can't seem to find a simple example that works! All of the examples I've found seem to be fragmented and don't work for some reason or other.

UPDATE

I found this example which works, but I'm not sure how to bind it into the actual args within the main method.

import org.rogach.scallop._; 

object cmdlinetest {
  def main(args: Array[String]) 

    val opts = Scallop(List("-d","--num-limbs","1"))
      .version("test 1.2.3 (c) 2012 Mr Placeholder")
      .banner("""Usage: test [OPTION]... [pet-name]
                |test is an awesome program, which does something funny
                |Options:
                |""".stripMargin)
      .footer("\nFor all other tricks, consult the documentation!")
      .opt[Boolean]("donkey", descr = "use donkey mode")
      .opt("monkeys", default = Some(2), short = 'm')
      .opt[Int]("num-limbs", 'k',
      "number of libms", required = true)
      .opt[List[Double]]("params")
      .opt[String]("debug", hidden = true)
      .props[String]('D',"some key-value pairs")
      // you can add parameters a bit later
      .args(List("-Dalpha=1","-D","betta=2","gamma=3", "Pigeon"))
      .trailArg[String]("pet name")
      .verify

    println(opts.help)
  }
}
1
  • As for your comment: >"I'm not sure how to bind it into the actual args within the main method", just replace List("-d","--num-limbs","1") with args Commented Sep 29, 2014 at 19:40

3 Answers 3

8

Well, I'll try to add more examples :)

In this case, it would be much better to use ScallopConf:

import org.rogach.scallop._

object Main extends App {
  val opts = new ScallopConf(args) {
    banner("""
NDE/SCEP Certificate enrollment prototype

Example: java -jar demo.jar --dn CN=Test --nde-url http://www.example.com --password password

For usage see below:
    """)

    val ndeUrl = opt[String]("nde-url")
    val password = opt[String]("password", descr = "set the password")
    val capi = toggle("capi", prefix = "no-", descrYes = "enable adding to Windows key-store", descrNo = "disable adding to Windows key-store")
    val version = opt[Boolean]("version", noshort = true, descr = "Print version")
    val help = opt[Boolean]("help", noshort = true, descr = "Show this message")

  }

  println(opts.password())
}

It prints:

$ java -jar demo.jar --help

NDE/SCEP Certificate enrollment prototype

Example: java -jar demo.jar --dn CN=Test --nde-url http://www.example.com --password password

For usage see below:

  -c, --capi              enable adding to Windows key-store 
      --no-capi           disable adding to Windows key-store 
      --help              Show this message 
  -n, --nde-url  <arg>     
  -p, --password  <arg>   set the password 
      --version           Print version 
Sign up to request clarification or add additional context in comments.

Comments

1

Did you read the documentation? It looks like all you have to do is call get for each option you want:

def get [A] (name: String)(implicit m: Manifest[A]): Option[A]

It looks like you might need to provide the expected return type in the method call. Try something like this:

val donkey = opts.get[Boolean]("donkey")
val numLimbs = opts.get[Int]("num-limbs")

Comments

0

If you're just looking for a quick and dirty way to parse command line arguments, you can use pirate, an extremely barebones way to parse arguments. Here is what it would look like to handle the usage you describe above:

import com.mosesn.pirate.Pirate

object Main {
  def main(commandLineArgs: Array[String]) {
    val args = Pirate("[ -n string ] [ -p string ] [ -chv ]")("-n whatever -c".split(" "))
    val c = args.flags.contains('c')
    val v = args.flags.contains('v')
    val h = args.flags.contains('h')
    val n = args.strings.get("n")
    val p = args.strings.get("p")

    println(Seq(c, v, h, n, p))
  }
}

Of course, for your program, you would pass commandLineArgs instead of "-n whatever -c".

Unfortunately, pirate does not yet support GNU style arguments, nor the version or help text options.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.