Wie verwalte ich mehrere voneinander abhängige Module mit SBT und IntelliJ IDEA?


82

Ich entwickle mehrere Module mit Abhängigkeiten zwischen ihnen und möchte mit ihnen alle zusammen in einem IDEA-Projekt arbeiten. Ich verwende sbt-idea , um IDEA-Projekte aus den sbt-Build-Definitionen zu generieren, was für einzelne Projekte hervorragend funktioniert. Im Fall mit mehreren Modulen funktionieren die Dinge, die ich bisher ausprobiert habe, jedoch nicht ganz:

Verwenden Sie sbt-idea, um für jedes Modul unabhängig eine IDEA-IML-Datei zu generieren . Erstellen Sie dann ein Master-IDEA-Projekt von Grund auf neu und fügen Sie diese Module hinzu. Dadurch können die Modulquellen alle im selben Fenster bearbeitet werden, aber die Abhängigkeiten zwischen ihnen werden nicht nachverfolgt. Wenn ich also versuche, von einer Quelle innerhalb des foo- Projekts zu etwas in der Leiste zu navigieren, gehe ich zur importierten Bibliotheksversion der Leiste , nicht zu den lokalen Quellen ).

Verwenden Sie sbt - Multiprojekt -Builds (auch als Unterprojekte bezeichnet) , wobei die Build.scala des übergeordneten Projekts Folgendes enthält:

lazy val foo = Project(id = "foo", base = file("foo"))
lazy val bar = Project(id = "bar", base = file("bar")) dependsOn(foo)

Dies funktioniert fast, da sbt-idea ein Master-IDEA-Projekt mit den Abhängigkeiten zwischen den verfolgten Teilprojekten generiert. Es gibt jedoch zwei Einschränkungen:

  1. Es scheint eine sbt-Einschränkung zu sein, dass die Teilprojekte in Unterverzeichnissen des Masterprojekts gespeichert werden müssen (dh file("../foo")nicht zulässig sind). Dies ist nicht wirklich das, was ich will (was ist, wenn ein Modul - wie ein "utils" - oder "commons" -Paket - in zwei verschiedenen Masterprojekten verwendet wird?), Aber ich kann damit leben.
  2. Eines meiner Teilprojekte hat seine eigenen Teilprojekte; Ich bin nicht sicher, ob sbt selbst mit diesen verschachtelten Projekten richtig umgeht, aber auf jeden Fall werden sie von sbt-idea ignoriert. Natürlich brauche ich verschachtelte Teilprojekte, um rekursiv in das Masterprojekt aufgenommen zu werden.

Zusammenfassend: Ich möchte Module, die möglicherweise bereits Teilprojekte enthalten, in einem großen IDEA-Projekt mit nachverfolgten Abhängigkeiten für eine bequeme Bearbeitung sammeln . Wie kann ich es tun? Vielen Dank!


2
Versuchen Sie, ein Metaprojekt einzurichten, das als externe Projektreferenzen mit den anderen verknüpft ist ( github.com/harrah/xsbt/wiki/Full-Configuration ). Ich habe das nicht selbst mit sbt-idea versucht, daher ist dies eher ein Kommentar als eine Antwort.
Retronym

Vielen Dank für die Idee - aber leider ignoriert sbt-idea die externen Referenzen vollständig.
David Soergel


Cool, also habe ich svn-idea von den neuesten Git-Quellen installiert, um diese Änderungen zu übernehmen, dann die Projekte bereinigt und sbt-idea erneut ausgeführt. Es gab einige seltsame Probleme mit der Auflösung von Abhängigkeiten, die ich nicht vollständig verstehe, aber irgendwie kam ich zu einem funktionierenden Projekt! Ich musste die Quellverzeichnisse in IDEA für die Unter-Unterprojekte manuell festlegen. und im nachhinein bin ich mir nicht sicher, ob ich das mit der stock sbt-idea 11.1 überhaupt nicht hätte tun können. Wie auch immer, danke ... Ich denke, ich kann vorerst aufhören, diesen Yak zu rasieren.
David Soergel

Nachdem ich diesen letzten Kommentar geschrieben hatte, stellte ich fest, dass ich doch kein funktionierendes Projekt hatte (wieder Probleme mit den Unter-Unterprojekten). Also habe ich diese nur in erstklassige Projekte unterteilt, sodass mein Masterprojekt nur noch eine Ebene von Teilprojekten darunter hat. Natürlich konnte ich das nur tun, weil dies zunächst mein ganz eigener Code ist.
David Soergel

Antworten:


7

Der Ansatz beim Erstellen mehrerer Projekte ist der richtige. Sie können einen verschachtelten Baum von Teilprojekten beliebiger Länge haben, aber Sie können kein Modul haben, das zu mehreren übergeordneten Projekten gehört. Das ist absolut sinnvoll und in Maven passiert dasselbe.

Der Grund ist, dass es schwierig ist, dasselbe Modul in mehreren Projekten zu haben und die Quellen synchron zu halten. Ein normaler Workflow ist folgender:

  • Sie haben ein Projekt, zu dem das Modul gehört, in dem Sie die Modulquelle ändern.
  • Sie veröffentlichen das Modul in Ihrem lokalen Repository
  • In anderen Projekten, in denen Sie das Modul benötigen, deklarieren Sie es als libraryDependency

Wenn Sie ein Modul laden möchten, das nicht zum aktuellen Projekt in Idea gehört, ist dies jedoch möglich, da Sie es als externes Modul zum Arbeitsbereich hinzufügen können:

  • SBT-IDEA generiert die IML-Dateien für Ihr Projekt und importieren sie in den Arbeitsbereich
  • Sie können dem Arbeitsbereich other.iml anderer Projekte hinzufügen
  • Wenn Sie externe SBT-Module ändern, die Sie manuell zum Arbeitsbereich hinzugefügt haben, sollten Sie sie erneut veröffentlichen, damit die Änderungen im "Haupt" -Projekt sichtbar werden. Diese externen Module sind eine "libraryDependency".

Danke für die Eingabe. Das Problem ist jedoch, dass es nicht der Fall ist, dass "Sie einen verschachtelten Baum von Teilprojekten beliebiger Länge haben können". Ich bin damit einverstanden, dass dies mit sbt funktionieren sollte, aber sbt-idea enthält anscheinend keine Unter-Unterprojekte in der resultierenden IDEA-Projektdatei.
David Soergel

Kommt diese Einschränkung von der Idee?
Edmondo1984

Nein, ich habe IDEA-Projekthierarchien sicherlich mehrere Ebenen tief gemacht.
David Soergel

7

Es scheint eine sbt-Einschränkung zu sein, dass die Unterprojekte in Unterverzeichnissen des Masterprojekts gespeichert werden müssen (dh Datei ("../foo") ist nicht zulässig). Dies ist nicht wirklich das, was ich will (was ist, wenn ein Modul - wie ein "utils" - oder "commons" -Paket - in zwei verschiedenen Masterprojekten verwendet wird?), Aber ich kann damit leben.

Mit sbt 13.5 und Intellij 13.x können Sie mithilfe einer Build.scala die Abhängigkeit zwischen Projekten mit dem relativen Pfad angeben . Angenommen, Sie haben zwei Projekte, ein Kernprojekt Commons und ein weiteres Projekt foo , die beide in einem gemeinsamen Verzeichniscode leben .

  1. Erstellen Sie Build.scala unter Code / foo / project /
  2. Fügen Sie dieses Code-Snippet in Build.scala ein

    object ProjectDependencies {
        val commons = RootProject(file("../commons"))
    }
    
    object ProjectBuild extends Build {
        import ProjectDependencies._
    
        lazy val root = Project(id = "foo", base = file(".")).dependsOn(commons)
    }
  3. Generieren Sie Ihr IntelliJ-Projekt über sbt by sbt gen-idea


Ermöglicht dies die Bearbeitung der "Commons" -Quelle durch Verlinken von "foo"?
Tjunkie

Ja, das erlaubt es. Und es funktioniert auf meiner sbt 0.13.7 und Intellij 14.0.3 Installation
user2829759
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.