HaRe - Home

Kurzbeschreibung

Basis einer professionellen Softwareentwicklung

Es werden die grundlegendsten Voraussetzungen für jede x-beliebige Software-Entwicklung beschrieben. Dazu zählen

Abbildung eines professionellen Entwicklungsumfeldes (bekannt als Continuous Integration).
Abbildung eines professionellen Entwicklungsumfeldes

Im Zuge der Entwicklung einer Software wechselt der Zustand des Produkts immer wieder zwischen "im Umbau befindlich" und "stabil". Während der Umbautphasen werden u.U. Teile verworfen, die später möglicherweise in einem anderen Zusammenhang wieder brauchbar wären und für die Produktion oder auch Präsentationen werden die stabilen Versionen benötigt.
Um effizient entwickeln zu können, sollten alle Artefakte, die zu einem Projekt gehören schnell und einfach erreichbar sein.
Diese Anforderungen werden durch die Verwendung einer Quellcodeverwaltung (und einer Entwicklungsumgebung) abgedeckt.

In diesem Beispiel verwende ich CVS und Eclipse.
Für CVS spricht die weite Verbreitung und die von RCS gewohnte Dateistruktur, die dem Administrator auch lokale Hacks ermöglicht. In einem anderen Umfeld erscheint mir heute Subversion die bessere Wahl.
Für Eclipse spricht der große Bekanntheitsgrad. Je nach Anwendungsfall ist eine andere IDE empfehlenswert und die Integration einer Quellcodeverwaltung ist praktisch in jeder IDE enthalten.

Für Selbststudium wird für CVS das cvsbook empfohlen.

Quellcodeverwaltung

Achtung! Alle Daten werden auf /tmp abgelegt und werden somit üblicherweise beim nächsten Rechnerstart gelöscht. Sollte das nicht gewünscht sein, so sollte zumindest /tmp/cvsroot z.B. auf /var/lib/cvs geändert werden.

Auf /tmp ein Arbeitsverzeichnis mit ein paar Beispieldateien erstellen.
Weiters ein Verzeichnis fü CVS erstellen und initialisieren.

Starting A Repository
~$ mkdir /tmp/cvsroot
~$ cvs -d /tmp/cvsroot/ init
~$ ls /tmp/cvsroot/
CVSROOT
~$ ls /tmp/cvsroot/*
checkoutlist    cvswrappers,v  notify       posttag,v    taginfo
checkoutlist,v  Emptydir       notify,v     postwatch    taginfo,v
commitinfo      history        postadmin    postwatch,v  val-tags
commitinfo,v    loginfo        postadmin,v  preproxy     verifymsg
config          loginfo,v      postproxy    preproxy,v   verifymsg,v
config,v        modules        postproxy,v  rcsinfo
cvswrappers     modules,v      posttag      rcsinfo,v

Starting A New Project
~$ mkdir /tmp/test ; cd $_
/tmp/test$ mkdir dir1 dir2
/tmp/test$ touch test0 dir1/test1 dir2/test2
/tmp/test$ cvs -d /tmp/cvsroot/ import -m '' cvstest hare start
/tmp/test$ ls /tmp/cvsroot/
CVSROOT  cvstest
/tmp/test$ ls /tmp/cvsroot/cvstest/*
/tmp/cvsroot/cvstest/test0,v

/tmp/cvsroot/cvstest/dir1:
test1,v

/tmp/cvsroot/cvstest/dir2:
test2,v
/tmp/test$ ls *
test0

dir1:
test1

dir2:
test2

Checking Out A Working Copy
/tmp/test$ cd ..
/tmp$/ cvs -d /tmp/cvsroot/ checkout cvstest
/tmp$ cd cvstest/
/tmp/cvstest$ ls *
test0

CVS:
Entries  Repository  Root

dir1:
CVS  test1

dir2:
CVS  test2
/tmp/cvstest$ more CVS/*
::::::::::::::
CVS/Entries
::::::::::::::
/test0/1.1.1.1/Wed Apr 16 06:49:50 2008//
D/dir1////
D/dir2////
::::::::::::::
CVS/Repository
::::::::::::::
cvstest
::::::::::::::
CVS/Root
::::::::::::::
/tmp/cvsroot/
/tmp/cvstest$ echo "Neuer Text fuer Version 1.0" >> test0
/tmp/cvstest$ echo "Neuer Text fuer Version 1.0" >> dir1/test1
/tmp/cvstest$ cvs diff
cvs diff: Diffing .
Index: test0
===================================================================
RCS file: /tmp/cvsroot/cvstest/test0,v
retrieving revision 1.1.1.1
diff -r1.1.1.1 test0
0a1
> Neuer Text fuer Version 1.0
cvs diff: Diffing dir1
Index: dir1/test1
===================================================================
RCS file: /tmp/cvsroot/cvstest/dir1/test1,v
retrieving revision 1.1.1.1
diff -r1.1.1.1 test1
0a1
> Neuer Text fuer Version 1.0
cvs diff: Diffing dir2
/tmp/cvstest$ cvs commit -m 'Erste Aenderungen'
/tmp/cvstest$ cvs tag Version-1_0
/tmp/cvstest$ cvs log -h
cvs log: Logging .

RCS file: /tmp/cvsroot/cvstest/test0,v
Working file: test0
head: 1.2
branch:
locks: strict
access list:
symbolic names:
	Version-1_0: 1.2
	start: 1.1.1.1
	hare: 1.1.1
keyword substitution: kv
total revisions: 3
=============================================================================
cvs log: Logging dir1

RCS file: /tmp/cvsroot/cvstest/dir1/test1,v
Working file: dir1/test1
head: 1.2
branch:
locks: strict
access list:
symbolic names:
	Version-1_0: 1.2
	start: 1.1.1.1
	hare: 1.1.1
keyword substitution: kv
total revisions: 3
=============================================================================
cvs log: Logging dir2

RCS file: /tmp/cvsroot/cvstest/dir2/test2,v
Working file: dir2/test2
head: 1.1
branch: 1.1.1
locks: strict
access list:
symbolic names:
	Version-1_0: 1.1.1.1
	start: 1.1.1.1
	hare: 1.1.1
keyword substitution: kv
total revisions: 2
=============================================================================
Mit Absicht schon erste Änderungen für Version 2, obwohl am Server eigentlich Version 1 gewünscht sein wird.
/tmp/cvstest$ echo "Neuer Text fuer Version 2.0" >> dir1/test1
/tmp/cvstest$ echo "Neuer Text fuer Version 2.0" >> dir2/test2
/tmp/cvstest$ cvs commit -m "Erste Aenderungen fuer V2"
Am Server, auf dem die Anwendung letztendlich laufen soll. So wie das Beispiel gemacht wurde ist es gleichgültig, ob am gleichen Rechner oder einem anderen Rechner gearbeitet wird.
Fälschlicherweise wird zuerst die Entwicklungsversion ausgecheckt und dann erst auf die Version 1.0 zurück gewechselt.
/tmp/cvstest$ mkdir /tmp/server ; cd $_
/tmp/server$ cvs -d :extssh:user@rechner:/tmp/cvsroot checkout cvstest
/tmp/server$ cd cvstest/
/tmp/server/cvstest$ cat dir1/test1
Neuer Text fuer Version 1.0
Neuer Text fuer Version 2.0
/tmp/server/cvstest$ cvs update -r Version-1_0
/tmp/server/cvstest$ cat dir1/test1
Neuer Text fuer Version 1.0
Version 2 fertig stellen und den Server auf Version 2 aktualisieren.
Wegen Problemen mit Version 2 danach wieder zurücksetzen auf Version 1.
/tmp/server/cvstest$ cd /tmp/cvstest
/tmp/cvstest$ echo "Neuer Text fuer Version 2.0" >> test4
/tmp/cvstest$ cvs add test4
/tmp/cvstest$ cvs commit -m "Weitere Aenderungen fuer V2"
/tmp/cvstest$ cvs tag Version-2_0
/tmp/cvstest$ cd /tmp/server/cvstest/
/tmp/server/cvstest$ cvs update -r Version-2_0
/tmp/server/cvstest$ ls
CVS  dir1  dir2  test0  test4
/tmp/server/cvstest$ cvs update -r Version-1_0
/tmp/server/cvstest$ ls
CVS  dir1  dir2  test0

Entwicklungsumgebung

Eclipse
Open Perspective - CVS Repository Exploring
CVS Repositories - Rechtsklick - New - Repository Location
Host: localhost, Repository path: /tmp/cvsroot, Connection Type: extssh
bißchen herumblättern
dann HEAD/cvstest auschecken

rsnapshot

Mit rsnapshot kann sichergestellt werden, dass die Änderungen eines Tages regelmäßig, beispielsweise stündlich, automatisch gesichert werden, ohne viel Festplattenplatz oder CPU-Zeit zu verschwenden oder ein zusätzliches Speichermedium zu benötigen.

Debian und Derivate (u.a. Ubuntu)
# apt-get install rsnapshot

Basierend auf der Quellcodeverwaltung sollten Tests (mit Alarmierung bei Problemen) und Softwareverteilung der Testversion automatisiert werden.

Bsp.: bei jedem Einchecken oder zumindest einmal nachts soll in ein Testverzeichnis ein aktueller Snapshot geholt werden und das Ergebnis der Tests per E-Mail verteilt werden. Es ist sinnvoll ein positives Ergebnis nicht zu unterdrücken, da ansonsten eine Fehlfunktion kaum bemerkt wird, allerdings sollte im Subject schon erkennbar sein, ob es Fehler gab oder nicht.
Gerade bei einer Webanwendung kann ebenfalls automatisiert ein Testsystem für den Kunden sehr einfach aktuell gehalten werden. Auch hier sollte das Ergebnis der eventuell notwendigen DB-Migrationsskripte und des Serverstarts per E-Mail verschickt werden.

Typisches Anwendungsszenario

Ein Entwickler checkt seine Arbeit ein. Diese Aktion veranlasst die Aktualisierung einer Testversion und die Unit-Tests starten. Das Ergebnis der Unit-Tests wird dem Entwickler per E-Mail übermittelt.
Check in mit Unit Tests

Jede Nacht wird automatisch ein job gestartet, der die Testversion aktualisiert und die Unit-Tests startet. Das Ergebnis der Unit-Tests wird allen Entwicklern per E-Mail übermittelt.
Automatische Tests in der Nacht

Wenn die Tests fehlerfrei ablaufen, wird auch das Testsystem aktualisiert, das dem Kunden zur Verfügung steht.


Testsystem automatisch aktualisieren