Skip to content

Commit

Permalink
Scala Examples sbt
Browse files Browse the repository at this point in the history
Signed-off-by: Rafael Raposo <[email protected]>
  • Loading branch information
RRap0so committed Aug 5, 2024
1 parent 13f5f88 commit a54f4d6
Show file tree
Hide file tree
Showing 10 changed files with 290 additions and 148 deletions.
1 change: 1 addition & 0 deletions flytekit-examples-scala/.bsp/sbt.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"name":"sbt","version":"1.10.1","bspVersion":"2.1.0-M1","languages":["scala"],"argv":["/Users/rafaelraposo/.sdkman/candidates/java/11.0.22-amzn/bin/java","-Xms100m","-Xmx100m","-classpath","/Users/rafaelraposo/Library/Application Support/JetBrains/IntelliJIdea2024.1/plugins/Scala/launcher/sbt-launch.jar","-Dsbt.script=/Users/rafaelraposo/.sdkman/candidates/sbt/current/bin/sbt","xsbt.boot.Boot","-bsp"]}
10 changes: 10 additions & 0 deletions flytekit-examples-scala/build.sbt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import org.flyte.flytekitscala.FlytekitScalaPlugin

ThisBuild / version := "0.4.60-SNAPSHOT"

ThisBuild / scalaVersion := "2.13.14"

lazy val root = (project in file("."))
.settings(
name := "flytekit-examples-scala_2.13",
).enablePlugins(FlytekitScalaPlugin)
137 changes: 0 additions & 137 deletions flytekit-examples-scala/pom.xml

This file was deleted.

136 changes: 136 additions & 0 deletions flytekit-examples-scala/project/FlytekitScalaPlugin.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
package org.flyte.flytekitscala

import io.github.classgraph.{ClassGraph, ClassInfo, ClassInfoList, ScanResult}
import sbt.Keys._
import sbt._

import scala.collection.JavaConverters.*

object FlytekitScalaPlugin extends AutoPlugin {
val autoImport = FlytekitJavaKeys
import autoImport._

private val MetaInfoServiceFileNames = Seq(
"org.flyte.flytekit.SdkRunnableTask",
"org.flyte.flytekit.SdkDynamicWorkflowTask",
"org.flyte.flytekit.SdkPluginTask",
"org.flyte.flytekit.SdkContainerTask",
"org.flyte.flytekit.SdkWorkflow",
"org.flyte.flytekit.SdkLaunchPlanRegistry"
)

override def trigger: PluginTrigger = noTrigger



override lazy val projectSettings: Seq[Def.Setting[_]] = Seq(
flyteVersion := "0.4.58",
libraryDependencies ++=
Seq(
"org.flyte" % "flytekit-api" % flyteVersion.value,
"org.flyte" %% "flytekit-scala" % flyteVersion.value,
"org.flyte" % "flytekit-testing" % flyteVersion.value % Test
),
// add flyte generated services after compilation as a jar resource
// note that we first have to remove potentially duplicated META-INF/services
// files to address a failure path like:
// $ sbt clean pack
// And then build project in IntelliJ (where generated files are copied to target/classes folder)
// $ sbt pack # this will result duplicated files and fail the build
Compile / packageBin / mappings :=
(Compile / packageBin / mappings).value
.filterNot(v => MetaInfoServiceFileNames.contains(v._1.getName)) ++
flyteGenerateServicesTask(Compile)
.map(_.map(f => (f, s"META-INF/services/${f.getName}")))
.value,
// add flyte generated services after compilation as a test resource
Test / resourceGenerators += flyteGenerateServicesTask(Test)
)

private def flyteGenerateServicesTask(configKey: ConfigKey) = Def.task {
val log = (configKey / streams).value.log
val classPath = (Runtime / fullClasspath).value.map(_.data.getAbsolutePath)
val classGraph = new ClassGraph().overrideClasspath(classPath: _*)
val result = classGraph.enableMethodInfo().scan()
try {
MetaInfoServiceFileNames
.filter(fileName => result.getClassInfo(fileName) != null) // in case old version of flytekit-java
.map { fileName =>
val impls = getClassesImplementingOrExtending(result, fileName, log)
impls.foreach(x => log.info(s"Discovered $fileName: $x"))
val services = impls.mkString("\n")
val file = (configKey / classDirectory).value / "META-INF" / "services" / fileName
IO.write(file, services)
file
}
} finally {
result.close()
}
}

private def getClassesImplementingOrExtending(
result: ScanResult,
className: String,
log: Logger
): List[String] = {
val classesOrInterfaces =
if (result.getClassInfo(className).isInterface) {
result.getClassesImplementing(className)
} else {
result.getSubclasses(className)
}

warnAnonymousClasses(classesOrInterfaces, log)

val subClasses =
classesOrInterfaces
.filter(x => !x.isAbstract && !x.isAnonymousInnerClass)

failIfMissingDefaultConstructor(subClasses, log)

val subInterfaces = classesOrInterfaces.getInterfaces.getNames.asScala.toList
val subAbstractClasses = classesOrInterfaces.filter(_.isAbstract).getNames.asScala.toList

val all = subClasses.getNames.asScala.toList ++
subInterfaces.flatMap(getClassesImplementingOrExtending(result, _, log)) ++
subAbstractClasses.flatMap(getClassesImplementingOrExtending(result, _, log))

all.distinct
}

private def warnAnonymousClasses(
classesOrInterfaces: ClassInfoList,
log: Logger
): Unit = {
classesOrInterfaces
.filter(_.isAnonymousInnerClass)
.forEach(
x =>
log.warn(
s"Anonymous class ${x.getName} cannot be used to implement Flyte entities"
)
)
}

private def failIfMissingDefaultConstructor(classes: ClassInfoList, log: Logger): Unit = {
val classesMissingDefaultConstructor = classes.filter(hasNoDefaultConstructor)

if (!classesMissingDefaultConstructor.isEmpty) {
classesMissingDefaultConstructor.forEach(
x => log.error(s"Class ${x.getName} has no default constructor defined")
)

throw new MessageOnlyException(
"One or more classes implementing Flyte entity have no default constructor defined"
)
}
}

private def hasNoDefaultConstructor(clazz: ClassInfo): Boolean =
clazz.getDeclaredConstructorInfo.filter(_.getParameterInfo.isEmpty).isEmpty
}

object FlytekitJavaKeys {
// don't override defaults for these settings unless you want to use unstable version
lazy val flyteVersion = settingKey[String]("Flyte version")
}
1 change: 1 addition & 0 deletions flytekit-examples-scala/project/build.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
sbt.version = 1.10.1
6 changes: 6 additions & 0 deletions flytekit-examples-scala/project/build.sbt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import scala.collection.immutable.Seq


libraryDependencies ++=Seq(
"io.github.classgraph" % "classgraph" % "4.8.87"
)

This file was deleted.

This file was deleted.

This file was deleted.

Loading

0 comments on commit a54f4d6

Please sign in to comment.