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 | |
} |