Sometimes you need to automate maintenance tasks in your Play application (e.g.
import data from CSV file into your app’s database, generate a report…).
To do anything useful you need the proper classpath and probably a connection to
the database using the same infrastructure normally used by the application.
This is very similar to how tests are run. In this post I will show how I
created a Scripts object that takes care of the FakeApplication
initialization to allow simple script creation and usage from the
test:console.
The Scripts object
Place a Scripts.scala file inside the test folder. This is required as the
files inside this folder are compiled with a classpath that includes the
play.api.test._ symbols.
// I'm using Slick and I will need these to pass the Slick sessions to the scriptsimportscala.slick.session.Databaseimportscala.slick.session.Session// FakeApplication and the running() helperimportplay.api.test._importplay.api.test.Helpers._importplay.api.db.DB// Where I place the actual scripts and utilities (e.g. JogosCSVImporter)importtools._objectScripts{// Declare this implicit to have it easily passed to DB.getDataSource()privateimplicitlazyvalapplication=FakeApplication()// Lazily initialized Slick Databaseprivatelazyvaldb=Database.forDataSource(DB.getDataSource())/** * $ play test:console * > Scripts.importJogosFromCSV("path/to/file.csv") */defimportJogosFromCSV(csvFilePath:String)={dbwithSession{implicits:Session=>JogosCSVImporter.importJogos(csvFilePath)}}}
JogosCSVImporter
To minimize the code in the test folder place the JogosCSVImporter object
inside the app/tools folder.
Implementation of the JogosCSVImporter Script
1234567891011121314151617181920
packagetoolsimportscala.slick.jdbc.{StaticQuery=>Q}importscala.slick.session.Sessionimportscala.slick.session.Database// My Slick Tablesimporttables._importutils.CSVobjectJogosCSVImporter{...// The implicit Session will be accessible to all the script code and will// be passed automatically to functions that require a Slick Session.defimportJogos(csvFilePath:String)(implicits:Session):Int={...}}
Using scripts in the test:console
Implementation of the JogosCSVImporter Script
1
$playtest:console#startthetestconsole
In the test:console you can call any Scripts.\_ without worring about the
classpath or any context initialization.