Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

use case: single project, multiple apps #633

Closed
wookietreiber opened this issue Jul 30, 2015 · 10 comments
Closed

use case: single project, multiple apps #633

wookietreiber opened this issue Jul 30, 2015 · 10 comments

Comments

@wookietreiber
Copy link

As I understand it, from a cursory reading of your documentation, sbt-native-packager considers only a single main class and will create only a single script invoking that main class, is that correct?

The use case I am currently pondering on is having a single project with multiple main classes, i.e. multiple distinct apps, each of which should get its own script, e.g.:

package foobar

object foo extends App with Library with Util
object bar extends App with Library with Util

trait Library
trait Util

Supposed to be deployed result:

bin/foo
bin/bar
lib/project.jar

Each of the scripts in bin uses the same lib/project.jar only with a different main class.

Is this possible to achieve right now? If not: Is sbt-native-packager able to be extended to support this use case?

@metasim
Copy link
Member

metasim commented Jul 30, 2015

The way I handle this is via a packaging submodule, which in turn has separate submodules for each package I want to create. Here's a rough idea of what I'm talking about.

@muuki88
Copy link
Contributor

muuki88 commented Jul 31, 2015

Submodules are one way to handle this. If you just want different startup scripts you could

  • create a script for each main in src/universal/bin
  • content of each script ( not tested, only to the get the idea )
#!/bin/bash
you-app-name -main path.to.Main

See #319

@muuki88
Copy link
Contributor

muuki88 commented Jul 31, 2015

@metasim can you put your snippet here? At some point we can move parts from there to the docs.

@metasim
Copy link
Member

metasim commented Jul 31, 2015

@muuki88
Copy link
Contributor

muuki88 commented Jul 31, 2015

@metasim sweet :)

@muuki88
Copy link
Contributor

muuki88 commented Jul 31, 2015

@wookietreiber did one of the solutions solve your problem?

@wookietreiber
Copy link
Author

Sorry for not replying sooner, I had to postpone the project I had this feature in mind for a while.

Today I dove a bit into sbt tasks and the way I handled it for now is this:

val scripts = taskKey[Unit]("Creates the scripts.")

scripts := {
  val scriptDir = target.value / "scripts"
  if (!scriptDir.exists) scriptDir.mkdir()

  val prefix = sys.env.getOrElse("PREFIX", "/usr/local")

  def script(clazz: String) =
    s"""|#!/bin/sh
        |java -cp ${prefix}/share/grid-engine-tools/grid-engine-tools.jar $clazz
        |""".stripMargin

  (discoveredMainClasses in Compile).value foreach { clazz =>
    val app = clazz.drop(clazz.lastIndexOf(".") + 1)
    val s = scriptDir / app
    IO.write(s, script(clazz))
  }
}

scripts <<= scripts dependsOn assembly

In the end I realized this wasn't that complicated overall. The one part that is not handled by this snippet is the actual installation and prefix handling which I did with an external Makefile, because there are some other non-Scala bash scripts which also need installation.

I always intended the solution to center around the discoveredMainClasses sbt key and to iterate over its values. Other solutions work around the problem too much and make it more complicated by e.g. having to have a separate sbt project for each app.

Do you think using discoveredMainClasses could be implemented in sbt-native-packager?

If you would like to see the full project, here is a link, both Makefile and build.sbt are not very complex.

Note: I depend in my example on the sbt assembly task.

@muuki88
Copy link
Contributor

muuki88 commented Mar 28, 2016

Sorry for the VERY late reply. Building a small archetype plugin for this would generally be a nice idea. Best case would be to just call the initial start script, but with a different main class.

@atrosinenko
Copy link
Contributor

Looks like this already works in version 1.2.2.

@muuki88
Copy link
Contributor

muuki88 commented Aug 26, 2017

Thanks for the hint. Indeed this was introduced in 1.2.0

@muuki88 muuki88 closed this as completed Aug 26, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants