TimeStamp - erweitert zu kleiner Versionsverwaltung für (.au3 und .lua) alle Typen

  • EDIT [02.10.2021] - Eine neuere Version (kpl. überarbeitet) gibt es hier.

    EDIT [04.01.2019] - Mit v 1.4 wird das Skript allgemeingültig. Ohne weiter Änderungen am Skript kann jetzt jeder Dateityp in die Versionsverwaltung und/oder TimeStamp-Routine aufgenommen werden!

    ACHTUNG! Script breaking chance! DIE PROPERTIES MÜSSEN ZWINGEND GEÄNDERT WERDEN!

    Es wird nicht mehr für jeden Dateityp eine eigen Property erstellt, sondern wie folgt:

    Auflisten der Dateitypen, für die ein Timestamp gesetzt werden soll

    #~ TimeStamp setzen für folgende Dateitypen: EXT|EXT..

    Use.TimeStamp.With.Files=au3|lua|py

    Die Zeichen für Zeilenkommentare der verschiedenen Dateitypen müssen angegeben werden

    #~ Kommentarzeichen für einzeiligen Kommentar: EXT=ZEICHEN|..|..

    Line.Comment.Char=au3=;|lua=--|py=#

    Auflisten der Dateitypen, für die ein Versionsbackup gespeichert werden soll

    #~ Versions-Backup anwenden für folgende Dateitypen: EXT|EXT..

    Use.VersionBackUp.With.Files=au3|lua

    Version.Prefix und Version.Path.* bleiben unverändert.


    Hallo,
    ich habe die TimeStamp Funktion nun zu einer kleinen Versionsverwaltung für Skripte erweitert. Dabei habe ich mich allerdings auf eine zweistufige Versionierung (v Main.Sub) beschränkt.
    So gehts:
    In den User.properties wird festgelegt in welchem Pfad die Versionsbackups gespeichert werden sollen. Mit der Angabe von 'Default'  geschieht das im Skriptordner (ebenso bei fehlender Property oder Property ohne Wert), wird ein fester Ordner angegeben (ohne abschließenden Backslash!), wird dieser verwendet, mit 'no' wird keine Versionssicherung durchgeführt. Es lassen sich die in SciTE üblichen Pfadmakros (z.B. "$(SciteDefaultHome)" ) verwenden.

    Beim erstmaligen Speichern einer Datei wird (wenn gewünscht)
    - standardmäßig die Versionsnummer 'v 0.1' vergeben
    - im Pfad aus den .properties wird ein Unterverzeichnis der Form: \BackupVer_DATEINAME.EXT\ angelegt
    - in diesem Ordner wird eine Kopie der Datei als: DATEINAME[0.1].EXT erstellt

    Beim Speichern ohne Setzen eines Markers wird nur der TimeStamp aktualisiert.

    Es können folgende Marker gesetzt werden (direkt hinter die aktuelle Versionsnummer):
    - v Subversionsnr. wird um 1 erhöht
    - V Mainversionsnr. wird um 1 erhöht, Subversionsnr. wird auf 0 gesetzt
    - n die autom. Zählung ist nicht aktiv - aber eine per Hand eingetragene Änderung der Versionsnr. wird übernommen
    So werden die Marker gesetzt:
    Erhöhen Sub-Version:
    ;-- TIME_STAMP 2011-05-24 14:36:36 v 0.1v ==> ergibt dann nach dem Speichern: v 0.2

    Erhöhen Main-Version:
    ;-- TIME_STAMP 2011-05-24 14:36:36 v 0.1V ==> ergibt dann nach dem Speichern: v 1.0

    Setzen gewünschter Versions-Nr.:
    ;-- TIME_STAMP 2011-05-24 14:36:36 v 0.1
    ==> 0.1 ersetzen mit gewünschter Versions-Nr, z.B.: 0.5n ergibt dann nach dem Speichern: v 0.5

    NEU:
    Um von einem Skript keine Backups anzulegen einfach vor dem ersten Speichern ein * an die erste Position im Editor setzen. Dafür notwendige Codeänderung: s. Post #2

    Somit habe ich im Normalfall einen TimeStamp und lege bei Bedarf eine höhere Version mit Backup an.

    Da LUA ja keine Windows-orientierte Sprache ist, mußte ich einige Funktionen erst selbst zusammenbasteln (FileExists, FileCopy, FolderExists, FolderCreate). Nicht wundern, dass beim Erstellen des jeweiligen Versionsordners ganz kurz ein CMD-Window aufpopt. Aber da mußte ich den Umweg über die CMD nehmen, da LUA keine direkte Möglichkeit zum Erstellen eines Ordners bietet. <-- Behoben durch Einsatz der shell.dll.
    In meinen Tests hat bisher alles gut funktioniert, hoffe ihr werdet das dann bestätigen können. ^^

    Edit 17.05.2011:
    Manchmal muß man einfach nochmal drüber schlafen, sonst sieht man den Wald vor lauter Bäumen nicht. ;)
    Eine Kopie der bestehenden Datei anzulegen ist ja gar nicht möglich, da die Aktion bei "BeforeSave" stattfindet. Somit wurde zum Einen der alte Inhalt gespeichert (mit falscher VersNr) und zum Anderen crashte es bei einer neuen Datei, da dort die zu kopierende ja noch gar nicht existierte.
    Habe diesen Bug jetzt beseitigt und schreibe den aktuellen Editorinhalt in das Versionsbackup.

    Dazu sollte dann die SciTEStartup.lua so aussehen

    geändert 29.05.


    Die Datei "AutoStampSaveVersion[1.4].lua" speichern und umbenennen zu "AutoStampSaveVersion.lua")


    Und hier die Anpassungen in den SciTEUser.properties

    geändert 04.01.19

    Edit 21.05.2011:
    Ich habe den Code nochmal überarbeit, die Funktionen jetzt alle sauber in ein Array gepackt und eine kleine Funktionserweiterung vorgenommen: Wird ein Skript beim erstmaligen Speichern von der Versionsverwaltung ausgenommen (Asterisk an erster Editorposition), so wird in diesem Fall auch nur der Timestamp gesetzt. Auch bei späterem Speichern bleibt dies so. Aber man kann jederzeit durch Markieren mit 'v' oder 'V' das Skript in die Versionsverwaltung aufnehmen.
    Ich habe es soeben im EN-Forum gepostet, deshalb vorerst mal nur der Link dorthin: AutoStampSaveVersion.lua

    Edit 29.05.2011
    Die im letzten Edit benannten Änderungen sind jetzt auch hier im Skript. Alle nicht global benötigten Funktionen sind jetzt auch als lokal erstellt.
    Zusätzlich erweitert: Beim Speichern springt die Cursorposition nicht mehr an den unteren Editorrand, die Ansicht im Editor ist identisch zu 'VorSpeichern'.
    Aktuelle Version: "v 1.1"


    Edit: 16.05.2014
    Nach Jahren mal wieder was Neues hier. Ich habe jetzt die shell.dll integriert, somit gibt es kein aufpopendes Fenster mehr, wenn ein neuer Ordner beim Sichern erstellt wird.
    Weiterhin habe ich die Darstellung des TimeStamps verändert, mit der #Region gefällt mir das nicht mehr. Es wird jetzt in dieser Form ausgegeben:
    ;-- TIME_STAMP 2014-05-16 12:41:54 v 0.1
    Es ist eine zusätzliche Property in der SciTEUser.properties festzulegen: Version.Prefix=BUVer_
    Bisher wurde automatisch der Präfix "BUVer_" verwendet bei der Erstellung des Ordners für eine neu zu sichernde Datei. Das kann jetzt vom User festgelegt werden.
    Ansonsten ändert sich nichts an der Vorgehensweise.
    Um die shell.dll einzubinden, empfehle ich folgendes Vorgehen:

    Installation shell.dll


    - In der SciTEUser,properties eine Property erstellen für die eigenen Lua-Pfade Lua.User.Scripts.Path=C:\Code_AutoIt\LUA
    - In diesen Pfad die shell.dll kopieren
    - In der SciTEStartup.lua am Anfang einfügen
    local sUserLua = props["Lua.User.Scripts.Path"]

    LUA_USER_PATH = sUserLua .. "\\?.dll;" .. sUserLua .. "\\?\\?.dll;"
    package.cpath = LUA_USER_PATH .. package.cpath

    Jetzt werden die in diesen Pfaden gespeicherten Dll beim Start von SciTE geladen.

    Die bereits vorhandenen TimeStamps können mit der beigefügten "ReplaceTimeStamp.au3" auf die neue Version geswitcht werden. Einfach den Root auswählen, alle *.au3 werden rekursiv von dort ausgelesen und vorhandene TimeStamps auf die neue Version geswitcht. Sicherheitshalber wird zuerst im Root ein Ordner ".\BAK_TimeStamp\" erstellt, in den alle gefundenen au3-Dateien in der vorhandenen Ordnerstruktur gesichert werden.

    Aktuelle Version: "v 1.4"

    • Offizieller Beitrag

    Ich habe noch eine Ergänzung gemacht:
    Soll ein Skript gar nicht erst in die Versionsverwaltung aufgenommen werden, so wird vor dem ersten Speichern an die erste Position im Editor ein * geschrieben.
    Damit wird die Funktion TimeStamp angewiesen nur den Zeitstempel zu setzen ( dieser beinhaltet allerdings standardmäßig die Versionsnr. "v 0.1" ).

    Dazu in der "EigeneTools.lua" die Funktion InsertTimestamp gegen die folgende austauschen:

    geänderte InsertTimestamp
  • BugFix

    sehr schöne Funktion. Danke für das Script.

    Muss ich immer hinter der Versionsnummer ein "v" oder "V" machen?
    Beim Ausführen mit "F5" wird die Versionsnummer erhöht aber der Marker "v" oder "V" wird gelöscht.
    Wenn das so gewollt ist für was ist dann der Marker "n"

    Gruß Paule

    • Offizieller Beitrag

    Muss ich immer hinter der Versionsnummer ein "v" oder "V" machen?
    Beim Ausführen mit "F5" wird die Versionsnummer erhöht aber der Marker "v" oder "V" wird gelöscht.
    Wenn das so gewollt ist für was ist dann der Marker "n"


    Man möchte ja nicht bei jedem Speichern ein Kopie der Version erstellen.
    Bsp.: Du fügst eine Debugzeile ein um einen Bug aufzuspüren - wär schön blöd, wenn dann bei jedem Speichern (mit F5 ausführen speichert auch vorher) auch ein Backup erstellt wird.
    Deshalb soll ein Backup mit der entsprechenden Versionsnummer nur angelegt werden, wenn du es wirklich willst.
    Schreibst du ein 'v' hinter die aktuelle Versionsnummer ist das die Anweisung die Nummer der Subversion hochzuzählen (aus 'v 0.5' wird 'v 0.6').
    Mit einem 'V' weist du an, dass die Mainversion hochgezählt und die Subersion zurück auf '0' gesetzt wird (aus 'v 1.4' wird 'v 2.0').
    Das 'n' wiederum bewirkt, dass du z.B. einen Versionssprung machen kannst. Du schreibst anstelle der vorhandenen Versionsnummer die Versionsnummer deiner Wahl und dahinter das 'n'. Das bewirkt dann, dass nicht hochgezählt wird, aber ein Backup mit der per Hand eingetragenen Versionsnummer wird trotzdem angelegt.

  • BugFix ,

    nachdem ich vergessen hatte ein kleines "v" einzutragen habe ich mich dazu entschlossen Deine Versionsverwaltung dauerhaft einzuschalten, wenn man es möchte.
    Bei einem größerem Programm kann man schon ein bisschen suchen, wo denn nun die kleine Programmänderung war.

    Ich habe in der SciteUser.properties eine Variable AutoInc=1 gesetzt.
    Diese frage ich im deinem Programm ab und füge so immer ein kleines "v" hinter der Versionsnummer ein, wenn AutoInc=1 gesetzt ist.
    Dadurch das Du ein eigenes Backup Verzeichnis für jedes Script erstellt bleibt das Verzeichnis schön übersichtlich.

    Danke nochmals für die Veröffentlichung deines Programmes.

    Gruß Paule

    • Offizieller Beitrag

    Ich habe in der SciteUser.properties eine Variable AutoInc=1 gesetzt.


    So rum kann man es auch lösen. ;)
    Es gibt ja grundsätzlich 2 sinnvolle Wege:
    1. Sichern, wenn ich es bewußt will und dieses per Marker mitteilen
    2. Immer sichern und nur, wenn ich es nicht will einen Marker dafür setzen (z.B. Debugzeile eingefügt)

    Ich hatte mich nun für Weg 1 entschieden, aber natürlich ist dein Gedanke genauso nützlich, wobei ich auf jeden Fall mir die Möglichkeit einbauen würde, dass nicht gesichert wird.

  • Danke für das LUA Script.

    Ich habe alles eingestellt, mich an den Beispielen oben gehalten, jedoch bekomme ich eine Fehlermeldung:

    Code
    cannot open S:\Programmierung\AutoIt\Programme\AutoIt3\SciTE\_OWN\LUA_ScriptsAutoStampSaveVersion.lua: No such file or directory
    >Lua: error occurred while loading startup script
    cannot open S:\Programmierung\AutoIt\Programme\AutoIt3\SciTE\_OWN\LUA_ScriptsAutoStampSaveVersion.lua: No such file or directory
    >Lua: error occurred while loading startup script

    Habe folgenden Eintrag in meiner SciTEUser.properties:
    Lua.User.Scripts.Path=$(SciteDefaultHome)\_OWN\LUA_Scripts
    --> hier liegt AutoStampSaveVersion.lua
    --> hier liegt shell.dll


    Hier mein ENDE der SciTEStartup.lua

    Code
    -- Start up the events (Calls OnStartup()).
    EventClass:BeginEvents()
    -- Erst nach Registrierung der EventClass werden eigene Dateien geladen
    local sUserLua = props["Lua.User.Scripts.Path"]
    LUA_USER_PATH = sUserLua .. "\\?.dll;" .. sUserLua .. "\\?\\?.dll;"
    package.cpath = LUA_USER_PATH .. package.cpath
    LoadLuaFile("AutoStampSaveVersion.lua", sUserLua )  -- enthält Event: "OnBeforeSave"


    EDIT:
    Habe es dann mal doch hinbekommen. Mir war nicht bewußt, dass ich mit LUA zwei \\ benutzen muss.

    Hier meine Lösung in der SciTEStartup.lua:
    LoadLuaFile("AutoStampSaveVersion.lua", sUserLua .. "\\") -- enthält Event: "OnBeforeSave"


    Sucht er nicht automatisch in diesem Pfad nach den User-LUA-Scripten?
    Dachte dafür wurde die PATH erweitert.

  • Habe folgenden Eintrag in meiner SciTEUser.properties:
    Lua.User.Scripts.Path=$(SciteDefaultHome)\_OWN\LUA_Scripts
    --> hier liegt AutoStampSaveVersion.lua
    --> hier liegt shell.dll

    Eigene Lua-Tools sollten NICHT ins SciTE-Verzeichnis rein, da sie bei einem Update gelöscht werden.


    Bei mir sieht die Config so aus...

    Brainfuck
    Folgender Eintrag in der SciTEUser.properties:
    Lua.User.Scripts.Path=C:\Users\Bitnugger\LuaScripts
    Brainfuck
    Folgende Einträge als letzte Einträge in der SciTEStartup.lua:
    -- Erst nach Registrierung der EventClass werden eigene Dateien geladen
    LoadUserLuaFile("Ownhotkeys.lua")
    LoadUserLuaFile("AutoStampSaveVersion.lua")  -- enthält Event: "OnBeforeSave"
    LoadUserLuaFile("EdgingSelection.lua")
    LoadUserLuaFile("SelectStatement.lua")
    LoadUserLuaFile("VarGetTipp_ListEvent.lua")
    LoadUserLuaFile("ShowHexColorFromCursor.lua")
  • nachdem ich jetzt so langsam einige weitere LUA-Scripte hinzugefügt habe, habe ich hier auch die Lösung gefunden:

    es fehlte die Zeile
    LUA_USER_PATH = LUA_USER_PATH .. sUserLua .. "\\?.lua;" .. sUserLua .. "\\?\\?.lua;"

    Code
    -- Start up the events (Calls OnStartup()).
    EventClass:BeginEvents()
    -- Erst nach Registrierung der EventClass werden eigene Dateien geladen
    local sUserLua = props["Lua.User.Scripts.Path"] .. "\\"
    LUA_USER_PATH = sUserLua .. "\\?.dll;" .. sUserLua .. "\\?\\?.dll;"
    LUA_USER_PATH = LUA_USER_PATH .. sUserLua .. "\\?.lua;" .. sUserLua .. "\\?\\?.lua;"
    package.cpath = LUA_USER_PATH .. package.cpath
    LoadLuaFile("AutoStampSaveVersion.lua", sUserLua ) -- enthält Event: "OnBeforeSave"
    • Offizieller Beitrag

    Hi,
    inzwischen konntet ihr das Problem ja lösen. ^^

    Hier mal meine Startup.lua, alle NICHT-ORIGINAL-Einträge sind rot markiert:

    Spoiler anzeigen


    --------------------------------------------------------------------------------

    -- SciTE startup script.
    --------------------------------------------------------------------------------

    local sUserLua = props["Lua.User.Scripts.Path"]

    LUA_USER_PATH = sUserLua .. "\\?.dll;" .. sUserLua .. "\\?\\?.dll;"
    package.cpath = LUA_USER_PATH .. package.cpath

    LUA_USER_LUA = sUserLua .. "\\?.lua;" .. sUserLua .. "\\?\\?.lua;"
    package.path = LUA_USER_LUA .. package.path

    -- A table listing all loaded files.
    LoadLuaFileList = { }

    --------------------------------------------------------------------------------
    -- LoadLuaFile(file, directory)
    --
    -- Helper function for easily loading Lua files.
    --
    -- Parameters:
    -- file - The name of a Lua file to load.
    -- directory - If specified, file is looked for in that directory. By default,
    -- this directory is $(SciTEDefaultHome)\Lua.
    --------------------------------------------------------------------------------
    function LoadLuaFile(file, directory)
    if directory == nil then
    directory = props["SciteDefaultHome"] .. "\\Lua\\"
    end
    table.insert(LoadLuaFileList, directory .. file)
    dofile(directory .. file)
    end -- LoadLuaFile()
    --------------------------------------------------------------------------------
    -- Calls LoadLuaFile() with directory from Lua-User-Script property
    -- Also used from file "Ownhotkeys.lua"
    --------------------------------------------------------------------------------
    function LoadUserLuaFile(file)
    LoadLuaFile(file, props["Lua.User.Scripts.Path"] .. "\\")
    end -- LoadUserLuaFile()
    --------------------------------------------------------------------------------


    -- Load all the Lua files.
    LoadLuaFile("Class.lua") -- Always load first.
    LoadLuaFile("Common.lua") -- Always load second.
    LoadLuaFile("AutoItPixmap.lua")
    LoadLuaFile("AutoHScroll.lua")
    LoadLuaFile("AutoItAutoComplete.lua")
    LoadLuaFile("LoadSession.lua")
    LoadLuaFile("AutoItIndentFix.lua")
    LoadLuaFile("EdgeMode.lua")
    LoadLuaFile("SmartAutoCompleteHide.lua")
    LoadLuaFile("Tools.lua")
    LoadLuaFile("AutoItTools.lua")
    LoadLuaFile("AutoItGotoDefinition.lua")
    LoadLuaFile("SciTE_extras.lua")

    if os.getenv("SCITE_USERHOME") ~= nil then
    f = io.open(os.getenv("SCITE_USERHOME") .. "\\PersonalTools.lua")
    if f ~= nil then
    LoadLuaFile("PersonalTools.lua",os.getenv ("SCITE_USERHOME") .. "\\")
    f:close()
    end
    else
    f = io.open(os.getenv("USERPROFILE") .. "\\PersonalTools.lua")
    if f ~= nil then
    LoadLuaFile("PersonalTools.lua",os.getenv ("USERPROFILE") .. "\\")
    f:close()
    end
    end

    -- Start up the events (Calls OnStartup()).
    EventClass:BeginEvents()

    LoadUserLuaFile("AutoStampSaveVersion.lua") -- Timpe-Stamp, Version Management
    LoadUserLuaFile("ContinuousComments.lua") -- Aligned Comments
    LoadUserLuaFile("EdgingSelection.lua") -- Paired Characters, Auto array declaration from selected values
    LoadUserLuaFile("Ownhotkeys.lua") -- Activates OwnHotkeys
    LoadUserLuaFile("MySciTETools.lua") -- My SciTE-Tools
    LoadUserLuaFile("CodeAsHtml.lua") -- Au3 To HTML
    LoadUserLuaFile("SelectStatement.lua") -- Selected code set in statement
    LoadUserLuaFile("ShowHexColorFromCursor.lua") -- Displays colors inside SciTE
    LoadUserLuaFile("CommentAutoPos.lua") -- Comments behind code in line starts automatically at given column
    LoadUserLuaFile("ReplTabWithSpaces.lua") -- Inserts spaces while hit the TAB, with Backspace delete count spaces for Tab width


    Hier noch mal eine kurze Erklärung, was die PATH-Anweisungen bewirken:

    LUA_USER_PATH = sUserLua .. "\\?.dll;" .. sUserLua .. "\\?\\?.dll;"
    Hiermit stelle ich zwei Pfadangaben mit Platzhalter zusammen, die anschließend der Globalen Variablen package.cpath hinzugefügt werden.
    Die Pfade werden mit Semikolon voneinander getrennt. Das Fragezeichen ist Platzhalter für einen identischen Wert.
    Bsp.:
    Mein User-Lua-Pfad ist: C:\Skripte\MeinLua
    Ich möchte die shell.dll einbinden. Dann kann ich jetzt entweder die Dll direkt in den User-Pfad kopieren
    • C:\Skripte\MeinLua\shell.dll oder in einen gleichnamigen Ordner im User-Pfad
    • C:\Skripte\MeinLua\shell\shell.dll

    LUA_USER_LUA = sUserLua .. "\\?.lua;" .. sUserLua .. "\\?\\?.lua;"
    Dieser Pfad verweist auf zu verwendende Lua-Dateien, die Bezeichnung der Ordner und Dateien erfolgt analog zum Bsp. der Dll-Dateien.
    Anschließend erfolgt hier die Zuordnung zur Globalen Variablen package.path.

    Die Verwendung von gleichnamigen Ordnern, die das jeweilige Skript/die Dll enthalten ist sehr sinnvoll um Ordnung zu halten. So kann man notwendige Dateien, auf die die einzubindenden Dateien zugreifen müssen, übersichtlich mit im jeweiligen Modul-Ordner speichern.

  • BugFix 5. Januar 2019 um 00:41

    Hat den Titel des Themas von „TimeStamp - erweitert zu kleiner Versionsverwaltung für .au3 und .lua“ zu „TimeStamp - erweitert zu kleiner Versionsverwaltung für (.au3 und .lua) alle Typen“ geändert.
    • Offizieller Beitrag

    Nach langer Zeit etwas Neues (v 1.4):

    - einen Fehler behoben (Event wurde genutzt statt Event Class - allerdings nur problematisch, wenn man den Fehler nochmal macht, dann wird nur eine Funktion ausgeführt)

    - Umbau der Funktion, jetzt kpl. gesteuert über die Properties, auf beliebig viele Dateitypen erweiterbar. BITTE BEACHTEN: PROPERTIES MÜSSEN GEÄNDERT WERDEN.

    (s. Startpost)