Frage

Subversion können Sie Arbeitskopien von anderen Repositories einbetten mit Externen ermöglicht Ihnen eine einfache Versionskontrolle von Drittanbieter-Software-Bibliothek in Ihrem Projekt.

Während diese scheinen ideal für die Wiederverwendung von Bibliotheken und Versionskontrolle von händlerspezifische Software , sind sie nicht ohne ihre Kritiker :

  

Bitte verwenden Sie keine Subversion Äußerlichkeiten (oder ähnlich in anderen Werkzeugen), sie sind ein Anti-Muster und daher nicht nötig

Gibt es versteckte Risiken in Äußerlichkeiten mit? Bitte erklären, warum sie würden sie ein Antipattern in Betracht gezogen werden.

War es hilfreich?

Lösung

Ich bin der Autor des Zitats in der Frage, die von einem vorherige Antwort .

Jason hat recht suspekt kurze Aussagen wie meine zu sein, und um eine Erklärung zu bitten. Natürlich, wenn ich voll und ganz alles in dieser Antwort erklärt, ich müsste ein Buch geschrieben haben.

Mike ist auch zu Recht darauf hin, dass eines der Probleme, mit einem svn:external artigen Merkmale ist, dass Änderungen in der Zielquelle Ihre eigene Quelle brechen könnten, vor allem, wenn die gezielte Quelle in einem Repository ist, dass Sie nicht besitzen.

In weiteren meinen Kommentar erklären, lassen Sie mich zunächst sagen, dass es „sicher“ Möglichkeiten, die svn:external ähnliche Funktion nutzen zu können, so wie bei jedem anderen Werkzeug oder Funktion. Aber ich bezeichnen es als ein Antipattern , da die Funktion viel wahrscheinlicher werden missbraucht wird. Nach meiner Erfahrung ist es immer missbraucht wurde, und ich finde mich sehr unwahrscheinlich auch immer es in dieser sicheren Art und Weise zu verwenden, noch jemals, dass die Verwendung zu empfehlen. Bitte weiter zur Kenntnis, dass ich keine Verunglimpfung zum Subversion-Team bedeuten - Ich liebe Subversion, obwohl ich zu Bazaar bewegen plane

.

Das primäre Problem mit dieser Funktion ist, dass sie ermutigt und es wird in der Regel verwendet, um direkt die Quelle von einem Build zu verknüpfen ( „Projekt“) mit der Quelle eines anderen, oder das Projekt in einem binären (DLL, JAR zu verknüpfen, etc.) von denen es abhängt. Keines dieser Anwendungen ist klug, und sie bilden eine Antipattern.

Wie ich in meiner anderen Antwort sagte, glaube ich, dass ein wesentlicher Grundsatz für Software-Builds ist, dass jedes Projekt baut genau ein binäres oder primäre lieferbar. Dies kann eine Anwendung des Grundsatzes der Trennung von Bedenken in Betracht gezogen werden. Dies gilt insbesondere in Bezug auf ein Projekt direkt die Quelle eines anderen verweisen, die auch eine Verletzung des Grundsatzes der Kapselung . Eine weitere Form dieser Art von Verletzung versucht, eine Build-Hierarchie erstellen durch rekursives Aufrufen von Unter baut ein gesamtes System oder Untersystem zu konstruieren. Maven stark ermutigt / dieses Verhalten erzwingt, die einer der vielen Gründe ist, dass ich es nicht empfehlen.

Schließlich finde ich, dass es verschiedene praktische Fragen, die diese Funktion unerwünscht machen. Zum einen hat svn:external einige interessante Verhaltensmerkmale (aber die Details entgeht mir im Moment). Zum anderen finde ich immer, dass ich solche Abhängigkeiten müssen mein Projekt explizit sichtbar sein (Build-Prozess), nicht als eine Quelle Steuer Metadaten begraben.

Also, was ist eine „sichere“ Art und Weise dieser Funktion zu verwenden? Ich würde das sein, wenn es nur von einer Person, die vorübergehend verwendet wird, wie zum Beispiel eine Art und Weise zu „konfiguriert“ eine Arbeitsumgebung. Ich konnte sehen, wo ein Programmierer könnte ihre eigenen Ordner im Repository erstellen (oder einem für jeden Programmierer), wo sie svn:external Links zu den verschiedenen anderen Teilen des Repository konfigurieren würden, dass sie gerade arbeiten. Dann wird eine Kasse des einen Ordner, der eine Arbeitskopie aller ihrer aktuellen Projekte erstellen. Wenn ein Projekt hinzugefügt wird oder beendet ist, könnten die svn:external Definitionen angepasst werden und die Arbeitskopie entsprechend aktualisiert. Allerdings ziehe ich einen Ansatz, der nicht auf eine bestimmte Quellkontrollsystem gebunden ist, wie dies mit einem Skript, das die Kassen aufruft.

Für die Aufzeichnung meines letzter Kontakt zu diesem Problem trat im Sommer 2008 im Rahmen eines Consulting-Client, den svn:external in großem Maßstab unter Verwendung wurde - alles war vernetzt eine einzigen Master-Arbeitskopie zu erzeugen. ihre Ant& Jython-Basis (für WebLogic) Build-Skripte wurden im oberen Teil der Hauptarbeitskopie gebaut. Das Nettoergebnis: NICHTS könnte eigenständigen gebaut, es buchstäblich Dutzende von Teilprojekte waren, aber nicht war sicher Kasse / von selbst auf arbeiten. Deshalb auf diesem System keine Arbeit erforderlich zunächst eine Kasse / Update von mehr als 2 GB-Dateien (sie Binärdateien in dem Repository stellen auch). Erstes alles getan war eine Übung in Sinnlosigkeit, und ich verließ nach drei Monaten lang versuchen (es viele andere Antipatterns auch anwesend waren).

EDIT: erkläret auf rekursive baut -

Im Laufe der Jahre (vor allem im letzten Jahrzehnt), habe ich massiv Systeme für Fortune 500-Unternehmen und großen Behörden die viele Dutzende von Teilprojekten in Verzeichnishierarchien angeordnet gebaut, die viele Ebenen tief sind. Ich habe Microsoft Visual Studio-Projekte / Lösungen verwendet, um .NET-basierten Systeme, Ant oder Maven 2 für Java-basierte Systeme zu organisieren, und ich habe mit distutils und Setuptool (Easy) für Python-basierter Systeme begonnen. Diese Systeme haben auch große Datenbanken in der Regel in Oracle oder Microsoft SQL Server enthalten.

Ich habe großen Erfolg diese massiven baut für einfache Handhabung und Wiederholbarkeit der Gestaltung hat. Mein Design Standard ist, dass ein neuer Entwickler an ihrem ersten Tag zeigen kann, eine neue Workstation (vielleicht gerade von Dell mit nur ein typischen Installation des Betriebssystem) gegeben werden, ein einfaches Setup-Dokument (in der Regel nur eine Seite der Montageanleitung) gegeben werden, und in der Lage sein, den Arbeitsplatz zu voll Setup und bauen das gesamte System von der Quelle, ohne Aufsicht, ohne fremde Hilfe, und in einem halben Tag oder weniger. Aufrufen der build selbst eine Befehls-Shell schließt Öffnen, Ändern in das Stammverzeichnis des Quellbaums und Ausgeben einer einzeiligen Befehl ALLES aufzubauen.

Trotz dieses Erfolg System, wie ein massives Build Konstruktion erfordert große Sorgfalt und Haftung auf solide Design-Prinzipien, wie bei einem massiven geschäftskritische Anwendung / System zu konstruieren. Ich habe festgestellt, dass ein wesentlicher Teil ist, dass jedes Projekt (die ein einzelnes Artefakt / lieferbaren produziert) muss ein einzelnes Build-Skript haben, die eine gut definierte Schnittstelle (für Befehle aufruft Abschnitte des Erstellungsprozesses) haben muss, und es muss stehen allein von allen anderen (Teil-) Projekten. Historisch gesehen, ist es leicht, das ganze System zu bauen, aber schwer / unmöglich nur ein Stück zu bauen. Erst vor kurzem habe ich gelernt, sorgfältig, um sicherzustellen, dass jedes Projekt wirklich allein steht.

In der Praxis bedeutet dies, dass es mindestens zwei Schichten von Build-Skripte sein muß. Die unterste Schicht ist das Projekt Build-Skripte, die jeden lieferbar / Artefakt erzeugen. Jedes solches Skript befindet sich im Stammverzeichnis der Projektquellbaum (in der Tat, dieses Skript sein Projekt Quellbaum DEFINIERT), diese Skripte wissen nichts über die Quellcodeverwaltung, erwarten sie von der Kommandozeile ausgeführt werden soll, verweisen sie alles im Projekt relativ (keine andere Source-Projekte Werkzeuge oder binäre Artefakte) auf den Build-Skript, und sie verweisen auf ihre externen Abhängigkeiten basierend auf einigen konfigurierbaren Einstellungen (Umgebungsvariablen, Konfigurationsdateien, usw.).

Die zweite Schicht von Build-Skripte sollte auch von der Kommandozeile aufgerufen werden, aber diese wissen über die Quellcodeverwaltung. Tatsächlich ist diese zweite Schicht ist oft ein einziges Skript, das mit einem Projektnamen aufgerufen wird, und eine Version, dann überprüft er die Quelle aus für das genannte Projekt in ein neuen temporären Verzeichnis (vielleicht auf der Kommandozeile angegeben) und ruft seinen Build-Skript.

Es müssen möglicherweise mehr Variation sein Continuous Integration Server, mehrere Plattformen gerecht zu werden, und verschiedene Freisetzungsszenarien.

Manchmal gibt es einen Bedarf für eine dritte Schicht von Skripten, die die zweite Schicht von Skripten ruft zum Zwecke der Aufbau spezifischer Untergruppen des Gesamtprojektes Satz (die die erste Schicht aufrufen). Zum Beispiel kann jeder Entwickler ihre eigenen sc habenript dass baut die Projekte, die sie heute arbeiten. Es kann ein Skript sein, um alles, um beim Aufbau der Master-Dokumentation zu generieren, oder Metriken zu berechnen.

Egal, ich habe, dass das System als eine Hierarchie von Projekten versucht, gefunden zu behandeln kontraproduktiv ist. Es bindet die Projekte miteinander, so dass sie nicht frei allein gebaut werden können, oder in beliebigen Orten (temporäres Verzeichnis auf dem Continuous-Integration-Server) oder in beliebiger Reihenfolge (vorausgesetzt, Abhängigkeiten erfüllt sind). Oft eine Hierarchie zu erzwingen versucht, bricht jede IDE-Integration, dass man versuchen könnte.

Schließlich kann eine massive Hierarchie von Projekten den Aufbau einfach zu Leistung intensiv sein. Zum Beispiel im Frühjahr 2007 habe ich versucht, eine bescheidene Quellhierarchie (Java und Oracle), die ich mit Ant gebaut, die schließlich scheiterten, weil der Bau immer mit einem Java OutOfMemoryException abgebrochen. Dies war auf einem 2 GB RAM Workstation mit 3,5 GB Swap-Speicher, für die ich die JVM abgestimmt hatte der Lage sein, den gesamten verfügbaren Speicher zu verwenden. Die Anwendung / System war relativ trivial in Bezug auf die Menge an Code, aber die rekursive Build Anrufungen schließlich Speicher erschöpft, egal, wie viel Speicher ich es gab. Natürlich dauerte es auch immer als gut (30-60 Minuten üblich war, bevor er abgebrochen) auszuführen. Ich weiß, wie sehr gut zu stimmen, aber letztlich war ich mehr als nur die Grenzen der Werkzeuge (Java / Ant in diesem Fall).

Sie sich also einen Gefallen tun, bauen Ihren Build als eigenständige Projekte, dann in einem vollständigen System zusammenstellen. Halten Sie es leicht und flexibel. Genießen Sie.

EDIT: Mehr über Antipatterns

Genau genommen ist ein Antipattern eine gemeinsame Lösung, die aussieht wie es das Problem löst aber nicht der Fall, sei es, weil es große Lücken hinterlässt, oder weil es bringt zusätzliche Probleme (oft schlechter als das ursprüngliche Problem). Eine Lösung beinhaltet notwendigerweise ein oder mehr Werkzeuge sowie die Technik für sie, um das Problem bei der Hand Anwendung. Daher ist es eine Strecke zu einem Werkzeug oder einem bestimmten Merkmal eines Werkzeugs als Antipattern beziehen, und es scheint, dass die Menschen zu erfassen und zu dieser Strecke reagieren -. Fair genug

Auf der anderen Seite, da es scheint gängige Praxis in unserer Branche wird auf Werkzeuge zu konzentrieren, statt Technik ist es das Werkzeug / Feature, das die Aufmerksamkeit bekommt (eine lässige Befragung von Fragen hier auf Stackoverflow scheint leicht zu veranschaulichen) . Meine Kommentare, und diese Frage selbst, reflektieren diese Praxis.

Aber manchmal scheint es besonders gerechtfertigt, dass die Strecke zu machen, wie in diesem Fall. Einige Tools scheinen, um den Benutzer zu bestimmten Techniken „führen“, um sie für die Anwendung, bis zu dem Punkt, wo einige argumentieren, dass Tools Form dachte (leicht umformuliert). Es ist vor allem in diesem Sinne, dass ich vorschlagen, dass svn:external ein Antipattern ist.

Um genauer die Ausgabe erhält, ist die Antipattern eine Build-Lösung zu entwerfen, die Binde Projekte zusammen auf Quellebene enthält, oder implizit Version die Abhängigkeiten zwischen den Projekten, oder solche Abhängigkeiten zu ermöglichen implizit zu ändern, da jeder von ihnen ruft sehr negative Folgen. Die Art der svn:external artige Funktion macht diese negativen Folgen zu vermeiden sehr schwierig.

Richtig, die Abhängigkeiten zwischen den Projekten Umgang beinhaltet diese Dynamik zusammen mit dem Grundproblem Adressierung und die Werkzeuge und Techniken, um einen anderen Weg führen hinunter. Ein Beispiel, das in Betracht gezogen werden sollte, ist Ivy , die in einer ähnlichen Weise wie Maven hilft, aber ohne die vielen Schattenseiten. Suche ich Ivy, verbunden mit Ant, als meine kurzfristige Lösung für das Java-Build-Problem. Langfristig Ich suche die grundlegenden Konzepte und Funktionen in einem offenen einzuarbeitenSource-Tool, das eine Multiplattform-Lösung erleichtert.

Andere Tipps

Ich glaube nicht, das ist ein Anti-Muster überhaupt. Ich habe ein paar schnelle Suche auf Google und kam mit im Grunde nichts ... niemand beschwert sich, dass svn: externals schlecht oder schädlich ist. Natürlich gibt es einige Einschränkungen, die Sie von ... bewusst sein, und es ist nicht etwas, das man nur schwer in all Ihren Repositories streuen sollte ... aber wie für das ursprüngliche Zitat, das ist nur seine persönliche (und subjektive) Meinung . Äußerlichkeiten, außer sie als anti-Muster zu verurteilen: Er hat nie wirklich svn diskutiert. Solche pauschalen Aussagen ohne Unterstützung oder zumindest zu begründen, wie die Person kam die Aussage zu machen sind immer suspekt.

Das heißt, es gibt einige Probleme mit Äußerlichkeiten verwenden. Wie Mike beantwortet, können sie sehr hilfreich sein für den Hinweis auf stabile Zweige der freigegebenen Software ... vor allem Software, die Sie bereits steuern. Wir nutzen sie intern in einer Reihe von Projekten für Utility Bibliotheken und so weiter. Wir haben eine kleine Gruppe, die auf der Utility-Bibliothek Basis verbessert und funktioniert, aber das Basiscode wird in einer Reihe von Projekten gemeinsam genutzt. Wir wollen nicht nur verschiedene Teams in Dienstprogramm Projektcode überprüft und wir wollen nicht mit einer Million Zweige beschäftigen, so für uns svn: externals funktioniert sehr gut. Für manche Menschen können sie die Antwort nicht sein. Allerdings würde ich stark mit der Aussage nicht zustimmen „Bitte verwenden Sie nicht ...“ und dass diese Werkzeuge stellen ein anti-Muster.

Das Hauptrisiko bei der Verwendung von svn: externals ist, dass das referenzierte Repository in einer Weise verändert werden, dass Ihr Code bricht oder führt eine Sicherheitslücke. Wenn das externe Repository auch unter Ihrer Kontrolle ist, dann kann dies akzeptabel sein.

Ich persönlich nur svn: externals auf „stabil“ Zweige eines Endlagers zu verweisen, die ich besitze

.

Ein alter Thread, aber ich möchte die Sorge tragen, dass ein sich ändernder externer Code brechen könnte. Wie bereits erwähnt, ist dies meistens durch eine falsche Nutzung der externen Eigenschaft. Externe Verweise sollten in fast allen Fällen, zeigen Sie auf eine bestimmte Revisionsnummer im externen Repository-URI. Dadurch wird sichergestellt, dass die externe nie, wenn Sie es an eine andere Versionsnummer Punkt ändern ändern.

Für einige unserer internen Bibliotheken, die wir als Äußerlichkeiten verwenden in unserer Endanwender Projekte habe ich fand es nützlich, einen Tag der Bibliothek an major.minor Version zu erstellen, in denen wir keine Bruch Änderungen erzwingen. Mit einem Vier-Punkte-Versionsschema (Major.Minor.BugFix.Build), erlauben wir dem Tag mit BugFix.Build Änderungen Strom gehalten werden (auch hier keine Bruch Änderungen durchzusetzen). Dies erlaubt uns, ohne Revisionsnummer einen externen Verweis auf den Tag zu verwenden. Im Fall von großen oder anderen wichtigen Änderungen wird ein neuer Tag erstellt.

Äußerlichkeiten selbst ist nicht schlecht, aber das bedeutet nicht aufhören Menschen zu schaffen schlechte Implementierungen von ihnen. Es braucht nicht viel Forschung nehmen, nur ein wenig durch einige Dokumentation zu lesen, zu lernen, wie sie sicher und effektiv zu nutzen.

Wenn Ebene extern ist ein Anti-Muster, weil es das Repository brechen kann, dann eine explizite Revision should'nt.

Auszug aus svn Buch :

  

Eine externe Definition ist eine Abbildung eines lokalen Verzeichnisses in das URL ** - und möglicherweise eine bestimmte Revision - ** ein versionierten Ressource

.

Ich denke, es ist alles hängt Ihr Ziel, die Funktion zu verwenden, es ist nicht ein Anti-Muster von selbst aus.

Es gibt bestimmte Fehler in Subversion Äußerlichkeiten, aber wir scheinen sie zu nutzen maßen erfolgreich, einschließlich Bibliotheken (sowohl eigene und Lieferanten), dass das aktuelle Projekt abhängt. So sehe ich sie nicht als „Anti-Muster“. Die wichtige Nutzungs Punkte für mich sind:

  • Sie weisen auf eine bestimmte Revision oder Tag (nie den Kopf) des anderen Projektes.
  • Sie werden das aktuelle Projekt eingefügt in gut weg von seinem eigenen Quellcode usw. (zum Beispiel in einem Unterverzeichnis „Support-Dateien“ genannt).
  • Sie beziehen sich nur auf die anderen Projekte „Schnittstelle“ Dateien (zum Beispiel umfassen Ordner) und Binär-Bibliotheken (das heißt wir nicht die volle Quelle des anderen Projekt erhalten).

Es würde mich auch an irgendwelchen wesentlichen Risiken dieser Anordnung und bessere Ansätze.

Zu sagen, dass a b nicht machen a a b , wenn Sie sagen, Warum ist dies so.

Der Hauptfehler I mit externen Referenzen in Subversion zu sehen ist, dass Sie nicht garantiert sind, dass das Repository vorhanden ist, wenn Sie Ihre Arbeitskopie aktualisieren.

Subversion können externe Referenzen verwendet werden und missbraucht, und das Feature selbst ist nichts anderes als nur das, eine Funktion . Es kann nicht gesagt werden, daß ein Muster noch ein Antipattern .

Ich habe die Antwort von der Person lesen Sie zitieren, und ich muss sagen, dass ich nicht zustimmen. Wenn Ihr Projekt Version XYZ erfordert Dateien von einem Repository, eine externe Subversion Referenz kann man so leicht geben.

Ja, Sie können es falsch verwenden, indem Sie nicht ausdrücklich angeben, welche Version der Referenz Sie benötigen. Will, dass Sie Probleme geben? Wahrscheinlich!

Ist es ein Antipattern? Es hängt davon ab. Wenn Sie den Link vom Autor des Textes Sie zitieren, dh befolgen. hier , dann nicht. Das ist etwas, kann verwendet werden, um eine schlechte Lösung zu schaffen, macht nicht das gesamte Verfahren so zu tun, ein Antipattern . Wenn das der Regel war, dann würde ich, dass Programmiersprachen sagen Großen und Ganzen sind Antipatterns, weil in jeder Programmiersprache Sie können schlechte Lösungen machen .

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top