Versionsverwaltung mit Monotone - Benutzerdefinierte Befehle
Zwei Möglichkeiten gibt es, das Versionsverwaltungs System Monotone mit der eingebauten Scriptsprache Lua zu erweitern:
- Lua Hooks
- Benutzerdefinierte Befehle
In diesem Artikel gehe ich auf letztere ein.
rcfiles
Generell werden Lua-Funktionen in rcfiles definiert, die bei jedem Lauf von monotone gelesen werden. Diese rcfiles findet monotone an verschiedenen Stellen:
- ~/.monotone/monotonerc bzw. %APPDATA%\monotone\monotonerc
- _MTN/monotonerc im aktuellen Arbeitsbereich
- Dateien, die mit
--rcfile=Dateiname
in der Kommandozeile angegeben werden - alle Dateien in Verzeichnissen, die mit
--rcfile=Verzeichnisname
in der Kommandozeile angegeben werden
Zuerst wird die Datei ~/.monotone/monotonerc, dann _MTN/monotonerc, wenn vorhanden und schließlich die mit --rcfile angegebenen in der Reihenfolge der Kommandozeile geladen. Spätere Definitionen überschreiben dabei frühere.
Definieren von eigenen Befehlen
Um Monotone einen eigenen Befehl beizubringen, muss man eine Lua-Funktion registrieren, die bei Aufruf dieses Befehls gerufen wird. Dazu verwendet man die von monotone zur Verfügung gestellte Funktion register_command:
register_command(name, params, abstract, description, function)
Diese Funktion fügt einen Befehl name zu den Benutzerbefehlen von
monotone
hinzu. Wenn dieser registrierte Befehl aufgerufen wird, wird monotone
die mit
function bereitgestellte Definition aufrufen. Diese Funktion würde
üblicherweise mtn_automate
(siehe unten) verwenden, um den Aufruf
abzuarbeiten. params ist eine Zeichenkette mit der Liste der
Parameter
für den Befehl. abstract ist eine kurze Beschreibung, description
eine
längere Beschreibung des Benutzerbefehls. Bei mtn help
werden
params,
abstract und description ausgegeben.
Die von monotone bereitgestellte Funktion mtn_automate stellt die
Funktionalität von mtn automate
für andere Lua-Funktionen zur
Verfügung:
rc, output = mtn_automate(command args ...)
Das Ergebnis ist ein pair (Lua), bestehend aus einem Boolean (true
bei Erfolg) und einer Zeichenkette, die den Inhalt von stdout nach
Aufruf von automate command
enthält.
Beispiel: Einbetten der aktuellen Revision
Bei einigen Versionsverwaltungssystemen - zum Beispiel RCS und CVS - gibt es Schlüsselworte, die im Quelltext eingesetzt werden können und dann vom Versionsverwaltungssystem durch die entsprechenden Werte, wie die Version der Datei oder das Datum des Check-in, ersetzt werden. So etwas gibt es bei monotone nicht, sodass man sich hier im Bedarfsfall mit einem Script behilft, das eine Datei automatisch generiert, die dann im Quelltext eingebunden wird.
Für das Monotone Brevier habe ich ein solches rcfile verwendet, das mir die Angaben zur Revision und etwas Zusatztext passend zur Weiterverarbeitung mit den Python Docutils ausgibt:
-- revision.lua -- Monotone extension command "mtn revision"
-- usage: mtn --rcfile revision.lua revision
register_command(
"revision", "",
"Print info about actual revision.",
"Determines the base revision and whether the current " ..
"revision is different. Prints the information " ..
"suitable for inclusion into restructured text.",
"command_revision"
)
function say(abc) io.stdout:write(abc .. "\n") end
function command_revision()
rc, txt = mtn_automate("get_base_revision_id")
base_rev = string.match(txt,"%x+")
if nil == base_rev then
base_rev = ""
end
input, output, pid = spawn_pipe("mtn", "ls", "changed")
res, rc = wait(pid)
changed = output:read('*a')
if 0 == string.len(changed) and "" ~= base_rev then
curr_rev = base_rev
else
rc, txt = mtn_automate("get_current_revision_id")
curr_rev = string.match(txt,"%x+")
end
say(":Autor: Mathias Weidner")
say(":Datum: " .. os.date('%Y-%m-%d'))
say(":Basisrevision: " .. base_rev)
say(":Aktuelle Revision: " .. curr_rev)
say(":Lizenz: CC BY-SA 3.0 (Creative Commons)")
end
Diese Erweiterung verwende ich wie folgt:
$ mtn --rcfile revision.lua revision > revision.txt
Die Ausgabe sieht dann in etwa so aus:
:Autor: Mathias Weidner
:Datum: 2011-06-16
:Basisrevision: 73eccbdd18e918b1a99d611692d67689dec04e10
:Aktuelle Revision: 73eccbdd18e918b1a99d611692d67689dec04e10
:Lizenz: CC BY-SA 3.0 (Creative Commons)
Mit mtn help
kann ich mir den Hilfetext zu dieser selbstdefinierten
Funktion ansehen:
$ mtn --rcfile revision.lua help revision
Aufruf: mtn [OPTION...] Kommando [ARGUMENTE...]
Beschreibung für 'mtn revision':
Print info about actual revision..
Determines the base revision and whether the current revision is different.
Prints the information suitable for inclusion into restructured text.
Weitere Beispiele zu benutzerdefinierten Funktionen findet man im Verzeichnis contrib/command der Quellcode-Distribution von Monotone.
Ein Einstieg zur Erweiterung von monotone mit Lua findet sich in englischer Sprache unter http://www.monotone.ca/docs/Lua-Reference.html. Eine kurze Referenz der von monotone bereitgestellten Lua-Funktionen findet sich unter http://www.monotone.ca/docs/Additional-Lua-Functions.html.
Posted 2011-06-17