Parse and resolve Play! project configuration from external tool

configuration

(Adrian) #1

Hi,

I am trying to build a tool that when run inside a Play! 2.6+ project folder loads and resolves the application configuration, including any reference.conf or application.conf present in dependency jars, in the same way the Play! server does upon start to account for overrides and merges. The goal is to be able to analyze the configuration values to alert the user of anti patterns, security weaknesses, or standard deviations present in the settings.

Ideally, I wouldn’t have to start up the Play! application to achieve this, but I am not sure if that’s even possible.

The way I started going about this is to define my own Application object with a CustomApplicationLoader, and fiddle with the Environment, ServcerConfig, Configuration, and Mode objects to try and parse the configuration the same way the application under analysis would, but it quickly becomes complicated and it doesn’t seem to capture all .conf files anyway. Something along these lines:

object Main extends App {
  new CustomApplicationLoader
  /*
    Extracted from DevServerStart and ApplicationLoader
   */
  val path = new File("/Users/adrian/code/playProject/") // originally BuildLink.projectPath from the run plugin
  val dirAndDevSettings: Map[String, String] = ServerConfig.rootDirConfig(path) ++ buildLink.settings.asScala.toMap
  val environment = Environment(path, projectClassloader, Mode.Dev)
  val configuration = Configuration.load(environment, dirAndDevSettings)
}
class CustomApplicationLoader extends GuiceApplicationLoader {

  override def builder(context: ApplicationLoader.Context): GuiceApplicationBuilder = {

    initialBuilder
      .in(context.environment)
      .overrides(overrides(context): _*)
  }
}

I would appreciate any pointers to direct my efforts to either pieces of Play! / sbt code or a better approach to achieve this.

Thanks!


(Adrian) #2

I’m still digging through Play!'s and sbt’s source to find the best way around this, but I figured I’d bubble this up in case anyone has any good pointers.

Thanks!


(Marcos Pereira) #3

Hi @adrian,

I think you can have a sbt plugin that does that, having the same logic Play has to load the configuration:

Of course you don’t need all the parameters there, but you need a ClassLoader. I know that there are some utilities to get a ClassLoader from the classpath (fullclasspath in Runtime, from sbt), but I don’t where to point you to here. Maybe check how it is done for the test task.

Hope this helps. :slight_smile:


(Adrian) #4

Thanks, @marcospereira. I’ll try that avenue and see where I get!