Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using SBT to manage projects that contain both Scala and Python

Tags:

python

scala

sbt

In a current project, I've built Python code for interacting with a specific datasource; now, I'm working on building a Scala version.

I've rearranged things so that all of the Python code lives in src/main/python within the SBT project for my Scala code, but this got me thinking: Is there any nice way to integrate the project management between the two? To set up SBT so that I can run my Python distutils installation/sdist generation or sphinx document generation as SBT tasks?

Or, more generally: Is there a standard method for running arbitrary system tasks by way of SBT?

like image 495
Nick Peterson Avatar asked May 13 '15 03:05

Nick Peterson


2 Answers

You can create a python task which zips the source files. This example depends on the assembly task:

  lazy val pythonAssembly = TaskKey[Unit]("pythonAssembly", "Zips all files in src/main/python")

  lazy val pythonAssemblyTask = pythonAssembly := {
    val baseDir = sourceDirectory.value
    val targetDir = assembly.value.getParentFile.getParent
    val target = new File(targetDir + s"/python/rfu-api-client-python-${Commons.appVersion}.zip")
    val pythonBaseDir = new File(baseDir + "/main/python")
    val pythonFiles = Path.allSubpaths(pythonBaseDir)

    println("Zipping files in " + pythonBaseDir)
    pythonFiles foreach { case (_, s) => println(s) }
    IO.zip(pythonFiles, target)
    println(s"Created $target")
like image 110
Mikael Valot Avatar answered Sep 19 '22 19:09

Mikael Valot


To run Python unit tests of python code with SBT test tasks I did this in build.sbt:

//define task that should be run with tests.
val testPythonTask = TaskKey[Unit]("testPython", "Run python tests.")

val command = "python3 -m unittest app_test.py"
val workingDirectory = new File("python/working/directory")

testPythonTask := {
  val s: TaskStreams = streams.value
  s.log.info("Executing task testPython")
  Process(command,
    // optional
    workingDirectory,
    // optional system variables
    "CLASSPATH" -> "path/to.jar",
    "OTHER_SYS_VAR" -> "other_value") ! s.log
}

//attach custom test task to default test tasks
test in Test := {
  testPythonTask.value
  (test in Test).value
}

testOnly in Test := {
  testPythonTask.value
  (testOnly in Test).value
}
like image 43
Eugene Lopatkin Avatar answered Sep 19 '22 19:09

Eugene Lopatkin