77

我有一个 sbt (Scala) 项目,该项目目前从网络上提取工件。我们希望转向可以缓存工件的企业标准化 Nexus 存储库。从 Nexus 文档中,我了解如何为 Maven 项目执行此操作。但是 sbt 显然使用了不同的方法。(我知道 Ivy 以某种方式参与其中,但我从未使用过它,也不明白它是如何工作的。)

我如何告诉 sbt 和/或底层 Ivy 使用公司 Nexus 存储库系统来处理所有依赖项?我想要使​​用某种项目级配置文件的答案,以便我们的源存储库的新克隆将自动使用代理。(即,在点目录中处理每个用户的配置文件是不可行的。)

谢谢!

4

6 回答 6

34

第 1 步:按照详细主题:代理存储库中的说明进行操作,我已将其总结并添加到下面:

  1. (如果您使用 Artifactory,则可以跳过此步骤。)在您的公司 Maven 存储库上创建一个完全独立的Maven 代理存储库(或组),以代理ivy 样式的存储库,例如以下两个重要的存储库:

    这是必需的,因为一些存储库管理器无法处理混合在一起的 Ivy 风格和 Maven 风格的存储库。

  2. 创建一个文件repositories,列出您的主要公司存储库和您在步骤 1 中创建的任何额外存储库,格式如下所示:

    [repositories]
      my-maven-proxy-releases: http://repo.example.com/maven-releases/
      my-ivy-proxy-releases: http://repo.example.com/ivy-releases/, [organization]/[module]/(scala_[scalaVersion]/)(sbt_[sbtVersion]/)[revision]/[type]s/[artifact](-[classifier]).[ext]
    
  3. 将该文件保存在.sbt主目录中的目录中,或者在 sbt 命令行中指定它:

    sbt -Dsbt.repository.config=<path-to-your-repo-file>
    

对于那些使用旧版本 sbt 的人来说是个好消息:即使至少在 sbt 0.12.0 启动器 jar 中,旧 sbt 版本的引导属性文件不包含所需的行(提到的那一行repository.config),它仍然可以工作对于那些版本的 sbt,如果您编辑这些文件以添加所需的行,并将它们重新打包到 sbt 0.12.0 启动器 jar 中!这是因为该功能是在启动器中实现的,而不是在 sbt 本身中实现的。sbt 0.12.0 启动器声称能够启动所有版本的 sbt,直接回到 0.7!

第 2 步:为确保未使用外部存储库,请从解析器中删除默认存储库。这可以通过以下两种方式之一完成:

  1. -Dsbt.override.build.repos=true添加上面详细主题页面中提到的命令行选项。这将导致您在文件中指定的存储库覆盖在任何 sbt 文件中指定的任何存储库。不过,这可能仅适用于 sbt 0.12 及更高版本 - 我还没有尝试过。
  2. 在您的构建文件中fullResolvers := Seq( 为您的公司 maven 存储库 使用解析器,而不是您曾经使用过的任何东西。)resolvers ++=resolvers :=
于 2013-04-05T19:45:39.513 回答
12

好的,在 sbt 邮件列表上的 Mark Harrah 的帮助下,我得到了一个有效的答案。

我的构建类现在如下所示(加上其他一些存储库):

import sbt._

//By extending DefaultWebProject, we get Jetty support
class OurApplication(info: ProjectInfo) extends DefaultWebProject(info) {

  // This skips adding the default repositories and only uses the ones you added
  // explicitly. --Mark Harrah
  override def repositories = Set("OurNexus" at "http://our.nexus.server:9001/nexus/content/groups/public/") 
  override def ivyRepositories = Seq(Resolver.defaultLocal(None)) ++ repositories

  /* Squeryl */
  val squeryl = "org.squeryl" % "squeryl_2.8.0.RC3" % "0.9.4beta5"

  /* DATE4J */
  val date4j = "hirondelle.date4j" % "date4j" % "1.0" from "http://www.date4j.net/date4j.jar"

  // etc
}

现在,如果我从我的机器.ivy2/cache目录中删除 Squeryl 树,sbt 会尝试使用适当的 URL 从 Nexus 树中抓取它。问题解决了!

于 2010-09-27T19:15:34.800 回答
9

您所需要的只是定义一个属性文件sbt.boot.properties,它允许您:

  • 重新定义常春藤缓存位置(我需要它,因为否则它将成为我们漫游 Windows 配置文件的一部分,这在我们商店的磁盘空间中受到严重限制。请参阅第 74 期
  • 定义您想要的任何其他 Maven 存储库
    C:\HOMEWARE\apps\sbt-0.74\sbt.boot.properties

    [斯卡拉]
      版本:2.7.7
    # 分类器:来源、javadoc

    [应用程序]
      组织:org.scala-tools.sbt
      名称:sbt
      版本:读取(sbt.version)
      类:sbt.xMain
      组件:xsbti
      跨版本:真
      分类器:来源、javadoc

    [存储库]
      当地的
      my-nexus:http://my.nexus/nexus/content/repositories/scala-tools/,[组织]/[模块]/[修订]/[类型]s/[工件](-[分类器])。 [分机]
      本地行家
    # sbt-db: http://databinder.net/repo/, [organization]/[module]/[revision]/[type]s/[artifact](-[classifier]).[ext]
    # Maven 中心
    # scala-tools-releases
    # scala-tools-snapshots

    [开机]
     目录:项目/启动
     属性:项目/build.properties
     prompt-create: 项目不存在,新建项目?
     提示填充:真
     快速选项:真

    [日志]
     级别:调试

    [应用程序属性]
     project.name: quick=set(test), new=prompt(Name)[p], fill=prompt(Name)
     project.organization: new=prompt(Organization)[org.vonc]
     project.version: quick=set(1.0), new=prompt(Version)[1.0], fill=prompt(Version)[1.0]
     build.scala.versions: quick=set(2.8.0.RC2), new=prompt(Scala 版本)[2.8.0.RC2], fill=prompt(Scala 版本)[2.8.0.RC2]
     sbt.version: quick=set(0.7.4), new=prompt(sbt version)[0.7.4], fill=prompt(sbt version)[0.7.4]
     project.scratch:快速=设置(真)
     项目初始化:快速=设置(真),新=设置(真)

    [常春藤]
     缓存目录:C:\HOMEWARE\projects\.ivy2\cache

注意:此sbt.boot.properties文件的灵感来自:

我评论了任何外部Maven 存储库定义,并添加了对我自己的 Nexus Maven 存储库的引用。

启动器可以按优先级递增顺序以下列方式之一进行配置:

  • 替换. /sbt/sbt.boot.properties_jar
  • 将一个名为的配置文件sbt.boot.properties放在类路径上。将其放在不带/sbt前缀的类路径根目录中。
  • 在命令行上指定备用配置的位置。这可以通过以下方式完成:
    • 将位置指定为系统属性sbt.boot.properties
    • 或作为启动器的第一个参数,前缀为“ @”。

系统属性的优先级较低。
相对路径的分辨率为:

  • 第一次尝试针对当前工作目录,
  • 然后针对用户的主目录,
  • 然后针对包含启动器 jar 的目录。

如果这些尝试均未成功,则会生成错误。


定义一个 sbt.bat 包装器(为了确保指定您的 sbt.boot.properties),例如:

C:\HOMEWARE>more C:\HOMEWARE\bin\sbt.BAT
@echo off
set t=%~dp0
set adp0=%t:C:\="%"

set SBT_DIR=%adp0%..\apps\sbt-0.74
dir C:\%SBT_DIR%\sbt-launch-0.7.4.jar
# if needed, add your proxy settings
set PROXY_OPTIONS=-Dhttp.proxyHost=my.proxy -Dhttp.proxyPort=80xx -Dhttp.proxyUser=auser -Dhttp.proxyPassword=yyyy
set JAVA_OPTIONS=-XX:+CMSClassUnloadingEnabled -XX:MaxPermSize=256m -Xmx512M -cp C:\HOMEWARE\apps\sbt-0.74\sbt-launch-0.7.4
set SBT_BOOT_PROPERTIES=-Dsbt.boot.properties="sbt.boot.properties"
cmd /C C:\HOMEWARE\apps\jdk4eclipse\bin\java.exe %PROXY_OPTIONS% %JAVA_OPTIONS% %SBT_BOOT_PROPERTIES% -jar C:\HOMEWARE\apps\sbt-0.74\sbt-launch-0.7.4.jar %*

而且您的 sbt 将仅从以下位置下载工件:

  • 你的 Nexus
  • 你当地的 Maven 仓库。

刚刚在家里用我运行的旧 Nexus 开源 1.6、java 1.6、sbt07.4 进行了测试

C:\Prog\Java\jdk1.6.0_18\jre\bin\java  -Xmx512M -Dsbt.boot.properties=sbt.boot.properties - jar "c:\Prog\Scala\sbt\sbt-launch-0.7.4.jar"  

这给出了:

[success] Build completed successfully.
C:\Prog\Scala\tests\pp>sbt
Getting Scala 2.8.0 ...
downloading http://localhost:8081/nexus/content/repositories/scala/org/scala-lang/scala-compiler/2.8.0/scala-compiler-2.
8.0.jar ...
        [SUCCESSFUL ] org.scala-lang#scala-compiler;2.8.0!scala-compiler.jar (311ms)
downloading http://localhost:8081/nexus/content/repositories/scala/org/scala-lang/scala-library/2.8.0/scala-library-2.8.
0.jar ...
        [SUCCESSFUL ] org.scala-lang#scala-library;2.8.0!scala-library.jar (185ms)
:: retrieving :: org.scala-tools.sbt#boot-scala
        confs: [default]
        2 artifacts copied, 0 already retrieved (14484kB/167ms)
[info] Building project test 0.1 against Scala 2.8.0
[info]    using sbt.DefaultProject with sbt 0.7.4 and Scala 2.7.7

如果我在 sbt.boot.properties 文件中尝试一个有趣的值:

C:\Prog\Scala\tests\pp>sbt
Getting Scala 2.9.7 ...

:: problems summary ::
:::: WARNINGS
                module not found: org.scala-lang#scala-compiler;2.9.7
        ==== nexus: tried
          http://localhost:8081/nexus/content/repositories/scala/org/scala-lang/scala-compiler/2.9.7/scala-compiler-2.9.7.pom
          -- artifact org.scala-lang#scala-compiler;2.9.7!scala-compiler.jar:
          http://localhost:8081/nexus/content/repositories/scala/org/scala-lang/scala-compiler/2.9.7/scala-compiler-2.9.7.jar

所以它确实将自己限制在我定义的两个仓库中:

[repositories]
nexus:  http://localhost:8081/nexus/content/repositories/scala
nexus2: http://localhost:8081/nexus/content/repositories/scala, [organization]/[module]/[revision]/[type]s/[artifact](-[classifier]).[ext]

(我评论了其他所有内容:local, maven-local, ...)

如果我评论所有存储库并为 scala 版本添加一个有趣的值(2.7.9)sbt.boot.properties,我会得到(就像 OP 一样)

C:\Prog\Scala\tests\pp>sbt
Error during sbt execution: No repositories defined.

如果我放了 2.7.7 (同时仍然对所有repo 进行了评论),是的,它不会产生错误:

C:\Prog\Scala\tests\pp>sbt
[info] Building project test 0.1 against Scala 2.8.0
[info]    using sbt.DefaultProject with sbt 0.7.4 and Scala 2.7.7

但这只是因为它在我之前的尝试中已经下载了 scala2.8.0。
如果我从我的project/boot目录中删除该库,那么它将引发异常:

[info]    using sbt.DefaultProject with sbt 0.7.4 and Scala 2.7.7
> C:\Prog\Scala\tests\pp>sbt
Error during sbt execution: No repositories defined.
        at xsbt.boot.Pre$.error(Pre.scala:18)
        at xsbt.boot.Update.addResolvers(Update.scala:197)
...
        at xsbt.boot.Boot$.main(Boot.scala:15)
        at xsbt.boot.Boot.main(Boot.scala)
Error loading project: Error during sbt execution: No repositories defined.
于 2010-09-22T16:00:21.750 回答
7

编辑 sbt_home/conf "sbtconfig.txt" 中的配置文件

添加两行

-Dsbt.override.build.repos=true
-Dsbt.repository.config="C:/Program Files (x86)/sbt/conf/repo.properties"

repo.properties 内容是

[repositories]
    local
    public: http://222.vvfox.com/public  <-fix this ,write your local nexus group url
于 2015-01-30T09:31:17.030 回答
5

Well this has bugged me for a while so I found a guy that has written an SBT plugin for maven out on github called maven-sbt so all you have to do is include it in your plugins project and make your project mixin with maven.MavenDependencies and all your operations like update and publish-local work with your local maven. The nice thing about that is if you are like me, your org is all maven. So, all you libs are in you local maven repo but if for some reason you build with sbt first, then you start getting a bunch or jars in ivy too. What a waste of space, and time since you will still need to get them for your maven builds.

That said, I wish this were built into sbt so I would not need to add it to every project. Maybe as a processor at least. He mentioned in one thing I read that he would like to add it to 0.9 but I have not been able to find it.

于 2011-05-07T02:21:17.963 回答
1

我收到此错误是因为我在~/.sbt/repositories. 将存储库添加到文件和删除文件都解决了这个问题。

于 2017-11-03T19:06:20.730 回答