diff options
Diffstat (limited to 'tools/gui/src/ProjectBuilder.scala')
-rw-r--r-- | tools/gui/src/ProjectBuilder.scala | 149 |
1 files changed, 149 insertions, 0 deletions
diff --git a/tools/gui/src/ProjectBuilder.scala b/tools/gui/src/ProjectBuilder.scala new file mode 100644 index 0000000..ceba376 --- /dev/null +++ b/tools/gui/src/ProjectBuilder.scala @@ -0,0 +1,149 @@ +import java.io.File +import java.nio.file._ + +import Main.StringExtensionMethods + +import scala.io.Source + +class ProjectBuilder( + name: String, + defaultPackage: String, + dependencyString: String, + flagsString: String, + location: File, + scalaMajorVersion: String +) { + + private val newLine = System.lineSeparator() + private val blankLine = newLine + newLine + private val templateDir = System.getenv("CBT_HOME") / "tools" / "gui" / "resources" / "template-project" + private val projectPath = location.getPath / name + private val buildDir = projectPath / "build" + private val mainDir = projectPath / "src" / "main" / "scala" / defaultPackage.split("\\.").reduce(_ / _) + private val testDir = projectPath / "src" / "test" / "scala" / defaultPackage.split("\\.").reduce(_ / _) + + private val dependencies = + if (dependencyString.isEmpty) + "" + else { + def parseDependencies(input: String): Seq[Dependency] = { + input.split(" ").map { x => + val xs = x.split("/") + Dependency(xs(0), xs(1), xs(2)) + } + } + + val list = parseDependencies(dependencyString) + val str = list.map(" " ++ _.serialized).mkString(s",$newLine") + s""" override def dependencies = { + | super.dependencies ++ Resolver(mavenCentral).bind( + |$str + | ) + | }""".stripMargin + } + + private val flags = { + val map = flagsString.split(" ").map { x => + val Array(a, b) = x.split("/") + (a, b) + }.toMap + Flags(map("readme") == "true", map("dotty") == "true", map("uberJar") == "true", map("wartremover") == "true") + } + + private val plugins = { + var content = "" + if (flags.dotty) + content += " with Dotty" + if (flags.uberJar) + content += " with UberJar" + if (flags.wartremover) + content += " with WartRemover" + content + } + + private val buildBuildDependencies = { + var content = "" + if (flags.uberJar) + content += " :+ plugins.uberJar" + if (flags.wartremover) + content += " :+ plugins.wartremover" + content + } + + def build(): Unit = { + new File(buildDir).mkdirs() + new File(mainDir).mkdirs() + new File(testDir).mkdirs() + addBuild() + if (buildBuildDependencies.nonEmpty) + addBuildBuild() + addMain() + addReadme(flags) + } + + private def writeTemplate(templatePath: String, targetPath: String, replacements: (String, String, String)*) = { + var content = Source.fromFile(templatePath).mkString + for (replacement <- replacements) + if (replacement._1.nonEmpty) + content = content.replace(replacement._3, replacement._2) + else + content = content.replace(replacement._3, "") + write(new File(targetPath), content, StandardOpenOption.CREATE_NEW) + } + + private def addBuild() = + writeTemplate( + templateDir / "build" / "build.scala", + buildDir / "build.scala", + (name, s""" override def projectName = "$name"$blankLine""", "##projectName##"), + (dependencyString, dependencies + blankLine, "##dependencies##"), + (plugins, plugins, "##with##") + ) + + private def addBuildBuild() = + writeTemplate( + templateDir / "build" / "build" / "build.scala", + buildDir / "build" / "build.scala", + (buildBuildDependencies, buildBuildDependencies, "##plus##") + ) + + private def addMain() = + writeTemplate( + templateDir / "src" / "main" / "scala" / "Main.scala", + mainDir / "Main.scala", + (defaultPackage, s"package $defaultPackage$blankLine", "##package##") + ) + + private def addReadme(flags: Flags) = { + if (flags.readme) { + val content = + if (name.nonEmpty) + s"# $name$blankLine" + else + "" + write(new File(projectPath / "readme.md"), content, StandardOpenOption.CREATE_NEW) + } + } + + private case class Dependency(group: String, artifact: String, version: String) { + val nameVersion = """^(.+)_(\d+\.\d+)$""".r + val (name, scalaVersion) = artifact match { + case nameVersion(n, v) => (n, Some(v)) + case str => (str, None) + } + + def serialized = + if (scalaVersion.contains(scalaMajorVersion)) + s"""ScalaDependency("$group", "$name", "$version")""" + else + s"""MavenDependency("$group", "$artifact", "$version")""" + } + + private def write(file: File, content: String, option: OpenOption) = { + file.getParentFile.mkdirs() + Files.write(file.toPath, content.getBytes, option) + } + + private case class Flags(readme: Boolean, dotty: Boolean, uberJar: Boolean, wartremover: Boolean) + +} |