Go: cmd/go: Unterstützung für Paketversionen zur Go-Toolchain hinzufügen

Erstellt am 7. März 2018  ·  242Kommentare  ·  Quelle: golang/go

Vorschlag: Unterstützung für Paketversionen zur Go-Toolchain hinzufügen

Es ist längst an der Zeit, Versionen zum Arbeitsvokabular sowohl der Go-Entwickler als auch unserer Tools hinzuzufügen.
Der verlinkte Vorschlag beschreibt einen Weg, dies zu tun. Siehe insbesondere den Abschnitt Begründung für eine Erörterung von Alternativen.

Diese GitHub-Ausgabe dient der Diskussion über den Inhalt des Vorschlags.

Weitere Referenzen:

Proposal Proposal-Accepted modules

Hilfreichster Kommentar

Dieser Vorschlag ist seit über zwei Monaten mit aktiven Diskussionen offen: @rsc & @spf13 haben Feedback-Sitzungen durchgeführt und wertvolle Beiträge aus der Community gesammelt, die zu Überarbeitungen des Vorschlags geführt haben. @rsc hat auch wöchentliche Treffen mit @sdboyer abgehalten, um weiteres Feedback zu erhalten. Es gab wertvolles Feedback zu dem Vorschlag, das zu weiteren Überarbeitungen geführt hat. Zunehmend bezieht sich dieses Feedback eher auf die begleitende Implementierung als auf den Vorschlag. Nach eingehender Prüfung sind wir der Meinung, dass es an der Zeit ist, diesen Vorschlag anzunehmen und das breite Ökosystem von Go-Tool-Implementierern damit beginnen zu lassen, kritische Anpassungen vorzunehmen, damit unsere Benutzerbasis die bestmögliche Erfahrung machen kann.

Es gab zwei Einwände gegen diesen Vorschlag, mit denen wir unserer Meinung nach sprechen sollten:

  1. Der Vorschlag wird von den Menschen verlangen, einige ihrer Praktiken in Bezug auf die Verwendung und Freigabe von Bibliotheken zu ändern.
  2. Der Vorschlag bietet keine technische Lösung für alle möglichen Szenarien, die mit Inkompatibilitäten einhergehen könnten.

Diese sind in ihrer Beobachtung genau, funktionieren aber wie beabsichtigt. Autoren und Benutzer von Code _werden_ einige ihrer Praktiken in Bezug auf die Verwendung und Veröffentlichung von Bibliotheken ändern müssen, so wie sich Entwickler an andere Details von Go angepasst haben, wie z. B. das Ausführen von gofmt. Die Umstellung von Best Practices ist manchmal die richtige Lösung. Ebenso muss vgo nicht alle möglichen Situationen mit Inkompatibilitäten behandeln. Wie Russ kürzlich in seinem Vortrag auf der Gophercon Singapore betonte , besteht die einzige dauerhafte Lösung für Inkompatibilitäten darin, zusammenzuarbeiten, um die Inkompatibilität zu beheben und das Go-Paket-Ökosystem zu erhalten. Temporäre Problemumgehungen in einem Tool wie vgo oder dep müssen nur lange genug funktionieren, um Entwicklern Zeit zu geben, das eigentliche Problem zu lösen, und vgo erledigt diese Aufgabe gut genug.

Wir schätzen all das Feedback und die Leidenschaft, die Sie in dieses wichtige Thema eingebracht haben. Der Vorschlag wurde angenommen.

— Das Go-Proposal-Review-Komitee

Alle 242 Kommentare

Häufig gestellte Fragen

Dieser Problemkommentar beantwortet die am häufigsten gestellten Fragen, sei es aus der Diskussion unten oder aus anderen Diskussionen. Weitere Fragen aus der Diskussion finden Sie im nächsten Heftkommentar.

Warum lautet der Vorschlag nicht „Use Dep “?

Zu Beginn der Reise, die vor fast zwei Jahren zu diesem Vorschlag führte, glaubten wir alle, dass die Antwort darin bestehen würde, dem Ansatz der Paketversionierung zu folgen, der von Ruby's Bundler und dann von Rust's Cargo veranschaulicht wird: getaggte semantische Versionen, eine handbearbeitete Abhängigkeitsbeschränkungsdatei bekannt als Manifest, eine separate maschinengenerierte Beschreibung der transitiven Abhängigkeit, bekannt als Sperrdatei, ein Versionslöser zum Berechnen einer Sperrdatei, die das Manifest erfüllt, und Repositories als Einheit der Versionierung. Dep folgt diesem groben Plan ziemlich genau und sollte ursprünglich als Vorbild für die Go-Kommando-Integration dienen. Je mehr ich jedoch die Details des Bundler/Cargo/Dep-Ansatzes verstand und was sie für Go bedeuten würden, insbesondere eingebaut in den go-Befehl, und je mehr ich diese Details mit anderen im Go-Team besprach, desto mehr Details schien immer weniger gut zu Go zu passen. Der Vorschlag passt diese Details in der Hoffnung an, ein System zu liefern, das für Entwickler einfacher zu verstehen und zu verwenden ist. Weitere Informationen zu den konkreten Details, die wir ändern wollten, finden Sie im Abschnitt „Begründung“ des Vorschlags sowie im Blogbeitrag zur Ankündigung des Vorschlags .

Warum müssen Hauptversionsnummern in Importpfaden erscheinen?

Befolgen Sie die Importkompatibilitätsregel , die den Rest des Systems dramatisch vereinfacht. Siehe auch den Blogbeitrag zur Ankündigung des Vorschlags , der mehr über die Motivation und Begründung für die Importkompatibilitätsregel spricht.

Warum werden die Hauptversionen v0, v1 in den Importpfaden weggelassen?

v1 wird aus zwei Gründen aus den Importpfaden weggelassen. Erstens werden viele Entwickler Pakete erstellen, die niemals eine bahnbrechende Änderung vornehmen, sobald sie v1 erreicht haben, was wir von Anfang an gefördert haben. Wir glauben nicht, dass all diese Entwickler gezwungen werden sollten, eine explizite v1 zu haben, wenn sie möglicherweise nicht die Absicht haben, jemals v2 zu veröffentlichen. Die v1 wird nur Rauschen. Wenn diese Entwickler schließlich eine v2 erstellen, tritt die zusätzliche Präzision ein, um sie von der Standardversion v1 zu unterscheiden. Es gibt gute Argumente für die sichtbare Stabilität, um die v1 überall einzusetzen, und wenn wir ein System von Grund auf neu entwerfen würden, wäre es vielleicht knapp. Aber das Gewicht des vorhandenen Codes gibt den Ausschlag, v1 wegzulassen.

v0 wird in den Importpfaden weggelassen, da es laut semver für diese Versionen überhaupt keine Kompatibilitätsgarantien gibt. Das Erfordernis eines expliziten v0-Elements würde wenig zur Gewährleistung der Kompatibilität beitragen; Sie müssten v0.1.2 sagen, um ganz genau zu sein, und alle Importpfade bei jedem Update der Bibliothek aktualisieren. Das scheint übertrieben zu sein. Stattdessen hoffen wir, dass Entwickler sich einfach die Liste der Module ansehen, von denen sie abhängen, und angemessen vorsichtig mit allen v0.xy-Versionen umgehen, die sie finden.

Dies hat den Effekt, dass v0 nicht von v1 in Importpfaden unterschieden wird, aber normalerweise ist v0 eine Folge von Breaking Changes, die zu v1 führen, daher ist es sinnvoll, v1 als letzten Schritt in dieser Breaking-Sequenz zu behandeln, nicht als etwas, das von v0 unterschieden werden muss . Wie @Merovius es ausdrückte (https://github.com/golang/go/issues/24301#issuecomment-376213693):

Durch die Verwendung von v0.x akzeptieren Sie, dass v0.(x+1) Sie zwingen könnte, Ihren Code zu reparieren. Warum ist es ein Problem, wenn v0.(x+1) stattdessen v1.0 heißt?

Schließlich ist das Weglassen der Hauptversionen v0 und v1 obligatorisch – nicht optional –, damit es für jedes Paket einen einzigen kanonischen Importpfad gibt.

Warum muss ich einen neuen Zweig für v2 erstellen, anstatt weiter am Master zu arbeiten?

Sie müssen keinen neuen Zweig erstellen. Der Beitrag zu den vgo-Modulen vermittelt leider diesen Eindruck in seiner Diskussion des Repository-Layouts des "Hauptzweigs". Aber vgo kümmert sich nicht um Branches. Es sucht nur nach Tags und löst auf, auf welche spezifischen Commits sie verweisen. Wenn Sie v1 auf dem Master entwickeln, Sie entscheiden, dass Sie mit v1 vollständig fertig sind, und Sie mit dem Erstellen von v2-Commits auf dem Master beginnen möchten, ist das in Ordnung: Fangen Sie an, Master mit v2.xy-Tags zu markieren. Beachten Sie jedoch, dass einige Ihrer Benutzer v1 weiterhin verwenden werden und Sie gelegentlich eine kleinere Fehlerbehebung für v1 durchführen möchten. Vielleicht möchten Sie zumindest einen neuen v1-Zweig für diese Arbeit an dem Punkt forken, an dem Sie anfangen, master für v2 zu verwenden.

Wird die minimale Versionsauswahl Entwickler nicht davon abhalten, wichtige Updates zu erhalten?

Das ist eine weit verbreitete Befürchtung, aber ich glaube wirklich, dass das Gegenteil passieren wird. Zitieren des Abschnitts "Upgrade Speed" von https://research.swtch.com/vgo-mvs :

Angesichts der Tatsache, dass die minimale Versionsauswahl die minimal zulässige Version jeder Abhängigkeit verwendet, ist es leicht zu glauben, dass dies zur Verwendung sehr alter Kopien von Paketen führen würde, was wiederum zu unnötigen Fehlern oder Sicherheitsproblemen führen könnte. In der Praxis wird jedoch meiner Meinung nach das Gegenteil passieren, da die minimal zulässige Version das Maximum aller Einschränkungen ist, sodass der einzige Kontrollhebel, der allen Modulen in einem Build zur Verfügung steht, die Möglichkeit ist, die Verwendung einer neueren Version zu erzwingen einer Abhängigkeit als sonst verwendet werden würde. Ich gehe davon aus, dass Benutzer mit minimaler Versionsauswahl Programme erhalten, die fast so aktuell sind wie ihre Freunde, die aggressivere Systeme wie Cargo verwenden.

Angenommen, Sie schreiben ein Programm, das von einer Handvoll anderer Module abhängt, die alle von einem sehr verbreiteten Modul wie gopkg.in/yaml.v2 abhängen. Der Build Ihres Programms verwendet die neueste YAML-Version unter denen, die von Ihrem Modul und dieser Handvoll Abhängigkeiten angefordert werden. Selbst nur eine gewissenhafte Abhängigkeit kann Ihren Build dazu zwingen, viele andere Abhängigkeiten zu aktualisieren. Dies ist das Gegenteil des zuvor erwähnten Problems mit dem Kubernetes Go-Client.

Wenn überhaupt, würde die minimale Versionsauswahl stattdessen das gegenteilige Problem erleiden, dass diese „Maximum-der-Minima“-Antwort als Ratsche dient, die Abhängigkeiten zu schnell vorantreibt. Aber ich denke, in der Praxis bewegen sich Abhängigkeiten mit genau der richtigen Geschwindigkeit vorwärts, was am Ende genau die richtige Menge langsamer ist als Cargo und Freunde.

Mit "richtiger Betrag langsamer" bezog ich mich auf die Schlüsseleigenschaft, dass Upgrades nur erfolgen, wenn Sie danach fragen, nicht, wenn Sie dies nicht getan haben. Das bedeutet, dass sich Code nur dann ändert (auf möglicherweise unerwartete und bahnbrechende Weise), wenn Sie dies erwarten und bereit sind, ihn zu testen, zu debuggen usw.

Siehe auch die Antwort https://github.com/golang/go/issues/24301#issuecomment -375992900 von @Merovius.

Wenn $GOPATH veraltet ist, wo befindet sich der heruntergeladene Code?

Code, den Sie auschecken, an dem Sie arbeiten und den Sie ändern, kann überall in Ihrem Dateisystem gespeichert werden, genau wie bei praktisch jedem anderen Entwicklertool.

Vgo benötigt etwas Platz, um heruntergeladenen Quellcode zu speichern und Binärdateien zu installieren, und verwendet dafür immer noch $GOPATH, das ab Go 1.9 standardmäßig $HOME/go ist. Daher müssen Entwickler niemals $GOPATH festlegen, es sei denn, sie möchten, dass sich diese Dateien in einem anderen Verzeichnis befinden. Um nur den Installationsort der Binärdatei zu ändern, können sie (wie immer) $GOBIN festlegen.

Warum führen Sie den Kommentar // import ein?

Waren nicht. Das war eine bereits bestehende Konvention . Der Zweck dieses Beispiels in der Tour war zu zeigen, wie go.mod die richtigen Modulpfade aus Importkommentaren ableiten kann, falls vorhanden. Sobald alle Projekte go.mod -Dateien verwenden, werden Importkommentare vollständig überflüssig und wahrscheinlich veraltet sein.

Zusammenfassung der Diskussion (zuletzt aktualisiert am 25.04.2017)

Dieser Issue-Kommentar enthält eine Zusammenfassung der folgenden Diskussion.

Wie können wir mit Migration umgehen?

[ https://github.com/golang/go/issues/24301#issuecomment -374739116 von @ChrisHines.]

Antwort https://github.com/golang/go/issues/24301#issuecomment -377529520 von @rsc. Der ursprüngliche Vorschlag geht davon aus, dass die Migration von Autoren durchgeführt wird, die in Unterverzeichnisse wechseln, wenn ihnen Kompatibilität wichtig ist, aber diese Motivation ist natürlich falsch. Die Kompatibilität ist für Benutzer am wichtigsten, die wenig Einfluss auf den Umzug der Autoren haben. Und es hilft nicht älteren Versionen. Der verlinkte Kommentar, jetzt auch #25069, schlägt eine minimale Änderung am alten „go build“ vor, um modulbewussten Code nutzen und bauen zu können.

Wie können wir mit Singleton-Registrierungen umgehen?

[ https://github.com/golang/go/issues/24301#issuecomment -374791885 von @jimmyfrasche.]

Antwort https://github.com/golang/go/issues/24301#issuecomment -377527249 von @rsc. Singleton-Registrierungskollisionen (z. B. http.Handle des gleichen Pfads) zwischen völlig unterschiedlichen Modulen sind von dem Vorschlag nicht betroffen. Bei Kollisionen zwischen verschiedenen Hauptversionen eines einzelnen Moduls können Autoren die verschiedenen Hauptversionen schreiben, von denen erwartet wird, dass sie koordiniert werden, normalerweise indem v1 in v2 aufgerufen wird, und dann einen Anforderungszyklus verwenden, um sicherzustellen, dass v2 nicht mit älteren v1 verwendet wird, die dies nicht tun. t wissen über die Koordination.

Wie sollten wir einen versionierten Befehl installieren?

[ https://github.com/golang/go/issues/24301#issuecomment -375106068 von @leonklingele.]

Antwort https://github.com/golang/go/issues/24301#issuecomment -377417565 von @rsc. Kurz gesagt, verwenden Sie go get. Wir verwenden immer noch $GOPATH/bin als Installationsort. Denken Sie daran, dass $GOPATH jetzt standardmäßig $HOME/go ist, sodass Befehle in $HOME/go/bin landen und $GOBIN dies überschreiben kann.

Warum werden v0, v1 in den Importpfaden weggelassen? Warum müssen die anderen erscheinen? Warum darf v0, v1 nie erscheinen?

[ https://github.com/golang/go/issues/24301#issuecomment -374818326 von @justinian.]
[ https://github.com/golang/go/issues/24301#issuecomment -374831822 von @jayschwa.]
[ https://github.com/golang/go/issues/24301#issuecomment -375437150 von @mrkanister.]
[ https://github.com/golang/go/issues/24301#issuecomment -376093912 von @mrkanister.]
[ https://github.com/golang/go/issues/24301#issuecomment -376135447 von @kaikuehne.]
[ https://github.com/golang/go/issues/24301#issuecomment -376141888 von @kaikuehne.]
[ https://github.com/golang/go/issues/24301#issuecomment -376213693 von @Merovius.]
[ https://github.com/golang/go/issues/24301#issuecomment -376247926 von @kaikuehne.]

Oben zu FAQ hinzugefügt.

Warum werden im Vorschlag Zip-Dateien erwähnt?

[ https://github.com/golang/go/issues/24301#issuecomment -374839409 von @nightlyone.]

Das Ökosystem wird von der Definition eines konkreten Austauschformats profitieren. Dadurch werden Proxys und andere Tools aktiviert. Gleichzeitig verzichten wir auf die direkte Verwendung der Versionskontrolle (siehe Begründung oben in diesem Beitrag ). Beides motiviert die Beschreibung des spezifischen Formats. Die meisten Entwickler müssen überhaupt nicht an Zip-Dateien denken; kein Entwickler muss in sie hineinschauen, es sei denn, er baut so etwas wie godoc.org.

Siehe auch #24057 über zip vs. tar.

Verstößt das Einfügen von Hauptversionen in Importpfade nicht gegen DRY?

[ https://github.com/golang/go/issues/24301#issuecomment -374831822 von @jayschwa.]

Nein, denn die Semantik eines Imports sollte ohne Bezugnahme auf die go.mod-Datei verständlich sein. Die go.mod-Datei spezifiziert nur feinere Details. Siehe die zweite Hälfte des Abschnitts semantische Importversionen des Vorschlags , beginnend mit dem Blockzitat.

Wenn Sie zu viel TROCKNEN, erhalten Sie außerdem zerbrechliche Systeme. Redundanz kann eine gute Sache sein. Also „violat[ing] DRY“ – also begrenztes Wiederholen – ist nicht immer schlecht. Zum Beispiel fügen wir die Paketklausel in jede .go-Datei im Verzeichnis ein, nicht nur in eine. Das fing schon früh ehrliche Fehler auf und wurde später zu einer einfachen Möglichkeit, externe Testpakete zu unterscheiden (Paket x vs. Paket x_test). Es muss ein Gleichgewicht gefunden werden.

Welche Zeitzone wird für den Zeitstempel in Pseudoversionen verwendet?

[ https://github.com/golang/go/issues/24301#issuecomment -374882685 von @tpng.]

KOORDINIERTE WELTZEIT. Beachten Sie auch, dass Sie niemals selbst eine Pseudoversion eingeben müssen. Sie können einen Git-Commit-Hash (oder Hash-Präfix) eingeben und vgo berechnet und ersetzt die entsprechende Pseudoversion.

Wird vgo Nicht-Go-Abhängigkeiten wie C oder Protokollpuffer ansprechen? Generierter Code?

[ https://github.com/golang/go/issues/24301#issuecomment -374907338 von @AlexRouSg.]
[ https://github.com/golang/go/issues/24301#issuecomment -376606788 von @stevvooe.]
[ https://github.com/golang/go/issues/24301#issuecomment -377186949 von @nim-nim.]

Non-Go-Entwicklung ist weiterhin kein Ziel des go -Befehls, daher wird es keine Unterstützung für die Verwaltung von C-Bibliotheken und dergleichen geben, noch wird es explizite Unterstützung für Protokollpuffer geben.

Allerdings verstehen wir sicherlich, dass die Verwendung von Protokollpuffern mit Go zu schwierig ist, und wir möchten, dass dies separat behandelt wird.

Was den generierten Code im Allgemeinen betrifft, so ist ein echtes sprachübergreifendes Build-System die Antwort, insbesondere weil wir nicht möchten, dass jeder Benutzer die richtigen Generatoren installiert haben muss. Besser für den Autor, die Generatoren laufen zu lassen und das Ergebnis einzuchecken.

Wird die minimale Versionsauswahl Entwickler nicht davon abhalten, wichtige Updates zu erhalten?

[ https://github.com/golang/go/issues/24301#issuecomment -375090551 von @TocarIP.]
[ https://github.com/golang/go/issues/24301#issuecomment -375985244 von @nim-nim.]
[ https://github.com/golang/go/issues/24301#issuecomment -375992900 von @Merovius.]

Zu den häufig gestellten Fragen hinzugefügt.

### Kann ich master verwenden, um v1 zu entwickeln, und es dann wiederverwenden, um v2 zu entwickeln?

[ https://github.com/golang/go/issues/24301#issuecomment -375248753 von @mrkanister.]
[ https://github.com/golang/go/issues/24301#issuecomment -375989173 von @aarondl.]

Ja. Zu den häufig gestellten Fragen hinzugefügt.

Was ist der Zeitplan dafür?

[ https://github.com/golang/go/issues/24301#issuecomment -375415904 von @flibustenet.]

Antwort in https://github.com/golang/go/issues/24301#issuecomment -377413777 von @rsc. Kurz gesagt, das Ziel ist es, eine "Technologievorschau" in Go 1.11 zu landen; Die Arbeiten können einige Wochen nach dem Einfrieren fortgesetzt werden, aber nicht weiter. Senden Sie wahrscheinlich keine PRs, die go.mod zu jeder Bibliothek hinzufügen, die Sie finden können, bis der Vorschlag als akzeptiert markiert ist und die Entwicklungskopie von cmd/go aktualisiert wurde.

Wie kann ich eine abwärtsinkompatible Sicherheitsänderung vornehmen?

[ https://github.com/golang/go/issues/24301#issuecomment -376236546 von @buro9.]

Antwort in https://github.com/golang/go/issues/24301#issuecomment -377415652 von @rsc. Kurz gesagt, die Go 1-Kompatibilitätsrichtlinien erlauben Breaking Changes aus Sicherheitsgründen, um ein Anstoßen der Hauptversion zu vermeiden, aber es ist immer am besten, dies so zu tun, dass der vorhandene Code so gut wie möglich funktioniert. Entfernen Sie beispielsweise keine Funktion. Machen Sie die Funktion stattdessen nur dann panisch oder log.Fatal, wenn sie unsachgemäß aufgerufen wird.

Wenn ein Repo verschiedene Module in Unterverzeichnissen enthält (z. B. v2, v3, v4), kann vgo verschiedene Commits mischen und abgleichen?

[ https://github.com/golang/go/issues/24301#issuecomment -376266648 von @jimmyfrasche.]
[ https://github.com/golang/go/issues/24301#issuecomment -376270750 von @AlexRouSg.]

Ja. Es behandelt jedes Versions-Tag so, als würde es nur einem Teilbaum des gesamten Repositorys entsprechen, und es kann für jede Entscheidung ein anderes Tag (und daher ein anderes Commit) verwenden.

Was ist, wenn Projekte Semver missbrauchen? Sollten wir Nebenversionen in Importpfaden zulassen?

[ https://github.com/golang/go/issues/24301#issuecomment -376640804 von @pbx0.]
[ https://github.com/golang/go/issues/24301#issuecomment -376645212 von @powerman.]
[ https://github.com/golang/go/issues/24301#issuecomment -376650153 von @pbx0.]
[ https://github.com/golang/go/issues/24301#issuecomment -376660236 von @powerman.]

Wie @powerman anmerkt, müssen wir auf jeden Fall einen API-Konsistenzprüfer bereitstellen, damit Projekten zumindest mitgeteilt werden kann, wann sie im Begriff sind, eine offensichtlich bahnbrechende Änderung zu veröffentlichen.

Können Sie feststellen, ob Sie mehr als ein Paket in einem Build haben?

[ https://github.com/golang/go/issues/24301#issuecomment -376640804 von @pbx0.]

Am einfachsten wäre es, goversion -m für die resultierende Binärdatei zu verwenden. Wir sollten eine Go-Option machen, um dasselbe zu zeigen, ohne die Binärdatei zu erstellen.

Bedenken hinsichtlich der Abhängigkeit von vgo von Proxy vs. Anbieter, insbesondere Open Source vs. Enterprise.

[ https://github.com/golang/go/issues/24301#issuecomment -376925845 von @joeshaw.]
[ https://github.com/golang/go/issues/24301#issuecomment -376936614 von @kardianos.]
[ https://github.com/golang/go/issues/24301#issuecomment -376947621 von @Merovius.]
[ https://github.com/golang/go/issues/24301#issuecomment -376979054 von @joeshaw.]
[ https://github.com/golang/go/issues/24301#issuecomment -376988873 von @jamiethermo.]
[ https://github.com/golang/go/issues/24301#issuecomment -377134575 von @Merovius.]

Antwort: [ https://github.com/golang/go/issues/24301#issuecomment -377411175 von @rsc.] Proxy und Anbieter werden beide unterstützt. Proxy ist für Unternehmen sehr wichtig, und Anbieter sind für Open Source sehr wichtig. Wir wollen auch ein zuverlässiges Mirror-Netzwerk aufbauen, aber erst, wenn aus vgo go wird.

Bedenken hinsichtlich des Protobuilds in Abhängigkeit von der GOPATH-Semantik.

[ https://github.com/golang/go/issues/24301#issuecomment -377601170 von @stevvooe.]

Antwort [ https://github.com/golang/go/issues/24301#issuecomment -377602765 von @rsc] bat um weitere Details in einem neuen Problem, aber dieses Problem scheint nicht eingereicht worden zu sein.

Vorschlag zum Hinzufügen eines speziellen vgo-v1-lock -Tags.

[ https://github.com/golang/go/issues/24301#issuecomment -377662150 von @kybin.]

Das erscheint zunächst verlockend, führt aber zu Sonderfällen, die sich vermutlich nicht lohnen. Vollständige Antwort in https://github.com/golang/go/issues/24301#issuecomment -384344659.

Wie patcht man eine tiefe Abhängigkeit ohne Vendoring?

[ https://github.com/golang/go/issues/24301#issuecomment -378255833 von @chirino.]

Antwort [ https://github.com/golang/go/issues/24301#issuecomment -378261916 von @kardianos.] Durch die Verwendung einer Ersetzungsdirektive.

Was werden wir tun, wenn sich Modulnamen ändern?

[ https://github.com/golang/go/issues/24301#issuecomment -379020339 von @jimmyfrasche.]

Antwort [ https://github.com/golang/go/issues/24301#issuecomment -379307176 von @rsc.]
Dies sind echte, bereits bestehende Probleme, die der vgo-Vorschlag nicht direkt anzugehen versucht, aber wir sollten sie eindeutig irgendwann angehen. Die Antwort auf das Verschwinden von Code ist, Caching-Proxys (Spiegel) zusammen mit einem Grund zu haben, ihnen zu vertrauen; das ist Zukunftsarbeit. (Oder verwenden Sie Vendoring in Top-Level-Projekten, wenn Sie dies vorziehen.) Die Antwort auf das Verschieben von Code besteht darin, ein explizites Konzept von Modul- oder Paketumleitungen hinzuzufügen, ähnlich wie Typaliase Typumleitungen sind. das ist auch zukunftsarbeit.

Was ist mit der Verbindung zu lokalen Git-Servern?

[ https://github.com/golang/go/issues/24301#issuecomment -383168012 von @korya.]

Direkter Git-Zugriff wurde dem Plan wieder hinzugefügt. Siehe #24915.

Was ist mit reinen Binärpaketen?

[ https://github.com/golang/go/issues/24301#issuecomment -382793364 von @sdwarwick.]

Nur-Binär-Pakete wurden bisher nur unter den begrenzten Umständen einer Art Out-of-Band-Installation in GOPATH/pkg unterstützt. Go get hat das Abrufen und Installieren eines Nur-Binär-Pakets nie unterstützt und wird dies auch weiterhin nicht unterstützen. Ein reines Binärpaket funktioniert nur mit einem bestimmten Compiler und einer bestimmten Kopie der Abhängigkeiten, was die Unterstützung stark einschränkt. Die richtige Antwort ist fast immer, stattdessen Quellcode zu verwenden.

Sollten wir die path@version -Syntax in der go.mod-Datei verwenden?

[ https://github.com/golang/go/issues/24301#issuecomment -382791513 von @sdwarwick.]

Dies ist #24119. Es schien zunächst eine gute Idee zu sein, aber nach reiflicher Überlegung nein.

.

.

Änderung https://golang.org/cl/101678 erwähnt dieses Problem: design: add 24301-versioned-go

Dieser Vorschlag ist beeindruckend und ich mag fast alles daran. Ich habe jedoch das folgende Anliegen auf der Mailingliste gepostet, aber nie eine Antwort erhalten. In der Zwischenzeit habe ich gesehen, dass dieses Problem von anderen im Gophers-Slack-Kanal für vgo angesprochen wurde, und auch dort keine zufriedenstellende Antwort erhalten.

Von: https://groups.google.com/d/msg/golang-dev/Plc42fslQEk/rlfeNlazAgAJ

Ich mache mir am meisten Sorgen darüber, dass der Migrationspfad zwischen einer Pre-VGO-Welt und einer VGO-Welt schlecht läuft. Ich denke, wir riskieren, der Go-Community große Schmerzen zuzufügen, wenn es keinen reibungslosen Migrationspfad gibt. Natürlich kann die Migration nicht atomar über die gesamte Community hinweg erfolgen, aber wenn ich alles verstanden habe, was Sie bisher über vgo geschrieben haben, kann es einige Situationen geben, in denen vorhandene weit verbreitete Pakete nicht sowohl von Pre-vgo-Tools als auch von Post-Tools verwendet werden können -vgo-Tools.

Insbesondere glaube ich, dass vorhandene Pakete, die bereits Releases mit Hauptversionen >= 2 gekennzeichnet haben, nicht mit vgo funktionieren, bis sie eine go.mod-Datei haben und auch mit einem erweiterten /vN-Importpfad importiert werden. Sobald diese Änderungen jedoch am Repository vorgenommen wurden, wird die Verwendung des Pakets vor vgo unterbrochen.

Dies scheint eine andere Art von Diamond-Importproblem zu schaffen, bei dem die beiden Geschwisterpakete in der Mitte des Diamond ein gemeinsames v2+-Paket importieren. Ich mache mir Sorgen, dass die Geschwisterpakete vgo-Importpfade atomar übernehmen müssen, um zu verhindern, dass sich das Paket oben im Diamanten in einem nicht erstellbaren Zustand befindet, unabhängig davon, ob es vgo- oder Pre-vgo-Tools verwendet.

Ich habe noch nichts gesehen, was den Migrationspfad in diesem Szenario erklärt.

Der Vorschlag besagt:

Modulbewusste Builds können nicht modulbewusste Pakete (diejenigen außerhalb eines Baums mit einer go.mod-Datei) importieren, vorausgesetzt, sie sind mit einer v0- oder v1-Semantikversion gekennzeichnet. Sie können sich auch auf ein bestimmtes Commit beziehen, indem sie eine „Pseudo-Version“ der Form v0.0.0-yyyymmddhhmmss-commit verwenden. Das Pseudoversionsformular ermöglicht den Verweis auf nicht getaggte Commits sowie Commits, die mit semantischen Versionen ab v2 oder höher getaggt sind, aber nicht der semantischen Import-Versionierungskonvention folgen.

Aber ich sehe keine Möglichkeit für nicht modulfähige Pakete, modulfähige Pakete mit transitiven Abhängigkeiten >= v2 zu importieren. Das scheint zu einer Fragmentierung des Ökosystems auf eine noch nicht behandelte Weise zu führen. Sobald Sie eine modulbewusste Abhängigkeit haben, die irgendwo in ihren transitiven Abhängigkeiten ein Paket >= v2 enthält, scheint dies alle ihre Abhängigkeiten zu zwingen, ebenfalls vgo zu übernehmen, damit der Build funktioniert.

Aktualisierung: siehe auch https://github.com/golang/go/issues/24454

Das Go-Projekt hat diese Konvention von Beginn des Projekts an gefördert, aber dieser Vorschlag gibt ihr mehr Biss: Upgrades durch Paketbenutzer werden nur in dem Maße erfolgreich sein oder scheitern, wie Paketautoren die Importkompatibilitätsregel befolgen.

Mir ist unklar, was das bedeutet und wie es sich gegenüber der aktuellen Situation ändert. Mir scheint, dass dies auch die aktuelle Situation beschreibt: Wenn ich gegen diese Regel verstoße, werden Upgrades und Go-Get fehlschlagen. AIUI ändert sich nichts wirklich und ich würde vorschlagen, zumindest die Erwähnung von "mehr Zähnen" zu entfernen. Es sei denn, dieser Absatz soll natürlich implizieren, dass es zusätzliche Mechanismen gibt, um Brüche zu bestrafen/zu verhindern?

Dies würde auch Dinge wie Datenbanktreiber und Bildformate betreffen, die sich während der Initialisierung bei einem anderen Paket registrieren, da dies am Ende mehrere Hauptversionen desselben Pakets tun können. Was das alles für Folgen hat, ist mir unklar.

Wenn die Hauptversion v0 oder v1 ist, muss das Versionsnummernelement weggelassen werden; andernfalls muss es enthalten sein.

Warum ist das? In dem verlinkten Beitrag sehe ich nur die Begründung, dass dies derzeit das ist, was Entwickler tun, um alternative Pfade zu erstellen, wenn sie Breaking Changes vornehmen - aber dies ist eine Problemumgehung für die Tatsache, dass sie ursprünglich nicht planen, dass die Tools keine Versionen für sie handhaben . Wenn wir zu einer neuen Praxis wechseln, warum nicht zulassen und fördern (oder sogar vorschreiben), dass neue vgo-fähige Pakete v0 oder v1 enthalten? Es scheint, als ob Pfade ohne Versionen nur Gelegenheiten für Verwirrung sind. (Ist dies ein Paket im vgo-Stil? Wo ist die Modulgrenze? usw.)

Ich mag den Vorschlag im Allgemeinen, bin aber aufgelegt, Hauptversionen in Importpfaden zu benötigen:

  1. Es verstößt gegen das DRY-Prinzip, wenn die Hauptversion bereits aus dem go.mod bekannt sein kann. Es ist auch schwer zu verstehen, was passieren wird, wenn es eine Diskrepanz zwischen den beiden gibt.
  2. Die Unregelmäßigkeit, v0 und v1 fehlen zu lassen, ist ebenfalls nicht intuitiv.
  3. Das Ändern aller Importpfade beim Aktualisieren einer Abhängigkeit scheint potenziell mühsam zu sein.

Ich verstehe, dass Szenarien wie das moauth -Beispiel praktikabel sein müssen, aber hoffentlich nicht auf Kosten der Einfachheit für häufigere Szenarien.

Erstmal: Beeindruckende Arbeit!

Eine Sache, die mir völlig unklar ist und etwas unterspezifiziert erscheint:

Warum enthält dieser Vorschlag eine ZIP-Datei?

Layout, Einschränkungen und mehrere Anwendungsfälle, z. B. wann es erstellt wird und wie sein Lebenszyklus verwaltet wird, welche Tools Unterstützung benötigen, wie Tools wie Linters damit interagieren sollten, sind ebenfalls unklar, da sie nicht im Vorschlag behandelt werden.

Daher würde ich vorschlagen, hier entweder auf einen späteren, noch ungeschriebenen Vorschlag zu verweisen und das Wort zip zu entfernen oder den ganzen Teil aus dem Vorschlagstext zu entfernen, wenn Sie vorhaben, ihn überhaupt nicht im Rahmen dieses Vorschlags zu diskutieren.

Eine spätere Diskussion ermöglicht es auch einem anderen Publikum, sich hier besser einzubringen.

Welche Zeitzone wird für den Zeitstempel in der Pseudo-Version (v0.0.0-yyyymmddhhmmss-commit) verwendet?

Bearbeiten:
Es ist in UTC angegeben, wie in https://research.swtch.com/vgo-module angegeben.

@rsc Werden Sie sich mit C-Abhängigkeiten befassen?

Sieht so aus, als würde die minimale Versionsauswahl die Weitergabe von nicht brechenden Änderungen sehr langsam machen. Angenommen, wir haben eine beliebte Bibliothek Foo, die von den Projekten A, B und C verwendet wird. Jemand verbessert die Leistung von Foo, ohne die API zu ändern. Der aktuelle Empfang von Updates ist ein Opt-out-Prozess. Wenn Projekt A Foo bereitgestellt hat, B und C jedoch nicht, muss der Autor nur pr mit dem Update zur Anbieterabhängigkeit an A senden. Daher haben Nicht-API-Breaking-Beiträge nicht so viel Einfluss auf die Community und sind im Vergleich zu aktuellen etwas entmutigt Lage. Noch problematischer ist dies bei Sicherheitsupdates. Wenn ein aufgegebenes/kleines/nicht sehr aktives Projekt (keine Bibliothek) eine direkte Abhängigkeit von einer alten Version von z. B. x/crypto erklärt, werden alle Benutzer dieses Projekts anfällig für Fehler in x/crypto sein, bis das Projekt aktualisiert wird, möglicherweise für immer. Derzeit erhalten Benutzer solcher Projekte die neueste korrigierte Version, was die Sicherheitssituation verschlechtert. IIRC gab einige Vorschläge, wie man dies in der Maillisten-Diskussion beheben könnte, aber soweit ich das beurteilen kann, wird es in diesem Vorschlag nicht erwähnt.

IIRC gab einige Vorschläge, wie man [Sicherheitspatches erhalten] in der Maillistendiskussion beheben kann, aber soweit ich das beurteilen kann, erwähnt dieser Vorschlag es nicht.

Siehe die Erwähnung von go get -p .

Siehe die Erwähnung von go get -p.

Ich habe es gesehen, aber dies ist immer noch ein Opt-in-Mechanismus.
Ich habe über eine Möglichkeit nachgedacht, wie die Bibliothek alle früheren Versionen als unsicher markieren kann, um den Benutzer zu zwingen, go get -p auszuführen oder sich ausdrücklich für die unsichere Bibliothek anzumelden.

Wenn die Unterstützung für go get , wie wir sie heute kennen, veraltet und schließlich entfernt wird, was ist dann der empfohlene Weg, um (nicht markierte) Go-Binärdateien abzurufen und zu installieren? Muss das Projekt zuerst git clone erstellt werden, gefolgt von einer manuellen go install Installation der Binärdatei?
Wenn $GOPATH veraltet ist, wo werden diese Binärdateien installiert?

@leonklingele : nach meinem Verständnis wird go get nicht veraltet sein, im Gegenteil.
Es wird um automatische und transparente Versionierungsfunktionen erweitert. Wenn ein Projekt von einem ungetaggten Projekt abhängt, würde es einfach den Master nehmen und ihn mit genau dieser Version "liefern".
Nochmals, mein eigenes Verständnis, wenn ich nur ein wenig über vgo lese. Ich bin immer noch dabei, es vollständig zu verstehen.

Ich frage mich, wie sich dies auf den Arbeitsfluss mit einem Git-Repository im Allgemeinen auswirken wird, auch aufbauend auf diesem Satz aus dem Vorschlag:

Wenn die Hauptversion v0 oder v1 ist, muss das Versionsnummernelement weggelassen werden; andernfalls muss es enthalten sein.

Momentan scheint es üblich zu sein, am Master zu arbeiten (dazu gehören für mich kurzlebige Feature Branches) und hin und wieder einen Commit mit einer neuen Version zu taggen. Ich habe das Gefühl, dass dieser Workflow mit Go-Modulen verwirrender wird, sobald ich v2 meiner Bibliothek veröffentliche, da ich jetzt einen master - und einen v2 -Zweig habe. Ich würde erwarten, dass master der aktuelle Zweig und v2 ein Wartungszweig ist, aber es ist genau umgekehrt.

Ich weiß, dass der Standard-Zweig von master in v2 geändert werden kann, aber das lässt mich immer noch mit der Aufgabe zurück, das jedes Mal zu aktualisieren, wenn ich eine neue Hauptversion veröffentliche. Ich persönlich hätte lieber einen master - und einen v1 -Zweig, aber ich bin mir nicht sicher, wie genau das zu dem Vorschlag passen würde.

Neue Hauptversionen verursachen Abwanderung. Wenn Sie bei jeder neuen Version eine Einstellung in Ihrem Git-Repository (dem Standardzweig) ändern müssen, sind die Kosten im Vergleich dazu, dass die Benutzer Ihrer Bibliothek auf die neue Version wechseln, sehr gering.

Ich denke, dieser Aspekt des Vorschlags setzt den richtigen Anreiz: Er ermutigt Upstream-Autoren, darüber nachzudenken, wie sie Änderungen auf rückwärtskompatible Weise vornehmen können, um die allgemeine Veränderung des Ökosystems zu verringern.

Jetzt habe ich einen Master- und einen v2-Zweig

Sie können stattdessen ein v2/ -Unterverzeichnis im Master erstellen.

@mrkanister

Ich hätte lieber einen Master- und einen v1-Zweig, aber ich bin mir nicht sicher, wie genau das zu dem Vorschlag passen würde.

Nach meinem Verständnis von https://research.swtch.com/vgo-module verwendet vgo Tags und keine Zweige, um die Versionen zu identifizieren. Sie können also die Entwicklung auf dem Master belassen und von v1 abzweigen, solange die Tags auf den richtigen Zweig und Commit verweisen.

Neue Hauptversionen verursachen Abwanderung. Wenn Sie bei jeder neuen Version eine Einstellung in Ihrem Git-Repository (dem Standardzweig) ändern müssen, sind die Kosten im Vergleich dazu, dass die Benutzer Ihrer Bibliothek auf die neue Version wechseln, sehr gering.

Dies ist eine problematische Denkweise, die Go meiner Meinung nach in der Vergangenheit hart getroffen hat. Für eine Person in einem Projekt ist es im Moment einfach, den Standardzweig zu wechseln, ja. Aber gegen die Konventionen des Arbeitsablaufs zu verstoßen, wird dazu führen, dass die Leute vergessen, besonders wenn sie in mehreren Sprachen arbeiten. Und es wird ein weiteres skurriles Beispiel dafür sein, wie Go Dinge völlig anders macht, die Neulinge lernen müssen. Gegen gängige Programmierer-Workflow-Konventionen zu verstoßen, ist _überhaupt nicht_ ein geringer Kostenfaktor.

Gegen gängige Programmierer-Workflow-Konventionen zu verstoßen, ist keineswegs ein geringer Kostenfaktor.

Den konventionellen Weg nicht zu gehen, ist manchmal die notwendige Bedingung für Innovation.

Wenn ich Teile des Vorschlags richtig verstanden habe, müssen Sie nie ein Unterverzeichnis oder einen neuen Zweig erstellen. Möglicherweise haben Sie nur einen Master-Branch und Git-Tags für Ihr Repo von 0.0 über 1.0 bis 2.0 usw. , solange Sie sicherstellen, dass Sie Ihr go.module auf den richtigen Importpfad für Ihre Bibliothek aktualisieren.

@mrkanister Ich denke, für Entwickler klonen Sie Ihren Master (oder einen beliebigen Entwicklerzweig) und verwenden die Direktive "replace" (siehe vgo-tour), um darauf zu verweisen. (wenn ich verstehe, was du meinst, keine Ahnung).

@rsc Ich möchte Sie bitten, die Roadmap genauer zu beschreiben und was wir jetzt tun sollten.
Wird es der Go-Richtlinie folgen und vgo nach 3 Monaten (jetzt 2) einfrieren?
Sollten wir jetzt mit unserem Pilgerstock weitermachen und jeden libs-Betreuer bitten, eine go.mod-Datei hinzuzufügen, oder sollten wir warten, bis der Vorschlag offiziell angenommen wird (um sicherzugehen, dass sich Name und Syntax nicht ändern)?

@flibustenet- Tools fallen nicht unter die 1.0-Richtlinie, sodass sich alles ändern kann.

https://golang.org/doc/go1compat

Schließlich befindet sich die Go-Toolchain (Compiler, Linker, Build-Tools usw.) in aktiver Entwicklung und kann ihr Verhalten ändern. Das bedeutet zum Beispiel, dass Skripte, die von Standort und Eigenschaften der Tools abhängen, durch eine Point-Release kaputt gehen können.

Auch aus dem Vorschlag

Der Plan ist, vorbehaltlich der Genehmigung des Vorschlags, die Modulunterstützung in Go 1.11 als optionales Feature zu veröffentlichen, das sich noch ändern kann. Die Version Go 1.11 gibt Benutzern die Möglichkeit, Module „in echt“ zu verwenden und kritisches Feedback zu geben. Auch wenn sich die Details ändern können, werden zukünftige Versionen in der Lage sein, Go 1.11-kompatible Quellbäume zu nutzen. Beispielsweise wird Go 1.12 verstehen, wie die go.mod-Dateisyntax von Go 1.11 zu konsumieren ist, selbst wenn sich bis dahin die Dateisyntax oder sogar der Dateiname geändert hat. In einer späteren Version (z. B. Go 1.12) werden wir die Modulunterstützung für abgeschlossen erklären. In einer späteren Version (z. B. Go 1.13) werden wir die Unterstützung für Go Get von Nicht-Modulen beenden. Die Unterstützung für die Arbeit in GOPATH wird auf unbestimmte Zeit fortgesetzt.

Danke für die Rückmeldung.

@AlexRouSg

Nach meinem Verständnis von https://research.swtch.com/vgo-module verwendet vgo Tags und keine Zweige, um die Versionen zu identifizieren. Sie können also die Entwicklung auf dem Master belassen und von v1 abzweigen, solange die Tags auf den richtigen Zweig und Commit verweisen.

Sie haben Recht, dies wird weiterhin wie bisher funktionieren (nur doppelt überprüft, um sicherzugehen), guter Fang!

Nachdem dies aus dem Weg geräumt ist, verstehe ich (und anscheinend andere) nicht, warum ein v1 -Paket nicht existieren darf. Ich habe versucht, eines mit /v1 am Ende des Imports zu importieren und es auch zu go.mod des zu importierenden Pakets hinzuzufügen, aber vgo sucht nach einem Ordner namens v1 stattdessen.

@mrkanister
Ich denke, der Hauptgrund dafür, v1 oder v0 im Importpfad nicht zuzulassen, besteht darin, sicherzustellen, dass es nur einen Importpfad für jede kompatible Version eines Pakets gibt.
Die Verwendung des einfachen Importpfads anstelle von /v1 erleichtert den Übergang, sodass Sie nicht alle Ihre Importpfade aktualisieren müssen, um /v1 am Ende hinzuzufügen.

Hallo,

Während viele der Punkte in dem Vorschlag mehr als willkommen sind und dazu beitragen werden, die großen Go-Codebasen zu zähmen, die im Laufe der Zeit entstanden sind, ist die Regel „Verwende minimale Version“ ziemlich schädlich:

  • Sie möchten, dass Ihr Code-Ökosystem Fortschritte macht. Das heißt, Sie möchten, dass die Leute neue Versionen testen und verwenden und Probleme frühzeitig erkennen, bevor sie sich anhäufen.
  • Sie möchten, dass neue Modulversionen, die Sicherheitsprobleme beheben, so schnell wie möglich angewendet werden
  • Sie möchten in der Lage sein, neue Modulversionen, die Sicherheitsprobleme beheben, so schnell wie möglich anzuwenden. Sie sind nicht immer bei Sicherheitsfixes gekennzeichnet. Wenn Sie neue Releases vermeiden, vermeiden Sie auch diese Fixes
  • Selbst wenn eine neue Version keine Sicherheitsfixes enthält, die ihre Änderungen frühzeitig anwenden, bedeutet dies, dass weniger Änderungen überprüft werden müssen, wenn die nächste Version veröffentlicht wird, die Sicherheitsfixes enthält (und das Letzte, was Sie wollen, wenn eine solche Version veröffentlicht wird und Sie müssen schnell zu sein bedeutet, sich in zwischenzeitlichen Änderungen zu verzetteln, die man sich vorher nicht angesehen hat).
  • Das Anwenden von Zwischenversionen ist nur schädlich, wenn sie die Kompatibilität brechen, und sie sollten die Kompatibilität nicht brechen, und wenn sie die Kompatibilität brechen, sollten Sie es besser erkennen und den Modulautoren mitteilen, bevor sie es für die nächsten Veröffentlichungen zur Gewohnheit machen, Sie werden es schließlich absolut tun müssen.
  • Sie möchten nicht, dass alte Codeteile Sie herunterziehen, weil sie immer noch eine alte Abhängigkeitsversion angeben und niemand die Zeit findet, ihr Manifest zu aktualisieren. Die Verwendung der neuesten Version einer Hauptversion erfüllt dieses soziale Bedürfnis in anderen Code-Ökosystemen: Entwickler zwingen, die neueste Version zu testen und nicht zu verschieben, bis es zu spät ist, weil „es wichtigere“ (dh unterhaltsamere) Dinge zu tun gibt.

    • Während Sie theoretisch eine unbegrenzte Anzahl von Modulversionen ausliefern können, sodass jedes Stück Code die gewünschte verwenden kann, müssen Sie in der Praxis, sobald Sie zwei Module zusammenstellen, die dieselbe Dep verwenden, eine Version auswählen, je komplexer Ihre ist Software ist, desto weniger werden Sie mehrere Versionen tolerieren. So stößt man bald auf das alte Problem, was man mit Nachzüglern machen soll, die den ganzen Konvoi verlangsamen. Ich habe noch nie eine menschliche Kultur getroffen, die dieses Problem gelöst hat, indem sie den Nachzüglern gesagt hat: "Du hast Recht, fahr so ​​langsam, wie du willst, alle werden auf dich warten". Es mag nett und altruistisch sein, aber es ist nicht produktiv.

Der Kampf gegen die menschliche Trägheit ist hart und schmerzhaft, und wir kämpfen dagegen, weil es erforderlich ist, um voranzukommen, nicht weil es angenehm ist. Angenehme Tools zu entwickeln, die das Problem vermeiden und die Menschen dazu anregen, noch etwas aufzuschieben, ist überhaupt nicht hilfreich, sondern beschleunigt nur die Sedimentation von Projekten und die Anhäufung technischer Schulden. Es gibt bereits Dutzende von Go-Projekten auf GitHub, wobei die meisten ihrer Readme dem Autor gewidmet sind und seine Benutzer bitten, ein Upgrade durchzuführen, weil er wichtige Korrekturen vorgenommen hat. Wenn Sie standardmäßig auf die älteste Version zurückgreifen, wird das Problem verallgemeinert.

Eine gute Regel wäre "verwenden Sie die neueste Version, die der Hauptversion entspricht, nicht jeden zwischengeschalteten Commit". Das wäre ein Kompromiss in Richtung Zukunft und Stabilität. Es gibt dem ursprünglichen Projekt das Kommando, das die Codebasis am besten kennt und vernünftig entscheiden kann, wann es seine Benutzer auf einen neuen Codestatus umstellen soll.

Meine unbeantwortete Frage aus der Mailingliste kopiert:

Wir gehen davon aus, dass die meisten Entwickler es vorziehen werden, der üblichen „Hauptzweig“-Konvention zu folgen, in der verschiedene Hauptversionen in verschiedenen Zweigen leben. In diesem Fall hätte das Stammverzeichnis in einem v2-Zweig eine go.mod, die v2 angibt, wie folgt:

Es scheint, als gäbe es Unterverzeichnisse und diese große Zweigkonvention, die beide von vgo unterstützt werden. Nach meiner anekdotischen Erfahrung folgen keine Repositories dieser Konvention in Go oder anderen Sprachen (ich kann mir eigentlich kein einziges vorstellen, außer denen, die von gopkg.in gezwungen werden, was heutzutage relativ ungenutzt zu sein scheint). Der Master-Zweig ist das Neueste und hat v2.3.4-Tags in seiner Geschichte. Es gibt Tags, um alles zu trennen (nicht nur Nebenversionen). Wenn es notwendig ist, eine alte Version zu patchen, wird aus dem letzten v1-Tag vorübergehend ein Branch erstellt, Commits gepusht, ein neues Tag gepusht und der Branch kurzerhand gelöscht. Es gibt keinen Zweig für Versionen, es sind nur aktuelle Master-/Dev-/Feature-Zweige + Versions-Tags. Ich weiß, dass in Git "alles ein Ref" ist, aber für andere VCS ist die Unterscheidung möglicherweise nicht so unscharf.

Trotzdem habe ich den oben beschriebenen Workflow mit vgo getestet (nur mit Tags, die v2.0.0, v2.0.1 und keine Branches sagen) und es scheint zu funktionieren. Meine Frage ist also: Obwohl das jetzt funktioniert, ist es beabsichtigt? Da es nicht so gründlich beschrieben zu sein scheint wie die anderen beiden Workflows im Blog, und ich sicherstellen möchte, dass das Arbeiten ohne einen v2/v3...-Zweig keine zufällige Funktionalität ist, die verschwinden wird, da ich es, wie oben erklärt, nie getan habe gesehen, dass dieser (oder der andere) beschriebene Workflow in der Post von niemandem (insbesondere außerhalb der Go-Community) massiv übernommen wird.

Natürlich läuft mein Argument auf Vorlieben und Anekdoten hinaus, daher wäre ich bereit, ein Repo-Scraping durchzuführen, um dies bei Bedarf für alle Sprachen zu beweisen. Bisher haben mir die Proposal-Posts sehr gut gefallen und ich bin generell mit den Änderungen einverstanden, werde weiter mitverfolgen und mit vgo spielen.

Vielen Dank für all Ihre Bemühungen.

Kann jemand vielleicht klären, wie das vorgeschlagene Alternativmodell zu MVS funktionieren würde, um die Upgrade-Kadenz zu verbessern? Weil es mir nicht klar ist. Mein Verständnis des alternativen (weit verbreiteten) Modells ist

  • Der Entwickler erstellt ein handgefertigtes Manifest, das Versionseinschränkungen für alle verwendeten Abhängigkeiten auflistet
  • Der Entwickler führt $solver aus, das eine Sperrdatei erstellt, die eine ausgewählte Teilmenge transitiver Abhängigkeitsversionen auflistet, die die angegebenen Einschränkungen erfüllen
  • Diese Sperrdatei wird festgeschrieben und zur Build- und Installationszeit verwendet, um reproduzierbare Builds zu gewährleisten
  • Wenn eine neue Version einer Abhängigkeit veröffentlicht und verwendet werden soll, aktualisiert der Entwickler möglicherweise das Manifest, führt den Solver erneut aus und übergibt die neue Sperrdatei erneut

Das vorgeschlagene MVS-Modell, wie ich es verstehe, ist es

  • Der Entwickler generiert automatisch go.mod basierend auf dem Satz von Importpfaden im Modul und wählt die aktuell neueste Version einer transitiven Abhängigkeit aus
  • go.mod wird festgeschrieben und wird verwendet, um niedrigere Grenzen für Versionen zur Build- und Installationszeit zu erhalten. MVS garantiert reproduzierbare Builds
  • Wenn eine neue Version einer Abhängigkeit veröffentlicht und verwendet werden soll, führt der Entwickler vgo get -u aus, wodurch die neuesten Versionen der transitiven Abhängigkeiten abgerufen und go.mod mit den neuen Untergrenzen überschrieben werden. Das wird dann eingereicht.

Es scheint, ich muss etwas grob übersehen, und es wäre hilfreich, wenn jemand darauf hinweisen würde, was. Da dieses Verständnis zu implizieren scheint, dass fällige Sperrdateien die genauen Versionen angeben und diejenigen, die im tatsächlichen Build verwendet werden, ist MVS besser darin, die Upgrade-Kadenz zu erhöhen - da es im Allgemeinen nicht erlaubt, Versionen zurückzuhalten.

Offensichtlich fehlt mir etwas (und werde mich in etwa 5 Minuten dumm fühlen), was ist das?

@tpng

Die Verwendung des einfachen Importpfads anstelle von /v1 erleichtert den Übergang, sodass Sie nicht alle Ihre Importpfade aktualisieren müssen, um /v1 am Ende hinzuzufügen.

Dies sollte eigentlich nicht nötig sein. Lassen Sie mich ein Beispiel geben:

Ein Benutzer verwendet derzeit z. B. v1.0.0 einer Bibliothek, die von einem Abhängigkeitsmanager und dem Tag im Upstream-Repository gepinnt wird. Jetzt beschließt der Upstream, ein go.mod zu erstellen und ruft auch das Modul /v1 . Dies sollte zu einem neuen Commit und einem neuen Tag führen (z. B. v1.0.1 ). Da vgo niemals versuchen wird, Abhängigkeiten selbst zu aktualisieren, sollte dies für den Benutzer nichts kaputt machen, aber er/sie kann bewusst aktualisieren, indem er auch den Importpfad ändert (pr vgo kann dies tun für ihn/sie).

Ich denke, der Hauptgrund dafür, v1 oder v0 im Importpfad nicht zuzulassen, besteht darin, sicherzustellen, dass es nur einen Importpfad für jede kompatible Version eines Pakets gibt.

Ja, ich denke, ich kann diesen Punkt tatsächlich sehen, um neue Benutzer einer Bibliothek nicht zu verwirren.

Wenn die Hauptversion v0 oder v1 ist, muss das Versionsnummernelement weggelassen werden; andernfalls muss es enthalten sein.

Kann mir bitte jemand die Begründung dafür erklären? Was mache ich als Benutzer einer Bibliothek, wenn ich v1 noch nicht verwenden möchte, weil es eine bahnbrechende Änderung eingeführt hat, die mit semantischer Versionierung (neue Hauptversion) völlig in Ordnung wäre?

Ich würde es vorziehen, nur die Version vor Version 1 wegzulassen, was auf ein instabiles/unfertiges Paket hinweist. Ab Version 1 möchte ich mich darauf verlassen können, dass ich ein stabiles Release erhalte. Das Weglassen von v1 im Importpfad ist verwirrend, da Sie nicht wissen, ob Sie eine sich ständig ändernde Bibliothek oder eine stabile Version verfolgen. Ich denke, dass dies auch nicht gut mit dem semantischen Versionierungsschema funktioniert, bei dem v1 die erste stabile Version festlegt, die verwendet wird, um diese Version klar von den Versionen 0.x zu unterscheiden.

@kaikühne

Was mache ich als Benutzer einer Bibliothek, wenn ich v1 noch nicht verwenden möchte, weil es eine bahnbrechende Änderung eingeführt hat, die mit semantischer Versionierung (neue Hauptversion) völlig in Ordnung wäre?

Soweit ich verstanden habe, wird vgo Abhängigkeiten niemals selbst aktualisieren, nicht einmal auf eine Patch-Version, sondern dies als bewusste Entscheidung für Sie überlassen. Wenn Sie also auf v0.4.5 einer Bibliothek angewiesen sind (die ein Tag dafür hat), können Sie diese theoretisch für immer verwenden. Sie können die Version auch manuell in Ihrer go.mod -Datei anheften.

Was ist, wenn eine andere Abhängigkeit, die ich verwende, von demselben Paket abhängt, aber Version v1? Beide Pakete werden über denselben Importpfad importiert. Gibt es keinen Konflikt, wenn diese in dieselbe Binärdatei kompiliert werden?

Wenn v1 auch Teil des Importpfads sein müsste, würden beide als unterschiedliche Pakete behandelt, was sie auch sind.

@kaikuehne dann würde es auf die minimale gemeinsame Version aktualisieren, die funktioniert. (zu meinem Verständnis)

@kaikuehne Ich verstehe deine Argumentation nicht. Sie verwenden v0, also sind Sie vermutlich mit Breaking Changes einverstanden; Warum wäre es ein Problem, wenn v1 kaputt geht, da Sie bereits eine Version verwenden, die keine Stabilitätsgarantie hat? Anstatt von v0.1->v1.0 mit einer Breaking Change zu gehen, würde Upstream die Unterbrechung zu v0.2 hinzufügen und dann eine (nicht brechende) v1.0 veröffentlichen. Das scheint gut innerhalb der Erwartungen an semantische Versionen zu liegen, würde aber genau die gleiche Menge an Mühe für Sie bedeuten (unabhängig vom verwendeten Paketmanager). Das heißt, ich verstehe wirklich nicht, wie "der Autor plötzlich aufgehört hat, seine API zu beschädigen" ein Problem darstellt, das nicht durch die Verwendung einer Version vor 1.0 verursacht wird.

Anders ausgedrückt: Indem Sie v0.x verwenden, akzeptieren Sie, dass v0.(x+1) Sie zwingen könnte, Ihren Code zu reparieren. Warum ist es ein Problem, wenn v0.(x+1) stattdessen v1.0 heißt?

Zu Diskussionspunkt 4: Explizit Übernahme der Import-Kompatibilitätsregel und "das neue Paket muss abwärtskompatibel zum alten Paket sein"...

In meinem Fall habe ich ein Sicherheitspaket https://github.com/microcosm-cc/bluemonday und ich hatte kürzlich (Ende letzten Jahres) ein Szenario, in dem ich erfahren habe, dass eine öffentliche Funktion grundsätzlich nicht zweckmäßig ist. Also habe ich es entfernt.

Unter diesem Vorschlag würde, wenn ich die Funktion entfernte, die Version erhöht und der unsichere/unsichere Code würde niemals entfernt.

Um dies zu vermeiden, würde ich wahrscheinlich stattdessen log.Fatal() innerhalb der Funktion, die ich entfernen wollte, nur um sicherzustellen, dass vorhandener Code keinen unsicheren Endpunkt verwendet, sondern um die Kompatibilität zu wahren.

Angesichts der Tatsache, dass beides nicht ideal ist ... wie können wir Sicherheitskorrekturen vorhersehen, die erfordern, dass eine öffentliche Funktion hart abgelehnt wird? (Wenn nicht, indem Sie den Entwickler mit einem Laufzeitprotokoll überraschen. Fatal ()?)

Für diejenigen, die den Commit dafür sehen möchten: https://github.com/microcosm-cc/bluemonday/commit/a5d7ef6b249a7c01e66856b585a359970f03502c

@Merovius Danke für die Klarstellung bei der Verwendung der Versionen 0.x. Wie Sie sagten, gibt es keine Garantien, auf die Sie sich verlassen können, wenn Sie eine Version vor 1.0 verwenden, und dass die Versionen 0.x in einigen Fällen ein Sonderfall sind. Wenn ich das richtig verstanden habe, gelten die skizzierten Regeln eigentlich überhaupt nicht für die Versionen 0.x. Meine Frage ist nur, ob es sinnvoll wäre, diese Unterscheidung auch im Code widerzuspiegeln - insbesondere bei der Benennung von Paketen. Wenn ein Paket beispielsweise nur Pakete ohne Version importiert, können Sie auf einen Blick erkennen, dass es auf instabilem Code aufbaut. Wenn alle Importe eine Version v1 enthalten, sehen Sie, dass stabile Versionen verwendet werden.

@buro9 Der Vorschlag schlägt vor, grob den go1-Kompatibilitätsgarantien zu folgen, die Ausnahmen für sicherheitsrelevante API-Brüche enthalten.

@kaikuehne Danke, das verdeutlicht dein Anliegen.

Es gibt eine Interaktion von Funktionen, über die ich mir Sorgen mache (vorausgesetzt, ich verstehe die Dinge richtig).

Wenn Sie ein Modul M haben, das verifizierte Versionen verwendet (wörtliche vN-Verzeichnisse in der Quelle, keine synthetischen Importpfadelemente, die von Tags abgeleitet sind), und Sie ein Programm P erstellen, das sich transitiv auf mehrere Hauptversionen von M stützt, wird das nicht der Fall sein müssen Sie in einigen Szenarien gegen die minimale Versionsauswahl verstoßen?

Angenommen, P hängt von den Hauptversionen 2, 3 und 4 von M ab. Für jede Hauptversion von M ist eine minimale vollständige Version angegeben. Da die Versionen von M den Quellcode für den ausdrücklichen Zweck gemeinsam nutzen, Dinge wie die transparente Verwendung der gleichen Typdefinition mit Typaliasnamen tun zu können, kann nur eine Kopie von M für alle drei Hauptversionen anstelle einer Kopie pro Hauptversion enthalten sein. Jede Wahl der vollständigen Version für eine Hauptversion legt die Wahl für die vollständige Version der anderen beiden Hauptversionen fest und könnte dazu führen, dass eine nicht minimale Version für eine oder beide der anderen Hauptversionen ausgewählt wird.

Wie geht vgo damit um? Könnte dies andere Probleme verursachen, als nur manchmal etwas weniger als minimal zu sein? (Wie zum Beispiel die Möglichkeit, versehentlich eine Reihe von Modulen zu konstruieren, die keine Lösung ergeben oder den Solver in eine Schleife versetzen?)

@jimmyfrasche

Wenn Sie Hauptversionsverzeichnisse verwenden, verwendet vgo weiterhin Tags und ruft dann nur den passenden Versionsordner dieses Tags ab. zB Sie sind abhängig von den Versionen 2, 3, 4. vgo checkt das Tag v2.nm, v3.nm, v4.nm aus
Und dann holen Sie sich vom Tag v2.nm nur den v2-Ordner und so weiter. Am Ende folgt also alles noch Tags.

Ich habe in diesem Mailinglisten-Beitrag eine Frage gestellt, aber keine konkrete Antwort gesehen. Ich wiederhole es hier:

Was passiert mit Nicht-Go-Ressourcen wie Protobufs oder C-Dateien? Entschuldigung, wenn dies bereits in Ihren Posts beantwortet wurde, aber wir verwenden den Herstellerpfad, um den Importpfad für Protobuf-Dateien zu verteilen und festzulegen. Während wir Go-Pakete gegen vorkompilierte Protobuf-Ausgabe kompilieren würden, müssen wir auch den Fall berücksichtigen, dass neue Go-Pakete aus Protobuf-Dateien kompiliert werden, die von Abhängigkeiten des Herstellers abhängig sind (dh Verweise auf rpc.Status aus einer anderen Protobuf-Datei). Ich kann einige konkretere Beispiele liefern, wenn diese Beschreibung zu dicht ist.

Insbesondere habe ich ein Projekt namens protobuild , das es ermöglicht, den Import von Protobuf-Dateien den GOPATH-Speicherorten zuzuordnen. Ich sehe nicht, wie dieser Vorschlag mit der Auflösung von Ressourcen in GOPATH umgehen wird und wie wir dies in andere Compiler-Importbereiche abbilden können.

Dies war für uns ein großer Schmerzpunkt bei der Arbeit mit Protobufs, und dieses Projekt hat viele dieser Probleme gelindert. Es wäre schade, wenn dies mit dem Vorschlag völlig unvereinbar wäre.

Nochmals Entschuldigung, falls ich etwas übersehen habe.

Ich liebe den Vorschlag. Ich mache mir nur Sorgen, dass zu viele Projekte häufig kleine Breaking Changes zwischen Minor-Versionen einführen und Major-Versionsbumps nur für sehr große Breaking Changes reservieren. Wenn häufig Breaking Changes in Minor-Versionen auftreten, treten Probleme mit der Diamond-Abhängigkeit auf, da dies gegen die Annahme von SIV verstößt. Ich frage mich, ob die Einbeziehung der Nebenversion in die Import-Anweisung mehr Projekten helfen würde, den Non-Breaking-Changes-Vertrag einzuhalten. Ich denke, Nachteile sind zusätzliche Importabwanderungen und das Aktualisieren von Nebenversionen wird schwieriger (und expliziter).

Dies wirft eine weitere Frage auf, die ich habe: Ist es (heute) mit vgo einfach festzustellen, ob Sie mehr als 1 Version eines Pakets in einem Build haben? Während es manchmal entscheidend ist, zwei Versionen desselben Pakets zuzulassen, um voranzukommen, scheinen die meisten Projekte dies vermeiden zu wollen, es sei denn, es handelt sich um vorübergehende Auswirkungen auf mögliche unvorhergesehene Nebenwirkungen von init. Eine einfache Möglichkeit, dies zu überprüfen, kann nützlich sein, und einige Projekte möchten dies möglicherweise beim Einchecken des Codes erzwingen.

Ich mache mir nur Sorgen, dass zu viele Projekte häufig kleine Breaking Changes zwischen Minor-Versionen einführen und Major-Versionsbumps nur für sehr große Breaking Changes reservieren.

Breaking Change ist ein Breaking Change. Es kann nicht klein oder groß sein. Ich nehme an, dass solche Pakete schließlich von der Community als zu unzuverlässig und nicht folgerichtig abgelehnt werden. Selbst wenn sie semver folgen und schnell zu großen Major-Nummern wie 42.xx gelangen, sind sie dennoch sehr umständlich zu verwenden. Wenn Sie also viele grundlegende Änderungen vornehmen möchten, verwenden Sie einfach weiterhin die Hauptnummer 0. Auf diese Weise funktioniert es weiterhin genau wie das aktuelle go get , mit denselben Problemen. Wenn Sie nach der Veröffentlichung der Nicht-0-Hauptversion mit der API experimentieren möchten, verschieben Sie diese Experimente in ein separates „experimentelles“ Paket mit der dauerhaften Hauptversion 0 und erhöhen Sie die Hauptversion des Hauptpakets, wenn Sie mit „kleinen Breaking Changes“ fertig sind, und erhalten Sie schließlich die nächste stabile API.

Das Einschließen von Minor in den Importpfad verstößt gegen die Semver-Ideologie und bietet keine neuen Funktionen gegenüber dem Einschließen von Major.

Obwohl ich verstehe, dass Autoren dies angesichts der Semantik von semver tun sollten , befürchte ich, dass geringfügige Breaking Changes zwischen Nebenversionen ein häufiger und verlockender Fall für jemanden sind, der bereits Version 1 hinter sich hat. Nach meiner anekdotischen Erfahrung tun Paketautoren dies nicht Folgen Sie der genauen Semantik von semver, und oft reservieren Unternehmen die Bumps der Hauptversionen für Marketingzwecke. Mein Appell bezieht sich also nicht darauf, was ideal ist, sondern darauf, ob es praktisch sein kann, bestimmte Änderungen vorzunehmen, um besser mit der chaotischen menschlichen Realität umzugehen, die Semver ist.

Vielleicht ist es sogar möglich, optional die Minor-Version für Pakete einzuschließen, die Semver nicht gehorchen, vielleicht vermasselt das den gesamten Vorschlag, ich müsste mehr darüber nachdenken. Ich schlage nicht vor, dass dies ein besserer Weg ist, nur weil ich daran interessiert bin, die Kompromisse weiter zu untersuchen, ob die Nebenversion optional in Importe aufgenommen oder deren Einbeziehung vorgeschrieben wird.

Es ist wahrscheinlich möglich, hier bessere Daten aus dem Go-Korpus (und einem Tool, das nach offensichtlichen Breaking Changes sucht) zu generieren, um festzustellen, wie oft Semver unter bestehenden populären Projekten, die Semver-Tags verwenden, am meisten befolgt wird.

Der vgo-Vorschlag ermöglicht es Hauptversionen, API-Änderungen ordnungsgemäß zu unterbrechen. Es (an sich) tut nichts, um sie zu verhindern.

Der vgo-Vorschlag ermöglicht es einer Hauptversion, auf eine andere Hauptversion zu verweisen, wodurch eine ordnungsgemäße Wiederverwendung von Code ermöglicht wird. Es tut nichts, um das zu erzwingen.

Der vgo MVS-Vorschlag ermöglicht die Aktualisierung auf neuere Pakete. Es zwingt Sie nicht, zu aktualisieren.


Hier sind Dinge, die wir in einer vgo-Welt viel einfacher bauen können:

  1. Tools zum Erfassen von API-Bremsänderungen vor dem Pushen an einen Modulhost. Jede Version ist in einer Zip-Datei und kann ohne viele verschiedene vcs-Tools und -Befehle verglichen werden.
  2. Registrierung von Sicherheitsproblemen. Hosten Sie neben dem Modul-Hosting für Mehrwert. Tools können sie ähnlich wie go list entweder manuell oder automatisch abfragen und werden über Probleme benachrichtigt, die durch eine Abfrage gefiltert werden.

vgo erleichtert dies durch:

  • Beschränken des Problembereichs (nur mit ZIP-Dateien arbeiten, keine Notwendigkeit, beliebige git/hg/svn-Verläufe zu speichern, um API-Vergleiche durchzuführen).

    • Definieren des Problemraums (MVS, Versionsdefinition)

  • Werkzeugbau des Bauabschnitts.

vgo arbeitet nach einem Hauptprinzip: Ein einzelner Satz von Eingaben sollte immer dasselbe erstellen. Wenn wir uns auf zufällige Rebuilds verlassen, um Sicherheitsupdates abzufangen , machen wir etwas falsch . Als Betreuer von Projekten laufen einige Go-Projekte einfach jahrelang ohne Neuaufbau. Ich stimme zu, dass zeitnahe Sicherheitsupdates wichtig sind: vgo erfüllt den Build-Teil dieses Bedarfs.

Wir sollten das, was vgo erlaubt, nicht mit dem verwechseln, was vgo ist.

@ pbx0 Ich bin mir nicht sicher, ob dies der richtige Ort für eine solche Diskussion ist, vielleicht ist die Mailliste besser geeignet. In jedem Fall kommt es zu Breaking Changes ohne Änderung der Major-Nummer. Sogar gelegentlich. Semver hat diesen Fall in FAQ beantwortet:

Sobald Sie feststellen, dass Sie gegen die Semantic Versioning-Spezifikation verstoßen haben, beheben Sie das Problem und veröffentlichen Sie eine neue Nebenversion, die das Problem behebt und die Abwärtskompatibilität wiederherstellt.

Aber ich denke, hier gibt es Verbesserungspotential. Ich nehme an, es sollte einfach genug sein, einen automatisierten API-Checker zu implementieren (vielleicht existiert sogar bereits einer), der alle auf godoc.org aufgelisteten Pakete nimmt und regelmäßig nach neuen Versionen sucht, und falls eine neue Version erkannt wird, überprüft, ob die neue Version mit der vorherigen kompatibel ist -Versions-API, falls sie Semver-Tags verwendet und Major nicht geändert wurde. Versuchen Sie dann, den Autor zu kontaktieren, falls eine inkompatible Änderung erkannt wird – möglicherweise automatisch geöffnete Probleme auf GitHub oder verwenden Sie die E-Mail vom GitHub-Konto. Dies wird nicht alle möglichen Fälle abdecken, kann aber für die Community sehr hilfreich sein.

Ich glaube fest daran, Pfade zu verwenden, um Hauptversionen zu erfassen, und wollte meine Unterstützung ausdrücken, FWIW.

Vor einem Jahr dachte ich, dass es hässlich, unerwünscht und wahrscheinlich vermeidbar sei, Versionen in solche Importpfade zu stecken. Aber im letzten Jahr habe ich verstanden, wie viel Klarheit und Einfachheit sie in das System bringen.

Vor fast zwanzig Jahren brauchte ich ein VCS für mein Startup und probierte ungefähr zehn verschiedene aus. Ich schloss Perforce sofort aus, weil es Branches mit Verzeichnissen offenlegte. Der v2-Zweig wäre also nur derselbe Code, aber unter einem v2-Ordner. Ich hasste diese Idee. Aber nachdem ich Pilotversuche mit den anderen neun durchgeführt hatte, stellte ich fest, dass ich oft beide Versionen eines Zweigs auf meinem lokalen Dateisystem haben wollte, und es stellte sich heraus, dass Perforce dies trivial einfach machte, während die anderen es überraschend kompliziert machten. Das Dateisystem ist unsere Containment-Metapher. Lass es uns benutzen.

Aus dem Vorschlag:

Definieren Sie ein URL-Schema zum Abrufen von Go-Modulen von Proxys, das sowohl zum Installieren von Modulen mit benutzerdefinierten Domänennamen als auch beim Festlegen der Umgebungsvariable $GOPROXY verwendet wird. Letzteres ermöglicht es Unternehmen und Einzelpersonen, alle Modul-Download-Anfragen aus Sicherheits-, Verfügbarkeits- oder anderen Gründen über einen Proxy zu senden.

Ich habe das an anderer Stelle erwähnt, aber meine größte Sorge bei dem Vorschlag ist, dass er eine der größten Stärken des heutigen Vendoring zu verwerfen scheint (oder zumindest nicht anspricht): immer verfügbarer Code und perfekt reproduzierbare Builds. Ich denke nicht, dass das vorgeschlagene Proxy-System diese Stärken angemessen adressiert oder ersetzt.

Ein Projekt, das heute Vendoring verwendet, benötigt nur die Go-Toolchain und Git (oder ein anderes Versionskontrollsystem). Es gibt nur einen einzigen Fehlerpunkt: das Git-Repository. Sobald der Code ausgecheckt ist, kann er perfekt erstellt und neu erstellt werden, ohne dass das Netzwerk erneut berührt werden muss – ein wichtiger Sicherheitsaspekt. Für die meisten von uns erfordert ein Vendoring-Projekt keine zusätzliche Infrastruktur – nur Ihren lokalen Computer und ein kostenloses GitHub-Konto.

Die Abhängigkeit von vgo von Proxys führt zu einem nicht unerheblichen Infrastruktur-Overhead, der meines Erachtens nicht ausreichend betont wird. Neue Infrastruktur muss bereitgestellt, implementiert, gewartet und überwacht werden. Dies mag für Software-Organisationen sinnvoll sein, ist jedoch eine Belastung für Einzelpersonen und dezentrale Open-Source-Projekte. Darüber hinaus werden Dinge wie CI oft an Dritte wie Travis CI ausgelagert, die nicht in derselben Infrastruktur wie die Entwicklungsumgebung des Unternehmens laufen. Dies erschwert die Wiederverwendung der Proxy-Infrastruktur.

Andere Sprachen erlauben die Verwendung von Caching-Proxys. Python ist diejenige, mit der ich die meiste Erfahrung habe, und meiner Erfahrung nach wird sie aufgrund des Aufwands für die Einrichtung selten verwendet. Vielleicht kann das Go-Projekt dies vereinfachen, aber wenn es nicht die Standardeinstellung ist, werden wir feststellen, dass es weniger oft verwendet wird und die Verfügbarkeit von Go-Builds in freier Wildbahn erheblich abnehmen wird. Die Auswirkungen des NPM-Ereignisses auf der linken Seite sind in dieser Hinsicht eine großartige Fallstudie.

Wenn das Modul- und Proxy-System es uns ermöglicht, Abhängigkeiten neben dem Code unseres eigenen Projekts einzuchecken (ähnlich wie heute, aber nicht unbedingt die gleiche Implementierung) und die Proxy-Implementierung vgo es verwenden kann, würde das meine Bedenken ausräumen. Aber wenn dies die Absicht ist, denke ich, dass dies viel umfassender in dem Vorschlag angegangen werden muss.

@joeshaw Sie können weiterhin ein Anbieterverzeichnis verwenden, um einen eigenständigen Build zu erstellen.

Aus dem Vorschlag:

Verbieten Sie die Verwendung von Anbieterverzeichnissen, außer in einer eingeschränkten Verwendung: Ein Anbieterverzeichnis an der Spitze der Dateistruktur des zu erstellenden Moduls der obersten Ebene wird weiterhin auf den Build angewendet, um weiterhin eigenständige Anwendungs-Repositories zuzulassen. (Das Ignorieren anderer Anbieterverzeichnisse stellt sicher, dass Go zu Builds zurückkehrt, in denen jeder Importpfad während des gesamten Builds dieselbe Bedeutung hat, und feststellt, dass nur eine Kopie eines Pakets mit einem bestimmten Importpfad in einem bestimmten Build verwendet wird.)

Ein Projekt, das heute Vendoring verwendet, benötigt nur die Go-Toolchain und Git (oder ein anderes Versionskontrollsystem). Es gibt nur einen einzigen Fehlerpunkt: das Git-Repository.

Wenn Sie heute Pakete unter Ihrer eigenen Domain hosten, müssen Sie a) das Git-Repository hosten und b) die <meta> -Tags bereitstellen, die für go-get erforderlich sind, um es zu finden. In Zukunft müssen Sie a) die Dateien .zip und .json bereitstellen, die für vgo zum Abrufen des Codes erforderlich sind. Es scheint weniger Fehlerquellen zu geben und es wird weniger Infrastruktur für reines Hosting benötigt. Natürlich müssen Sie das Repository weiterhin für die Entwicklung hosten, aber das bringt uns nicht nur im schlimmsten Fall auf das gleiche Niveau wie zuvor, das Repository selbst erfordert auch weit weniger skalierbares und zuverlässiges Hosting, da es nur von Leuten verwendet wird, die tatsächlich entwickeln.

Bei Eitelkeitsimporten scheint es also keinen großen Unterschied in Bezug auf den Overhead zu geben.

Wenn Sie, OTOH, keine Vanity-Importe verwenden, ignorieren Sie die gesamte Infrastruktur, die github für Sie betreibt. Das scheint also kein Vergleich von Apfel zu Apfel zu sein: Man gewinnt nur, weil man andere Leute die schwierigen Probleme lösen lässt. Aber nichts hindert Sie daran, dies in Zukunft zu tun. AIUI Microsoft und andere haben sich bereits bereit erklärt, Ingenieurstunden und Servicekapazitäten in diese Aufgabe zu investieren. Ich gehe davon aus, dass der Aufwand für das Hosten von Go-Paketen in Zukunft in etwa durch den Aufwand für das Hosten von npm-Paketen oder Gems oder Crates begrenzt wird: Sie haben ein Github-Repository und klicken dann auf einigen zentral auf die Schaltfläche „Dieses verfügbar machen“. Managed Service zum Hosten der Reißverschlüsse.

Abhängigkeit von vgo von Proxys

Ich persönlich mag das Wort „Proxy“ nicht für das, was die erforderliche Infrastruktur leistet. "Spiegel" scheint passender zu sein. Der Spiegel kann als Proxy implementiert werden, aber es kann auch nur ein Bündel von Dateien sein, die von einem Webserver Ihrer Wahl bereitgestellt werden, versteckt hinter Cloudflare für nahezu unbegrenzte Skalierbarkeit und Betriebszeit.

Andere Sprachen erlauben die Verwendung von Caching-Proxys.

Ich würde argumentieren, dass andere Sprachen als perfektes Modell dafür dienen, warum dies nicht wirklich ein Problem ist. Sie neigen dazu, sich auf zentralisiertes Hosting für ihre Pakete zu verlassen, um Pakete zu hosten - vgo unterstützt dieses Modell nicht nur außerordentlich gut, sondern macht es auch optional (so dass Sie alle Vorteile ohne die Nachteile erhalten) und sehr einfach zu implementieren, zu skalieren und zu betreiben.


IMO, wenn Sie direkt vergleichen, was vorher und nachher und in Go und in anderen Sprachen passiert, sollte klar sein, dass es viele 1: 1-Äquivalenzen gibt. Und der einzige Grund, warum es sich anfühlt , als wäre es in Zukunft mehr Aufwand, ist, weil wir die bestehende Infrastruktur als selbstverständlich ansehen und sehen, dass die neue Infrastruktur noch nicht existiert. Aber ich glaube nicht, dass wir gute Gründe haben, daran zu zweifeln.

Bei Eitelkeitsimporten scheint es also keinen großen Unterschied in Bezug auf den Overhead zu geben.

Stimmt, aber die _große_ Minderheit der Pakete verwendet Vanity-Domains, daher denke ich nicht, dass dies ein starker Kontrapunkt ist. (Ich habe auch andere praktische Probleme mit Vanity-Domains, nämlich dass ihre Verfügbarkeit tendenziell _viel schlechter_ ist als nur die Verwendung von GitHub.)

Wenn Sie, OTOH, keine Vanity-Importe verwenden, ignorieren Sie die gesamte Infrastruktur, die github für Sie betreibt.

Ja genau! Ich fühle, dass dies meinen Punkt für mich macht. Sie erhalten all diese wunderbare Arbeit an der Infrastruktur und der Aufrechterhaltung der Betriebszeit kostenlos oder zu einem angemessenen Preis. Noch wichtiger ist, dass es keine Ihrer eigenen Zeit in Anspruch nimmt.

Wenn GitHub am Ende einen vgo -kompatiblen Spiegel laufen lässt, dann ist das vielleicht weniger besorgniserregend, obwohl ich die Eleganz eines einzelnen Git-Abrufs mag – eine atomare Aktion aus der Sicht des Benutzers – die den gesamten Code enthält Ich muss ein Projekt erstellen.

Ich würde argumentieren, dass andere Sprachen als perfektes Modell dafür dienen, warum dies nicht wirklich ein Problem ist. Sie neigen dazu, sich auf zentralisiertes Hosting für ihre Pakete zu verlassen, um Pakete zu hosten - vgo unterstützt dieses Modell nicht nur außerordentlich gut, sondern macht es auch optional (so dass Sie alle Vorteile ohne die Nachteile erhalten) und sehr einfach zu implementieren, zu skalieren und arbeiten.

Das Problem ist, dass dadurch Single Points of Failure (SPOFs) zum Erstellen eines Projekts hinzugefügt werden. Der Code wird in jedem Fall in einem VCS (und wahrscheinlich GitHub) leben, also ist das ein SPOF. In anderen Sprachen ist ein zentrales Repository ein zweiter SPOF. Für Go ist jeder Importpfad ein zusätzlicher SPOF (github.com, golang.org, honnef.co, rsc.io usw.) und die Erhöhung der SPOFs verringert die Gesamtverfügbarkeit.

Das Ausführen eines Spiegels kann das zwar auf zwei reduzieren, aber es ist eine Infrastruktur, von der ich behaupte, dass sie nicht existieren muss. Wenn Sie Ihre Deps verkaufen (oder einen lokalen On-Disk-Spiegel haben), reduziert sich dies auf nur eines: Ihr VCS.

In jedem Fall kann dies ein strittiger Punkt sein. Ich habe ursprünglich den Teil des Vorschlags über das vendor -Verzeichnis der obersten Ebene nicht verstanden, der meine Hauptbedenken zu lösen scheint - danke für den Hinweis, @kardianos -, obwohl es eine saubere Abkehr vom Alten ist Verkäufersystem könnte schöner sein.

Ich bin froh, dass "Top-Level vendor " immer noch eine unterstützte Konfiguration sein wird, weil ich git grep so sehr liebe.

Das Ausführen eines Spiegels kann das zwar auf zwei reduzieren, aber es ist eine Infrastruktur, von der ich behaupte, dass sie nicht existieren muss.

Unternehmensentwickler hier. Vielleicht sind wir nicht die demografische Zielgruppe, aber wir würden gerne Go verwenden. Ich kann mir nicht vorstellen, dass dies geschieht, ohne dass wir einen Spiegel in unserem Unternehmen haben, wie wir es für Java und Javascript tun, um sicherzustellen, dass alles, was wir heute bauen, auch morgen gebaut werden kann.

Unternehmensentwickler hier. Vielleicht sind wir nicht die demografische Zielgruppe, aber wir würden gerne Go verwenden. Ich kann mir nicht vorstellen, dass dies geschieht, ohne dass wir einen Spiegel in unserem Unternehmen haben, wie wir es für Java und Javascript tun, um sicherzustellen, dass alles, was wir heute bauen, auch morgen gebaut werden kann.

@jamiethermo Spricht Vendoring das heute nicht für Sie an?

Die Unterstützung für Proxys oder Mirrors ist in Ordnung, und wenn das der Einführung von Go hilft, bin ich dafür. Mir ging es um Mirrors als Ersatz für lokale, in sich geschlossene Quellbäume (was wir heute Vendoring nennen).

@joeshaw

Geht Vendoring das heute nicht für Sie an?

Nun, ich muss Unwissenheit und eine gewisse Frustration mit "Wie soll ich meinen Code organisieren" gestehen. Meinen Sie mit „eigenständiger Quellbaum“, dass ich ein riesiges Git-Repo habe, das meinen gesamten Code sowie den gesamten Code im Anbieterbaum enthält? Ich brauche also keinen Spiegel, weil ich all diesen anderen Code in mein eigenes Repo eingecheckt habe?

In Bezug auf "wie soll ich meinen Code organisieren" gibt diese Seite, How to Write Go Code , Anweisungen zur Verzeichnisstruktur, erwähnt jedoch nicht den Anbieter.

Führen Sie eine semantische Importversionierung ein, bei der jede Hauptversion einen eigenen Importpfad hat. Insbesondere enthält ein Importpfad einen Modulpfad, eine Versionsnummer und den Pfad zu einem bestimmten Paket innerhalb des Moduls. Wenn die Hauptversion v0 oder v1 ist, muss das Versionsnummernelement weggelassen werden; andernfalls muss es enthalten sein.

Die als my/thing/sub/pkg , my/thing/v2/sub/pkg und my/thing/v3/sub/pkg importierten Pakete stammen aus den Hauptversionen v1 , v2 und v3 des Moduls my/thing, but der Build behandelt sie einfach als drei verschiedene Pakete.

my/thing/sub/pkg kann auch v0 sein.

Ich habe die Tour verfolgt. Das Beispiel wurde außerhalb des GOPATH-Baums erstellt und funktioniert, während dep init in dieser Situation barf. Ich arbeite jetzt mit, glaube ich, 80 Teams, und es wäre wirklich schön, nicht einen riesigen Baum haben zu müssen. (Während ich dies tippte, kam jemand mit seinem Laptop und einem finsteren Gesicht und „Ich habe diesen wirklich seltsamen Fehler …“)

@joeshaw

Sie erhalten all diese wunderbare Arbeit an der Infrastruktur und der Aufrechterhaltung der Betriebszeit kostenlos oder zu einem angemessenen Preis.

Das habe ich schlecht formuliert. Ich wollte sagen: "Wenn Sie behaupten, dass Sie früher weniger Infrastruktur benötigten, wenn Sie keine Eitelkeitsimporte verwenden, ignorieren Sie alle Infrastruktur-Github-Läufe für Sie". Ich wollte darauf hinweisen, dass die Infrastruktur immer noch da ist und noch laufen muss. Und es kann auch in Zukunft für Sie weitergeführt werden.

Ihre Bedenken würden also in dem meiner Meinung nach wahrscheinlichsten Szenario angesprochen: Dass eine finanzierte Stelle (derzeit entwickelt sich Microsoft dazu) das Hosting der Zip-Dateien übernimmt.

obwohl ich die Eleganz eines einzelnen Git-Abrufs mag – eine atomare Aktion aus der Sicht des Benutzers

vgo get ist genauso eine atomare Aktion und macht weniger Arbeit, von der gleichen Art (HTTP-Anfragen), die leichter zu verstehen ist.

Das Problem ist, dass dadurch Single Points of Failure (SPOFs) zum Erstellen eines Projekts hinzugefügt werden.

Wo ist mein letzter Kommentar dann falsch? Da es mir ziemlich offensichtlich erscheint, dass die Anzahl der Fehlerpunkte, wenn überhaupt, geringer ist, sind sie einfacher, einfacher zu skalieren und billiger zu betreiben.

In anderen Sprachen ist ein zentrales Repository ein zweiter SPOF. Für Go ist jeder Importpfad ein zusätzlicher SPOF (github.com, golang.org, honnef.co, rsc.io usw.) und die Erhöhung der SPOFs verringert die Gesamtverfügbarkeit.

Ich denke, das ist zu stark vereinfacht. Wenn Sie Ihren Code auf einem Spiegel hosten, der ausfällt, können Sie immer noch entwickeln (Github ist immer noch aktiv) und Benutzer können möglicherweise immer noch installieren (indem Sie einen anderen Spiegel verwenden). Der Host einer Ihrer Abhängigkeiten, der ausfällt, spielt keine Rolle, da Sie Ihre Abhängigkeiten spiegeln. Wenn Sie nicht darauf vertrauen, dass der "zentralisierte" Community-Mirror aktiv bleibt, können Sie Ihren eigenen betreiben oder jemanden dafür bezahlen, ohne Unterschied für die Benutzer, wodurch Sie die volle Kontrolle darüber haben, wie stark Sie von Ausfallzeiten betroffen sind das zentralisierte Repo.

Keines der Dinge, die Sie erwähnen, ist tatsächlich ein SPOF, da Sie immer noch mindestens einen eingeschränkten Betrieb erhalten. Hinzu kommt, dass die eigentlichen Spiegel vergleichsweise einfach zu bedienen sind (da es sich nur um zustandslose HTTP-Server handelt) und ich nicht überzeugt bin, dass Zuverlässigkeit und Verfügbarkeit erheblich abnehmen würden.

Und FTR, im Moment ist Ihr Git-Hosting ein SPOF: Wenn Ihr Git-Host ausfällt, können Benutzer nicht installieren und Sie können nicht entwickeln.

Das Ausführen eines Spiegels kann das zwar auf zwei reduzieren, aber es ist eine Infrastruktur, von der ich behaupte, dass sie nicht existieren muss.

Und mein (schlecht formulierter) Punkt oben war, dass es das bereits tut :) Du ignorierst einfach a) dass es jetzt passiert und b) gehst davon aus, dass es in Zukunft nicht passieren wird :)

Um eine andere Perspektive zu geben:

  • Wir erstellen viele Go-Projekte mit unserem systemweiten, sprachübergreifenden Softwarekomponenten-Manager (rpm/dnf auf Fedora, Centos und RHEL).
  • Es ermöglicht uns, viele der gleichen Tricks wie der vgo-Vorschlag zu verwenden, indem wir mit dem Namensraum der RPM-Schichtkomponente spielen (normalerweise das Umbenennen eines Projekts auf RPM-Namensraumebene von project in compat-project-x, um die Unterscheidung zwischen inkompatiblen Versionen der gleichen Importpfad, genau wie es vgo tun wird).
  • Diese Tricks sind definitiv nützlich, um komplexe Go-Projekte zu erstellen
  • obwohl es nicht so vollständig und robust ist wie auf Sprachebene
  • Wir würden Sprachbeschränkungen lieber an rpm/dnf weitergeben, als eine rpm/dnf-Überlagerung von Beschränkungen über den ursprünglichen Code hinzuzufügen.
  • Wir haben die Nase voll von all den Dateisystem-Workarounds, die derzeit erforderlich sind, um Go-Tools davon zu überzeugen, sich Go-Projektquellen anzusehen. Der physische GOPATH wird auf keinen Fall fehlen.

Daher sind wir von vgo begeistert und hoffen, dass es bald zum Einsatz kommt (wir brauchten es vor Jahren).

Davon abgesehen hat unsere Verwendung von vgo-ähnlichen Workflows die folgenden Schwierigkeiten aufgeworfen.

Der vgo-Vorschlag gratuliert sich selbst dazu, Makefiles überflüssig gemacht zu haben. Das ist nicht ganz richtig.

  • Viele Go-Projekte haben sich in automatisch generierte Go-Dateien verliebt, und es gibt keinen Standardweg in Go, um zu verlangen, diese neu zu generieren oder auszudrücken, was die Generierung erfolgreich sein muss
  • Es ist so schlimm, dass viele Projekte mit vorgenerierten Dateien ausgeliefert werden müssen (manchmal bilden sie komplette separate Repositories für vorgenerierte Dateien).
  • Diese Dateien sind eine große Quelle für Versionsinkompatibilitäten. Menschen achten darauf, Code zu schreiben, der nicht jeden Tag geändert werden muss, wenn er neuen Abhängigkeitsversionen ausgesetzt wird. Automatisch generierte Dateien OTOH sind oft eng mit einer genauen Generierungsumgebung verknüpft, da die Autoren von Generator-Tools davon ausgehen, dass Sie sie einfach nach Bedarf neu generieren.
  • Damit vgo erfolgreich ist, muss es eine Möglichkeit finden, diese Dateien zu identifizieren, sie aus .zip-Modulen zu entfernen und den Benutzern der .zip-Module mitzuteilen, wie sie neu generiert werden können

Verschärft wird dies durch die aktuelle „alles muss in GOPATH“-Regel

  • alles kann nicht in GOPATH sein, wenn die Generierung von Proto-Dateien abhängt, die außerhalb von GOPATH von mehrsprachigen Projekten veröffentlicht werden
  • Die Go-Toolchain muss lernen, Ressourcen außerhalb ihres GOPATH zu lesen
  • Die Go-Toolchain muss lernen, Ressourcen außerhalb von GOPATH zu veröffentlichen, wenn sie Projekten ausgesetzt sind, die nicht unbedingt in Go geschrieben wurden
  • Die aktuelle Problemumgehung zum Duplizieren von Ressourcen in Kopien mit GOPATH ist eine weitere Quelle für Versionsinkompatibilitäten
  • nicht jeder wird die gleichen Dateien gleichzeitig kopieren
  • Manchmal kopieren Projekte aus mehreren Quellen und erstellen so einzigartige Mischungen.
  • Jedes Projekt wird auf seiner eigenen Kopie einer Qualitätssicherung unterzogen, was die Go-Projektzusammenstellung gefährlich macht
  • Der vgo-Versionslöser funktioniert nicht wie beabsichtigt, wenn er Beziehungen zwischen Codeversionen berechnet, aber Beziehungen zwischen Ressourcenversionen ignoriert.
  • vgo muss private Kopien von Dingen, die außerhalb von GOPATH veröffentlicht werden, unnötig machen, um eine Explosion inkompatibler Modulversionen zu vermeiden.

Viele Projekte haben die Regel "Jedes Go-Verzeichnis ist ein separates Paket" ausgenutzt, um Projekte mit inkompatiblem oder vollständig kaputtem Code in separaten Unterverzeichnissen zu veröffentlichen

  • Viele andere Go-Projekte haben die gleiche Regel verwendet, um bestimmte Unterverzeichnisse herauszupicken und sie in einem Kontext zu verwenden, der mit den Komponententests und QA des ursprünglichen Projekts nicht kompatibel ist
  • das "funktioniert" und "reproduzierbare Builds" erzeugt, solange keine Änderung im ursprünglichen Projekt oder im Projektverbraucher einen anderen Teil des ursprünglichen Projekts verwendet. Wenn das passiert, bröckelt die ganze Sandburg unter der angehäuften technischen Schuld,
  • Sie sehen Projekte, die sich weigern, auf neuere Projektversionen zu aktualisieren, weil dies die Bereinigung ihres früheren Missbrauchs anderer Projekte erfordert.
  • Sie haben eine seltsame Schizophrenie, bei der Go-Projekte sich für nicht verantwortlich für Fehler in den Codebasen halten, die sie wiederverwenden, und sich gleichzeitig weigern, die von denselben Codebasen veröffentlichten Korrekturen anzuwenden (ich denke, wir sind alle Menschen und unangenehme Realitätsverleugnung ist fest verdrahtet im menschlichen Gehirn)
  • Korrekturen werden nicht weitergegeben, und alles ist „in Ordnung“, bis Sie die Fehler gefunden haben, die die Korrekturen überhaupt erforderten, oder die Komponententests, die durch Rosinenpickerei ungültig wurden.
  • Ein automatisierter Sicherheitsprüfer, der den Sicherheitsstatus von Projekten mit dem Sicherheitsstatus derselben Projekte in den Anbieterverzeichnissen vergleicht, hätte einen großen Tag
  • Je größer das Projekt, desto wahrscheinlicher ist es, dass solche tickenden Bomben in seinem Verkaufsraum versteckt sind
  • Durch die klare Definition von Projektgrenzen innerhalb von Zip-Modulen setzt vgo solchen Praktiken ein Ende
  • Es wird jedoch auch eine umfassende Bereinigung vieler Go-Codebasen mit sich bringen
  • Damit vgo erfolgreich ist, muss es Tools bereitstellen, die bestehenden Go-Projekten beim Refactoring helfen und ihre Codebasis in Module aufteilen, die aus Sicht der Softwarekompatibilität sinnvoll sind. Andernfalls werden Projekte, die vgo verwenden, entweder unvereinbare Einschränkungen erzeugen oder einfach den Status quo sperren (was für bestehenden Code funktioniert, aber aus Sicht der Codeentwicklung schrecklich ist).

Die derzeitige Praxis, die gesamte Go-Codebasis in einem einzigen GOPATH-Baum mit geringen Grenzen zwischen den Projekten bereitzustellen, hat zu schädlichen Nebenwirkungen eines Software-Engineering POW geführt

  • Code wird nicht in dem Projekt festgeschrieben, wo es technisch sinnvoll ist, sondern in dem für den Code-Autor bequemsten Repo (dem Repo, auf das er Zugriff hat)
  • Go-Projekte fließen ineinander über, wobei Teile eines Projekts von Teilen eines anderen Projekts abhängen und Teile dieses anderen Projekts von dem ursprünglichen Projekt abhängen
  • die affektiv gesperrte Versionseinschränkungsgraphen erzeugt, in denen Sie einen Teil nicht verschieben können, ohne alle anderen zu verschieben
  • Niemand hat die Ressourcen, um alle anderen in einem einzigen Vorgang zu ändern
  • Projekte festgefahren und nicht mehr vorankommen
  • Die Verwendung von Modulen mit klaren Grenzen und der Versuch, Versionseinschränkungen zwischen Modulen explizit zu machen, wird diese Situationen aufdecken
  • das wird massiv unbeliebt sein (obwohl das Problem heute existiert, versteckt unter dem Schleier des Verkaufs)
  • oft geht es nicht nur darum, ein Unterverzeichnis zu trennen: Das Problem Projektabhängigkeiten kann in einem A/B/C/D-Verzeichnisbaum auf A- und D-Ebene auftreten, aber nicht auf B und C.
  • Damit vgo erfolgreich ist, muss es Tools bereitstellen, die bestehenden Go-Projekten beim Refactoring helfen und ihre Codebasen in separate Module aufteilen, die Abhängigkeitsdiagrammlinien folgen

Testfing/fixtures, example und testdata sind eine ganz andere Dose von Würmern mit ihren eigenen Anforderungen an Abhängigkeiten und Abhängigkeitsversionen

  • Sie müssen auf die eine oder andere Weise in separaten Modulen isoliert werden, oder ihre Anforderungen vergiften die Solver-Versionsauflösung
  • Wenn Sie ihre Bedürfnisse ignorieren, entscheiden Sie effektiv, dass niemand außer dem ursprünglichen Projekt Komponententests durchführt
  • Dies ist ziemlich gefährlich, wenn Sie Versions-Upgrades zulassen. Probleme werden passieren. Sie müssen sie erkennen
  • Integrationstests, die nicht nur von anderem Code abhängen, sondern von einer bestimmten Umgebung, die niemand außer dem ursprünglichen Projekt replizieren kann (z. B. ein bestimmter Server oder eine bestimmte Website, mit der kommuniziert werden soll), benötigen wahrscheinlich eine bestimmte Isolierung

Ich habe wahrscheinlich noch viel mehr Dinge vergessen, aber das sind die kritischsten.

Zuletzt:

  • Go-Projekte leben nicht isoliert
  • Einige Go-Projekte veröffentlichen Konnektoren für andere Sprachen
  • Einige Projekte in anderen Sprachen veröffentlichen Go-Konnektoren
  • das macht es zu einem Problem, semver anders zu behandeln als diese anderen Sprachen.
  • Sie können nicht alles außer dem Go-Teil auf die neueste Nebenversion aktualisieren lassen, wenn ein mehrsprachiges Projekt veröffentlicht wird.
  • das wäre die Hölle von einem Kriegsgefangenen des operativen Managements.
  • Das automatische Upgrade auf die neueste Unterversion spielt eine große Rolle bei der Vereinfachung von Softwareeinschränkungsgraphen, indem jeder ältere Versionen vakuumiert (der Vorteil ist technischer, der Mechanismus ist sozial).
  • High-Fidelity-Rebuilds ähneln pixelgenauen Websites. Sie sehen aus wie eine offensichtlich gute Idee, sie belohnen das Ego des ursprünglichen Autors, aber sie sind eine PITA für jeden, der tatsächlich versucht, das Ergebnis zu verwenden, weil sie nicht entwicklungsfähig und an den lokalen (nicht ursprünglichen) Kontext anpassbar sind.

Auf Proxy-Servern:

zum einfachen Debuggen kann $GOPROXY sogar eine file:/// URL sein, die auf einen lokalen Baum zeigt.

Bitte sorgen Sie dafür, dass es mit einer file:/// von https:/// URL funktioniert, die auf ein Verzeichnis verweist, das Module von Drittanbietern in einer Zip-Form enthält (und schließen Sie alles andere aus).

Dies ist der einfachste Weg für eine Einheit, die Arbeit mehrerer Entwicklungsteams zu koordinieren, die sich auf Teilmengen derselben Liste von Drittanbieterprojekten stützen: einen QA-/Rechts-/Sicherheitsmitarbeiter haben, der für die Überprüfung „guter“ Releases von Drittanbietern und deren Bereitstellung verantwortlich ist in einem gemeinsamen Verzeichnis und lassen alle anderen ihre Arbeit von den Modulen abhängen, die in diesem gemeinsamen Verzeichnis verfügbar sind.

Auf diese Weise können Sie sicher sein, dass niemand mit der Arbeit an einer Version beginnt, die mit der Arbeit anderer nicht kompatibel ist, und niemand bei einer fehlerhaften oder gefährlichen Version bleibt, die bereits von einem anderen Team identifiziert wurde, und Ihre Entwicklungsstationen nicht ständig auf den Download derselben Kopien warten von bereits lokal verfügbarer Software.

@Merovius Ich bin anderer Meinung, aber ich denke, wir schweifen vom Thema ab und wollen die Themendiskussion nicht verzetteln. Ich freue mich jedoch, in einem anderen Medium weiterzumachen. (Meine E-Mail ist in meinem Github-Profil und ich bin Joeshaw auf dem Gophers-Slack.)

https://github.com/golang/go/issues/24301#issuecomment -374882685, @tpng :

Welche Zeitzone wird für den Zeitstempel in der Pseudo-Version (v0.0.0-yyyymmddhhmmss-commit) verwendet?

Wie Sie in Ihrer Bearbeitung angemerkt haben, UTC. Beachten Sie aber auch, dass Sie diese niemals eingeben müssen. Sie können einfach einen Git-Commit-Hash (Präfix) eingeben und vgo berechnet und ersetzt die richtige Pseudo-Version.

https://github.com/golang/go/issues/24301#issuecomment -374907338, @AlexRouSg :

Werden Sie sich mit C-Abhängigkeiten befassen?

https://github.com/golang/go/issues/24301#issuecomment -376606788, @stevvooe :

Was passiert mit Nicht-Go-Ressourcen wie Protobufs oder C-Dateien?

https://github.com/golang/go/issues/24301#issuecomment -377186949, @nim-nim:

Der vgo-Vorschlag gratuliert sich selbst dazu, Makefiles überflüssig gemacht zu haben. Das ist nicht ganz richtig. [Diskussion des generierten Codes.]

Non-Go-Entwicklung ist weiterhin kein Ziel des go -Befehls, daher wird es keine Unterstützung für die Verwaltung von C-Bibliotheken und dergleichen geben, noch wird es explizite Unterstützung für Protokollpuffer geben.

Allerdings verstehen wir sicherlich, dass die Verwendung von Protokollpuffern mit Go zu schwierig ist, und wir möchten, dass dies separat behandelt wird.

Was den generierten Code im Allgemeinen betrifft, so ist ein echtes sprachübergreifendes Build-System die Antwort, insbesondere weil wir nicht möchten, dass jeder Benutzer die richtigen Generatoren installiert haben muss. Besser für den Autor, die Generatoren laufen zu lassen und das Ergebnis einzuchecken.

https://github.com/golang/go/issues/24301#issuecomment -375248753, @mrkanister :

Ich weiß, dass der Standard-Branch von Master auf v2 geändert werden kann, aber das lässt mich immer noch mit der Aufgabe zurück, das jedes Mal zu aktualisieren, wenn ich eine neue Hauptversion veröffentliche. Ich persönlich hätte lieber einen Master- und einen v1-Zweig, aber ich bin mir nicht sicher, wie genau das zu dem Vorschlag passen würde.

Wie @AlexRouSg und vielleicht andere darauf hingewiesen haben, können Sie dies tun. Ich wollte nur ihre Antworten bestätigen. Ich werde dies auch in die FAQ aufnehmen.

https://github.com/golang/go/issues/24301#issuecomment -375989173, @aarondl :

Obwohl das jetzt funktioniert, ist es beabsichtigt?

Absolut ja.

@jamiethermo , vielen Dank für den Kommentar zu Perforce und Zweigen in verschiedenen Verzeichnissen. Ich hatte diese Funktion vergessen, aber vielleicht hat mich das davon überzeugt, dass es wichtig ist, in vgo zuzulassen.

Beginnend bei https://github.com/golang/go/issues/24301#issuecomment -376925845 gab es eine nette Diskussion über Vendoring im Vergleich zu Proxys. Hier gibt es eindeutig zwei unterschiedliche Gruppen von Bedenken.

Open-Source-Entwickler neigen dazu, es zu vermeiden, sich auf die Infrastruktur zu verlassen, also wollen sie Anbieter, wie @joeshaw schrieb. Zur Bestätigung werden wir dies in eingeschränkter Form am Laufen halten (nur das Vendor-Verzeichnis auf der obersten Ebene des gesamten Target-Moduls, in dem Sie go-Befehle ausführen).

Unternehmensentwickler haben kein Problem damit, sich auf die Infrastruktur zu verlassen – das ist nur ein weiterer Kostenfaktor – insbesondere, wenn dies zu einer größeren Kostensenkung führt, z. B. wenn sie nicht den gesamten bereitgestellten Code in jedem Repo duplizieren und Zeit damit verbringen müssen, alles synchron zu halten. Im Grunde möchte jedes Unternehmen, mit dem wir gesprochen haben, Proxys/Mirrors, nicht Vendoring, wie es @jamiethermo gefordert hat. Wir sorgen dafür, dass das auch funktioniert.

Wir möchten auch unbedingt ein gemeinsames Spiegelnetzwerk aufbauen, dem Entwickler vertrauen und auf das sie sich verlassen können, damit alle Open-Source-Entwickler nicht das Gefühl haben, dass sie Anbieter sein müssen. Aber das ist später. Zuerst muss vgo zu go werden.

https://github.com/golang/go/issues/24301#issuecomment -377220411, @nim-nim:

Bitte sorgen Sie dafür, dass es mit einer file:/// von https:/// URL funktioniert, die auf ein Verzeichnis verweist, das Module von Drittanbietern in einer Zip-Form enthält (und schließen Sie alles andere aus).

Ich bin mir nicht ganz sicher, wonach Sie fragen, wenn Sie sagen, "alles andere ausschließen". Wenn $GOPROXY gesetzt ist, fragt vgo diesen Proxy. Es fällt nie irgendwo anders zurück. Dieser Proxy kann von einem statischen Dateibaum bereitgestellt werden, bei dem es sich hauptsächlich um Module von Drittanbietern in ZIP-Form handelt. Der Dateibaum muss jedoch auch einige andere Metadatendateien für die Navigation und Suche enthalten. Diese zusätzlichen Dateien sind unvermeidlich, da HTTP uns keine Standardmethode für Dinge wie Verzeichnislisten bietet.

https://github.com/golang/go/issues/24301#issuecomment -377186949, @nim-nim:

Wow, das ist ein langer Kommentar. Ich denke, ich stimme dem meisten von dem zu, was du geschrieben hast. Ich möchte auf den letzten Punkt in Ihrem Beitrag antworten:

  • High-Fidelity-Rebuilds ähneln pixelgenauen Websites. Sie sehen aus wie eine offensichtlich gute Idee, sie belohnen das Ego des ursprünglichen Autors, aber sie sind eine PITA für jeden, der tatsächlich versucht, das Ergebnis zu verwenden, weil sie nicht entwicklungsfähig und an den lokalen (nicht ursprünglichen) Kontext anpassbar sind.

Ich denke, ich würde argumentieren, dass Sperrdateien wie pixelgenaue Websites sind. Im Gegensatz dazu werden High-Fidelity-Builds elegant degradiert, wenn sich der Kontext ändert. Standardmäßig verwendet ein Build beispielsweise B 1.2 und C 1.4. Aber wenn es dann Teil eines größeren Builds ist, das B 1.3 benötigt, gut, wird es mit B 1.3 auskommen, aber C 1.4 behalten (auch wenn neuere existieren), wenn keine konkrete Anforderung für ein Upgrade besteht. Wirklich High-Fidelity-Builds sind also das Beste aus beiden Welten: So weit wie möglich dem Original treu bleiben, aber nicht auf Pixelperfektion bestehen, wenn dies nicht möglich ist.

https://github.com/golang/go/issues/24301#issuecomment -375415904, @flibustenet :

@rsc Ich möchte Sie bitten, die Roadmap genauer zu beschreiben und was wir jetzt tun sollten.
Wird es der Go-Richtlinie folgen und vgo nach 3 Monaten (jetzt 2) einfrieren?

Vgo ist ein Prototyp und wird niemals alleine veröffentlicht. Es unterliegt nicht dem Einfrieren oder irgendetwas anderem. Aber dieser Vorschlag besteht darin, die Ideen und den größten Teil des Codes in das Haupt-cmd/go zu verschieben. Im Rahmen des Releases unterliegt cmd/go sicherlich dem Freeze. Da es sich um ein Opt-in handelt und der vgo-spezifische Code ziemlich gut vom Rest der Operation des go-Befehls isoliert ist, ist die Arbeit an vgo-spezifischen Teilen ziemlich risikoarm, und ich könnte sehen, dass ein wenig davon für ein paar Wochen fortgesetzt wird ins Einfrieren. Im Moment konzentriere ich mich auf die Angebotsdiskussion und Anpassungen. Sobald der Vorschlag ohne nennenswerte Probleme in gutem Zustand zu sein scheint, wenden wir uns dem Verschieben von Code in cmd/go zu.

Sollten wir jetzt mit unserem Pilgerstock weitermachen und jeden Betreuer von Bibliotheken bitten, eine go.mod-Datei hinzuzufügen, oder sollten wir warten, bis der Vorschlag offiziell akzeptiert wird (um sicherzugehen, dass sich Name und Syntax nicht ändern)?

Ich denke, dass sich die go.mod-Syntax wahrscheinlich ändern wird (beachten Sie diese Ausgabe). Aber wie ich im Vorschlag angemerkt habe, werden wir alte Syntaxen für immer akzeptieren, und vgo wird nur vorhandene Dateien aktualisieren, also ist es keine große Sache. Allerdings würde ich nicht versuchen, PRs an jede Bibliothek zu senden, die Sie finden können, bis der Code in der Entwicklungskopie von cmd/go landet.

https://github.com/golang/go/issues/24301#issuecomment -376640804, @pbx0 :

Ist es (heute) mit vgo einfach festzustellen, ob Sie mehr als 1 Version eines Pakets in einem Build haben?

Am einfachsten ist es heute, die Binärdatei zu erstellen und dann goversion -m darauf auszuführen (siehe https://research.swtch.com/vgo-repro). Wenn wir eine allgemeinere modulbewusste Go-Liste haben, sollte sie in der Lage sein, dasselbe zu tun, ohne zuerst die Binärdatei zu erstellen.

https://github.com/golang/go/issues/24301#issuecomment -376236546, @buro9 :

[Kann ich eine rückwärtsinkompatible Sicherheitsänderung vornehmen, wie microcosm-cc/ bluemonday@a5d7ef6? ]

Wie @Merovius sagte, wenn wir die Go 1-Kompatibilitätsrichtlinien übernehmen sollen, sind Sicherheitsänderungen ausdrücklich erlaubt, ohne die Hauptversion zu beeinträchtigen.

Das heißt, selbst wenn Sie etwas für die Sicherheit tun müssen, sollten Sie wahrscheinlich immer noch nach minimalen Störungen streben. Das Commit, mit dem Sie verknüpft sind, ist wohl störender als nötig, und in einer zukünftigen Situation würde ich Sie ermutigen, eine solche Änderung unter dem Gesichtspunkt anzugehen: „Wie kann ich so wenige Clients wie möglich beschädigen und gleichzeitig das Sicherheitsproblem beseitigen? "

Entfernen Sie beispielsweise keine Funktion. Machen Sie die Funktion stattdessen nur dann panisch oder log.Fatal, wenn sie unsachgemäß aufgerufen wird.

In diesem Fall hätte ich AllowDocType beibehalten, anstatt AllowDocType zu löschen, und AllowDocType (false) auf jeden Fall weiterhin akzeptiert, da dies die sichere Einstellung ist. Wenn jemand einen Wrapper für Ihre Bibliothek geschrieben hätte, vielleicht als Befehlszeilenprogramm mit einem -allowdoctype-Flag, dann würde zumindest die Verwendung des Programms ohne dieses Flag weiterhin funktionieren.

Und darüber hinaus scheint es, als ob die Sorge darin bestand, dass der Doctype völlig ungeprüft war, aber ich hätte wahrscheinlich nur eine minimale Überprüfung vorgenommen, um die häufigsten Verwendungen aufrechtzuerhalten, und dann andere konservativ abgelehnt. Zum Beispiel hätte ich zumindest weiterhin zugelassen und vielleicht auch die Mühe gemacht, ..> mit Zeichenfolgen in Anführungszeichen ohne &#<>\ Zeichen zuzulassen.

https://github.com/golang/go/issues/24301#issuecomment -375090551, @TocarIP :

[Bedenken, Updates nicht umgehend zu erhalten.]

Ich denke wirklich, dass das Gegenteil passieren wird, dass Programme aktueller sein könnten, da es bei der minimalen Versionsauswahl für eine Abhängigkeit _unmöglich_ ist, zu verhindern, dass der gesamte Build auf eine neuere Version aktualisiert wird.

Was @Merovius in https://github.com/golang/go/issues/24301#issuecomment -375992900 geschrieben hat, klingt für mich genau richtig. Der entscheidende Punkt ist, dass Sie nur dann Updates erhalten, wenn Sie danach fragen, sodass die Dinge (möglicherweise) nur dann kaputt gehen, wenn Sie dies erwarten und zum Testen, Debuggen usw. bereit sind. Sie müssen zwar danach fragen, aber nicht wesentlich häufiger als in anderen Systemen mit Sperrdateien. Außerdem möchten wir es einfacher machen, Warnungen wie „Sie bauen mit einer veralteten/unsicheren Version“ an die Oberfläche zu bringen. Aber es ist wichtig, nicht einfach unbemerkt als Nebeneffekt von Nicht-Update-Vorgängen zu aktualisieren.

Auch zu FAQ hinzugefügt.

Vielen Dank an alle für die großartige Diskussion bisher und für die Beantwortung der Fragen der anderen. Wirklich großartige Antworten von vielen Leuten, aber besonderer Dank geht an @Merovius und @kardianos. Ich habe die FAQ https://github.com/golang/go/issues/24301#issuecomment -371228664 und die Diskussionszusammenfassung https://github.com/golang/go/issues/24301#issuecomment -371228742 aktualisiert. Es gibt drei wichtige Fragen, die noch nicht beantwortet sind (in der Zusammenfassung steht TODO), an denen ich als nächstes arbeiten werde. :-)

@rsc , #24057 hat einige Diskussionen über die Verwendung von tar anstelle von zip.

https://github.com/golang/go/issues/24301#issuecomment -375106068, @leonklingele :

Wenn die Unterstützung für Go Get, wie wir sie heute kennen, veraltet und schließlich entfernt wird, was ist dann der empfohlene Weg, um (nicht gekennzeichnete) Go-Binärdateien abzurufen und zu installieren?

Es wird immer noch gehen. Wenn das Repo der Binärdatei nicht getaggt ist, verwendet go get den neuesten Commit. Aber wirklich Leute, die Binärdateien veröffentlichen, sollten ermutigt werden, die enthaltenden Repos genauso zu markieren wie Repos, die Bibliotheken (oder eine Mischung) enthalten.

Wenn $GOPATH veraltet ist, wo werden diese Binärdateien installiert?

Sie müssen nicht mehr in $GOPATH arbeiten, aber der Code wird immer noch in das erste Verzeichnis geschrieben, das in $GOPATH aufgeführt ist - es ist der Quellcache, siehe $GOPATH/src/v nach der Verwendung von vgo. Binärdateien werden in $GOPATH/bin installiert. Seit einigen Veröffentlichungen müssen Sie $GOPATH nicht mehr festlegen - es hat einen Standardwert, $HOME/go. Was also passieren sollte, ist, dass Entwickler aufhören, sich Gedanken über das Setzen von $GOPATH zu machen oder überhaupt zu wissen, was es ist, und sie erfahren einfach, dass sich ihre Binärdateien in $HOME/go/bin befinden. Sie können $GOBIN verwenden, um diesen Ort zu überschreiben.

@dsnet , danke, ich habe einen Link in der Diskussionszusammenfassung hinzugefügt. Bleiben wir bei der Diskussion dort drüben.

Wenn $GOPROXY gesetzt ist, fragt vgo diesen Proxy. Es fällt nie irgendwo anders zurück. Dieser Proxy kann von einem statischen Dateibaum bereitgestellt werden, bei dem es sich hauptsächlich um Module von Drittanbietern in ZIP-Form handelt. Der Dateibaum muss jedoch auch einige andere Metadatendateien für die Navigation und Suche enthalten. Diese zusätzlichen Dateien sind unvermeidlich, da HTTP uns keine Standardmethode für Dinge wie Verzeichnislisten bietet.

Solange die Originalmodule in ZIP-Form aufbewahrt werden, um jede Versuchung zu beseitigen, sie zu manipulieren, und der Indexer robust und leicht ist, ist das in Ordnung.

Obwohl die Auflistungsbeschränkungen nicht für Dateien gelten und Utilities wie lftp seit Ewigkeiten HTTP-Verzeichnisse auflisten können (es spielt keine Rolle, ob es nicht dem Standard entspricht, wenn es auf großen HTTP-Servern funktioniert). Daher ist ein indexloser Betrieb wahrscheinlich möglich und für kleine Unternehmen vorzuziehen, die nicht in Infrastruktur investieren möchten. yum/dnf/zipper sind ebenfalls auf benutzerdefinierte Indizes angewiesen, und die Indizierung eines gemeinsam genutzten Verzeichnisses ist nicht immer so einfach, wie Sie in einigen Organisationen vielleicht denken.

Open-Source-Entwickler neigen dazu, es zu vermeiden, sich auf die Infrastruktur zu verlassen, also wollen sie Anbieter, wie @joeshaw schrieb

Nicht wirklich, Open-Source-Entwickler wollen meistens, dass der gesamte Prozess offen und transparent ist und sich nicht auf die guten Wünsche anderer verlassen muss. Infra ist also völlig in Ordnung, solange es selbst Open Source ist und einfach und kostengünstig lokal bereitgestellt werden kann. Sich auf riesige proprietäre Blackbox-Sites wie github zu verlassen, fällt eindeutig nicht in diese Kategorie, aber das ist nicht dasselbe wie Infra. Open-Source-Leute haben Jahrzehnte vor allen anderen gespiegelt. Was sie nicht akzeptieren werden, sind geschlossene und teuer einzurichtende Mirrors (in Open-Source-Begriffen wird teuer in menschlicher Zeit gemessen).

Die offene, einfache und kostengünstige Natur des Vendoring wird geschätzt, der Vendoring-Prozess selbst und die Art und Weise, wie er die fortschreitende Fossilisierung von Codebasen auf veralteten Versionen von Code von Drittanbietern fördert, nicht so sehr.

Unternehmensentwickler haben kein Problem damit, sich auf die Infrastruktur zu verlassen – das sind nur weitere Kosten

Es muss so schön sein, bei Google zu arbeiten :(. Abgesehen von den wenigen Unternehmen mit einem bestehenden großen Go-Betrieb, bei denen die Investition in Go-Infra ein Kinderspiel ist, müssen alle anderen lange und langwierige Genehmigungsverfahren durchlaufen , und sei es nur, um zu rechtfertigen, dass jemand bezahlt wird, der sich das Problem ansieht. Daher werden alle Infrastrukturkosten die Reichweite von Go verringern und die Übernahme durch neue Strukturen verhindern.

Unternehmen sind wie Opensourcer, sie kümmern sich um billig und einfach. Sie haben sich früher überhaupt nicht um offene Lösungen gekümmert, aber das ändert sich langsam, da sie erkennen, dass es mit billig korreliert (zum Entsetzen traditioneller Unternehmensanbieter, die sich früher auf teure Blackbox-Lösungen mit teurer Beratung zur Unterstützung der Bereitstellung spezialisiert haben).

Unternehmen, die interne IT an den günstigsten Bieter vergeben, werden definitiv auf Mirrors bestehen, da sie definitiv nicht wollen, dass ihre billigen Entwickler kaputten oder gefährlichen Code aus dem Internet herunterladen, den diese Entwickler nicht verstehen. Sie werden Menschen und Tools dafür bezahlen, den Inhalt des lokalen Spiegels auf Probleme zu scannen, und die interne IT dazu zwingen, ihn ausschließlich zu verwenden.

Wir möchten auch unbedingt ein gemeinsames Spiegelnetzwerk aufbauen, dem Entwickler vertrauen und auf das sie sich verlassen können, damit alle Open-Source-Entwickler nicht das Gefühl haben, dass sie Anbieter sein müssen.

Veröffentlichen Sie einfach irgendwo eine Referenzkopie eines indizierten Verzeichnisses, das Module enthält. Vergessen Sie Proxy-ähnliche Setups, die eine spezifische Webserver-Konfiguration erfordern. Das ist es, was Open Sourcer tun, und sie haben keine Schwierigkeiten, sich selbst spiegeln zu lassen. Solange Spiegelung nur den Inhalt eines Verzeichnisses kopiert und keine spezielle Webserver-Konfiguration erfordert, gibt es viele Organisationen, die bereit sind, zu spiegeln.

Was den generierten Code im Allgemeinen betrifft, so ist ein echtes sprachübergreifendes Build-System die Antwort.

Sie wissen so gut wie ich, dass das nie passieren wird, irgendjemand wird immer eine neue Sprache erfinden wollen, die ihre eigenen Sachen macht. Das ist ein Strohmann-Argument.

Das hindert Go jedoch nicht daran, einen Standardbefehl zu normalisieren, der einen beliebigen projektspezifischen Prozess startet, der den Code generiert, mit strengen Richtlinien, was er tun kann und was nicht (normalerweise sollte er nichts tun, was bereits durch Standard-Go-Befehle abgedeckt ist, da diese Befehle dies tun sollten schon gut sein, wie es ist).

Vor allem, weil wir nicht wollen, dass jeder Benutzer die richtigen Generatoren installiert haben muss. Besser für den Autor, die Generatoren laufen zu lassen und das Ergebnis einzuchecken.

Das würde ein grundlegendes Umdenken bei der Implementierung vorhandener Generatoren erfordern, da sie sich derzeit überhaupt nicht um Versionsportabilität kümmern und erwarten, dass die Softwareumgebung vor der Generierung eingefroren wird. Mit der direkten Auswirkung, dass das Generieren jede spätere Versionsänderung ohne Regenerierung gefährlich macht. Es spielt keine Rolle, ob das Ergebnis von Menschen überprüft wird oder nicht, da Menschen nur mit dem ursprünglichen Versionssatz vergleichen. vgo ist darauf angewiesen, spätere Versionsänderungen vornehmen zu können.

vgo wird sich also früher oder später mit der Regeneration auseinandersetzen müssen. Später bedeutet, darauf zu warten, dass Projekte feststellen, dass vgo-Updates in Gegenwart von generiertem Code gefährlich sind.

https://github.com/golang/go/issues/24301#issuecomment -374791885, @jimmyfrasche :

Dies würde auch Dinge wie Datenbanktreiber und Bildformate betreffen, die sich während der Initialisierung bei einem anderen Paket registrieren, da dies am Ende mehrere Hauptversionen desselben Pakets tun können. Was das alles für Folgen hat, ist mir unklar.

Ja, das Problem des Codes, der davon ausgeht, dass „es nur eines davon in einem Programm geben wird“, ist real, und es ist etwas, das wir alle durcharbeiten müssen, um neue (bessere) Best Practices und Konventionen zu etablieren. Ich glaube nicht, dass dieses Problem von vgo eingeführt wird, und vgo macht die Situation wohl besser als zuvor.

Ich verstehe, dass einige Leute argumentieren, dass vgo die Regel von Dep übernehmen sollte, dass es nicht einmal 1.x und 2.x zusammen geben kann, aber das passt ganz klar nicht zu den großen Codebasen, auf die wir mit Go abzielen. Es ist nicht praktikabel zu erwarten, dass ganze große Programme auf einmal von einer API auf eine andere aktualisiert werden, wie der Beitrag vgo-import zeigt. Ich glaube, dass im Wesentlichen alle anderen Paketmanager 1.x und 2.x aus dem gleichen Grund zusammen zulassen. Sicherlich Cargo tut.

Im Allgemeinen reduziert vgo die Duplizierung im Vergleich zum Vendoring. Beim Vendoring ist es leicht, am Ende 1.2, 1.3 und 1.4 eines bestimmten Pakets in einer einzigen Binärdatei zu haben, ohne es zu merken, oder vielleicht sogar drei Kopien von 1.2. Zumindest reduziert vgo die mögliche Duplizierung auf eine 1.x, eine 2.x und so weiter.

Es ist bereits so, dass Autoren verschiedener Pakete sicherstellen müssen, dass sie nicht versuchen, dasselbe zu registrieren. Beispielsweise führt expvar http.Handle("/debug/vars") aus und hat im Wesentlichen Anspruch auf diesen Pfad erhoben. Ich hoffe, wir sind uns alle einig, dass ein Drittanbieter-Paket wie awesome.io/supervars nicht versuchen sollte, denselben Pfad zu registrieren. Dadurch bleiben Konflikte zwischen mehreren Versionen eines einzelnen Pakets bestehen.

Wenn wir expvar/v2 einführen, dann ist das ein zweites, anderes Paket, genau wie awesome.io/supervars, und es könnte in einem großen Build mit expvar in Konflikt geraten. Im Gegensatz zu Supervars gehört expvar/v2 jedoch derselben Person oder demselben Team wie expvar, sodass sich die beiden Pakete koordinieren können, um die Registrierung gemeinsam zu nutzen. Das würde wie folgt funktionieren. Angenommen, expvar v1.5.0 ist das letzte, bevor wir uns entscheiden, v2 zu schreiben, also enthält v1.5.0 ein http.Handle. Wir möchten, dass v2 der Ersatz für v1 ist, also verschieben wir das http.Handle auf v2.0.0 und fügen eine API in v2 hinzu, die es v1 ermöglicht, seine Aufrufe an v2 weiterzuleiten. Dann erstellen wir v1.6.0, das mit dieser Weiterleitung implementiert ist. v1.6.0 ruft http.Handle nicht auf; es delegiert das an v2.0.0. Jetzt können expvar v1.6.0 und expvar/v2 koexistieren, weil wir es so geplant haben. Das einzige verbleibende Problem ist, was passiert, wenn ein Build expvar v1.5.0 mit expvar/v2 verwendet? Wir müssen dafür sorgen, dass das nicht passiert. Wir machen das, indem wir expvar/v2 dazu bringen, expvar in v1.6.0 (oder höher) zu erfordern, obwohl es keinen Import in diese Richtung gibt, und expvar v1.6.0 erfordert natürlich auch expvar/v2 in v2.0.0 oder höher, um seine APIs aufzurufen . Mit diesem Anforderungszyklus können wir sicherstellen, dass v1.5.0 und v2 niemals gemischt werden. Das Planen dieser Art von hauptversionsübergreifender Koordination ist genau der Grund, warum die minimale Versionsauswahl Zyklen im Anforderungsdiagramm zulässt.

Die Regel „Nur eine Hauptversion“ in Kombination mit dem Zulassen von Zyklen im Anforderungsdiagramm gibt Autoren die Tools an die Hand, die sie benötigen, um die ordnungsgemäße Koordination von Singletons (und die Migration des Singleton-Besitztums) zwischen verschiedenen Hauptversionen ihrer Module zu verwalten. Wir können das Problem nicht beseitigen, aber wir können den Autoren die Werkzeuge an die Hand geben, die sie benötigen, um es zu lösen.

Ich weiß, dass insbesondere Protokollpuffer Registrierungsprobleme haben, und diese Probleme werden durch die sehr spontane Art und Weise verschlimmert, wie .pb.go-Protokolldateien herumgereicht und in Projekte kopiert werden. Das ist wieder etwas, das größtenteils unabhängig von vgo ist. Wir sollten es beheben, aber wahrscheinlich, indem wir Änderungen an der Art und Weise vornehmen, wie Go-Protokollpuffer verwendet werden, nicht vgo.

https://github.com/golang/go/issues/24301#issuecomment -374739116, @ChrisHines :

Ich mache mir am meisten Sorgen darüber, dass der Migrationspfad zwischen einer Pre-VGO-Welt und einer VGO-Welt schlecht läuft. [Mehr Details]

Ich bin wirklich froh, dass dies der allererste Kommentar zu dem Vorschlag war. Es ist eindeutig das Wichtigste, es richtig zu machen.

Der Übergang vom alten Go Get und den unzähligen Vendoring-Tools zum neuen Modulsystem muss reibungslos funktionieren. Ich habe in letzter Zeit viel darüber nachgedacht, wie das genau funktionieren soll.

Der ursprüngliche Vorschlag erlaubt Entwicklern die Option, Version 2 eines Moduls in einem Repo-Unterverzeichnis namens v2/ abzulegen. Die Ausübung dieser Option würde es Entwicklern ermöglichen, ein Repo zu erstellen, das eine semantische Importversionierung verwendet, mit Modulen kompatibel und dennoch abwärtskompatibel mit dem alten „go get“ ist. Der Beitrag, der diese Option beschreibt, gibt zu, dass die überwiegende Mehrheit der Projekte diese Option nicht ausüben möchte, was in Ordnung ist. Es wird nur aus Kompatibilitätsgründen benötigt, wenn ein Projekt bereits v2 oder höher ist. Gleichzeitig habe ich die Anzahl der weit verbreiteten, großen Projekte, die v2 oder höher sind, unterschätzt. Beispielsweise:

  • github.com/godbus/dbus ist auf v4.1.0 (importiert von 462 Paketen).
  • github.com/coreos/etcd/clientv3 ist auf v3.3.3 (importiert von 799-Paketen).
  • k8s.io/client-go/kubernetes ist auf v6.0.0 (importiert von 1928-Paketen).

Um zu vermeiden, dass ihre Clients beschädigt werden, müssten diese Projekte in ein Unterverzeichnis verschoben werden, bis davon ausgegangen werden kann, dass alle Clients Module verwenden, und dann wieder nach oben zum Stammverzeichnis verschoben werden. Das ist viel verlangt.

Eine weitere Option, um mit Git-Submodulen einen Streich zu spielen. Der alte go get-Befehl bevorzugt ein Tag oder einen Branch mit dem Namen „go1“ gegenüber dem Standard-Branch des Repos, sodass ein Projekt, das einen reibungslosen Übergang ermöglichen wollte, ein Commit auf einem „go1“-Branch erstellen konnte, in dem nur ein „v2“-Unterverzeichnis eingerichtet war als Git-Submodul, das zurück auf die echte Repo-Root zeigt. Wenn „go get“ diesen go1-Zweig auscheckte und Submodule auffüllte, erhielt es das richtige Dateibaum-Layout. Das ist jedoch ziemlich schrecklich, und die Submodulzeiger müssten jedes Mal aktualisiert werden, wenn eine neue Version erstellt wird.

Beides hat den unglücklichen Effekt, dass Autoren Maßnahmen ergreifen müssen, um ihre Benutzer nicht zu beschädigen, und selbst dann nur für neue Versionen. Wir möchten stattdessen, dass der Code der Benutzer auch ohne zusätzliche Arbeit von Autoren weiter funktioniert, und idealerweise sogar für alte Versionen.

Aber das sind die einzigen Möglichkeiten, die mir einfallen, um unveränderte, alte Geräte zu erhalten, während wir in die Modulwelt übergehen. Wenn dies nicht der Fall ist, besteht die Alternative darin, das alte Go Get zu modifizieren, was wirklich bedeutet, das alte Go Build zu modifizieren.

Grundsätzlich gibt es zwei verschiedene Importpfadkonventionen: die alte ohne Hauptversionen und die neue mit Hauptversionen ab v2. Code in einem alten Baum verwendet wahrscheinlich die alte Konvention, während Code in einem neuen Baum – unter einem Verzeichnis, das eine go.mod-Datei enthält – wahrscheinlich die neue Konvention verwendet. Wir brauchen eine Möglichkeit, die beiden Konventionen während eines Übergangs überlappen zu lassen. Wenn wir den Alten beibringen, ein wenig über semantische Importversionierung zu lernen, können wir die Überlappung erheblich erhöhen.


Vorgeschlagene Änderung: Definieren Sie „neuen“ Code als Code mit einer go.mod-Datei im selben Verzeichnis oder einem übergeordneten Verzeichnis. Der alte Go Get muss den Code weiterhin genau so herunterladen, wie er es immer getan hat. Ich schlage vor, dass der Schritt „go build“ seine Handhabung von Importen in „neuem“ Code anpasst. Insbesondere wenn ein Import in neuem Code x/y/v2/z sagt, x/y/v2/z aber nicht existiert und x/y/go.mod „Modul x/y/v2“ sagt, dann wird go build gelesen stattdessen den Import als x/y/z. Wir würden dieses Update als Point-Release für Go 1.9 und Go 1.10 veröffentlichen.

Update : Auskopiert nach #25069.


Diese Änderung sollte es Modul-unbewussten Paketen ermöglichen, neuere Versionen von Modul-bewussten Paketen zu verwenden, unabhängig davon, ob diese Pakete den „Hauptzweig“- oder „Hauptunterverzeichnis“-Ansatz zur Strukturierung ihrer Repos wählen. Sie würden nicht länger in den Unterverzeichnis-Ansatz gezwungen, aber es wäre immer noch eine funktionierende Option. Und Entwickler, die ältere Go-Releases verwenden, könnten den Code immer noch erstellen (zumindest nach dem Update auf das Point-Release).

@rsc Ich habe versucht herauszufinden, wie wir den Übergang zu vgo auch zum Laufen bringen könnten. Ich bin zu den gleichen Schlussfolgerungen gekommen, die Sie in Ihrer Antwort dargelegt haben, und Ihr Vorschlag entspricht dem besten Ansatz, den ich mir ausgedacht habe alleine. Ich finde deinen Änderungsvorschlag gut.

https://github.com/golang/go/issues/24301#issuecomment -377527249, @rsc :

Dann erstellen wir v1.6.0, das mit dieser Weiterleitung implementiert ist. v1.6.0 ruft http.Handle nicht auf; es delegiert das an v2.0.0. Jetzt können expvar v1.6.0 und expvar/v2 koexistieren, weil wir es so geplant haben.

Das klingt einfacher als es ist. In Wirklichkeit muss dies in den meisten Fällen bedeuten, dass v1.6.0 eine vollständige Neufassung von v1 in Form eines v2-Wrappers sein muss _ (ein weitergeleiteter Aufruf an http.Handle führt zur Registrierung eines anderen Handlers – einen von v2 – was wiederum bedeutet, dass alle verwandt sind Code sollte auch von v2 sein, um korrekt mit registrierten Handern zu interagieren)_.

Dies wird sehr wahrscheinlich subtile Details über das Verhalten von v1 ändern, insbesondere mit der Zeit, wenn sich v2 weiterentwickelt. Selbst wenn wir in der Lage sein werden, diese subtilen Detailänderungen zu kompensieren und v1 in v1.6.x gut genug zu emulieren, ist es dennoch eine Menge zusätzlicher Arbeit und macht sehr wahrscheinlich die zukünftige Unterstützung des v1-Zweigs (ich meine Nachfolger von v1.5.0 hier) bedeutungslos.

@powerman , ich sage absolut nicht, dass das trivial ist. Und Sie müssen sich nur so weit koordinieren, dass v1 und v2 um eine gemeinsam genutzte Ressource wie eine HTTP-Registrierung streiten. Aber Entwickler, die an diesem Verpackungsökosystem teilnehmen, müssen unbedingt verstehen, dass v1 und v2 ihrer Pakete in großen Programmen koexistieren müssen. Viele Pakete brauchen keine Arbeit – yaml und blackfriday zum Beispiel befinden sich beide auf v2, die sich völlig von v1 unterscheiden, aber es gibt keinen gemeinsamen Zustand, um den gekämpft werden muss, sodass keine explizite Koordination erforderlich ist – aber andere werden es tun.

@powerman @rsc
Ich entwickle ein GUI-Paket, was bedeutet, dass ich aufgrund der Verwendung des "Haupt" -Threads nicht einmal 2+ Instanzen haben kann. Ausgehend vom Worst-Case-Singleton-Szenario habe ich mich für Folgendes entschieden.

  • Haben Sie nur eine v0/v1-Version, so dass es unmöglich ist, 2+ Versionen zu importieren

  • Haben Sie öffentlichen Code in einem eigenen API-Versionsordner, z. B. v1/v2, vorausgesetzt, vgo erlaubt dies oder vielleicht api1/api2.

  • Diese öffentlichen API-Pakete hängen dann von einem internen Paket ab, sodass es, anstatt auf einer v2 neu geschrieben werden zu müssen, eine fortlaufende Neuschreibung ist, wenn das Paket wächst und viel einfacher zu handhaben ist.

In https://github.com/golang/go/issues/24301#issuecomment -377529520 definiert die vorgeschlagene Änderung „neuen“ Code als Code mit einer go.mod-Datei im selben Verzeichnis oder einem übergeordneten Verzeichnis. Umfasst dies beispielsweise "synthetisierte" go.mod-Dateien, die durch das Einlesen von Abhängigkeiten aus einer Gopkg.toml erstellt wurden?

@zeebo , ja. Wenn Sie eine go.mod-Datei in Ihrem Baum haben, wird davon ausgegangen, dass Ihr Code tatsächlich mit vgo erstellt wird. Wenn nicht, dann rm go.mod (oder checken Sie es zumindest nicht in Ihr Repo ein, wo andere es finden könnten).

@AlexRouSg , dein Plan für dein GUI-Paket macht für mich Sinn.

@rsc hmm .. Ich bin mir nicht sicher, ob ich es verstehe und entschuldige mich, wenn ich unklar war. Zählt ein Paket mit nur einer Gopkg.toml im Dateibaum als "neu" für die Definition?

@rsc

Was den generierten Code im Allgemeinen betrifft, so ist ein echtes sprachübergreifendes Build-System die Antwort, insbesondere weil wir nicht möchten, dass jeder Benutzer die richtigen Generatoren installiert haben muss. Besser für den Autor, die Generatoren laufen zu lassen und das Ergebnis einzuchecken.

Wir haben es geschafft, dies zu lösen, indem wir protobuf in den GOPATH gemappt haben. Ja, wir haben es so, dass gelegentliche Benutzer die Tools zum Aktualisieren nicht benötigen, aber für diejenigen, die Protobufs ändern und neu generieren, funktioniert die Lösung in Protobuild sehr gut.

Die Antwort hier ist ziemlich enttäuschend. Ein neues Build-System zu finden, das nicht existiert, ist nur eine Nicht-Antwort. Die Realität hier ist, dass wir diese Build-Systeme nicht neu erstellen und weiterhin das verwenden werden, was funktioniert, und die Übernahme des neuen vgo-Systems vermeiden.

Erklärt vgo nur Bankrott für diejenigen, die GOPATH mochten und übernahmen und seine Probleme umgingen?

@zeebo , nein, eine Gopkg.toml zu haben, zählt nicht als neu; hier bedeutet "neu", dass voraussichtlich Importe im vgo-Stil (semantische Importversionierung) verwendet werden.

@stevvooe :

Wir haben es geschafft, dies zu lösen, indem wir protobuf in den GOPATH gemappt haben. ...
Erklärt vgo nur Konkurs für diejenigen, die GOPATH mochten und übernahmen und seine Probleme umgingen?

Ich habe mir Ihren Protobuild nicht angesehen, aber im Allgemeinen ja, wir wechseln zu einem Nicht-GOPATH-Modell, und einige der Tricks, die GOPATH möglicherweise aktiviert hat, werden zurückgelassen. Zum Beispiel ermöglichte GOPATH dem ursprünglichen Godep, das Vendoring ohne Vendoring-Unterstützung zu simulieren. Das wird nicht mehr möglich sein. Auf den ersten Blick sieht es so aus, als ob protobuild auf der Annahme basiert, dass es Dateien (pb.go) in andere Pakete ablegen kann, die Sie nicht besitzen. Diese Art von globaler Operation wird nicht mehr unterstützt, nein. Ich meine es absolut ernst und aufrichtig, dass Protobufs unabhängig von vgo gut unterstützt werden. @neild wäre wahrscheinlich daran interessiert, Vorschläge zu hören, aber vielleicht nicht zu diesem Thema.

@stevvooe hat die Kommentare von @rsc in https://github.com/golang/go/issues/24301#issuecomment -377602765 gegeben Dieses Problem deckt am Ende den vgo -Winkel ab. Wenn die Dinge am Ende woanders behandelt werden, bin ich sicher, dass @dsnet et al uns einen Wegweiser geben wird.

Hinweis: Ich habe die vorherigen Kommentare nicht genau gesehen, es scheint, als ob das Problem mit einem anderen Ansatz gelöst wurde. Unten war meine Idee.

Nur eine Idee.

Wie wäre es, vgo get auf bestimmte Tags wie vgo-v1-lock aufmerksam zu machen?
Wenn ein Repository das Tag hat, kann es andere Versions-Tags ignorieren und an das Tag gepinnt werden.

Wenn also ein Repository v2.1.3 als letzte Version markiert hat,
aber auch das Besitzer-Push-Tag vgo-v1-lock auf denselben Commit, der mit v2.1.3 gekennzeichnet ist
es könnte go.mod schreiben

require (
    "github.com/owner/repo" vgo-v1-lock
)

Es sollte nicht aktualisiert werden, selbst wenn vgo get -u , bis der Eigentümer des Repositorys das Tag geändert oder entfernt hat.
Es könnte große Repositories einfacher machen, ihren Umzug vorzubereiten.

Wenn ein Bibliotheksautor vorbereitet ist, könnte der Autor den Benutzer ankündigen
die sie manuell aktualisieren könnten, indem sie "/v2" in den Importpfad einfügen.

Wie gehen wir mit dem Fall um, dass eine tiefe Abhängigkeit gepatcht werden muss (z. B. um einen CVE-Fix anzuwenden, den der ursprüngliche Autor noch nicht in einem Tag veröffentlicht hat). Scheint, dass die Herstellerstrategie damit umgehen könnte, da Sie einen Patch auf die ursprüngliche Autorenversion anwenden könnten. Ich sehe nicht, wie vgo damit umgehen kann.

@chirino Sie können die Direktive replace in der Datei go.mod verwenden, um auf das gepatchte Paket zu verweisen.

@rsc

Auf den ersten Blick sieht es so aus, als ob protobuild auf der Annahme basiert, dass es Dateien (pb.go) in anderen Paketen ablegen kann, die Sie nicht besitzen.

Das ist überhaupt nicht das, was das Projekt tut. Es baut einen Importpfad aus dem GOPATH und dem Vendor-Verzeichnis auf. Alle Protobuf-Dateien in Ihrem Projekt werden dann mit diesem Importpfad generiert. Es macht auch Dinge wie Kartenimporte in bestimmte Go-Pakete.

Der Vorteil davon ist, dass es einem ermöglicht, Protobufs in einem Blattprojekt zu generieren, die von anderen in Abhängigkeiten definierten Protobufs abhängig sind, ohne alles neu generieren zu müssen. Der GOPATH wird effektiv zu den Importpfaden für die Protobuf-Dateien.

Das große Problem bei diesem Vorschlag ist, dass wir die Möglichkeit, Dateien in Projekten relativ zu Go-Paketen im Dateisystem aufzulösen, vollständig verlieren. Die meisten Verpackungssysteme sind dazu in der Lage, auch wenn sie es erschweren. GOPATH ist insofern einzigartig, als es sehr einfach ist, dies zu tun.

@stevvooe Es tut mir leid, aber ich denke, ich bin immer noch verwirrt darüber, was Protobuild tut. Können Sie ein neues Problem "x/vgo: not compatible with protobuild" einreichen und ein einfaches funktionierendes Beispiel für einen heute existierenden Dateibaum geben, was protobuild dem Baum hinzufügt und warum das mit vgo nicht funktioniert? Danke.

Was ist, wenn sich der Modulname ändern muss (Domain verloren, Inhaberwechsel, Markenstreit etc.)?

@jimmyfrasche

Als Benutzer:
Dann können Sie als temporären Fix die go.mod-Datei bearbeiten, um das alte Modul durch ein neues zu ersetzen, während Sie die gleichen Importpfade beibehalten. https://research.swtch.com/vgo-tour

Langfristig möchten Sie jedoch alle Importpfade ändern und die Datei go.mod bearbeiten, um das neue Modul zu verwenden. Im Grunde dasselbe, was Sie mit oder ohne vgo tun müssten.

Als Paketbetreuer:
Aktualisieren Sie einfach die Datei go.mod, um den Importpfad des Moduls zu ändern, und informieren Sie Ihre Benutzer über die Änderung.

@jimmyfrasche ,

Was ist, wenn sich der Modulname ändern muss (Domain verloren, Inhaberwechsel, Markenstreit etc.)?

Dies sind echte, bereits bestehende Probleme, die der vgo-Vorschlag nicht direkt anzugehen versucht, aber wir sollten sie eindeutig irgendwann angehen. Die Antwort auf das Verschwinden von Code ist, Caching-Proxys (Spiegel) zusammen mit einem Grund zu haben, ihnen zu vertrauen; das ist Zukunftsarbeit. Die Antwort auf das Verschieben von Code besteht darin, ein explizites Konzept von Modul- oder Paketumleitungen hinzuzufügen, ähnlich wie Typaliase Typumleitungen sind; das ist auch zukunftsarbeit.

Die Antwort auf das Verschwinden von Code ist, Caching-Proxys (Spiegel) zu haben.

IMO, das ist wirklich für die Unternehmen. Die meisten kleinen Unternehmen und andere wären vollkommen in Ordnung, wenn sie alle Abhängigkeiten in demselben Repo anbieten und festschreiben würden

Eingereicht # 24916 für die Kompatibilität, die ich im obigen Kommentar erwähnt habe.
Auch eingereicht #24915 mit dem Vorschlag, wieder direkt git usw. zu verwenden, anstatt auf HTTPS-Zugriff zu bestehen. Es scheint klar zu sein, dass Code-Hosting-Setups noch nicht für API-only bereit sind.

kleiner Vorschlag, Konsistenz in Mod-Dateien mit dem geplanten Befehl vgo get zu schaffen

Im Dokument „vgo-tour“ wird der Befehl vgo get wie folgt angezeigt:

vgo get rsc.io/[email protected]

Wie wäre es, dieses Format in der Mod-Datei zu spiegeln? Beispielsweise:

module "github.com/you/hello"
require (
    "golang.org/x/text" v0.0.0-20180208041248-4e4a3210bb54
    "rsc.io/quote" v1.5.2
)

könnte einfach sein:

module "github.com/you/hello"
require (
    "golang.org/x/[email protected]"
    "rsc.io/[email protected]"
)
  • verbessert die Konsistenz mit der Befehlszeile
  • Ein einzelner Bezeichner definiert den Artikel vollständig
  • Bessere Struktur zur Unterstützung von Operationen, die in der Mod-Datei definiert sind und mehrere versionierte Paketkennungen erfordern

Ich suche mehr Klarheit darüber, wie dieser Vorschlag mit der Paketverteilung "nur binär" umgeht.

Die Versionierung / Verteilung von Binärbibliotheken scheint in keinem der Beschreibungsdokumente rund um vgo aufzutauchen. muss man sich das genauer anschauen?

So wie es heute funktioniert, wenn ich das einfache git -Tool verwenden kann, wird go get gut funktionieren. Dabei spielt es keine Rolle, ob es sich um ein privates Github-Repository oder meinen eigenen Git-Server handelt. Ich liebe es wirklich.

Soweit ich weiß, wird es unmöglich sein, so weiterzuarbeiten. Ist das wahr? Wenn ja, ist es möglich, die Option beizubehalten, eine lokal installierte git -Binärdatei zu verwenden, um den Code auszuchecken? (falls es ein explizites CLI-Flag verwendet)

@korya Bitte sehen Sie sich die kürzlich eingereichte Ausgabe an https://github.com/golang/go/issues/24915

@sdwarwick , zu https://github.com/golang/go/issues/24301#issuecomment -382791513 (go.mod-Syntax), siehe #24119.

re https://github.com/golang/go/issues/24301#issuecomment -382793364, es ist möglich, dass ich nicht verstehe, was du meinst, aber go get hat nie Nur-Binär-Pakete unterstützt, und wir planen nicht Unterstützung hinzuzufügen. Es ist zu schwierig, alle möglichen verschiedenen Binärdateien aufzuzählen, die man möglicherweise benötigt. Es ist besser, die Quelle anzufordern und neu zu kompilieren, wenn sich die Abhängigkeiten oder der Compiler ändern.

@rsc Ich glaube, https://github.com/golang/go/issues/24301#issuecomment -382793364 bezieht sich auf
https://golang.org/pkg/go/build/#hdr -Binary_Only_Packages

@AlexRouSg Ja. Diese werden von "go get" nicht unterstützt (aber "go build" unterstützt sie als Build-Typ), worauf sich @rsc bezieht. Die Verteilung dieser Arten von Paketen muss außerhalb des "go get"-Tools erfolgen und ist daher wahrscheinlich dasselbe für diesen neuen Vorschlag.

Ich gehe davon aus, dass die derzeitige Unterstützung für Nur-Binär-Pakete weiterhin so schlecht funktionieren wird, wie sie jemals funktioniert hat. Ich werde mir nicht die Mühe machen, es zu entfernen.

Ich habe die Diskussionszusammenfassung noch einmal aktualisiert. Ich habe auch #25069 für meinen früheren Vorschlag zur minimalen Modulerkennung in alten cmd/go eingereicht.

@kybin , re https://github.com/golang/go/issues/24301#issuecomment -377662150 und das Tag vgo-v1-lock , ich sehe den Appell, aber das Hinzufügen eines Sonderfalls bedeutet, dass durchweg weitere Sonderfälle hinzugefügt werden der Rest der Modulunterstützung. Ich glaube nicht, dass der Nutzen in diesem Fall im Verhältnis zu den Kosten steht. Menschen können bereits Pseudoversionen verwenden, um einen ähnlichen Effekt zu erzielen. Ich mache mir auch Sorgen, dass das Tag verschoben wird und / oder die Leute die Abwärtskompatibilität nicht richtig respektieren (z. B. das Verschieben von vgo1-v1-lock von v2.3.4 auf v3.0.0, nur um die semantische Importversionierung zu vermeiden). Alles in allem denke ich, dass wir dies wahrscheinlich nicht tun sollten.

Ich denke, es ist an der Zeit, diesen Vorschlag als angenommen zu markieren.

Ob es in irgendeiner Form angenommen werden würde, war nie fraglich. Stattdessen war das Ziel der Diskussion hier, die genaue Form zu erarbeiten, zu identifizieren, was wir anpassen sollten. Wie ich im Blogbeitrag geschrieben habe:

Ich weiß, dass es Probleme damit gibt, die das Go-Team und ich nicht sehen können, weil Go-Entwickler Go auf viele clevere Arten verwenden, von denen wir nichts wissen. Das Ziel des Feedback-Prozesses für Vorschläge ist, dass wir alle zusammenarbeiten, um die Probleme im aktuellen Vorschlag zu identifizieren und anzugehen, um sicherzustellen, dass die endgültige Implementierung, die in einer zukünftigen Go-Version enthalten ist, für so viele Entwickler wie möglich gut funktioniert. Bitte weisen Sie auf Probleme in der Vorschlagsdiskussion hin. Ich werde die Diskussionszusammenfassung und die FAQ auf dem neuesten Stand halten, sobald Feedback eintrifft.

Die Diskussionszusammenfassung und die FAQ sind ab sofort auf dem neuesten Stand. Die Diskussion hier und außerhalb der Ausgabe führte zu den folgenden wichtigen Änderungen:

  • minimales Modulbewusstsein im alten cmd/go, #25069.
  • Wiederherstellung der minimalen Herstellerunterstützung, #25073.
  • Wiederherstellung der Unterstützung für direkten Git-Zugriff, #24915.
  • Anführungszeichen in go.mod, #24641, weglassen.
  • bessere Unterstützung für gopkg.in, #24099, andere.
  • Unterstützung für die Benennung von Commits nach Branch-IDs, #24045.

Es löste auch Diskussionen über eine mögliche Änderung des go.mod-Dateinamens und der Syntax aus, aber die einzige resultierende Änderung war das Weglassen der Anführungszeichen.

Die Diskussion hat nachgelassen und ist auch lang genug geworden, um ziemlich schmerzhaft zu sein, sie auf GitHub zu laden (anscheinend sind 100 Kommentare zu viele!). Indem wir den Vorschlag als akzeptiert markieren, können wir uns darauf konzentrieren, vgo zu verwenden und es für die Aufnahme in Go 1.11 als „Vorschau“ vorzubereiten, und wir können zu Problemen übergehen, die GitHub schneller laden kann.

Natürlich müssen noch mehr Fehler gefunden und behoben und weitere Designanpassungen vorgenommen werden. Diskussionen über diese Details können zu neuen Themen geführt werden, die sich speziell auf diese Details beziehen. Bitte verwenden Sie ein „x/vgo:“-Präfix und den vgo-Meilenstein .

Danke an alle.

@rsc Wie kann ich vgo jetzt ausprobieren? Sollen wir github.com/golang/vgo oder github.com/golang/go abrufen und erstellen?

@ngrilly verwendet weiterhin go get -u golang.org/x/vgo .

@rsc Vielen Dank für die harte Arbeit und Zeit, die Sie in diesen Vorschlag investiert haben. Ich hoffe wirklich, dass wir irgendwann an einen Punkt kommen, an dem es eine gute Geschichte rund um das Go-Abhängigkeitsmanagement gibt.

Ich denke, es ist an der Zeit, diesen Vorschlag als angenommen zu markieren.

Ich denke nicht, dass es für eine Person, die einen Vorschlag einreicht, angebracht ist, zu erklären, wann er zur Annahme bereit ist. Ich denke, diejenigen, die einen Vorschlag einreichen, insbesondere einen so großen und eigensinnigen, sollten kein Mitspracherecht bei der Annahme haben. Ihre Einreichung des Vorschlags teilt ihre Vorurteile mit. Andererseits denke ich, dass Autoren definitiv ein Mitspracherecht bei der Ablehnung des Vorschlags haben sollten, wenn sie es sich anders überlegen, nachdem sie ihn vorgebracht haben.

Derzeit scheint es, als gäbe es tiefgreifende Meinungsverschiedenheiten über technische Entscheidungen innerhalb vgo , von denen ich befürchte, dass sie das Ökosystem _und_ die Community fragmentieren werden. In Anbetracht dessen denke ich, dass wir den konkurrierenden Vorschlägen etwas mehr Zeit einräumen sollten, damit sie fertig sind und im Rampenlicht stehen. Sobald dies geschieht, brauchen wir eine _neutrale_ Partei, die aus Vertretern mehrerer Unternehmen und der Gemeinde besteht, um die Diskussion und die endgültige Entscheidung zu erleichtern.

Ich mache mir zunehmend Sorgen, dass ein großer Teil der Go-Führung zu sehr von der Community hinter Go isoliert ist (einschließlich anderer Unternehmen, die es verwenden) und dass die Sprache und das Ökosystem dadurch zu schaden beginnen. Aus diesem Grund denke ich, dass wir eine neutrale Gruppe haben müssen, deren Vertretung die Benutzer der Programmiersprache Go widerspiegelt, um Vorschläge wie diesen zu ratifizieren.

Letztendlich führt die Arbeit als Softwareentwickler bei Google zu einer anderen Perspektive im Vergleich zu einem großen Teil der Branche. Die kritische Masse der Kernentwickler bei Google zu haben, trägt nicht zu der Vielfalt bei, die wir brauchen, wenn wir Go nach vorne bringen.

@teckman Ihre Denkweise scheint zu sein:

  1. Entscheidungen über Go werden von einem kleinen Team getroffen, das hauptsächlich aus Google-Ingenieuren besteht.
  2. Google-Ingenieure sind vom Rest der Community isoliert, da die Anforderungen von Google sehr spezifisch sind.
  3. Dies führt zu Entscheidungen, die die Google-Perspektive bevorzugen und nicht an andere Go-Nutzer angepasst sind.
  4. Dies könnte der Go-Community schaden und sie fragmentieren.
  5. Um dieses Problem zu lösen, sollte Go einen formalen Entscheidungsprozess einführen, bei dem Entscheidungen kollegial von einer Gruppe getroffen werden, die die Vielfalt der Go-Community widerspiegelt (etwas „Demokratisches“).

Theoretisch wäre ich geneigt, alles "Demokratische" zu mögen, aber in der Praxis:

  • Ich glaube nicht, dass die vom Go-Team getroffenen Entscheidungen auf Kosten der "kleinen" Go-Nutzer auf die Bedürfnisse von Google ausgerichtet sind. Als Entwickler in einem sehr kleinen Geschäft (ganz im Gegensatz zu Google) habe ich das Gefühl, dass Go sehr gut an unsere Bedürfnisse angepasst ist, und ich kenne andere kleine Teams um mich herum, die Go gerne verwenden. Persönlich wurden die einzigen Probleme, die ich mit der Go-Sprache habe, vom Go-Team anerkannt (Abhängigkeitsmanagement, Mangel an Generika, ausführliche Fehlerbehandlung) und ich bin zuversichtlich, dass sie daran arbeiten. Können Sie Beispiele für Entscheidungen des Go-Teams nennen, die anders ausgefallen wären und „dem Rest der Gemeinschaft“ besser gedient hätten, wenn wir einen „demokratischen“ Prozess gehabt hätten?

  • Ich bin nicht davon überzeugt, dass die Annahme eines „demokratischen“ Entscheidungsprozesses automatisch die von Ihnen erwähnten Probleme lösen und das Risiko einer „Fragmentierung“ der Gemeinschaft beseitigen würde. Es kann eine Verbesserung gegenüber dem BDFL -Modell darstellen, ist aber per se keine Garantie für Stabilität. Die Open-Source-Geschichte und die Menschheitsgeschichte im Allgemeinen bieten viele Beispiele für demokratische Gesellschaften, die durch Meinungsverschiedenheiten und Konflikte ruiniert wurden.

@theckman , während @ngrilly versuchte, höflich zu sein, werde ich konkret sein: Wenn Sie irgendwelche technischen Probleme sehen, warum der vgo-Vorschlag nicht bereit ist, angenommen zu werden - sagen Sie es uns so schnell wie möglich und genau hier! Wenn Sie der Meinung sind, dass einige bekannte Probleme nicht angemessen behandelt wurden, teilen Sie uns dies bitte mit. Wenn es keine solchen Fälle gibt - was ist der Unterschied, wer sagt: "Es ist Zeit, den Vorschlag anzunehmen"? Wir hatten zwei Monate Zeit, um darüber zu diskutieren, wenn Sie glauben, dass es einen technischen Grund gibt, warum es nicht ausreicht - sagen Sie es uns.

Es hört sich so an, als wollten Sie hier ohne Grund mehr Politik hinzufügen, was alles nur verlangsamen wird, und das ist, wenn wir Glück haben und es keinen anderen Schaden anrichtet. Und selbst wenn Sie glauben, dass es dafür einen Grund gibt - dies ist nicht der richtige Ort, um dies zu diskutieren - beginnen Sie diese Diskussion stattdessen in der Mailliste.

Entschuldigung für einen weiteren Offtopic-Kommentar, alle zusammen!

@powerman Tut mir leid, lahm zu sein und meinen früheren Kommentar zu zitieren:

Zum jetzigen Zeitpunkt scheint es tiefgreifende Meinungsverschiedenheiten über technische Entscheidungen innerhalb von vgo zu geben, von denen ich befürchte, dass sie das Ökosystem und die Community fragmentieren werden. In Anbetracht dessen denke ich, dass wir den konkurrierenden Vorschlägen etwas mehr Zeit einräumen sollten, damit sie fertig sind und im Rampenlicht stehen.

Ich weiß, dass alternative Vorschläge kommen, und meine Bitte war, den Kibosh darauf zu stellen, dies zu akzeptieren, bis diese die Zeit dafür haben. Wir haben seit einiger Zeit kein Abhängigkeitsmanagement mehr, daher denke ich, dass es nicht unangemessen ist, um einen kurzen Aufenthalt zu bitten, während wir anderen Vorschlägen den letzten Schliff geben.

Ich bin mir nicht sicher, ob es einfach ist, es in dieser Ausgabe gut zu artikulieren, nur weil das Format etwas eingeschränkt ist. Selbst dann würde ich zögern, weil ich im Grunde Teile der WIP-Vorschläge duplizieren würde. Ich möchte die Ideen nicht zersplittern oder den Autoren den Donner stehlen.

Da man jedoch wusste, dass diese Vorschläge in Arbeit sind und wer daran arbeitet, fühlte es sich an, als wäre die Erklärung, dass dies bereit sei, ein aktiver Versuch, diese konkurrierenden Meinungen zu unterdrücken. Aufgrund von Mustern, die ich in meinen Jahren als Gopher beobachtet habe, fühlte ich mich gezwungen, diese Bedenken zu äußern. Ich möchte wirklich, dass die Sprache, das Ökosystem und die Community erfolgreich sind, und diese werden nur mit diesem Ziel im Hinterkopf entwickelt.

Bearbeiten: Zur Verdeutlichung, mit kurzem Aufenthalt meine ich nicht zwei Monate oder so etwas. Ich meine ein paar Wochen.

@ngrilly Sorry, ich wollte deinen Kommentar nicht ignorieren. Ich hatte vor, es an das frühere zu richten, war aber am Ende ausführlicher als ich wollte.

Ich denke, es gibt zwei Probleme. Obwohl ich der Meinung bin, dass in einem anderen Forum darüber diskutiert werden muss, wie diese Entscheidungen getroffen werden, weshalb ich etwas Kontext dazu hinzugefügt habe, möchte ich mich wirklich darauf konzentrieren, die Annahme dieses Vorschlags vorübergehend zu unterbrechen, bis die anderen Vorschläge dies getan haben hatte die Chance, öffentlich zu werden.

Ich weiß, dass alternative Vorschläge kommen, und meine Bitte war, den Kibosh darauf zu stellen, dies zu akzeptieren, bis diese die Zeit dafür haben. ... Da diese Vorschläge in Arbeit sind und wer daran arbeitet, fühlte es sich an, als wäre die Erklärung, dass dies bereit sei, ein aktiver Versuch, diese konkurrierenden Meinungen zu unterdrücken.

Ich versichere Ihnen, das war es nicht. Ich habe mich hier ziemlich klar über die Zeitleiste ausgedrückt. Mein erster Beitrag von Mitte Februar besagt, dass das Ziel darin besteht, den vgo-Vorschlag in Go 1.11 zu integrieren; der Entwicklungsstopp naht. Ich weiß nichts über andere laufende Vorschläge oder wer daran arbeitet. Das ist mir neu. Wenn Leute sich mit diesem Vorschlag auseinandersetzen oder Gegenvorschläge machen wollen, dieser Vorschlag ist seit anderthalb Monaten offen, also ist es ein bisschen spät.

Um es klar zu sagen, ich habe den Vorschlag nicht als akzeptiert markiert, ungeachtet dessen, was Golang Weekly und vielleicht andere berichteten. Ich sagte nur, dass ich denke, dass es an der Zeit ist, dies zu tun. Das heißt, ich habe das Label „Proposal-Accepted“ nicht angewendet, genau weil ich zuerst überprüfen wollte, ob es einen allgemeinen Konsens dafür gibt. Und der allgemeine Konsens scheint für die Akzeptanz zu sein, zumindest nach der Gesamtdiskussion hier sowie den Emoji-Zählern auf https://github.com/golang/go/issues/24301#issuecomment -384349642 zu urteilen.

Ich weiß, es kommen Alternativvorschläge

@theckman , wenn du so etwas kennst, bist du wahrscheinlich der einzige, der es weiß. Bis heute habe ich niemanden gesehen, der dieses Problem angesprochen hat. Ich denke, die Aussagen von Russ, dass er dies für Go 1.11 ausprobieren wollte, waren von Anfang an sehr klar. Wenn also jemand an alternativen Vorschlägen arbeitet, hatte er etwa 2 Monate Zeit, um sie vorzulegen, sogar als Heads-Up.

Ich denke auch, dass wir die Tatsache akzeptieren können, dass das Go-Team eine gute Erfolgsbilanz darin hat, Entscheidungen nicht aus einer Laune heraus zu treffen, und wenn wir uns nur ansehen, wie sie den Alias ​​im letzten Moment von Go 1.8 gezogen haben, weil es nicht richtig war was zu dieser Zeit zu tun ist, dann sollten wir ihnen wahrscheinlich die Höflichkeit erweisen, ihnen zumindest zu erlauben, ihr eigenes Experiment/ihre eigene Lösung zu bauen.

Am Ende des Tages bringt der Vorschlag viel mehr als nur einen Algorithmus, wie man auswählt, welche Version der Abhängigkeit verwendet wird. Wenn jemand einen Weg findet, es zu verbessern, gibt es zwei Möglichkeiten: Es über den regulären CL-Prozess einreichen ODER ein eigenes Tool erstellen und es der Community überlassen, falls sie sich dafür entscheiden. Das Go-Team kann meiner Meinung nach immer noch eine eigene Version des Tools bereitstellen, daher sehe ich kein geschlossenes Problem.

Bitte denken Sie jedoch daran, dass die meisten Spaltungsaktionen bisher von der Community und nicht vom Go-Team unternommen wurden. Lassen Sie uns dem Go-Team die Möglichkeit geben, ein Tool zu entwickeln und es dann zu bewerten, wenn es machbar ist, und dann Argumente vorbringen, wie es verbessert und vorangebracht werden kann, anstatt darüber zu schreiben, wie schlecht es ist.

Betrachten Sie dies bitte als Teil eines anderen Erfahrungsberichts: demjenigen, in dem ich ein _sehr_ lautstarker Gegner des Alias-Vorschlags war, um den Vorschlag dann zu verstehen und jetzt in Aktion zu sehen.

Bearbeiten: Die ursprüngliche Nachricht hatte eine sehr unglückliche Auslassung record of *not* making decisions on a whim hätte der Text sein sollen, leider fehlte der "nicht"-Teil. Ich entschuldige mich dafür.

Ich habe eine detaillierte Beschreibung der grundlegenden Bedenken mit dem Vorschlag. Ich habe versucht, diesen Bericht fertigzustellen, damit ich sie alle auf einmal vorstellen kann – dies ist ein komplexes, subtiles Gebiet, und als solches müssen diese Themen in ihrer Gesamtheit behandelt werden –, aber das Leben und die Arbeit haben das schwierig gemacht.

Obwohl ich auf diesen Artikel in Slack angespielt und Teile davon direkt mit @rsc besprochen habe, habe ich mich entschieden, diese hier bis jetzt nicht zu erwähnen. Es schien mir, dass die Werbung für diesen Artikel, bevor ich bereit war, ihn vollständig zu veröffentlichen, nicht besonders konstruktiv wäre. Aber, wie bereits erwähnt, es sind zwei Monate vergangen, also werde ich einen großen Vorstoß machen, um den Start der Serie nächste Woche herauszubringen.

(Bearbeiten: Dies sind die "Alternativen", auf die sich @theckman bezog)

@sdboyer Sie haben erwähnt, dass Sie mehrere Bedenken haben. Könnten Sie bitte jetzt wenigstens ihre Liste veröffentlichen?
Ich arbeite mit mehreren Systemen, die die Abhängigkeitshölle auf eine andere Ebene bringen (Chef, Go, npm, Composer), und aus Erfahrung ist dieser Vorschlag die Lösung für alle in Bezug auf Go.

@theckman , kannst du bestätigen, dass du dich nur auf das Feedback von @sdboyer bezogen hast? Das ist kein Geheimnis. Sam erwähnte es buchstäblich am ersten Tag, an dem vgo veröffentlicht wurde („ich schreibe detailliertere Dokumente über meine Bedenken“ – https://sdboyer.io/blog/vgo-and-dep/). Aber das ist Feedback, kein Vorschlag, und Sie haben mehrfach auf "andere Vorschläge" im Plural verwiesen. Weißt du noch mehr?

Welche Auswirkungen hat vgo auf go/types-API-Benutzer? Wie ist der aktuelle Stand der go/types-Unterstützung?

Ich habe eine PR mdempsky/gocode#26 erhalten, um eine vgo-fähige go/types.Importer-Implementierung hinzuzufügen, aber es ist mir unklar, ob/warum dies notwendig ist.

Angenommen, es ist notwendig, können wir einen kanonischen vgo-fähigen go/types.Importer an anderer Stelle hinzufügen (z. B. im x/vgo- oder x/tools-Repo), sodass go/types-basierte Tools diese Unterstützung nicht jedes Mal neu implementieren müssen ?

Ich habe die vgo-Details nicht wirklich befolgt, also ist dies vielleicht einfach "keine Auswirkung", aber ich sehe oben keine Erwähnung von go/types. Google-Suchanfragen nach "vgo go/types golang" sind ebenfalls nicht informativ.

Danke.

@mdempsky , der Plan ist, einen Paketlader zu haben, der vgo unterstützt (und für diese Angelegenheit Cache-fähig ist), wahrscheinlich golang.org/x/tools/go/packages, aber er existiert noch nicht. Die Leute sollten auf dieses Paket warten, anstatt Code zu schreiben, der weggeworfen werden muss. Führen Sie die PR nicht zusammen. Ich habe es kommentiert.

@mdempsky wollte in https://github.com/mdempsky/gocode/pull/26 antworten, aber ich werde vorerst hier antworten.

https://github.com/mdempsky/gocode/pull/26 ist vollständig wegwerfbar; nur ein Proof-of-Concept, der eine jetzt aufgegebene CL gegen vgo verwendet.

Ich habe gerade eine @rsc- Antwort gesehen, also weise ich einfach darauf hin, dass unter https://github.com/golang/go/issues/14120#issuecomment -383994980 auch eine Diskussion im Gange ist.

Zusammenfassung: Nach einigen Jahren Erfahrung mit Versionen war der letzte beste Versuch ein sehr komplexer Algorithmus, ein Sat-Solver. Aber wenn Sie einige einfache Änderungen an den Eingabedaten vornehmen, wird das NP-vollständige Entscheidungsproblem nicht nur handhabbar, sondern auch sehr schnell.

Als Go-Anwender in einem kleinen Team mit viel Erfahrung im Umgang mit NPM gefällt mir der vgo-Vorschlag sehr gut. FWIW, ich freue mich darauf, dass vgo in go implementiert wird und je früher es eingeführt wird, desto besser für mein Team und mich.

Nicht, dass ich jemand Besonderes wäre, nur weil ich Diskussionen über kleine Teamprobleme gesehen habe, dachte ich, ich würde mich einschalten.

Hier ist meine Bewertung.

Oberflächlich betrachtet erscheint der _Proposal_-Abschnitt der letzten Überarbeitung des Vorschlagsdokuments in Ordnung, wenn auch nicht sehr spezifisch (z. B. ist unklar, inwieweit Subversion unterstützt werden kann). Eine Ausnahme ist, dass „Verwendung von Herstellerverzeichnissen nicht zulassen, außer in einer eingeschränkten Verwendung“ zu sagen scheint, dass Herstellerverzeichnisse in Nicht-Modul-Paketen überhaupt nicht unterstützt werden; ist das so?

Andererseits impliziert der Vorschlag bestimmte Design- und Implementierungsentscheidungen, die verschiedene Vorteile der aktuellen go get untergraben. Die Verluste mögen akzeptabel sein, einige können abgewendet werden, aber wenn vgo get go get ersetzen soll, sollten sie als Designüberlegungen angegangen und diskutiert werden, da wir sonst möglicherweise mit einem Werkzeug enden, das ist kein angemessener Ersatz, und entweder vgo wird nicht in go zusammengeführt oder go get muss als Drittanbieter-Tool wiederbelebt werden.

Im Abschnitt _Implementation_ heißt es: „In einer späteren Version (z. B. Go 1.13) werden wir die Unterstützung für Go Get von Nicht-Modulen beenden. Die Unterstützung für die Arbeit in GOPATH wird auf unbestimmte Zeit fortgesetzt.“ Das ist mühsam. Erstens gibt es viele gute Projekte, die seit Jahren nicht mehr aktualisiert wurden. Sie funktionieren dank des Go 1-Kompatibilitätsversprechens immer noch, aber viele werden keine go.mod -Dateien hinzufügen. Zweitens zwingt es die Entwickler von Projekten ohne Abhängigkeiten oder diejenigen, die sich nicht um Versionen kümmern, Moduldateien hinzuzufügen oder auf das neue go get -Ökosystem zu verzichten. Sie können berechtigt sein, dies zu wollen, aber erklären Sie bitte warum. (Für mich erscheint es unnötig umständlich; ich würde lieber den Fork des alten go get verwenden. Ich stimme zu, dass Paketmanager für andere Sprachen noch umständlicher sind, und ich bin sicher, dass vgo ist besser als sie, aber es bewältigt meine Anwendungsfälle nicht besser als das aktuelle go get , mit gelegentlicher Hilfe von govendor ).

Mein Hauptanliegen bei vgo vs go ist der von ihnen unterstützte Workflow. Ich hatte es im vgo-intro-Post zum Ausdruck gebracht. Dies könnte im Großen und Ganzen in den Abschnitt _Kompatibilität_ des Vorschlags gehören oder außerhalb seines Anwendungsbereichs liegen, entspricht jedoch anderen hier aufgeworfenen Fragen und Problemen.

Als Referenz ist hier eine Kopie meines vgo-intro-Kommentars.

In einigen späteren Versionen werden wir die Unterstützung für das alte, nicht versionierte go get entfernen.

Während andere Aspekte des Vorschlags gut klingen, ist dieser unglücklich. (So ​​viel, dass ich, wenn ich zwischen der Integration der Versionierung in die go-Toolchain und der Arbeit mit Versionskontrolltools wählen müsste, letzteres wählen würde.) Der Vorteil von vgo besteht darin, dass es reproduzierbare Builds erleichtert und den Abbruch Ihres Projekts verzögert aufgrund inkompatibler Updates, bis Sie als Autor des Projekts (mit der go.mod-Datei) damit konfrontiert werden möchten; aber der Vorteil von go get ist, dass es die Vorteile eines Monorepos in die Multi-Repository-Welt bringt: Aufgrund vollständiger Klone der Abhängigkeiten können Sie damit so einfach arbeiten wie mit Ihrem eigenen Projekt (Historie einsehen, bearbeiten, Diff-Änderungen; gehen Sie zur Definition von allem und beschuldigen Sie es), es erleichtert die Zusammenarbeit (Sie drängen einfach und schlagen Ihre Änderungen vor) und erzwingt im Allgemeinen die Ansicht, dass es zu jeder Zeit nur einen aktuellen Zustand der Welt gibt – die Spitze jedes Projekts – und alles alles andere ist Geschichte. Ich denke, dass dieser einzigartige Ansatz (außerhalb der eigentlichen Monorepos) ein unverwechselbarer Segen des Go-Ökosystems ist, der mehr Gutes als Schlechtes bewirkt hat, und er sollte nicht aufgegeben werden.

Eine subtilere negative Konsequenz des Vorschlags ist, dass er die Versionierung unheilbar und vererbbar macht: Sobald ein Projekt eine Version markiert, kann es nicht erwarten, dass zukünftige Änderungen Benutzer erreichen, ohne neue Versionen zu markieren. Selbst wenn der ursprüngliche Autor entschlossen bleibt, weiterhin zu taggen, sind die Autoren der Forks jetzt gezwungen, sie entweder ebenfalls zu taggen (was besonders umständlich ist, wenn das Quellprojekt noch aktiv ist) oder alte Tags zu löschen.

Insgesamt möchte ich betonen, dass der aktuelle Go-Ansatz zum Abhängigkeitsmanagement der Versionierung insgesamt überlegen ist. Es passt besser zum modernen, dynamischen und kollaborativen Open Source, das erwartet, dass alle Commits sichtbar sind, und es reicht nicht aus, nur die Quellen von Releases zu veröffentlichen (oder „interne Änderungen“ in riesige, nicht beschreibende Commits zu integrieren) (weil es die Sichtbarkeit und Zusammenarbeit stark reduziert). und Dynamik). Sowohl in Monorepos als auch im aktuellen Go-Ökosystem ist zu sehen, dass die meisten Projekte keine Versionen benötigen. Natürlich ist dieser Ansatz nicht der ultimative, er hat Nachteile, und es ist wichtig, auch versionierte Projekte zu unterstützen, aber dies sollte nicht zu Lasten der versionierten Projekte gehen.

Zusammenfassend unterstützt das aktuelle go get (mit Hilfswerkzeugen, z. B. godef ) den Workflow, der Folgendes bietet:

  • editierbarer Quellcode der Abhängigkeiten
  • Quellcode der Abhängigkeiten unter ihrem VCS
  • letzten Revisionen der Abhängigkeiten

Ich schätze, ich kann davon ausgehen, dass der Quellcode der Abhängigkeiten editierbar bleibt, dh godef wird auf _Dateien_ verlinken, die _nicht schreibgeschützt_ sind und _während des Builds_ verwendet werden. Allerdings wird vgo auf die anderen beiden Punkte verzichten. Bezüglich des zweiten Punktes hat #24915 die Unterstützung für VCS-Tools verlängert, erklärt aber weiterhin das Ziel, sie fallen zu lassen; und der Arbeitsablauf erfordert nicht nur, dass Abhängigkeiten aus VCS ausgecheckt werden, sondern auch, dass das Auschecken für Entwickler nützlich ist (z. B. kein flaches Git-Auschecken, kein Git-Auschecken, bei dem .git entfernt wurden) und während des Builds verwendet wird , aber vgo erfüllt diese Anforderung möglicherweise nicht. In Bezug auf den dritten Punkt habe ich seinen Wert im vgo-intro-Kommentar begründet, aber vgo scheint ihn ganz aufzugeben.

Ein Go-Versionierungstool muss die Unterstützung für den aktuellen Workflow nicht aufgeben, und es darf ihn nicht aufgeben, um die einzigartigen Vorteile der Arbeit im Go-Ökosystem zu erhalten und ein angemessener Ersatz für go get zu sein. Das Design von vgo macht dies herausfordernd, aber nicht offensichtlich undurchführbar. Der _Proposal_-Abschnitt des Proposals hingegen scheint nahezu kompatibel mit dem aktuellen Workflow zu sein. Die einzige Herausforderung bei der Unterstützung des dritten Punktes (Auschecken der letzten Revision) – und es ist eine große – ist, dass es schwierig ist, für Module ≥v2.0.0 zu entscheiden, ob sie für master ausgecheckt werden können. master eine andere Hauptversion hat. Dies ist keine Herausforderung für die aktuellen go get mit gopkg.in, da alles standardmäßig bei master ausgecheckt wird und die Sachen bei gopkg.in am passenden Tag oder Zweig ausgecheckt werden; aber vgo verwischt diese Unterscheidung und verbreitet das gopkg.in-Modell auf allen Paketen. (Außerdem hört es auf, Zweige zu finden.) In der Tat wird es unmöglich, sicher zu sagen, und es ist notwendig, zu erraten, wie man die neueste Revision der angegebenen Hauptversion erhält.

Ich habe es vielleicht übersehen, aber wie würde vgo in diesem Szenario funktionieren?

  • Ich arbeite an Dienst A und Dienst B, beide abhängig von lib X (an dem ich auch arbeite)
  • Ich brauche eine größere Änderung in lib X

Bei den derzeitigen Vorgehensweisen nehme ich einfach meine Änderungen vor, kompiliere Dienst A und Dienst B, sie holen alles ab, was in meinem $GOPATH für lib X steht, ich repariere Sachen, dann pushe ich lib X mit einem großen Semver-Bump, dann pushe ich beide Dienste A und B sagen ihnen, dass sie das neue Major von lib X in ihrem Gopkg.toml verwenden sollen.

Wenn jetzt vgo übernimmt, wird go build in meinen Diensten versuchen, eine nicht vorhandene neue Version von lib X von github zu finden, und ich kann alle möglichen Probleme vorhersehen.

Übersehe ich also etwas Offensichtliches?

Für solche Dinge können Sie die Ersetzungsdirektive verwenden.

Am Mo, 30. April 2018, 12:15 schrieb Antoine [email protected] :

Ich habe es vielleicht übersehen, aber wie würde vgo in diesem Szenario funktionieren?

  • Ich arbeite an Dienst A und Dienst B, beide abhängig von lib X (dass ich
    auch weiterarbeiten)
  • Ich brauche eine größere Änderung in lib X

Mit den aktuellen Vorgehensweisen nehme ich einfach meine Änderungen vor, kompiliere Dienst A und
Dienst B, sie holen alles ab, was in meinem $GOPATH für Bibliothek X ist, ich repariere Sachen,
dann pushe ich lib X mit einem großen Semver-Bump, dann pushe ich beide Dienste A und B
ihnen sagen, dass sie das neue Major von lib X in ihrer Gopkg.toml verwenden sollen.

Wenn jetzt vgo übernimmt, bauen Sie auf meinen Diensten auf und versuchen, keine zu finden
vorhandene neue Version von lib X von github, und ich kann alles mögliche vorhersehen
Probleme.

Übersehe ich also etwas Offensichtliches?


Sie erhalten dies, weil Sie erwähnt wurden.
Antworten Sie direkt auf diese E-Mail und zeigen Sie sie auf GitHub an
https://github.com/golang/go/issues/24301#issuecomment-385499702 oder stumm
der Faden
https://github.com/notifications/unsubscribe-auth/AAuFsfnD8_kbUj8fSXvGgeN77ki6KYM6ks5tt2LLgaJpZM4Sg3bp
.

@kardianos ja, aber das bedeutet immer noch, dass ich meine Lib-Änderungen pushen muss, um es zu versuchen?

BEARBEITEN: Es scheint, dass Sie Pfade zum Ersetzen verwenden können (https://github.com/golang/go/issues/24110), was gut ist. Aber ich kann auch vorhersagen, dass dies viele Male begangen werden wird.

Gibt es Pläne, eine zusätzliche Datei wie go.mod.replace oder ähnliches erstellen zu können, damit wir die Überschreibungen in Entwicklungsumgebungen definieren und sie ignorieren können?

@primalmotion Um schlechte Commits zu verhindern, sollten Sie wahrscheinlich einen Git-Hook verwenden.

Aber ich nehme an, die richtige Antwort ist, dies nicht zu oft zu tun (durch lokalen Pfad ersetzen). Wenn Ihre Bibliothek so eng gekoppelt ist, sollte sie nicht in einem separaten Repo leben (und somit so tun, als wäre sie lose gekoppelt). Im Allgemeinen sollten Sie in der Lage sein, diese Bibliothek zu reparieren, zu testen und freizugeben, ohne die aktuelle Implementierung dieser Dienste zu berücksichtigen. Insbesondere bei vgo, die garantieren, dass beide Dienste weiterhin die ältere Lib-Version (die sie zuvor verwendet haben) verwenden, bis Sie sie manuell auf eine neuere Version dieser Lib aktualisieren. Wenn Sie gelegentlich einmal im Jahr lokale Pfade ersetzen, ist das keine große Sache, CI hilft Ihnen dabei, dies in wenigen Minuten zu bemerken und zu beheben.

@primalmotion mit einem nicht versionierten go.mod.replace können Sie ein Projekt übergeben, das nicht reproduzierbar ist. Stattdessen sind Sie mit replace in go.mod sicher, dass Sie genau das übernehmen, was Sie gerade verwenden und testen.
Es kann ein Fehler sein, sich mit einer Ersetzung zu begehen, aber Sie werden es bemerken und korrigieren.
Oder es kann freiwillig sein, ich mache es mit Untermodulen, es ist in Ordnung, wenn Sie an einem Projekt und einer Bibliothek zusammen arbeiten, und es ist reproduzierbar, wenn Sie das Untermodul festschreiben. Ich habe es oft in Python gemacht und es mit Go verpasst. Mit vgo bin ich froh, dass ich wieder so arbeiten kann. _(hoffe, mich mit meinem schlechten Englisch klar auszudrücken, sorry)._

Nun, das Problem ist, dass wir uns nicht um reproduzierbare Builds kümmern, bis wir entscheiden, dass wir uns darum kümmern (dh wenn wir Releases vorbereiten). Wir haben eine sehr flinke Entwicklungsumgebung, in der das Aktualisieren einer Bibliothek nur auschecken, neu erstellen und Tests ausführen muss. Wir schreiben die Gopkg.lock nicht in Master-Zweige unserer Dienste, nur die Toml mit festen Versionen für externe Bibliotheken und großen Einschränkungen für unsere. Sobald wir einen Release-Zweig erstellt haben, übergeben wir die Gopkg.lock und nur dann haben wir reproduzierbare Builds (dies wird von unserem ci durchgeführt).

Vgo bricht im Grunde alle Workflows, die wir im Laufe der Jahre aufgebaut haben. Um jetzt etwas so Dummes wie ein wenig Print-Debugging in einer Bibliothek (weil wir das alle tun, lügen Sie nicht :)) oder eine kleine Optimierung zu versuchen, müssen wir Dutzende von Diensten durchgehen, fügen Sie replace hinzu

Was vgo für uns arbeiten lassen könnte:

  • ein Override-System, wie ich erwähnt habe
  • eine Möglichkeit, es überhaupt nicht zu verwenden und für die Entwicklung auf das gute alte GOPATH zurückzugreifen.

Und wir wollen wirklich, dass es für uns funktioniert, weil es großartig ist.

Können wir etwas in go 1.11 (es ist jetzt eingefroren) oder vielleicht in go 1.12 testen?
Es ist bereits als experimentell markiert. Und ich denke, je mehr Leute es in der realen Entwicklung testen, desto wertvoller wird das Feedback sein.

Ich habe über das Problem mit versionierten Paketen gelesen. Für ein einfaches Szenario, wenn ich eine Bibliothek schreibe, die besagt, verwenden Sie eine dep zum Analysieren von plist namens foo-plist . Als Folge des Parsens stellt diese Plist-Bibliothek bestimmte eigene Typen bereit. Jetzt wird diese Bibliothek auf v2 aktualisiert, und meine Bibliothek muss auf v2 aktualisieren, wenn ich zufällig Objekte dieser plist-Typen zurückgebe.

Dies scheint zum Beispiel ziemlich schwer zu lösen zu sein, wenn ich möchte, dass meine Bibliothek unter dem Eindruck dieses Vorschlags sowohl v1 als auch v2 der genannten plist-Bibliothek unterstützt.

Unter npm kann meine Bibliothek beispielsweise einfach eine Peer-Abhängigkeit angeben, um >=1.0.0|>=2.0.0 zu sagen, und es liegt am Benutzer meiner Bibliothek, zu entscheiden, welche Version von plist verwendet werden soll. Wenn also der Benutzer meiner Bibliothek foo-plist auch eine andere Bibliothek verwendet, die von plist abhängt, und beide Bibliotheken mit v1 und v2 von plist zufrieden sind, kann der Benutzer auswählen, welche tatsächlich importieren. Noch wichtiger ist, dass, wenn beide Bibliotheken Plist-Typen exportieren, diese Typen tatsächlich kompatibel sind.

Wenn es sich dabei um unterschiedliche Importpfade handelt, gibt es meines Erachtens keine Möglichkeiten, dies zu unterstützen.

@itsnotvalid foo-plist.2 kann foo-plist importieren und seine Typen mithilfe von Typaliasnamen erneut exportieren. Eine gute Beschreibung dieser Technik finden Sie hier https://github.com/dtolnay/semver-trick

Aram wies hier auf die Schwierigkeit hin, Änderungen zu früheren Release-Zweigen (oder Verzeichnissen) zurückzuportieren. Da „selbst“-Referenzen auf Quellen innerhalb desselben Moduls auch die Version im Importpfad enthalten, werden entweder Patches nicht sauber importiert oder man kann versehentlich Versionsübergreifende Importe einführen.

Die Gedanken?

Um es klar zu sagen, ich fühle mich mit modulübergreifenden Importen unter Verwendung von Versionen im Importpfad vollkommen wohl; Ich denke, die Argumente von Russ waren sehr überzeugend. Bei Importen innerhalb von Modulen bin ich mir weniger darüber im Klaren. Ich verstehe das Ziel, einen einzigen Importpfad für ein bestimmtes Paket in einem Build zu haben (unabhängig davon, ob es modulübergreifend oder innerhalb eines eigenen Moduls importiert wird), aber wenn ich mich entscheiden müsste, hätte ich lieber eine Lösung dafür Arams Problem, als diese Eigenschaft zu erhalten. (Ich stelle mir auch vor, dass das Build-System die Version aus der Mod-Datei beim Erstellen eines Moduls der obersten Ebene einfügen und sie nach dem Herunterladen einer Modulabhängigkeit buchstäblich in die Quelle einfügen könnte.)

@rsc gibt es eine Chance, dass wir das vorantreiben? Ich sehe nichts Wichtiges, das dies zurückhält.

Es tut mir leid, wenn ich deswegen ungeduldig wirke, aber es gibt immer mehr Tools, die an der Unterstützung für vgo arbeiten, und je mehr wir dies verzögern, desto mehr wird es für uns, die Tool-Betreuer, ein Durcheinander geben, wenn wir hier hin und her gehen .

@sdboyer plant , seine Artikel diese Woche zu veröffentlichen. Ich würde sagen, es ist fair, auf sie zu warten.

Ich denke, dass der Auflösungsalgorithmus für die Auswahl der Abhängigkeitsversionen nicht der Grund sein sollte, den gesamten Vorschlag zu blockieren, der auch Dinge wie Module, die Proxy-Unterstützung, die Versionierung und so weiter enthält.

Und wenn wir uns später entscheiden, den Algorithmus zum Herunterladen dieser Abhängigkeiten zu verbessern/ändern, können wir dies tun, ohne irgendetwas anderes zu beeinflussen.

Ich stimme @dlsniper zu - wir sind bereits weit im Freeze und es ist fast drei Monate her, seit das vgo-Design eingeführt wurde. Wenn sich die Arbeit an 1.11 weiter verzögert, mache ich mir Sorgen, dass es auf 1.12 verschoben wird.

Der erste Beitrag einer Serie ist endlich live . Ich entschuldige mich dafür, dass die Veröffentlichung so lange gedauert hat und dass es noch länger dauern wird, bis die Serie abgeschlossen ist. Aber der erste Beitrag bietet einen breiten Überblick über die Themen, die ich in der gesamten Serie behandeln möchte, sodass die Leute zumindest in der Lage sein sollten, ein Gefühl für den Umfang zu bekommen.

Kurz gesagt: vgo hat viele tolle Dinge, von denen wir uns als Community viele schon lange gewünscht haben. Ich glaube jedoch, dass MVS seinen Zweck nicht erfüllt und es nicht in die Produktion schaffen sollte. Es ist eine Schande, dass so viele dieser Dinge, die wir wollen, um MVS gewickelt wurden, besonders wenn so wenige davon spezifisch dafür sind. Ich arbeite an einem alternativen Ansatz, auf den in der gesamten Blogserie zu Vergleichszwecken verwiesen wird und der im letzten Beitrag artikuliert wird.

Der alternative Kernalgorithmus, an dem ich arbeite, wird wahrscheinlich ziemlich einfach zu go.mod zu migrieren sein, daher gehe ich nicht davon aus, dass wir Probleme haben würden, wenn es wahrscheinlich möglich wäre, dies so weiterzumachen, wie es ist Es wurde eine separate Sperrdatei hinzugefügt, die die transitive Schließung von Abhängigkeiten enthält, und _das_ das ist, woraus der Compiler liest, und nicht der Erstellungslistenalgorithmus. (Es gibt auch andere Gründe für eine Lock-Datei, obwohl das in Post 5 sein wird.) Zumindest gibt uns das ein Ausweichventil.

Wenn wir jedoch sagen, dass MVS in Ordnung ist, auch als Notlösung, dann geht es hinein und gewinnt den Vorteil der Trägheit. An diesem Punkt müssen wir @rsc beweisen, dass es unangemessen ist (obwohl er das schon vor der Zusammenführung als Standard festgelegt hat), und er glaubt, dass dies im Moment eine wahre Aussage über go get ist:

Heutzutage achten viele Programmierer meist nicht auf die Versionierung, und meistens funktioniert alles gut.

In Anbetracht all dessen befürchte ich, dass es zu „Generika, Runde zwei“ führen wird, wenn wir dies jetzt durchgehen lassen – außer dass es dieses Mal um Regeln geht, die bestimmen, wie wir miteinander interagieren, nicht mit Maschinen.

Wenn wir jedoch sagen, dass MVS in Ordnung ist, auch als Notlösung, dann geht es hinein und gewinnt den Vorteil der Trägheit.

Beachten Sie, dass dep im Moment den Vorteil der Trägheit hat (sowohl dadurch, dass es auf den gleichen Prämissen wie Versionsmanager anderer Sprachen aufgebaut ist, als auch länger mit breiter Community-Unterstützung existiert). Zumindest für mich hat der vgo-Vorschlag es dennoch geschafft, diese Trägheit zu überwinden, indem er ein gutes Design war, das von guten Argumenten gestützt wurde.

Ich persönlich habe nichts dagegen, wenn sich die Versionierung in Go verzögert, ich bin dafür, etwas richtig zu machen, anstatt schnell. Aber zumindest im Moment sieht vgo für mich immer noch nach der richtigen Lösung aus (und viele Leute in der AIUI-Community sehen dies als dringendes Problem an).

@mvdan Diese Änderung ist nicht ohne Auswirkungen. Wir alle wollen das, aber ich denke, es ist auch ratsam, sich die zusätzliche Zeit zu nehmen, um Zweifel zu zerstreuen, besonders wenn die Person, die diese Zweifel äußert, eindeutig viel über das Problem nachgedacht hat.

Ich höre immer wieder die Erwähnung des Einfrierens und seiner Auswirkungen auf das Abrufen einer Vorschau von vgo in 1.11 . Was ist die offizielle Linie zu diesem Zeitpunkt, ob dies für 1.11 integriert wird? Dieses Thema scheint mir angesichts der möglichen Auswirkungen überraschend ruhig zu sein.

@sdboyer , was ist Ihre Position dazu, ob dies in 1.11 zusammengeführt werden sollte, wenn man bedenkt, dass Sie Ihre Position zu MVS nur _nur_ offiziell und öffentlich zum Ausdruck gebracht haben?

Wenn dies es nicht in 1.11 schafft, wird es erst ab Februar 2019 für 1.12 offiziell zur Vorschau verfügbar sein und bis mindestens 1.13 im August offiziell veröffentlicht 2019. Damit liegt die früheste mögliche Veröffentlichung 18 Monate, nachdem @rsc erstmals mit der Diskussion darüber begonnen hat. Natürlich sollten wir dies nicht unnötig überstürzen, aber wie @Merovius oben sagte, betrachten viele Menschen, mich eingeschlossen, eine offizielle Antwort auf das Abhängigkeitsmanagement als „dringende“ Angelegenheit. 18 Monate zu warten erscheint mir übertrieben.

Es schien auf jeden Fall, dass dep die offizielle Antwort sein würde, und wir haben unsere Repositories darauf umgestellt (und waren mit den Ergebnissen zufrieden). Mit diesem Vorschlag, der effektiv dep für die langfristige Verwendung ablehnt, aber keinen offiziellen Weg hat, mit der Integration vgo zu beginnen (zumindest bis #25069 zusammengeführt wird), befinden wir uns in der unbefriedigenden Position, dazu gezwungen zu werden Verwenden Sie ein Werkzeug (mit dep ), von dem wir wissen, dass es eine sehr begrenzte Haltbarkeit hat.

FWIW, ich bin absolut der Meinung, dass wir damit weitermachen sollten, indem wir vgo als Vorschlag in 1.11 und #25069 in 1.11 integrieren (und als Patch-Veröffentlichungen für 1.9 und 1.10 nach der Veröffentlichung von 1.11 ).

Ich verstehe ehrlich gesagt nicht die vollen Auswirkungen von MVS und @sdboyers Bedenken darüber. In Anbetracht seiner Erfahrung in diesem Bereich denke ich jedoch, dass diese Bedenken ernsthaft berücksichtigt werden sollten. Das heißt, wenn er mit der Integration vgo in MVS in 1.11 ist (während er versteht, dass sein [noch in Entwicklung befindlicher] Vorschlag, wenn er [für 1.12 ] angenommen wird, keine Module beschädigen darf ursprünglich für MVS entworfen), dann sehe ich keinen Grund, nicht weiterzumachen.

Ich möchte auch @rsc für diesen Vorschlag danken. Ich schätze, dass Go nicht einfach den Ansatz eines anderen Tools kopiert hat und versucht, dieses Problem auf eine Weise anzugehen, die idiomatisch erscheint. Obwohl Abhängigkeitsmanagement niemals Spaß macht, scheint Go mit diesem Vorschlag sicherlich das Potenzial zu haben, die Branche voranzutreiben und möglicherweise sogar Systeme zu überspringen, die derzeit als Best-of-Breed gelten.

Nur um meine 0,02 $ hinzuzufügen, meine Meinung ist, dass MVS ein „Aha“-Moment für das Abhängigkeitsmanagement ist. Ich schätze die vielen Gedanken, die die Leute in diese Richtung gesteckt haben, bin aber weiterhin davon überzeugt, dass MVS der Weg dorthin ist, wo dies hingehen muss.

Ich stimme insbesondere den Punkten zu, die andere angesprochen haben: „Automatische Sicherheitsfixes“ sind bestenfalls ein Wunschtraum und im schlimmsten Fall eine riesige Dose mit Würmern.

Außerdem bin ich bei @joshuarubin : Eine offizielle Antwort auf das Abhängigkeitsmanagement ist ein dringendes Problem. Andere haben kommentiert, dass wir jetzt mit MVS weitermachen und später bei Bedarf zu anderen Lösungen wechseln könnten; Wenn das tatsächlich möglich ist, denke ich, dass das der bessere Weg ist.

Ich schlage vor, Hauptversionen auf folgende Weise von Importpfaden zu entkoppeln. (Ich glaube, dass ich die Argumentation in vgo-import berücksichtigt habe und dass ich die dort angegebenen vgo-Leistungen nicht herabsetze.) Dies ist inspiriert von der Idee aus #25069, dass go build in Go 1.9 und 1.10 lernen sollte Importpfade kreativ interpretieren (indem der Versionsteil weggelassen wird); in meinem Vorschlag ändert sich das alte go build nicht, aber vgo lernt einen ähnlichen Trick.


Syntaktisch sind die einzigen Änderungen die folgenden:

  1. In .go -Dateien bleibt $ import "repo/v2/pkg" import "repo/v2/pkg" , wenn v2 ein Verzeichnis ist, wird aber andernfalls zu import "repo/pkg" . Dadurch bleibt die Kompatibilität mit dem aktuellen go get .
  2. In go.mod -Dateien bleibt module "repo/v2" gleich, wenn es sich im Unterverzeichnis v2 befindet, wird aber zu module "repo" , wenn es sich auf der obersten Ebene befindet. (Dies ist das kanonische Importpräfix.)
  3. In go.mod Dateien können Sie auch require repo v2.3.4 as repo2 schreiben. Dann verwenden Sie in .go -Dateien import "repo2/pkg" (oder import "repo2/v2/pkg" , wenn v2 ein Verzeichnis ist). Dies kann nicht durch das aktuelle go get importiert werden (es sei denn, Sie verwenden etwas wie require github.com/owner/project v2.3.4 as gopkg.in/owner/project.v2 ), aber dies ist nur erforderlich, wenn Sie mehrere Hauptversionen im selben Modul verwenden möchten und die Abhängigkeit dies nicht tut Hauptversionen in Unterverzeichnissen speichern, was von den aktuellen go get sowieso nicht unterstützt werden kann.

Technisch gesehen können Sie damit go.mod schreiben mit:

require repo v1.0.0
require repo v1.1.1 as repo1
require repo v2.2.2 as repo2
require repo v2.3.3 as repo3

aber die minimale Versionsauswahl löst dies so, dass sowohl repo als auch repo1 auf das Repo bei v1.1.1 und repo2 und repo3 $ verweisen bei v2.3.3 . Ich weiß nicht, ob dieses Aliasing erlaubt oder verboten sein sollte.


Vorteile:

  • modulfähiger Code wird mit dem aktuellen go get kompatibel sein, sogar nach v2.0.0; Folglich:

    • keine Notwendigkeit, go get minimal modulbewusst zu machen (#25069)

    • Projekte nach v2.0.0 müssen die Kompatibilität mit dem modulunbewussten go get nicht brechen

  • Projekte müssen nicht warten, bis ihre Abhängigkeiten zu Modulen werden, bevor sie selbst zu Modulen werden [1]
  • keine Notwendigkeit, modulunbewusste Projekte zu verwerfen oder Autoren davon abzuhalten, neue modulunbewusste Projekte zu starten
  • einfachere Unterstützung für den versionlosen Workflow des aktuellen go get ( hier und oben erklärt)

Nachteile:

  • kann unpraktisch sein, das Versprechen zu halten, dass bereits geschriebene go.mod Dateien weiterhin funktionieren (es sei denn, die neue Moduldatei heißt anders als go.mod )

Ambivalenzen:

  • derselbe Importpfad in verschiedenen Modulen kann auf verschiedene Hauptversionen verweisen

    • gut: einfacher zu warten nach v2.0.0 und bei größeren Versionsänderungen

    • schlecht: Sie wissen nicht, welche Hauptversion Sie verwenden, ohne auf go.mod zu schauen

  • Module können beliebige Importpräfixe zur Verwendung in ihrem Code definieren

    • Einige Benutzer entscheiden sich dafür, alles mit einem Kurznamen zu importieren (z. B. import "yaml" mit require gopkg.in/yaml.v2 v2.2.1 as yaml ).

[1] Derzeit kann vgo nicht-modulare Abhängigkeiten nur so lange richtig unterstützen, wie keine nicht-modulare transitive Abhängigkeit eines Moduls älter als v2.0.0 ist. Andernfalls muss das Projekt warten, bis alle Abhängigkeiten, die indirekt von einem Projekt nach v2.0.0 abhängen, zu Modulen werden.

Ich habe eine Analyse der Gopkg.toml-Dateien durchgeführt, die ich aus Paketen in https://github.com/rsc/corpus finden konnte, und eine Zusammenfassung unter https://github.com/zeebo/dep-analysis verfasst. Basierend auf den dortigen Daten scheint es nicht viele Hinweise darauf zu geben, dass vgo nicht in der Lage wäre, fast jeden identifizierten Anwendungsfall zu bewältigen.

Ich hoffe wirklich, dass dies dazu beitragen wird, die Angst in der Community abzubauen und zu einer Einigung zu gelangen, dass wir den Vorschlag unverändert weiterverfolgen sollten, wobei ich daran denke, dass es weitere 6 Monate geben wird, um echte Erfahrungen mit dem Tool zu sammeln und zu machen alle notwendigen Änderungen, um eventuell auftretende Probleme zu beheben.

Wenn ich dich zitiere:

Fast die Hälfte aller Constraints sind eigentlich gar keine Constraints: Sie zeigen auf den Master-Zweig.

Dies liegt wahrscheinlich daran, dass nur der Master existiert und keine Tags oder "benannte Zweige wie v2, v3". Wenn dies der Fall ist, ist der Vergleich nicht fair, da Sie keine Wahl haben!

@mvrhov Ich bin mir nicht sicher, was du mit "nicht fair" meinst. Es scheint mir, dass vgo und dep diesen Fall gut handhaben würden. Oder besser gesagt, jede realistische Alternative müsste diesen Fall problemlos bewältigen. Insbesondere: Wenn es noch keine veröffentlichte Version gibt, könnten sie in einer vgo-Welt einfach mit v1.0/v0.x gekennzeichnet werden, und es wäre keine Änderung an irgendwelchen Importpfaden (der Haupteigenart von vgo) erforderlich.

Soweit ich das beurteilen kann, besteht der Sinn der Analyse darin, zu versuchen, den realen Schmerz abzuschätzen, der durch die verschiedenen Ansätze verursacht wird. Ich verstehe nicht, wie dieser Fall jemandem echte Schmerzen bereitet.

Dieser Vorschlag ist seit über zwei Monaten mit aktiven Diskussionen offen: @rsc & @spf13 haben Feedback-Sitzungen durchgeführt und wertvolle Beiträge aus der Community gesammelt, die zu Überarbeitungen des Vorschlags geführt haben. @rsc hat auch wöchentliche Treffen mit @sdboyer abgehalten, um weiteres Feedback zu erhalten. Es gab wertvolles Feedback zu dem Vorschlag, das zu weiteren Überarbeitungen geführt hat. Zunehmend bezieht sich dieses Feedback eher auf die begleitende Implementierung als auf den Vorschlag. Nach eingehender Prüfung sind wir der Meinung, dass es an der Zeit ist, diesen Vorschlag anzunehmen und das breite Ökosystem von Go-Tool-Implementierern damit beginnen zu lassen, kritische Anpassungen vorzunehmen, damit unsere Benutzerbasis die bestmögliche Erfahrung machen kann.

Es gab zwei Einwände gegen diesen Vorschlag, mit denen wir unserer Meinung nach sprechen sollten:

  1. Der Vorschlag wird von den Menschen verlangen, einige ihrer Praktiken in Bezug auf die Verwendung und Freigabe von Bibliotheken zu ändern.
  2. Der Vorschlag bietet keine technische Lösung für alle möglichen Szenarien, die mit Inkompatibilitäten einhergehen könnten.

Diese sind in ihrer Beobachtung genau, funktionieren aber wie beabsichtigt. Autoren und Benutzer von Code _werden_ einige ihrer Praktiken in Bezug auf die Verwendung und Veröffentlichung von Bibliotheken ändern müssen, so wie sich Entwickler an andere Details von Go angepasst haben, wie z. B. das Ausführen von gofmt. Die Umstellung von Best Practices ist manchmal die richtige Lösung. Ebenso muss vgo nicht alle möglichen Situationen mit Inkompatibilitäten behandeln. Wie Russ kürzlich in seinem Vortrag auf der Gophercon Singapore betonte , besteht die einzige dauerhafte Lösung für Inkompatibilitäten darin, zusammenzuarbeiten, um die Inkompatibilität zu beheben und das Go-Paket-Ökosystem zu erhalten. Temporäre Problemumgehungen in einem Tool wie vgo oder dep müssen nur lange genug funktionieren, um Entwicklern Zeit zu geben, das eigentliche Problem zu lösen, und vgo erledigt diese Aufgabe gut genug.

Wir schätzen all das Feedback und die Leidenschaft, die Sie in dieses wichtige Thema eingebracht haben. Der Vorschlag wurde angenommen.

— Das Go-Proposal-Review-Komitee

Um dem Rekord etwas Farbe zu verleihen, sollten die wöchentlichen Treffen mit @sdboyer nicht als Bestätigung angesehen werden. Sam hat vor kurzem begonnen, über die Probleme mit MVS zu schreiben, zusammen mit den Dingen, die er an vgo mag . Ich füge dies hinzu, um sicherzustellen, dass es keine Missverständnisse für andere gibt, die mitkommen. Wenn Sie seine Meinung wollen, lesen Sie bitte seine Worte. Meiner Meinung nach enthalten sie eine ziemliche Menge an Unstimmigkeiten mit dem derzeit beabsichtigten Ansatz.

@mattfarina FWIW, ich lese diesen Satz eher als "wir sind uns seiner Kritik bewusst (wie er sie privat geäußert hat) und sie hat unsere Meinung nicht geändert". Es ist bedauerlich, dass seine Meinungen und Argumente zu diesem Zeitpunkt jedoch nicht öffentlich sind.

Es fühlt sich unverantwortlich an, einen Vorschlag anzunehmen, wenn noch grundlegende Bedenken bezüglich des Ansatzes offen sind. Ein Konsens zwischen dem Autor und dem Community-Domain-Experten @sdboyer scheint ein vernünftiger Mindeststandard zu sein, der erreicht werden muss, bevor der Vorschlag als angenommen gilt.

@merovius Einige von uns haben öffentlich und privat ihre Meinung geteilt. Viele Leute sind der Meinung, dass die angesprochenen Probleme (manchmal grob) plattgewalzt wurden, anstatt eine ausreichende Lösung zu erhalten. Ich fange an, praktische Probleme öffentlich zu teilen, damit wir versuchen können, sie zu lösen. Zum Beispiel habe ich gerade heute einige Details zu einem praktischen Problem hier geteilt . Lustige Nebenbemerkung, dies war auf der Titelseite der Hacker-News zur gleichen Zeit, als dies als akzeptiert markiert wurde.

@peterbourgon Als eine Person, die die Go Dependency Management-Umfrage durchgeführt und an Glide gearbeitet hat, wo ich auf die Bedürfnisse der Menschen gehört und versucht habe, diese zum Funktionieren zu bringen, kann ich praktische Probleme zeigen (und nicht nur Meinungen). Das heißt, ich kann Wünsche, Bedürfnisse und Erwartungen von Benutzern mit Lösungen für diese Probleme abgleichen. Meine Sorge ist die Nichtübereinstimmung mit dem aktuellen Pfad von vgo. Es gibt unerfüllte Bedürfnisse und pragmatische Probleme aufgrund von Unterschieden in der Art und Weise, wie Menschen Abhängigkeitsmanagement betreiben.

Eine einfache Möglichkeit, meine Bedenken zu zerstreuen, besteht darin, vgo zur Zufriedenheit von Tim Hockins für Kubernetes arbeiten zu lassen.

Eine einfache Möglichkeit, meine Bedenken zu zerstreuen, besteht darin, vgo zur Zufriedenheit von Tim Hockins für Kubernetes arbeiten zu lassen.

vgo heute für Kubernetes arbeiten lassen oder vgo in den kommenden Jahren für Kubernetes arbeiten lassen? So wie ich es verstehe, ist eine der grundlegenden Meinungsverschiedenheiten zwischen vgo und dep, ob wir mit dem Ökosystem arbeiten müssen, wie es heute existiert (Annahme von dep) oder ob wir die Community dazu bringen können, getaggte Veröffentlichungen durchzuführen und die Kompatibilität aufrechtzuerhalten (Annahme von vgo). .

Daher ist es möglich, dass vgo für einige Zeit nicht für Kubernetes funktioniert, die viele Abhängigkeiten verwenden, bis sich die Normen der Go-Community ändern.

@mattfarina Sicher. Ich persönlich finde es jedoch sehr frustrierend, dies als "Dampfwalze" zu malen. @sdboyer hält sich seit Monaten weitgehend aus der öffentlichen Diskussion heraus und es gibt immer noch keine wirklichen, konkreten Argumente von ihm. Er hatte seine Gründe und das ist fair. Aber Konsens muss immer noch diskutiert werden, und zumindest was die öffentlichen Aufzeichnungen betrifft, sind mir persönlich keine Probleme bekannt, die angesprochen und einfach ignoriert wurden (habe Ihren Beitrag jedoch noch nicht gelesen).

Soweit es mich betrifft, fanden alle Diskussionen hinter verschlossenen Türen statt. Und da wir so oder so keine Informationen haben, halte ich es für fair anzunehmen, dass beide Seiten angemessen berücksichtigt wurden.

@bradfitz SemVer wird heute von Go-Paketen verwendet, im Allgemeinen in PHP, in node.js, in Rust und in zahlreichen anderen Sprachen. Es ist eine ziemlich häufige Sache. Ich bin in diesen Sprachen und mehr auf Probleme gestoßen, bei denen Pakete von SemVer-Kompatibilitätsproblemen abbrachen. Manchmal absichtlich und manchmal aus Versehen. Was wird Go anders machen, um ein Problem zu vermeiden, das in all diesen anderen Sprachen vorhanden ist, weil Menschen fehlbar sind?

Wenn wir das nicht artikulieren können, ist es eine schlechte Annahme, dass die Kompatibilität immer aufrechterhalten wird, und Entwickler sollten keine Knöpfe haben, auf die sie zugreifen können, um das abzustimmen und diese Informationen an den Abhängigkeitsbaum weiterzugeben.

Ich denke, alle werden zustimmen: Die aktuelle Situation mit dem Abhängigkeitsmanagement ist schrecklich, in jeder Sprache/Plattform. Ich glaube, @bradfitz hat den Hauptkonfliktpunkt richtig erklärt. Vielleicht wird vgo nicht erfolgreich sein, aber für mich ist es offensichtlich, dass wir etwas ändern müssen (ich meine nicht nur in Go, sondern im Allgemeinen), und vgo sieht sehr vielversprechend aus, es auszuprobieren.

@mattfarina Wir planen, einen Dienst zu implementieren, der automatisch kontrolliert, ob die Kompatibilität tatsächlich aufrechterhalten wird. Die Integration mit godoc.org, die Bereitstellung von Abzeichen für README, die Verwendung als Proxy für go get - es gibt viele Möglichkeiten, wie wir versuchen können, dass es gut genug funktioniert. Sicher, @sdboyer hat recht damit, dass die API-Kompatibilität keine tatsächliche Kompatibilität garantiert, aber das ist ein guter Anfang und sollte in den meisten Fällen gut genug funktionieren.

Daher ist es möglich, dass vgo für einige Zeit nicht für Kubernetes funktioniert, die viele Abhängigkeiten verwenden, bis sich die Normen der Go-Community ändern.

Hoffnung ist keine Strategie, besonders wenn bestehende Verhaltensweisen und Erwartungen bereits fest etabliert sind. Wenn wir diese Diskussion vor fünf Jahren geführt hätten, hätte Go hier vielleicht Innovation-Tokens ausgeben können, und die Dinge ließen sich leichter beeinflussen. Aber nachdem ich das Thema so lange ignoriert habe, scheint es mir klar, dass alle jetzt vorgeschlagenen Tools die Benutzer dort treffen müssen, wo sie sind.

Was wird Go anders machen, um ein Problem zu vermeiden, das in all diesen anderen Sprachen vorhanden ist, weil Menschen fehlbar sind?

Wir haben über eine Art go release -Befehl diskutiert, der sowohl Releases/Tagging vereinfacht als auch API-Kompatibilität prüft (wie der Go-interne go tool api -Checker, den ich für Go-Releases geschrieben habe). Es ist möglicherweise auch in der Lage, godoc.org abzufragen und Aufrufer Ihres Pakets zu finden und ihre Tests auch zur Vorabveröffentlichungszeit mit Ihrer neuen Version durchzuführen, bevor ein Tag übertragen wird. etc.

Finden Sie Aufrufer Ihres Pakets und führen Sie deren Tests auch zur Vorabveröffentlichungszeit mit Ihrer neuen Version durch, bevor ein Tag übertragen wird. etc.

Das ist für jemanden, der nicht Google ist, nicht wirklich praktisch.

Das ist für jemanden, der nicht Google ist, nicht wirklich praktisch.

Angesichts der Tatsache, dass alle Cloud-Anbieter damit beginnen, sekundengenaue Container als Service anzubieten, sehe ich keinen Grund, warum wir dies nicht als Open-Source-Tool anbieten könnten, das jeder ausführen und die 0,57 oder 1,34 US-Dollar zahlen kann, die er benötigt um ein paar Minuten lang eine Bazillion Tests über eine Reihe von Hosts laufen zu lassen.

Es gibt nicht viel Geheimrezept von Google, wenn es um die Durchführung von Tests geht.

Angesichts der Tatsache, dass alle Cloud-Anbieter damit beginnen, sekundengenaue Container als Service anzubieten, sehe ich keinen Grund, warum wir dies nicht als Open-Source-Tool anbieten könnten, das jeder ausführen und die 0,57 oder 1,34 US-Dollar zahlen kann, die er benötigt um ein paar Minuten lang eine Bazillion Tests über eine Reihe von Hosts laufen zu lassen.

Dies erfordert ein Konto bei einem bestimmten Cloud-Anbieter, erfordert, dass Sie die Nutzungsbedingungen eines bestimmten Cloud-Anbieters akzeptieren (was Sie möglicherweise aus rechtlichen Gründen tun können oder nicht, auch wenn die meisten Menschen dies so behandeln, als ob dies nicht der Fall wäre Angelegenheit), erfordert, dass Sie in einem Gebiet leben, in dem der Cloud-Anbieter Dienste anbietet (z. B. wenn Sie sich im Iran befinden und der Cloud-Anbieter in den Vereinigten Staaten ist, können Sie ihn möglicherweise aufgrund von Exportgesetzen nicht nutzen), und dies erfordert Sie haben das Geld, das Sie ausgeben müssen, um den Cloud-Anbieter zu bezahlen (vermutlich jedes Mal, wenn Sie eine Veröffentlichung durchführen). Es ist vielleicht nicht viel Geld, aber das bedeutet nicht, dass jeder in der Lage sein wird, es zu bezahlen. Wenn wir wollen, dass Go inklusiv und für ein vielfältiges Publikum nutzbar ist, scheint dies keine gute Lösung zu sein.

/zwei Cent

@SamWhited MeteorJS hatte dies mit Galaxy, einem eingebauten meteor publish -Befehl, um Ihr Projekt in einem Cloud-Anbieter auszuführen. Vielleicht verstehe ich das aufgeworfene Problem falsch, aber ihr Schwung schien in Ordnung zu sein.

@bradfitz Was ist, wenn sich die API nicht ändert, aber das Verhalten dahinter? Das ist ein Fall, der von SemVer abweicht und diejenigen betrifft, die ihn importieren. Wie erkennen Sie diese Situation? Ich frage, weil ich es mehr als einmal erlebt habe.

Open-Source-Tool, das jeder ausführen und die 0,57 oder 1,34 US-Dollar zahlen kann, die erforderlich sind, um ein paar Minuten lang eine Bazillion Tests auf einer Reihe von Hosts durchzuführen.

Das berührt jetzt die Kosten. Für Leute in einer Technologiestadt in den USA mag sich das gut anfühlen. Was ist mit Menschen in Afrika, Mittelamerika oder anderen Orten, die global verteilt sind? Wie sind solche Tools außerhalb der Kreise der „Tech-Elite“ allgemein zugänglich?

Und was ist mit all den Fällen, in denen Sie keine Public-Cloud-Arbeit machen? On-Premise (viele Leute tun es) oder proprietär und mit Vertrauensproblemen. Wie wird dieses Zeug für sie funktionieren? Wenn Sie über ein internes Tool verfügen, möchten Sie möglicherweise nicht an öffentliche Dienste weitergeben, welche Importe Sie verwenden. Angenommen, Sie beziehen Ihre Importe von GitHub, aber dieser Dienst wird in Google ausgeführt. Fühlen sich die Leute in Ordnung, wenn sie ihren Abhängigkeitsbaum an Google übergeben? Ein Haufen wird nicht.

Es ist möglicherweise auch in der Lage, godoc.org abzufragen und Aufrufer Ihres Pakets zu finden und ihre Tests auch zur Vorabveröffentlichungszeit mit Ihrer neuen Version durchzuführen, bevor ein Tag übertragen wird. etc.

Nehmen wir als Beispiel Kubernetes. Jemand schreibt ein Paket, das in Kubernetes importiert wird. Also muss ein Tool das verstehen und alle Tests durchführen. Teile davon sind so konzipiert, dass sie unter Windows und POSIX laufen. Können wir auf Multi-OS/Multi-Arch testen (da Go damit umgeht). Wie wird das wirklich aussehen (und kosten)?

--

Ich denke, solche Tools können nützlich sein. Ich meine nicht, dass die Leute anders denken. Ich sehe einfach nicht, wie sie das Problem für viele Menschen lösen. Sie sind nicht praktisch genug oder passen nicht zu jedem Setup.

Es fühlt sich an, als würden wir versuchen, ein mathematisches Problem mit bekannten und kontrollierbaren Einschränkungen zu lösen. Aber die Menschen sind chaotisch, also brauchen wir fehlertolerante Lösungen.

Um heute @technosophos zu zitieren:

"Versionsmanager sind nicht wirklich Werkzeuge für Compiler oder Linker oder so ... Versionsmanager sind für Leute, die zusammenarbeiten."

Für das, was es wert ist, hat er mehr als einen Abhängigkeitsmanager geschrieben, andere studiert und mit Leuten gesprochen, die noch mehr geschrieben haben.

Es fühlt sich unverantwortlich an, einen Vorschlag anzunehmen, wenn noch grundlegende Bedenken bezüglich des Ansatzes offen sind. Ein Konsens zwischen dem Autor und dem Community-Domain-Experten @sdboyer scheint ein vernünftiger Mindeststandard zu sein, der erreicht werden muss, bevor der Vorschlag als angenommen gilt.

Nur um hier ein wenig aufzuzählen: Wir haben eine Geschichte rund um Verpackungen, die sowohl nicht standardmäßig als auch suboptimal ist (das go get -Ökosystem). Es wäre besser, einen Standard-Paketmanager einfach aufzugeben, als einen weiteren go get herauszubringen, der die Leute im Namen der Kompatibilität mit dem "Standard"-Tool zu schlechten Praktiken drängt. Als jemand, der Go seit seiner Veröffentlichung verwendet, finde ich dieses Gespräch frustrierend und entmutigend, da es scheint, dass die Führung des Go-Teams die Lektionen aus den Fehlern, die mit go get (nee goinstall ) gemacht wurden, nicht gelernt hat

Es gibt vernünftige und praktische Probleme, die sich zu diesem Vorschlag geäußert haben. Wir sollten den Vorschlag ändern, um sie anzugehen, und nicht einfach sagen: "funktioniert wie beabsichtigt." Wenn wir es für 1.11 oder 1.12 oder 1.13 nicht richtig machen können, sollten wir warten, bis es richtig gemacht werden kann. Dieser Vorschlag schlägt ein System vor, das sich deutlich anders verhält als die meisten anderen Systeme und nicht auf eine gute Weise.

Der motivierende Grund hinter MVS scheint zu sein, dass der traditionelle Ansatz NP-Complete ist. Ich finde das eine sehr schlechte Motivation. Beim Umgang mit NP-vollständigen Problemen lautet die Hauptfrage: "Wie oft treten die harten Instanzen auf." Bei der Paketverwaltung scheint die Antwort "sehr selten" zu sein. Wir sollten uns nicht mit einer unvollständigen und nicht hilfreichen Problemformulierung zufrieden geben, nur um das NP-HARD-Etikett auf dem Problem zu vermeiden.

Die meisten konkreten Punkte wurden von anderen Leuten geäußert, die näher am Thema dran waren ( @sdboyer @peterbourgon @mattfarina etc...). Mein Hauptkritikpunkt ist, dass wir diesen Vorschlag akzeptieren, obwohl diese konkreten Punkte nicht angemessen angegangen wurden.

@SamWhited , Sie stellen ein optionales Feature eines hypothetischen Designs in Frage. Der hypothetische Benutzer, der keinem Cloud-Anbieter vertraut oder keinen Cloud-Anbieter innerhalb der Firewall seines Landes verwenden kann oder nicht zahlen möchte, kann jederzeit Tests (oder einen Bruchteil davon) auf seinem eigenen Computer über Nacht ausführen. Oder nutzen Sie einfach die go release -Signaturprüfung, mit der Sie 95 % des Weges kostenlos erhalten.

@mattfarina , @SamWhited , verschieben wir die Diskussion auf https://github.com/golang/go/issues/25483.

@Mattfarina

Ich bin in diesen Sprachen und mehr auf Probleme gestoßen, bei denen Pakete von SemVer-Kompatibilitätsproblemen abbrachen. Manchmal absichtlich und manchmal aus Versehen. Was wird Go anders machen, um ein Problem zu vermeiden, das in all diesen anderen Sprachen vorhanden ist, weil Menschen fehlbar sind?

Mir ist immer noch nicht klar, warum vgo in diesen Fällen schlechter abschneiden soll als dep. Im Gegenteil, es scheint mir, dass vgo strikt besser abschneidet. In Ihrem Blogpost erwähnen Sie ein konkretes Problem mit helm als Beweis für das Versagen des vgo-Modells. In der vgo-Welt gibt es jedoch zwei Szenarien, warum sich vgo für die Verwendung von v1.4.0 für grpc entschieden hätte:

  1. Die Entwickler von helm haben sich dafür entschieden, grpc >= v1.4.0 in go.mod als Anforderung anzugeben. In diesem Fall können sie diese Anforderung einfach rückgängig machen und so zu einer früheren Version von grpc zurückkehren, die für sie funktioniert.
  2. Die Entwickler einer Abhängigkeit von helm haben sich dafür entschieden, grpc >= v1.4.0 anzugeben. In diesem Fall hätte dep das auch installiert, und wenn helm versuchen würde, ein Rollback durch Einschränkung von grpc < v1.4.0 durchzuführen, müsste dep wegen widersprüchlicher Anforderungen krächzen.

So scheint es mir, dass vgo dieses Problem mindestens so gut löst wie dep. In der Zwischenzeit gibt es in einer tiefen Welt eine andere Option:

  1. Die transitiven Abhängigkeiten von helm erforderten grpc >= v1.x.0 , einige x < 4 , dann gab grpc v1.4.0 frei und dep entschied sich, die neuere Version bei der Installation zu verwenden, ohne gefragt zu werden . In diesem Fall wäre helm kaputt und müsste sich zusammenkauern, um ein Bugfix-Release durchzuführen (wie in Ihrem Beitrag beschrieben), was mühsam wäre. In der Zwischenzeit hätte vgo die neue Version einfach ignoriert und die Dinge würden weiterhin einwandfrei funktionieren.

Ich übersehe anscheinend etwas grundlegendes. Aber als ich das letzte Mal in Slack um Klärung gebeten habe, wurde ich auf einen hypothetischen zukünftigen Blog-Beitrag verwiesen. Daher meine Frustration, weil ich wirklich nicht verstehe, woher die Idee kommt, dass vgo irgendwie mehr Probleme mit Leuten hat, die die Semantik ihrer Versionen brechen, als dep hätte.

Zur Verdeutlichung: Hier geht es nicht um dep . Es ist eine Analyse, wie sich MVS (vgo) im Vergleich zu anderen SAT-Solver-basierten Paketverwaltungslösungen (dep enthalten) verhält.

Ein weiteres Beispiel von Matt besagt Folgendes:

Sie sind der Entwickler des Moduls app und haben zwei Abhängigkeiten:

  • grpc [>= 1.8 ]
  • helm , die die folgende Abhängigkeit haben:

    • grpc [>= 1.0, < 1.4] (weil grpc eine bahnbrechende Änderung in 1.4 eingeführt hat).

Die meisten Leute werden nichts über die transitiven Abhängigkeitsanforderungen wissen ( helm -> grpc [>= 1.0, < 1.4]), weil sie sich bewusst sein müssten, dass helm wann bricht mit grpc >= 1.4. Ich würde davon ausgehen, dass die Mehrheit der Menschen sich nicht darum kümmern oder Zeit und Energie darauf verwenden wird, es zu untersuchen.

Wenn Sie vgo verwenden (insbesondere auf MVS angewiesen), erhalten Sie Folgendes:

  • helm
  • grpc [>= 1.8 ]

Das sollte eine ungültige Kombination sein (da die Anforderungen helm nicht erfüllt sind) und die meisten Abteilungsleiter würden Ihnen eine Fehlermeldung geben, die Ihnen mitteilt, dass Sie einen Konflikt haben (da helm seine Anforderungen in einigen angegeben hat Format).

Dies ist ein wesentlicher Kritikpunkt an MVS und vgo. Es möchte nicht zulassen, dass Abhängigkeiten angeben, wenn sie ein Problem mit einer bestimmten Version haben , um zu vermeiden, dass eine vollständige SAT-Lösung erforderlich ist . Weitere Erläuterungen finden Sie in den Abschnitten Theory und Excluding Modules im MVS-Artikel .

MVS will diese Möglichkeit nicht anerkennen (oder zumindest die Fähigkeit zum Diktieren auf das aktuelle Modul beschränken) unter der Annahme, dass SemVer immer eingehalten wird und dies daher nicht erforderlich ist, was praktisch nicht immer der Fall ist. Ich verweise auf Ihren Artikel über Abwärtskompatibilität , um zu zeigen, warum die Einhaltung der Abwärtskompatibilität schwierig und unpraktisch ist, wenn man den vgo-Weg erzwingt.

Die MVS-Lösung besteht darin, den Modulentwickler aufzufordern , anzugeben, welche Versionen ausgeschlossen werden sollen, und dabei das Wissen zu ignorieren, das von den Autoren der Abhängigkeiten über diese Inkompatibilitäten geteilt werden kann. Somit wird die Verantwortung auf den Entwickler übertragen, die verworrene Logik zu kennen und auszuführen, die die meisten Abteilungsleiter durchlaufen, um herauszufinden, welche Versionen welcher Abhängigkeiten miteinander kompatibel sind (dh eine SAT-Lösung).

Wenn die Leute nicht auf magische Weise anfangen, sich an SemVer anzupassen, würde ich mir vorstellen, eine Abhängigkeit zu installieren, wenn sie vgo verwenden, um sich in eine exzentrische Übung zu verwandeln, bei der Sie nach dem Importieren eines Moduls eine README-Datei überprüfen müssten, um die Liste der nicht kompatiblen Versionen zu kopieren sie in Ihrer go.mod -Datei. Beachten Sie, dass die exclude -Anweisung derzeit nur eine Version akzeptiert.

@Merovius

Im Blogbeitrag von @mattfarina beschreiben sie das absichtliche Upgrade von Helm auf grpc v1.4.0, das entspricht der Aktualisierung von go.mod . Die Frage ist nicht, wie dep oder vgo dieses Problem vermeiden, sondern wie sie es dem Bibliotheksautor ermöglichen, sich davon zu erholen. Im Fall von dep können sie einen Patch veröffentlichen, der die Einschränkung grpc<v1.4.0 enthält. Für Benutzer, die keine andere Abhängigkeit von grpc besitzen, wird dies einfach funktionieren. Wenn ein Benutzer bereits auf die neueste Version von helm aktualisiert hat und eine andere Abhängigkeit von grpc>=v1.4.0 besitzt, führt diese Einschränkung dazu, dass sein Build fehlschlägt. nicht ideal, aber besser als subtil gebrochenes Laufzeitverhalten.

Haben die Helm-Betreuer mit vgo gleichwertige Optionen zur Verfügung? Wenn ein Benutzer aus irgendeinem Grund grpc auf v1.4.0 aktualisiert hat, wählt MVS immer [email protected] , Helm wird beschädigt, und die Helm-Betreuer können nichts dagegen tun (ohne Anpassungen an das geänderte Verhalten, was häufig der Fall ist zeitaufwendig). Ich kann nicht für @mattfarina sprechen, aber so lese ich die geäußerten Bedenken und teile sie. Mit dep und ähnlichen Systemen können sich Zwischenbibliotheken gegen Kompatibilitätsverletzungen mit Beschränkungen der Obergrenzen wehren (oder sich häufiger davon erholen).

@ibrasho @mattfarina

Es scheint, als ob eines von Russ' Beispielen im GopherconSG-Vortrag ein sehr ähnliches (vielleicht identisches?) Szenario abdeckt.

Im obigen Beitrag sagen Sie, dass Helm von "grpc [>= 1.0, < 1.4]" abhängt. Aber das ist nicht ganz genau. Ich denke, Sie meinen, dass eine bestimmte Version von Helm von "grpc [> = 1.0, < 1.4]" abhängt. Nehmen wir an, die Version von helm ist 2.1.3; vermutlich wurde diese Version von helm nach grpc 1.4 veröffentlicht (andernfalls hätte es nicht gewusst, dass es sich selbst als mit grpc 1.4 inkompatibel markiert). Russ' Punkt in diesem Vortrag ist, dass die frühere Version von helm (z. B. 2.1.2) sich vermutlich (noch) nicht als inkompatibel mit grpc 1.4 gekennzeichnet hätte.

Mit anderen Worten, eine zufriedenstellende Zuordnung (laut dep) wäre helm = 2.1.2, grpc = 1.8 gewesen. Dep konnte diese Versionszuweisung ohne Fehler korrekt auswählen, da sie alle Einschränkungen bei den angegebenen Versionen erfüllt.

@balasanjay

Helms Version ändert das Beispiel nicht grundlegend. [email protected] könnte eine Abhängigkeit von [email protected] deklarieren und der Benutzer von helm könnte direkt oder über ein anderes Paket eine Abhängigkeit von [email protected] haben. In diesem Szenario schlägt MVS fehl und installiert [email protected] und [email protected]. Außerdem wird in diesem Beispiel davon ausgegangen, dass der Benutzer absichtlich auf [email protected] (und damit [email protected]) und vielleicht sogar auf [email protected] , [email protected] usw. aktualisiert, bevor das Problem aufgedeckt wird.

MVS verbietet absichtlich Ausschlüsse von Zwischenabhängigkeiten, um seine theoretischen Ziele zu erreichen:

Negative Implikationen (X → ¬ Y, äquivalent ¬ X ∨ ¬ Y: wenn X installiert ist, dann darf Y nicht installiert sein) können nicht hinzugefügt werden...

Für dieses Beispiel müssen wir ausdrücken, wenn X= helm>= 2.1.3 installiert ist, dann darf Y= grpc>=1.4.0 nicht installiert werden, was wir absichtlich nicht tun können.

Tatsächlich haben nur das Paket der obersten Ebene (durch Beheben des Fehlers) und die Benutzer der untersten Ebene (durch manuelles Hinzufügen von Ausschlüssen) einen Rückgriff, wenn Kompatibilitätsregeln verletzt werden. Zwischenprodukte wie Helm müssen mit allen zukünftigen Versionen aller Abhängigkeiten funktionieren, was meiner Meinung nach das Wertversprechen solcher Bibliotheken erheblich reduziert.

Vielleicht fördert dies ein besseres Verhalten in stark genutzten Bibliotheken wie grpc und aws-sdk-go, da die volle Hauptlast eines Bruchs von allen Parteien zu spüren sein wird und schwieriger zu umgehen ist. Allerdings ist es nicht immer so einfach. Was ist, wenn der "Bruch" nicht wirklich ein Bruch ist, sondern eine legitime Verhaltensänderung, die für einige Benutzer unbeabsichtigte Folgen hat, für andere jedoch hilfreich ist? So etwas ist nicht ungewöhnlich, und Upstream-Autoren würden zu Recht zögern, eine Änderung in diesem Szenario rückgängig zu machen.

Ich glaube, ich war nicht annähernd so klar wie Russ. Lass mich es nochmal versuchen.

Anfangs sieht der Zustand von deps so aus.
Helm 2.1.2: grpc >= 1.0

Dann wird grpc 1.4 veröffentlicht. Die Entwickler von Helm erkennen, dass es eine Inkompatibilität gibt, und veröffentlichen daher eine neue Version von Helm:
Helm 2.1.3: grpc >= 1.0, < 1.4

Ich starte eine neue App, die von Helm und einigen neuen Funktionen von grpc abhängt (aus Gründen der Argumentation). Ich liste die folgenden Deps auf:
Helm >= 2.0.0
grpc >= 1.4

Die obige Behauptung war, dass dep den inhärenten Konflikt bemerken und einen Fehler melden würde.

Aber Russ wies darauf hin, dass das nicht stimmt, weil es eine Versionszuweisung ohne Konflikte gibt. Insbesondere könnte sich dep für die Verwendung von helm 2.1.2 und grpc 1.4 entscheiden. Laut dep ist dies eine gültige Zuordnung, da helm 2.1. 3 ist derjenige, der mit grpc 1.4 nicht kompatibel ist, während 2.1. 2 ist kompatibel mit allen grpc >= 1.0.

Mit anderen Worten, dep könnte sich _gültig_ dafür entscheiden, einen Konflikt zu "reparieren", indem er auf eine Version heruntergestuft wird, die den Konflikt noch nicht aufgezeichnet hat. Wenn Sie unveränderliche Versionen haben, scheint dies unvermeidlich. Daher scheint es, dass dep auch https://codeengineered.com/blog/2018/golang-vgo-broken-dep-tree/ misshandeln würde.

@balasanjay Sicher, aber schließlich bringt Helm 2.2.0 mit einer netten neuen Funktion heraus, die Sie wollen, und Sie versuchen, ein Upgrade durchzuführen, und dann tritt das Problem auf.

(Ich bin vorsichtig optimistisch, dass dies gut funktionieren wird, wenn vgo eine gut gestaltete UX hat, um die Menschen darauf aufmerksam zu machen, dass ihr MVS-Ergebnis einen „Konflikt“ dieser Form hat. Mit „gut gestaltet“ meine ich, dass es die Menschen ermutigt, sich damit auseinanderzusetzen das Problem, anstatt die ganze Zeit nur mit vielen Warnungen einverstanden zu sein.)

Ich stimme sicherlich zu, dass es Situationen gibt, in denen dep einen Konflikt erkennt, aber ich wollte nur klarstellen, dass es _nicht_ der Konflikt ist, der in diesem Blogbeitrag präsentiert wird (oder zumindest nicht mit den Versionsanforderungen, wie sie derzeit präsentiert werden).

Und FWIW, ich denke, es ist vernünftig, die Wirksamkeit einer Sicherheitsvorkehrung in Frage zu stellen, wenn sie an einem relativ einfachen Beispiel eines Konflikts bricht.

Fürs Protokoll, ich habe Russ' Beispiel aufgespürt (es ist ziemlich identisch mit diesem, in beeindruckendem Maße): https://youtu.be/F8nrpe0XWRg?t=31m28s

Re: minimale Versionsauswahl, ich habe Probleme herauszufinden, wie ich die folgende Situation lösen kann:

Stellen Sie sich eine beliebte Bibliothek im Wartungsmodus vor, z. B. v1.2.3 ist seit über einem Jahr ohne Änderungen auf dem Markt. Viele andere Bibliotheken hängen davon ab.
Ein Entwickler kommt daher und realisiert eine Geschwindigkeitsoptimierung, die in v1.2.3 vorgenommen werden soll. Es beschleunigt die Kernfunktion der Bibliothek um das 10-fache, ohne API-Änderung! Dies wird als v1.3.0 veröffentlicht. In diesem Paket werden für das folgende Jahr keine Fehler mehr gefunden.

Wie erhalten Angehörige dieses Update? Sie können mit v1.2.3 arbeiten, aber v1.3.0 ist offensichtlich besser.

@daurnimator

Wie erhalten Angehörige dieses Update?

Jede Anwendung müsste 1.3.0 als Mindestversion festlegen, die verwendet werden soll.

Was für ein blöder Tag heute! 😄

Dieser Vorschlag ist seit über zwei Monaten mit aktiven Diskussionen offen

Dieses Problem ist seit Jahren offen, und die Zeitachse, die rsc für all dies festgelegt hat, war alles in allem ziemlich künstlich kurz.

Es gab zwei Einwände gegen diesen Vorschlag, mit denen wir unserer Meinung nach sprechen sollten:

  1. Der Vorschlag bietet keine technische Lösung für alle möglichen Szenarien, die mit Inkompatibilitäten einhergehen könnten.

Wenn dies eine Anspielung auf die Positionen ist, die ich gegenüber Russ skizziert habe, ist es eine irreführende Karikatur. Ein Grund, warum ich so lange gebraucht habe, um meine Gedanken zu diesem Thema zu ordnen, ist, dass die wiederholte Verwendung irreführender Argumente und Aussagen ... offen gesagt, destabilisierend ist.

Buchstäblich niemand denkt, dass ALLE möglichen Szenarien abgedeckt werden können. Das Problem ist und war immer, dass MVS nur ein _illusorisches_ Problem löst (Vermeidung von SAT), stattdessen _neue_ Probleme schafft, die in der Praxis viel wichtiger sind, und nicht effektiv als Zwischenschicht fungieren kann, auf der wir vernünftig operieren können.

Diese sind in ihrer Beobachtung genau, funktionieren aber wie beabsichtigt. Autoren und Benutzer von Code müssen einige ihrer Praktiken in Bezug auf die Verwendung und Veröffentlichung von Bibliotheken ändern, so wie sich Entwickler an andere Details von Go angepasst haben, z. B. das Ausführen von gofmt.

Nichts hilft, wenn man das Ausmaß der hier vorgeschlagenen Änderungen trivialisiert, indem man sie mit der Ausführung von gofmt vergleicht – möglicherweise die geistloseste Aktivität, die wir als Go-Entwickler ausführen.

Wie Russ kürzlich in seinem Vortrag auf der Gophercon Singapur betonte, besteht die einzige dauerhafte Lösung für Inkompatibilitäten darin, zusammenzuarbeiten, um die Inkompatibilität zu beheben und das Go-Paket-Ökosystem zu erhalten. Temporäre Problemumgehungen in einem Tool wie vgo oder dep müssen nur lange genug funktionieren, um Entwicklern Zeit zu geben, das eigentliche Problem zu lösen, und vgo erledigt diese Aufgabe gut genug.

Lassen Sie uns klar sein - was zählt, ist die _Community_. Uns. Die Menschen, die das Software-Ökosystem produzieren. Wir erreichen ein besseres Ökosystem, indem wir Tools entwickeln, die uns helfen, unsere begrenzten Token für nützliche Kooperationen auszugeben – nicht indem wir spröde Tools entwickeln, die uns dafür bestrafen, dass wir überhaupt daran teilnehmen.

@Merovius :

Ich wurde auf einen hypothetischen zukünftigen Blogbeitrag verschoben. Daher meine Frustration, weil ich wirklich nicht verstehe, woher die Idee kommt, dass vgo irgendwie mehr Probleme mit Leuten hat, die die Semantik ihrer Versionen brechen, als dep hätte.

All diese Argumente zusammenzubringen, braucht Zeit, und es ist nicht meine Hauptaufgabe. Ich wollte heute Abend fertig werden, aber ich bin immer noch bei meinem letzten Bearbeitungspass. 😢Morgen früh...? Nichts ist in Stein gemeißelt!

Das Problem ist und war schon immer, dass MVS nur ein illusorisches Problem löst (SAT vermeiden), ...

Bei allem Respekt, IMHO ist die SAT-Lösung keine Lösung, daher löst MVS für mich ein sehr reales Problem.

IMHO ist die SAT-Lösung keine Lösung, daher löst MVS für mich ein sehr reales Problem.

Würde gerne die Argumentation dahinter verstehen, wenn möglich?

Dieses Problem ist seit Jahren offen, und die Zeitachse, die rsc für all dies festgelegt hat, war alles in allem ziemlich künstlich kurz.

Ich sehe hier zwei eindeutig widersprüchliche Ideen. Die Umfragen haben immer wieder gezeigt, dass Abhängigkeitsmanagement früher als später eine Lösung braucht. Ein Zeitrahmen von sechs Monaten reicht jedoch nicht aus, um einen Vorschlag zu prüfen und zu genehmigen.

Ich verstehe, dass wir nicht die erste zu implementierende Lösung auswählen sollten. Aber Zeit ist einer der Faktoren. Der Gegenvorschlag zu vgo ist noch nicht klar definiert und würde sehr wahrscheinlich Jahre brauchen, um zum Leben erweckt zu werden. Ich würde vgo in Go 1.11 jederzeit einer super-genialen SAT-basierten Lösung in Go 1.14 vorziehen.

Dies setzt auch voraus, dass das, was vgo implementiert, in Stein gemeißelt ist. Soweit wir wissen, könnte sich vgo während der Fenster 1.12 und 1.13 erheblich ändern.

Würde gerne die Argumentation dahinter verstehen, wenn möglich?

Es ist die gleiche Argumentation, die hinter der Bevorzugung von Gos Regexp gegenüber PCRE steht, dh. einem Programm nicht erlauben, von einem Algorithmus mit quadratischer/exponentieller Worst-Case-Komplexität abzuhängen.

Wir sollten bedenken, dass vgo nur go get ersetzen wird, nichts weiter, nichts anderes. Wir sollten vgo mit go get vergleichen und nicht vgo mit etwas, das nicht existiert. "Schlimmer ist besser" ! Konzentrieren wir uns nun auf die Implementierungsdetails.

FWIW, es ist IMO durchaus möglich, Obergrenzen einzuführen, ohne einen vollständigen SAT-Löser zu haben - es ist einfach nicht möglich, dass die generierte Lösung optimal ist oder garantiert wird, dass eine vorhandene Lösung gefunden wird. Wenn es sein muss, können Sie

  1. Ermöglicht die Angabe von Obergrenzen
  2. Ignorieren Sie sie beim Lösen über MVS
  3. Überprüfen Sie die gefundene Lösung gegen alle Grenzen und krächzen Sie, wenn sie nicht passt (das ist der Hauptunterschied: Traditionelle Ansätze würden stattdessen versuchen, eine andere Lösung zu finden)

Damit hätte man zwar die Vorteile von MVS (ein einfacher Algorithmus ohne pathologische Laufzeiten), die Möglichkeit, Inkompatibilitäten zu markieren und statisch zu erkennen, aber man verzichtet auf die Garantie, immer eine Lösung zu finden, falls es eine gibt. Obwohl argumentiert werden kann, dass die Lösung, die Sie finden würden , sowieso keine Lösung ist, da die Inkompatibilität immer noch da ist, nur dem Algorithmus unbekannt.

Zumindest für mich scheint es also durchaus möglich zu sein, eine Möglichkeit nachzurüsten, um Obergrenzen für MVS zu erhalten. Ich bin immer noch nicht davon überzeugt, dass es wirklich benötigt wird, aber sollte sich herausstellen, dass es der Fall ist, kann es jederzeit später hinzugefügt werden. Machen Sie die Behauptung „MVS ist grundsätzlich ungeeignet“ problematisch. Aber ich könnte das Problem immer noch falsch verstehen. Und es gibt vielleicht ein Fehlerszenario, das dies besser veranschaulicht?

@sdboyer Keine Sorge. Wie ich bereits sagte, verstehe ich vollkommen, dass dies nicht Ihre Hauptaufgabe ist, und ich schätze die Zeit, die Sie sich nehmen, um daran teilzunehmen. Es ist immer noch eine praktische Frage von "wenn wir die Argumente nicht kennen, können wir nicht darüber reden". Ich kann mir vorstellen, dass du von der ganzen Situation genauso frustriert bist wie ich :)

Es ist die gleiche Argumentation, die hinter der Bevorzugung von Gos Regexp gegenüber PCRE steht, dh. einem Programm nicht erlauben, von einem Algorithmus mit quadratischer/exponentieller Worst-Case-Komplexität abzuhängen.

@cznic Ich bin der Meinung, dass Abhängigkeitsmanagement nicht nur ein technisches Problem ist, sondern mit gesellschaftlichen Zwängen und Überlegungen verflochten ist. Ich bin mir also nicht sicher, ob ich es mit regulären Ausdrücken vergleichen kann (ein rein technisches Implementierungsproblem) und einen Algorithmus zu bevorzugen, der im Wesentlichen auf Zeitkomplexität basiert, ist ein fairer Ansatz.

Ich sehe einige Leute, die MVS bevorzugen, weil es einfacher und leichter zu argumentieren ist, und das ist eine verständliche Überlegung, wenn es die anderen Aspekte des vorliegenden Problems löst.

Ich habe mich gefragt, ob die Leute andere Gründe haben, es einem SAT-basierten Algorithmus vorzuziehen.

Ich habe mich gefragt, ob die Leute andere Gründe haben, es einem SAT-basierten Algorithmus vorzuziehen.

@ibrasho MVS benötigt keine Sperrdatei.

Ich habe mich gefragt, ob die Leute andere Gründe haben, es einem SAT-basierten Algorithmus vorzuziehen.

Persönlich sind meine Gründe

  1. Es vereint Sperrdatei und Manifest in einer Datei, die größtenteils am Computer bearbeitet werden kann. Das bedeutet weniger Rauschen und dennoch reproduzierbare (oder "High-Fidelity") Builds im üblichen Fall. AFAICT, das ist etwas Einzigartiges bei MVS. Da eine meiner größten Frustrationen bei anderen Paketmanagern die Mühe ist, Manifestdateien bearbeiten zu müssen, ist dies für mich enorm.
  2. Eine schrittweise Reparatur wird erleichtert/ermöglicht. Da ich fest an diesen Ansatz zur Lösung des Problems der verteilten Entwicklung glaube, ist dies auch für mich wichtig.
  3. Es kann dem Ökosystem helfen, für die meisten Bibliotheken gemeinsam in der Nähe von HEAD zu bleiben. Dies ist weitgehend Spekulation und hängt etwas von den verfügbaren Werkzeugen ab. Aber wenn ein „Alles auf die neueste Version ziehen“ ausreichend einfach ist, kann es die Kadenz erhöhen, mit der neuere Versionen von Bibliotheken in der Produktion gegeneinander getestet werden.
  4. All dies wird erreicht, während die wünschenswerten Eigenschaften anderer Ansätze, AFAICT, erhalten oder übertroffen werden. Upgrades erfolgen nur auf Wunsch. Und Binärpakete werden auch dann weiter gebaut, wenn der Bau einiger ihrer Abhängigkeiten in einer neuen Version unterbrochen wird, was dem Autor Zeit gibt, an einer Lösung zu arbeiten.

Besonders dieser letzte Teil ist irgendwie ironisch. Denn genau diese Qualität wurde im letzten Beitrag von @sdboyer als äußerst wichtig bezeichnet - aber an diesem Punkt glaube ich immer noch, dass vgo in dieser Hinsicht absolut besser ist als herkömmliche Ansätze.

@Merovius
"Es vereint Lock-Datei und Manifest in einer Datei"

  • Dies ist nicht ganz richtig, da Manifeste effektiv über Ihre Dateien verstreut sind. Importanweisungen fungieren effektiv als Manifeste.

@docmerlin Als ich "Manifest" sagte, meinte ich eine Datei, die alle Module auflistet, von denen Sie abhängig sind, mit ihren entsprechenden Versionen (insbesondere enthält sie strikt mehr Informationen als die Importanweisungen, sonst würden Sie sie nicht benötigen). Im Fall von vgo wäre das go.mod , im Fall von dep ist es Gopkg.toml . Sie könnten dies auch die Konfigurationsdatei für den Abhängigkeitslöser nennen. Wenn Sie einen anderen Begriff für angemessener halten, können Sie ihn gerne durch Manifest ersetzen, wenn Sie meinen Kommentar lesen.

Beachten Sie, dass es ziemlich normal ist, dass es sowohl eine Datei mit allen Abhängigkeiten als auch eine Liste expliziter Importe (die eine potenziell strenge Teilmenge der Abhängigkeiten sind) pro Datei gibt. Insbesondere tun das alle mir bekannten Go-Abhängigkeitsmanager. Andere Ansätze verwenden auch eine Sperrdatei, die bestimmte, genaue Versionen beschreibt, die verwendet werden sollen, um reproduzierbare Builds sicherzustellen. Und das Unterscheidungsmerkmal von MVS, auf das ich mich bezog, ist, dass diese Datei nicht benötigt wird, da sie eindeutig von der Datei manifest/dependency-solver-config/go.mod abgeleitet werden kann.

(gelöscht + neu gepostet von meinem persönlichen Konto)

@cznic Der Fokus auf die Komplexitätsklassen von MVC im Vergleich zu einem SAT-basierten Ansatz macht keinen Sinn (wie ich denke, @sdboyer schreibt irgendwo - wir reden darüber, weil es eines der wenigen Dinge ist, die wir können benennen/identifizieren).

Der Vorschlag von @bradfitz in #25483, einige der Bedenken mit vgo auszuräumen (was meiner Meinung nach eine anfänglich verrückte, aber vielleicht großartige praktische Lösung ist), beinhaltet das Ausführen der Tests von beliebigen Benutzern Ihrer API vor einer Veröffentlichung. Dies ist im Allgemeinen ein NP-vollständiges Problem, aber in der Praxis könnte es eine großartige Lösung sein (genau wie gps2).

Auf der einen Seite haben wir also SAT-basierte Paketverwaltungsalgorithmen, und auf der anderen Seite haben wir einen Algorithmus in NL, der uns zwingt, später NP-vollständige Arbeit zu leisten (oder eine Zeitüberschreitung, was jeder praktische SAT-Löser tun würde). für Adversarial-Lock-Dateien).

die isolierte Fokussierung auf die Komplexitätsklassen von MVC vs. SAT-basiertem Ansatz macht keinen Sinn ...

Ich bin mir nicht sicher, woher der Begriff „Fokus“ kommt. Es ist nur so, dass, wenn zwei Algorithmen verfügbar sind, der schlimmste Fall des einen quadratisch oder schlechter ist und der andere linear oder besser ist, ich mich für den späteren wähle und den ersteren vermeide. Ich würde es ein Prinzip nennen, nicht Fokus.

... Vorschlag in #25483, um einige der Bedenken mit vgo auszuräumen ...

Scheint, als hätte das Problem Nr. 25483 nichts mit vgo zu tun. Tippfehler?

Es ist nur so, dass, wenn zwei Algorithmen verfügbar sind, der schlimmste Fall des einen quadratisch oder schlechter und der andere linear oder besser ist, ich den letzteren wähle und den ersteren vermeide.

@cznic sicher, normalerweise, wenn zwei Algorithmen die gleichen Ergebnisse liefern, möchten Sie den mit geringerer Komplexität (obwohl dies nicht immer so geschnitten und trocken ist - Python verwendet Insertion Sort für kleine Eingaben, da es trotz schlechterer Komplexitätsgrenzen besser ist Konstanten + Laufzeit bis zu einem Punkt).

In diesem Fall (MVS vs. SAT-basierte Algorithmen) unterscheiden sich die Ergebnisse absichtlich und haben weitreichende Konsequenzen. Ich schlage vor, dass Sie aus diesem Grund nicht nur die algorithmische Komplexität vergleichen können, sondern ihre weiteren Auswirkungen berücksichtigen müssen.

Scheint, als hätte das Problem Nr. 25483 nichts mit vgo zu tun

Die erste Zeile in dieser Ausgabe ist ein Link zu Brads Kommentar in dieser Ausgabe: https://github.com/golang/go/issues/24301#issuecomment -390788506 . Obwohl dieses Tool außerhalb von vgo nützlich sein wird, scheint es, als würde es weitgehend in Betracht gezogen, um einige der Nachteile von MVS (meiner Meinung nach/meinem Verständnis nach) zu mildern.

Huch, so viele Kommentare. Ich werde versuchen, einige Details und den Verlauf hinzuzufügen, um zu helfen.

Vor ein paar Jahren gab es eine Reihe verschiedener Abhängigkeitsverwaltungslösungen (z. B. Godep, Glide usw.). Um einen Weg nach vorne zu finden, sind ein paar Dinge passiert:

  1. Eine Gruppe engagierter und sachkundiger Leute kam in einem Komitee zusammen . Beachten Sie, dass ein Go-Teammitglied bei Google Teil dieser Gruppe war.
  2. Eine zweite Gruppe von Personen, die Abhängigkeitsmanager erstellt hatten oder über Informationen darüber verfügten, unterstützte diese erste Gruppe.
  3. Es wurde eine Umfrage unter der Community zu den Bedürfnissen und Gedanken zu bestehenden Tools (in Go und außerhalb von Go) durchgeführt . Beachten Sie, dass einige Ergebnisse nur für die Augen des Ausschusses privat waren.
  4. Unternehmen, die Go für die Produktion verwenden, wurden befragt, um Einzelheiten zu ihren Anforderungen zu erfahren. Die Details davon sind nicht öffentlich, so dass die Leute frei sprechen konnten.

Die Umfrage- und Interviewdaten wurden alle in das Komitee zurückgeführt. Nachdem sie sich die Daten angesehen und diskutiert hatten, entschieden sie, dass wir eine Lösung mit bestimmten Funktionen brauchten, und erstellten eine Spezifikation . Danach begann die Entwicklung von dep, diesen Anforderungen gerecht zu werden.

Auf der Gophercon im letzten Jahr gab es einen Contributor Summit , bei dem Leute, die sich mit Abhängigkeitsmanagement beschäftigten, darüber sprachen. Gegen Ende dieser Gespräche kam Russ an den Tisch und sagte so etwas wie: Ich kann es besser, wenn ich alleine losziehe und etwas aufbaue. Er tat das und entwickelte vgo. Es wurde getrennt von der Gemeinschaft durchgeführt.

Erfüllt vgo die in der Umfrage und den Interviews geäußerten Bedürfnisse? Nach dem, was ich von Russ verstehe, hat er die Ergebnisse nicht gelesen, aber er hat den Prozess kritisiert. Es könnte sich lohnen, dass jemand ein Mapping durchführt.

Oh, auf dem Gipfel teilte Russ einen der Gründe mit, dass er damals keinen SAT-Löser mochte. Er wollte eine Lösung mit weniger Codezeilen, weil er nicht wollte, dass das Go-Team bei Google so viel Code verwaltet. Ich erinnere mich besonders daran, weil ich danach einige LOC-Vergleiche zwischen Tiefen-, Gleit- und anderen Werkzeugen durchgeführt habe, um ein besseres Bild von den Unterschieden zu bekommen.

Go ist ein von Google betriebenes Projekt. Wenn es um Ressourcen geht, sollte Go unter eine Stiftung gestellt werden und Menschen aus anderen Organisationen in Besitz genommen werden? Dies ist eine weitere Möglichkeit, Ressourcen zur Wartung der Toolchain hinzuzufügen.

Nein, #25483 hat nichts mit vgo zu tun. Ich habe es nur beiläufig als etwas anderes aufgeführt, was ein hypothetischer go release Hilfsbefehl tun könnte. Aber es wäre jederzeit nützlich.

Mein wichtiger Punkt war, dass Go es nie super einfach gemacht hat, Releases von Go-Paketen zu erstellen. In einem früheren Leben habe ich http://search.cpan.org/dist/ShipIt/ geschrieben, um die Veröffentlichung von Perl-CPAN-Paketen zu automatisieren, und es machte einen großen Unterschied, wenn Sie solche Dinge mit Werkzeugen umgehen konnten, anstatt es von Hand zu tun.

Ich habe überhaupt nur ein hypothetisches go release erwähnt, weil ich gefragt wurde, was Go anders machen könnte, um Menschen dabei zu helfen, keine Fehler zu machen.

Das einzige eigentliche Problem, das ich mit vgo sehe, scheint trivial zu beheben ... das Problem mit der maximalen Version. Wenn eine Bibliothek mit v1.7 einer Dep bricht, gibt es keine andere Möglichkeit, dies anzugeben als einen Ausschluss ... was nur hilft, bis v1.8 herauskommt, das wahrscheinlich immer noch auf genau die gleiche Weise kaputt ist.

Es scheint trivial zu sein, max version zu vgo hinzuzufügen, nur um vgo dabei zu helfen, festzustellen, wann zwei Bibliotheken inkompatibel sind. Wenn eine Bibliothek sagt, dass sie mindestens v1.7 benötigt, und eine Bibliothek sagt, dass sie benötigt wird

Ohne dies verwendet vgo nur 1.7 und eine der Bibliotheken wird kaputt gehen. Wenn Sie Glück haben, gibt es einen Compiler-Fehler. Wahrscheinlicher ist nur ein subtiler Verhaltensfehler, der möglicherweise erst später bemerkt wird. Und was heimtückisch ist, ist, dass es sich wahrscheinlich um eine transitive Abhängigkeit handelt, die Sie nicht einmal direkt aufrufen.

Max-Versionsbeschränkungen von @natefinch stoßen MVS aus seinem sehr cleveren Vermeidungs-SMT-Solver-Territorium.

Ich denke, @natefinch bedeutet maximale Versionen als letzte Prüfung / Filter. Sobald MVS seine Arbeit erledigt hat, würde vgo einen Fehler verursachen, wenn eine dieser Max-Version-Einschränkungen nicht erfüllt wäre. Das bringt uns immer noch nicht in das Gebiet des SAT-Lösers.

Exakt. Es gibt keine Lösung. Es gibt nur "vgo sagt, dass 1.7 das Richtige ist, aber Modul X gibt an, dass es mit dieser Version nicht funktioniert". Dies kann bereits heute mit vgo passieren, wenn Sie etwas haben, das require foo 1.7 und etwas anderes exclude foo 1.7 sagt, wenn es keine höhere foo-Version gibt.

Und was soll man dann machen?

Sie verwenden Ihr menschliches Gehirn, um eine Lösung zu finden, weil es keine mechanische Lösung gibt. Sie versuchen, zwei Bibliotheken zu verwenden, die kategorisch angeben, dass sie inkompatible Versionen einer Bibliothek erfordern. A wird mit 1.6 brechen, B wird mit 1.7 brechen. Das Ende.

Sie müssen entweder den Autor der Abhängigkeit überzeugen, den Fehler zu beheben (wenn es sich um einen Fehler handelt), einen der Bibliotheksautoren davon überzeugen, eine neue Version zu veröffentlichen, die mit der neuen Version der Abhängigkeit kompatibel ist, oder eine ganze Reihe von Dingen forken und selbst beheben .

Es gibt keine gute Antwort. Aber es gibt auch kein Werkzeug der Welt, das dies für Sie beheben kann.

@sdboyer

Das Problem ist und war immer, dass MVS nur ein illusorisches Problem löst (Vermeidung von SAT),

Ich kann nicht zu Ihren privaten Gesprächen mit Russ sprechen, aber „SAT zu vermeiden“ erscheint mir wie ein Strohmannargument. „SAT vermeiden“ ist ebenso wenig ein Ziel wie „SAT nutzen“: Beides hat keine konkreten Auswirkungen auf die Nutzer.

Aus meiner Sicht sind die konkreten Probleme, die MVS löst, folgende:

  • Builds standardmäßig reproduzierbar machen,
  • so nah wie möglich an den getesteten Versionen bauen, und
  • falsche Ablehnungen zu vermeiden.

Wir erreichen ein besseres Ökosystem, indem wir Tools entwickeln, die uns helfen, unsere begrenzten Token für nützliche Kooperationen auszugeben – nicht indem wir spröde Tools entwickeln, die uns dafür bestrafen, dass wir überhaupt daran teilnehmen.

Ich stimme zu. Aber ich möchte mal genauer auf Ihre Vermutungen eingehen: Welche Tools „bestrafen“ Partizipation und warum?

Eines der Beispiele, die Sie in Ihrem Beitrag gegeben haben, war: „Unser Projekt hängt derzeit von [email protected] ab, aber es funktioniert nicht mit [email protected] oder neuer. Wir wollen gute Bürger sein und uns anpassen, aber wir haben im Moment einfach nicht die Bandbreite.“


Die erste (implizite) Annahme, die Sie treffen, ist, dass Sie (oder Ihre Benutzer) die Zeit und Bandbreite hatten, Ihr Projekt umfassend gegen alle Versionen seiner Abhängigkeiten zu testen.¹ Für einige Projekte kann diese Annahme an und für sich nicht gelten : Indem Sie die Erwartung setzen, dass jeder Obergrenzen markiert, wenn er Inkompatibilitäten entdeckt, „bestrafen“ Sie am Ende Betreuer, die nicht die Bandbreite haben, um potenziell alle ihre Veröffentlichungen auf Regressionen zu testen und Grenzen zu aktualisieren.

Im Gegensatz dazu müssen Betreuer unter MVS nur eines angeben: „Wir haben gründlich gegen [email protected] getestet und es hat funktioniert.“ Wenn Ihre Benutzer nichts tun, um das zu stören, bauen sie gegen [email protected] und alles funktioniert weiter wie zuvor.

Unter MVS tritt _Bruch nur zum Zeitpunkt eines expliziten Upgrades auf._ Das ist ein erheblicher Vorteil: Wenn Ihr Benutzer eine andere Abhängigkeit aktualisiert, sodass sie [email protected] einzieht und ihre Verwendung Ihres Pakets unterbricht, dann können sie das einfach tun Setzen Sie dieses Upgrade zurück, bis Sie Zeit haben, es zu beheben, _oder bis der Betreuer von X Zeit hat, die Inkompatibilität zu beheben._ Und wenn Sie die richtigen Erwartungen haben, ist Letzteres viel wahrscheinlicher als Ersteres: Ausklinken [email protected] kann sich als unnötige Arbeit erweisen, wenn [email protected] die Kompatibilität wiederherstellt.


Die zweite Annahme, die Sie treffen, ist, dass jede Inkompatibilität, die _irgendeinen Teil_ Ihres Moduls betrifft, _alle Benutzer_ Ihres Moduls betrifft. Wenn der Teil Ihres Pakets, der unter [email protected] abstürzt, eine wenig genutzte Funktion ist, warum sollten Sie dann Ihre Benutzer davon abhalten, X in ihrem Programm zu aktualisieren, das sie nicht einmal aufruft?

Sie könnten argumentieren, dass einige Teile des Moduls, wenn sie nicht von anderen Teilen abhängen, separate Module sein sollten, aber das zwingt Paketbetreuer wieder zu zusätzlicher Arbeit: Wenn ich nur die Bandbreite habe, um regelmäßig zu testen und zu aktualisieren, habe ich vielleicht nur die Bandbreite, um ein Modul zu verwalten, nicht einen ganzen Komplex von feinkörnigen Modulen mit feinkörnigen Abhängigkeiten.


¹ Im Allgemeinen erfordert das Erkennen von Inkompatibilitäten mit Abhängigkeiten, dass Sie gegen _das Kreuzprodukt aller Versionen_ dieser Abhängigkeiten testen: Es ist möglich, dass Ihre spezielle Verwendung von [email protected] in Ordnung ist, aber in Kombination mit einem anderen Paket, von dem Sie abhängen, bricht es zusammen an. Beispielsweise benötigen Sie und Ihre Abhängigkeit möglicherweise inkompatible Optionen in einer globalen Konfiguration.

Sie können dieses Upgrade einfach rückgängig machen

Das setzt voraus, dass es sich um einen Compilerfehler oder etwas ähnlich gut sichtbares handelt. Es ist viel wahrscheinlicher, dass es sich um einen subtilen Verhaltensfehler handelt, der nicht sofort offensichtlich ist. Sie aktualisieren, führen Ihre Tests durch und alles sieht gut aus. Vielleicht ist ein Timeout von 10 Sekunden jetzt 30, und das wirft die Timeouts im Rest Ihres Stapels unter Last ab. Sie würden es nicht bemerken, bis es in der Produktion läuft (etwas Ähnliches ist uns vor einigen Jahren mit einem Wechsel in mgo passiert).

Wenn der Teil Ihres Pakets, der unter [email protected] kaputt geht, eine wenig genutzte Funktion ist, warum sollten Sie dann Ihre Benutzer davon abhalten, X in ihrem Programm zu aktualisieren, das es nicht einmal aufruft?

Weil sie wahrscheinlich nicht wissen, ob sie diese Funktion verwenden oder nicht, wenn es sich um eine transitive Abhängigkeit handelt, und wer sagt, dass ein ungenutzter Codepfad nicht plötzlich aktiviert wird, wenn Sie Ihren Code ändern? Diese kaputte Funktion wird jetzt also aufgerufen. Es ist viel besser, dem Bibliotheksverwalter zu vertrauen, der ein Experte darin ist, seine eigene Bibliothek zu verstehen, dass, wenn er sagt, dass es mit 1.7 nicht funktioniert, nicht mit 1.7 gebaut wird.

Das setzt voraus, dass es sich um einen Compilerfehler oder etwas ähnlich gut sichtbares handelt. Es ist viel wahrscheinlicher, dass es sich um einen subtilen Verhaltensfehler handelt, der nicht sofort offensichtlich ist.

In fast jeder Version von fast jedem Softwarepaket lauern subtile Fehler. Wir markieren Releases im Allgemeinen nicht als völlig unbrauchbar, nur weil wir einen solchen Fehler gefunden haben; Stattdessen beheben wir es in einer späteren Punktversion.

Was macht diese spezielle Käferklasse so besonders?

Wer sagt denn, dass ein unbenutzter Codepfad später nicht plötzlich aktiviert wird, wenn Sie Ihren Code ändern?

Das ist genau das MVS-Argument: Wenn Sie Ihren Code ändern, erkennen Sie den Bruch _bei dieser Revision_ und Sie können die Versionseinschränkung auch bei dieser Revision aktualisieren.

Das bedeutet, dass es als Benutzer einfacher ist, Fehler zu halbieren, wenn Sie Ihre Abhängigkeiten einzeln statt in großen Mengen aktualisieren, aber das gilt für Änderungen im Allgemeinen: Je kleiner Ihre Änderungen sind, desto präziser können Sie Halbieren Sie sie, unabhängig davon, ob es sich um Änderungen an Ihrem Code oder seinen Abhängigkeiten handelt.

Was macht diese spezielle Käferklasse so besonders?

Es ist nicht nur ein Fehler. Es ist größer als das. Der Bibliotheksautor, der der beste Experte für ihren Code ist, hat der Welt gesagt: „Yo, Version 1.7 von X macht meine Sachen auf so schlimme Weise kaputt, bauen Sie einfach nicht einmal damit.“

Sofern es sich nicht um einen Compilerfehler handelt, handelt es sich eindeutig um eine Entscheidung. Wenn 99 Ihrer Funktionen in Panik geraten, aber eine nicht ... ist das nur ein Fehler? Oder ist es eine komplette Inkompatibilität? Was ist, wenn nur eine Funktion in Panik gerät?

Irgendwann muss ein Mensch diese Entscheidung treffen. Ich würde mich viel lieber mit einer präventiv deklarierten Inkompatibilität befassen, die während der Erstellungszeit auftritt, als mir Sorgen über ein nicht deklariertes schwerwiegendes Problem zu machen, das es in die Produktion schafft.

Es ist nicht nur ein Fehler. Es ist größer als das. Der Bibliotheksautor, der der beste Experte für ihren Code ist, hat der Welt gesagt: „Yo, Version 1.7 von X macht meine Sachen auf so schlimme Weise kaputt, bauen Sie einfach nicht einmal damit.“

Es gibt eine andere Möglichkeit für einen Bibliotheksautor, dies auszudrücken: Schreiben Sie einen Test, der fehlschlägt, wenn er mit einer inkompatiblen Version von X verwendet wird. Dies hat den Vorteil, dass keine Änderungen an der Bibliothek erforderlich sind, wenn X eine gefixte Version herausgibt, und auch keine Änderungen abfangen zukünftige Regressionen.

Schreiben Sie einen Test, der fehlschlägt, wenn er mit einer inkompatiblen Version von X verwendet wird.

Ja, daran habe ich gedacht. Aber dann bitten Sie jede Binärdatei der obersten Ebene, alle Tests für alle transitiven Abhängigkeiten auszuführen, Tests, die möglicherweise eine Infrastruktur erfordern, die Sie nicht haben. Nicht alle Testsuiten sind zu 100 % isoliert.

Es gibt einen Grund, warum go test ./... keine Tests im Vendor-Verzeichnis ausführt.

Zusammenfassend (wahrscheinlich schlecht) scheint das wichtigste technische Argument gegen vgo zu sein, dass es eine Möglichkeit für Bibliotheken geben muss, global respektierte Einschränkungen für ihre eigenen Abhängigkeiten zu deklarieren.

Warum nicht beide Seiten vereinbaren, einen konkurrierenden Vorschlag zu genehmigen, der untersucht, wie GPS2 in die Teile von vgo passen könnte, die beiden Seiten gefallen. Dann das vgo-Experiment in der Zwischenzeit zusammenführen und den GPS2-Vorschlag erneut überprüfen, bevor vgo die Hauptlinie zusammenführt?

Als jemand, der in der Vergangenheit mit vielen Abhängigkeitstools zu kämpfen hatte, freue ich mich auf vgo. FWIW, als "Community"-Mitglied fühle ich mich durch die vgo-Lösung weithin gut vertreten. Ich bin jedoch offen dafür, die Argumente für das Hinzufügen globaler Versionseinschränkungen zu prüfen, und freue mich darauf, dass sich dieses Argument weiter entwickelt.

Wirf das einfach hier raus:

Das setzt voraus, dass es sich um einen Compilerfehler oder etwas ähnlich gut sichtbares handelt. Es ist viel wahrscheinlicher, dass es sich um einen subtilen Verhaltensfehler handelt, der nicht sofort offensichtlich ist. Sie aktualisieren, führen Ihre Tests durch und alles sieht gut aus. Vielleicht ist ein Timeout von 10 Sekunden jetzt 30, und das wirft die Timeouts im Rest Ihres Stapels unter Last ab.

Dies ist ein Problem in der Software im Allgemeinen. NPM (das andere Versionierungstool, mit dem ich persönlich am besten vertraut bin) verwendet einen SAT-Solver in Kombination mit einer Community, die Semver stark unterstützt, und dieses Problem besteht immer noch.

Was die Diskussion über transitive Abhängigkeiten betrifft, so gibt es in Wirklichkeit keinen Zauberstab: Irgendwann muss sich der Entwickler der von ihm verwendeten Abhängigkeiten bewusst sein und sich die Zeit nehmen, den Code, für den er letztendlich verantwortlich ist, ordnungsgemäß zu testen. Mein Arbeitgeber kann nicht der einzige sein, bei dem wir aus rechtlichen und anderen Gründen verpflichtet sind, jede von uns verwendete Bibliothek zu rechtfertigen, einschließlich transitiver Bibliotheken.

Ehrlich gesagt scheinen viele der Beschwerden gegenüber vgo in meinen Augen zu lauten: "Es ist nicht perfekt, deshalb wird es nicht funktionieren". Lassen Sie es uns nicht versäumen, aus Mangel an einer perfekten Lösung eine gute Lösung zu implementieren.

Für mich scheint es sehr gut mit der allgemeinen Go-Philosophie übereinzustimmen, dass das Kernteam ein Werkzeug bereitstellt, das in den meisten Situationen gut ist, und es der Community überlässt, fortgeschrittenere und/oder spezifischere Werkzeuge bereitzustellen.

@malexdev Es kann ein Problem mit Ihren Schauspielern in der Argumentation geben, dass:

Lassen Sie es uns nicht versäumen, aus Mangel an einer perfekten Lösung eine gute Lösung zu implementieren.

dep ist heute eine gute Lösung. Eine, die durch die Zusammenarbeit der Community geschaffen wurde. vgo macht, wie zuvor begonnen, ein paar Annahmen:

  1. Dass niemand jemals aus Semver brechen wird, nicht einmal aus Versehen
  2. Dass wir die bestehenden Codebasen im bestehenden Ökosystem überarbeiten müssen

vgo basiert mehr auf der „perfekten Lösung“ in einer „perfekten Welt“, während dep heute dem folgt, was bereits in anderen Programmiersprachen-Ökosystemen funktioniert, und gleichzeitig fehlertolerant ist.

Sie können dies in der Historie des Paketverwaltungs-Problembereichs sehen, den ich gerade geschrieben habe .

Zusammenfassend (wahrscheinlich schlecht) scheint das wichtigste technische Argument gegen vgo zu sein, dass es eine Möglichkeit für Bibliotheken geben muss, global respektierte Einschränkungen für ihre eigenen Abhängigkeiten zu deklarieren.

Ich stimme dieser Zusammenfassung zu.

Warum nicht beide Seiten vereinbaren, einen konkurrierenden Vorschlag zu genehmigen, der untersucht, wie GPS2 in die Teile von vgo passen könnte, die beiden Seiten gefallen.

An diesem Punkt bin ich noch nicht davon überzeugt, dass GPS2 eine Notwendigkeit oder sogar eine gute Idee ist. Die Fähigkeit, die Sie oben beschrieben haben, kann auf vgo auf MVS nachgerüstet werden (wie this oder this ). Ich persönlich hoffe, dass der nächste Blog-Beitrag von @sdboyer gute Argumente gegen MVS selbst enthalten wird, aber im Moment sehe ich nicht wirklich einen Grund für einen anderen Algorithmus - insbesondere einen, der erhebliche UX-Vorteile von vgo kosten würde.

Allerdings sehe ich ehrlich gesagt auch keinen Grund dagegen, damit zu experimentieren.

dep ist heute eine gute Lösung.

Ich bin nicht sicher, ob ich einverstanden bin. Ich habe es selbst nicht verwendet, aber dort, wo sich mehrere Leute über Probleme beschwerten, die direkt auf den SAT-Lösungsansatz zurückzuführen zu sein scheinen. Und ich weiß, dass ich sehr unzufrieden mit dem Gesamtdesign von deps bin (abgesehen von der Frage des Abhängigkeitslösers selbst, also allgemeiner Workflow und UX).

  1. Dass niemand jemals aus Semver brechen wird, nicht einmal aus Versehen

Es tut mir leid, aber ich habe wiederholt nach einer Begründung für diese Aussage gefragt und keine bekommen. Warum sollte vgo dies in irgendeiner Weise annehmen, mehr formen oder formen als dep? Dieser Aussage stimme ich grundsätzlich nicht zu. Es ist eine Annahme, die gemacht wird, um den Algorithmus zu erklären. So wie Sie den Algorithmus von dep erklären würden, würden Sie die Annahmen erklären, die in semantische Versionen eingebaut sind. Im schlimmsten Fall zeigen sie die gleichen Brüche, wenn Sie diese Semantik nicht einhalten.


Ich denke, im Allgemeinen ist es sinnvoll, zwischen verschiedenen Teilen dessen zu unterscheiden, worüber wir sprechen. Einige der Beschwerden betreffen SIV, einige MVS und einige die allgemeine vgo-Shell. Es stimmt beispielsweise, dass MVS keine oberen Versionsgrenzen handhaben kann, aber das bedeutet nicht, dass vgo keine oberen Versionsgrenzen handhaben könnte. SIV erfordert das Ändern einer Menge Code da draußen (durch Umschreiben von Importanweisungen), aber das bedeutet noch nicht einmal unbedingt, dass vgo dies erfordern würde. Um es klar zu sagen, ich denke auch nicht, dass es eine so große Sache ist, solange wir migrieren können. Welche AFAICT wir können.

Ich habe mir gerade die GopherConSG - Eröffnungsrede von @rsc über Versionierung angesehen. Er ging auf das Szenario ein, in dem eine Abhängigkeit eine Breaking Change einführt, und verglich, wie vgo und dep damit umgehen würden, was hier das Hauptanliegen zu sein scheint. (Es ist eine großartige Uhr.)

Wenn ich seinen Punkt richtig verstanden habe, kann dep den Build auch beschädigen, wenn eine maximale Versionsbeschränkung verwendet wird, um eine schlechte Version zu vermeiden . Ich wäre sehr daran interessiert zu sehen, dass dieser Punkt von denen hier angesprochen wird, die besorgt sind, dass vgo in dieser Hinsicht hinter dep zurückbleibt.

@willfaught Für uns ist es ein Erfolg, den Build zu unterbrechen, wenn eine maximale Versionsbeschränkung verwendet wird, um eine schlechte Version zu vermeiden! Das wollen wir erreichen. Russ weist zu Recht darauf hin, dass dieses Problem nicht automatisch behoben wird. Eine Beschränkung auf Helm>2.0.0 wird den Benutzer nicht automatisch auf „ [email protected] “ upgraden, aber es würde erfolgreich funktionieren (grpc herunterstufen oder einen Build-Fehler auslösen, wenn dies unmöglich ist), wenn der Benutzer ausdrücklich von „Helm ==2.1.4". Persönlich versuche ich normalerweise als Erstes, wenn ich auf ein Problem mit einer Bibliothek stoße, ein Update auf die neueste Version zu erzwingen. Bei Dep würde mich dies über den durch GRPC 1.4.0 eingeführten Fehler informieren. Bei vgo kann Helm mir dies nur durch Dokumentation mitteilen.

Um den Punkt zu wiederholen, weil er weiterhin nicht verstanden wird: Weder dep noch vgo können dieses Problem verhindern oder eine narrensichere Lösung bieten. Stattdessen erlaubt dep Helm zu kommunizieren , dass das Problem existiert, während vgo dies nicht tut.

Zusammenfassend (wahrscheinlich schlecht) scheint das wichtigste technische Argument gegen vgo zu sein, dass es eine Möglichkeit für Bibliotheken geben muss, global respektierte Einschränkungen für ihre eigenen Abhängigkeiten zu deklarieren.

Ich würde dieser Zusammenfassung etwas Farbe verleihen, da diese Einschränkungen erforderlich sind, um mit dem unglücklichen Weg umzugehen, wenn Kompatibilitätsregeln verletzt werden. vgo legt die Importkompatibilitätsregel fest und fährt dann mit der Entwicklung einer Lösung fort, wobei davon ausgegangen wird, dass diese Regel immer befolgt wird. In dieser idealisierten Welt ist der Bedarf an Obergrenzen begrenzt oder gar nicht vorhanden. In der realen Welt wird dies nicht passieren: Entwickler werden Updates veröffentlichen, die die Kompatibilität beeinträchtigen, entweder absichtlich oder auf andere Weise.

Ich denke, @Merovius hat eine praktikable Lösung gefunden. MVS würde wie angegeben fortfahren, und nach Abschluss der Auflösung würde vgo jedes aufgelöste Paket auf Ausschlüsse prüfen. Wenn welche gefunden werden, werden diese an den Endbenutzer gemeldet, der entweder seine Abhängigkeiten ändern kann, um diese Einschränkungen zu erfüllen, oder sich dafür entscheidet, die Einschränkungen zu überschreiben und zu ignorieren. Ich war auch auf der anderen Seite und manchmal weißt du es besser als der Betreuer; es funktioniert für Ihre Anwendung und das ist alles, was Sie interessiert.

Dadurch wird ein Pfad für zwischengeschaltete Bibliotheken wiederhergestellt, um Endbenutzern eine Inkompatibilität mitzuteilen . Um das Helm-Beispiel noch einmal zu wiederholen:

[email protected] : Helm @2.1.2
[email protected] : GRPC @1.3.5

==> Benutzer aktualisiert absichtlich auf [email protected] .

Benutzer: Helm @2.1.3, [email protected] ("Helm aktualisiert, damit ich endlich grpc 1.4 verwenden kann!")
Helm: GRPC @1.4.0

==> Fehler erkannt! Der Benutzer sieht einige Probleme mit Helm, also suchen Sie nach einer neuen Version.

Benutzer: [email protected] , [email protected]
Helm: GRPC @1.3.5, schwacher GRPC <1.4.0

Der Benutzer sieht eine Warnung, dass GRPC 1.4.0 von der Installation von [email protected] abgelehnt wird. Da Helm für mich kaputt ist und ich versuche, das zu beheben, entferne ich meine Abhängigkeit von GRPC 1.4.0 (leider verliere ich einige nützliche Funktionen) und führe MVS erneut aus. Dieses Mal löst MVS GRPC in 1.3.5 und Helm in 2.1.4 auf, überprüft alle schwachen Einschränkungen erneut, stellt fest, dass sie gelten, und ich bin fertig.

Ich erwarte nicht, dass irgendein Tool diese Probleme auf magische Weise löst, aber ich erwarte einige Rückgriffe als Middleware-Bibliothek. Soweit ich das beurteilen kann, besteht die einzige Option in vgo darin, alle meine Upstream-Abhängigkeiten zu forken und umzubenennen (oder gleichwertig in mein Projekt zu kopieren), wenn ich meine Benutzer vor Kompatibilitätsproblemen mit diesen Abhängigkeiten isolieren möchte. Ich glaube nicht, dass das jemand will.

@willfaught Für uns ist es ein Erfolg, den Build zu unterbrechen, wenn eine maximale Versionsbeschränkung verwendet wird, um eine schlechte Version zu vermeiden! Das wollen wir erreichen.

Der Punkt, der in dem Vortrag angesprochen wurde, ist, dass vgo in diesem Szenario nicht schlechter als dep ist. In seinem Beispiel ist der Build nicht in dem Sinne kaputt, dass dep keine Lösung finden kann; Es ist in dem Sinne kaputt, dass dep eine Lösung findet und diese Lösung die schlechte Version enthält, was zu der gleichen schlechten Situation führt, die wir vermeiden wollten.

Sie sollten sich wirklich das Video ansehen, das ein hervorragendes Beispiel durchläuft, aber hier ist das Wesentliche, wie ich es verstanden habe / mich daran erinnere:

  • Paketversionen (einschließlich ihrer Abhängigkeitsanforderungen) sind unveränderlich
  • Um eine maximale Versionsbeschränkung zu einer bestehenden Abhängigkeit für Ihr Paket hinzuzufügen, müssen Sie eine neue Version Ihres Pakets veröffentlichen.
  • Es ist möglich, dass dep die vorherige Version Ihres Pakets wählt, um alle Anforderungen zu erfüllen, in diesem Fall wird Ihre neue maximale Versionsbeschränkung nicht vorhanden sein. Dadurch kann die schlechte Version doch verwendet werden.

Ich stimme größtenteils dem Vorschlag zu, maximale Versionsausschlüsse hinzuzufügen, aber ich habe diese Sorge: Angenommen, ich füge in meine Bibliothek „use gRPC >1.4, <1.8“ ein, dann entscheiden die Autoren in gRPC 1.9: „Weißt du was, Helm war Richtig, wir haben in 1.8 eine bahnbrechende Änderung vorgenommen, wir kehren in 1.9.0 zu unserem vorherigen Verhalten zurück." Jetzt können Leute, die versuchen, Helm+gRPC zu importieren, 1.9 nicht verwenden, bis Helm eine Version veröffentlicht, die besagt: „Verwenden Sie gRPC >1.4, außer 1.8.0, 1.8.1, 1.8.2, aber 1.9+ ist cool“.

Mit anderen Worten, vielleicht reicht exclude grpc 1.8 aus, weil wir nicht wissen, ob gRPC 1.9 inkompatibel sein wird oder nicht, bis es veröffentlicht wird, an welchem ​​Punkt Helm es entweder zur Ausschlussliste hinzufügen kann oder nicht.

Ich weiß im Grunde nichts über diesen Raum. Aber wenn man die Diskussion hier liest, hört es sich so an, als ob die größte Meinungsverschiedenheit darin besteht, wie man fehlerhafte Fälle erkennt. Das heißt, sowohl MVS (vgo) als auch SAT (dep) bewältigen normale Situationen mehr oder weniger gut, vielleicht nicht identisch, aber gut genug.

SAT bietet eine Fähigkeit, die MVS nicht bietet: Mit SAT kann der Autor des Bibliothekspakets P1 deklarieren: „P1 erfordert P2 und funktioniert mit P2Version > 1.1 und P2Version < 1.4“. MVS kann nur deklarieren „P1 erfordert P2 und funktioniert mit P2Version > 1.1“ und kann die Einschränkung „P2Version < 1.4“ nicht ausdrücken. Im Normalfall spielt das keine Rolle. Es spielt nur eine Rolle, wenn ein Vorgang versucht, P2 auf Version 1.4 zu aktualisieren. In diesem Fall meldet SAT einen Fehler, während MVS dies nicht tut. Wenn die Inkompatibilität bei der Verwendung von MVS kein Kompilierungsfehler ist, kann dies lange im Nachhinein zu einem Fehler führen.

Zweifellos sehen die SAT-Anhänger andere große Probleme mit MVS, aber bisher ist dies das, was ich verstehe.

Ich denke, es ist erwähnenswert, dass, wenn die Einschränkungsausdrücke selbst versioniert sind – wenn sie Teil einer bestimmten Version von P1 sind – dann im normalen Verlauf der Ereignisse, bevor P2 Version 1.4 veröffentlicht wird, P1 Version 2.2 glücklicherweise „P2Version > 1,1". Erst wenn die P2-Version 1.4 veröffentlicht wird, werden die P1-Autoren die Inkompatibilität bemerken und die P1-Version 2.3 mit "P2Version > 1.1 und P2Version < 1.4" veröffentlichen. Wenn Sie also P1 Version 2.2 verwenden, werden weder SAT noch MVS Probleme beim Upgrade von P2 auf Version 1.4 melden, obwohl dies auf möglicherweise subtile Weise fehlschlagen wird.

Mit anderen Worten, während es für eine Version von P1 durchaus sinnvoll ist, minimal kompatible Versionen von P2 aufzulisten, ist es für eine Version nicht sinnvoll, maximal kompatible Versionen aufzulisten, wenn die Version mit der neuesten Version von P2 korrekt funktioniert . Die maximal kompatible Version ist entweder konservativ und daher zunehmend falsch, wenn neuere und bessere Versionen von P2 erscheinen, oder wenn sich P2 in Zukunft auf inkompatible Weise ändert, wird diese Anforderung nicht angegeben, da dies zum Zeitpunkt der Veröffentlichung nicht der Fall ist Es gibt sie nicht.

Wenn wir also ein System haben wollen, das etwas anderes als minimale Versionsanforderungen definiert, dann dürfen diese Anforderungen nicht Teil einer bestimmten Version sein, sondern müssen stattdessen Teil einer Art von Metadaten sein, die mit dem Paket verknüpft sind, Metadaten, die abgerufen werden können jederzeit, ohne das Paket selbst zu aktualisieren. Und das bedeutet, dass die Operation „Dieses Paket aktualisieren“ von der Operation „Überprüfen, ob meine aktuellen Paketversionen kompatibel sind“ getrennt sein muss.

Ich würde weiter behaupten - und das ist definitiv schwächer als das oben Gesagte -, dass es im Allgemeinen unklug ist, einem Tool zur Lösung des Problems zu vertrauen, wenn "Prüfen, ob meine aktuellen Paketversionen kompatibel sind" fehlschlägt. Lässt sich das Kompatibilitätsproblem nicht durch die einfache Operation „jedes relevante Paket auf die aktuelle Version aktualisieren“ lösen, dann ist Nachdenken angesagt. Ein Tool kann diesen Gedanken einleiten, aber im Allgemeinen nicht ersetzen. Insbesondere erscheint es für ein Tool sehr unklug, Pakete automatisch herunterzustufen.

Also, wenn wir in Begriffen denken

  1. eine Möglichkeit, Paketmetadaten zu definieren, die Paketinkompatibilitäten beschreiben
  2. Darauf basierend ein Tool, das meldet, ob Ihre aktuellen Pakete kompatibel sind

dann verlieren vielleicht einige der Hauptunterschiede zwischen MVS und SAT an Bedeutung.

Danke, dass du das so gut gesagt hast, Ian. Um nachzufassen, sobald wir Versionen und vgo erstellt haben, wollen wir unbedingt eine neue godoc.org (vielleicht einen anderen Namen) haben, die zusätzliche Informationen über Pakete aufzeichnet, Informationen, die der go-Befehl einsehen kann. Und einige dieser Informationen wären paarweise Inkompatibilität, die der go-Befehl als Warnungen oder Fehler in einem bestimmten Build melden könnte (d. h. den Schaden melden, nicht versuchen, ihn zu verbergen, indem man ihn umgeht). Aber überhaupt Versionen in der Kern-Toolchain zu haben, ist der erste Schritt, und das ist, zusammen mit nur minimalen Versionsanforderungen und semantischer Import-Versionierung, das, was in dieser Ausgabe akzeptiert wurde.


Wir sind bestrebt, dies so reibungslos wie möglich zu landen. Das erfordert zusätzliche Tools, mehr Aufklärungsarbeit und PRs, um Probleme in bestehenden Paketen zu beheben. All dies wurde daran gehindert, diesen Vorschlag anzunehmen, da es anmaßend schien, voranzukommen, ohne dass der Gesamtansatz akzeptiert wurde. Aber der Vorschlag wird angenommen, und die Arbeit wird jetzt, da die Unsicherheit vorbei ist, aggressiver landen.

Ich hatte den gleichen Gedanken über externe Informationen für die Versionskompatibilität ... da die Versionskompatibilität über konstant sein muss, muss sie nicht in der Quellcodeverwaltung sein (und in der Tat ist die Quellcodeverwaltung ein definitiver Nachteil, wie oben erwähnt). Es wäre schön, wenn es dafür einen Lösungsvorschlag gäbe, da dies definitiv das einzige große Problem mit MVS wie vorgeschlagen zu sein scheint.

Es ist großartig zu sehen, wie sich die Diskussion organisch in diese Richtung bewegt. Es war eine zentrale Stoßrichtung meiner Bedenken, und es macht es so viel einfacher, grundlegende Probleme zu erklären, wenn die Leute bereits den größten Teil des Weges dazu gegangen sind.

@ianlancetaylor , ich denke, Sie liegen genau richtig mit dieser Beobachtung, dass Sie in der Lage sein müssen, Änderungen an Einschränkungsinformationen in bereits veröffentlichten Versionen vorzunehmen. Wie @rsc angedeutet hat, haben wir einen solchen Dienst in unseren Meetings besprochen/vorgeschlagen. Wir könnten es mit godoc.org oder etwas anderem tun, sicher. Aber ich glaube eigentlich nicht, dass es einen separaten Dienst mit sich bringt, und es wäre ohne einen besser. Ich habe in dem Artikel, den ich am Freitag veröffentlicht habe, kurz darauf verwiesen (direkt von diesem Anker). Nicht zuletzt in einem Dienst müssen dann Fragen beantwortet werden, wessen Inkompatibilitätserklärungen in Warnungen auftauchen sollen, was den Umgang mit Identitäten bedeutet und wie wir Erklärungen auf bestimmte Situationen im Depgraph ausrichten. Da wir die Deklarationen in Metadatendateien aufbewahren, brauchen wir uns darüber keine Gedanken zu machen. Aber dazu gleich mehr.

Was hier wirklich wichtig ist, ist dieser Punkt, wenn auch vielleicht nicht so, wie Sie es beabsichtigt haben:

vielleicht verlieren einige der Hauptunterschiede zwischen MVS und SAT an Bedeutung.

Der Vorschlag eines Meta-Tools, das diese Suche durchführt – ja, das ist eine SAT-Suche – als Lösung für die Probleme, die die Leute identifizieren, ist aufschlussreich. Es ist ziemlich genau das, was wir aus dep machen müssen, wenn MVS wie beschrieben weitermacht. Und als erstes ist anzumerken, dass, wenn wir so besorgt über diese Inkompatibilitäten sind, dass wir über ein Suchtool sprechen, wir eigentlich sagen, dass MVS nur ein Schritt in einem größeren Algorithmus wird, und das Die Grokkability-Vorteile gehen direkt aus dem Fenster.

Abgesehen davon, dass es noch schlimmer ist, weil keine Menge Meta-Tools das eingebackene Problem des Informationsverlusts umgehen können, das sich aus der Komprimierung von Mindest- und aktuellen Versionen zusammen ergibt. Das große Ergebnis davon sind kaskadierende Rollbacks , was bedeutet, dass der tatsächliche Versuch, eine der Inkompatibilitäten in dieser Liste zu beheben, sehr wahrscheinlich dazu führen wird, dass andere Teile des Abhängigkeitsdiagramms zurückgeworfen werden, die nicht unbedingt mit Ihrem Problem zusammenhängen. Und Entwickler werden nicht in der Lage sein, einer Update-Strategie zu folgen, die anderen nicht schadet. . (Oh, und Phantomregeln , aber das ist im Allgemeinen nur ein MVS-Nebeneffekt).

Aus diesem Grund habe ich behauptet, dass MVS eine ungeeignete Zwischenschicht ist, auf der ein Werkzeug höherer Ordnung wie dieses aufgebaut werden kann - "nicht zweckdienlich". Es ist klar, dass die Leute glauben, dass diese Inkompatibilitäten auftreten werden, also nimmt MVS nur ein schwieriges Problem und macht es schwieriger.

Wenn wir stattdessen das Problem eines "Inkompatibilitätsdienstes" wieder in einer Metadatendatei vereinheitlichen, dann glaube ich, dass es möglich ist, mit nur einem einfachen Satz paarweiser Deklarationen den gleichen Effekt zu erzielen. (Dies ist ein Entwurf des Konzepts, scheint aber zunehmend zusammenzuhängen)

Dies würde dazu führen, dass sich Teile von MVS ändern, aber MVS könnte immer noch auf den dort codierten Informationen laufen. Das wäre vor allem dann nützlich, wenn Inkompatibilitäten wirklich verrückt werden und Sie sie einfach alle vermeiden möchten. Aber der primäre Algorithmus würde von einer Baseline ausgehen, die wie MVS aussieht, und dann zu einer breiteren Suche wechseln (um es klarzustellen, MVS selbst sollte immer noch als Suche betrachtet werden), ohne die Möglichkeit, in absurd alte Versionen zu wechseln.

(Achtung, ich bin diese Woche im Urlaub, antworte also erst nächstes Wochenende)

@sdboyer

Der Vorschlag eines Meta-Tools, das diese Suche durchführt - ja, das ist eine SAT-Suche

Kannst du genauer sein? Der Satz, den Sie zitiert haben, steht direkt nachdem Ian ein Tool vorgeschlagen hat, um zu melden, ob die ausgewählten Versionen kompatibel sind - und nach meinem besten Wissen ist dies die hier vorgeschlagene Hauptalternative (es ist sicherlich das, was ich oben beabsichtigt habe). Dieses Problem ist definitiv keine Suche und es ist trivial und erfordert keine Lösung von SAT (es wertet nur eine boolesche Formel für einen bestimmten Satz von Werten aus und versucht nicht, Werte zu finden, die es erfüllen).

Richtig, einfach zu melden, dass es einige bekanntermaßen inkompatible Werte in der Formel gibt, erfordert nicht das Lösen von SAT. Ergreifen von Maßnahmen auf dieser Grundlage, z. B. für ein Tool, das dabei hilft, ein Ergebnis ohne solche Werte zu finden.

Ich habe diesen Satz nicht zitiert, weil ich denke, dass er darauf hindeutet, dass Menschen die Suche als immer notwendig akzeptiert haben, sondern weil wir glauben, dass es wichtig ist, solche Bedingungen zu melden, dann weil wir glauben, dass wir wahrscheinlich auf solche Szenarien stoßen werden.

Das Problem ist, sobald die Plausibilität und Wichtigkeit der Behandlung dieser Fälle feststeht, sieht es so aus, als ob die Leute dann den irrtümlichen Sprung machen, dass "wir einfach alle Suchaufgaben auf MVS erledigen können, und es wird gut." wir können, aber solche Versuche werden viel schwieriger zu handhaben, da MVS nützliche mögliche Pfade abschneidet.

Am 28. Mai 2018 um 16:02:13 Uhr EDT schrieb Axel Wagner [email protected] :

@sdboyer

Der Vorschlag eines Meta-Tools, das diese Suche durchführt - ja, das ist ein
SAT-Suche

Kannst du genauer sein? Der von Ihnen zitierte Satz steht direkt nach Ian
schlägt ein Tool vor, um zu melden, ob die ausgewählten Versionen vorhanden sindkompatibel - und das ist meines Wissens nach das Wichtigste
Alternative hier vorgeschlagen (es ist sicherlich das, was ich oben beabsichtigt habe).
Dieses Problem ist definitiv keine Suche und es ist trivial und
erfordert kein Lösen von SAT (es wird nur eine boolesche Formel ausgewertet
für eine gegebene Menge von Werten, ohne zu versuchen, Werte zu finden, die diese erfüllen).

--
Sie erhalten dies, weil Sie erwähnt wurden.
Antworten Sie direkt auf diese E-Mail oder sehen Sie sie auf GitHub an:
https://github.com/golang/go/issues/24301#issuecomment -392595150

Ich habe diesen Satz nicht zitiert, weil ich denke, dass er darauf hindeutet, dass Menschen die Suche als immer notwendig akzeptiert haben, sondern weil wir glauben, dass es wichtig ist, solche Bedingungen zu melden, dann weil wir glauben, dass wir wahrscheinlich auf solche Szenarien stoßen werden.

Um es klar zu sagen: Der Vorschlag, Obergrenzen auf diese Weise nachzurüsten, ist eine reine Reaktion auf geäußerte Bedenken und um zu zeigen, dass dies möglich ist (um die Behauptung kritisch zu hinterfragen, dass MVS grundsätzlich ungeeignet für den Zweck ist). Es scheint ein bisschen unfair, dieses Zugeständnis und diese Kompromissbereitschaft als Beweis dafür zu nehmen, dass Sie unserer Meinung nach die ganze Zeit Recht hatten.

Für mich ist diese Behauptung (dass MVS ungeeignet und ein im Wesentlichen irreversibler Schritt in die falsche Richtung ist) das, was ich persönlich in Frage stelle, und die Linse, durch die ich Ihre Argumente lese. Eines dieser Argumente war, dass es ein Feature ist, wenn wir Inkompatibilitäten deklarieren können und der Versionsauswahlalgorithmus fehlschlägt, wenn sie auftreten. Ein weiteres faires Argument ist, dass es schön wäre, wenn der Algorithmus sie für uns lösen könnte, wenn sie auftreten (was tatsächlich einen SAT-Löser erfordern würde).

Obwohl ich denke, dass dies berechtigte und berechtigte Bedenken sind, glaube ich nicht, dass sie die Messlatte überschreiten, um mir zu beweisen, dass MVS grundsätzlich ungeeignet ist. Ich glaube immer noch, dass MVS als Ausgangspunkt gute und wichtige Funktionen auf den Tisch bringt. Und wenn sich herausstellt, dass diese Bedenken in der Praxis erhebliche Probleme verursachen, gibt es immer noch viele Möglichkeiten, wie wir das wiederholen können – vom Hinzufügen von Obergrenzen (ob als Teil von go.mod oder als separater Dienst) bis hin zu reinen Fehlern bis hin zum Hinzufügen eines vollständigen SAT-Solvers und Sperren von Dateien an einem bestimmten Punkt. Das heißt, ich stimme Ihnen zu, dass diese Dinge passieren werden, aber a) bin (vielleicht naiv) optimistisch, dass sie nicht so viel Schmerz verursachen werden, wie Sie erwarten, und b) dass sie lösbare Probleme sind, selbst wenn wir mit MVS beginnen.

Mir scheint, dass etwas außerhalb der Quellcodeverwaltung, das die Kompatibilität bestimmt, den Determinismus eines MVS-Systems ändern würde. Wenn Sie foo >= 1.5.0 als Einschränkung in einer Bibliothek haben und eine andere Bibliothek foo >= 1.6.0. Dann setzen Sie diese beiden in eine Binärdatei und sie wählen 1.6.0. In MVS ist dies alles, was Sie für einen wiederholbaren Build benötigen. es wird immer 1.6 gewählt

Aber wenn Sie dem Mix externe Kompatibilität hinzufügen, könnten Sie diese erste Bibliothek aktualisieren, um zu sagen, dass sie nicht mit 1.6 kompatibel ist, und dann würde der Algorithmus 1.7 wählen, obwohl sich der Code nicht geändert hat ... Was bedeutet, dass Sie brauchen würden wieder eine Sperrdatei.

Als Referenz denke ich nicht, dass eine Sperrdatei eine schlechte Sache ist. Es ist schön, eine explizite Liste mit genau dem zu haben, was Sie bauen müssen. Und das sollte es schnell machen. Keine magische Logik erforderlich.

@natefinch Wenn die go.mod-Datei der Anwendung so aktualisiert wurde, dass v1.7.0 erforderlich ist, weil das externe Kompatibilitätstool anzeigte, dass v1.6.0 inkompatibel war, würden Sie keine Sperrdatei benötigen. Da die Angabe von v1.7.0 in der go.mod-Datei enthalten ist, könnte der Autor auch einen Kommentar hinzufügen, der erklärt, warum v1.7.0 verwendet wird und dass diese Information für die Leser nützlich wäre.

@leighmcculloch , wenn Dateien in der App aktualisiert werden, handelt es sich um einen anderen Build und liegt außerhalb des Bereichs des Problems "reproduzierbarer Build ohne Sperrdatei".

Out-of-Band-Kompatibilitätsinformationen werden vorgeschlagen, um widerzuspiegeln, wie sich das Wissen entwickelt: Zum Zeitpunkt der Veröffentlichung waren keine Inkompatibilitäten bekannt, aber dann wurde es offensichtlich und es werden zusätzliche Informationen zu bereits veröffentlichten Versionen veröffentlicht. IMHO per Definition führt dieser Ansatz zu einer Änderung, wie Abhängigkeiten gezogen werden, warum sonst überhaupt diese Inkompatibilitätsinformationen extrahieren?

@redbaron @natefinch

Der Zweck der Inkompatibilitätsinformationen besteht darin, dass Autoren von Bibliotheken Inkompatibilitätsinformationen an ihre Benutzer weitergeben. Ob diese Informationen zum Build- oder Release-Zeitpunkt verwendet werden, ist eine andere Frage.

Im Fall von vgo besteht die aktuelle Idee darin, nur Warnungen anzuzeigen (oder möglicherweise zu krächzen). Aber vor allem nicht die Wahl der verwendeten Versionen beeinflussen zu lassen (da dies die Lösung von SAT erfordern würde). Es spielt also keine Rolle, Sie können es bei einem oder beiden verwenden und es wird seine Aufgabe gut erfüllen, während es die Eigenschaft der Wiederholbarkeit behält¹.

In dep werden diese Informationen nur zum Release-Zeitpunkt verwendet und dann in einer Sperrdatei aufgezeichnet, die zum Build-Zeitpunkt verwendet wird. Es scheint also, dass wir eine Verwendung zur Veröffentlichungszeit ohnehin als "gut genug" in Betracht ziehen, zumindest wenn es um Bedenken hinsichtlich vgo vs. dep geht.

Ich glaube aber immer noch nicht, dass wir diese Fragen jetzt wirklich beantworten müssen.


[1] Persönlich würde ich argumentieren, dass es besser ist, es zur Veröffentlichungszeit und nur dann zu verwenden, wenn -v zur Buildzeit verwendet wird, da ein Benutzer nicht entscheiden muss, ob eine Warnung umsetzbar ist oder nicht.

@rsc schrieb:

Um nachzufassen, sobald wir Versionen und vgo erstellt haben, wollen wir unbedingt eine neue godoc.org (vielleicht einen anderen Namen) haben, die zusätzliche Informationen über Pakete aufzeichnet, Informationen, die der go-Befehl einsehen kann. Und einige dieser Informationen wären paarweise Inkompatibilität, die der go-Befehl als Warnungen oder Fehler in einem bestimmten Build melden könnte (d. h. den Schaden melden, nicht versuchen, ihn zu verbergen, indem man ihn umgeht).

Ich frage mich, ob es notwendig ist, die paarweise Inkompatibilität aufzuzeichnen. So wie ich es derzeit sehe, ist jede Inkompatibilität zwischen Modul A@vN und Modul B@vM wirklich darauf zurückzuführen, dass B eine inkompatible Änderung von einer Version vL vorgenommen hat, in der L < M.

Wenn Modul B keine inkompatible Änderung vorgenommen hat, dann hat Modul A nur einen Fehler. Wenn ja, dann geht es um B selbst, nicht um die Paarung von A und B.

Daher kann ISTM, dass jedes öffentliche Repository von Modul-Metadaten nur Inkompatibilitäten eines Moduls mit früheren Versionen von sich selbst aufzeichnen kann, was das Problem möglicherweise leichter handhabbar macht. Diese Inkompatibilitätsberichte sind den Fehlerberichten ziemlich ähnlich, obwohl sie nicht behoben werden können, da eine einmal veröffentlichte Version nicht mehr geändert werden kann.

Wenn Sie Ihre Modulversionen aktualisieren, könnte das Go-Tool die Metadaten berücksichtigen und sich weigern, eine Version zu berücksichtigen, die mit einer derzeit ausgewählten Version nicht kompatibel ist. Ich denke, dies vermeidet die Notwendigkeit, SAT zu lösen. Es könnte auch entscheiden, dass ein bestimmtes Modul zu viele Inkompatibilitätsberichte hat, und sich weigern, es als Abhängigkeit hinzuzufügen.

Ein Satz von Tupeln der Form ( module , oldVersion , newVersion , description ) könnte ausreichend sein.

Das Go-Tool könnte die Metadaten berücksichtigen und sich weigern, eine Version zu berücksichtigen, die mit einer derzeit ausgewählten Version nicht kompatibel ist

Dies funktioniert natürlich nicht, wenn Sie mehrere Abhängigkeiten hinzufügen, die letztendlich die Verwendung von miteinander inkompatiblen Versionen erfordern, da die neuen Versionen nicht Teil des vorhandenen Moduls sind, aber es könnte eine vernünftige Heuristik verfügbar sein. AFAICS ist nicht entscheidend, da Abhängigkeiten relativ selten hinzugefügt werden sollten .

Ich mache mir Sorgen, dass go release zum "ausreichend intelligenten Compiler" dieser Diskussion wird. Was können Nutzer konkret von go release in Go 1.11/12 erwarten? Ich denke, das macht einen Unterschied, was vernünftige Erwartungen in Bezug auf MVS/SIV sind.

Vielen Dank für die Energie, die so viele von Ihnen für Go und insbesondere für diesen Vorschlag aufgebracht haben.

Das erste Ziel des Vorschlagsverfahrens besteht darin, "sicherzustellen, dass Vorschläge eine angemessene, faire, zeitnahe und aufgezeichnete Bewertung mit einer klaren Antwort erhalten". Dieser Vorschlag wurde ausführlich diskutiert und wir haben eine Zusammenfassung der Diskussion veröffentlicht. Nach sechs Wochen und vielen Diskussionen nahm der Vorschlagsprüfungsausschuss – der als Schiedsrichter eintrat, weil ich den Vorschlag geschrieben hatte – den Vorschlag an.

Ein einzelnes GitHub-Problem ist ein schwieriger Ort, um eine umfassende Diskussion zu führen, da GitHub kein Threading für verschiedene Konversationsstränge hat und nicht einmal mehr alle Kommentare anzeigt. Der einzige Weg, wie eine Diskussion wie diese überhaupt funktioniert, ist die aktive Kuratierung der Diskussionszusammenfassung. Selbst die Zusammenfassung war unhandlich geworden, als der Vorschlag angenommen wurde.

Jetzt, da der Vorschlag angenommen wurde, ist dieses Thema nicht mehr der richtige Ort für Diskussionen, und wir aktualisieren die Zusammenfassung nicht mehr. Reichen Sie stattdessen bitte neue, gezielte Fragestellungen zu Ihren Problemen oder konkrete Änderungsvorschläge ein, damit wir gezielt über das jeweilige Thema diskutieren können. Bitte stellen Sie diesen neuen Ausgaben „x/vgo:“ voran. Wenn Sie #24301 im Text der neuen Ausgabe erwähnen, wird hier darauf verwiesen, damit andere es finden können.

Ein letzter Punkt ist, dass das Akzeptieren des Vorschlags bedeutet, die Idee zu akzeptieren, nicht die Prototyp-Implementierungsfehler und alles. Es müssen noch Details ausgearbeitet und Fehler behoben werden, und wir werden das weiterhin gemeinsam tun.

Nochmals danke für all deine Hilfe.

Es gibt noch viel zu tun (siehe Modulbezeichnung ), aber die anfängliche Modulimplementierung, wie in dieser Ausgabe vorgeschlagen, wurde in den Hauptbaum übernommen, also schließe ich diese Ausgabe.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen