Sonntag, 24. Juli 2011

Versionskontrolle mit Git Teil 3: mit Änderungen umgehen

Nehmen wir an, man benutzt Git im Team. Obwohl man immer auf seinem eigenen Repository arbeitet muss man irgendwann wieder mit den anderen Teammitgliedern synchronisieren. Bei Git arbeitet man dabei besonders mit dem Konzept von Branches.
Die Hauptbranch in Git ist per Naming Convention der "master". Auch wenn ich nur an einem kleinen Feature arbeite lege ich mir sofort eine Branch an, die den Stand vom Master hat mit

git checkout -b myFeatureBranch

Auf dieser Branch arbeite ich weiter, mache Änderungen, commite sie oder lege sie ab. Statt Änderungen komplett zu verwerfen lege ich sie lieber ab, was man mit Git Stash machen kann. Wer weiß, vielleicht möchte ich sie ja doch später wieder hohlen.
git stash
legt die aktuellen Änderungen im Stash ab und setzt den Arbeitsstand zurück auf den letzten Commit. Stash ist mächtig, man kann den gesamten Stash durchsuchen und die verworfenen Stände zurückhohlen. Meist brauche ich aber nur
git stash pop
welches die letzte Änderung vom Stash holt. Ansonsten mache ich Commits mit meinen Änderungen.

Sollte das Feature nicht ganz so klein sein, muss man sich Gedanken machen, wie man die Branch auf dem Stand des Masters hält. Andere Team-Members pushen dort vielleicht Änderungen.  Arbeite ich alleine an meiner Branch gibt es das tolle Feature "Rebase" bei Git. Ziel ist am Ende der Entwicklung mein Feature in den Master zu mergen und zwar möglichst so, dass es bei Problemen leicht ausgebaut werden kann. Dafür ist es schön wenn bei Git log nicht jeder einzelne Commit den ich lokal gemacht habe auftaucht, sondern vielleicht einer: myNewFeature Featurenummer xyz oder so etwas. Rebase verändert die History und lässt mich Commits genau dort einfügen wo ich sie haben will. Ein regelmäßiges Rebase verhindert das Auflösen von Konflikten an Ende der Entwicklung. Um ein Rebase zu machen wechsle ich ich erstmal wieder auf den Master
git checkout master
und hohle mir die neuesten Änderungen
git pull
Nun ist der Master lokal auf dem neuesten Stand und ich kann wieder zur Branch wechseln mit
git checkout myNewFeature
Hier rufe ich nun
git rebase master
auf. Gibt es keine Konflikte habe ich damit erfolgreich ein Rebase ausgeführt. Was man bei Konflikten tun kann beschreibe ich in einem anderen Blog Post ;-)

Sonntag, 19. Juni 2011

Versionskontrolle mit Git Teil 2: Remote Repository auf dem File System

Git Teil 2: Remote

Git lokal zu benutzen ist praktisch um wieder zu eigenen älteren Versionen zurückzukehren. In der gemeinsamen Entwicklung im Team gibt es aber normalerweise irgendwo ein für alle Teammembers erreichbares Repository.
Technisch unterscheidet das gemeinsame und das lokale Repository ersteinmal gar nichts. Jeder Benutzer hat das vollständige Repository lokal und synchronisiert nur mit dem Remote Repository.

git pull

git fetch

hohlen den Stand von einem Remote Repository, während mit

git push

lokale Commits auf ein Remote Repository geschoben werden. Mit

git remote

greift man auf Remote Repositories zu

Damit das funktioniert braucht ihr aber erst ein Remote Repository. Legen wir eins auf einem File System an ( z.B. einem gemeinsamen Laufwerk ). Navigiert zu dem Laufwerk z.B. mit

cd /Volumes/Shared/Projects

, legt einen Ordner für das Projekt an mit

mkdir Demo
cd Demo

und legt ein leeres Repository an mit

git --bare init

Nun könnt ihr in euer eigentliches lokales Testprojekt gehen und mit

git remote add origin file:///Volumes/Shared/Projects/Demo

das Remote Repository hinzufügen. Ein

git push origin master

spielt euren Stand in das Remote Repository. Nun kann jeder Benutzer das Repository clonen mit

git clone file:///Volumes/Shared/Projects/Demo

Sonntag, 22. Mai 2011

Developer Conference Hamburg Day 1 Wrap Up

Die 1. Developer Conference in Hamburg begrüßte ab Freitag ihre Gäste im OTTO Forum. Schon im Vorfeld möchte ich mich herzlich bei den Organisatoren bedanken: eine super Veranstaltung! Und das zu einem extrem faieren Preis.

Los ging es erst einmal mit einem leckeren Frühstück bei dem meine Kollegen besonders die Mettbrötchen lobten. Nach der Begrüßung entschied ich mich dafür, an den beiden Facebook Workshops teilzunehmen. Für einen wirklichen Workshop war die Session leider zu voll. Matthias Lau zeigte die Basics einer Page die sich mit Facebook verbinden soll. Also den Einbau eines Login, Logout und Likebutton, sowie das Handling entsprechender Events mit dem Javascript SDK. Außerdem das Abfragen von Daten verschiedener Freunde mit der Graph API. Für mich war es erst mal nicht viel Neues. Interessanter fand ich die 2. Session in der Matthias Lau Anwendungsbeispiele und Learnings aus seinen Erfahrungen präsentierte. Auf jeden Fall spannend ist die Smatch Community, ein Produkt-Recommender, der Empfehlungen anhand der Facebook - Likes eines Users berechnet.
Meine Lieblings-Empfehlungen:

Mir gefällt Bonita,
weil mir Bonita Project auf FACEBOOK gefällt.

Mir gefällt Laserdrucker,
weil mir Adobe MAX auf FACEBOOK gefällt.

Ansonsten aber eine sehr gute Idee, mal schauen wie sich das weiter entwickelt. Außerdem nehme ich mit, dass reine Facebook Entwicklung (z.B. Canvas App) nicht immer sinnvoll ist. Nicht jeder hat Facebook, es gibt auch entschiedene Gegner, daher sollte man immer mehrgleisig fahren und sich nicht auf Facebook verlassen.

Vollgefuttert nach dem Mittagessen ging es weiter mit CouchDB, wenn die Entscheidung auch schwer fiel. Die CouchDB speichert JSON basierte Dokumente, auf die über REST zugegriffen wird. Jan Lehnardt ist ein sehr schneller Redner, dem man aber gut folgen kann. Für mich sind die interessantesten Learnings aus dem Vortrag die mobilen CouchDB Implementierungen mit denen man automatisch lokale CouchDBs auf dem mobilen Device mit einer DB auf einem Webserver synchronisieren kann, wenn das mobile Gerät gerade eine stabile Netzwerkverbindung hat. Ein super Feature, dass ein typisches Problem vereinfachen kann. Leider ist die mobile Couch immer noch ein fetter Download (ca. 10MB).  Das finde ich zu groß um sie in kleine Apps einzubetten. Sobald sich das ändert, werde ich mal ein bisschen herumprobieren.

Anschließend ging es weiter zu Many-Cores & Functional Programming von Prof. Esser. Language Bashing kombiniert mit in Code gegossener Mathematik vorgetragen von einem großartigen Redner. In dem Vortrag ging es vor Allem um parallele Programmierung und Prof. Esser zeigte mehrere Concurrency/Threading Probleme in Java (als Beispiel für OOP Sprachen). Natürlich um schon mal auf den Scala Workshop am Samstag zu verweisen. Daneben gab es Perlen wie: "Ich habe nichts gegen Ruby. Mein Hund heißt seit 8 Jahren Ruby" oder dem Untertitel des Vortrags "Get functional or get out".  Nach dieser Session war ich nicht mehr aufnahmenfähig, dabei ging es noch 2 Sessions weiter, bevor der Doppeldecker zur Party an die Schanze startete.

So sollte jeder Freitag sein!

Montag, 16. Mai 2011

Flex Sonar Plugin 0.4

Tolle Neuigkeiten vom Flex Sonar Plugin: Version 0.4 ist released. In der Vergangenheit hatte das Flex Sonar Plugin ein Problem mit Projekten mit modular aufgebauten Poms, was mit dieser Version behoben ist. Nehmen wir also an ihr habt eine Parent pom, ein App Modul/Artifakt mit der App, einen Core mit der Logik, welcher als SWC gebaut wird und eine WebApp zum Packagen. Euer Projekt sollte mit Maven und FlexMojos gebaut werden. Mit dem neuen Plugin reicht es aus in der Parent pom

<sonar.language>flex</sonar.language>
    <sonar.dynamicanalysis<false</sonar.dynamicanalysis>

in den Properties einzutragen.

In den settings.xml sollte auf das FlexPMD Repo verwiesen werden. Ein Beispiel Projekt findet ihr auf meinem Github Account. In euren settings.xml muss auf ein Adobe repo mit dem Flex Framework und auf ein Repo mit den FlexMojos verwiesen werden, damit ihr das Projekt mit Maven bauen könnt. Ansonsten könnt ihr auch nur einen Blick auf die poms werfen.

Die Installation von Sonar ist denkbar einfach. Man lädt Sonar herunter und das Plugin. Sonar wird entpackt und das Plugin wird ins plugin Verzeichnis geschoben. Dann findet man im Sonar Ordner unter bin eine ausführbare Datei, die man aufruft. Sonar läuft dann unter http://localhost:9000. Nun stellt man in seinem Jenkins genau diese URL für Sonar ein und klickt bei seinem Projekt den Haken "Sonar" an. Fertig. Baut man das Projekt, bekommt man nun einen Report wie hier von meinem Example Projekt.


Samstag, 14. Mai 2011

Versionskontrolle mit Git Teil 1

Versionskontrolle mit Git Teil 1

Einen lokalen Integrationserver zu haben und seinen Build mit Maven oder Ant wie in den Posts ab Continuous Integration Teil 1 beschrieben zu automatisieren ist eine tolle Sache. Richtig sinnvoll wird beides dann, wenn man in einem Team an einem Projekt arbeitet und sicherstellen möchte, dass dieses Projekt immer funktioniert (oder zumindest kompiliert).
Ein Versionskontrollsystem, bzw. Versionsverwaltung (auch mit SCM - source code manager - abgekürzt) hilft dem Einzelnen Versionen des Source Codes zu verwalten, besonders aber einem Team an gleichen Dateien zu arbeiten und die Änderungen zusammen zu bringen.

Es gibt eine ganze Reihe von verschiedenen System, die man als Entwickler-Team nutzen kann:
  1. Git
  2. Mercurial
  3. SVN
  4. CVS
sind wohl die am Moment populärsten. Ein großer Unterschied zwischen Git und Mercurial zu SVN und CVS ist, dass die Ersteren verteilte Systeme sind. Jeder User hat das gesamte Repository bei sich auf dem Rechner. Bei SVN und CVS gibt es hingegen ein zentrales Repository normalerweise auf einem (Web)Server.
Git hat den großen Vorteil, dass man selbst ohne Webserver, z.B. auf einem gemeinsamen Laufwerk, ein Repository zum Synchronisieren mit dem Team nutzen kann. Damit kann man ohne großen Aufwand in einem kleinen Projekt (z.B. zu zweit) eine vernünftige Versionskontrolle machen und auch ein CI System an Git anbinden.
Starten mit Git
Zuerst muss man Git installieren. Github ist nicht nur ein Gitserver, der umsonst für Open Source Projekte ist, sie haben auch eine sehr gute Hilfe.
Für das Installieren von Git unter Windows kann man sich an dem Github Tutorial orientieren. Die Schritte mit dem SSH Key kann man weglassen, wenn man nicht Github oder einen anderen Server bei dem man sich authentifizieren muss nutzen möchte. Der Installer/Gui für Git unter Windows msysgit ist aber auch sehr einfach ohne Tutorial zu installieren. Einfach herunterladen und starten.
Nach der Installation von Git unter Windows könnt ihr einfach im Explorer zu einem neuen Ordner browsen, mit der rechten Maustaste auf den Projektordner klicken und "Git GUI Here" wählen. Im Menü kann man dann "Create New Repository wählen" und den Pfad zum Projektordner angeben. Nachdem Anlegen des Repositories gebt ihr am besten über "Edit" und "Settings" Namen und Email an damit ihr das nicht bei jedem "push" machen müsst.
Ich benutze bei Git eher eine Shell als ein grafisches Tool. Mit msysgit könnt ihr einfach auf "Git Bash here" klicken und ihr bekommt eine Shell im richtigen Verzeichnis.
Nun legt einfach mal eine Datei namens readme.txt an. Dort kann man sein Projekt beschreiben. Git weiß nun noch nicht, dass es diese Datei verwalten soll. Gebt in eure Shell
git status
Dann sollte ihr eine Rückmeldung bekommen, dass readme.txt noch nicht getrackt wird. Mit
git add readme.txt
stellt ihr die Datei unter Versionskontrolle. Mit
git commit readme.txt -m "add readme"
macht ihr einen Commit, ihr stellt einen bestimmten Stand in euer Repository ein. Nun ändert einfach mal die readme.txt und schreibt "Erste Versuch mit Git" hinein und speichert das Ganze. Wenn ihr nun auf der Shell
git diff
eingebt, seht ihr den Unterschied von dem aktuellen Stand zum letzten Commit. Nun commited die Änderungen. Mit
git log
könnt ihr euch die letzten Commits angucken.

Dienstag, 26. April 2011

Continuous Integration mit Flex/Actionscript 3: CI

Im letzten Teil hatten wir ein kleines Demo Projekt mit Ant gebaut. Damit können wir es nun in einem Continuous Integration System (CI) laufen bauen lassen. Ein CI kompiliert Projekte, führt diverse Metriken aus und gibt eine Rückmeldung über das Ergebnis. Zu den bekannten CIs gehören Hudson bzw. der Nachfolger Jenkins und Teamcity. Diese CIs sind Open Source oder frei verfügbar für eine geringe Anzahl an Nutzern.

Wir benutzen hier Jenkins, gerade in der Java-Welt wohl das bekannteste CI. Um das Ganze auszuprobieren kann man Jenkins erstmal lokal installieren. Das ist erstaunlich einfach:
  1. Das Package für die eigene Plattform von http://jenkins-ci.org/ herunterladen und eventuell entpacken
  2. In der Shell das entpackte Verzeichnis wechseln und dort wo jenkins.war liegt java -jar jenkins.war aufrufen. 
  3. Nach einem kurzen Moment ist Jenkins unter http://localhost:8080/ im Browser ereichbar.
Zum Probieren starte ich den Jenkins lokal immer per Hand, natürlich kann er auch als Service laufen.

Richten wir nun unser Projekt ein:
  1. Im Jenkins auf "New Job" klicken, den Job benennen und "freestyle-software project" auswählen
  2.  Im darauf folgenden Menü "Invoke from Ant" auswählen, bei den anderen Punkte sollten die Einstellungen ok sein
  3. Speichern
  4. Nun auf "Build now" klicken. Der Build wird failen, aber das Verzeichnis wird angelegt in das wir unser Projekt kopieren können
  5. Das Demo Projekt nach jenkins/jobs/DER NAME DES JENKINS JOB/workspace kopieren. Bei mir liegt Jenkins unter /var/lib
  6. Erneut auf "Build now" klicken.
Yeah, Jenkins baut das Demo!

Sonntag, 17. April 2011

Continuous Integration mit Flex/Actionscript Teil 2: Ant

Ersteinmal muss man Ant auf seinem System installieren. Dazu sind folgende Schritte nötig:
  1.  Ant herunterladen von http://ant.apache.org/bindownload.cgi und entpacken (an einen beliebigen Ort)
  2.  Java muss installiert sein. Eventuell also Java installieren.
  3.  Enviroment Variablen setzen. Bei Windows über System, Umgebungsvariablen und bei X-Systemen über das editieren der .bash_profile im home folder. Es muss das JAVA_HOME zur Java Installation zeigen, ANT_HOME dorthin, wo Ant enpackt wurde und  ${ANT_HOME}/bin (Unix) bzw.  %ANT_HOME%/bin (Win) sollten zum PATH hinzugefügt werden.
Zum Beispiel unter Linux:

vi /home/milena/.bash_profile
export $ANT_HOME=/home/milena/apps/ant
export PATH=$ANT_HOME/bin:$PATH
export JAVA_HOME=/usr/lib/jvm/java-6-sun-1.6.0.20/



Wenn ihr nun in der Console ant -version eingebt, solltet ihr eine sinnvolle Meldung mit einer Versionsnummer erhalten. Ant geht also schon mal, nun muss nur noch das Projekt konfiguriert werden.
Adobe hat beim Flex SDK schon entsprechende AntTasks mitgeliefert. Und man kann reine ActionScript Projekte ebenfalls mit dem Flex SDK kompilieren.
Für Ant benutzt man als Konfiguration ein build file (build.xml) indem steht was zu kompilieren ist und was es sonst noch für Tasks für Ant zu machen gibt. Außerdem benutzt man noch ein properties File das System spezifisch ist und eure Pfade enthält. Ihr könnt also in eurem Projekt auf höchster Ebene eine Datei namens build.properties anlegen. Dort sollte mindestens das FLEX_HOME definiert sein, was dann so aussieht:

FLEX_HOME=C:/Program Files/Adobe/Flash Builder Burrito/sdks/4.1

Hilfreich ist auch das src Directory

SRC_DIR =${basedir}/src 

Es können auch noch Pfade zum Folder wo die Libraries liegen angegeben werden usw. Es ist eure Entscheidung, ob ihr die Pfade auslagert oder in der build.xml direkt angebt.

Nun kommt auch schon das Build File. Legt eine Datei namens build.xml auf der gleichen Ebene wie die build.properties an. Die Angaben beziehen sich auf mein Sample bei GitHub.
Gehen wir die Teile der build.xml durch.
Als erstes sagt ihr Ant was es als default Task ausführen soll:

<project name="Flex Ant Tasks Build Script" default="compile flex project">

Dann verweist ihr auf eure properties für die Pfade:

 <property file="build.properties"/>

Nun definiert ihr einen Task zum Aufräumen, altes Verzeichnis löschen und neu erzeugen 

 <taskdef resource="flexTasks.tasks" classpath="${FLEX_HOME}/ant/lib/flexTasks.jar"/>
  <target name="init">
   <delete dir="bin-debug"/>
   <mkdir dir="bin-debug" />
  </target>

Nun das eigentliche Kompilieren:

 <target name="compile flex project" depends="init">
  <mxmlc file="${SRC_DIR}/AntSample.mxml" output="bin-debug/AntSample.swf">
    <load-config filename="${FLEX_HOME}/frameworks/flex-config.xml"/>
    <source-path path-element="${FLEX_HOME}/frameworks"/>
    <compiler.debug>false</compiler.debug>
   </mxmlc>
  </target>


Dann schliesst ihr das Anfangstag:

</project>


 Super! Das war es auch schon für mein Sample Projekt. Das findet ihr bei GitHub und es sollte leicht sein es auf ein eigenes kleines Projekt zu übertragen.