scala - how to deal with a sbt multi project with non-standard artifacts? -


what trying do:

first, let me present (very) simplified version of i'm trying achieve. consider following multi-project:

root |___backend |    |___frontend | |___deployer 

the backend packaged onejar, , performs standalone process background work. frontend web-service play project (packaged zip file dist). deployer yet self executable jar packaged onejar, packaging modified include other projects artifacts. deployer job initialize system. deploys other artifacts specified machines, , initializes distributed system.

what problem:

basically, i'm trying (unsuccessfully) play's dist zip artifact & backend onejar self executable artifact packaged inside deployer jar (with other resources files)

the deployer jar should like:

deployer-executable.jar |___0/ |   |___backend-selfexec.jar |   |___frontenf-dist.zip | |___1/ |   |___other resources (mostly configuration files) |   |___ ... | |___meta-inf/ ... |___com/simontuffs/onejar/ ... |___doc/ ... |___lib/ ... |___main/deployer-version.jar |___other resources (such logback.xml) , onejar files.... 

what have far:

build.sbt

...  lazy val backend = project in file("backend")   lazy val frontend = project in file("frontend")   lazy val deployer = project in file("deployer") dependson(backend % "optional->compile", frontend % "optional->compile")    aggregate(backend, frontend)  ... 

backend/build.sbt

...  seq(com.github.retronym.sbtonejar.onejarsettings: _*)  exportjars := true  mainclass in onejar := some("org.product.backend.main")  artifact in onejar <<= modulename(artifact(_, "selfexec"))  addartifact(artifact in (compile, onejar), onejar)  ... 

frontend/build.sbt

import play.project._  ...  play.project.playscalasettings  lazy val dist = com.typesafe.sbt.sbtnativepackager.nativepackagerkeys.dist  lazy val publishdist = taskkey[sbt.file]("publish-dist", "publish dist artifact")  publish <<= (publish) dependson dist  publishlocal <<= (publishlocal) dependson dist  artifact in publishdist ~= {   (art: artifact) => art.copy(`type` = "zip", extension = "zip", classifier = some("dist")) }  publishdist <<= (target in universal, normalizedname, version) map { (targetdir, id, version) =>   val packagename = s"$id-$version"   targetdir / (packagename + ".zip") }  addartifact(artifact in publishdist, publishdist)  ... 

deployer/build.sbt

...  seq(com.github.retronym.sbtonejar.onejarsettings: _*)  exportjars := true  mainclass in onejar := some("org.product.deployer.main")  unmanagedresources in compile := seq() //don't add resources "src/main/resources" inner jar, fat one-jar.  classpathtypes :=  classpathtypes.value + "zip" //don't ommit dist zip file classpath  mappings in onejar := {     def isneedtobeindir0(f: file) = f.getname == "frontend-version-dist.zip" || f.getname == "backend-version-selfexec.jar"     def nameforpackaging(name: string): string = if(name.contains("frontend")) "frontend.zip" else "backend.jar"     //following method replaced with: http://www.scala-sbt.org/release/docs/detailed-topics/mapping-files.html#relative-to-a-directory     def files2tuplerec(pathprefix: string, dir: file): seq[tuple2[file,string]] = {         sbt.io.listfiles(dir) flatmap {             f => {                 if(f.isfile) seq((f,s"${pathprefix}${f.getname}"))                 else files2tuplerec(s"${pathprefix}${f.getname}/",f)             }         }     }     val oldseq = (mappings in onejar).value     oldseq.filternot(t => isneedtobeindir0(t._1)) ++      oldseq.filter(t => isneedtobeindir0(t._1)).map{         case (f,_) => (f,s"/0/${nameforpackaging(f.getname)}") //not working     } ++      files2tuplerec("",file("deployer/src/main/resources")) }  //following lines commented out because it's not working, shows i'm trying do. //(types wrong. need file have sbt.artifact):  //mappings in onejar <+= (artifact in localproject("backend") in onejar) map {_ -> "/0/backend.jar"}   //mappings in onejar <+= (artifact in localproject("frontend") in onejar) map {_ -> "/0/frontend.zip"}   artifact in onejar <<= modulename(artifact(_, "executable"))  addartifact(artifact in (compile, onejar), onejar)  ... 

notice in root build.sbt, have per-configuration classpath dependencies "optional->compile". iv'e put there after looking @ ivy.xml file:

...  <configurations>          <conf name="compile" visibility="public" description=""/>          <conf name="runtime" visibility="public" description="" extends="compile"/>          <conf name="test" visibility="public" description="" extends="runtime"/>          <conf name="provided" visibility="public" description=""/>          <conf name="optional" visibility="public" description=""/>          <conf name="sources" visibility="public" description=""/>          <conf name="pom" visibility="public" description=""/>  </configurations>  <publications>          <artifact name="frontend_2.10" type="zip" ext="zip" conf="compile,runtime,test,provided,optional,sources,pom" e:classifier="dist"/>          <artifact name="frontend_2.10" type="pom" ext="pom" conf="pom"/>          <artifact name="frontend_2.10" type="jar" ext="jar" conf="compile"/>          <artifact name="frontend_2.10" type="src" ext="jar" conf="sources" e:classifier="sources"/>  </publications> ... 

and seeing dist.zip artifact found in optional scope, thought artifact dependency way (not seem working though...). also, when tried out commented out lines, got error saying it's wrong type.

==================================================

as i'm writing question, figured out i've done wrong...

update:

there's few things missed (to snippets copy & pasted...). first, deployer should not dependon(backend,frontend) @ all. aggregate. moreover, these artifacts (backend & frontend) should not visible on deployer's classpath @ all. line:

classpathtypes :=  classpathtypes.value + "zip" 

is unneeded. also, code transform mappings in onejar in deployer/build.sbt file, more simple. need take care of resources. , finally, commented out lines, should be:

mappings in onejar <+= (artifactpath in localproject("backend") in onejar) map {_ -> "0/backend.jar"}   mappings in onejar <+= (packagebin in localproject("frontend") in universal) map {_ -> "0/frontend.zip"} 

that's pretty it.


Comments

Popular posts from this blog

Android layout hidden on keyboard show -

google app engine - 403 Forbidden POST - Flask WTForms -

c - Why would PK11_GenerateRandom() return an error -8023? -