【问题标题】:When sbt-assembly executes?sbt-assembly 什么时候执行?
【发布时间】:2016-01-07 11:09:10
【问题描述】:

堆栈溢出:

使用 sbt-assembly(sbt 插件)和 sbt-multiproject, 我想生成命令行参数中指定的子项目的胖罐子。

命令可能如下:

sbt "assemblyWith hello world"

我定义了四个子项目,分别命名为 hello、world、alien 和 root。 我希望该命令生成 hello-assembly.jar 和 world-assembly.jar。 但还有 alien-assembly.jar。

什么时候触发组装过程?

这是产生问题的示例 build.sbt。 ( 希望能看到日志

'managedProject: ProjectRef(module/hello,hello)'

之前

'Packaging /path/to/dir/module/world/target/scala-2.11/world-assembly-0.1-SNAPSHOT.jar ...'

)

[build.sbt]

import sbt._
import Keys._
import complete.DefaultParsers.spaceDelimited

name := "sbt-query"

scalaVersion in ThisBuild := "2.11.7"

scalacOptions in ThisBuild ++= Seq("-unchecked", "-deprecation", "-feature")

test in assembly in ThisBuild := {}

lazy val hello = (project in file("./module/hello"))

lazy val world = (project in file("./module/world"))

lazy val alien = (project in file("./module/alien"))

lazy val root = (project in file(".")).aggregate(hello, world, alien)

// sbt "assemblyWith hello world"
// aims to produce hello-assembly.jar and world-assembly.jar (not alien-assembly.jar)

lazy val assemblyWith = inputKey[Unit]("assembly sub-projects specified in args")

assemblyWith := {
    val args = spaceDelimited("<arg>").parsed
    val stateee = state.value
    val log = stateee.globalLogging.full
    val extractedRoot = sbt.Project.extract(stateee)
    val destDirectory = (crossTarget in extractedRoot.currentRef get extractedRoot.structure.data).get
    args.collect {
        case projectName if (file("module") / projectName).exists =>
            ProjectRef(file("module") / projectName, projectName)
    }.map { proj =>
        log.info(s"managedProject: $proj")
        // improve: https://github.com/sbt/sbt/issues/1095
        // -> outside the task's definition (i.e. as a top level statement in build.sbt), then it works.
        val assemblyJarFile = proj.project match {
            case "hello" => assembly.all(ScopeFilter(inProjects(hello))).value.head
            case "world" => assembly.all(ScopeFilter(inProjects(world))).value.head
            case "alien" => assembly.all(ScopeFilter(inProjects(alien))).value.head
        }
        log.info(s"out: ${assemblyJarFile.getCanonicalPath}")
        // IO.copyFile(assemblyJarFile, destDirectory)
    }
}

[项目/build.properties]

sbt.version=0.13.9

[项目/plugins.sbt]

addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.13.0")

[目录树]

├─alien
│  └─src
│      └─main
│          └─scala
│              └─com.example.alien -> SayAlien.scala
├─hello
│  └─src
│      └─main
│          └─scala
│              └─com.example.hello -> SayHello.scala
└─world
   └─src
       └─main
           └─scala
               └─com.example.world -> SayWorld.scala

[版本]

java version "1.8.0_51"

[日志]

[info] Including from cache: scala-library-2.11.7.jar
[info] Including from cache: scala-library-2.11.7.jar
[info] Including from cache: scala-library-2.11.7.jar
[info] Checking every *.class/*.jar file's SHA-1.
[info] Merging files...
[warn] Merging 'META-INF\MANIFEST.MF' with strategy 'discard'
[warn] Strategy 'discard' was applied to a file
[info] Checking every *.class/*.jar file's SHA-1.
[info] Merging files...
[warn] Merging 'META-INF\MANIFEST.MF' with strategy 'discard'
[warn] Strategy 'discard' was applied to a file
[info] Checking every *.class/*.jar file's SHA-1.
[info] Merging files...
[warn] Merging 'META-INF\MANIFEST.MF' with strategy 'discard'
[warn] Strategy 'discard' was applied to a file
[info] Packaging ...../world-assembly-0.1-SNAPSHOT.jar ...
[info] Packaging ...../alien-assembly-0.1-SNAPSHOT.jar ...
[info] Packaging ...../hello-assembly-0.1-SNAPSHOT.jar ...
[info] Done packaging.
[info] Done packaging.
[info] Done packaging.
[info] managedProject: ProjectRef(module/hello,hello)
[info] out: ...../hello-assembly-0.1-SNAPSHOT.jar
[info] managedProject: ProjectRef(module/world,world)
[info] out: ...../world-assembly-0.1-SNAPSHOT.jar

【问题讨论】:

  • 您的问题和代码感觉不一致。您在问题中说“但也是外星人-assembly.jar。”,但在您的代码 cmets 中您说:“旨在生成 hello-assembly.jar 和 world-assembly.jar(不是外星人-assembly.jar)”代码似乎设置得很好,你试过运行“assemblyWith hello world alien 吗?看起来它可以解决问题......
  • @EdgeCaseBerg 谢谢。我在下面发布了答案。

标签: scala sbt


【解决方案1】:

代码没有问题。构建任务很清楚,您应该将要构建的模块的名称传递给assemblyWith 任务。我刚刚在本地构建并复制了您的代码。你可以找到它here on github

我运行 sbt&gt; assemblyWith hello alien world 并没有发现任何问题,并且生成了所有三个项目。

这是输出:

> assemblyWith hello alien world
[info] Including from cache: scala-library-2.11.7.jar
[info] Including from cache: scala-library-2.11.7.jar
[info] Including from cache: scala-library-2.11.7.jar
[info] Checking every *.class/*.jar file's SHA-1.
[info] Merging files...
[warn] Merging 'META-INF/MANIFEST.MF' with strategy 'discard'
[warn] Strategy 'discard' was applied to a file
[info] Checking every *.class/*.jar file's SHA-1.
[info] Merging files...
[warn] Merging 'META-INF/MANIFEST.MF' with strategy 'discard'
[warn] Strategy 'discard' was applied to a file
[info] Checking every *.class/*.jar file's SHA-1.
[info] Merging files...
[warn] Merging 'META-INF/MANIFEST.MF' with strategy 'discard'
[warn] Strategy 'discard' was applied to a file
[info] Assembly up to date: /code/module/hello/target/scala-2.11/hello-assembly-0.1-SNAPSHOT.jar
[info] Assembly up to date: /code/module/world/target/scala-2.11/world-assembly-0.1-SNAPSHOT.jar
[info] Assembly up to date: /code/module/alien/target/scala-2.11/alien-assembly-0.1-SNAPSHOT.jar
[info] managedProject: ProjectRef(module/hello,hello)
[info] out: /code/module/hello/target/scala-2.11/hello-assembly-0.1-SNAPSHOT.jar
[info] managedProject: ProjectRef(module/alien,alien)
[info] out: /code/module/alien/target/scala-2.11/alien-assembly-0.1-SNAPSHOT.jar
[info] managedProject: ProjectRef(module/world,world)
[info] out: /code/module/world/target/scala-2.11/world-assembly-0.1-SNAPSHOT.jar
[success] Total time: 4 s, completed Oct 9, 2015 10:05:46 AM

我不确定您的问题是关于什么的,如果您可以改写您的问题以使其更清晰,这将有所帮助。

什么时候触发组装过程?

当需要它产生的值时,会触发组装过程,即:

    val assemblyJarFile = proj.project match {
        case "hello" => assembly.all(ScopeFilter(inProjects(hello))).value.head

会告诉sbt这部分任务依赖于hello项目的组装值。这将导致组装过程被解雇。 SBT 任务本质上是通过指定它们依赖另一个任务来工作的,这导致该任务在需要其值时被调用。至少我是这样处理 sbt 任务的,在这方面它很像 make。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-03-17
    • 2012-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-20
    • 1970-01-01
    • 2013-05-01
    相关资源
    最近更新 更多