weidner/computer/rcs/monotone/

Versionsverwaltung mit Monotone - Benutzerdefinierte Befehle

Zwei Möglichkeiten gibt es, das Versionsverwaltungs System Monotone mit der eingebauten Scriptsprache Lua zu erweitern:

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:

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
Tags: