diff --git a/build.sbt b/build.sbt index d84dcfee1..4151bcc77 100644 --- a/build.sbt +++ b/build.sbt @@ -104,75 +104,23 @@ lazy val sources = (project in file("sources")) ) ) -val generateSnapiParser = taskKey[Unit]("Generated antlr4 base SNAPI parser and lexer") - lazy val snapiParser = (project in file("snapi-parser")) + .enablePlugins(GenParserPlugin) .settings( commonSettings, commonCompileSettings, + javaSrcBasePath := s"${baseDirectory.value}/src/main/java", + parserDefinitions := List( + (s"${javaSrcBasePath.value}/raw/compiler/rql2/generated", + "raw.compiler.rql2.generated", + s"${javaSrcBasePath.value}/raw/snapi/grammar", + "Snapi") + ), Compile / doc := { file("/dev/null") }, compileOrder := CompileOrder.JavaThenScala, libraryDependencies ++= Seq( antlr4Runtime ), - generateSnapiParser := { - // List of output paths - val basePath: String = s"${baseDirectory.value}/src/main/java" - val parsers = List( - ( - s"$basePath/raw/compiler/rql2/generated", - "raw.compiler.rql2.generated", - s"$basePath/raw/snapi/grammar", - "Snapi" - ) - ) - def deleteRecursively(file: File): Unit = { - if (file.isDirectory) { - file.listFiles.foreach(deleteRecursively) - } - if (file.exists && !file.delete()) { - throw new IOException(s"Failed to delete ${file.getAbsolutePath}") - } - } - val s: TaskStreams = streams.value - parsers.foreach(parser => { - val outputPath = parser._1 - val file = new File(outputPath) - if (file.exists()) { - deleteRecursively(file) - } - val packageName: String = parser._2 - val jarName = "antlr-4.12.0-complete.jar" - val command: String = s"java -jar $basePath/antlr4/$jarName -visitor -package $packageName -o $outputPath" - val output = new StringBuilder - val logger = ProcessLogger( - (o: String) => output.append(o + "\n"), // for standard output - (e: String) => output.append(e + "\n") // for standard error - ) - val grammarPath = parser._3 - val grammarName = parser._4 - val lexerResult = s"$command $grammarPath/${grammarName}Lexer.g4".!(logger) - if (lexerResult == 0) { - s.log.info("Lexer code generated successfully") - } else { - s.log.error("Lexer code generation failed with exit code " + lexerResult) - s.log.error("Output:\n" + output.toString) - } - val parserResult = s"$command $grammarPath/${grammarName}Parser.g4".!(logger) - if (parserResult == 0) { - s.log.info("Parser code generated successfully") - } else { - s.log.error("Parser code generation failed with exit code " + lexerResult) - s.log.error("Output:\n" + output.toString) - } - }) - }, - Compile / compile := (Compile / compile).dependsOn(generateSnapiParser).value, - Compile / doc := (Compile / doc).dependsOn(generateSnapiParser).value, - Test / compile := (Test / compile).dependsOn(generateSnapiParser).value, - publish := (publish dependsOn generateSnapiParser).value, - publishLocal := (publishLocal dependsOn generateSnapiParser).value, - publishSigned := (publishSigned dependsOn generateSnapiParser).value ) lazy val snapiFrontend = (project in file("snapi-frontend")) @@ -285,70 +233,24 @@ lazy val snapiClient = (project in file("snapi-client")) testSettings ) -val generateSqlParser = taskKey[Unit]("Generated antlr4 base SQL parser and lexer") lazy val sqlParser = (project in file("sql-parser")) + .enablePlugins(GenParserPlugin) .settings( commonSettings, commonCompileSettings, + javaSrcBasePath := s"${baseDirectory.value}/src/main/java", + parserDefinitions := List( + (s"${javaSrcBasePath.value}/raw/client/sql/generated", + "raw.client.sql.generated", + s"${javaSrcBasePath.value}/raw/psql/grammar", + "Psql") + ), Compile / doc := { file("/dev/null") }, compileOrder := CompileOrder.JavaThenScala, libraryDependencies ++= Seq( - antlr4Runtime - ), - generateSqlParser := { - // List of output paths - val basePath: String = s"${baseDirectory.value}/src/main/java" - val parsers = List( - (s"$basePath/raw/client/sql/generated", "raw.client.sql.generated", s"$basePath/raw/psql/grammar", "Psql") - ) - def deleteRecursively(file: File): Unit = { - if (file.isDirectory) { - file.listFiles.foreach(deleteRecursively) - } - if (file.exists && !file.delete()) { - throw new IOException(s"Failed to delete ${file.getAbsolutePath}") - } - } - val s: TaskStreams = streams.value - parsers.foreach(parser => { - val outputPath = parser._1 - val file = new File(outputPath) - if (file.exists()) { - deleteRecursively(file) - } - val packageName: String = parser._2 - val jarName = "antlr-4.12.0-complete.jar" - val command: String = s"java -jar $basePath/antlr4/$jarName -visitor -package $packageName -o $outputPath" - val output = new StringBuilder - val logger = ProcessLogger( - (o: String) => output.append(o + "\n"), // for standard output - (e: String) => output.append(e + "\n") // for standard error - ) - val grammarPath = parser._3 - val grammarName = parser._4 - val lexerResult = s"$command $grammarPath/${grammarName}Lexer.g4".!(logger) - if (lexerResult == 0) { - s.log.info("Lexer code generated successfully") - } else { - s.log.error("Lexer code generation failed with exit code " + lexerResult) - s.log.error("Output:\n" + output.toString) - } - val parserResult = s"$command $grammarPath/${grammarName}Parser.g4".!(logger) - if (parserResult == 0) { - s.log.info("Parser code generated successfully") - } else { - s.log.error("Parser code generation failed with exit code " + lexerResult) - s.log.error("Output:\n" + output.toString) - } - }) - }, - Compile / compile := (Compile / compile).dependsOn(generateSqlParser).value, - Compile / doc := (Compile / doc).dependsOn(generateSqlParser).value, - Test / compile := (Test / compile).dependsOn(generateSqlParser).value, - publish := (publish dependsOn generateSqlParser).value, - publishLocal := (publishLocal dependsOn generateSqlParser).value, - publishSigned := (publishSigned dependsOn generateSqlParser).value + antlr4Runtime, + ) ) lazy val sqlClient = (project in file("sql-client")) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 2eb8b58ee..e8f0ad589 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -53,6 +53,8 @@ object Dependencies { // from snapi-parser val antlr4Runtime = "org.antlr" % "antlr4-runtime" % "4.12.0" + val antlr4 = "org.antlr" % "antlr4-maven-plugin" % "4.12.0" + // from snapi-frontend val kiamaVersion = IO.read(new File("./deps/kiama/version")).trim val kiama = "org.bitbucket.inkytonik.kiama" %% "kiama" % kiamaVersion diff --git a/project/GeneratePlugin.scala b/project/GenParserPlugin.scala similarity index 66% rename from project/GeneratePlugin.scala rename to project/GenParserPlugin.scala index b2b7b76a6..ad4e910da 100644 --- a/project/GeneratePlugin.scala +++ b/project/GenParserPlugin.scala @@ -1,30 +1,33 @@ package raw.build -import sbt._ import sbt.Keys._ -import scala.sys.process._ +import sbt.{ Def, _ } +import com.jsuereth.sbtpgp.PgpKeys.{publishSigned} +import sbt.plugins.JvmPlugin import java.io.IOException +import scala.sys.process._ -import com.jsuereth.sbtpgp.PgpKeys.{publishSigned} -object Generate extends AutoPlugin { - // Task keys - val generateParser = taskKey[Unit]("Generated antlr4 base parser and lexer") +object GenParserPlugin extends AutoPlugin { + override def requires = JvmPlugin + override def trigger: PluginTrigger = noTrigger + + // Task keys + object autoImport { + val generateParser = taskKey[Unit]("Generated antlr4 base parser and lexer") + val parserDefinitions = settingKey[List[(String, String, String, String)]]("List of parser definitions with output path first followed by the name of the generated package") + val javaSrcBasePath = settingKey[String]("Java src relative path") + } - // Automatically enable this plugin (set to noTrigger if you want to enable it manually) - override def trigger = noTrigger + import autoImport._ // Provide default settings override def projectSettings: Seq[Def.Setting[_]] = Seq( - generateParser := { - - // List of output paths - val basePath: String = s"${baseDirectory.value}/src/main/java" - val parsers = List( - (s"${basePath}/raw/compiler/rql2/generated", "raw.compiler.rql2.generated", s"$basePath/raw/snapi/grammar", "Snapi"), - ) + generateParser := { + val basePath: String = javaSrcBasePath.value + val parsers = parserDefinitions.value def deleteRecursively(file: File): Unit = { if (file.isDirectory) { file.listFiles.foreach(deleteRecursively) @@ -33,33 +36,23 @@ object Generate extends AutoPlugin { throw new IOException(s"Failed to delete ${file.getAbsolutePath}") } } - val s: TaskStreams = streams.value - parsers.foreach(parser => { - val outputPath = parser._1 - val file = new File(outputPath) if (file.exists()) { deleteRecursively(file) } - val packageName: String = parser._2 - val jarName = "antlr-4.12.0-complete.jar" - val command: String = s"java -jar $basePath/antlr4/$jarName -visitor -package $packageName -o $outputPath" - val output = new StringBuilder val logger = ProcessLogger( (o: String) => output.append(o + "\n"), // for standard output (e: String) => output.append(e + "\n") // for standard error ) - val grammarPath = parser._3 val grammarName = parser._4 - val lexerResult = s"$command $grammarPath/${grammarName}Lexer.g4".!(logger) if (lexerResult == 0) { s.log.info("Lexer code generated successfully") @@ -67,7 +60,6 @@ object Generate extends AutoPlugin { s.log.error("Lexer code generation failed with exit code " + lexerResult) s.log.error("Output:\n" + output.toString) } - val parserResult = s"$command $grammarPath/${grammarName}Parser.g4".!(logger) if (parserResult == 0) { s.log.info("Parser code generated successfully") @@ -76,6 +68,12 @@ object Generate extends AutoPlugin { s.log.error("Output:\n" + output.toString) } }) - } + }, + parserDefinitions := List(), + javaSrcBasePath := "", + Compile / compile := (Compile / compile).dependsOn(generateParser).value, + Test / test := (Test / test).dependsOn(generateParser).value, + publish := publish.dependsOn(generateParser).value, + publishSigned := publishSigned.dependsOn(generateParser).value ) }