Wie kann ich sbt dazu bringen, ein lokales Maven-Proxy-Repository (Nexus) zu verwenden?

73

Ich habe ein sbt (Scala) -Projekt, das derzeit Artefakte aus dem Web abruft. Wir möchten auf ein unternehmensstandardisiertes Nexus-Repository umsteigen, das Artefakte zwischenspeichert. Aus der Nexus-Dokumentation geht hervor, wie das für Maven-Projekte gemacht wird. Aber sbt verwendet offensichtlich einen anderen Ansatz. (Ich verstehe, dass Ivy irgendwie involviert ist, aber ich habe es nie benutzt und verstehe nicht, wie es funktioniert.)

Wie kann ich sbt und / oder dem zugrunde liegenden Ivy anweisen, das Nexus-Repository-System des Unternehmens für alle Abhängigkeiten zu verwenden? Ich möchte, dass die Antwort eine Art Konfigurationsdatei auf Projektebene verwendet, damit neue Klone unseres Quell-Repositorys automatisch den Proxy verwenden. (Das heißt, es ist nicht möglich, mit Konfigurationsdateien pro Benutzer in einem Punktverzeichnis herumzuspielen.)

Vielen Dank!

Harlan
quelle
@VonC Ich habe einige Massenaktualisierungen von Fragen mit dem [maven]Tag durchgeführt und dachte, dass dies mehr über Nexus als über Maven (-2) war. Aber wenn Sie denken, dass es relevant ist, können Sie das Rollback / Update entsprechend durchführen. Ich bin bei diesem möglicherweise zu schnell vorgegangen.
Pascal Thivent
Ja, Maven ist vielleicht nicht das primäre Tag, aber es geht sicherlich um Maven-Repos. Ich rollte es zurück.
Harlan
Übrigens ist es bestätigt: Es funktioniert wie angekündigt, sowohl zu Hause als auch bei der Arbeit. Ich habe meine Frage bearbeitet, um dies zu veranschaulichen und um einige Repository-Definitionen hinzuzufügen, die Sie untersuchen können.
VonC

Antworten:

34

Schritt 1: Befolgen Sie die Anweisungen unter Detaillierte Themen: Proxy-Repositorys , die ich unten zusammengefasst und ergänzt habe:

  1. (Wenn Sie Artifactory verwenden, können Sie diesen Schritt überspringen.) Erstellen Sie ein vollständig separates Maven-Proxy-Repository (oder eine Gruppe) in Ihrem Unternehmens-Maven-Repository, um Repositorys im Ivy-Stil wie diese beiden wichtigen zu vertreten:

    Dies ist erforderlich, da einige Repository-Manager nicht damit umgehen können, dass Repositorys im Ivy- und Maven-Stil miteinander gemischt werden.

  2. Erstellen Sie eine Datei repositories, in der sowohl Ihr Hauptunternehmens-Repository als auch alle zusätzlichen, die Sie in Schritt 1 erstellt haben, in dem unten gezeigten Format aufgelistet sind:

    [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. Speichern Sie diese Datei entweder in dem .sbtVerzeichnis in Ihrem Home-Verzeichnis oder geben Sie sie in der sbt-Befehlszeile an:

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

Gute Nachrichten für Benutzer älterer Versionen von sbt : Auch wenn die Boot-Eigenschaftendateien für ältere sbt-Versionen zumindest im Launcher-JAR von sbt 0.12.0 nicht die erforderliche Zeile enthalten (die erwähnte repository.config), funktioniert dies dennoch für diese Versionen von sbt, wenn Sie diese Dateien bearbeiten, um die erforderliche Zeile hinzuzufügen, und sie erneut in das Launcher-Glas sbt 0.12.0 packen! Dies liegt daran, dass die Funktion im Launcher implementiert ist, nicht in sbt selbst. Und der sbt 0.12.0 Launcher soll in der Lage sein, alle Versionen von sbt direkt auf 0.7 zu starten!

Schritt 2: Um sicherzustellen, dass keine externen Repositorys verwendet werden, entfernen Sie die Standard-Repositorys von Ihren Resolvern. Dies kann auf zwei Arten erfolgen:

  1. Fügen Sie die Befehlszeilenoption hinzu, -Dsbt.override.build.repos=truedie oben auf der Seite Detaillierte Themen aufgeführt ist. Dies führt dazu, dass die in der Datei angegebenen Repositorys alle in einer Ihrer sbt-Dateien angegebenen Repositorys überschreiben. Dies funktioniert jedoch möglicherweise nur in sbt 0.12 und höher - ich habe es noch nicht ausprobiert.
  2. Verwenden Sie fullResolvers := Seq( Resolver (s) für Ihre Corporate Maven-Repositorys ) in Ihren Build-Dateien anstelle von resolvers ++=oder resolvers :=oder was auch immer Sie verwendet haben.
Robin Green
quelle
1
Ich verwende Scala 2.10, Artifactory 3, sbt 12.3 und habe kein Glück, wenn ich die Anweisungen hier und in den hier genannten Dokumenten verwende. Ich kenne die Lese-Repositories, nachdem ich dort einen Tippfehler gefunden habe. Ich habe die Eigenschaft auf dem Launcher über -D festgelegt. SBT verhält sich so, als würde es die Standard-Resolver nicht außer Acht lassen, wie es mit -Dsbt.override.build.repos = true angegeben ist. Ich könnte Punkt 2 oben versuchen, aber es klingt so, als ob es nicht notwendig sein sollte?
Totoro
1
@Robin Green: Vielen Dank, dieses Problem hat mich verrückt gemacht und Ihre Lösung hat für mich funktioniert.
Grundlefleck
3
Wenn Sie dies pro Projekt konfigurieren möchten (wie in der ursprünglichen Frage gestellt) und nicht bei jedem sbtLauf die Befehlszeilenoptionen hinzufügen möchten , können Sie eine Datei mit dem Namen ".sbtopts" neben Ihrer "build.sbt" erstellen. Geben Sie die Optionen ( -Dsbt.override.build.repos=true -Dsbt.repository.config=<…>) ein und sie werden von der sbtausführbaren Datei übernommen.
F30
12

OK, mit etwas Hilfe von Mark Harrah auf der sbt-Mailingliste habe ich eine Antwort, die funktioniert.

Meine Build-Klasse sieht jetzt wie folgt aus (plus einige andere Repos):

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
}

Wenn ich nun den Squeryl-Baum aus dem .ivy2/cacheVerzeichnis meines Computers lösche, versucht sbt, ihn mit der entsprechenden URL aus dem Nexus-Baum abzurufen. Problem gelöst!

Harlan
quelle
6
Dies ist jetzt für Play 2 Final und SBT 0.11.2 veraltet.
delitescere
9

Sie müssen lediglich eine Eigenschaftendatei definieren sbt.boot.properties, mit der Sie:

  • Definieren Sie den Speicherort des Efeu-Cache neu (ich brauche das, weil es sonst Teil unseres Roaming-Windows-Profils wäre , dessen Speicherplatz in unserem Shop stark eingeschränkt ist. Siehe Ausgabe 74 ).
  • Definieren Sie ein beliebiges anderes Maven-Repo
    C: \ HOMEWARE \ apps \ sbt-0.74 \ sbt.boot.properties

    [Scala]
      Version: 2.7.7
    # Klassifikatoren: Quellen, Javadoc

    [App]
      org: org.scala-tools.sbt
      name: sbt
      version: read (sbt.version)
      Klasse: sbt.xMain
      Komponenten: xsbti
      Cross-Version: wahr
      Klassifikatoren: Quellen, Javadoc

    [Repositories]
      lokal
      my-nexus: http://my.nexus/nexus/content/repositories/scala-tools/, [Organisation] / [Modul] / [Revision] / [Typ] s / [Artefakt] (- [Klassifikator]). [ext]
      Maven-lokal
    # sbt-db: http://databinder.net/repo/, [Organisation] / [Modul] / [Revision] / [Typ] s / [Artefakt] (- [Klassifikator]). [ext]
    # maven-central
    # Scala-Tools-Releases
    # scala-tools-snapshots

    [boot]
     Verzeichnis: Projekt / Boot
     Eigenschaften: project / build.properties
     prompt-create: Projekt existiert nicht, neues Projekt erstellen?
     prompt-fill: true
     Schnelloption: wahr

    [Log]
     Level: Debug

    [App-Eigenschaften]
     Projektname: quick = set (Test), new = Eingabeaufforderung (Name) [p], fill = Eingabeaufforderung (Name)
     project.organization: new = prompt (Organisation) [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-Version) [2.8.0.RC2], fill = prompt (Scala-Version) [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: quick = set (true)
     project.initialize: quick = set (true), new = set (true)

    [Efeu]
     Cache-Verzeichnis: C: \ HOMEWARE \ projects \ .ivy2 \ cache

Hinweis: Diese sbt.boot.propertiesDatei ist inspiriert von:

Ich habe jede externe Maven-Repository-Definition kommentiert und einen Verweis auf mein eigenes Nexus Maven-Repo hinzugefügt.

Der Launcher kann auf eine der folgenden Arten in aufsteigender Rangfolge konfiguriert werden:

  • Ersetzen Sie die /sbt/sbt.boot.propertiesDatei in der jar.
  • Fügen Sie eine Konfigurationsdatei mit dem Namen sbt.boot.propertiesim Klassenpfad ein. Fügen Sie es ohne /sbtPräfix in den Klassenpfadstamm ein .
  • Geben Sie den Speicherort einer alternativen Konfiguration in der Befehlszeile an. Dies kann erfolgen durch:
    • Geben Sie entweder den Speicherort als Systemeigenschaft an sbt.boot.properties
    • oder als erstes Argument für den Launcher mit dem Präfix ' @'.

Die Systemeigenschaft hat eine niedrigere Priorität.
Die Auflösung eines relativen Pfades ist:

  • erster Versuch gegen das aktuelle Arbeitsverzeichnis,
  • dann gegen das Home-Verzeichnis des Benutzers,
  • und dann gegen das Verzeichnis, das das Launcher-Glas enthält.

Ein Fehler wird generiert, wenn keiner dieser Versuche erfolgreich ist.


Definieren Sie einen sbt.bat-Wrapper (um sicherzugehen, dass Sie Ihren angeben sbt.boot.properties) wie folgt :

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 %*

Und Ihr sbt lädt Artefakte nur herunter von:

  • dein Nexus
  • Ihr lokales Maven Repo.

Gerade zu Hause mit einem alten Nexus OpenSource 1.6 getestet, den ich ausgeführt habe, 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"  

Das gibt:

[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

Wenn ich einen lustigen Wert in der Datei sbt.boot.properties versuche:

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

Es beschränkt sich also auf die beiden von mir definierten Repos:

[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]

(I kommentiert alles andere: local, maven-local, ...)

Wenn ich alle Repositories kommentiere und einen lustigen Wert (2.7.9) für die Scala-Version in die einfüge sbt.boot.properties, bekomme ich (wie das OP)

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

Wenn ich 2.7.7 setze (während immer noch alle Repos kommentiert sind), wird kein Fehler generiert:

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

Das liegt aber nur daran, dass scala2.8.0 bereits bei meinen vorherigen Versuchen heruntergeladen wurde.
Wenn ich diese Bibliothek aus meinem project/bootVerzeichnis entferne, wird eine Ausnahme ausgelöst:

[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.
VonC
quelle
Vielen Dank für die äußerst vollständige Antwort! Aber es funktioniert nicht bei mir. Ich habe eine sbt.boot.properties-Datei erstellt, in der nur drei Repositorys aufgelistet sind: local, maven-local und my-nexus, die auf unser lokales Nexus-Repo verweisen. sbtist ein Skript mit folgendem java -Xmx1024M -Dsbt.boot.properties="sbt.boot.properties" -jar Inhalt : dirname $ 0 /sbt-launch.jar "$@"Wenn ich dann ein Paket (z. B. Squeryl) aus meinem .ivy2-Cache lösche und dann "sbt update" durchführe, wird es anscheinend aus dem öffentlichen Internet abgerufen, ohne unsere Nexus-Installation zu berühren. Wie warum?
Harlan
@ Harlan: Warum? weil es dein Konto nicht berücksichtigt sbt.boot.properties. Hast du es direkt daneben erstellt sbt-launch-0.7.4.jar(was in deinem Klassenpfad bedeutet)? Wenn Sie sich das vorstellen, sehe ich keinen Klassenpfad, der explizit in Ihrem Java-Befehl definiert ist.
VonC
Es lädt definitiv sbt.boot.properties. Wenn ich mit dem oben gezeigten Befehl die Scala-Version in dieser Datei auf 2.9.7 ändere, wird vergeblich versucht, 2.9.7 zu erhalten. Es ist also kein Klassenpfadproblem. sbt updateWird aber von scala-tools.org gezogen, auch wenn nur local und my-nexus definiert sind.
Harlan
@ Harlan: Hast du versucht, keine Repositorys zu definieren ? Oder um etwas offensichtlich Falsches zu definieren? Es fällt mir immer noch schwer zu glauben, dass Ihre spezifische Eigenschaftendatei berücksichtigt wird.
VonC
Das ist komisch. Wenn ich die Scala-Version auf 2.9.7 setze und alle Repositorys auskommentiere, wird "Fehler bei der Ausführung von sbt: Keine Repositorys definiert" angezeigt. Aber wenn ich die Scala-Version auf 2.7.7 setze und alle Repositorys auskommentiere, greift sie die Repository-Liste und ignoriert sie scheinbar!
Harlan
6

Bearbeiten Sie die Konfigurationsdatei in sbt_home / conf "sbtconfig.txt".

füge zwei Zeilen hinzu

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

Der Inhalt von repo.properties ist

[repositories]
    local
    public: http://222.vvfox.com/public  <-fix this ,write your local nexus group url
Foxundermon
quelle
5

Nun, das hat mich eine Weile nervt, also habe ich einen Typen gefunden, der ein SBT-Plugin für maven out auf github namens maven-sbt geschrieben hat. Alles, was Sie tun müssen, ist, es in Ihr Plugin-Projekt aufzunehmen und Ihr Projekt mit maven.MavenDependencies zu mischen und alle Ihre Operationen wie das Aktualisieren und Veröffentlichen lokaler Arbeiten mit Ihrem lokalen Maven. Das Schöne daran ist, wenn du wie ich bist, ist deine Organisation alles Maven. Also, alle Ihre Bibliotheken sind in Ihrem lokalen Maven-Repo, aber wenn Sie aus irgendeinem Grund zuerst mit sbt bauen, dann bekommen Sie auch ein paar Gläser in Efeu. Was für eine Verschwendung von Platz und Zeit, da Sie sie immer noch für Ihre Maven-Builds benötigen.

Trotzdem wünschte ich mir, dies wäre in sbt eingebaut, damit ich es nicht zu jedem Projekt hinzufügen müsste. Vielleicht zumindest als Prozessor. Er erwähnte in einer Sache, die ich gelesen habe, dass er es gerne zu 0,9 hinzufügen würde, aber ich konnte es nicht finden.

Ozon
quelle
1

Ich habe diesen Fehler erhalten, weil ich eine leere Datei in hatte ~/.sbt/repositories. Sowohl das Hinzufügen von Repositorys zur Datei als auch das Entfernen der Datei lösten das Problem.

mehtunguh
quelle