如何通过将 sbt-plugin 用作多项目构建中的依赖项来访问它的子项目?

Posted

技术标签:

【中文标题】如何通过将 sbt-plugin 用作多项目构建中的依赖项来访问它的子项目?【英文标题】:How can I access sub-projects of an sbt-plugin by using it as dependency in a multi-project build? 【发布时间】:2017-08-22 19:37:25 【问题描述】:

我有一个使用多项目构建的 sbt 插件项目。我想将此插件用作其他 sbt 项目的依赖项并访问此 sbt 插件的子项目。我创建了一个插件并将插件添加到一个 sbt 项目中,但我无法访问那里的插件子项目。

sbt 插件

build.sbt

name := "sbt-plugin"
sbtPlugin := true

val commonSettings = Seq(
    organization := "com.example",
    version := "1.0",
    scalaVersion := "2.11.7",
    javacOptions := Seq("-source", "1.8", "-target", "1.8"), 
    scalacOptions := Seq("-target:jvm-1.8", "-unchecked","-deprecation", "-encoding", "utf8")
   )

  lazy val root = (project in file("."))
                 .settings(commonSettings: _*)
                 .dependsOn(plugin)
                 .aggregate(plugin)

  lazy val plugin = (project in file("plugin"))
                 .settings(commonSettings: _*)
                 .settings(
                     name := "plugin" ,
                     mainClass in (Compile, run) := Some("com.example.Main")
    )

sbt-plugin\plugin\src\main\scala\com\example\Main.scala

package com.example

object Main 
    def main(args: Array[String])
        println("Hello from plugin in sbt-plugin");
    

sbt-plugin\plugin\src\main\scala\com\example\Hello.scala

  package com.example

  // Sample code I would like to access from another sbt project
  object Hello 
     def show = println("Hello, world!")
  

插件测试

plugin-test 是我用来测试 sbt-plugin 的一个 sbt 项目

插件测试\build.sbt

name := """plugin-test"""

val commonSettings = Seq(
    version := "1.0",
    scalaVersion := "2.11.7",
    javacOptions := Seq("-source", "1.8", "-target", "1.8"), 
    scalacOptions := Seq("-target:jvm-1.8", "-unchecked", "-deprecation", "-encoding", "utf8"),
    libraryDependencies += "org.scalatest" %% "scalatest" % "2.2.4" % "test"    
)

lazy val root = (project in file("."))
               .settings(commonSettings: _*)
               .dependsOn(pluginpro)
               .aggregate(pluginpro)
               .settings(
                   mainClass in (Compile, run) := Some("com.exam.Test")
  )

lazy val pluginpro = (project in file("pluginpro"))
                   .settings(commonSettings: _*)
                   .settings(
                        libraryDependencies += "com.example" % "plugin_2.11" % "1.0"         
    )

插件测试\src\main\scala\com\exam\Test.scala

  package com.exam

  object Test 
     def result = com.example.Hello.show()
  

当我从 root 运行插件测试项目时,它正在运行,但有下面提到的日志,我不确定它为什么会显示这个,因为根据我的输出只会是 Hello, world!

background log: info: Running com.exam.Test
background log: debug: Waiting for threads to exit or System.exit to be called.
background log: debug: Waiting for thread run-main-0 to terminate.
background log: debug:   Classpath:
E:\Play\SBT Plugin\sbt demo1\plugin-test\target\scala-2.11\classes
E:\Play\SBT Plugin\sbt demo1\plugin-test\pluginpro\target\scala-2.11\classes
C:\Users\Jeetu\.ivy2\cache\org.scala-lang\scala-library\jars\scala-library-2.11.7.jar
C:\Users\Jeetu\.ivy2\local\com.example\plugin_2.11\1.0\jars\plugin_2.11.jar
Hello, world!
()
background log: debug:  Thread run-main-0 exited.
background log: debug: Interrupting remaining threads (should be all daemons).
background log: debug: Sandboxed run complete..
background log: debug: Exited with code 0  

当我尝试通过pluginpro/run 运行 sbt-plugin 的子项目时,它找不到主类。

 > pluginpro/run
[trace] Stack trace suppressed: run last pluginpro/compile:backgroundRun for the full output.
[error] (pluginpro/compile:backgroundRun) No main class detected.

我在 sbt-plugin/plugin 项目中创建了主类。 我在两个项目上都执行了本地发布和插件/本地发布,并且正确解析了工件。

我在这里错过了什么?

【问题讨论】:

【参考方案1】:

我通过在 pluginpro 项目的 build.sbt 中添加以下内容来解决它:

mainClass in (Compile, run) := Some("com.example.Main")         

【讨论】:

以上是关于如何通过将 sbt-plugin 用作多项目构建中的依赖项来访问它的子项目?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 sbt-plugin 中使用 sbt-assembly?

如何组织多包颤振项目并将其用作依赖项

未解决的依赖关系:sbt-plugin;2.7.0 尝试编译播放模板项目时

如何关闭多项目构建的并行执行测试?

如何构建一个用作计时器的简单 chrome 扩展?

在多模块 Maven 项目中构建所有模块后,如何运行集成测试?