GlobalOptions.scala 5.3 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package de.tu_darmstadt.cs.esa.tapasco.parser
import  de.tu_darmstadt.cs.esa.tapasco.base._
import  de.tu_darmstadt.cs.esa.tapasco.base.json._
import  de.tu_darmstadt.cs.esa.tapasco.jobs._
import  de.tu_darmstadt.cs.esa.tapasco.jobs.json._
import  play.api.libs.json._
import  scala.io.Source
import  java.nio.file._
import  fastparse.all._

private object GlobalOptions {
  import BasicParsers._

  def validOption: Parser[String] = (
    longShortOption("h", "help")    |
16
17
    longShortOption("v", "verbose") |
    longShortOption("n", "dryRun")  |
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
    longOption("archDir")           |
    longOption("platformDir")       |
    longOption("coreDir")           |
    longOption("compositionDir")    |
    longOption("kernelDir")         |
    longOption("jobsFile")          |
    longOption("configFile")        |
    longOption("logFile")           |
    longOption("parallel")          |
    longOption("slurm")             |
    longOption("maxThreads") 
  ).opaque("a global option")

  def help: Parser[(String, String)] =
    (longShortOption("h", "help") | IgnoreCase("help") | IgnoreCase("usage")) ~
33
    (ws1 ~ string).? map { case (h, topic) => { Usage.topic(topic); ("Help", Usage()) } }
34

35
36
37
38
  def verbose: Parser[(String, String)] =
    (longShortOption("v", "verbose", Some("Verbose")) ~/ (ws1 ~ quotedString.opaque("verbose mode as quoted string")).? ~ ws)
      .map { case (k, mode) => (k, mode getOrElse "verbose") }

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
  def archDir: Parser[(String, Path)] =
    longOption("archDir", "Architecture") ~/ ws1 ~ path.opaque("root dir of Architectures") ~ ws
  def platformDir: Parser[(String, Path)] =
    longOption("platformDir", "Platform") ~/ ws1 ~ path.opaque("root dir of Platforms") ~ ws
  def coreDir: Parser[(String, Path)] =
    longOption("coreDir", "Core") ~/ ws1 ~ path.opaque("root dir of Cores") ~ ws
  def compositionDir: Parser[(String, Path)] =
    longOption("compositionDir", "Composition") ~/ ws1 ~ path.opaque("root dir of Compositions") ~ ws
  def kernelDir: Parser[(String, Path)] =
    longOption("kernelDir", "Kernel") ~/ ws1 ~ path.opaque("root dir of Kernels") ~ ws

  def jobsFile: Parser[(String, Path)] =
    longOption("jobsFile", "JobsFile") ~/ ws1 ~ path.opaque("path to .json file with jobs array") ~ ws

  def configFile: Parser[(String, Path)] =
    longOption("configFile", "ConfigFile") ~/ ws1 ~ path.opaque("path to .json file with config") ~ ws

  def logFile: Parser[(String, Path)] =
    longOption("logFile", "LogFile") ~ ws ~/ path.opaque("path to logfile") ~ ws

  def dirs: Parser[(String, Path)] =
    archDir | platformDir | kernelDir | compositionDir | coreDir
  def inputFiles: Parser[(String, Path)] =
    jobsFile | configFile | logFile

  def slurm: Parser[(String, Boolean)] =
    longOption("slurm", "Slurm").map((_, true)) ~ ws

  def parallel: Parser[(String, Boolean)] =
    longOption("parallel", "Parallel").map((_, true)) ~ ws

  def dryRun: Parser[(String, Path)] =
    longShortOption("n", "dryRun") ~/ ws ~ path.opaque("output file name") ~/ ws map {
      case (_, p) => ("DryRun", p)
    }

  def maxThreads: Parser[(String, Int)] =
    longOption("maxThreads", "MaxThreads") ~/ ws ~ posint ~ ws

  def globalOptionsSeq: Parser[Seq[(String, _)]] =
79
    ws ~ (help | verbose | dirs | inputFiles | slurm | parallel | dryRun | maxThreads).rep
80

81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
  def globalOptions: Parser[Configuration] =
    globalOptionsSeq map (as => mkConfig(as))

  private def mkConfig[A <: Seq[Tuple2[String, _]]](pa: A, c: Option[Configuration] = None): Configuration =
    pa match {
      case a +: as => a match {
        case ("Architecture", p: Path) => mkConfig(as, Some(c getOrElse Configuration() archDir p))
        case ("Composition", p: Path)  => mkConfig(as, Some(c getOrElse Configuration() compositionDir p))
        case ("Core", p: Path)         => mkConfig(as, Some(c getOrElse Configuration() coreDir p))
        case ("Kernel", p: Path)       => mkConfig(as, Some(c getOrElse Configuration() kernelDir p))
        case ("Platform", p: Path)     => mkConfig(as, Some(c getOrElse Configuration() platformDir p))
        case ("Slurm", e: Boolean)     => mkConfig(as, Some(c getOrElse Configuration() slurm e))
        case ("Parallel", e: Boolean)  => mkConfig(as, Some(c getOrElse Configuration() parallel e))
        case ("JobsFile", p: Path)     => mkConfig(as, Some(c getOrElse Configuration() jobs readJobsFile(p)))
        case ("LogFile", p: Path)      => mkConfig(as, Some(c getOrElse Configuration() logFile Some(p)))
        case ("ConfigFile", p: Path)   => mkConfig(as, Some(loadConfigFromFile(p)))
        case ("DryRun", p: Path)       => mkConfig(as, Some(c getOrElse Configuration() dryRun Some(p)))
        case ("MaxThreads", i: Int)    => mkConfig(as, Some(c getOrElse Configuration() maxThreads Some(i)))
99
100
        case ("Verbose", m: String)    => mkConfig(as, Some(c getOrElse Configuration() verbose Some(m)))
        case _                         => c getOrElse Configuration()
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
      }
      case x => c getOrElse Configuration()
    }

  private def readJobsFile(p: Path): Seq[Job] =
    Json.fromJson[Seq[Job]](Json.parse(Source.fromFile(p.toString).getLines mkString "")) match {
      case s: JsSuccess[Seq[Job]] => s.get
      case e: JsError => throw new Exception(e.toString)
    }

  private def loadConfigFromFile(p: Path): Configuration = Configuration.from(p) match {
    case Right(c) => c
    case Left(e)  => throw e
  }
}