web-dev-qa-db-fra.com

Comment gérer plusieurs modules interdépendants avec SBT et IntelliJ IDEA?

Je développe plusieurs modules avec des dépendances entre eux, et je voudrais travailler avec eux tous ensemble dans un seul projet IDEA. J'utilise sbt-idea pour générer IDEA projets à partir des définitions de construction sbt, ce qui fonctionne très bien pour des projets individuels. Dans le cas de plusieurs modules, cependant, les choses que j'ai essayées jusqu'à présent ne fonctionnent pas tout à fait:

Utilisez sbt-idea pour générer un fichier IDEA .iml pour chaque module indépendamment ; puis créez un maître IDEA projetez à partir de zéro et ajoutez-y ces modules. Cela rend les sources du module toutes modifiables dans la même fenêtre, mais les dépendances entre elles ne sont pas suivies (essayez donc de naviguer à partir d'une source dans le foo projetez quelque chose dans bar m'amène à la version de bibliothèque importée de bar, pas aux sources locales).

Utilisez sbt versions multi-projets (aka sous-projets) , où Build.scala du projet parent contient des choses comme:

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

Cela fonctionne presque, dans la mesure où sbt-idea génère un projet maître IDEA avec les dépendances parmi les sous-projets suivis. Il y a cependant deux mises en garde:

  1. Il semble être une restriction sbt que les sous-projets doivent vivre dans des sous-répertoires du projet maître (c'est-à-dire que file("../foo") n'est pas autorisé). Ce n'est pas vraiment ce que je veux (et si un module - comme un paquet "utils" ou "commons" - est utilisé dans deux projets maîtres différents?) Mais je peux vivre avec.
  2. Un de mes sous-projets a ses propres sous-projets; Je ne sais pas si sbt lui-même traite correctement ces projets imbriqués, mais en tout cas ils sont ignorés par sbt-idea. Évidemment, j'ai besoin que les sous-projets imbriqués soient inclus récursivement dans le projet principal.

Pour résumer: je voudrais rassembler les modules qui peuvent déjà avoir des sous-projets dans un grand projet IDEA avec des dépendances suivies pour une édition pratique. Comment puis-je le faire ? Merci!

80
David Soergel

L'approche avec la construction multi-projets est la bonne. Vous pouvez avoir une arborescence imbriquée de sous-projets de longueur arbitraire, mais vous ne pouvez pas avoir un module appartenant à plusieurs projets parents. Cela est absolument logique, et dans Maven, cela se produit de la même manière.

La raison en est qu'il serait difficile d'avoir le même module dans plusieurs projets et de garder les sources synchronisées. Un flux de travail normal est le suivant:

  • Vous avez un projet auquel appartient le module, où vous modifiez la source du module.
  • Vous publiez le module dans votre référentiel local
  • Dans d'autres projets où vous avez besoin du module, vous le déclarez comme bibliothèque

Si vous souhaitez charger un module qui n'appartient pas au projet en cours dans Idea, cela est cependant possible car vous pouvez l'ajouter en tant que module externe à l'espace de travail:

  • SBT-IDEA génère les fichiers .iml pour votre projet et vous les importez dans l'espace de travail
  • Vous pouvez ajouter other.iml d'autres projets à l'espace de travail
  • Si vous modifiez des modules SBT externes que vous avez ajoutés manuellement à l'espace de travail, vous devez les republier pour obtenir les modifications visibles sur le projet "principal", qui voit que ces modules externes sont une "bibliothèqueDépendance"
7
Edmondo1984

Il semble être une restriction sbt que les sous-projets doivent vivre dans les sous-répertoires du projet maître (c'est-à-dire que le fichier ("../ foo") n'est pas autorisé). Ce n'est pas vraiment ce que je veux (et si un module - comme un paquet "utils" ou "commun" - est utilisé dans deux projets maîtres différents?) Mais je peux vivre avec.

Avec sbt 13.5 et intellij 13.x, vous pouvez spécifier la dépendance entre projets avec un chemin relatif, en utilisant un Build.scala. Disons que vous avez deux projets, un projet principal communs et un autre projet foo, tous deux vivant dans un répertoire commun code /

  1. créez Build.scala sous le code/foo/project /
  2. mettre cet extrait de code dans Build.scala

    object ProjectDependencies {
        val commons = RootProject(file("../commons"))
    }
    
    object ProjectBuild extends Build {
        import ProjectDependencies._
    
        lazy val root = Project(id = "foo", base = file(".")).dependsOn(commons)
    }
    
  3. Générez votre projet IntelliJ via sbt par sbt gen-idea

7
user2829759