sbt/contraband

+generateContrabands doesn't work with crossScalaVersions

Closed this issue · 2 comments

When I run +generateContrabands, it will only generate the classes for the first Scala version. After that, the sbt FileFunction.cached method skips generating the code for the other Scala version.

I used the following sbt code in my local project to work around the issue:

lazy val myProject = (project in "myProject").enablePlugins(ContrabandPlugin).settings(
  inConfig(Compile)(Seq(
    scalacOptions := Seq(),
    libraryDependencies ++= (generateContrabands / contrabandCodecsDependencies).value,
    generateContrabands := {
      val generatedSourceCode = generateContrabands.value
      // clear out the gen-api cache, so that crossScalaVersions will generate the code for Scala 2.13
      (streams.value.cacheDirectory / "gen-api").delete()
      generatedSourceCode
    }
  ))
)

This would generate two separate src_managed folders in my target directory per Scala version. However, this requires regenerating the source code on every compile.

Can we use per Scala version caching rather than across all Scala versions?

I was having trouble the work-around listed above, so I opt-ed to just create separate sbt projects per-Scala version and this fixed the issue.

This was another work-around that worked (although I think you could invalidate the whole cache directory by just deleting it rather than only deleting the in-cache directory):

.settings(
  inConfig(Compile)(Seq(
    scalacOptions := Seq(),
    libraryDependencies ++= (generateContrabands / contrabandCodecsDependencies).value,
    generateContrabands := {
      // clear out the gen-api cache, so that crossScalaVersions will generate the code for Scala 2.13
      val s = streams.value
      val genSubDirName = "gen-api"
      val inCacheSuffix = "in-cache"
      s.cacheStoreFactory.sub(genSubDirName).make(inCacheSuffix).delete()
      val inCacheDir = s.cacheDirectory / genSubDirName / inCacheSuffix
      val wasDeleted = !inCacheDir.isDirectory && !inCacheDir.exists
      def message = s"Contraband cache directory '$inCacheDir' ${
        if (wasDeleted) "was successfully deleted"
        else "could not be deleted"
      }.\nThis is needed to generateContrabands for other Scala versions."
      if (wasDeleted) {
        s.log.info(message)
      } else {
        s.log.error(message)
      }
      generateContrabands.value
    }
  ))
)