Archiv für die Kategorie ‘Werkzeuge’

Trac-Themes

Donnerstag, 28. Januar 2010

2 Jahre ist es jetzt in etwa her, dass ich einen Artikel über Eigene Templates in Trac geschrieben habe. Seitdem ist ein wenig passiert. Diesen Änderungen möchte ich hiermit Rechnung tragen. Ich habe das ganze Trac-Themes genannt, weil es weniger um Templating an sich gehen soll, sondern eher um eine Möglichkeit gemeinsame Styles festlegen zu können.

Leider ist es mit Trac immer noch nicht möglich unter einem Environment mehrere Projekte bzw. Repositories laufen zu lassen. Darum wird für jedes Projekt eine eigene Trac-Umgebung angelegt. Wichtig hierbei ist insbesondere für Firmen, dass alle Projekte zumindest in der Grundstruktur gleich aussehen und die Firmenfarben tragen.

“… was bisher geschah”

Wer zuerst probieren will, wie und was er alles anpassen kann, sollte sich das Verzeichnis templates unterhalb seiner Trac-Umgebung anschauen. Standardmäßig liegt dort die Datei site.html. Wenn man sie das erste Mal aufmacht, kommt sie sehr unscheinbar daher, denn wie man sieht, sieht man nichts. Nur einen html-Tag und ein paar unbekannt anmutende Python-Attribute.
Auf der Seite http://trac.edgewall.org/wiki/TracInterfaceCustomization ist glücklicherweise bereits ein Beispiel-Code für den Inhalt dieser Datei. Für jene, die gerne lieber mehrere Dateien nutzen wollen hier gleich die Anpassung mit Einbindung externer Dateien:

<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:py="http://genshi.edgewall.org/"
      xmlns:xi="http://www.w3.org/2001/XInclude"
      py:strip="">

  <!--! Add site-specific style sheet -->
  <head py:match="head" py:attrs="select('@*')">
    ${select('*|comment()|text()')}
    <link rel="stylesheet" type="text/css"
          href="${href.chrome('common/style.css')}" />
  </head>

  <body py:match="body" py:attrs="select('@*')">
    <!--! Add site-specific header -->
    <div id="siteheader">
       <xi:include href="site_header.cs">
         <xi:fallback />
       </xi:include>
    </div>

    ${select('*|text()')}

    <!--! Add site-specific footer -->
    <div id="sitefooter">
      <xi:include href="site_footer.cs">
        <xi:fallback />
      </xi:include>
    </div>
  </body>
</html>

Interessanterweise funktioniert das einfache Anlegen einer site_header.cs und site_footer.cs nicht immer – bzw. bei mir hat das noch nie funktioniert -, wie es auf manchen Seiten beschrieben wird.
Mit diesem Grundgerüst ausgestattet lässt sich schon anfangen herumzuspielen. Für weiterführende Informationen zu Genshi und Clearsilver – den Engines im Hintergrund – sei auf folgende Seiten verwiesen:

Neue und alte Freunde

Ein altbekannter Helfer beim Erstellen von Templates ist auch in der Version 0.11.5 noch vorhanden. Der Konfigurationsparameter template_dir.

[inherit]
template_dir=

Mit diesem Parameter lässt sich das Verzeichnis für die Templates festlegen und wodurch verschiedene Seiten mit ein und demselben Template ausgestattet werden können.

Daneben ist ein neuer Freund dazugekommen der Parameter htdocs_location. Mit diesem Parameter werden alle internen URLs, die mit “common/” beginnen in die URL umgeschrieben, die als Wert angegeben wurde.

[trac]
htdocs_location=http://localhost/mytemplate

Führt, dazu, dass aus

<link rel="stylesheet" href="/trac/templating/chrome/common/css/trac.css" type="text/css" />

folgendes wird

<link rel="stylesheet" href="http://localhost/mytemplate/css/trac.css" type="text/css" />

Achtung! Leider hat die Sache einen Haken. Eigene Links aus der site.html werden nicht übersetzt. Der folgende Code

${href.chrome('common/style.css')}

wird nur in "/trac/templating/chrome/common/style.css" umgewandelt, aber nicht weiter.

Wichtig ist außerdem zu beachten, dass htdocs_location nur für statische Inhalte, wie Bilder, JavaScript- und CSS-Dateien gedacht ist. Templates werden nicht automatisch von dort erkannt. Diese müssen explizit über template_dir konfiguriert werden. Leider ist es hier nur möglich lokale Verzeichnisse zu setzen. Wer z.B. versucht eine Internetadresse anzugeben, bekommt zwar keine Fehlermeldung, wird aber mit einem Standard-Template “belohnt”.

Abschließend möchte ich sagen, dass – gefühlt – wesentlich mehr über die trac.ini konfigurierbar ist, als es noch vor 2 Jahren der Fall war. Das macht definitiv Lust auf mehr, aber dennoch bleibt das ein oder andere noch zu tun.

Und plötzlich war alles dunkel …

Samstag, 14. November 2009

Ich weiss nicht, was passiert ist, aber nach dem Upgrade von Ubuntu auf 9.10 wurden diverse Entwickler-Tools unbenutzbar. Dabei handelt es sich insbesondere um Anwendungen, die nicht direkt aus dem Ubuntu-Repository stammen. Im Folgenden will ich auf Eclipse und Trac eingehen.

Eclipse 3.5

Nachdem auf GTK+ 2.18 aktualisiert wurde, funktionieren diverse Buttons in Eclipse nicht mehr. Schnell wird man dank Google auf der Suche nach einem Fix bzw. Workaround fündig (Migrating to client-side windows). Offensichtlich ist die Umgebungsvariable GDK_NATIVE_WINDOWS für das Problem verantwortlich. Diese muss auf den Wert true gesetzt werden, damit SWT-basierte Java-Oberflächen (Anmerkung: auch andere Java-Applikationen mit SWT haben das Problem) wieder in altem Glanz erstrahlen.

#!/bin/bash
env GDK_NATIVE_WINDOWS=true <your/eclipse/path>/eclipse

(Den Pfad <your/eclipse/path> bitte an das jeweilige Installationsverzeichnis von Eclipse anpassen.)

Leider ist dies nur ein bescheidener Workaround, denn sobald man Eclipse aus sich heraus neu startet (z.B. nach Upgrades oder Plugin-Installationen) existiert das alte Problem wieder. Genauso, wenn man den Workspace versucht zu wechseln, da sich Eclipse auch hier herunterfährt und neu startet.

Ein richtiger Fix ist für die Version 3.5.2 angedacht bzw. soll in der 3.6 schon integriert sein, welche für die SDK-Variante bereits existiert. Nur für JEE-Developer wird es wohl noch etwas dauern.

Von einem globalen Umsetzen der Variable GDK_NATIVE_WINDOWS wird an diversen Stellen explizit abgeraten. Hier sei aber anzumerken, dass die Eclipse-Installation aus den Ubuntu-Repositories genau das macht. Für alle, die etwas “wagemutiger” sind hier das Startskript mit export.

#!/bin/sh

# work around e#290395 / LP: #458703
export GDK_NATIVE_WINDOWS=true

xuldir=/usr/lib/xulrunner-$(/usr/bin/xulrunner-1.9.1 --gre-version)
LD_LIBRARY_PATH=$xuldir${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH} <your/eclipse/path>/eclipse
 "$@"

(Den Pfad <your/eclipse/path> bitte an das jeweilige Installationsverzeichnis von Eclipse anpassen.)

Dieses Skript am besten unter /usr/local/bin als eclipse ablegen und alle Links, die vorher direkt auf die Eclipse-Startdatei gegangen sind auf dieses Skript umbiegen.

Trac

Interessanterweise – was die primäre Motivation für diesen Kurzkommentar war – hat es auch das Bugtracking-Tool Trac erwischt. Zum Glück nicht so “heftig” wie Eclipse, aber dafür umso unverständlicher.

Ich habe lokal Trac mittels easy_install installiert gehabt. Nach dem Upgrade auf Ubuntu 9.10 erhielt ich plötzlich auf allen Trac-Seiten einen 500-Fehler. Nach kurzem Suchen fand ich in der error.log-Datei von Apache (Pfad unter Ubuntu: /var/log/apache2/error.log) folgenden Eintrag:

... [error] [client 127.0.0.1] ImportError: No module named genshi, ...

Warum das Modul plötzlich nicht mehr vorhanden war kann ich zum aktuellen Zeitpunkt nicht erklären, aber das war noch nicht das Ende.

Just in dem Moment wo ich mit

sudo easy_install Genshi

das entsprechende Modul installieren wollte, quittierte mir Ubuntu die Nachricht, dass easy_install nicht existiert. Ein kurzer Blick in Synaptic unter python-setuptools bestätigte die Vermutung, dass das Paket nicht installiert war. Ich möchte an dieser Stelle nicht ausschließen, dass es beim Upgrade in der Liste der zu deinstallierenden Pakete dabei war, aber dennoch ärgerlich. Also war auch hier nachinstallieren angesagt.

Zum Glück fügte sich dann alles sehr schnell. Das Genshi-Modul installierte sich ohne Probleme.

Abschließend musste noch der Workaround für einen Bug (http://trac.edgewall.org/ticket/7526) eingebaut werden. Einfach die compat.py im functional/tests-Ordner in testcompat.py
umbenennen und die compat.pyc in compat.pyc.old umbenennen oder gleich löschen.

GIT geht nicht gern mit Fremden: *** Please tell me who you are.

Samstag, 15. August 2009

Für alle, die es leid waren, sich mit Subversion herumzuschlagen – oder einfach mal neugierig auf ein anderes Versionssystem sind, haben bestimmt schonmal etwas von GIT gehört.

Ich will an dieser Stelle weder die üblichen Lobeshymnen, noch die allseitsbeliebten Hasstiraden anstimmen, sondern nur eine kleine Hilfestellung geben, wenn man sich dazu entschließen will das GIT-Plugin von Hudson zu nutzen.

Die Installation ist zwar – wie immer – simpel, aber leider mag Hudson evtl. nicht gleich mit GIT “spielen”. Will man den Job starten kommt relativ schnell folgende Ausgabe in der Konsolenansicht.

Gestartet durch Benutzer anonymous
Checkout:workspace / /usr/local/apps/hudson_home/jobs/gitTest/workspace – hudson.remoting.LocalChannel@1063971
Last Build : #2
Checkout:workspace / /usr/local/apps/hudson_home/jobs/gitTest/workspace – hudson.remoting.LocalChannel@1063971
Fetching changes from the remote Git repository
Fetching upstream changes from file:///var/local/workspaces/experiments/sampleProject
[workspace] $ git fetch file:///var/local/workspaces/experiments/sampleProject +refs/heads/*:refs/remotes/origin/*
[workspace] $ git ls-tree HEAD
Seen branch in repository origin/master
Commencing build of Revision f7dc0e95f48a084d5192c3712f14b3353a98a876 (origin/master )
Checking out Revision f7dc0e95f48a084d5192c3712f14b3353a98a876 (origin/master )
[workspace] $ git checkout -f f7dc0e95f48a084d5192c3712f14b3353a98a876
[workspace] $ git tag -a -f -m “Hudson Build #3″ hudson-gitTest-3
FATAL: Could not apply tag hudson-gitTest-3
hudson.plugins.git.GitException: Could not apply tag hudson-gitTest-3
at hudson.plugins.git.GitAPI.tag(GitAPI.java:265)

[haufenweise stacktrace]

… 12 more
Caused by: hudson.plugins.git.GitException: Command returned status code 128:
*** Please tell me who you are.

Run

git config –global user.email “you@example.com”
git config –global user.name “Your Name”

to set your account’s default identity.
Omit –global to set the identity only in this repository.

fatal: empty ident <tomcat6@yourhost> not allowed

at hudson.plugins.git.GitAPI.launchCommandIn(GitAPI.java:297)
… 14 more

Offensichtlich ist GIT ein wenig schüchtern und mag nicht jeden an die digitale Wäsche ranlassen.

Leider findet man nicht wirklich eine Möglichkeit Hudson eine eigene Identität via Webfrontend zu geben. Der Trick liegt genau dahinter – und zwar im Dateisystem.

Genauer gesagt in der /etc/passwd. Aus irgendwelchen Gründen brauch GIT hier einen Eintrag im Feld für den fullName. Unter Ubuntu hat der Tomcat-User dort standardmäßig nichts gesetzt. Fügt man jetzt dort einfach ‘Tomcat 6,,,’ ein, läuft es auch mit dem CI-Nachbarn.

Alle, die sich über die Gründe Gedanken machen, seien auf die Git FAQs verwiesen.

So dann – viel Spaß beim Bauen.

Hudson und Grails am heimischen Herd

Donnerstag, 13. August 2009

Nachdem sich verschiedene Projekte bei mir angesammelt haben und ich für jedes in der Regel ein entsprechendes Trac-Projekt angelegt habe, fehlte mir immer mehr die projektübergreifende Oberfläche.

Mit den Wochen und Monaten schwängerte sich mein Geist mit dem Gedanken sich an Trac “zu vergreifen” und selbst so eine Oberfläche zu schreiben. Zum Glück kam mir eine neue Anforderung in den Weg, die mir die Arbeit teilweise abnahm: der Wunsch eines Continuous Integration Systems – kurz CI.

Da ich schon gute Erfahrungen mit Hudson gemacht hatte, war die Entscheidung schnell getroffen das System auch für mich einzusetzen. Die Vorteile:

  • einfache Installation
  • Open Source
  • kostenfrei

Allerdings musste gewährleistet werden, dass man damit Grails-Projekte bauen kann. Schaut man in die Plugin-Liste schreit es einen förmlich an: “Hier bin ich. Ist total easy-schneasy. Machs einfach!”

Aber wie so oft bei so offensichtlichen Aktionen liegt die Tücke im Detail. Leider hören – wie so oft – die Tutorials im Netz bei der Hälfte auf und vermitteln einem das Gefühl, dass man zu doof für die IT-Welt ist. Deshalb möchte ich hier einfach meine Erfahrungen bei der Einrichtung von Hudson mit den Grails- und Trac-Plugin auf einem Ubuntu-System vorstellen.

System

  • Ubuntu 09.04
  • Tomcat 6 (aus den Ubuntu-Repository)
  • Trac (manuell installiert)
  • Grails 1.1.1

Anmerkung
Ob Trac jetzt manuell oder aus dem Repository installiert wurde, ist eigentlich egal.

Hudson

Als erstes ging es darum Hudson zu installieren. Zwar bietet Ubuntu auch hier an über eine kleine Erweiterung der Repositories Hudson als Daemon zu installieren, allerdings bin ich persönlich kein großer Freund davon. Deshalb Alternative: war-File downloaden und einfach im Tomcat deployen.

Achtung!!! Wenn man das macht, sollte man vorsichtig beim Neustart aus Hudson heraus sein. Die Applikation fährt interessanterweise den Tomcat runter, bekommt ihn aber danach nicht mehr gestartet.

Zwei Dinge muss man dabei beachten, die aber auch auf der Hudson-Seite dokumentiert sind.

  1. die Variable HUDSON_HOME muss gesetzt sein – habe ich bei mir direkt in das Tomcat-Startskript geschrieben (Faulheit siegt)
  2. Es müssen teilweise noch Verzeichnis-Rechte angepasst werden, damit Hudson korrekt läuft

Nachdem Hudson nun endlich sein Pracht im Browser präsentiert geht es weiter mit dem Grails-Plugin.

Grails

Die Installation von Plugins ist in Hudson sehr simpel – oder wie manch Web 2.0-Entwickler sagen würde: “kissy” (von KISS – Keep it stupid simple). Einfach Häkchen setzen und auf “Installieren” klicken. Wie schon erwähnt, kann es hierbei dazu kommen, dass Hudson den kompletten Tomcat versucht neu zu starten, was zumindest bei mir nicht funktioniert hat. Ggf. einfach den Tomcat manuell neu starten.

Nachdem das Plugin installiert ist, müssen noch einige Konfigurationen durchgeführt werden. Als erstes muss der “Grails Builder” in der globalen Konfiguration von Hudson angelegt werden. Hier kann man verschiedene Grails-Installationen angeben, was insbesondere durch die teilweise Inkompatibilität der Versionen von großem Vorteil ist. Da die Sache in zwei Textboxen geregelt wird, verzichte ich mal auf den obligatorischen Screenshot.
Hat man jetzt die notwendigen Installationen angegeben kann man sich gütlich an die Konfiguration des Jobs machen. Hier muss ich vorausschicken, dass ich bereits einige Jobs angelegt hatte.

Unter dem Punkt “Build Verfahren” kann man über den Button “Build-Schritt hinzufügen” ein “Build with Grails” anlegen. Dabei lassen sich verschieden Werte konfigurieren. Nach einigem Herumprobieren waren aber nur drei relevant:

  1. Grails Installation (wurde eben in der globalen Konfiguration angelegt)
  2. Targets
  3. grails.work.dir

Die Targets kann sich jeder selbst aussuchen aus der Liste, die “grails help” ausgibt. Bei mir sind das "test-app -unit --non-interactive" war doc.
Wichtig ist allerdings vor allem der Parameter grails.work.dir!

Das Grails-Plugin erwartet standardmäßig, dass es Zugriff auf das Verzeichnis /usr/share/tomcat6/.grails besitzt um auf den scriptCache zugreifen zu können. Da dieses Verzeichnis aber nicht zwingend freigegeben werden soll, muss ein alternatives Verzeichnis über grails.work.dir gesetzt werden. Andernfalls müssen die Zugriffsrechte mittels sudo chmod -R 777 /usr/share/tomcat6/.grails gesetzt werden.
Das Projekt-Verzeichnis hat noch eine weitere Bedeutung. Wenn man z.B. in Subversion seinen Code unter “trunk” eincheckt und keinen expliziten Modulpfad angelegt hat, wird automatisch trunk als Projektname auch in Hudson beim Bauen verwendet. Nun kann man sich vorstellen, dass bei mehreren Projekten, die alle in “trunk” liegen dies zu einer Überschneidung führt, die nicht unbedingt erwünscht ist.

Nichtsdestotrotz, bin ich hiermit bereits an das Ende meiner Vorstellung gekommen. Nach der Konfiguration des Jobs einfach auf “Jetzt bauen” klicken und schauen was passiert – ich hoffe mal es funktioniert. Ansonsten: bitte nicht hauen, bei mir läufts ;)

Trac

Für alle, die jetzt fragend dastehen und wissen wollen: “aber er hat doch was von Trac erzählt”. Ja, das habe ich und ja, auch das geht sehr einfach. Nachdem man das Trac-Plugin installiert hat, erscheint ein Eingabefeld in der Job-Konfiguration, in dem man einen Link zum Trac-Projekt hinterlegen. Nachdem man diesen gespeichert hat, erscheint ein simpler Menüpunkt auf der Job-Seite “Trac”, der zu der entsprechenden Trac-Seite führt.

XML to the XStream

Donnerstag, 26. März 2009

Wer stand noch nicht vor dem Problem das “Allheilmittel”-Format XML parsen zu müssen?

Allein das Implementieren des DOM-Parsers war immer schon ein Aufwand, der zumindest mich immer davon abgeschreckt hatte. Wenn das alleine aber schon nicht genug gewesen wäre, wollen die Werte ja auch weiterverarbeitet werden. D.h. es muss noch ein Mapper geschrieben werden. Aufwand über Aufwand…

Doch wie so oft, ist ein “Retter in weißer Rüstung” zur Hilfe geeilt. Nachdem mehrere “Prinzen”, wie JAXB auf den Plan getreten sind, erschien letztens noch einer: XStream. Eine Bibliothek mit der XML-Mapping in beide Richtungen mit wenigen Zeilen möglich ist. Insbesondere das Einlesen ist extrem einfach.

<person>
  <firstname>Joe</firstname>
  <lastname>Walnes</lastname>
  <phone>
    <code>123</code>
    <number>1234-456</number>
  </phone>
  <fax>
    <code>123</code>
    <number>9999-999</number>
  </fax>
</person>
Person newJoe = (Person)xstream.fromXML(xml);

Und schon hat man sein Objekt. Hierbei sollte man jedoch Vorsicht walten lassen. Xstream ruft standardmäßig keinen Konstruktor auf. Das bedeutet, eigene Variablen, die nicht in der XML-Datei stehen werden gegebenenfalls nicht initialisiert. Wer darauf angewiesen ist, muss einen eigenen Converter registrieren.

Das Schreiben mit XStream ist ebenso einfach, wenngleich nicht so elegant. Vor allem bei Klassen, die viele Hilfsfelder haben, müssen diese mittels omitField von der Serialisierung ausgeklammert werden. Ein transient vor dem Attribut hilft da glücklicherweise. Es sei hier angemerkt, dass auf Feldebene gearbeitet wird. Man kann also keine Felder “verstecken”, da auch vor private nicht Halt gemacht wird.
Hier wäre die Möglichkeit schön, alternativ alle Felder auszuschalten und nur explizit Felder freigeben zu können. Alternativ wäre interessant eher über die öffentlichen Zugriffsmethoden zu gehen.
Ebenfalls ist noch keine Vererbungsprüfung möglich. D.h. wenn ich gleiche Felder in verschiedenen Subklassen existieren, muss jede Subklasse einzeln behandelt werden, was es insbesondere bei Plugin-Architekturen schwierig macht, da dort die Subklassen nicht immer bekannt sind.

Zusammenfassend würde ich sagen, dass XStream ein netter Anfang ist, aber noch einiges an Optimierungspotenzial enthält.