toscho.design

Das Datum als Versionsnummer

Software braucht Nummern. Für jede Version eine. Das gilt uns als Gesetz. Oft orientieren wir uns dabei am Semantic Versioning: Major.Minor.Patch, jeder Teil wird separat gezählt.

Nachteile des Semantic Versioning

Überwiegend praktische und psychologische Probleme:

  • Sprünge in der ersten Zahl suggerieren dem Nutzer große Änderungen. Das trügt: Bei WordPress war der Sprung von 2.7 zu 2.8 stärker als der von 2.9 zu 3.0. Google Chrome zählt die erste Nummer hoch, wenn nur das Icon ersetzt wird, Firefox bei jedem Vollmond. Wozu dann noch drei Stellen, wenn sie keine Relevanz mehr kennzeichnen?
  • Es fällt mir schwer zu entscheiden, wann ich als Entwickler welche Stelle ändern soll. Rechtfertigen drei Bugfixes und ein neues Feature einen Sprung der ersten Stelle? Das ist bei jeder Software anders, es gibt kein festes, vorhersagbares Muster. Nicht für mich, und nicht für den Nutzer.
  • Die Nummern sind unterschiedlich lang. Nicht schlimm, aber man muß es immer im Interface berücksichtigen und kann nicht einfach sagen: Die Box für die Versionsnummer sei stets 6em breit.
  • Versionen mit einer 0 am Ende werden von Nutzern gerne übersprungen; sie warten auf das erste »Servicepack«, die Version x.0.1. Für die Entwickler bedeutet das: Sie bekommen weniger Rückmeldungen für diese Version, und Wahrscheinlichkeit einer Version x.0.2 steigt. Das finde ich ziemlich frustrierend.

In der Praxis ist Semantic Versioning … semantisch vage, für Sender und Empfänger.

Ich bin deshalb zu einem System übergegangen, das zwar meistens drei Stellen benutzt, sich aber am Datum orientiert. Das Plugin T5 Fresh Editor Stylesheets hat beispielsweise momentan die Version 2012.08.09. Ich folge hier dem Standard ISO 8601 und verwende das Schema YYYY.MM.DD. Statt der Bindestriche benutze ich Punkte.

Vorteile des Datums als Versionsnummer

  • Es gibt keine Version mit einer 0 am Ende.
  • Ein Sprung in der ersten Zahl suggeriert keine dramatischen Änderungen, man kann einfach Happy new year! ins Commitlog schreiben.
  • Die Nummern haben eine feste Länge, sie sind leicht zu parsen.
  • Das System ist kompatibel mit version_compare() und dem System Major.Minor.Patch.
  • Der Nutzer sieht sofort, wie alt eine Version ist, ob die Software noch gepflegt wird.
  • Die Entwickler geraten nie in Versuchung, eine Versionsnummernralley anzustoßen. Siehe Firefox.
  • Man kann @since-Tags besser lesen und leichter im Commit-Log finden, denn der Wert des Tags entspricht (hoffentlich) genau dem Änderungsdatum. In Git:
    git log --pretty=format:"%H" --since="2010-03-25" --before="2010-03-26"

Vorabversionen wie Alpha, Beta oder Release Candidate werden nicht mit einer speziellen Nummer gekennzeichnet, sondern sie stehen als eigene Branches im Repository. Gleiches gilt für Versionen mit Longtime-Support (falls ich mich mal dazu hinreißen lassen sollte): Sie bekommen einen benannten Branch.

Offen ist die Kennzeichnung einer nicht rückwärtskompatiblen Version. Normalerweise schreibt man ja Code, der beim Update inkompatible Daten konvertiert … sollte das einmal nicht möglich sein, braucht man vermutlich ohnehin eine bessere Informationsquelle als die pure Versionsnummer.

Lektüre

12 Kommentare

  1. Rüdiger am 11.08.2012 · 14:25

    Moin,

    die Versionierung mit Datum hat auch z.B. beim Tomcat 7 mit Version-Switching einen Vorteil. Jahr 4 Stellen, Monat 2 Stellen und Tag hat 2 Stellen. Also alles feste anzahl von Zeichen.

    Major.Minor.Patch hat den Nachteil das man vorher wissen muss wie viele Versionschritte man an den einzelnen Stellen machen will. Entscheidet man sich zu Minor mit 2 Stellen muss man mit .01. bei Minor anfangen. Problem ist dabei dann aber das man ab der 99 nicht weiter kommt. Wer dann bei Minor .100. einträgt wird Probleme bekommen.

    Man muss also vorher schon entscheiden und vor allem Wissen braucht man 1, 2, 3 oder gar 4 Stellen bei den jeweiligen Versionen Major, Minor oder Patch. Ansonsten kann es dazu führen das der Versionswitch bei Tomcat 7 nicht mehr klappt ;-)

    Wissen viele nicht, daher werden sie irgendwann mal böse drüber stolpern.
    Daher ist Datum in der Version hier auch klar im Vorteil.

  2. Ralf Albert am 11.08.2012 · 15:12

    Interessanter Ansatz. Ich stehe gerade vor dem Problem mit zwei Versionen zu hantieren, eine für PHP5.2 und eine für PHP5.3. Das Problem ist klar, nehme ich V2.x und v1.x? Das geht nur, wenn man die PHP5.2-Version in absehbarer Zeit nicht mehr weiter entwickelt.
    Noch konfuser würde es werden, würde man auch noch eine Version für PHP5.4 entwickeln.
    Da ich die PHP5.2-Version nicht mehr weiter entwickeln werde, ist es für mich recht einfach. PHP5.3 bekommt v2.x, die PHP5.2-Version 1.9.x.
    Da aber auch die PHP5.2-Version noch einige Zeit lang gepflegt werden soll, würde ich mit dem Datum als alleinige Versionsnummer recht schnell Probleme bekommen.

    Man kann aber zu major (minor.patch) auch noch Build hinzuziehen und das Datum als Build-Nummer verwenden. Im Docblock verwendet man dann halt @version und @since, wobei bei @since der Build rein kommt.

    Das die Versionsnummer für den Endanwender oft unnütze Information ist, zeigt ja schon die Tatsache das einige dadurch verwirrt sind wenn der Patch auf .10 steht. Nicht wenige gehen davon aus das Version x.x.10 älter sei als Version x.x.9 (wobei das dann auch ein Fehler bei der Versionierung ist).
    Ich denke mehr als Major und ggf. Minor beachtet kaum ein Anwender. Nützlicher für den Anwender wäre die Versionsnummer wenn sie z.B. Informationen enthält auf welchen System sie lauffähig ist. Also z.B. v2.x.52 für PHP5.2 oder v2.x.win7. Dabei könnte man die Minor auch auf das System setzen und das Datum hinten anhängen was dann z.B. v2.52.2012-08-11 ergeben würde.

  3. Rüdiger am 11.08.2012 · 15:41

    @Ralf Albert: In Deinem Fall würde ich das anders machen. Ähnlich wie unter Linux Programme für 32bit und 64 Bit gekennzeichnet werden. Programmname-i386... oder Programmname-amd64... Bei Dir also, programmname-php52-YYYY.MM.DD oder programmname-php53-YYYY.MM.DD, das macht das sortieren einfacher ;-)

  4. Thomas Scholz am 11.08.2012 · 16:20

    @Ralf Albert: Genau dafür nimmst du unterschiedliche Branches. Das funktioniert natürlich nicht mit dem Update-Mechanismus auf wp.org, in einem eigenen jedoch könntest du die PHP-Version abfragen und das passende Update ausliefern.

  5. Ralf Albert am 11.08.2012 · 20:16

    @Rüdiger: Und wenn ich einen Intel 64Bit habe, kann ich das Programm nicht installieren? ;)
    Bei einem PHP-Script gehe ich mal davon aus das niemand versucht es unter Perl oder Python zu installieren. Aber es sieht natürlich etwas besser aus und man sieht im Dateibrowser auch später noch was im Archiv drin ist. Also ob es ein PHP-Script oder sonstwas ist.

    @Thomas Scholz: Wenn das Plugin erst einmal installiert ist, ist die Versionsnummer ja zweitrangig. Aber wenn ein Anwender hört "Das Plugin Schlumpatz ist total toll" und wenn er dann versucht das Plugin zu downloaden, hilft es ihm vielleicht wenn die benötigte PHP-Version im Versions-String enthalten ist.

  6. neb am 11.08.2012 · 22:47

    Nachteil bei ausschließlicher Verwendung des Datums: Was, wenn an einem Tag mehrere Versionen veröffentlicht werden? (etwa wenn man 1 Stunde nach Relase merkt, dass man 'nen groben Schnitzer drin hat)

    Gerade hinsichtlich kritischer Sicherheitslücken wäre es sinnvoll, da unterscheiden zu können, ob man nun die anfällige oder die gefixte Version hat.

  7. Thomas Scholz am 11.08.2012 · 23:00

    @neb: Stimmt, dann reicht das Datum nicht mehr. Man kann dann aber noch eine Build-Nummer anhängen. Das habe ich bei diesem Plugin beispielsweise gemacht: T5 Preset editor post content.

  8. David am 13.08.2012 · 22:07

    »Wozu dann noch drei Stellen, wenn sie keine Relevanz mehr kennzeichnen?« Dann nimm halt nur zwei Stellen. Oder Eine. Letztlich geht es doch darum, veröffentlichte Versionen irgendwie zu unterscheiden. Was schreibst Du in den @since-Tag einer neuen Funktion/Methode? Den Tag an dem Du die Funktion commitest, oder den Tag, an dem die neue stabile Version veröffentlicht wird, die diese Funktion beinhaltet. Aus Sicht eines kritischen Anwenders interessiert mich vor allem letzteres. Dem Endanwender wird das egal sein.

  9. Thomas Scholz am 14.08.2012 · 11:32

    @David: In @since kommt exakt das Datum, an dem ich es geschrieben habe. Ich muß mich jetzt nicht mehr darum sorgen, ob die nächste veröffentlichte Version eventuell eine andere Nummer hat, als ich da hineingeschrieben habe (also 4.5 statt 4.4.8).

  10. Hasenplautze am 12.09.2012 · 23:51

    Wofür das Datum?
    Suggeriert ein Datumssprung zwischen einem Monat zwischen den Releases nicht genauso ein "großes Featureupdate" wie ein Sprung von 2.x auf 3.0?

    Wie kennzeichne ich relevante Änderungen in der Codebasis? Einen Sprung von PHP5.3 auf PHP5.4 ? Das geht mit Datumsänderungen kaum.

  11. Thomas Scholz am 13.09.2012 · 00:20

    @Hasenplautze: Aus dem String wird ja deutlich, daß hier ein Datum angegeben wird. Damit senkt man die Furcht des Nutzers vor zu großen Änderungen. Hat sich nicht Relevantes geändert, gibt es kein Release. Gibt es doch eines, so steht alles Wichtige im Changelog, bzw. in der Ankündigung. Ich halte die Versionsnummer für einen schlechten Ort, um vage auf wichtige Änderungen hinzuweisen.

  12. Troll am 26.09.2012 · 13:32

    Das Datum als Versionsnummer erscheint, mir zumindest, meist als unfertige Veröffentlichung. So als wären es nur Snapshots des Programms. So macht es z.B. auch Videolan bei x264.