2015-08-09 3 views
7

Я намереваюсь создавать ресурсы на основе шаблонов и параметров sbt. Должны быть разные настройки sbt для Compile и Test. Шаблоны находятся в project/resources/hdfs/*.xml. Из чата sbt-dev gitter у меня была рекомендация использовать Setting и inConfig, но я не мог заставить его работать.Сгенерировать ресурсы для компиляции и тестирования

код до сих пор:

val hdfsNamenode = settingKey[String]("Namenode for the HDFS access") 

def genHdfsConfigs: Setting[_] = 
    hdfsNamenode := { 
    resourceGenerators += Def.task { 
     val files = ((baseDirectory.value/"project"/"resources"/"hdfs") * "*.xml").get 
     files.foreach({ hdfsTemplate => 
     val config = IO.read(hdfsTemplate).replace("{{namenode}}", hdfsNamenode.value) 
     IO.write(resourceManaged.value/hdfsTemplate.getName, config) 
     }) 
     files.toSeq 
    }.taskValue 
    } 

hdfsNamenode in Test := "localhost" 
hdfsNamenode in Compile := "172.31.32.228" 

def allHdfsNamenodeConfigs: Seq[Setting[_]] = 
    inConfig(Compile)(Seq(hdfsNamenode)) ++ inConfig(Test)(Seq(hdfsNamenode)) 

Ошибка:

[error] found : sbt.Def.Setting[Seq[sbt.Task[Seq[java.io.File]]]] 
[error] required: String 
[error]  resourceGenerators += Def.task { 
[error]      ^

[error] found : sbt.SettingKey[String] 
[error] required: sbt.Def.Setting[_] 
[error]  inConfig(Compile)(Seq(hdfsNamenode)) ++ inConfig(Test)(Seq(hdfsNamenode)) 
[error]   

Следующая итерация, я не знаю, как получить hdfsNameNode в рамках Compile/Test вместо незаданного.

(некрасиво) раствор
lazy val hdfsNameNode = settingKey[String]("Namenode for the HDFS access") 

val genHdfsConfig = Def.task { 
    val files = ((baseDirectory.value/"project"/"templates"/"resources"/"hdfs") * "*.xml").get 
    files.map({ hdfsTemplate => 
    val config = IO.read(hdfsTemplate).replace("{{namenode}}", hdfsNameNode.value) 
    val outputPath = resourceManaged.value/hdfsTemplate.getName 
    IO.write(outputPath, config) 
    outputPath 
    }) 
} 

Seq(
    hdfsNameNode := "undefined", // Only this one is accepted 
    hdfsNameNode in Test := "localhost", 
    hdfsNameNode in Compile := "172.31.32.228", 
    resourceGenerators in Compile += genHdfsConfig.taskValue, 
    resourceGenerators in Test += genHdfsConfig.taskValue 
) 

ток:

val hdfsTestNameNode = "localhost" 
val hdfsMainNameNode = "172.31.32.228" 

val hdfsNameNode = settingKey[String]("Namenode for the HDFS access") 

val genTestHdfsConfig = Def.task { 
    val files = ((baseDirectory.value/"project"/"templates"/"resources"/"hdfs") * "*.xml").get 
    files.map({ hdfsTemplate => 
    val config = IO.read(hdfsTemplate).replace("{{namenode}}", (hdfsNameNode in Test).value) 
    val outputPath = resourceManaged.value/hdfsTemplate.getName 
    IO.write(outputPath, config) 
    outputPath 
    }) 
} 

val genCompileHdfsConfig = Def.task { 
    val files = ((baseDirectory.value/"project"/"templates"/"resources"/"hdfs") * "*.xml").get 
    files.map({ hdfsTemplate => 
    val config = IO.read(hdfsTemplate).replace("{{namenode}}", (hdfsNameNode in Compile).value) 
    val outputPath = resourceManaged.value/hdfsTemplate.getName 
    IO.write(outputPath, config) 
    outputPath 
    }) 
} 

Seq(
    hdfsNameNode in Test := hdfsTestNameNode, 
    hdfsNameNode in Compile := hdfsMainNameNode, 
    resourceGenerators in Compile += genCompileHdfsConfig.taskValue, 
    resourceGenerators in Test += genTestHdfsConfig.taskValue 
) 
+0

Эта вещь с 'Def.task' и' .taskValue' выглядит сложной для меня. Возможно, это было необходимо для старых версий sbt? Вы просмотрели http://www.scala-sbt.org/0.13/tutorial/Custom-Settings.html#Implementing+a+task - это должно быть так же просто, как 'taskKey' и': = '. –

+0

@ 0__, то я не знаю, как добавить его в 'resourceGenerators', чтобы его подхватили. – Reactormonk

ответ

6

Просто передайте конфигурации в качестве аргумента при определении вашего генератора ресурсов.

val hdfsTestNameNode = "localhost" 
val hdfsMainNameNode = "172.31.32.228" 

val hdfsNameNode = settingKey[String]("Namenode for the HDFS access") 

def genHdfsConfig(cfg: Configuration) = Def.task { 
    val files = ((baseDirectory.value/"project"/"templates"/"resources"/"hdfs") * "*.xml").get 
    files.map({ hdfsTemplate => 
    val config = IO.read(hdfsTemplate).replace("{{namenode}}", (hdfsNameNode in cfg).value) 
    val outputPath = (resourceManaged in cfg).value/hdfsTemplate.getName 
    IO.write(outputPath, config) 
    outputPath 
    }) 
} 

Seq(
    hdfsNameNode in Test := hdfsTestNameNode, 
    hdfsNameNode in Compile := hdfsMainNameNode, 
    resourceGenerators in Compile += genHdfsConfig(Compile).taskValue, 
    resourceGenerators in Test += genHdfsConfig(Test).taskValue 
) 

Не хотите указывать область действия дважды? Просто реорганизуйте немного больше.

val hdfsTestNameNode = "localhost" 
val hdfsMainNameNode = "172.31.32.228" 

val hdfsNameNode = settingKey[String]("Namenode for the HDFS access") 

def addHdfsConfigGenerator(cfg: Configuration) = { 
    inConfig(cfg) { 
    val hdfsConfigGenerator = Def.task { 
     val files = ((baseDirectory.value/"project"/"templates"/"resources"/"hdfs") * "*.xml").get 
     files.map({ hdfsTemplate => 
     val config = IO.read(hdfsTemplate).replace("{{namenode}}", (hdfsNameNode in cfg).value) 
     val outputPath = (resourceManaged in cfg).value/hdfsTemplate.getName 
     IO.write(outputPath, config) 
     outputPath 
     }) 
    } 
    resourceGenerators += hdfsConfigGenerator.taskValue 
    } last 
} 

Seq(
    hdfsNameNode in Test := hdfsTestNameNode, 
    hdfsNameNode in Compile := hdfsMainNameNode, 
    addHdfsConfigGenerator(Compile), 
    addHdfsConfigGenerator(Test) 
) 
+0

Я надеялся, что будет такой способ, не указывая область действия дважды. – Reactormonk

+0

Просто сделайте немного больше рефакторинга, см. Мое обновление. – thirstycrow

+0

Я искал решение sbt-refactoring, но это работает так же хорошо. – Reactormonk

Смежные вопросы