1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
|
// SPDX-License-Identifier: Apache-2.0
package firrtl.options
import firrtl.AnnotationSeq
import firrtl.{seqToAnnoSeq, annoSeqToSeq}
import logger.{ClassLogLevelAnnotation, LogClassNamesAnnotation, LogFileAnnotation, LogLevelAnnotation}
import scopt.OptionParser
import java.util.ServiceLoader
/** A utility for working with command line options
* @param applicationName the application associated with these command line options
*/
class Shell(val applicationName: String) {
/** Command line argument parser (OptionParser) with modifications */
val parser = new OptionParser[AnnotationSeq](applicationName) with DuplicateHandling with ExceptOnError
/** Contains all discovered [[RegisteredLibrary]] */
final lazy val registeredLibraries: Seq[RegisteredLibrary] = {
val libraries = scala.collection.mutable.ArrayBuffer[RegisteredLibrary]()
val iter = ServiceLoader.load(classOf[RegisteredLibrary]).iterator()
while (iter.hasNext) {
val lib = iter.next()
libraries += lib
parser.note(lib.name)
lib.addOptions(parser)
}
libraries.toSeq
}
/** Contains all discovered [[RegisteredTransform]] */
final lazy val registeredTransforms: Seq[RegisteredTransform] = {
val transforms = scala.collection.mutable.ArrayBuffer[RegisteredTransform]()
val iter = ServiceLoader.load(classOf[RegisteredTransform]).iterator()
if (iter.hasNext) { parser.note("FIRRTL Transform Options") }
while (iter.hasNext) {
val tx = iter.next()
transforms += tx
tx.addOptions(parser)
}
transforms.toSeq
}
/** The [[AnnotationSeq]] generated from command line arguments
*
* This requires lazy evaluation as subclasses will mixin new command
* line options via methods of [[Shell.parser]]
*/
def parse(args: Array[String], initAnnos: AnnotationSeq = Seq.empty): AnnotationSeq = {
registeredTransforms
registeredLibraries
parser
.parse(args, initAnnos.reverse)
.getOrElse(throw new OptionsException("Failed to parse command line options", new IllegalArgumentException))
.reverse
}
parser.note("Shell Options")
ProgramArgsAnnotation.addOptions(parser)
Seq(TargetDirAnnotation, InputAnnotationFileAnnotation, OutputAnnotationFileAnnotation)
.foreach(_.addOptions(parser))
parser
.opt[Unit]("show-registrations")
.action { (_, c) =>
val rtString = registeredTransforms.map(r => s"\n - ${r.getClass.getName}").mkString
val rlString = registeredLibraries.map(l => s"\n - ${l.getClass.getName}").mkString
println(s"""|The following FIRRTL transforms registered command line options:$rtString
|The following libraries registered command line options:$rlString""".stripMargin)
c
}
.unbounded()
.text("print discovered registered libraries and transforms")
parser.help("help").text("prints this usage text")
parser.note("Logging Options")
Seq(LogLevelAnnotation, ClassLogLevelAnnotation, LogFileAnnotation, LogClassNamesAnnotation)
.foreach(_.addOptions(parser))
}
|