¿Cómo utilizar subposiciones mercuriales para componentes y dependencias compartidas?

Desarrollamos software empresarial .NET en C #. Estamos buscando mejorar nuestro sistema de control de versiones. He usado mercurial antes y lo he estado experimentando en nuestra empresa. Sin embargo, dado que desarrollamos productos empresariales, nos centramos en los componentes o módulos reutilizables. He estado intentando usar los sub-repos de mercurial para administrar componentes y dependencias, pero estoy teniendo algunas dificultades. Estos son los requisitos básicos para el control de fuente / gestión de dependencias:

Componentes reutilizablesCompartido por fuente (para depuración)Tener dependencias en binarios de terceros y otros componentes reutilizablesPuede ser desarrollado y comprometido con el control de fuente en el contexto de un producto consumidor.DependenciasLos productos tienen dependencias en binarios de terceros y otros componentes reutilizablesLas dependencias tienen sus propias dependencias.Los desarrolladores deben ser notificados de conflictos de versiones en dependencias.

Aquí está la estructura en mercurial que he estado usando:

Un componente reutilizable:
SHARED1_SLN-+-docs
            |
            +-libs----NLOG
            |
            +-misc----KEY
            |
            +-src-----SHARED1-+-proj1
            |                 +-proj2
            |
            +-tools---NANT
Un segundo componente reutilizable, que consume el primero:
SHARED2_SLN-+-docs
            |
            +-libs--+-SHARED1-+-proj1
            |       |         +-proj2
            |       |
            |       +-NLOG
            |
            +-misc----KEY
            |
            +-src-----SHARED2-+-proj3
            |                 +-proj4
            |
            +-tools---NANT            
Un producto que consume ambos componentes:
PROD_SLN----+-docs
            |
            +-libs--+-SHARED1-+-proj1
            |       |         +-proj2
            |       |
            |       +-SHARED2-+-proj3
            |       |         +-proj4
            |       |
            |       +-NLOG
            |
            +-misc----KEY
            |
            +-src-----prod----+-proj5
            |                 +-proj6
            |
            +-tools---NANT
NotasRepos estan en CAPSSe supone que todos los repos de niños son subreposLas bibliotecas de terceros (binarias) y los componentes internos (de origen) son todos subpospos ubicados en la carpeta libsLas bibliotecas de terceros se guardan en repositorios mercuriales individuales para que los proyectos consumidores puedan hacer referencia a versiones particulares de las bibliotecas (es decir, un proyecto antiguo puede hacer referencia a NLog v1.0, y un proyecto más nuevo puede hacer referencia a NLog v2.0).Todos los archivos .csproj de Visual Studio se encuentran en el cuarto nivel (carpetas proj *), lo que permite referencias relativas a dependencias (es decir, ../../../libs/NLog/NLog.dll para todos los proyectos de Visual Studio que hacen referencia a NLog)Todos los archivos .sln de Visual Studio se encuentran en el segundo nivel (carpetas src) para que no se incluyan cuando se "comparte" un componente en un componente o producto consumidor.Los desarrolladores tienen la libertad de organizar sus archivos de origen como mejor les parezca, siempre y cuando los orígenes sean hijos de la carpeta proj * del proyecto de Visual Studio que consume (es decir, puede haber n hijos en las carpetas de proj *, que contienen varios recursos / fuentes)Si Bob está desarrollando el componente SHARED2 y el producto PROD1, es perfectamente legal para él realizar cambios en la fuente SHARED2 (por ejemplo, las fuentes que pertenecen a proj3) dentro del repositorio PROD1_SLN y confirmar esos cambios. No nos importa si alguien desarrolla una biblioteca en el contexto de un proyecto consumidor.Los componentes desarrollados internamente (SHARED1 y SHARED2) generalmente se incluyen por fuente en el proyecto consumidor (en Visual Studio se agrega una referencia a un proyecto en lugar de buscar una referencia de DLL). Esto permite la depuración mejorada (ingresar en el código de la biblioteca), permite que Visual Studio administre cuándo necesita reconstruir proyectos (cuando se modifican las dependencias) y permite la modificación de las bibliotecas cuando sea necesario (como se describe en la nota anterior).Preguntas

Si Bob está trabajando en PROD1 y Alice está trabajando en SHARED1, ¿cómo puede saber Bob cuando Alice realiza cambios en SHARED1? Actualmente con Mercurial, Bob se ve obligado a extraer y actualizar manualmente dentro de cada subrepo. Si él empuja / jala al servidor desde el repositorio de PROD_SLN, nunca sabe acerca de las actualizaciones de los subpospos. Esto se describe enWiki mercurial. ¿Cómo se puede notificar a Bob las actualizaciones de los subpospos cuando extrae la última versión de PROD_SLN del servidor? Idealmente, debería ser notificado (preferible durante el tirón) y luego decidir qué subposiciones desea actualizar manualmente.

Supongamos que SHARED1 hace referencia a NLog v1.0 (commit / rev abc en mercurial) y SHARED2 hace referencia a Nlog v2.0 (commit / rev xyz en mercurial). Si Bob está absorbiendo estos dos componentes en PROD1, debe ser informado de esta discrepancia. Aunque técnicamente Visual Studio / .NET permitiría que 2 ensamblajes hicieran referencia a diferentes versiones de dependencias, mi estructura no lo permite porque la ruta a NLog es fija para todos los proyectos .NET que dependen de NLog. ¿Cómo puede saber Bob que dos de sus dependencias tienen conflictos de versión?

Si Bob está configurando la estructura del repositorio para PROD1 y quiere incluir SHARED2, ¿cómo puede saber qué dependencias son necesarias para SHARED2? Con mi estructura, tendría que clonar manualmente (o buscar en el servidor) el repositorio SHARED2_SLN y buscar en la carpeta libs, o ver el archivo .hgsub para determinar qué dependencias debe incluir. Idealmente esto sería automatizado. Si incluyo SHARED2 en mi producto, SHARED1 y NLog también se incluyen de manera automática, notificándome si hay un conflicto de versión con alguna otra dependencia (consulte la pregunta 2 más arriba).

Preguntas más grandes

¿Es mercurial la solución correcta?

¿Hay una mejor estructura mercurial?

¿Es este un uso válido para subrepos (es decir, los desarrolladores de Mercurial marcadossubrepos como una característica de último recurso)?

¿Tiene sentido usar mercurial para la gestión de la dependencia? Podríamos usar otra herramienta más para la gestión de dependencias (¿quizás un feed interno de NuGet?). Si bien esto funcionaría bien para dependencias de terceros, realmente crearía una molestia para los componentes desarrollados internamente (es decir, si se desarrollan activamente, los desarrolladores tendrían que actualizar constantemente la fuente, tendríamos que atenderlos internamente, y no permitiría componentes a ser modificados por un proyecto consumidor (Nota 8 y Pregunta 2).

¿Tienes una mejor solución para proyectos de software Enterprise .NET?

Referencias

He leído varias preguntas de SO y he encontradoéste para ser de ayuda, pero larespuesta aceptada Sugiere utilizar una herramienta dedicada para dependencias. Si bien me gustan las características de una herramienta de este tipo, no permite que se modifiquen y confirmen las dependencias de un proyecto consumidor (consulte la Pregunta 4 más grande).

Respuestas a la pregunta(2)

Su respuesta a la pregunta