Scala 如何动态';注入';使用SBT在运行任务中的文件中定义的环境变量

Scala 如何动态';注入';使用SBT在运行任务中的文件中定义的环境变量,scala,playframework,sbt,environment-variables,Scala,Playframework,Sbt,Environment Variables,我正在寻找一种从动态文件将环境变量注入SBT任务的方法 例如:sbt-run-dev或sbt-dev:run或sbt-dev-run在注入文件conf/env/database.dev中定义的环境变量后启动sbt-run任务 目前,我在build.sbt中有此代码: // ... val dev = taskKey[Unit]("Dev config") val local = taskKey[Unit]("Local config") def setEnvVar(env: String) =

我正在寻找一种从动态文件将环境变量注入SBT任务的方法

例如:
sbt-run-dev
sbt-dev:run
sbt-dev-run
在注入文件
conf/env/database.dev中定义的环境变量后启动sbt-run任务

目前,我在
build.sbt
中有此代码:

// ...
val dev = taskKey[Unit]("Dev config")
val local = taskKey[Unit]("Local config")

def setEnvVar(env: String) = {
  try{
    val split: Array[String] = (s"cat conf/env/database.$env" !!).split("\\n")
    val raw_vars = split.map(_.span(! _.equals('='))).map(x => x._1 -> x._2.tail).toList
    raw_vars foreach (v => {
      println(s"INJECTING ${v._1} = ${v._2}")
      javaOptions += s"-D${v._1}=${v._2}"
    })
  }catch{
    case e: Exception => println(s"Cannot inject env vars (${e.getMessage})")
  }
}


dev := {
  setEnvVar("dev")
}

local := {
  setEnvVar("local")
}
当我启动
sbt dev run
时,我得到以下结果:

[info] Loading project definition from ...
[info] Set current project to ...
INJECTING PG_DB = qgd
INJECTING PG_HOST = localhost
INJECTING PG_PORT = 5432
INJECTING PG_USERNAME = ...
INJECTING PG_PASSWORD = ...
[success] Total time: 0 s, completed 12 févr. 2016 10:46:10

--- (Running the application, auto-reloading is enabled) ---

[info] p.c.s.NettyServer - Listening for HTTP on /0:0:0:0:0:0:0:0:9000

(Server started, use Ctrl+D to stop and go back to the console...)
但是,当我转到
localhost:9000
时,我可以看到变量没有被注入

在my application.conf中:

// ...
pg.db               = ${?PG_DB}
pg.host             = ${?PG_HOST}
pg.port             = ${?PG_PORT}
pg.default.username = ${?PG_USERNAME}
pg.default.password = ${?PG_PASSWORD}
// ...

你有什么办法解决我的问题吗?

正如@AjayPadala所建议的,我使用fork流程解决了我的问题

我刚刚用以下代码更新了以前的代码:

fork := true // <=======================

val dev = taskKey[Unit]("Dev config")
val local = taskKey[Unit]("Local config")

def setEnvVar(env: String) = {
  try{
    val split: Array[String] = (s"cat conf/env/database.$env" !!).split("\\n")
    val raw_vars = split.map(_.span(! _.equals('='))).map(x => x._1 -> x._2.tail).toList
    val sysProp = System.getProperties // <=======================
    raw_vars foreach (v => {
      println(s"INJECTING ${v._1} = ${v._2}")
      sysProp.put(v._1, v._2) // <=======================
    })
    System.setProperties(sysProp) // <=======================
  }catch{
    case e: Exception => println(s"Cannot inject env vars (${e.getMessage})")
  }
}


dev := {
  setEnvVar("dev")
}

local := {
  setEnvVar("dev.default")
}
fork:=true//x.\u 1->x.\u 2.tail).toList
val sysProp=System.getProperties//{
println(s“注入${v.'u 1}=${v.'u 2}”)

系统属性put(v.。_1,v._2)//我不知道它为什么会失败,与其说它是一个游戏框架,不如说它是一个SBT问题。但是,为什么不按照游戏中的标准方法,在每个环境中定义不同的配置文件,并使用-Dconfig.file=application-dev.conf运行呢?Reference可能需要设置fork:=true,以使用这些环境变量set.t启动一个新进程谢谢你的回答。@JonasAnso:是的,我同意。但我的目标是使用类似于
sbt dev run
。所以,你的建议对我来说有点太长了。@AjayPadala:分叉是个很好的主意。而且效果很好。(见我的答案)