代码之家  ›  专栏  ›  技术社区  ›  YSC

如何将我的应用程序打包为多个存档?

  •  0
  • YSC  · 技术社区  · 5 年前

    例如,我想要一个任务,它为我的应用程序构建一个包含所有构建jar的ZIP存档,以及另一个包含所有依赖项的存档。

    1 回复  |  直到 5 年前
        1
  •  1
  •   YSC    5 年前

    sbt-1.2 sbt-native-packager-1.x

    在多项目构建中, sbt-native-packager 添加任务, Universal / packageBin

    // in your (sub)project definition (a .sbt file, anyone)
    lazy val MySubProject1 = (project in file("MySubProject1"))
      .enablePlugins(JavaAppPackaging)
    

    这允许您:

    sbt:MyProject> project MySubProject1
    sbt:MySubProject1> universal:packageBin
    [...]
      adding: lib/
      adding: lib/MySubProject2-0.1.0.jar
      adding: lib/MySubProject1-0.1.0.jar
      adding: lib/org.apache.kafka.kafka_2.11-0.10.0.1.jar
    [...]
      adding: bin/
      adding: bin/MySubProject1
      adding: bin/MySubProject1.bat
    [success] [...]
    ^D
    $ unzip -l target/universal/MySubProject1.zip # list archive content :)
    [...]
    

    ZIP存档:一个用于 他们的 jars(sbt下载的那些)。这并不容易,但可以实现。

    为了组织事情,我们将在scala文件中定义一些代码。假设以下项目层次结构:

    MyProject              |
    ├── build.sbt          | Define all that is not defined in modules.sbt
    ├── modules.sbt        | Defile all (sub)projects
    ├── project/           |
    │   ├── Settings.scala | Define settings to apply to (sub)projects
    │   └── Deps.scala     | Define dependencies
    ├── MySubProject1/     | This is the subproject you will package
    │   └── src/           |
    ├── ...                | Some of those subprojects are dependencies to MuSubProject1
    └── MySubProjectn/     | 
        └── src/           |
    

    modules.sbt

    lazy val MySubProject1 = (project in file("MySubProject1"))
      .settings(
        name := "AwesomeApp",
        Settings.Common ++ Settings.Package, // this is here (Settings.Package) that magic operates
        libraryDependencies ++= Deps.Spark,
      )
      .dependsOn(MySubProject2)
      .enablePlugins(JavaAppPackaging) // This is still needed
    
    

    project/Settings.scala :定义打包所需的设置

    从一个简单的scala对象开始,我们将扩展我们的打包策略

    import sbt._
    import Keys._
    
    // additional imports (0/)
    
    object Settings {
      lazy val Common = Seq(
        version := "0.1.0",
        scalaVersion := "2.11.8",
        // other settings
      )
    
      // <packaging strategy> (1/, 2/ & 3/)
    }
    

    0/添加一些导入

    import com.typesafe.sbt.SbtNativePackager.autoImport._
    import com.typesafe.sbt.packager.universal.UniversalPlugin.autoImport._
    import com.typesafe.sbt.packager.universal.Archives.makeNativeZip
    

      val Application  = config("application")
      val Dependencies = config("dependencies")
    

    2/定义我们的分区(哪个文件放在哪个配置中)

      //! @brief Return the configuration this file is into.
      private[this] def configOf(mapping: (File, String)): Configuration = mapping match {
        case (file, _) =>
          if (file.getPath() contains "/cache/") Dependencies // this depends on **your** context and should be improved
          else Application
      }
    
      //! @brief Return a file filter for this configuration to apply with @c filter on a file mapping.
      private[this] def filterOf(conf: Configuration): ((File, String)) => Boolean = {
        mapping: (File, String) => configOf(mapping) == conf
      }
    

    3/为每个配置创建ZIP存档

      //! @brief Define the task packageBin for this configuration.
      private[this] def packageDefinition(conf: Configuration): Setting[Task[File]] = {
        conf / packageBin := {
          // TODO add JavaAppPackaging plugin to the project here, but how? See `thisProject.value.autoPlugins`?
          val targets = (Universal / mappings).value filter filterOf(conf)
          makeNativeZip(target.value, s"${packageName.value}-${conf.name}", targets, None, Nil)
        }
      }
    
       /**
        * @brief Add packaging configuration to a project.
        *
        * Apply with:
        * @code
            lazy val subproject = (project in file ("directory")).settings(
              name := "MyAwesomeSubProject",
              Settings.Package,
            ).enablePlugins(JavaAppPackaging)
        * @endcode
        */
      def Package = Seq(
        maintainer := "YSC@example.com",
        packageName := s"${name.value}",
    
        packageDefinition(Application),
        packageDefinition(Dependencies),
      )
    

    就是这样!现在可以应用 application:packageBin dependencies:packageBin AwesomeApp-application.zip AwesomeApp-dependencies.zip .

    好好享受!