使用Scala约8年之后,我绕道绕过了一种您可能听说过的叫做Go的小语言。它并非没有缺陷(增长一个实类型系统,boi!),但是它做的某些事情比Scala曾经希望的要好得多。
Go以源代码形式管理依赖关系,任何明智的工程师都将考虑到可怕,直到她发现在依赖关系解决的情况下,将自己的依赖关系存储在源代码控制下的vendor/
目录中是“摆脱困境”的卡要么出于自身利益变得过于复杂,要么取决于不稳定的第三方资源,例如网络。
Go的CLI工具的最新版本附带了一个名为go mod vendor
的命令,该命令可以轻松地将当前模块的依赖项下载到项目内部的vendor/
目录中,随后可以将其检入源代码中。控制。暂不讨论以这种方式主动和抢先缓存依赖项的优点,我谨在此声明,该命令非常方便。
SBT因将依赖项下载到~/.ivy2
而臭名昭著,后者更多是由用户的所有项目共享的免费共享缓存,而不仅仅是一个项目。 ~/.sbt
中有一个较小的缓存,SBT本身将其用作“矮胖” /“土豆头先生”的暂存空间。如果这两个目录都不存在,将自动创建并填充这两个目录,但这两个目录都不打算由用户显式管理。两者都是SBT和/或Ivy的内部实现细节,并且不应与“除非您知道自己在做什么”相混淆。
我想要的(现在我将要问的是)是一个sbt vendor
命令,该命令可以将项目的所有依赖项填充到unmanaged classpath中。如果它也可以将运行SBT本身所需的所有内容下载到同一目录中,那将是桃花心木。
是否有一个SBT插件或一些奥术咒语序列可用于完成我所寻求的目标?
答案 0 :(得分:0)
在这个问题被主持人的过分热心永远解决之前,我将在此发布骇客,这让我度过了这个特别的难关。像往常一样,解决方案最终是一个shell脚本:
#!/bin/bash
root="$(readlink -f "$(dirname "$0")")"
sbt="$root/.sbt-launcher"
if [ ! -x "$sbt" ]; then
echo "$sbt does not exist or is not executable"
exit 1
fi
exec "$sbt" \
-ivy "$root/.ivy2" \
-sbt-dir "$root/.sbt" \
-sbt-boot "$root/.sbt/boot" \
-sbt-launch-dir "$root/.sbt/launchers" \
$@
让我们迅速打开包装。首先,shell脚本是真实SBT启动器的包装,该启动器位于同一目录中,名为.sbt-launcher
。任何最新版本都可以使用;您也可以从http://git.io/sbt
下载一个。
我的包装程序确保始终将四个标志传递给真正的SBT启动器:
-ivy
指定常春藤缓存的自定义位置。-sbt-dir
,-sbt-boot
和-sbt-launch-dir
一起迫使SBT停止使用整个帐户范围的~/.sbt
目录作为SBT JAR和其他内容的垃圾场。我将此外壳程序脚本保存为项目内的sbt
,从.sbt-launcher
放置http://git.io/sbt
到它旁边,然后开始使用包装器而不是真正的SBT。然后,我在项目内部创建的目录.ivy2
和.sbt
进入源代码管理。
仅此而已。这不是一个很好的解决方案,但是很好地将我的CI / CD流程与Internet工件存储库中的波动隔离开来。