Aus Linux-Magazin 04/2006

Softwareprojekte verwalten mit Trac

© sxc.hu

Größere Softwareprojekte bedeuten Teamarbeit – doch die will koordiniert sein. Trac, ein Python-basiertes Framework, vereinigt alle nötigen Komponenten unter einer gemeinsamen Weboberfläche.

Viele Softwareprojekte setzen Subversion, ein Webinterface zum SVN-Repository, Bugzilla und ein Wiki-System wie Mediawiki ein, um Code zu verwalten und zu dokumentieren. Die Nachteile beim Einsatz unabhängiger Komponenten sind der hohe Administrationsaufwand und die mangelnde Integration der Einzelanwendungen: Der Bugtracker weiß nichts von den Versionen in SVN und im Wiki lassen sich keine Links auf den Bugtracker setzen.

Dieser Artikel stellt eine Alternative vor, deren einzelne Komponenten aufeinander abgestimmt sind: Trac [1] integriert ein Wiki-Modul, ein Ticketsystem, einen Sourcecode-Browser sowie eine Timeline- und eine Roadmap-Funktion. Trac lässt sich auch durch Plugins erweitern.

Voraussetzungen

Die Installation von Trac erfordert einige Vorarbeit: Voraussetzungen sind Python, Subversion, die Python-Subversion-Bindings, das Templating-System Clearsilver [2] und – je nachdem, welche Datenbank eingesetzt werden soll – SQLite oder PostgreSQL mit zugehörigen Python-Bindings. Dennoch gelingt die Installation leichter als bei Bugzilla. Das Trac-Manual [3] enthält eine genaue Installationsanleitung.

Trac kann seine Dienste über vier verschiedene Methoden im Netz anbieten: über den mitgelieferten Webserver Tracd, im Apache über das »mod_python« sowie als Fast-CGI- oder herkömmliches CGI-Skript. Für den Produktiveinsatz sind »mod_python« oder Fast-CGI zu empfehlen, von der Benutzung des CGI-Interface ist aus Performancegründen abzuraten. Tracd ist performant, bietet allerdings weniger Features als der Apache-Webserver. Beispielsweise fehlt eine SSL-Unterstützung.

Neue Projekte legt der jeweilige Projektverwalter mit dem Kommandozeilentool »trac-admin« [4] an. Hier lassen sich unter anderem Zugriffsrechte für Nutzer vergeben, Konfigurationen für das Ticketmodul vornehmen, Milestones verwalten und Backups erstellen oder frühere Zustände einspielen.

Die Zugriffsrechte regelt Trac auf Komponenten-Ebene. Im Ticketsystem existieren zum Beispiel folgende Rechte: »TICKET_VIEW«, »TICKET_CREATE«, »TICKET_APPEND«, »TICKET_CHGPROP«, »TICKET_MODIFY«, »TICKET_ADMIN«. Auch die anderen Komponenten stellen auf die jeweilige Funktionalität zugeschnittene Zugriffslevel bereit. Mit »_ADMIN« steht ein Platzhalter für alle möglichen Rechte eines Moduls zur Verfügung. Benutzer, die nicht eingeloggt sind, arbeiten mit den Rechten des Users »anonymous«.

Das Wiki

Das Wiki in Trac (Abbildung 1) unterstützt die meisten von anderen Wiki-Systemen bekannten Features. Eine Besonderheit des Trac-Wiki sind Links auf andere Trac-Komponenten: »ticket:153« verweist auf Ticket 153 im Ticketsystem. Links auf Dateien im Subversion-Repository sind mit »source:/ Pfad« leicht zu realisieren. Auch in Commitmessages des Versionskontrollsystems und in Ticketkommentaren des Bugtracker lassen sich Links zu den anderen Trac-Komponenten herstellen. Diese Verzahnung der Komponenten ist der größte Vorteil der Trac-Projektverwaltung.

Abbildung 1: Alle Komponenten unter einer einheitlichen Oberfläche: Die Startseite des Trac-Wiki nach der Einrichtung eines Projekts.

Abbildung 1: Alle Komponenten unter einer einheitlichen Oberfläche: Die Startseite des Trac-Wiki nach der Einrichtung eines Projekts.

Das Ticketsystem

Tracs Ticketsystem (Abbildung 2) ähnelt dem anderer Bugtracker wie Bugzilla. Die meisten Ticketeigenschaften lassen sich mit dem »trac-admin« konfigurieren. Dazu gehören Tickettypen, Prioritäten, Versionen und Milestones. Darüber hinaus kann der Administrator in der Datei »trac.ini« weitere Felder für Tickets hinzugefügten [7].

Abbildung 2: Trac integriert ein Ticketsystem, das zwar nicht den Funktionsumfang von Bugzilla erreicht, das jedoch alle für kleine bis mittelgroße Projekte benötigten Features bietet.

Abbildung 2: Trac integriert ein Ticketsystem, das zwar nicht den Funktionsumfang von Bugzilla erreicht, das jedoch alle für kleine bis mittelgroße Projekte benötigten Features bietet.

Zudem ist es ebenfalls möglich, bei Ticketänderungen automatische E-Mail-Notifikationen an die Teammitglieder zu verschicken [8] und über Commitmessages Tickets im Bugtracker zu verändern. Eine Unterstützung für Time-Tracking und Bug-Statistiken sowie andere Features, die Bugzilla bietet, fehlen allerdings. Für kleinere bis mittlere Projekte reicht die gebotene Funktionalität aber trotzdem aus.

Sourcecode-Browser, Timeline und Roadmap

Außer den beiden Hauptkomponenten, dem Wiki und dem Ticketsystem, liefert Trac noch drei Hilfsmodule mit: Der Sourcecode-Browser (Abbildung 3) verschafft dem Benutzer lesenden Zugriff zum Repository. Das ist einerseits hilfreich, wenn ein Benutzer von einem System ohne Subversion-Client auf das Repository zugreifen möchte. Zudem lassen sich mit ihm vom Ticketsystem oder den Wiki-Seiten aus Links auf Dateien im Repository setzen.

Abbildung 3: Der Trac-Sourcecode-Browser bietet einen komfortablen Lesezugriff: Neben den Commitmessages zeigt er den Quellcode mit Zeilennummerierung und Syntax-Higlighting.

Abbildung 3: Der Trac-Sourcecode-Browser bietet einen komfortablen Lesezugriff: Neben den Commitmessages zeigt er den Quellcode mit Zeilennummerierung und Syntax-Higlighting.

Die Timeline zeigt einen chronologischen Überblick über Änderungen am Projekt, also über Commits, Ticketänderungen und Änderungen im Wiki. Jedes angezeigte Event enthält einen Link auf die zugehörige Trac-Komponente. So leiten die Links der Commit-Events zum Changeset-Viewer des Sourcecode-Browsers weiter, der eine Diff-Ansicht der veränderten Dateien anzeigt. Alle Einträge der Timeline stellt Trac als RSS-Feed bereit. Der RSS-Feed eignet sich auch, um über einen IRC-Bot Ereignisse wie Commits im Chat anzukündigen.

Die Roadmap-Komponente verschafft einen Überblick über den Fortschritt bei der Projektentwicklung: Jedes Ticket lässt sich einem so genanten Milestone zuordnen. In der Roadmap zeigt Trac eine grafische Übersicht über offene und bereinigte Bugs.

Wiki-Makros

Über Wiki-Makros [5] und Plugins lässt sich Trac an die eigenen Wünsche anpassen. Die Plugin-Architektur existiert seit Version 0.9. Alle Trac-Komponenten sind seither als Plugins implementiert. Zudem ist es im Wiki-Kontext möglich, Custom Queries, also eine benutzerdefinierte Auswahl der Einträge, im Ticketsystem zu erstellen [9].

Wiki-Makros sind Python-Module, die im Wiki mit der Syntax »[[Dateiname(Makroargumente)]]« eingebunden werden. Sie sind einfacher zu realisieren als Plugins. Die Quelldateien liegen entweder im globalen Installationsverzeichnis oder im lokalen »wiki-macros«-Verzeichnis. Listing 1 zeigt ein einfaches Beispiel, das die aktuelle Zeit ausgibt.

Listing 1: Einfaches
Wiki-Makro

01 import time
02 def execute(hdf, txt, env):
03         return "Aktuelle Zeit: %s" % time.strftime("%c", time.localtime())

Die Ausführung des Makros startet mit der »execute()«-Methode. Trac übergibt dieser Methode drei Parameter: »hdf« ist das HDF-Dataset des Clearsilver-Template [10] für die Seite, das die Anzeige der Seite steuert. »args« enthält die im Wiki-Quellcode angegebenen Parameter und »env« schließlich ist ein Objekt der Trac-Klasse »Environment«, die einen Zugriff auf verschiedene Eigenschaften des Projekts möglich macht.

Das vorgestellte einfache Makro wertet keinen der genannten Parameter aus, es gibt über die »execute()«-Methode lediglich einen einfachen Zeitwert zurück. Den Rückgabewert dieser Methode fügt das Wiki als HTML-Code in die Seite ein. Trac liefert in der Standarddistribution bereits einige Makros mit. Der Trac-Guide [5] enthält eine Übersicht.

Ein größere Auswahl fertiger Makros, beispielsweise ein Makro, das ein Inhaltsverzeichnis generiert, bietet der Makro-Bazaar auf der Trac-Webseite [6]. Hier finden sich auch Beispiele, die die »Environment«-Methoden und das HDF-Dataset des Clearsilver-Template-Systems demonstrieren.

Plugins

Trac-Plugins setzen auf den Python-Code der Standardkomponenten auf [11]. Das Modul »trac.core« implementiert den minimalistischen Trac-Kernel, der aber lediglich die anderen Komponenten verwaltet. Jedes Plugin ist als Subklasse von »Component« zu realisieren. Der »ComponentManager« des Trac-Kernels koordiniert diese Unterklassen.

Trac-Komponenten können so genannte Extension Points definieren, über die sich andere Komponenten einklinken und dadurch Tracs Verhalten beeinflussen. So kann ein Plugin die Extension Points der Klasse »IEnvironmentSetupParticipant« implementieren und damit Einfluss auf die Erstellung von Trac-Projekten durch die Klasse »Environment« nehmen. In diesem Fall ist es also die Klasse »IEnvironmentSetupParticipant«, die die Extension Points für die Klasse »Environment« definiert.

Viele weitere Trac-Komponenten bieten ebenfalls eine Reihe von Extension Points an, auf die Plugins zugreifen können, um die Standardfunktionalität von Trac zu erweitern oder zu verändern.

Plugin-Beispiel

Listing 2 zeigt ein Plugin, das ein einfaches Frontend für das »trac-admin«-Tool realisiert. Es leitet die Benutzereingabe als Befehl weiter und erspart so den Konsolenaufruf. Zusätzlich fügt es das Verzeichnis des aktuellen Projekts in den Aufruf ein. Ausgaben des »trac-admin« zeigt das Plugin ebenfalls an. Die Zeilen 1 bis 6 importieren die erforderlichen Module. Zeile 8 definiert die Klasse »TracAdminModule«, die »Component« aus der Trac-Umgebung beerbt, und der Aufruf der »implements()«-Methode legt die Klassen fest, deren Extension Points das Plugin implementiert.

Listing 2: Webfrontend zu
»trac-admin«

01 from trac.core import * # benötigte Klassen importieren
02 from trac.perm import IPermissionRequestor
03 from trac.web.chrome import INavigationContributor
04 from trac.web import IRequestHandler
05 from trac.util import escape
06 import os
07 
08 class TracAdminModule(Component):
09     implements(INavigationContributor, IRequestHandler, IPermissionRequestor)
10 
11     tracadmin_cs = """ 
12     <?cs include "header.cs" ?>
13     <?cs include "macros.cs" ?>
14     <div id="content" class="stats">
15       <h1>trac-admin</h1>
16       <form method="POST" action="">
17         trac-admin <?cs var:trac_path ?> <input type="text" name="command" />
18         <input type="submit" value="Execute"> <br />
19         Output: <pre><?cs var:command_output ?></pre>
20       </form>
21     </div>
22 
23     <?cs include "footer.cs" ?>
24     """
25 
26     # INavigationContributor methods
27     def get_active_navigation_item(self, req):
28         return 'tracadmin'
29 
30     def get_navigation_items(self, req):
31         if not req.perm.has_permission('TRAC_ADMIN_PLUGIN'):
32             return
33         yield 'mainnav', 'tracadmin', "<a href='%s'>trac-admin</a>" 
34                                        % escape(self.env.href.tracadmin())
35 
36     # IPermissionRequestor methods
37     def get_permission_actions(self):
38         return ['TRAC_ADMIN_PLUGIN']
39 
40     # IRequestHandler methods
41     def match_request(self, req):
42         return req.path_info == '/tracadmin'
43 
44     def process_request(self, req):
45         req.perm.assert_permission('TRAC_ADMIN_PLUGIN')
46         req.hdf['trac_path'] = self.env.path
47 
48         if req.method == 'POST':
49             command = req.args.get('command')
50             (stdin, stdout_stderr) = os.popen4('trac-admin %s %s' % (self.env.path, command))
51             req.hdf['command_output'] =
52             escape(stdout_stderr.read()).replace('n', '<br />')
53 
54         template = req.hdf.parse(self.tracadmin_cs)
55         return template, None

Plugins integrieren ihre Ausgabe über das Clearsilver-Templatesystem in das Trac-Interface. Hierzu weisen sie der Variablen »tracadmin_cs« Code zu. Das Beispiel-Plugin übergibt hier den HTML-Code für ein Formular (Zeilen 12 bis 21). Zusätzlich setzt es Clearsilver-spezifische Includes ein, um Seitenkopf und -fuß zu erzeugen. Mit Hilfe von Clearsilver-Variablen fügt es dynamischen Text in die Seite ein: »cs var:trac_path« und »cs var:command_output« geben den Pfad des Trac-Projekts und die Ausgabe des »trac-admin«-Tools zurück.

Die Zeilen 26 bis 54 enthalten den eigentlichen Programmcode, der Methoden aus mehreren Trac-Komponenten implementiert: Die beiden »INavigationContributor«-Methoden (Zeilen 27 bis 34) dienen zur Erweiterung der Trac-Menüleiste. Die Methode »get_navigation_items()« legt per Rückgabewert die Menü-Einträge fest, die das Plugin hinzufügen soll. Sie finden sich nur im Rückgabewert der Methode, wenn der Benutzer die »TRAC_ADMIN_PLUGIN«-Permission hat. Die Zeilen 37 und 38 definieren diesen Permission-Typ mit der »get_permission_actions()«-Methode: Jedes Plugin kann eigene Permissions definieren. »get_active_navigation_item()« legt den Navigationseintrag fest, der beim Klick auf des Menü hervorzuheben ist. Nur dann kann der Benutzer die Funktion ausführen.

An die Öffentlichkeit

Bis jetzt ist noch kein Zugriff auf das Plugin möglich. Die Methode »match_request()« verknüpft die URL »/tracadmin« mit dem Plugin, die Methode »process_request()« leistet die eigentliche Arbeit. Sie wertet die Anfragen aus und gibt den fertigen Seitencode zurück: Zunächst setzt sie die Variable »trac_path« des Clearsilver-Template auf den absoluten Pfad des Trac-Projekts. Dann prüft sie, ob der Benutzer das Formular bereits abgeschickt hat. Wenn ja, führt sie das eingegebene Kommando aus und füllt die Variable »command_output« mit der Rückgabe des Trac-Admin. Schließlich erzeugt sie aus der Variablen »template« ein Clearsilver-Templateobjekt und gibt es mit zurück (Abbildung 4).

Abbildung 4: Neuer Eintrag im Trac-Menü: Ein Plugin bindet das Kommandozeilentool »trac-admin« in die Weboberfläche ein. Es übergibt ihm Befehle und zeigt die Ausgabe des Tools an.

Abbildung 4: Neuer Eintrag im Trac-Menü: Ein Plugin bindet das Kommandozeilentool »trac-admin« in die Weboberfläche ein. Es übergibt ihm Befehle und zeigt die Ausgabe des Tools an.

Um das Plugin in ein Projekt einzubauen, muss es als Python Egg [12] gepackt werden. Das Setuptools-Paket von Python schafft hierfür die Voraussetzung. Listing 3 zeigt ein Setup-Skript, um das Plugin in die Trac-Umgebung zu integrieren. Es liegt in der Ordnerhierarchie einen Level über dem Ordner »tracadmin«, der den Plugin-Code enthält.

Listing 3:
»setup.py«

01 from setuptools import setup
02 
03 PACKAGE = 'TracAdminPlugin'
04 VERSION = '0.1'
05 
06 setup(name=PACKAGE, version=VERSION,packages=['tracadmin'],
07       entry_points = { 'trac.plugins': ['tracadmin = tracadmin'] } )

Im »tracadmin«-Ordner ist neben der Datei »tracadmin.py« mit dem Programmcode noch eine Datei »__init__.py« mit dem Inhalt »from tracadmin import *« nötig, die das Plugin initialisiert. »python setup.py bdist_egg« erzeugt schließlich die Egg-Datei. Diese ist entweder in den »plugins«-Ordner des aktuellen Trac-Projekts zu kopieren oder global mit »python setup.py install« einzubinden. Weitere Informationen zur Plugin-Entwicklung stehen auf der Trac-Hacks-Seite [13] und im Entwicklerbereich [14] der Trac-Website zur Verfügung.

Fazit

Trac eignet sich für die Verwaltung kleinerer bis mittelgroßer Softwareprojekte. Die gute Integration der einzelnen Komponenten erleichtert die Arbeit. Zudem stehen alle Teilsysteme übersichtlich unter einer einheitlichen Weboberfläche bereit. Durch Plugins und Wiki-Makros ist es möglich, Trac an die eigenen Bedürfnisse anzupassen. (pkr)

Infos

[1] Trac Projektwebsite: [http://projects.edgewall.com/trac/]

[2] Projektseite des Clearsilver-Templatesystem: [http://www.clearsilver.net/]

[3] Trac-Manual: [http://projects.edgewall.com/trac/wiki/TracGuide]

[4] Trac-Admin-Tool: [http://projects.edgewall.com/trac/wiki/TracAdmin]

[5] Wiki-Makros: [http://projects.edgewall.com/trac/wiki/WikiMacros]

[6] Macro-Bazaar: [http://projects.edgewall.com/trac/wiki/MacroBazaar]

[7] Benutzerdefinierte Felder für Tickets: [http://projects.edgewall.com/trac/wiki/TracTicketsCustomFields]

[8] E-Mail-Notifikationen für Ticketänderungen: [http://projects.edgewall.com/trac/wiki/TracNotification]

[9] Custom Queries: [http://projects.edgewall.com/trac/wiki/TracQuery]

[10] Erläuterung zum HDF-Datenset des Clearsilver-Templatesystems: [http://www.clearsilver.net/docs/man_hdf.hdf]

[11] Tracs Komponentenarchitektur: [http://projects.edgewall.com/trac/wiki/TracDev/ComponentArchitecture]

[12] Python Eggs: [http://peak.telecommunity.com/DevCenter/PythonEggs]

[13] Trac-Hacks: [http://trac-hacks.swapoff.org]

[14] Entwicklerbereich der Trac-Projektwebsite: [http://projects.edgewall.com/trac/wiki/TracDev]

Der Autor

Michael Göttsche besucht den 13. Jahrgang eines Gymnasiums in Bargteheide. Daneben beschäftigt er sich mit verschiedenen Themen aus dem Bereich Software-Entwicklung.

LINUX-MAGAZIN KAUFEN
EINZELNE AUSGABE Print-Ausgaben Digitale Ausgaben
ABONNEMENTS Print-Abos Digitales Abo
TABLET & SMARTPHONE APPS Readly Logo
E-Mail Benachrichtigung
Benachrichtige mich zu:
0 Kommentare
Älteste
Neuste Beste Bewertung
Inline Feedbacks
Alle Kommentare anzeigen
Nach oben