Verzweigungs- und Versionsstrategie für gemeinsam genutzte Bibliotheken


12

Diese Posts scheinen miteinander verwandt zu sein, aber mein Gehirn beginnt zu schmelzen und versucht, Folgendes zu überdenken: P

Mein Arbeitgeber hat gerade damit begonnen, die Quellcodeverwaltung zu verwenden, hauptsächlich, weil das "Repository" vor der Einstellung weiterer Entwickler die Festplatte des einzelnen Entwicklers war, der hauptsächlich von zu Hause aus arbeitet. Der gesamte von ihm geschriebene .NET-Code wurde massenhaft eingecheckt , und es gibt viele duplizierte (read: copy-paste) Funktionen. Im Moment ist unser SCM-System eine verherrlichte Sicherung.

Ich möchte einen Teil des duplizierten Codes in gemeinsam genutzte Bibliotheken ziehen. Ich lasse das ursprüngliche Repo in Ruhe, damit wir nichts kaputt machen - wir können vorhandenen Code nach Bedarf verschieben und / oder umgestalten. Deshalb habe ich ein Repo nur für neuen Code eingerichtet, einschließlich Bibliotheken.

Mein Problem besteht darin, die Bibliotheken zu versionieren, ohne uns in einen übermäßigen Prozess zu verstricken: Nachdem ich erkannt habe, dass wir einen kohärenteren Ansatz benötigen, bei dem mehr Entwickler alle sehr ähnlichen Code schreiben, ist das Management und die anderen Entwickler offen für Reorganisationen, aber das wird es wahrscheinlich nicht Gehen Sie gut runter, wenn die Lösung beginnt, die Produktivität zu beeinträchtigen.

Ich bin der Meinung, dass die beste Lösung darin besteht, die Bibliotheken separat zu erstellen, wobei jedes abhängige Projekt anhand von absichtlich ausgewählten, kompatiblen Versionen erstellt wird. Auf diese Weise wissen wir genau, welche Clients über welche Versionen von welchen Bibliotheken verfügen, können Fehler zuverlässiger reproduzieren, unabhängige Release-Zweige für Produkte und Bibliotheken pflegen und die Projekte des jeweils anderen nicht unterbrechen, wenn gemeinsam genutzter Code geändert wird.

Dies macht das Aktualisieren der Bibliotheken jedoch umständlich, insbesondere für Entwickler, die von zu Hause aus arbeiten. Ich erwarte, dass sich die Bibliotheken schnell ändern, zumindest anfangs, wenn wir (endlich) die gemeinsamen Bits zusammenziehen. Es ist durchaus möglich, dass ich das völlig überdenke und wir alles nur gegen die neuesten Bibliotheks-Commits bauen, aber ich möchte zumindest auf den Tag vorbereitet sein, an dem wir entscheiden, dass einige Komponenten unabhängig voneinander versioniert werden müssen und verteilt. Die Tatsache, dass einige der Bibliotheken im GAC installiert werden müssen, macht die Versionierung besonders wichtig.

Meine Frage lautet also: Was fehle ich? Ich habe das Gefühl, ich habe mich auf eine Lösung festgelegt und versuche nun, Variationen zu finden, die die Änderungen reibungsloser machen. Mit welchen Strategien haben Sie dieses Problem bisher gelöst? Mir ist klar, dass diese Frage allgegenwärtig ist. Ich werde mein Bestes tun, um alle Ungewissheiten zu beseitigen und zu klären.

Und so sehr ich Mercurial auch gerne nutzen würde, wir haben bereits Geld für ein zentrales kommerzielles SCM (Vault) ausgegeben, und das Wechseln ist keine Option. Außerdem denke ich, dass das Problem hier tiefer geht als die Wahl des Versionskontrolltools.


Fixkosten sind gesunken
Alternative

Antworten:


1

Ich empfehle Ihre Initiative. Dies sollte eine Reihe von Vorteilen für die Organisation mit sich bringen, wenn Sie dies implementieren. Ich würde den Code verschieben, anstatt ihn zu kopieren. Wenn Sie Kopien haben, führt dies wahrscheinlich zu inkompatiblen Änderungen, die behoben werden müssen.

Es wird einige Schmerzen geben, wenn die Bibliotheken entwickelt und stabilisiert werden. Sobald dies erledigt ist, werden die Vorteile eintreffen. Denken Sie daran, dass die Schnittstellen zur Bibliothek im Wesentlichen ein Vertrag mit den Projekten sind, die mit dem Vertrag arbeiten. Sie haben möglicherweise den Vorteil, alte Schnittstellen zu entfernen, da Sie möglicherweise feststellen können, ob sie verwendet werden.

Während sich die Bibliotheken stabilisieren, sollte das Abrufen neuer Bibliotheken wahrscheinlich Teil des Code-Aktualisierungsprozesses sein. Möglicherweise möchten Sie Commits für Bibliotheksänderungen planen. Das Ankündigen des zu verschiebenden Codes kann dazu beitragen, widersprüchliche Änderungen zu reduzieren.

Die Bibliotheken sollten als separate Projekte behandelt und so bald wie möglich stabilisiert werden. Sobald sie stabilisiert sind (insbesondere die Schnittstellen), sollte es einfacher sein, Änderungen in andere Projekte zu integrieren. Neue Bibliotheken sollten mit altem Code funktionieren. Versehen Sie stabile Bibliotheksreleases mit einer eigenen Release-ID. Behandeln Sie die Bibliotheken wie Bibliotheken von Drittanbietern.


6

Code, der von mehreren Projekten gemeinsam verwendet wird, muss als eigenständige Projekte behandelt werden. Sie müssen genauso gründlich behandelt werden wie Bibliotheken von Drittanbietern. Es gibt keinen anderen Weg.

Wenn Sie Ihre Gruppe nicht dazu bringen können, eine Strategie für gemeinsam genutzten Code zu verabschieden, können Sie diese mithilfe moderner Tools zur Quellcodeverwaltung wie Mercurial oder GIT selbst übernehmen, auch wenn das SCM von Ihrem Unternehmen nicht offiziell verwendet wird. Mit ein wenig Sorgfalt können zwei SCMs dasselbe Arbeitsverzeichnis verwenden, indem sie einem mitteilen, die internen Dateien des anderen zu ignorieren. Sie würden ein SCM verwenden, um den Alltag zu bewältigen, und das Unternehmen, um sich zu integrieren.

In jedem Fall müssen Sie dafür verantwortlich sein, wann Sie Ihr Arbeitsverzeichnis mit den Änderungen aktualisieren, die andere Projekte am gemeinsam genutzten Code vorgenommen haben. Diese sollten nur dann auftreten, wenn Sie bereit sind, mit den möglicherweise auftretenden Inkompatibilitäten umzugehen. Andernfalls wird Ihre Arbeit möglicherweise instabil und kann nicht mehr ausgeführt werden.


4

Wenn Sie die Möglichkeit haben, sie in separate "Modul" -Projekte aufzuteilen, würde ich diesen Ansatz verfolgen. Eine Sache, um die man sich Sorgen machen muss, ist die Codekopplung. Sie würden eine Trennung von Bedenken schaffen, indem Sie sie auflösen, was eine gute Praxis ist.

Einige Vorteile:

  1. Einfacheres Debuggen jedes Moduls.
  2. Schnellere Erstellungszyklen (keine Neuerstellung von Bibliotheken, die sich nicht geändert haben)
  3. Sobald etwas funktioniert, ist es weniger wahrscheinlich, dass Sie es brechen, indem Sie einen anderen Bereich außerhalb dieses Moduls ändern (nicht 100%, aber Sie verringern die Chancen).
  4. Einfachere Aufteilung von Arbeitsaufträgen, wenn es sich nicht um ein großes, voneinander abhängiges Durcheinander handelt.
  5. Schnellere Verteilung kleinerer Teile, wenn Sie eine Bibliothek reparieren (ein wichtiger Grund, warum Sie DLL- / SO-Dateien haben).

Ich habe eine Frage zu diesem Teil:

"Ich bin der Meinung, dass die beste Lösung darin besteht, die Bibliotheken separat zu erstellen, wobei jedes abhängige Projekt gegen absichtlich ausgewählte, kompatible Versionen von ihnen erstellt wird."

Verknüpfen Sie statisch das gesamte Projekt? Wenn ja, würde dies zu Folgendem führen: 6. Reduzierung von unnötigem Aufblähen von Code.

Einige Negative:

  1. Wenn es sich um ein kleines Projekt handelt, wird die Komplexität nur dort erhöht, wo sie nicht benötigt wird.
  2. Das Verzweigen vieler Module kann bei sehr großen Projekten zu einem Wartungsproblem werden. Ich kenne "Vault" nicht, daher bin ich mir nicht sicher, ob die Verzweigungsoperationen gut oder schlecht sind.

Es ist C # -Code, das ist also ein "Nein" zu statischen Verknüpfungen in der üblichen Bedeutung. Vault ist wie Subversion vor 1.5: PI wartete so eifrig auf das Merge-Tracking in svn und dachte, ich wäre im Himmel, als es endlich ankam. Dann habe ich DVCS gefunden.
Shambulator

1

Im Moment sieht es so aus, als ob Sie eine Codebasis auf einmal in ein Ziel eingebaut haben. Sie haben wahrscheinlich nicht mehr als fünf Entwickler. Ich sehe nicht wirklich den Nutzen, die Bibliotheken zu sehr zu trennen. Sie würden Ihren Workflow von Code -> Kompilieren -> Ausführen in Code -> Kompilieren -> DLL kopieren -> Kompilieren -> Ausführen ... ick ändern.

Einige Unternehmen (Google und Amazon) verfügen über eine ausreichende Infrastruktur für die Entwicklung, sodass es ziemlich einfach ist, viele separate Bibliotheken separat zu erstellen. Die Infrastruktur, mit der dies problemlos möglich ist, umfasst die Angabe von Bibliotheksversionen, die in Ihrem SCM vorhanden sind (was wahrscheinlich der Fall ist), die Angabe von Abhängigkeitsversionen, die in Ihrem SCM vorhanden sind, sowie einen Build-Server, der dies sinnvoll macht und alles ordnungsgemäß kompiliert und eine Möglichkeit, die entsprechenden Build-Artefakte von Ihrem Build-Server und Ihrem lokalen Arbeitsbereich abzurufen. Ich bezweifle, dass du das hast.

Ohne diese Infrastruktur würde ich das Projekt trennen, wenn eine der folgenden Bedingungen zutrifft:

  • Abhängig von dieser Bibliothek verfügen Sie über mehrere Produkte oder unterschiedliche Anwendungen
  • Sie arbeiten mehrere Tage lang ausschließlich an diesen Bibliotheken
  • Die Funktionalität der Bibliothek unterscheidet sich erheblich von geschäftlichen Aspekten (z. B. Wrapper für plattformspezifische APIs).
  • Die Bauzeiten für das kombinierte Projekt werden zu lang

Ich würde mir Sorgen machen, diese Infrastruktur aufzubauen, wenn Sie viele Projekte haben und einige engagierte Entwickler und unabhängige Release-Zyklen.

Sie können und sollten jetzt einen Build-Server für zuverlässige, wiederholbare Builds einrichten und sicherstellen, dass Sie die Quellversion einer bestimmten ausführbaren Datei finden. Sie scheinen .NET zu verwenden. Es ist ziemlich einfach, CruiseControl.NET so einzurichten, dass eine Versionszeichenfolge einschließlich der Revisionsnummer eingefügt wird.

Sobald Sie einen Build-Server haben, müssen Sie eine Bibliothek in Vault verschieben, ein weiteres Ziel in CC.NET hinzufügen und die resultierende DLL in den Bibliotheksordner Ihres Hauptprojekts kopieren und festschreiben. Einfacher auf der SCM-Seite als bei der täglichen Entwicklung.


1

Mercurial hat eine Funktion namens Subrepositories. Ich habe kürzlich diesen Blog von Kiln gelesen, in dem erklärt wird, wie sie funktionieren.

Grundsätzlich verknüpfen Sie Ihr Projekt mit einer bestimmten Revision eines Bibliotheksrepositorys. Sie können die Bibliothek so oft aktualisieren, wie Sie möchten, ohne die abhängigen Projekte zu unterbrechen. Wenn Sie bereit sind, können Sie die neuen Funktionen der Bibliothek in Ihr Projekt einbinden und eventuelle Beschädigungen beheben. Verschiedene Projekte können mit verschiedenen Versionen der Bibliothek verknüpft werden, sodass nicht alle synchronisiert sein und dieselbe Bibliotheksversion verwenden müssen.

Vielleicht hat Vault eine ähnliche Funktion.


1

Wir haben jedem Modul in SC eine Metadatendatei hinzugefügt, die den Namen aller anderen Module angibt, von denen es abhängt. Ein Produkt verfügt über eine zweite Metadatendatei, die angibt, welche Version jedes abhängigen Moduls für das Produkt erforderlich ist. Darüber hinaus gibt es ein Tool zum Analysieren der Metadatendateien, zum Auschecken aller erforderlichen Module und zum Generieren eines Projekts für unsere IDE.

Dies stellt sicher, dass unsere Builds immer reproduzierbar sind und dass die Komponenten immer die richtigen Header-Dateien gemeinsam nutzen. Je nach Bedarf kann eine andere Komplexität aufgeschichtet werden. Wir haben Tools, mit denen jetzt Berichte über die Unterschiede zwischen zwei beliebigen Builds eines Produkts erstellt werden können. Dabei werden geänderte Quelldateien, Check-in-Kommentare, Versionskommentare und Autoren für alle unabhängigen Module in SC angegeben. Wir erhalten eine phänomenale Menge Wiederverwendung von unserer Codebasis.

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.