Este es un debate en el que estoy participando. Me gustaría conocer más opiniones y puntos de vista.
Tenemos algunas clases que se generan en tiempo de compilación para manejar operaciones de DB (en este caso específico, con SubSonic, pero no creo que sea muy importante para la pregunta). La generación se establece como un paso previo a la compilación en Visual Studio. Entonces, cada vez que un desarrollador (o el proceso de compilación oficial) ejecuta una compilación, estas clases se generan y luego se compilan en el proyecto.
Ahora, algunas personas afirman que tener estas clases guardadas en el control de código fuente podría causar confusión, en caso de que el código que obtenga no coincida con el que se habría generado en su propio entorno.
Me gustaría tener una forma de rastrear el historial del código, incluso si generalmente se trata como una caja negra.
¿Algún argumento o contraargumento?
ACTUALIZACIÓN: Hice esta pregunta porque realmente creía que hay una respuesta definitiva. Mirando todas las respuestas, podría decir con un alto nivel de certeza que no existe tal respuesta. La decisión debe tomarse en función de más de un parámetro. La lectura de las respuestas a continuación podría proporcionar una muy buena guía sobre los tipos de preguntas que debería hacerse al tener que decidir sobre este tema.
No seleccionaré una respuesta aceptada en este momento por las razones mencionadas anteriormente.
fuente
Respuestas:
Guardarlo en el control de fuente es más problemático de lo que vale la pena.
Tienes que hacer un compromiso cada vez que haces una compilación para que tenga algún valor.
Generalmente dejamos el código generado (idl, cosas de jaxb, etc.) fuera del control de fuente donde trabajo y nunca ha sido un problema
fuente
Ponlo en control de código fuente. La ventaja de tener el historial de todo lo que escribe disponible para futuros desarrolladores supera el pequeño dolor de reconstruir ocasionalmente después de una sincronización.
fuente
Cada vez que quiero mostrar cambios en un árbol de fuentes en mi propio repositorio personal, todos los 'archivos generados' aparecerán como si hubieran cambiado y deben ser confirmados.
Preferiría tener una lista más limpia de modificaciones que solo incluye actualizaciones reales que se realizaron y no cambios generados automáticamente.
Déjelos fuera y luego, después de una compilación, agregue un 'ignorar' en cada uno de los archivos generados.
fuente
Mírelo de esta manera: ¿comprueba sus archivos de objeto en el control de código fuente? Los archivos de origen generados son artefactos de compilación como archivos de objetos, bibliotecas y ejecutables. Deben recibir el mismo trato. La mayoría argumentaría que no debería comprobar los archivos de objetos generados y los ejecutables en el control de código fuente. Los mismos argumentos se aplican a la fuente generada.
Si necesita ver la versión histórica de un archivo generado, puede sincronizar con la versión histórica de sus fuentes y reconstruir.
La verificación de archivos generados de cualquier tipo en el control de fuente es análogo a la desnormalización de la base de datos. En ocasiones, existen razones para hacer esto (normalmente por motivos de rendimiento), pero debe hacerse con mucho cuidado, ya que resulta mucho más difícil mantener la corrección y la coherencia una vez que los datos se desnormalizan.
fuente
Yo diría que debería evitar agregar cualquier código generado (u otros artefactos) al control de fuente. Si el código generado es el mismo para la entrada dada, entonces puede simplemente verificar las versiones que desea diferenciar y generar el código para comparar.
fuente
Yo llamo al principio SECO. Si ya tiene los "archivos fuente" en el repositorio que se utilizan para generar estos archivos de código en el momento de la compilación, no es necesario tener el mismo código comprometido "dos veces".
Además, puede evitar algunos problemas de esta manera si, por ejemplo, la generación del código se rompe algún día.
fuente
No, por tres razones.
El código fuente es todo lo necesario y suficiente para reproducir una instantánea de su aplicación en algún momento actual o anterior, nada más y nada menos. Parte de lo que esto implica es que alguien es responsable de todo lo registrado. Generalmente, estoy feliz de ser responsable del código que escribo, pero no del código que se genera como consecuencia de lo que escribo.
No quiero que alguien se sienta tentado a intentar atajar una compilación a partir de fuentes primarias mediante el uso de un código intermedio que puede o no ser actual (y lo que es más importante, del que no quiero aceptar la responsabilidad). tentador para algunas personas quedar atrapadas en un proceso sin sentido sobre la depuración de conflictos en código intermedio basado en compilaciones parciales.
Una vez que esté en el control de la fuente, acepto la responsabilidad de a. estando allí, b. siendo actual, y c. siendo integrable de manera confiable con todo lo demás allí. Eso incluye quitarlo cuando ya no lo use. Cuanto menor sea esa responsabilidad, mejor.
fuente
Realmente no creo que debas registrarlos.
Seguramente cualquier cambio en el código generado será ruido, cambios entre entornos o cambios como resultado de otra cosa, por ejemplo, un cambio en su base de datos. Si los scripts de creación de su base de datos (o cualquier otra dependencia) están en control de código fuente, ¿por qué necesita también los scripts generados?
fuente
La regla general es no , pero si se necesita tiempo para generar el código (debido al acceso a la base de datos, los servicios web, etc.), es posible que desee guardar una versión en caché en el control de código fuente y ahorrarles a todos el dolor.
Sus herramientas también deben ser conscientes de esto y manejar la verificación desde el control de fuente cuando sea necesario, demasiadas herramientas deciden verificar desde el control de fuente sin ningún motivo.
Una buena herramienta usará la versión en caché sin tocarla (ni modificar los pasos de tiempo en el archivo).
También debe poner una gran advertencia dentro del código generado para que las personas no modifiquen el archivo, una advertencia en la parte superior no es suficiente, debe repetirla cada docena de líneas.
fuente
Tampoco almacenamos el código de base de datos generado: dado que se genera, puede obtenerlo a voluntad en cualquier versión dada de los archivos fuente. Almacenarlo sería como almacenar código de bytes o algo así.
Ahora, ¡debe asegurarse de que el generador de código utilizado en una versión determinada esté disponible! Las versiones más nuevas pueden generar código diferente ...
fuente
Déjalo afuera.
Si está revisando archivos generados, está haciendo algo mal. ¿Qué hay de malo puede ser diferente, podría ser que su proceso de construcción es ineficiente, o algo más, pero no puedo verlo jamás ser una idea buena. El historial debe estar asociado con los archivos de origen, no con los generados.
Simplemente crea un dolor de cabeza para las personas que luego terminan tratando de resolver las diferencias, encuentran los archivos que ya no son generados por la compilación y luego los eliminan, etc.
¡Un mundo de dolor aguarda a quienes registran los archivos generados!
fuente
Existe un caso especial en el que desea registrar sus archivos generados: cuando puede necesitar construir en sistemas donde las herramientas utilizadas para generar los otros archivos no están disponibles. El ejemplo clásico de esto, y con el que trabajo, es el código Lex y Yacc. Debido a que desarrollamos un sistema en tiempo de ejecución que tiene que compilarse y ejecutarse en una gran variedad de plataformas y arquitecturas, solo podemos confiar en que los sistemas de destino tengan compiladores C y C ++, no las herramientas necesarias para generar el código lexing / parsing para nuestra definición de interfaz. traductor. Por lo tanto, cuando cambiamos nuestras gramáticas, revisamos el código generado para analizarlo.
fuente
llegando un poco tarde ... de todos modos ...
¿Pondría el archivo intermedio del compilador en el control de la versión de origen? En el caso de la generación de código, por definición, el código fuente es la entrada del generador, mientras que el código generado puede considerarse como archivos intermedios entre la fuente "real" y la aplicación construida.
Entonces yo diría: no ponga el código generado bajo control de versiones, sino el generador y su entrada.
Concretamente, trabajo con un generador de código que escribí: nunca tuve que mantener el código fuente generado bajo control de versiones. Incluso diría que, dado que el generador alcanzó un cierto nivel de madurez, no tuve que observar el contenido del código generado aunque la entrada (por ejemplo, la descripción del modelo) cambió.
fuente
En algunos proyectos agrego código generado al control de fuente, pero realmente depende. Mi pauta básica es que si el código generado es una parte intrínseca del compilador, no lo agregaré. Si el código generado es de una herramienta externa, como SubSonic en este caso, lo agregaría al control de fuente. Si actualiza periódicamente el componente, quiero saber los cambios en la fuente generada en caso de que surjan errores o problemas.
En lo que respecta al código generado que debe registrarse, el peor de los casos es diferenciar manualmente los archivos y revertirlos si es necesario. Si está utilizando svn, puede agregar un gancho de confirmación previa en svn para denegar una confirmación si el archivo no ha cambiado realmente.
fuente
El trabajo de la administración de la configuración (del cual el control de versiones es solo una parte) es poder hacer lo siguiente:
El primero asegura que cuando le dice al cliente o al usuario final "el error que informó la semana pasada se corrigió y se agregó la nueva función", no regrese dos horas después y diga "no, no lo ha hecho". También se asegura de que no digan "¿Por qué está haciendo X? Nunca pedimos X".
El segundo significa que cuando el cliente o el usuario final informa un error en alguna versión que emitió hace un año, puede volver a esa versión, reproducir el error, corregirlo y demostrar que fue su corrección que eliminó el error en lugar de alguna perturbación del compilador y otras correcciones.
Esto significa que su compilador, bibliotecas, etc. también deben ser parte de CM.
Entonces, ahora para responder a su pregunta: si puede hacer todo lo anterior, entonces no necesita registrar ninguna representación intermedia, porque tiene la garantía de obtener la misma respuesta de todos modos. Si no puede hacer todo lo anterior, entonces todas las apuestas están canceladas porque nunca puede garantizar hacer lo mismo dos veces y obtener la misma respuesta. Por lo tanto, también podría poner todos sus archivos .o bajo control de versiones.
fuente
Depende realmente. En última instancia, el objetivo es poder reproducir lo que tenía si es necesario. Si puede regenerar sus binarios exactamente, no es necesario almacenarlos. pero debe recordar que para recrear sus cosas probablemente necesitará la configuración exacta con la que lo hizo en primer lugar, y eso no solo significa su código fuente, sino también su entorno de compilación, su IDE, tal vez incluso otras bibliotecas , generadores o cosas, en la configuración exacta (versiones) que ha utilizado.
Me he encontrado con problemas en proyectos en los que actualizamos nuestro entorno de compilación a versiones más nuevas o incluso a otros proveedores, donde no pudimos recrear los binarios exactos que teníamos antes. Esto es una verdadera molestia cuando los binarios que se van a desplegar dependen de un tipo de hash, especialmente en un entorno seguro, y los archivos recreados de alguna manera difieren debido a las actualizaciones del compilador o lo que sea.
Entonces, ¿almacenarías el código generado? Yo diría que no. Los binarios o entregables que se publican, incluidas las herramientas con las que los reprodujo, los almacenaría. Y luego, no hay necesidad de almacenarlos en el control de fuente, solo haga una buena copia de seguridad de esos archivos.
fuente
La respuesta correcta es "Depende". Depende de cuáles sean las necesidades del cliente. Si puede revertir el código a una versión en particular y hacer frente a cualquier auditoría externa sin él, todavía no está en terreno firme. Como desarrolladores, debemos considerar no solo el 'ruido', el dolor y el espacio en disco, sino el hecho de que tenemos la tarea de generar propiedad intelectual y puede haber ramificaciones legales. ¿Podrías demostrarle a un juez que puedes regenerar un sitio web exactamente como lo vio un cliente hace dos años?
No estoy sugiriendo que guarde o no guarde los archivos generados, de cualquier manera que decida si no está involucrando a los expertos en la materia de la decisión, probablemente esté equivocado.
Mis dos centavos.
fuente
Aquí se presentan buenos argumentos a favor y en contra. Para el registro, construí el sistema de generación T4 en Visual Studio y nuestra opción predeterminada lista para usar hace que el código generado se registre. Tienes que trabajar un poco más si prefieres no registrarte.
Para mí, la consideración clave es diferenciar la salida generada cuando se actualiza la entrada o el generador.
Si no ha registrado su salida, entonces debe tomar una copia de todo el código generado antes de actualizar un generador o modificar la entrada para poder comparar eso con la salida de la nueva versión. Creo que este es un proceso bastante tedioso, pero con la salida comprobada, es una simple cuestión de diferenciar la nueva salida con el repositorio.
En este punto, es razonable preguntarse "¿Por qué le preocupan los cambios en el código generado?" (Especialmente en comparación con el código objeto). Creo que hay algunas razones clave, que se reducen al estado actual de la técnica y no a un problema inherente.
Crea un código escrito a mano que se combina estrechamente con el código generado. Ese no es el caso en general con los archivos obj en estos días. Cuando el código generado cambia, lamentablemente es muy frecuente que algún código escrito a mano deba cambiar para coincidir. La gente a menudo no observa un alto grado de compatibilidad hacia atrás con los puntos de extensibilidad en el código generado.
El código generado simplemente cambia su comportamiento. No toleraría esto de un compilador, pero para ser justos, un generador de código a nivel de aplicación se dirige a un campo de problema diferente con una gama más amplia de soluciones aceptables. Es importante ver si las suposiciones que hizo sobre el comportamiento anterior ahora se rompen.
Simplemente no confía al 100% en la salida de su generador de un lanzamiento a otro. Se puede obtener mucho valor de las herramientas generadoras, incluso si no se construyen y mantienen con el rigor de su proveedor de compiladores. La versión 1.0 podría haber sido perfectamente estable para su aplicación, pero tal vez la 1.1 ahora tenga algunos fallos para su caso de uso. Alternativamente, cambia los valores de entrada y descubre que está ejercitando una nueva pieza del generador que no había usado antes; potencialmente, se sorprenderá con los resultados.
Básicamente, todas estas cosas se reducen a la madurez de las herramientas: la mayoría de los generadores de código de aplicaciones comerciales no están cerca del nivel que los compiladores o incluso las herramientas de nivel lex / yacc han estado durante años.
fuente
Ambas partes tienen argumentos válidos y razonables, y es difícil ponerse de acuerdo en algo común. Version Control Systems (VCS) realiza un seguimiento de los archivos que los desarrolladores introducen en él y asume que los archivos dentro de VCS están hechos a mano por los desarrolladores, y los desarrolladores están interesados en el historial y el cambio entre cualquier revisión de los archivos. Esta suposición iguala los dos conceptos, "Quiero obtener este archivo cuando realice el pago". y "Estoy interesado en el cambio de este archivo".
Ahora, los argumentos de ambos lados podrían reformularse así:
Afortunadamente, parece que los dos requisitos no están en conflicto fundamentalmente. Con alguna extensión de los VCS actuales, debería ser posible tener ambos. En otras palabras, es un falso dilema. Si reflexionamos un poco, no es difícil darse cuenta de que el problema se deriva de la suposición que sostienen los VCS. Los VCS deben distinguir los archivos, que son hechos a mano por los desarrolladores, de los archivos que no son hechos a mano por los desarrolladores, sino que simplemente están dentro de este VCS. Para la primera categoría de archivos, que normalmente llamamos archivos fuente (código), los VCS han hecho un gran trabajo ahora. Para la última categoría, los VCS no han tenido ese concepto todavía, hasta donde yo sé.
Resumen
Tomaré git como ejemplo para ilustrar lo que quiero decir.
git status
no debería mostrar los archivos generados de forma predeterminada.git commit
debe incluir archivos generados como instantánea.git diff
no debería mostrar los archivos generados de forma predeterminada.PD
Los ganchos de Git podrían usarse como una solución alternativa, pero sería genial si git los admite de forma nativa.
gitignore
no cumple con nuestro requisito, ya que los archivos ignorados no entrarán en VCS.enter code here
fuente
Yo abogaría por. Si está utilizando un proceso de integración continuo que verifica el código, modifica el número de compilación, compila el software y luego lo prueba, entonces es más simple y fácil tener ese código como parte de su repositorio.
Además, es parte integral de cada "instantánea" que tome de su repositorio de software. Si es parte del software, entonces debería ser parte del repositorio.
fuente
Yo diría que sí, quieres ponerlo bajo control de fuente. Desde el punto de vista de la gestión de la configuración, TODO lo que se utiliza para producir una compilación de software debe controlarse para poder volver a crearlo. Entiendo que el código generado se puede recrear fácilmente, pero se puede argumentar que no es lo mismo ya que la fecha / marca de tiempo será diferente entre las dos compilaciones. En algunas áreas, como el gobierno, muchas veces requieren que esto sea lo que se hace.
fuente
En general, el código generado no necesita almacenarse en el control de fuente porque el historial de revisión de este código se puede rastrear mediante el historial de revisión del código que lo generó.
Sin embargo, parece que el OP está utilizando el código generado como la capa de acceso a datos de la aplicación en lugar de escribir uno manualmente. En este caso, cambiaría el proceso de compilación y enviaría el código al control de código fuente porque es un componente crítico del código de tiempo de ejecución. Esto también elimina la dependencia de la herramienta de generación de código del proceso de compilación en caso de que los desarrolladores necesiten usar una versión diferente de la herramienta para diferentes ramas.
Parece que el código solo necesita generarse una vez en lugar de cada compilación. Cuando un desarrollador necesita agregar / eliminar / cambiar la forma en que un objeto accede a la base de datos, el código debe generarse nuevamente, al igual que hacer modificaciones manuales. Esto acelera el proceso de construcción, permite realizar optimizaciones manuales en la capa de acceso a datos y el historial de la capa de acceso a datos se conserva de manera sencilla.
fuente
(Lamentablemente) termino poniendo muchas fuentes derivadas bajo control de fuente porque trabajo de forma remota con personas que no pueden molestarse en configurar un entorno de construcción adecuado o que no tienen las habilidades para configurarlo para que el las fuentes derivadas se construyen exactamente correctamente. (¡Y cuando se trata de autotools de Gnu, yo mismo soy una de esas personas! No puedo trabajar con tres sistemas diferentes, cada uno de los cuales funciona con una versión diferente de autotools, y solo con esa versión).
Este tipo de dificultad probablemente se aplica más a proyectos voluntarios de código abierto a tiempo parcial que a proyectos pagados en los que la persona que paga las facturas puede insistir en un entorno de construcción uniforme.
Cuando hace esto, básicamente se compromete a crear los archivos derivados solo en un sitio, o solo en sitios configurados correctamente. Sus Makefiles (o lo que sea) deben configurarse para notar dónde se están ejecutando y deben negarse a volver a derivar las fuentes a menos que sepan que se están ejecutando en un sitio de compilación seguro.
fuente
Si es parte del código fuente, entonces debe colocarse en control de fuente independientemente de quién o qué lo genere. Quiere que su control de fuente refleje el estado actual de su sistema sin tener que regenerarlo.
fuente
Absolutamente tener el código generado en control de fuente, por muchas razones. Reitero lo que mucha gente ya ha dicho, pero algunas de las razones por las que lo haría son
fuente
CodeCompileUnit
en un orden canónico.Dejaría los archivos generados fuera de un árbol de fuentes, pero los pondría en un árbol de compilación separado.
por ejemplo, el flujo de trabajo es
Probablemente haya buenas formas en Subversion / Mercurial / Git / etc de unir el historial de los archivos fuente reales en ambos lugares.
fuente
Parece que hay opiniones muy fuertes y convincentes de ambos lados. Recomendaría leer todas las respuestas más votadas y luego decidir qué argumentos se aplican a su caso específico.
ACTUALIZACIÓN: Hice esta pregunta porque realmente creía que hay una respuesta definitiva. Mirando todas las respuestas, podría decir con un alto nivel de certeza que no existe tal respuesta. La decisión debe tomarse en función de más de un parámetro. La lectura de las otras respuestas podría proporcionar una muy buena guía sobre los tipos de preguntas que debería hacerse al tener que decidir sobre este tema.
fuente