Add ExecutionOptionsManager
Taken from https://github.com/ucb-bar/firrtl
This commit is contained in:
16
build.sbt
Normal file
16
build.sbt
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
// See LICENSE for license details.
|
||||||
|
|
||||||
|
import Dependencies._
|
||||||
|
|
||||||
|
lazy val commonSettings = Seq(
|
||||||
|
organization := "edu.berkeley.cs",
|
||||||
|
version := "0.1-SNAPSHOT",
|
||||||
|
scalaVersion := "2.11.8",
|
||||||
|
libraryDependencies ++= commonDependencies
|
||||||
|
)
|
||||||
|
|
||||||
|
lazy val executionoptions = (project in file("executionoptions"))
|
||||||
|
.settings(commonSettings)
|
||||||
|
.settings(
|
||||||
|
libraryDependencies ++= executionoptionsDependencies
|
||||||
|
)
|
||||||
@@ -0,0 +1,126 @@
|
|||||||
|
// See LICENSE for license details.
|
||||||
|
|
||||||
|
package bar.executionoptions
|
||||||
|
|
||||||
|
import scopt.OptionParser
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use this trait to define an options class that can add its private command line options to a externally
|
||||||
|
* declared parser
|
||||||
|
*/
|
||||||
|
trait ComposableOptions
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Most of the chisel toolchain components require a topName which defines a circuit or a device under test.
|
||||||
|
* Much of the work that is done takes place in a directory.
|
||||||
|
* It would be simplest to require topName to be defined but in practice it is preferred to defer this.
|
||||||
|
* For example, in chisel, by deferring this it is possible for the execute there to first elaborate the
|
||||||
|
* circuit and then set the topName from that if it has not already been set.
|
||||||
|
*/
|
||||||
|
case class CommonOptions(topName: String = "", targetDirName: String = "test_run_dir") extends ComposableOptions
|
||||||
|
|
||||||
|
abstract class HasParser(applicationName: String) {
|
||||||
|
final val parser: OptionParser[Unit] = new OptionParser[Unit](applicationName) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
trait HasCommonOptions {
|
||||||
|
self: ExecutionOptionsManager =>
|
||||||
|
var commonOptions = CommonOptions()
|
||||||
|
|
||||||
|
parser.note("common options")
|
||||||
|
|
||||||
|
parser.opt[String]("top-name")
|
||||||
|
.abbr("tn")
|
||||||
|
.valueName("<top-level-circuit-name>")
|
||||||
|
.foreach { x =>
|
||||||
|
commonOptions = commonOptions.copy(topName = x)
|
||||||
|
}
|
||||||
|
.text("This options defines the top level circuit, defaults to dut when possible")
|
||||||
|
|
||||||
|
parser.opt[String]("target-dir")
|
||||||
|
.abbr("td").valueName("<target-directory>")
|
||||||
|
.foreach { x =>
|
||||||
|
commonOptions = commonOptions.copy(targetDirName = x)
|
||||||
|
}
|
||||||
|
.text(s"This options defines a work directory for intermediate files, default is ${commonOptions.targetDirName}")
|
||||||
|
|
||||||
|
parser.help("help").text("prints this usage text")
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param applicationName The name shown in the usage
|
||||||
|
*/
|
||||||
|
class ExecutionOptionsManager(val applicationName: String) extends HasParser(applicationName) with HasCommonOptions {
|
||||||
|
|
||||||
|
def parse(args: Array[String]): Boolean = {
|
||||||
|
parser.parse(args)
|
||||||
|
}
|
||||||
|
|
||||||
|
def showUsageAsError(): Unit = parser.showUsageAsError()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* make sure that all levels of targetDirName exist
|
||||||
|
*
|
||||||
|
* @return true if directory exists
|
||||||
|
*/
|
||||||
|
def makeTargetDir(): Boolean = {
|
||||||
|
(new java.io.File(commonOptions.targetDirName)).mkdirs()
|
||||||
|
}
|
||||||
|
|
||||||
|
def targetDirName: String = commonOptions.targetDirName
|
||||||
|
|
||||||
|
/**
|
||||||
|
* this function sets the topName in the commonOptions.
|
||||||
|
* It would be nicer to not need this but many chisel tools cannot determine
|
||||||
|
* the name of the device under test until other options have been parsed.
|
||||||
|
* Havin this function allows the code to set the TopName after it has been
|
||||||
|
* determined
|
||||||
|
*
|
||||||
|
* @param newTopName the topName to be used
|
||||||
|
*/
|
||||||
|
def setTopName(newTopName: String): Unit = {
|
||||||
|
commonOptions = commonOptions.copy(topName = newTopName)
|
||||||
|
}
|
||||||
|
def setTopNameIfNotSet(newTopName: String): Unit = {
|
||||||
|
if(commonOptions.topName.isEmpty) {
|
||||||
|
setTopName(newTopName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
def topName: String = commonOptions.topName
|
||||||
|
def setTargetDirName(newTargetDirName: String): Unit = {
|
||||||
|
commonOptions = commonOptions.copy(targetDirName = newTargetDirName)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return a file based on targetDir, topName and suffix
|
||||||
|
* Will not add the suffix if the topName already ends with that suffix
|
||||||
|
*
|
||||||
|
* @param suffix suffix to add, removes . if present
|
||||||
|
* @param fileNameOverride this will override the topName if nonEmpty, when using this targetDir is ignored
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
def getBuildFileName(suffix: String, fileNameOverride: String = ""): String = {
|
||||||
|
makeTargetDir()
|
||||||
|
|
||||||
|
val baseName = if(fileNameOverride.nonEmpty) fileNameOverride else topName
|
||||||
|
val directoryName = {
|
||||||
|
if(fileNameOverride.nonEmpty) {
|
||||||
|
""
|
||||||
|
}
|
||||||
|
else if(baseName.startsWith("./") || baseName.startsWith("/")) {
|
||||||
|
""
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if(targetDirName.endsWith("/")) targetDirName else targetDirName + "/"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val normalizedSuffix = {
|
||||||
|
val dottedSuffix = if(suffix.startsWith(".")) suffix else s".$suffix"
|
||||||
|
if(baseName.endsWith(dottedSuffix)) "" else dottedSuffix
|
||||||
|
}
|
||||||
|
|
||||||
|
s"$directoryName$baseName$normalizedSuffix"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
// See LICENSE for license details.
|
||||||
|
|
||||||
|
package bar.executionoptions
|
||||||
|
|
||||||
|
import org.scalatest.{Matchers, FreeSpec}
|
||||||
|
|
||||||
|
class ExecutionOptionsManagerSpec extends FreeSpec with Matchers {
|
||||||
|
"ExecutionOptionsManager is a container for one more more ComposableOptions Block" - {
|
||||||
|
"It has a default CommonOptionsBlock" in {
|
||||||
|
val manager = new ExecutionOptionsManager("test")
|
||||||
|
manager.commonOptions.targetDirName should be ("test_run_dir")
|
||||||
|
}
|
||||||
|
"But can override defaults like this" in {
|
||||||
|
val manager = new ExecutionOptionsManager("test") { commonOptions = CommonOptions(topName = "dog") }
|
||||||
|
manager.commonOptions shouldBe a [CommonOptions]
|
||||||
|
manager.topName should be ("dog")
|
||||||
|
manager.commonOptions.topName should be ("dog")
|
||||||
|
}
|
||||||
|
"The add method should put a new version of a given type the manager" in {
|
||||||
|
val manager = new ExecutionOptionsManager("test") { commonOptions = CommonOptions(topName = "dog") }
|
||||||
|
val initialCommon = manager.commonOptions
|
||||||
|
initialCommon.topName should be ("dog")
|
||||||
|
|
||||||
|
manager.commonOptions = CommonOptions(topName = "cat")
|
||||||
|
|
||||||
|
val afterCommon = manager.commonOptions
|
||||||
|
afterCommon.topName should be ("cat")
|
||||||
|
initialCommon.topName should be ("dog")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
1
project/build.properties
Normal file
1
project/build.properties
Normal file
@@ -0,0 +1 @@
|
|||||||
|
sbt.version=0.13.12
|
||||||
16
project/dependencies.scala
Normal file
16
project/dependencies.scala
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
import sbt._
|
||||||
|
import Keys._
|
||||||
|
|
||||||
|
object Dependencies {
|
||||||
|
val scalatestVersion = "3.0.0"
|
||||||
|
val scalatest = "org.scalatest" %% "scalatest" % scalatestVersion % "test"
|
||||||
|
val scoptVersion = "3.4.0"
|
||||||
|
val scopt = "com.github.scopt" %% "scopt" % scoptVersion
|
||||||
|
|
||||||
|
val commonDependencies: Seq[ModuleID] = Seq(
|
||||||
|
scalatest
|
||||||
|
)
|
||||||
|
val executionoptionsDependencies: Seq[ModuleID] = Seq(
|
||||||
|
scopt
|
||||||
|
)
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user