我使用Scala 2.10.1和sbt将我的Web应用程序打包为war文件。为了实现高效的rsync增量,我希望将war打包为.war文件,但不使用zip压缩。我只需要知道如何为此配置我的构建。
更新:
所有这些插件文档都假设了语法如何工作以及如何将任务组合成一个新任务等方面的所有知识。我甚至不知道如何创建一个执行package-then命令的新任务。到目前为止,没有一个答案明确表示,"这是你所做的……"
需要明确的是,这就是我所要求的:
我需要一个任务"packnozip"这样做:
1) 运行"包"
2) 运行shell命令:
$ mkdir ./Whatever
$ pushd ./Whatever
$ jar xvf ../Whatever.war
$ popd
$ mv ./Whatever.war ./Whatever.war.orig
$ jar cvM0f ./Whatever.war -C ./Whatever .
所以我想说的是,我想在sbt控制台中键入"packnozip",然后让它执行#1,然后执行#2。
现在我只是手动做#2,如果它可以自动化的话,这看起来很傻。同样,看着一个30MB的文件被rsync b/c完全重新发送——这是不可区分的——当一个34MB的未压缩文件只多出13%的数据,并且只需要几分之一秒就可以发送b/c的有效差异时,这似乎很愚蠢,更不用说"-z"无论如何都会压缩传输。
如果您将war文件解压缩到一个目录中,您可以:
zip -r -0 project.war project/
这应该是零压缩。如果你看不到这些选项,这是我的设置:
[node@hip1 dev]$ zip -v
Copyright (c) 1990-2008 Info-ZIP - Type 'zip "-L"' for software license.
This is Zip 3.0 (July 5th 2008), by Info-ZIP.
我相信,在战争结束后,你可以作为一项运行任务执行
更新1
我相信这是实现您需求的最佳方式:
http://www.scala-sbt.org/release/docs/Detailed-Topics/Process
val exitcode = "zip -r -0 project.war project/"!
但是,如果您需要在特定目录下工作(请参阅下面的更新2):
将其修改为在目录内执行,但将.war放置在目录上方。path(第二个)参数应该包括目录,以便在其中执行zip:
Process("zip" :: "-r" :: "-0" :: "../project.war" :: "." :: Nil, "/path/to/project/") !
以下是关于ProcessBuilder的另一个SO问题,可能也会有所帮助:
Scala2.9中的"scala.sys.procedure"是如何工作的?
(注意:您不需要导入scala.sys.procedure_)
更新2
对于未来的读者,请注意,压缩项目目录本身是不起作用的,需要通过使用pushd在目录内执行war的压缩,将产生的war放在目录外,正如OP在本答案下面的评论中提到的那样。正如Orange80所提到的:
pushd ./project && zip -r -0 ../project.war ./ && popd
更新3
看看这个,它可能正是你需要的,用0表示选项来指定无压缩:
https://github.com/sbt/sbt-onejar
一个插件,可以让你创建一个单独的可执行jar,它有选项(例如"jar 0f blah.jar blah/"之类的命令中的"0"),我认为正如你在下面的评论中提到的那样,可以在不压缩的情况下创建jar文件。
关于用法,我在SO上找到了这个:SBT单罐插件
此外,如果它需要修改,它也是一个非常合理的插件示例,如果你把它放在家里~/.sbt/plugins,它将是全局的,可以按照上面SO答案中提到的方式在你的构建中使用。我希望这至少有一点帮助/
没有办法通过sbt配置直接做到这一点,因为sbt假设zip和jar工件中的任何文件都应该被压缩。
一种解决方法是解压缩并重新压缩(不压缩)war文件。您可以通过将以下设置添加到您的项目中(例如在build.sbt中)来做到这一点:
packageWar in Compile <<= packageWar in Compile map { file =>
println("(Re)packaging with zero compression...")
import java.io.{FileInputStream,FileOutputStream,ByteArrayOutputStream}
import java.util.zip.{CRC32,ZipEntry,ZipInputStream,ZipOutputStream}
val zis = new ZipInputStream(new FileInputStream(file))
val tmp = new File(file.getAbsolutePath + "_decompressed")
val zos = new ZipOutputStream(new FileOutputStream(tmp))
zos.setMethod(ZipOutputStream.STORED)
Iterator.continually(zis.getNextEntry).
takeWhile(ze => ze != null).
foreach { ze =>
val baos = new ByteArrayOutputStream
Iterator.continually(zis.read()).
takeWhile(-1 !=).
foreach(baos.write)
val bytes = baos.toByteArray
ze.setMethod(ZipEntry.STORED)
ze.setSize(baos.size)
ze.setCompressedSize(baos.size)
val crc = new CRC32
crc.update(bytes)
ze.setCrc(crc.getValue)
zos.putNextEntry(ze)
zos.write(bytes)
zos.closeEntry
zis.closeEntry
}
zos.close
zis.close
tmp.renameTo(file)
file
}
现在,当您在sbt中运行package
时,最终的war文件将被解压缩,您可以使用unzip -vl path/to/package.war
进行验证。