Soy el autor de la cita en la pregunta, que vino de un previous answer.
Jason tiene razón al desconfiar de declaraciones breves como la mía, y pedir una explicación. Por supuesto, si explicara completamente todo en esa respuesta, necesitaría haber escrito un libro.
Mike también tiene razón al señalar que uno de los problemas con una característica de svn:external
es que los cambios en la fuente de destino podrían romper su propia fuente, especialmente si esa fuente de destino está en un repositorio que no es de su propiedad.
Al explicar más mi comentario, permítanme decir primero que hay formas "seguras" de utilizar la característica svn:external
, al igual que con cualquier otra herramienta o función. Sin embargo, me refiero a él como antipattern porque la característica es mucho más probable que se use incorrectamente. En mi experiencia, siempre se ha usado mal, y es muy poco probable que alguna vez lo use de esa manera segura ni recomiende ese uso. Tenga en cuenta que no me refiero al menosprecio al equipo de Subversion. Me encanta Subversion, aunque tengo la intención de pasar a Bazar.
El principal problema con esta característica es que fomenta y se utiliza normalmente para vincular directamente el origen de una compilación ("proyecto") a la fuente de otra, o para vincular el proyecto a un archivo binario (DLL, JAR , etc.) de lo que depende. Ninguno de estos usos es sabio, y constituyen un antipatrón.
Como dije en mi otra respuesta, creo que un principio esencial para las compilaciones de software es que cada proyecto construye exactamente UN entregas binarias o primarias. Esto se puede considerar una aplicación del principio de separation of concerns al proceso de compilación. Esto es particularmente cierto con respecto a un proyecto que hace referencia directamente a la fuente de otro, que también es una violación del principio de encapsulation. Otra forma de este tipo de infracción es intentar crear una jerarquía de compilación para construir un sistema o subsistema completo mediante la invocación recursiva de subconstrucciones. Maven recomienda encarecidamente/impone este comportamiento, que es una de las muchas razones por las que no lo recomiendo.
Finalmente, considero que hay varias cuestiones prácticas que hacen que esta característica sea indeseable. Por un lado, svn:external
tiene algunas características de comportamiento interesantes (pero los detalles se me escapan por el momento). Por otro lado, siempre encuentro que necesito tales dependencias para ser explícitamente visibles para mi proyecto (proceso de compilación), no oculto como algunos metadatos de control de origen.
Entonces, ¿cuál es una manera "segura" de usar esta función? Lo consideraría así cuando lo usa temporalmente una sola persona, como una forma de "configurar" un entorno de trabajo. Pude ver dónde un programador podría crear su propia carpeta en el repositorio (o uno para cada programador) donde configuraría los enlaces svn:external
a las otras partes del repositorio en las que están trabajando actualmente. Luego, el pago de esa única carpeta creará una copia de trabajo de todos sus proyectos actuales. Cuando se agrega o finaliza un proyecto, las definiciones svn:external
se pueden ajustar y la copia de trabajo se puede actualizar adecuadamente. Sin embargo, prefiero un enfoque que no esté vinculado a un sistema de control de fuente en particular, como hacer esto con un script que invoca los checkouts.
Para el registro, mi exposición más reciente a este problema ocurrió durante el verano de 2008 en un cliente de consultoría que usaba svn:external
en una escala masiva: TODO fue reticulado para producir una única copia maestra de trabajo. Sus Ant & guiones de compilación basados en Jython (para WebLogic) se construyeron sobre esta copia maestra de trabajo. El resultado neto: NADA podría construirse de forma independiente, había literalmente docenas de subproyectos, pero ninguno era seguro para pagar/trabajar por sí mismo. Por lo tanto, cualquier trabajo en este sistema primero requirió una verificación/actualización de más de 2 GB de archivos (también colocaron binarios en el repositorio). Hacer cualquier cosa fue un ejercicio inútil, y me fui después de intentar durante tres meses (también había muchos otros antipatritos presentes).
EDIT: exponer sobre recursiva construye -
lo largo de los años (sobre todo la última década), he construido sistemas masivos de las compañías Fortune 500 y grandes agencias gubernamentales que implican muchas docenas de sub-proyectos organizados en jerarquías de directorios que son muchos niveles profundos. He utilizado proyectos/soluciones de Microsoft Visual Studio para organizar sistemas basados en .NET, Ant o Maven 2 para sistemas basados en Java, y he comenzado a usar distutils y setuptools (easyinstall) para sistemas basados en Python. Estos sistemas también han incluido enormes bases de datos típicamente en Oracle o Microsoft SQL Server.
He tenido un gran éxito diseñando estas construcciones masivas para facilitar el uso y la repetibilidad.Mi estándar de diseño es que un nuevo desarrollador puede aparecer en su primer día, recibir una nueva estación de trabajo (tal vez directamente de Dell con solo una instalación típica de sistema operativo), recibir un documento de configuración simple (generalmente solo una página de instrucciones de instalación). y poder configurar completamente la estación de trabajo y construir el sistema completo desde la fuente, sin supervisión, sin asistencia, y en medio día o menos. Invocar la compilación en sí implica abrir un shell de comando, cambiar al directorio raíz del árbol de origen y emitir un comando de una línea para compilar TODO.
A pesar de ese éxito, la construcción de un sistema de construcción tan masivo requiere gran cuidado y una adhesión estricta a principios sólidos de diseño, al igual que con la construcción de una aplicación/sistema masivo y crítico para el negocio. He descubierto que una parte crucial es que cada proyecto (que produce un artefacto/entregable único) debe tener un solo script de compilación, que debe tener una interfaz bien definida (comandos para invocar porciones del proceso de compilación), y debe mantenerse. solo de todos los otros (sub) proyectos. Históricamente, es fácil construir todo el sistema, pero es difícil/imposible construir solo una pieza. Recientemente, he aprendido a asegurarme cuidadosamente de que cada proyecto realmente se desarrolle solo.
En la práctica, esto significa que debe haber al menos dos capas de scripts de compilación. La capa más baja son los scripts de compilación del proyecto que producen cada producto/artefacto. Cada script reside en el directorio raíz de su árbol fuente del proyecto (de hecho, este script define su árbol fuente del proyecto), estos scripts no saben nada sobre el control fuente, esperan ejecutarse desde la línea de comando, hacen referencia a todo en el proyecto relativo al script de compilación, y hacen referencia a sus dependencias externas (herramientas o artefactos binarios, no a otros proyectos fuente) en función de algunas configuraciones configurables (variables de entorno, archivos de configuración, etc.).
La segunda capa de scripts de compilación también se debe invocar desde la línea de comandos, pero estos saben sobre el control de origen. De hecho, esta segunda capa es a menudo un único script que se invoca con un nombre de proyecto y una versión, luego verifica el origen del proyecto nombrado en un nuevo directorio temporal (tal vez especificado en la línea de comando) e invoca su script de compilación.
Puede ser necesario que haya más variaciones para acomodar servidores de integración continua, plataformas múltiples y varios escenarios de lanzamiento.
A veces existe la necesidad de una tercera capa de scripts que invoca la segunda capa de scripts (que invoca la primera capa) con el fin de crear subconjuntos específicos del conjunto de proyectos general. Por ejemplo, cada desarrollador puede tener su propia secuencia de comandos que crea los proyectos en los que están trabajando hoy. Puede haber un script para compilar todo con el fin de generar la documentación maestra o calcular métricas.
Independientemente, he encontrado que intentar tratar el sistema como una jerarquía de proyectos es contraproducente. Vincula los proyectos entre sí para que no se puedan compilar libremente solos o en ubicaciones arbitrarias (directorio temporal en el servidor de integración continua) o en un orden arbitrario (suponiendo que se satisfacen las dependencias). A menudo, intentar forzar una jerarquía rompe cualquier integración IDE que se pueda intentar.
Finalmente, construir una jerarquía masiva de proyectos puede ser simplemente demasiado intensivo en el rendimiento. Por ejemplo, durante la primavera de 2007, intenté una jerarquía de fuentes modesta (Java más Oracle) que construí utilizando Ant, que finalmente falló porque la compilación siempre abortaba con una excepción OutOfMemoryException de Java. Esto fue en una estación de trabajo RAM de 2 GB con un espacio de intercambio de 3,5 GB para el cual había sintonizado la JVM para poder usar toda la memoria disponible. La aplicación/sistema era relativamente trivial en términos de cantidad de código, pero las invocaciones de compilación recursivas eventualmente agotaron la memoria, sin importar la cantidad de memoria que le di. Por supuesto, también llevó una eternidad ejecutar también (30-60 minutos era común, antes de abortar). Sé cómo sintonizar MUY bien, pero al final simplemente estaba excediendo los límites de las herramientas (Java/Ant en este caso).
Así que hágase un favor, construya su compilación como proyectos independientes, luego compórtelos en un sistema completo. Mantenlo ligero y flexible. Disfrutar.
EDITAR: Más sobre antipatrones
en sentido estricto, un anti patrón es una solución común que parece que se soluciona el problema, pero no lo hace, ya sea porque deja lagunas importantes o porque introduce problemas adicionales (a menudo peores que el problema original). Una solución implica necesariamente una o más herramientas más la técnica para aplicarlas al problema en cuestión. Por lo tanto, es difícil referirse a una herramienta o una característica específica de una herramienta como un antipatrón, y parece que las personas están detectando y reaccionando a ese estiramiento, es suficiente.
Por otro lado, dado que parece ser una práctica común en nuestra industria centrarse en las herramientas en lugar de la técnica, es la herramienta/función la que llama la atención (una encuesta informal de preguntas aquí en StackOverflow parece ilustrar fácilmente) Mis comentarios y esta pregunta en sí reflejan esa práctica.
Sin embargo, a veces parece especialmente justificado realizar ese estiramiento, como en este caso. Algunas herramientas parecen "guiar" al usuario a técnicas particulares para aplicarlas, hasta el punto en que algunos argumentan que tools shape thought (ligeramente reformulada). Es sobre todo en ese espíritu que sugiero que svn:external
es un antipatrón.
Para establecer el problema de manera más estricta, el antipatrón es diseñar una solución de compilación que incluya vincular proyectos en el nivel de origen o versiones implícitamente las dependencias entre proyectos o permitir que esas dependencias cambien implícitamente, porque cada uno esto invoca consecuencias muy negativas. La naturaleza de la característica similar a svn:external
hace que evitar esas consecuencias negativas sea muy difícil.
El manejo adecuado de las dependencias entre proyectos implica abordar esas dinámicas junto con el problema de base, y las herramientas y técnicas conducen por un camino diferente. Un ejemplo que debe considerarse es Ivy, que ayuda de manera similar a Maven, pero sin las muchas desventajas. Estoy investigando a Ivy, junto con Ant, como mi solución a corto plazo para el problema de compilación de Java. A largo plazo, estoy buscando incorporar los conceptos centrales y las características en una herramienta de código abierto que facilita una solución multiplataforma.
Ver también esta respuesta: http://stackoverflow.com/a/248367/29152. – DuckMaestro
He visto mejores preguntas que las señaladas por los moderadores como inadecuadas para los foros de desbordamiento de pila debido a la naturaleza subjetiva de las posibles respuestas. Es bastante extraño lo inconsistentes que son los moderadores al marcar preguntas cuando, en algunos casos, las respuestas posteriores no están permitidas. – shawn1874