¿Cómo administrar múltiples módulos interdependientes con SBT e IntelliJ IDEA?

82

Estoy desarrollando varios módulos con dependencias entre ellos y me gustaría trabajar con todos juntos en un proyecto IDEA. Estoy usando sbt-idea para generar proyectos IDEA a partir de las definiciones de compilación de sbt, lo que funciona muy bien para proyectos individuales. Sin embargo, en el caso de varios módulos, las cosas que he probado hasta ahora no funcionan del todo:

Utilice sbt-idea para generar un archivo .iml IDEA para cada módulo de forma independiente ; luego cree un proyecto IDEA maestro desde cero y agregue esos módulos. Esto hace que todas las fuentes del módulo sean editables en la misma ventana, pero las dependencias entre ellas no se rastrean (por lo que intentar navegar desde alguna fuente dentro del proyecto foo a algo en bar me lleva a la versión de la biblioteca importada de bar , no a las fuentes locales ).

Use compilaciones de proyectos múltiples de sbt (también conocidas como subproyectos) , donde Build.scala del proyecto principal contiene cosas como:

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

Esto casi funciona, ya que sbt-idea genera un proyecto IDEA maestro con las dependencias entre los subproyectos rastreados. Sin embargo, hay dos advertencias:

  1. Parece ser una restricción de sbt que los subproyectos deben vivir en subdirectorios del proyecto principal (es decir, file("../foo")no está permitido). Esto no es realmente lo que quiero (¿y si un módulo, como un paquete "utils" o "commons", se usa en dos proyectos maestros diferentes?), Pero puedo vivir con él.
  2. Uno de mis subproyectos tiene sus propios subproyectos; No estoy seguro de si el propio sbt se ocupa de estos proyectos anidados correctamente, pero en cualquier caso sbt-idea los ignora. Obviamente, necesito que los subproyectos anidados se incluyan de forma recursiva en el proyecto principal.

Para resumir: me gustaría recopilar módulos que ya pueden tener subproyectos en un gran proyecto de IDEA con dependencias rastreadas para una edición conveniente. ¿Cómo puedo hacerlo? ¡Gracias!

David Soergel
fuente
2
Intente configurar un metaproyecto que se vincule a los demás como referencias de proyectos externos ( github.com/harrah/xsbt/wiki/Full-Configuration ). No lo he probado yo mismo con sbt-idea, por lo que es un comentario en lugar de una respuesta.
retronym
Gracias por la idea, pero lamentablemente sbt-idea ignora por completo las referencias externas.
David Soergel
Tal vez esto ayude en la próxima versión de sbt-idea: github.com/mpeltonen/sbt-idea/commit/9f17cc8 github.com/mpeltonen/sbt-idea/commit/4b4adf75
retronym
Genial, así que instalé svn-idea de las últimas fuentes de git para incorporar esos cambios, luego limpié los proyectos y ejecuté sbt-idea nuevamente. Hubo algunos problemas extraños de resolución de dependencias que no entiendo completamente, ¡pero de alguna manera terminé con un proyecto en funcionamiento! Tuve que configurar manualmente los directorios de origen en IDEA para los sub-subproyectos; y en retrospectiva, no estoy seguro de que no podría haber hecho eso en primer lugar con el stock sbt-idea 11.1. De todos modos, gracias ... Creo que puedo dejar de afeitarme este yak por ahora.
David Soergel
Después de escribir ese último comentario, descubrí que después de todo no tenía un proyecto en funcionamiento (nuevamente, problemas con los sub-subproyectos). Así que los separé en proyectos de primera clase, por lo que mi proyecto maestro ahora tiene solo un nivel de subproyectos debajo. Por supuesto, solo pude hacer eso porque, para empezar, es todo mi propio código.
David Soergel

Respuestas:

7

El enfoque con la construcción multiproyecto es el correcto. Puede tener un árbol anidado de subproyectos de longitud arbitraria, pero no puede tener un módulo que pertenezca a varios proyectos principales. Esto tiene absolutamente sentido, y en Maven sucede lo mismo.

La razón es que sería difícil tener el mismo módulo en varios proyectos y mantener las fuentes sincronizadas. Un flujo de trabajo normal es el siguiente:

  • Tiene un proyecto al que pertenece el módulo, donde modifica la fuente del módulo.
  • Publica el módulo en su repositorio local
  • En otros proyectos en los que necesita el módulo, lo declara como bibliotecaDependencia

Sin embargo, si desea cargar un módulo que no pertenece al proyecto actual dentro de Idea, esto es factible, ya que puede agregarlo como un módulo externo al espacio de trabajo:

  • SBT-IDEA genera los archivos .iml para su proyecto y usted los importa en el espacio de trabajo
  • Puede agregar otro.iml de otros proyectos al espacio de trabajo
  • Si modifica módulos SBT externos que ha agregado manualmente al espacio de trabajo, debe volver a publicarlos para que los cambios sean visibles en el proyecto "principal", que considera que esos módulos externos son una "dependencia de biblioteca".
Edmondo1984
fuente
Gracias por el aporte. Sin embargo, el problema es que no es el caso que "Puede tener un árbol anidado de subproyectos de longitud arbitraria". Estoy de acuerdo en que esto debería funcionar con sbt, pero sbt-idea aparentemente no incluye sub-subproyectos en el archivo de proyecto IDEA resultante.
David Soergel
¿Esta limitación proviene de la idea?
Edmondo 1984
No, ciertamente he creado jerarquías de proyectos IDEA a varios niveles de profundidad.
David Soergel
7

Parece ser una restricción de sbt que los subproyectos deben vivir en subdirectorios del proyecto maestro (es decir, el archivo ("../ foo") no está permitido). Esto no es realmente lo que quiero (¿y si un módulo, como un paquete "utils" o "commons", se usa en dos proyectos maestros diferentes?), Pero puedo vivir con él.

Con sbt 13.5 e intellij 13.x, puede especificar la dependencia entre proyectos con una ruta relativa, utilizando Build.scala . Digamos que tiene dos proyectos, un proyecto común común y otro proyecto foo , ambos viviendo en un código de directorio común /

  1. cree Build.scala en el código / foo / project /
  2. poner este fragmento de código en 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. Genere su proyecto IntelliJ a través de sbt por sbt gen-idea

usuario2829759
fuente
¿Permitirá esto editar la fuente "commons" enlazando desde "foo"?
Tjunkie
Sí lo permite. Y funciona en mi sbt 0.13.7 e intellij 14.0.3 installion
user2829759