Soll ich generierten Code in der Quellcodeverwaltung speichern?


106

Dies ist eine Debatte, an der ich teilnehme. Ich würde gerne mehr Meinungen und Standpunkte erhalten.

Wir haben einige Klassen, die in der Erstellungszeit generiert werden, um DB-Operationen zu verarbeiten (in diesem speziellen Fall mit SubSonic, aber ich denke nicht, dass dies für die Frage sehr wichtig ist). Die Generierung wird in Visual Studio als vorgefertigter Schritt festgelegt. Jedes Mal, wenn ein Entwickler (oder der offizielle Build-Prozess) einen Build ausführt, werden diese Klassen generiert und dann in das Projekt kompiliert.

Nun behaupten einige Leute, dass das Speichern dieser Klassen in der Quellcodeverwaltung Verwirrung stiften könnte, falls der Code, den Sie erhalten, nicht mit dem übereinstimmt, der in Ihrer eigenen Umgebung generiert worden wäre.

Ich hätte gerne eine Möglichkeit, den Verlauf des Codes zurückzuverfolgen, auch wenn dieser normalerweise als Black Box behandelt wird.

Irgendwelche Argumente oder Gegenargumente?


UPDATE: Ich habe diese Frage gestellt, da ich wirklich geglaubt habe, dass es eine endgültige Antwort gibt. Wenn ich mir alle Antworten anschaue, kann ich mit hoher Sicherheit sagen, dass es keine solche Antwort gibt. Die Entscheidung sollte auf der Grundlage von mehr als einem Parameter getroffen werden. Das Lesen der folgenden Antworten könnte eine sehr gute Richtlinie für die Arten von Fragen liefern, die Sie sich stellen sollten, wenn Sie sich für dieses Problem entscheiden müssen.

Ich werde an dieser Stelle aus den oben genannten Gründen keine akzeptierte Antwort auswählen.


1
Sie könnten an einer ähnlichen Frage interessiert sein: stackoverflow.com/questions/739391/…
mouviciel

Ich möchte sagen, dass es im Fall von SubSonic interessant sein könnte, die Quellcodeverwaltung beizubehalten, um auch (einige) Datenbankänderungen einfach zu verfolgen, falls Sie keine andere Möglichkeit haben, den Verlauf von zu verfolgen Ihre Datenbank.
Earlz

1
Meiner Meinung nach besteht das Hauptproblem darin, dass verschiedene Entwickler beim Generieren der Klassen nicht das gleiche Ergebnis erzielen. Die Konfiguration zum Generieren sollte eingecheckt sein und in allen Entwicklerumgebungen konsistente Builds enthalten.
Nawroth

1
Ich weiß nicht, wie ich das machen soll, aber ich denke, diese Frage sollte jetzt geschlossen werden, da sie zu offen für Meinungen und Diskussionen ist, ohne sich eng auf bestimmte Versionsverwaltungssysteme oder bestimmte Arten von generierten Dateien zu beziehen.
Chris Halcrow

Dies ist eine großartige Frage, aber sie ist für SO zu meinungsbasiert, wie aus den mehreren widersprüchlichen Antworten und dem diesbezüglichen Kommentar des OP hervorgeht.
Flimzy

Antworten:


48

Das Speichern in der Quellcodeverwaltung ist schwieriger als es sich lohnt.

Sie müssen jedes Mal ein Commit ausführen, wenn Sie einen Build ausführen, damit er einen beliebigen Wert aufweist.

Im Allgemeinen lassen wir generierten Code (idl, jaxb usw.) außerhalb der Quellcodeverwaltung, wo ich arbeite, und es war nie ein Problem


43
Ich bin nicht einverstanden mit "Sie müssen jedes Mal, wenn Sie bauen, ein Commit durchführen". Dies sollte kein zusätzliches Festschreiben verursachen, da das einzige, was sich auf das Festschreiben auswirken sollte, eine Änderung des Codes ist, wodurch die generierte Quelle geändert wird. Tatsächlich müssen Sie den generierten Code nur dann festschreiben, wenn Sie die Änderung bereits an der Quelle des generierten Codes festschreiben.
JaredPar

5
Stimmen Sie JaredPar zu. Ihr Code-Generator kann auch ein externes Tool sein. Wenn Sie ihn aktualisieren, kann sich der generierte Code ändern und Sie müssen möglicherweise Änderungen festschreiben. Aber in diesem Fall möchte ich die Änderungen in der Quellcodeverwaltung trotzdem sehen.
van

Unterschiedliche Tools können unterschiedliche Quellen generieren (zumindest können sie sich in Kommentaren oder Code-Formatierung unterscheiden). Beispiel: Idea fügt einen Kommentar "Generiert durch Idee" hinzu, Eclipse jedoch nicht.
Petr Gladkikh

1
Die Meinung ist geteilt, und diese als Antwort zu markieren, würde eine falsche Botschaft vermitteln.
Espresso

34

Setzen Sie es in die Quellcodeverwaltung. Der Vorteil, dass der Verlauf von allem, was Sie schreiben, für zukünftige Entwickler verfügbar ist, überwiegt den geringen Aufwand, der nach einer Synchronisierung gelegentlich neu erstellt wird.


18
Das ist kein Vorteil - da der Code, der ihn erstellt hat, eingecheckt ist, steht zukünftigen Entwicklern bereits alles zur Verfügung, was Sie schreiben.
Shane C. Mason

13
@ Shane, ich stimme überhaupt nicht zu. Der Code, der ihn erstellt hat, ist nicht gleichbedeutend mit dem Code. Alle zusätzlichen Schritte, die für die Generierung enthalten sein müssen, sind besonders ärgerlich, wenn Sie einen Fehler aufspüren. Es ist viel einfacher, den Verlauf des Codes durchzugehen, als N Versionen der Datei auszuchecken und N Versionen des generierten Codes neu zu generieren.
JaredPar

10
Manchmal ist es vorteilhaft, die generierten Dateien in der Quellcodeverwaltung zu haben. Wenn Sie beispielsweise eine Komponente aktualisieren, in diesem Fall SubSonic, können Sie Änderungen an der generierten Quelle leicht erkennen. Dies kann hilfreich sein, um Fehler und Probleme aufzuspüren. Ich würde nicht den gesamten generierten Code zur Quellcodeverwaltung hinzufügen. Manchmal ist es sehr nützlich. Bei den meisten Versionsverwaltungssystemen können Sie einen Unterschied machen, um festzustellen, ob sich die Dateien wirklich geändert haben, obwohl dies möglicherweise eher ein manueller Vorgang ist, wenn Sie die Dateien manuell zurücksetzen müssen, obwohl die einzige Änderung der Zeitstempel ist.
Ryan

18
Nach dieser Logik sollten Sie auch Ihre kompilierten Objektdateien, Bibliotheken und ausführbaren Dateien einchecken.
Laurence Gonsalves

9
Welche Art von Codegenerator verwenden Sie, wenn "die Originalsprache bedeutungslos ist"? Um zu verfolgen, welche Versionen Ihrer Tools Sie zum Erstellen der einzelnen Codeversionen verwenden, müssen Sie dieses Problem bereits für Ihre gesamte Toolchain lösen. Wie können Sie einen Fehler auf eine ältere Version Ihres Produkts zurückportieren, wenn Sie nicht wissen, welche Version des Compilers und Linkers Sie damals verwendet haben? Ein Codegenerator unterscheidet sich nicht von Ihrem C ++ / Java / C # -Compiler. Die Tatsache, dass Sie möglicherweise die Ausgabe lesen können, spielt keine Rolle: Die Eingabe ist die Quelle.
Laurence Gonsalves

31

Jedes Mal, wenn ich Änderungen an einem Quellbaum in meinem persönlichen Repo anzeigen möchte, werden alle "generierten Dateien" als geändert angezeigt und müssen angepasst werden.

Ich würde es vorziehen, eine übersichtlichere Liste von Änderungen zu haben, die nur echte Aktualisierungen enthalten, die durchgeführt wurden, und keine automatisch generierten Änderungen.

Lassen Sie sie weg und fügen Sie nach einem Build jeder generierten Datei ein "Ignorieren" hinzu.


3
Außerdem können bei Updates seltsame Konflikte auftreten, die vom VCS als lösungsbedürftig eingestuft werden, sich jedoch beim nächsten Erstellen tatsächlich selbst lösen. Ganz zu schweigen von der Unordnung in den Protokollen, die ich für noch schlimmer halte als die Unordnung in Ihrem lokalen Baum.
rmeador

5
Wo ich bin, werden sie nicht als "verändert" angezeigt, es sei denn, sie haben sich wirklich verändert. Wenn sie neu generiert wurden, aber immer noch den gleichen Inhalt haben, ist das einzige, was sich unterscheidet, das Erstellen / Ändern von Daten. Das System glaubt, dass sie sich nicht geändert haben, und alles ist in Ordnung.
Joel Coehoorn

+1 Ich möchte nur für den Code verantwortlich sein, den ich schreibe, nicht für Code, der von einem Toolkit generiert wurde, bei dem zu diesem Zeitpunkt möglicherweise Probleme aufgetreten sind, die jetzt nicht mehr dupliziert werden können (aber jemand könnte viel Zeit damit verbringen, es zu versuchen.)
dkretz

4
Ich habe Tools zur automatischen Generierung gesehen, die den Zeitstempel bei jeder Ausführung aktualisieren. Ich verfluche sie.
Kieveli

25

Betrachten Sie es so: Checken Sie Ihre Objektdateien in die Quellcodeverwaltung ein? Generierte Quelldateien sind Build-Artefakte wie Objektdateien, Bibliotheken und ausführbare Dateien. Sie sollten gleich behandelt werden. Die meisten würden argumentieren, dass Sie generierte Objektdateien und ausführbare Dateien nicht in die Quellcodeverwaltung einchecken sollten. Die gleichen Argumente gelten für die generierte Quelle.

Wenn Sie sich die historische Version einer generierten Datei ansehen müssen, können Sie sie mit der historischen Version ihrer Quellen synchronisieren und neu erstellen.

Das Einchecken generierter Dateien jeglicher Art in die Quellcodeverwaltung erfolgt analog zur Denormalisierung der Datenbank. Es gibt gelegentlich Gründe, dies zu tun (normalerweise aus Gründen der Leistung). Dies sollte jedoch nur mit großer Sorgfalt erfolgen, da es viel schwieriger wird, die Richtigkeit und Konsistenz aufrechtzuerhalten, sobald die Daten denormalisiert sind.


20

Ich würde sagen, dass Sie vermeiden sollten, generierten Code (oder andere Artefakte) zur Quellcodeverwaltung hinzuzufügen. Wenn der generierte Code für die angegebene Eingabe identisch ist, können Sie einfach die Versionen überprüfen, die Sie unterscheiden möchten, und den Code zum Vergleich generieren.



17

Ich nenne das DRY-Prinzip. Wenn Sie bereits die "Quelldateien" im Repository haben, mit denen diese Codedateien beim Erstellen generiert werden, muss nicht derselbe Code "zweimal" festgeschrieben werden.

Außerdem können Sie auf diese Weise einige Probleme vermeiden, wenn beispielsweise die Codegenerierung eines Tages unterbrochen wird.


15

Nein, aus drei Gründen.

  1. Der Quellcode ist alles Notwendige und Ausreichende, um einen Schnappschuss Ihrer Anwendung zu einem aktuellen oder vorherigen Zeitpunkt zu reproduzieren - nicht mehr und nicht weniger. Dies impliziert unter anderem, dass jemand für alles verantwortlich ist, was eingecheckt wurde. Im Allgemeinen bin ich froh, für den Code verantwortlich zu sein, den ich schreibe, aber nicht für den Code, der als Folge dessen generiert wird, was ich schreibe.

  2. Ich möchte nicht, dass jemand versucht ist, einen Build aus Primärquellen zu verknüpfen, indem er Zwischencode verwendet, der möglicherweise aktuell ist oder nicht (und was noch wichtiger ist, für den ich keine Verantwortung übernehmen möchte). Und nicht auch? Es ist verlockend für einige Leute, in einen bedeutungslosen Prozess über das Debuggen von Konflikten in Zwischencode verwickelt zu werden, der auf partiellen Builds basiert.

  3. Sobald es in der Quellcodeverwaltung ist, übernehme ich die Verantwortung für a. es ist da, b. es ist aktuell und c. es ist zuverlässig in alles andere integriert. Dazu gehört das Entfernen, wenn ich es nicht mehr benutze. Je weniger von dieser Verantwortung, desto besser.


14

Ich denke wirklich nicht, dass Sie sie einchecken sollten.

Sicherlich wird jede Änderung des generierten Codes entweder Rauschen sein - Änderungen zwischen Umgebungen oder Änderungen aufgrund von etwas anderem - z. B. einer Änderung in Ihrer Datenbank. Wenn sich die Erstellungsskripte Ihrer Datenbank (oder andere Abhängigkeiten) in der Quellcodeverwaltung befinden, warum benötigen Sie dann auch die generierten Skripte?


8

Die allgemeine Regel lautet " Nein" . Wenn das Generieren des Codes jedoch einige Zeit in Anspruch nimmt (aufgrund von DB-Zugriff, Webdiensten usw.), möchten Sie möglicherweise eine zwischengespeicherte Version in der Quellcodeverwaltung speichern und allen die Schmerzen ersparen.

Ihr Tool muss sich dessen ebenfalls bewusst sein und bei Bedarf das Auschecken aus der Quellcodeverwaltung übernehmen. Zu viele Tools entscheiden sich ohne Grund für das Auschecken aus der Quellcodeverwaltung.
Ein gutes Tool verwendet die zwischengespeicherte Version, ohne sie zu berühren (oder die Zeitschritte in der Datei zu ändern).

Außerdem müssen Sie eine große Warnung in den generierten Code einfügen, damit die Benutzer die Datei nicht ändern können. Eine Warnung oben reicht nicht aus. Sie müssen sie alle Dutzend Zeilen wiederholen.


6

Wir speichern auch keinen generierten DB-Code: Da er generiert wird, können Sie ihn nach Belieben in einer beliebigen Version aus den Quelldateien abrufen. Das Speichern wäre wie das Speichern von Bytecode oder ähnlichem.

Jetzt müssen Sie sicherstellen, dass der in einer bestimmten Version verwendete Codegenerator verfügbar ist! Neuere Versionen können unterschiedlichen Code generieren ...


5

Lass es aus.

Wenn Sie generierte Dateien einchecken, machen Sie etwas falsch. Was falsch ist, kann sich unterscheiden. Es kann sein, dass Ihr Erstellungsprozess ineffizient ist oder etwas anderes, aber ich kann nicht sehen, dass es jemals eine gute Idee ist. Der Verlauf sollte den Quelldateien zugeordnet werden, nicht den generierten.

Es bereitet nur Kopfschmerzen für Leute, die dann versuchen, Unterschiede zu lösen, die Dateien zu finden, die nicht mehr vom Build generiert werden, und sie dann zu löschen usw.

Eine Welt voller Schmerzen erwartet diejenigen, die generierte Dateien einchecken!


4

Es gibt einen Sonderfall, in dem Sie Ihre generierten Dateien einchecken möchten: Wenn Sie möglicherweise auf Systemen aufbauen müssen, auf denen keine Tools zum Generieren der anderen Dateien verfügbar sind. Das klassische Beispiel dafür und eines, mit dem ich arbeite, ist Lex- und Yacc-Code. Da wir ein Laufzeitsystem entwickeln, das auf einer Vielzahl von Plattformen und Architekturen erstellt und ausgeführt werden muss, können wir uns nur auf Zielsysteme mit C- und C ++ - Compilern verlassen, nicht auf die Tools, die zum Generieren des Lexing- / Parsing-Codes für unsere Schnittstellendefinition erforderlich sind Übersetzer. Wenn wir also unsere Grammatik ändern, checken wir den generierten Code ein, um ihn zu analysieren.


2
Ähnliche Kommentare gelten für von Autoconf / Automake generierte Dateien. Die meisten Benutzer checken ihre ./configure- und Makefile.in-Dateien ein, obwohl sie generiert wurden. Die meisten Benutzer (und viele Entwickler) müssen sie nicht neu erstellen. Wenn Sie diese Dateien einchecken, müssen keine Autotools installiert sein bauen.
Stobor

1
Ja, wir speichern unser Konfigurationsskript und unsere generierten Make-Abhängigkeiten auch in der Versionskontrolle.
Phil Miller

4

etwas spät ankommen ... sowieso ...

Würden Sie die Zwischendatei des Compilers in die Versionskontrolle der Quelle einfügen? Bei der Codegenerierung ist der Quellcode per Definition die Eingabe des Generators, während der generierte Code als Zwischendatei zwischen der "echten" Quelle und der erstellten Anwendung betrachtet werden kann.

Ich würde also sagen: Setzen Sie den generierten Code nicht der Versionskontrolle unter, sondern den Generator und seine Eingabe.

Konkret arbeite ich mit einem Codegenerator, den ich geschrieben habe: Ich musste den generierten Quellcode nie unter Versionskontrolle halten. Ich würde sogar sagen, dass ich, da der Generator einen bestimmten Reifegrad erreicht hat, den Inhalt des generierten Codes nicht beobachten musste, obwohl sich die Eingabe (zum Beispiel die Modellbeschreibung) geändert hat.


3

In einigen Projekten füge ich generierten Code zur Quellcodeverwaltung hinzu, aber das hängt wirklich davon ab. Meine grundlegende Richtlinie lautet: Wenn der generierte Code ein wesentlicher Bestandteil des Compilers ist, werde ich ihn nicht hinzufügen. Wenn der generierte Code von einem externen Tool stammt, wie in diesem Fall SubSonic, würde ich if zur Quellcodeverwaltung hinzufügen. Wenn Sie die Komponente regelmäßig aktualisieren, möchte ich die Änderungen in der generierten Quelle wissen, falls Fehler oder Probleme auftreten.

In Bezug auf den generierten Code, der eingecheckt werden muss, besteht ein Worst-Case-Szenario darin, die Dateien manuell zu differenzieren und die Dateien bei Bedarf zurückzusetzen. Wenn Sie svn verwenden, können Sie in svn einen Pre-Commit-Hook hinzufügen, um ein Commit zu verweigern, wenn sich die Datei nicht wirklich geändert hat.


3

Die Aufgabe des Konfigurationsmanagements (von dem die Versionskontrolle nur ein Teil ist) besteht darin, Folgendes zu tun:

  • Wissen, welche Änderungen und Fehlerbehebungen in jedem gelieferten Build vorgenommen wurden.
  • Sie können genau jeden gelieferten Build reproduzieren, beginnend mit dem ursprünglichen Quellcode. Automatisch generierter Code zählt unabhängig von der Sprache nicht als "Quellcode".

Die erste stellt sicher, dass, wenn Sie dem Client oder Endbenutzer mitteilen, dass "der Fehler, den Sie letzte Woche gemeldet haben, behoben ist und die neue Funktion hinzugefügt wurde", diese zwei Stunden später nicht zurückkommen und "Nein, hat es nicht" sagen. Es stellt auch sicher, dass sie nicht sagen "Warum macht es X? Wir haben nie nach X gefragt".

Der zweite bedeutet, dass Sie, wenn der Client oder Endbenutzer einen Fehler in einer Version meldet, die Sie vor einem Jahr herausgegeben haben, zu dieser Version zurückkehren, den Fehler reproduzieren, beheben und beweisen können, dass Ihr Fehler den Fehler behoben hat, anstatt ihn zu beseitigen Einige Störungen des Compilers und andere Korrekturen.

Dies bedeutet, dass Ihr Compiler, Ihre Bibliotheken usw. ebenfalls Teil von CM sein müssen.

Um Ihre Frage zu beantworten: Wenn Sie alle oben genannten Aufgaben ausführen können, müssen Sie keine Zwischendarstellungen aufzeichnen, da Sie garantiert trotzdem die gleiche Antwort erhalten. Wenn Sie nicht alle oben genannten Punkte ausführen können, sind alle Wetten ungültig, da Sie niemals garantieren können, dass Sie zweimal dasselbe tun und dieselbe Antwort erhalten. Sie können also auch alle Ihre .o-Dateien unter Versionskontrolle stellen.


2

Es kommt wirklich darauf an. Letztendlich ist es das Ziel, das, was Sie hatten, bei Bedarf reproduzieren zu können. Wenn Sie Ihre Binärdateien genau neu generieren können, müssen Sie sie nicht speichern. Sie müssen sich jedoch daran erinnern, dass Sie zum erneuten Erstellen Ihrer Inhalte wahrscheinlich Ihre genaue Konfiguration benötigen, mit der Sie sie ursprünglich erstellt haben. Dies bedeutet nicht nur Ihren Quellcode, sondern auch Ihre Build-Umgebung, Ihre IDE und möglicherweise sogar andere Bibliotheken , Generatoren oder ähnliches, in der genauen Konfiguration (Versionen), die Sie verwendet haben.

Ich bin in Projekten auf Probleme gestoßen, bei denen wir unsere Build-Umgebung auf neuere Versionen oder sogar auf Versionen anderer Anbieter aktualisiert haben, bei denen wir nicht in der Lage waren, die genauen Binärdateien wiederherzustellen, die wir zuvor hatten. Dies ist ein echtes Problem, wenn die zu verwendenden Binärdateien von einer Art Hash abhängen, insbesondere in einer gesicherten Umgebung, und die neu erstellten Dateien sich aufgrund von Compiler-Upgrades oder was auch immer unterscheiden.

Würden Sie generierten Code speichern? Ich würde nein sagen. Die freigegebenen Binärdateien oder Ergebnisse, einschließlich der Tools, mit denen Sie sie reproduziert haben, würde ich speichern. Und dann müssen sie nicht in der Quellcodeverwaltung gespeichert werden. Erstellen Sie einfach eine gute Sicherung dieser Dateien.


"Das bedeutet nicht nur Ihren Quellcode, sondern auch Ihre Build-Umgebung, Ihre IDE, vielleicht sogar andere Bibliotheken, Generatoren oder ähnliches." \ n Das ist alles, was ich einchecken würde. Wenn Sie Ihren Compiler aus dem Quellcode auf jedem Entwicklercomputer als Teil erstellen Überprüfen Sie die Quelle des gleichen Builds wie Ihre Apps (dh Sie geben einmal 'make' ein). Wenn nicht, dann checken Sie in den Binärdateien ein
KeyserSoze

2

Die richtige Antwort lautet "Es kommt darauf an". Es hängt von den Bedürfnissen des Kunden ab. Wenn Sie Code auf eine bestimmte Version zurücksetzen und ohne diese externen Audits standhalten können, sind Sie immer noch nicht auf festem Boden. Als Entwickler müssen wir nicht nur "Rauschen", Schmerzen und Speicherplatz berücksichtigen, sondern auch die Tatsache, dass wir die Aufgabe haben, geistiges Eigentum zu generieren, und dass es rechtliche Konsequenzen geben kann. Könnten Sie einem Richter beweisen, dass Sie eine Website genau so regenerieren können, wie es ein Kunde vor zwei Jahren gesehen hat?

Ich schlage nicht vor, dass Sie gen'd-Dateien speichern oder nicht speichern, unabhängig davon, wie Sie entscheiden, ob Sie die Fachexperten nicht in die Entscheidung einbeziehen, bei der Sie wahrscheinlich falsch liegen.

Meine zwei Cent.


Sie machen einen interessanten Punkt und nehmen die Abstimmung nicht persönlich. Es ist nur so, dass dies aus praktischen Gründen in oft schnelllebigen Entwicklungsumgebungen einfach nicht praktikabel ist. Warum sollte automatisch generierter Code auf jeden Fall Daten enthalten, die sich auf Inhalt oder IP beziehen? Ich würde vorschlagen, dass Clients im Allgemeinen nicht in der Lage sind, die Auswirkungen von automatisch generiertem Code zur Quellcodeverwaltung zu erfassen, und dass diese Option wahrscheinlich im Allgemeinen nicht angeboten werden sollte. IMHO ist es zu viel Aufwand und Kosten, um sich um eine hypothetische und unwahrscheinliche rechtliche Situation zu kümmern.
Chris Halcrow

In der Domäne, in der ich mich gerade befinde, hält die Versicherung unseres (sehr großen) Kunden ALLES für mindestens 10 Jahre. Wir entwickeln ausgefeilte Tools, um WCF-Dienste zu generieren. Kunden behalten den generierten Code, die Vorlagen und das Ganze. Aber das ist mein Klient. Vermutlich haben Sie den Punkt verpasst, den ich gemacht habe: "Es hängt von den Bedürfnissen des Kunden ab" und "wie auch immer Sie entscheiden, ob Sie die Fachexperten nicht in die Entscheidung einbeziehen, bei der Sie wahrscheinlich falsch liegen." Wenn das irgendwie eine schlechte Antwort ist oder Sie sich besser fühlen, wenn Sie eine -1 geben, sind Sie froh, geholfen zu haben. Siehe 'womp' im Kommentar über meiner Antwort.
James Fleming

2

Es gibt gute Argumente für und gegen hier. Für die Aufzeichnung baue ich das T4-Generierungssystem in Visual Studio und unsere standardmäßige Standardoption bewirkt, dass generierter Code eingecheckt wird. Sie müssen etwas härter arbeiten, wenn Sie nicht einchecken möchten.

Für mich ist es wichtig, die generierte Ausgabe zu unterscheiden, wenn entweder die Eingabe oder der Generator selbst aktualisiert wird.

Wenn Sie Ihre Ausgabe nicht eingecheckt haben, müssen Sie eine Kopie des gesamten generierten Codes erstellen, bevor Sie einen Generator aktualisieren oder die Eingabe ändern, um diese mit der Ausgabe der neuen Version vergleichen zu können. Ich denke, dies ist ein ziemlich langwieriger Prozess, aber bei eingecheckten Ausgaben ist es einfach, die neue Ausgabe vom Repository zu unterscheiden.

An dieser Stelle ist es vernünftig zu fragen: "Warum interessieren Sie sich für Änderungen im generierten Code?" (Insbesondere im Vergleich zum Objektcode.) Ich glaube, es gibt einige Hauptgründe, die eher auf den aktuellen Stand der Technik als auf ein inhärentes Problem zurückzuführen sind.

  1. Sie erstellen handgeschriebenen Code, der eng mit dem generierten Code verknüpft ist. Dies ist heutzutage bei obj-Dateien im Großen und Ganzen nicht der Fall. Wenn sich der generierte Code ändert, muss leider häufig handgeschriebener Code geändert werden, damit er übereinstimmt. Leute beobachten oft kein hohes Maß an Abwärtskompatibilität mit Erweiterungspunkten im generierten Code.

  2. Generierter Code ändert einfach sein Verhalten. Sie würden dies von einem Compiler nicht tolerieren, aber fairerweise zielt ein Codegenerator auf Anwendungsebene auf ein anderes Problembereich mit einer größeren Auswahl akzeptabler Lösungen ab. Es ist wichtig zu sehen, ob Annahmen, die Sie über das vorherige Verhalten getroffen haben, jetzt gebrochen sind.

  3. Sie vertrauen der Ausgabe Ihres Generators von Release zu Release einfach nicht zu 100%. Generator-Tools bieten viel Wert, auch wenn sie nicht mit der Genauigkeit Ihres Compiler-Anbieters erstellt und gewartet werden. Release 1.0 war für Ihre Anwendung möglicherweise perfekt stabil, aber 1.1 hat jetzt einige Probleme für Ihren Anwendungsfall. Alternativ ändern Sie die Eingabewerte und stellen fest, dass Sie ein neues Stück des Generators trainieren, das Sie zuvor noch nicht verwendet haben - möglicherweise werden Sie von den Ergebnissen überrascht.

Im Wesentlichen kommt es bei all diesen Dingen auf die Tool-Reife an - die meisten Code-Generatoren für Geschäftsanwendungen liegen nicht in der Nähe des Niveaus, das Compiler oder sogar Tools auf Lex / Yacc-Ebene seit Jahren haben.


2

Beide Seiten haben gültige und vernünftige Argumente, und es ist schwierig, sich auf etwas Gemeinsames zu einigen. Versionskontrollsysteme (VCS) verfolgen die Dateien, die Entwickler darin abgelegt haben, und gehen davon aus, dass die Dateien in VCS von Entwicklern von Hand erstellt wurden und Entwickler an der Historie und dem Wechsel zwischen jeder Überarbeitung der Dateien interessiert sind. Diese Annahme gleicht die beiden Konzepte aus: "Ich möchte diese Datei beim Auschecken erhalten." und "Ich bin an der Änderung dieser Datei interessiert."

Nun könnten die Argumente von beiden Seiten folgendermaßen umformuliert werden:

  • "Ich möchte alle diese generierten Dateien beim Auschecken abrufen, da ich nicht das Tool habe, um sie auf diesem Computer zu generieren."
  • "Ich sollte sie nicht in VCS einfügen, da ich nicht an der Änderung dieser Datei interessiert bin."

Glücklicherweise scheinen sich die beiden Anforderungen nicht grundlegend zu widersprechen. Mit einer gewissen Erweiterung der aktuellen VCS sollte es möglich sein, beides zu haben. Mit anderen Worten, es ist ein falsches Dilemma. Wenn wir eine Weile darüber nachdenken, ist es nicht schwer zu erkennen, dass das Problem auf der Annahme beruht, dass VCSs gelten. VCSs sollten die von Entwicklern handgefertigten Dateien von Dateien unterscheiden, die nicht von Entwicklern handgefertigt wurden, sondern sich zufällig in diesem VCS befinden. Für die erste Kategorie von Dateien, die wir normalerweise als Quelldateien (Code) bezeichnen, haben VCSs jetzt hervorragende Arbeit geleistet. Für die letztere Kategorie hatten VCS meines Wissens noch kein solches Konzept.

Zusammenfassung

Ich werde Git als ein Beispiel nehmen, um zu veranschaulichen, was ich meine.

  • git status sollte standardmäßig keine generierten Dateien anzeigen.
  • git commit sollte generierte Dateien als Schnappschuss enthalten.
  • git diff sollte standardmäßig keine generierten Dateien anzeigen.

PS

Git-Hooks könnten als Problemumgehung verwendet werden, aber es wäre großartig, wenn Git dies nativ unterstützt. gitignoreentspricht nicht unseren Anforderungen, da ignorierte Dateien nicht in VCSs gespeichert werden.enter code here


1

Ich würde dafür argumentieren. Wenn Sie einen kontinuierlichen Integrationsprozess verwenden, der den Code auscheckt, die Build-Nummer ändert, die Software erstellt und dann testet, ist es einfacher und einfacher, diesen Code nur als Teil Ihres Repositorys zu haben.

Darüber hinaus ist es Bestandteil jedes "Schnappschusses", den Sie von Ihrem Software-Repository erstellen. Wenn es Teil der Software ist, sollte es Teil des Repositorys sein.


5
Ich liebe die Fahrt von -1. Wenn Sie nicht einverstanden sind, stimmen Sie nicht ab - stimmen Sie die anderen Antworten ab. Speichern Sie die Downvotes für eine falsche Antwort. Dies ist eine subjektive Frage.
Womp

1

Ich würde sagen, dass Sie es ja unter Quellcodeverwaltung stellen möchten. Vom Standpunkt des Konfigurationsmanagements aus muss ALLES, was zur Erstellung eines Software-Builds verwendet wird, gesteuert werden, damit es neu erstellt werden kann. Ich verstehe, dass generierter Code leicht neu erstellt werden kann, aber es kann argumentiert werden, dass er nicht gleich ist, da die Datums- / Zeitstempel zwischen den beiden Builds unterschiedlich sind. In einigen Bereichen wie der Regierung ist häufig erforderlich, dass dies getan wird.


2
Checken Sie Ihre Objektdateien (.o) ein?
KeyserSoze

1

Im Allgemeinen muss der generierte Code nicht in der Quellcodeverwaltung gespeichert werden, da der Revisionsverlauf dieses Codes anhand des Revisionsverlaufs des Codes verfolgt werden kann, der ihn generiert hat!

Es scheint jedoch, dass das OP den generierten Code als Datenzugriffsschicht der Anwendung verwendet, anstatt manuell einen zu schreiben. In diesem Fall würde ich den Erstellungsprozess ändern und den Code der Quellcodeverwaltung übergeben, da er eine kritische Komponente des Laufzeitcodes ist. Dadurch wird auch die Abhängigkeit vom Tool zur Codegenerierung aus dem Erstellungsprozess entfernt, falls die Entwickler unterschiedliche Versionen des Tools für unterschiedliche Zweige verwenden müssen.

Es scheint, dass der Code anstelle jedes Builds nur einmal generiert werden muss. Wenn ein Entwickler die Art und Weise, wie ein Objekt auf die Datenbank zugreift, hinzufügen / entfernen / ändern muss, sollte der Code erneut generiert werden, genau wie manuelle Änderungen. Dies beschleunigt den Erstellungsprozess, ermöglicht manuelle Optimierungen an der Datenzugriffsschicht und der Verlauf der Datenzugriffsschicht wird auf einfache Weise beibehalten.


Ich bin nicht einverstanden. Wenn Sie es zu einem manuellen Vorgang machen, wird es kaputt gehen und niemand wird es bemerken, bis es Zeit ist, es erneut auszuführen. Wenn es jeden Tag auf Ihren Build-Servern generiert wird (und auf jedem Entwickler-Computer, wenn ein "sauberer" Build ausgeführt wird), werden Sie nicht überrascht sein.
KeyserSoze

Wenn der Code der Datenzugriffsschicht in die Quellcodeverwaltung eingecheckt wird, sollte es keine Überraschungen geben, da die Benutzer gezwungen sind, den Code zu aktualisieren. Wenn jemand die Version des Codegenerierungstools auf dem Buildcomputer ändert und die Entwickler alte Versionen auf ihrem Entwicklungscomputer haben (möglicherweise ein anderer Codezweig), treten Kopfschmerzen auf. Ich schlage vor, dass er den Codegenerierungsschritt aus dem Erstellungsprozess entfernt, da sie nicht die Betreuer des Codegenerators sind.
Benson

1

Ich werde (bedauerlicherweise) viele abgeleitete Quellen unter Quellcodeverwaltung stellen, weil ich remote mit Leuten zusammenarbeite, die entweder nicht die Mühe haben, eine ordnungsgemäße Build-Umgebung einzurichten, oder die nicht über die Fähigkeiten verfügen, sie so einzurichten, dass die abgeleitete Quellen sind genau richtig aufgebaut. (Und wenn es um Gnu-Autotools geht, bin ich selbst einer dieser Leute! Ich kann nicht mit drei verschiedenen Systemen arbeiten, von denen jedes mit einer anderen Version von Autotools funktioniert - und nur mit dieser Version.)

Diese Art von Schwierigkeit betrifft wahrscheinlich eher Teilzeit-Open-Source-Projekte als freiwillige Projekte, bei denen die Person, die die Rechnungen bezahlt, auf einer einheitlichen Bauumgebung bestehen kann.

Wenn Sie dies tun, verpflichten Sie sich grundsätzlich, die abgeleiteten Dateien nur an einem Standort oder nur an ordnungsgemäß konfigurierten Standorten zu erstellen. Ihre Makefiles (oder was auch immer) sollten so eingerichtet sein, dass sie feststellen, wo sie ausgeführt werden, und sich weigern, Quellen erneut abzuleiten, es sei denn, sie wissen, dass sie an einem sicheren Build-Standort ausgeführt werden.


1

Wenn es Teil des Quellcodes ist, sollte es in die Quellcodeverwaltung gestellt werden, unabhängig davon, wer oder was es generiert. Sie möchten, dass Ihre Quellcodeverwaltung den aktuellen Status Ihres Systems widerspiegelt, ohne ihn neu generieren zu müssen.


"ohne es regenerieren zu müssen." Sie checken also kompilierte Binärdateien ein? Checken Sie auch eine Version der Zielplattform ein? Diese Strategie lässt sich nicht gut skalieren. :(
dss539

1
Und das bringt mir eine Abwertung? Natürlich checken Sie kompilierte Binärdateien nicht ein (es sei denn, sie stammen aus Bibliotheken von Drittanbietern), da sie aus Ihrem Quellcode neu generiert werden können. Ich sprach davon, den generierten Code neu generieren zu müssen, nicht die Binärdateien. Aber hey, wenn du falsch interpretieren willst, was ich sage, dann mach weiter ...
Mezoid

Diese Antwort war keine Ablehnung wert! Zumindest scheint es vernünftig, generierten Code in SC zu platzieren (möglicherweise an einer eindeutig identifizierten Stelle), damit Sie zumindest den Hash des Codes, der zum Generieren des Objekts verwendet wird, mit dem neuen Code vergleichen können, den Sie verwenden möchten für einen neuen Build generieren. Interessant, wie polarisierend diese Frage ist.
rp.

1

Haben Sie den generierten Code aus vielen Gründen unbedingt in der Quellcodeverwaltung. Ich wiederhole, was viele Leute bereits gesagt haben, aber einige Gründe, warum ich es tun würde, sind

  1. Mit Codedateien in der Quellcodeverwaltung können Sie den Code möglicherweise kompilieren, ohne Ihren Visual Studio-Vorerstellungsschritt zu verwenden.
  2. Wenn Sie einen vollständigen Vergleich zwischen zwei Versionen durchführen, wäre es schön zu wissen, ob sich der generierte Code zwischen diesen beiden Tags geändert hat, ohne ihn manuell überprüfen zu müssen.
  3. Wenn sich der Codegenerator selbst ändert, sollten Sie sicherstellen, dass sich die Änderungen am generierten Code entsprechend ändern. Wenn sich Ihr Generator ändert, sich die Ausgabe jedoch nicht ändern soll, gibt es beim Festschreiben Ihres Codes keine Unterschiede zwischen dem, was zuvor generiert wurde, und dem, was jetzt im generierten Code enthalten ist.

1
Und Ihr Codegenerator selbst ist nicht in der Quellcodeverwaltung, weil ...?
Jeffrey Hantin

@ Jeffrey: Ich habe nie gesagt, dass der Codegenerator nicht in der Quellcodeverwaltung ist.
Joe Enos

Ich weiß, ich necke nur. :-) Ich habe festgestellt, dass viele CodeDom-basierte Codegeneratoren ihre Ausgabe jedoch gerne in zufälliger Reihenfolge produzieren, um die Wiederholbarkeit (und damit die Fähigkeit, leicht zu erkennen, ob sich der generierte Code von Lauf zu Lauf ändert) zu gewährleisten. Ich habe eine Routine geschrieben, die den Inhalt von a CodeCompileUnitin eine kanonische Reihenfolge sortiert.
Jeffrey Hantin

0

Ich würde generierte Dateien aus einem Quellbaum herauslassen, sie aber in einem separaten Build-Baum ablegen.

zB Workflow ist

  1. Quelle normal ein- / auschecken / ändern / zusammenführen (ohne generierte Dateien)
  2. Überprüfen Sie bei geeigneten Gelegenheiten den Quellbaum in einen sauberen Build-Baum
  3. Checken Sie nach einem Build alle "wichtigen" Dateien ("echte" Quelldateien, ausführbare Dateien + generierte Quelldatei) ein, die für Prüfungs- / Regulierungszwecke vorhanden sein müssen. Auf diese Weise erhalten Sie einen Verlauf aller geeigneten generierten Codes + ausführbaren Dateien + was auch immer, zu Zeitschritten, die sich auf Releases / Test-Snapshots usw. beziehen und von der täglichen Entwicklung entkoppelt sind.

In Subversion / Mercurial / Git / etc gibt es wahrscheinlich gute Möglichkeiten, den Verlauf der realen Quelldateien an beiden Stellen miteinander zu verknüpfen.


0

Anscheinend gibt es auf beiden Seiten sehr starke und überzeugende Meinungen. Ich würde empfehlen, alle Antworten mit den höchsten Stimmen zu lesen und dann zu entscheiden, welche Argumente für Ihren speziellen Fall gelten.

UPDATE: Ich habe diese Frage gestellt, da ich wirklich geglaubt habe, dass es eine endgültige Antwort gibt. Wenn ich mir alle Antworten anschaue, kann ich mit hoher Sicherheit sagen, dass es keine solche Antwort gibt. Die Entscheidung sollte auf der Grundlage von mehr als einem Parameter getroffen werden. Das Lesen der anderen Antworten könnte eine sehr gute Richtlinie für die Arten von Fragen sein, die Sie sich stellen sollten, wenn Sie sich für dieses Problem entscheiden müssen.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.