NuGet emite problemas con packages.config, references de proyectos y la carpeta de packages de toda la solución

Estamos empezando a usar NuGet y estamos teniendo algunos problemas:

Primero algunos hechos NuGet:

(Solo para asegurarnos de haber entendido las premisas de cómo funciona NuGet)

  • El package.config (ubicado en el proyecto-raíz) se crea y se actualiza a medida que agrega, actualiza o elimina packages. Dentro de este file, la propiedad de la versión del package refleja la versión completa que está en uso, por lo que en este sentido también es un estado. Es posible agregar la propiedad allowedVersions a la especificación del package, que es una restricción sobre las versiones que se pueden actualizar. Para que la restauración de packages funcione, este file debe estar bajo control de fuente.

  • La carpeta de packages se encuentra en la raíz de la solución y contiene una versión descargada de los packages dependientes en una subcarpeta llamada para que coincida con los nombres del package (incluida la versión), para permitir que múltiples versiones del mismo package sean utilizadas por diferentes proyectos en un -solución del proyecto Se recomienda no controlarlos como binarys y el hecho de que la restauración del package puede volver a crearlos cuando sea necesario. Cuando se actualiza un package, se crea una nueva carpeta que coincide con la actualización con el package que contiene.

  • Los files de proyecto contienen una reference a los packages en la carpeta de packages, para que las construcciones funcionen y para que el estudio visual también pueda proporcionar autocomplete, intellisense y más. Cuando se actualiza un package, las references en el file de proyecto se actualizan para coincidir con la nueva location del package en la carpeta de packages.

Preguntas:

  1. Como las inputs del package del file packages.config contienen la información completa de la versión, constantemente necesitamos actualizar el repository de control de origen con los cambios. O bien, podríamos ignorar los cambios, la mayoría de las veces, pero cuando solo la versión haya cambiado, (en la mayoría de los casos) podríamos ignorarlos. Esto parece muy innecesario ya que la restauración de NuGet debería poder saber qué versiones están permitidas (a través de allowedVersions).

  2. La propiedad allowedVersions debe agregarse manualmente, algo que se olvida fácilmente. Estamos utilizando versiones semánticas, por lo que para nosotros, al instalar, es decir, una versión de Foo-1.1.0, allowedVersions = "[1,2]" debe estar implícito.

  3. Al agregar AllowVersion, la restauración del package NuGet no parece poder encontrar ensamblajes previos (¿quizás un error?).

  4. ¿Por qué los packages manejados por NuGet en un nivel de solución? Si está trabajando en una solución mix-and-match, que contiene un proyecto-A (repo-1) y un proyecto-B (repo-2), entonces el empaque del nivel de solución no va a funcionar bien. Es decir, si guardas ese file de solución en una location separada, las cosas aún podrían funcionar como un error. Pero, si luego configuras otra solución que contiene el proyecto-A (repo-1) y el proyecto-C (repo-3), entonces el proyecto-A de repente necesitaría un package-restaurar nuevamente, y lo que es peor, las references del proyecto serían cambiado para que coincida con el último cambio. Volver a la primera solución tendrá references que no funcionan. Verificando esto sin duda hará que no funcionen para otros.

  5. En una actualización de package, las references de file de proyecto se actualizan (para que coincida con los nuevos nombres de carpeta con versionid en ellas) y aparecerán como un cambio no confirmado. Cometer este cambio parece ser la norma, pero en nuestra opinión esto no debería ser necesario.

Notas sobre ExcludeVersion (que podría sugerirse como una solución al problema anterior:

  • Solo puede proporcionar esa opción cuando ejecuta manualmente commands NuGet, afaik. Al instalar / actualizar packages a través de los menus NuGet en Visual Studio, esa opción no se puede usar. El uso de cualquiera de las herramientas automatizadas significa que el nombre de la carpeta y la reference del proyecto se deben reparar manualmente después.

  • Sabemos que ExcludeVersion no es la configuration pnetworkingeterminada, probablemente debido a que admite casos en los que alguien está trabajando en una solución multiproyecto, donde los diferentes proyectos dependen de diferentes versiones del mismo package.

¿Soluciones posibles?

(Pero, ¿qué puede requerir cambios sustanciales en el ecosistema NuGet?)

A – packages.config

Deseo que cada elemento del package en packages.config pueda deshacerse de las allowedVersions y, en su lugar, cambie la versión para que sea el especificador de range. El elemento packages también debe proporcionar una forma de identificar por separado de qué fuente get las actualizaciones. Finalmente, si un package instalado sigue al Versión semántica, la propiedad de la versión debe configurar automáticamente el range de versión de acuerdo con la versión instalada.

Muestra packages.config:

`<?xml version="1.0" encoding="utf-8"?> <packages> <package id="Foo" version="[1,2] source="Development Feed"> </packages>` 

Esto sería:

  • Solucione el problema con las confirmaciones excesivas del file package.config, ya que la propiedad de la versión ya no se actualiza constantemente.

  • No es necesario recordar establecer el range para proyectos con versiones semánticas.

  • Asegúrese de que los packages se obtienen de la fuente deseada y que no se desperdicia time buscándolo en las fonts incorrectas.

B – Carpeta de packages y los nombres de los packages instalados dentro

Desearía que la carpeta de packages estuviera ubicada en cada raíz de proyecto y que los nombres de las subcarpetas estuvieran limitados solo al nombre del package, excluyendo la versión. Esto sería:

  • Solucione el problema con las confirmaciones excesivas de los files de proyecto, ya que las references de proyecto en el file de proyecto apuntan ahora a la misma carpeta de package después de una actualización.

  • Permite que los proyectos utilicen versiones diferentes del mismo package, ya que son verdaderamente independientes entre sí.


Estaríamos muy felices de escuchar acerca de las soluciones a los problemas enumerados.

Como se sugiere en NuGet Enterprise: mejores prácticas para diferentes niveles de madurez de packages , creo que estás haciendo las cosas más complicadas de lo necesario 🙂

  1. ¿Por qué no quieres capturar la versión del package con el que se compiló el código? Esta es información crucial para diagnósticos confiables y comstackciones repetibles. Dado que es probable que esté confirmando los cambios de código al control de la versión, es muy útil confirmar los detalles de qué packages se usaron para ayudar a comstackr esa fuente.
  2. " cuando se instala, es decir, una versión de Foo-1.1.0, allowedVersions =" ​​[1,2) "debería estar implícita. " No creo que lasVisiones permitidas puedan estar implícitas, porque no todos los packages NuGet se adhieren a SemVer (vea la debacle con log4net 1.2.11 ). La configuration de un grep para allowedVersions como parte de CI build o pre-commit / pre-push Dev checks debería atrapar esto. No debería cambiar a menudo, y es útil vigilarlo (si otros equipos y packages usan SemVer correctamente, de todos modos :)).
  3. Para encontrar los packages de presentación, necesitará los indicadores de Presentación Prerelease o de Incluir actualización en la installation nuget.
  4. " Si está trabajando en una solución mix-and-match, que contiene un proyecto-A (repo-1) y proyecto-B (repo-2) ", ¿por qué ha dispuesto su código así? El código para una única solución debe vivir todo en el mismo repository. ¡Romper el código de la solución a través de los repos definitivamente va a ser doloroso!
  5. Puedes decirle a nuget que use nombres de carpeta sin versión para instalar packages ( -ExcludeVersion ).

Recomiendo encarecidamente abandonar la integración de Visual Studio NuGet a su favor utilizando la command-line nuget.exe y crear scripts en su lugar. Esto se relaciona particularmente con el # 5 pero con la interacción con NuGet en general. La integración de Visual Studio es agradable cuando se trabaja únicamente con packages públicos de terceros de nuget.org feed, pero no es lo suficientemente flexible para mi gusto cuando se trata con feeds y packages NuGet internos.