A somewhat cleaner syntax for defining scopt configuration parsing.
This precise sample is based on http://verhas.github.io/License3j/home.html
A somewhat cleaner syntax for defining scopt configuration parsing.
This precise sample is based on http://verhas.github.io/License3j/home.html
| case class Params( | |
| mode: String = "", | |
| input: Option[File] = None, | |
| output: Option[File] = None, | |
| keyRing: Option[File] = None, | |
| key: String = "", | |
| password: String = "", | |
| genDigest: Boolean = false | |
| ) { | |
| def withEncrypt() = this.copy(mode = "encrypt") | |
| def withDecrypt() = this.copy(mode = "decrypt") | |
| def withInput(f: File) = this.copy(input = Some(f)) | |
| def withOutput(f: File) = this.copy(input = Some(f)) | |
| def withKeyRing(f: File) = this.copy(keyRing = Some(f)) | |
| def withKey(k: String) = this.copy(key = k) | |
| def withPassword(p: String) = this.copy(password = p) | |
| def withGenDigest() = this.copy(genDigest = true) | |
| } | |
| val parser = new SmartOptionParser[Params]("licensing") { | |
| head("licensing", "<version goes here>") | |
| smartCmd("encrypt", "encrypt a license file.", _.withEncrypt()).children( | |
| smartOpt('i', "input", "<file>", "the plaintext license file to be encrypted", _.withInput ).required(), | |
| smartOpt('o', "output", "<file>", "the encrypted license file to write", _.withOutput ).required(), | |
| smartOpt('r', "keyring", "<file>", "the PRIVATE keyring containing the encryption cert", _.withKeyRing ).required(), | |
| smartOpt('k', "key", "<text>", "the name of the key containing the encryption cert", _.withKey ).required(), | |
| smartOpt('p', "password", "<text>", "the key's password", _.withPassword ).required() | |
| ) | |
| smartCmd("decrypt", "decrypt a license file.", _.withDecrypt()).children( | |
| smartOpt('i', "input", "<file>", "the encrypted license file to be decrypted", _.withInput ).required(), | |
| smartOpt('o', "output", "<file>", "the plaintext license file to write", _.withOutput ).required(), | |
| smartOpt('r', "keyring", "<file>", "the PUBLIC keyring containing the decryption cert", _.withKeyRing ).required() | |
| ) | |
| checkConfig { p => | |
| if (p.mode != "encrypt" && p.mode != "decrypt") { | |
| println(this.usage) | |
| failure("Must specify a command: encrypt or decrypt.") | |
| } else success | |
| } | |
| smartFlag("dumpdigest", "output the digest, as Scala code, to the console", _.withGenDigest() ) | |
| help("help") text "prints this usage text" | |
| } | |
| def main(args: Array[String]): Unit = { | |
| parser.parse(args, Params()) map { config => | |
| println(config) | |
| ... | |
| } getOrElse { | |
| println("bad args") | |
| } | |
| } |
| import scopt._ | |
| abstract class SmartOptionParser[Config](programName: String) extends scopt.OptionParser[Config](programName){ | |
| def smartCmd( | |
| name : String, | |
| description : String, | |
| fn : (Config) => Config | |
| ): OptionDef[Unit, Config] = cmd(name) action { (_, c) => fn(c) } text description | |
| def smartOpt[T: scopt.Read]( | |
| char : Char, | |
| name : String, | |
| valName : String, | |
| description : String, | |
| fn : (Config) => (T) => Config | |
| ): OptionDef[T, Config] = opt[T](char, name) valueName valName action { (x, c) => fn(c)(x) } text description | |
| def smartFlag( | |
| name : String, | |
| description : String, | |
| fn : (Config) => Config | |
| ): OptionDef[Unit, Config] = opt[Unit](name) action { (_, c) => fn(c) } text description | |
| } |