diff options
| author | Jiuyang Liu | 2021-11-30 08:54:07 +0800 |
|---|---|---|
| committer | GitHub | 2021-11-29 16:54:07 -0800 |
| commit | b7dd35e9cdeecb2d5125ef1d8802d5af17bff4ab (patch) | |
| tree | 2220995b3a36df4b0b8ee18185cb75414ba48d5b /src/main/scala/firrtl/ExecutionOptionsManager.scala | |
| parent | 82da33135fcac1a81e8ea95f47626e80b4e80fd1 (diff) | |
[deprecation clean up] remove firrtl.ExecutionOptionsManager (#2422)
Also remove all related APIs:
ComposableOptions
HasParser
CommonOptions
HasCommonOptions
FirrtlExecutionOptions
HasFirrtlOptions
FirrtlExecutionResult
FirrtlExecutionSuccess
FirrtlExecutionFailure
ExecutionOptionsManager
firrtl.stage.DriverCompatibility.firrtlResultView
logger.Logger.makeScope
OutputConfig
SingleFile
OneFilePerModule
* Change default LogLevel to None which means "unset"
Logger.getGlobalLevel then returns LogLevel.Warn when the current value
is LogLevel.None. This preserves the behavior of the default being
"Warn" but now uses LogLevel.None to indicate "I'm not setting the
value." This resolves issues where it was not possible to tell if
annotations were actually setting the log level or if the default level
of warn was just being filled in.
Co-authored-by: sinofp <sinofp@tuta.io>
Co-authored-by: Jack Koenig <koenig@sifive.com>
Diffstat (limited to 'src/main/scala/firrtl/ExecutionOptionsManager.scala')
| -rw-r--r-- | src/main/scala/firrtl/ExecutionOptionsManager.scala | 705 |
1 files changed, 0 insertions, 705 deletions
diff --git a/src/main/scala/firrtl/ExecutionOptionsManager.scala b/src/main/scala/firrtl/ExecutionOptionsManager.scala deleted file mode 100644 index b8c0dedd..00000000 --- a/src/main/scala/firrtl/ExecutionOptionsManager.scala +++ /dev/null @@ -1,705 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 - -package firrtl - -import logger.LogLevel -import logger.{ClassLogLevelAnnotation, LogClassNamesAnnotation, LogFileAnnotation, LogLevelAnnotation} -import firrtl.annotations._ -import firrtl.Parser.{AppendInfo, GenInfo, IgnoreInfo, InfoMode, UseInfo} -import firrtl.ir.Circuit -import firrtl.passes.memlib.{InferReadWriteAnnotation, ReplSeqMemAnnotation} -import firrtl.passes.clocklist.ClockListAnnotation -import firrtl.transforms.NoCircuitDedupAnnotation -import scopt.OptionParser -import firrtl.stage.{ - CompilerAnnotation, - FirrtlCircuitAnnotation, - FirrtlFileAnnotation, - FirrtlSourceAnnotation, - InfoModeAnnotation, - OutputFileAnnotation, - RunFirrtlTransformAnnotation -} -import firrtl.stage.phases.DriverCompatibility.{EmitOneFilePerModuleAnnotation, TopNameAnnotation} -import firrtl.options.{InputAnnotationFileAnnotation, OutputAnnotationFileAnnotation, ProgramArgsAnnotation, StageUtils} -import firrtl.transforms.{DontCheckCombLoopsAnnotation, NoDCEAnnotation} - -import scala.collection.Seq - -/** - * Use this trait to define an options class that can add its private command line options to a externally - * declared parser. - * '''NOTE''' In all derived trait/classes, if you intend on maintaining backwards compatibility, - * be sure to add new options at the end of the current ones and don't remove any existing ones. - */ -@deprecated("Use firrtl.options.HasScoptOptions and/or library/transform registration", "FIRRTL 1.2") -trait ComposableOptions - -@deprecated("Use firrtl.options.{ExecutionOptionsManager, TerminateOnExit, DuplicateHandling}", "FIRRTL 1.2") -abstract class HasParser(applicationName: String) { - final val parser = new OptionParser[Unit](applicationName) { - var terminateOnExit = true - override def terminate(exitState: Either[String, Unit]): Unit = { - if (terminateOnExit) sys.exit(0) - } - } - - /** - * By default scopt calls sys.exit when --help is in options, this defeats that - */ - def doNotExitOnHelp(): Unit = { - parser.terminateOnExit = false - } - - /** - * By default scopt calls sys.exit when --help is in options, this un-defeats doNotExitOnHelp - */ - def exitOnHelp(): Unit = { - parser.terminateOnExit = true - } -} - -/** - * 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. - */ -@deprecated("Use a FirrtlOptionsView, LoggerOptionsView, or construct your own view of an AnnotationSeq", "FIRRTL 1.2") -case class CommonOptions( - topName: String = "", - targetDirName: String = ".", - globalLogLevel: LogLevel.Value = LogLevel.None, - logToFile: Boolean = false, - logClassNames: Boolean = false, - classLogLevels: Map[String, LogLevel.Value] = Map.empty, - programArgs: Seq[String] = Seq.empty) - extends ComposableOptions { - - def getLogFileName(optionsManager: ExecutionOptionsManager): String = { - if (topName.isEmpty) { - optionsManager.getBuildFileName("log", "firrtl") - } else { - optionsManager.getBuildFileName("log") - } - } - - def toAnnotations: AnnotationSeq = List() ++ (if (topName.nonEmpty) Seq(TopNameAnnotation(topName)) else Seq()) ++ - (if (targetDirName != ".") Some(TargetDirAnnotation(targetDirName)) else None) ++ - Some(LogLevelAnnotation(globalLogLevel)) ++ - (if (logToFile) { Some(LogFileAnnotation(None)) } - else { None }) ++ - (if (logClassNames) { Some(LogClassNamesAnnotation) } - else { None }) ++ - classLogLevels.map { case (c, v) => ClassLogLevelAnnotation(c, v) } ++ - programArgs.map(a => ProgramArgsAnnotation(a)) -} - -@deprecated("Specify command line arguments in an Annotation mixing in HasScoptOptions", "FIRRTL 1.2") -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 - .opt[String]("log-level") - .abbr("ll") - .valueName("<error|warn|info|debug|trace>") - .foreach { x => - val level = x.toLowerCase match { - case "error" => LogLevel.Error - case "warn" => LogLevel.Warn - case "info" => LogLevel.Info - case "debug" => LogLevel.Debug - case "trace" => LogLevel.Trace - } - commonOptions = commonOptions.copy(globalLogLevel = level) - } - .validate { x => - if (Array("error", "warn", "info", "debug", "trace").contains(x.toLowerCase)) parser.success - else parser.failure(s"$x bad value must be one of error|warn|info|debug|trace") - } - .text(s"This options defines global log level, default is ${commonOptions.globalLogLevel}") - - parser - .opt[Seq[String]]("class-log-level") - .abbr("cll") - .valueName("<FullClassName:[error|warn|info|debug|trace]>[,...]") - .foreach { x => - val logAssignments = x.map { y => - val className :: levelName :: _ = y.split(":").toList - - val level = levelName.toLowerCase match { - case "error" => LogLevel.Error - case "warn" => LogLevel.Warn - case "info" => LogLevel.Info - case "debug" => LogLevel.Debug - case "trace" => LogLevel.Trace - case _ => - throw new Exception(s"Error: bad command line arguments for --class-log-level $x") - } - className -> level - } - - commonOptions = commonOptions.copy(classLogLevels = commonOptions.classLogLevels ++ logAssignments) - - } - .text(s"This options defines class log level, default is ${commonOptions.classLogLevels}") - - parser - .opt[Unit]("log-to-file") - .abbr("ltf") - .foreach { _ => - commonOptions = commonOptions.copy(logToFile = true) - } - .text(s"default logs to stdout, this flags writes to topName.log or firrtl.log if no topName") - - parser - .opt[Unit]("log-class-names") - .abbr("lcn") - .foreach { _ => - commonOptions = commonOptions.copy(logClassNames = true) - } - .text(s"shows class names and log level in logging output, useful for target --class-log-level") - - parser.help("help").text("prints this usage text") - - parser - .arg[String]("<arg>...") - .unbounded() - .optional() - .action((x, c) => commonOptions = commonOptions.copy(programArgs = commonOptions.programArgs :+ x)) - .text("optional unbounded args") - -} - -/** Firrtl output configuration specified by [[FirrtlExecutionOptions]] - * - * Derived from the fields of the execution options - * @see [[FirrtlExecutionOptions.getOutputConfig]] - */ -sealed abstract class OutputConfig -final case class SingleFile(targetFile: String) extends OutputConfig -final case class OneFilePerModule(targetDir: String) extends OutputConfig - -/** - * The options that firrtl supports in callable component sense - * - * @param inputFileNameOverride default is targetDir/topName.fir - * @param outputFileNameOverride default is targetDir/topName.v the .v is based on the compilerName parameter - * @param compilerName which compiler to use - * @param annotations annotations to pass to compiler - */ -@deprecated("Use a FirrtlOptionsView or construct your own view of an AnnotationSeq", "FIRRTL 1.2") -case class FirrtlExecutionOptions( - inputFileNameOverride: String = "", - outputFileNameOverride: String = "", - compilerName: String = "verilog", - infoModeName: String = "append", - inferRW: Seq[String] = Seq.empty, - firrtlSource: Option[String] = None, - customTransforms: Seq[Transform] = List.empty, - annotations: List[Annotation] = List.empty, - annotationFileNameOverride: String = "", - outputAnnotationFileName: String = "", - emitOneFilePerModule: Boolean = false, - dontCheckCombLoops: Boolean = false, - noDCE: Boolean = false, - annotationFileNames: List[String] = List.empty, - firrtlCircuit: Option[Circuit] = None) - extends ComposableOptions { - - require( - !(emitOneFilePerModule && outputFileNameOverride.nonEmpty), - "Cannot both specify the output filename and emit one file per module!!!" - ) - - def infoMode: InfoMode = { - infoModeName match { - case "use" => UseInfo - case "ignore" => IgnoreInfo - case "gen" => GenInfo(inputFileNameOverride) - case "append" => AppendInfo(inputFileNameOverride) - case other => UseInfo - } - } - - def compiler: Compiler = { - compilerName match { - case "none" => new NoneCompiler() - case "high" => new HighFirrtlCompiler() - case "low" => new LowFirrtlCompiler() - case "middle" => new MiddleFirrtlCompiler() - case "verilog" => new VerilogCompiler() - case "mverilog" => new MinimumVerilogCompiler() - case "sverilog" => new SystemVerilogCompiler() - } - } - - def outputSuffix: String = { - compilerName match { - case "verilog" | "mverilog" => "v" - case "sverilog" => "sv" - case "low" => "lo.fir" - case "middle" => "mid.fir" - case "high" => "hi.fir" - case "none" => "fir" - case _ => - throw new Exception(s"Illegal compiler name $compilerName") - } - } - - /** Get the name of the input file - * - * @note Does not implicitly add a file extension to the input file - * @param optionsManager this is needed to access build function and its common options - * @return a properly constructed input file name - */ - def getInputFileName(optionsManager: ExecutionOptionsManager): String = { - if (inputFileNameOverride.nonEmpty) inputFileNameOverride - else optionsManager.getBuildFileName("fir", inputFileNameOverride) - } - - /** Get the user-specified [[OutputConfig]] - * - * @param optionsManager this is needed to access build function and its common options - * @return the output configuration - */ - def getOutputConfig(optionsManager: ExecutionOptionsManager): OutputConfig = { - if (emitOneFilePerModule) OneFilePerModule(optionsManager.targetDirName) - else SingleFile(optionsManager.getBuildFileName(outputSuffix, outputFileNameOverride)) - } - - /** Get the user-specified targetFile assuming [[OutputConfig]] is [[SingleFile]] - * - * @param optionsManager this is needed to access build function and its common options - * @return the targetFile as a String - */ - def getTargetFile(optionsManager: ExecutionOptionsManager): String = { - getOutputConfig(optionsManager) match { - case SingleFile(targetFile) => targetFile - case other => throw new Exception("OutputConfig is not SingleFile!") - } - } - - /** Gives annotations based on the output configuration - * - * @param optionsManager this is needed to access build function and its common options - * @return Annotations that will be consumed by emitter Transforms - */ - def getEmitterAnnos(optionsManager: ExecutionOptionsManager): Seq[Annotation] = { - // TODO should this be a public function? - val emitter = compilerName match { - case "none" => classOf[ChirrtlEmitter] - case "high" => classOf[HighFirrtlEmitter] - case "middle" => classOf[MiddleFirrtlEmitter] - case "low" => classOf[LowFirrtlEmitter] - case "verilog" => classOf[VerilogEmitter] - case "mverilog" => classOf[MinimumVerilogEmitter] - case "sverilog" => classOf[VerilogEmitter] - } - getOutputConfig(optionsManager) match { - case SingleFile(_) => Seq(EmitCircuitAnnotation(emitter)) - case OneFilePerModule(_) => Seq(EmitAllModulesAnnotation(emitter)) - } - } - - /** - * build the annotation file name, taking overriding parameters - * - * @param optionsManager this is needed to access build function and its common options - * @return - */ - @deprecated("Use FirrtlOptions.annotationFileNames instead", "FIRRTL 1.1") - def getAnnotationFileName(optionsManager: ExecutionOptionsManager): String = { - optionsManager.getBuildFileName("anno", annotationFileNameOverride) - } - - def toAnnotations: AnnotationSeq = { - if (inferRW.nonEmpty) { - StageUtils.dramaticWarning("User set FirrtlExecutionOptions.inferRW, but inferRW has no effect!") - } - - List() ++ (if (inputFileNameOverride.nonEmpty) Seq(FirrtlFileAnnotation(inputFileNameOverride)) else Seq()) ++ - (if (outputFileNameOverride.nonEmpty) { Some(OutputFileAnnotation(outputFileNameOverride)) } - else { None }) ++ - Some(RunFirrtlTransformAnnotation.stringToEmitter(compilerName)) ++ - Some(InfoModeAnnotation(infoModeName)) ++ - firrtlSource.map(FirrtlSourceAnnotation(_)) ++ - customTransforms.map(t => RunFirrtlTransformAnnotation(t)) ++ - annotations ++ - (if (annotationFileNameOverride.nonEmpty) { Some(InputAnnotationFileAnnotation(annotationFileNameOverride)) } - else { None }) ++ - (if (outputAnnotationFileName.nonEmpty) { Some(OutputAnnotationFileAnnotation(outputAnnotationFileName)) } - else { None }) ++ - (if (emitOneFilePerModule) { Some(EmitOneFilePerModuleAnnotation) } - else { None }) ++ - (if (dontCheckCombLoops) { Some(DontCheckCombLoopsAnnotation) } - else { None }) ++ - (if (noDCE) { Some(NoDCEAnnotation) } - else { None }) ++ - annotationFileNames.map(InputAnnotationFileAnnotation(_)) ++ - firrtlCircuit.map(FirrtlCircuitAnnotation(_)) - } -} - -@deprecated("Specify command line arguments in an Annotation mixing in HasScoptOptions", "FIRRTL 1.2") -trait HasFirrtlOptions { - self: ExecutionOptionsManager => - var firrtlOptions = FirrtlExecutionOptions() - - parser.note("firrtl options") - - parser - .opt[String]("input-file") - .abbr("i") - .valueName("<firrtl-source>") - .foreach { x => - firrtlOptions = firrtlOptions.copy(inputFileNameOverride = x) - } - .text { - "use this to override the default input file name , default is empty" - } - - parser - .opt[String]("output-file") - .abbr("o") - .valueName("<output>") - .validate { x => - if (firrtlOptions.emitOneFilePerModule) - parser.failure("Cannot override output-file if split-modules is specified") - else parser.success - } - .foreach { x => - firrtlOptions = firrtlOptions.copy(outputFileNameOverride = x) - } - .text { - "use this to override the default output file name, default is empty" - } - - parser - .opt[String]("annotation-file") - .abbr("faf") - .unbounded() - .valueName("<input-anno-file>") - .foreach { x => - val annoFiles = x +: firrtlOptions.annotationFileNames - firrtlOptions = firrtlOptions.copy(annotationFileNames = annoFiles) - } - .text("Used to specify annotation files (can appear multiple times)") - - parser - .opt[Unit]("force-append-anno-file") - .abbr("ffaaf") - .hidden() - .foreach { _ => - val msg = "force-append-anno-file is deprecated and will soon be removed\n" + - (" " * 9) + "(It does not do anything anymore)" - StageUtils.dramaticWarning(msg) - } - - parser - .opt[String]("output-annotation-file") - .abbr("foaf") - .valueName("<output-anno-file>") - .foreach { x => - firrtlOptions = firrtlOptions.copy(outputAnnotationFileName = x) - } - .text { - "use this to set the annotation output file" - } - - parser - .opt[String]("compiler") - .abbr("X") - .valueName("<high|middle|low|verilog|mverilog|sverilog|none>") - .foreach { x => - firrtlOptions = firrtlOptions.copy(compilerName = x) - } - .validate { x => - if (Array("high", "middle", "low", "verilog", "mverilog", "sverilog", "none").contains(x.toLowerCase)) { - parser.success - } else { - parser.failure(s"$x not a legal compiler") - } - } - .text { - s"compiler to use, default is ${firrtlOptions.compilerName}" - } - - parser - .opt[String]("info-mode") - .valueName("<ignore|use|gen|append>") - .foreach { x => - firrtlOptions = firrtlOptions.copy(infoModeName = x.toLowerCase) - } - .validate { x => - if (Array("ignore", "use", "gen", "append").contains(x.toLowerCase)) parser.success - else parser.failure(s"$x bad value must be one of ignore|use|gen|append") - } - .text { - s"specifies the source info handling, default is ${firrtlOptions.infoModeName}" - } - - parser - .opt[Seq[String]]("custom-transforms") - .abbr("fct") - .valueName("<package>.<class>") - .foreach { customTransforms: Seq[String] => - firrtlOptions = firrtlOptions.copy( - customTransforms = firrtlOptions.customTransforms ++ - (customTransforms.map { x: String => - Class.forName(x).asInstanceOf[Class[_ <: Transform]].newInstance() - }) - ) - } - .text { - """runs these custom transforms during compilation.""" - } - - parser - .opt[Seq[String]]("inline") - .abbr("fil") - .valueName("<circuit>[.<module>[.<instance>]][,..],") - .foreach { x => - val newAnnotations = x.map { value => - value.split('.') match { - case Array(circuit) => - passes.InlineAnnotation(CircuitName(circuit)) - case Array(circuit, module) => - passes.InlineAnnotation(ModuleName(module, CircuitName(circuit))) - case Array(circuit, module, inst) => - passes.InlineAnnotation(ComponentName(inst, ModuleName(module, CircuitName(circuit)))) - } - } - firrtlOptions = firrtlOptions.copy( - annotations = firrtlOptions.annotations ++ newAnnotations, - customTransforms = firrtlOptions.customTransforms :+ new passes.InlineInstances - ) - } - .text { - """Inline one or more module (comma separated, no spaces) module looks like "MyModule" or "MyModule.myinstance""" - } - - parser - .opt[Unit]("infer-rw") - .abbr("firw") - .foreach { x => - firrtlOptions = firrtlOptions.copy( - annotations = firrtlOptions.annotations :+ InferReadWriteAnnotation, - customTransforms = firrtlOptions.customTransforms :+ new passes.memlib.InferReadWrite - ) - } - .text { - "Enable readwrite port inference for the target circuit" - } - - parser - .opt[String]("repl-seq-mem") - .abbr("frsq") - .valueName("-c:<circuit>:-i:<filename>:-o:<filename>") - .foreach { x => - firrtlOptions = firrtlOptions.copy( - annotations = firrtlOptions.annotations :+ ReplSeqMemAnnotation.parse(x), - customTransforms = firrtlOptions.customTransforms :+ new passes.memlib.ReplSeqMem - ) - } - .text { - "Replace sequential memories with blackboxes + configuration file" - } - - parser - .opt[String]("list-clocks") - .abbr("clks") - .valueName("-c:<circuit>:-m:<module>:-o:<filename>") - .foreach { x => - firrtlOptions = firrtlOptions.copy( - annotations = firrtlOptions.annotations :+ ClockListAnnotation.parse(x), - customTransforms = firrtlOptions.customTransforms :+ new passes.clocklist.ClockListTransform - ) - } - .text { - "List which signal drives each clock of every descendent of specified module" - } - - parser - .opt[Unit]("split-modules") - .abbr("fsm") - .validate { x => - if (firrtlOptions.outputFileNameOverride.nonEmpty) - parser.failure("Cannot split-modules if output-file is specified") - else parser.success - } - .foreach { _ => - firrtlOptions = firrtlOptions.copy(emitOneFilePerModule = true) - } - .text { - "Emit each module to its own file in the target directory." - } - - parser - .opt[Unit]("no-check-comb-loops") - .foreach { _ => - firrtlOptions = firrtlOptions.copy(dontCheckCombLoops = true) - } - .text { - "Do NOT check for combinational loops (not recommended)" - } - - parser - .opt[Unit]("no-dce") - .foreach { _ => - firrtlOptions = firrtlOptions.copy(noDCE = true) - } - .text { - "Do NOT run dead code elimination" - } - - parser - .opt[Unit]("no-dedup") - .foreach { _ => - firrtlOptions = firrtlOptions.copy( - annotations = firrtlOptions.annotations :+ NoCircuitDedupAnnotation - ) - } - .text { - "Do NOT dedup modules" - } - - parser.note("") -} - -@deprecated("Use FirrtlStage and examine the output AnnotationSeq directly", "FIRRTL 1.2") -sealed trait FirrtlExecutionResult - -@deprecated("Use FirrtlStage and examine the output AnnotationSeq directly", "FIRRTL 1.2") -object FirrtlExecutionSuccess { - def apply( - emitType: String, - emitted: String, - circuitState: CircuitState - ): FirrtlExecutionSuccess = new FirrtlExecutionSuccess(emitType, emitted, circuitState) - - def unapply(arg: FirrtlExecutionSuccess): Option[(String, String)] = { - Some((arg.emitType, arg.emitted)) - } -} - -/** - * Indicates a successful execution of the firrtl compiler, returning the compiled result and - * the type of compile - * - * @param emitType The name of the compiler used, currently "high", "middle", "low", "verilog", "mverilog", or - * "sverilog" - * @param emitted The emitted result of compilation - */ -@deprecated("Use FirrtlStage and examine the output AnnotationSeq directly", "FIRRTL 1.2") -class FirrtlExecutionSuccess( - val emitType: String, - val emitted: String, - val circuitState: CircuitState) - extends FirrtlExecutionResult - -/** - * The firrtl compilation failed. - * - * @param message Some kind of hint as to what went wrong. - */ -@deprecated("Use FirrtlStage and examine the output AnnotationSeq directly", "FIRRTL 1.2") -case class FirrtlExecutionFailure(message: String) extends FirrtlExecutionResult - -/** - * @param applicationName The name shown in the usage - */ -@deprecated("Use new FirrtlStage infrastructure", "FIRRTL 1.2") -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 = { - FileUtils.makeDirectory(commonOptions.targetDirName) - } - - 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 - } - val path = directoryName + baseName.split("/").dropRight(1).mkString("/") - FileUtils.makeDirectory(path) - s"$directoryName$baseName$normalizedSuffix" - } -} |
