@@ -7,10 +7,10 @@ package play.ebean.sbt
77import java .net .URLClassLoader
88import io .ebean .enhance .Transformer
99import io .ebean .enhance .ant .OfflineFileTransform
10+ import play .sbt .PluginCompat
1011import sbt .Keys ._
1112import sbt .internal .inc .FarmHash
1213import sbt .internal .inc .LastModified
13- import sbt .internal .inc .PlainVirtualFileConverter
1414import sbt .internal .inc .Stamper
1515import sbt .AutoPlugin
1616import sbt .Compile
@@ -19,41 +19,71 @@ import sbt.Task
1919import sbt .inConfig
2020import sbt .settingKey
2121import sbt .taskKey
22+ import xsbti .FileConverter
23+ import xsbti .VirtualFileRef
2224import xsbti .compile .CompileResult
2325import xsbti .compile .analysis .Stamp
2426import sbt ._
25- import xsbti .VirtualFileRef
26- import scala .util .control .NonFatal
2727
2828object PlayEbean extends AutoPlugin {
2929
3030 object autoImport {
31+ @ transient
3132 val playEbeanModels = taskKey[Seq [String ]](" The packages that should be searched for ebean models to enhance." )
3233 val playEbeanVersion =
3334 settingKey[String ](" The version of Play ebean that should be added to the library dependencies." )
3435 val playEbeanDebugLevel = settingKey[Int ](
3536 " The debug level to use for the ebean agent. The higher, the more debug is output, with 9 being the most. -1 turns debugging off."
3637 )
38+ @ transient
3739 val playEbeanAgentArgs = taskKey[Map [String , String ]](" The arguments to pass to the agent." )
3840 }
3941
4042 import autoImport ._
4143
4244 override def trigger = noTrigger
4345
44- override def projectSettings : Seq [Def .Setting [_ ]] = inConfig(Compile )(scopedSettings) ++ unscopedSettings
46+ override def projectSettings : Seq [Def .Setting [? ]] = inConfig(Compile )(scopedSettings) ++ unscopedSettings
4547
46- def scopedSettings : Seq [Def .Setting [_ ]] =
48+ def scopedSettings : Seq [Def .Setting [? ]] =
4749 Seq (
48- playEbeanModels := configuredEbeanModels.value,
49- manipulateBytecode := ebeanEnhance.value
50+ playEbeanModels := PluginCompat .uncached { configuredEbeanModels.value },
51+ manipulateBytecode := PluginCompat .uncached { ebeanEnhance.value },
52+ // sbt 2 / Play can reach compiled classes through these tasks without running compile first,
53+ // so make them trigger enhancement too.
54+ products := {
55+ manipulateBytecode.value
56+ products.value
57+ },
58+ productDirectories := {
59+ manipulateBytecode.value
60+ productDirectories.value
61+ },
62+ exportedProducts := PluginCompat .uncached {
63+ manipulateBytecode.value
64+ exportedProducts.value
65+ },
66+ fullClasspath := PluginCompat .uncached {
67+ manipulateBytecode.value
68+ fullClasspath.value
69+ }
5070 )
5171
52- def unscopedSettings : Seq [Def .Setting [_ ]] =
72+ def unscopedSettings : Seq [Def .Setting [? ]] =
5373 Seq (
5474 playEbeanDebugLevel := - 1 ,
5575 playEbeanAgentArgs := Map (" debug" -> playEbeanDebugLevel.value.toString),
5676 playEbeanVersion := readResourceProperty(" play-ebean.version.properties" , " play-ebean.version" ),
77+ // Test tasks need the already-enhanced main classes on their classpath, otherwise sbt 2
78+ // can run tests against non-enhanced entities even though Compile / manipulateBytecode exists.
79+ Test / dependencyClasspath := PluginCompat .uncached {
80+ (Compile / manipulateBytecode).value
81+ (Test / dependencyClasspath).value
82+ },
83+ Test / fullClasspath := PluginCompat .uncached {
84+ (Compile / manipulateBytecode).value
85+ (Test / fullClasspath).value
86+ },
5787 libraryDependencies ++=
5888 Seq (
5989 " org.playframework" %% " play-ebean" % playEbeanVersion.value,
@@ -73,30 +103,30 @@ object PlayEbean extends AutoPlugin {
73103 val agentArgs = playEbeanAgentArgs.value
74104 val analysis = result.analysis.asInstanceOf [sbt.internal.inc.Analysis ]
75105 val agentArgsString = agentArgs.map { case (key, value) => s " $key= $value" }.mkString(" ;" )
106+ val converter = fileConverter.value
107+ val models = playEbeanModels.value
76108
77109 val originalContextClassLoader = Thread .currentThread.getContextClassLoader
78110
79111 try {
80- val classpath = deps.map(_.data.toURI.toURL).toArray :+ classes.toURI.toURL
112+ implicit val fileConverterCompat : FileConverter = converter
113+ val classpath =
114+ (deps.map(dep => PluginCompat .toNioPath(dep.data).toUri.toURL).toVector :+ classes.toURI.toURL)
115+ .toArray[java.net.URL ]
81116 val classLoader = new URLClassLoader (classpath, null )
82117
83118 Thread .currentThread.setContextClassLoader(classLoader)
84119
85120 val transformer = new Transformer (classLoader, agentArgsString)
86121 val fileTransform = new OfflineFileTransform (transformer, classLoader, classes.getAbsolutePath)
87122
88- try {
89- fileTransform.process(playEbeanModels.value.mkString(" ," ))
90- } catch {
91- case NonFatal (_) =>
92- }
123+ fileTransform.process(models.mkString(" ," ))
93124
94125 } finally {
95126 Thread .currentThread.setContextClassLoader(originalContextClassLoader)
96127 }
97128
98129 val allProducts = analysis.relations.allProducts
99- val converter = new PlainVirtualFileConverter ()
100130
101131 /**
102132 * Updates stamp of product (class file) by preserving the type of a passed stamp. This way any stamp incremental
@@ -136,9 +166,12 @@ object PlayEbean extends AutoPlugin {
136166 // Creates a classloader with all the dependencies and all the resources, from there we can use the play ebean
137167 // code to load the config as it would be loaded in production
138168 def withClassLoader [T ](block : ClassLoader => T ): T = {
139- val classpath =
140- unmanagedResourceDirectories.value.map(_.toURI.toURL) ++ dependencyClasspath.value.map(_.data.toURI.toURL)
141- val classLoader = new URLClassLoader (classpath.toArray, null )
169+ val converter = fileConverter.value
170+ implicit val fileConverterCompat : FileConverter = converter
171+ val classpath =
172+ unmanagedResourceDirectories.value.map(_.toURI.toURL) ++
173+ dependencyClasspath.value.map(dep => PluginCompat .toNioPath(dep.data).toUri.toURL)
174+ val classLoader = new URLClassLoader (classpath.toArray[java.net.URL ], null )
142175 try {
143176 block(classLoader)
144177 } catch {
0 commit comments