Category Archives: git

DSL Projekt aufsetzen (mit Xtext)


Flattr this

Motivation

Da es ein wenig Mühe bereitet hat und ich nach einem Jahr nicht noch einmal den Aufwand investieren möchte schreibe ich hier eine kleine Anleitung wie man ein DSL Projekt unter folgenden Randbedingungen aufsetzt:

  • Als Entwicklungsumgebung wird eclipse eingesetzt
  • Zur Sicherstellung einer einheitlichen eclipse Installation wird yatta-profiles genutzt
  • Zur Modellierung der DSL wird Xtext verwendet
  • Die Sourcen werden auf github.com gehostet
  • Als CI System kommt travis-ci.org zum Einsatz
  • Zur Verteilung der Releasestände wird bintray.com genutzt

Die Eclipse aufsetzen

Lange habe ich nach einer Möglichkeit gesucht um diesen Schritt zu automatisieren. Angefangen über das Niederschreiben der Installation hier im Blog (Eclipse konfigurierenEclipse aufsetzen) über CloudConnect bin ich letztlich auf Yatta-Profiles gekommen. Yatta Profiles hat sich für meine Arbeitsweise als am besten geeignet erwiesen um die zu installierenden Plugins und die aus zu checkenden Projekte einheitlich für ein Team zu verteilen (Allerdings nutze ich das Angebot nicht als Team sondern als einzelner Entwickler. Halte mir aber die Möglichkeit offen mit mehreren Leuten zu gleich an einem Projekt zu entwickeln.)

Bleibt das Speichern der eigentlichen Konfiguration der installierten Plugins. Diese Arbeit kann ich an das Oomph Plugin delegieren. Zum Glück hat das Projekt jetzt eine Reife erlangt die zur produktiven Arbeit genügen sollte. 

Wer meine Eclipse Installation ausprobieren möchte, kann sich einfach das Yatta-Profile installieren: ECLIPSE XTEXT DSL TOOLS

Die Sourcen erstellen

Generell beginne ich mit dem Anlegen eines leeren Repositories (Projekt) auf Github. Dabei wähle ich zunächst den Namen aus, dann gebe ich java als Programmiersprache an und wähle eine mir genehme Lizenz aus. Weiterhin selektiere und aktiviere ich die Checkbox „Readme erstellen“. Nach dem Fertigstellen bietet github.com ein neues Projekt zum clonen an und genau das mache ich dann auch – ich klone das Projekt mittels git clone <url> in ein lokales Verzeichnis auf meinem PC. 

Nun starte ich eclipse und erzeuge über den Dialog „Neu/Projekt/Xtext“ ein neues xtext Projekt.

Hierbei sind bereits ein paar wichtige Dinge zu beachten. Da ich später auf bintray deployen möchte benötige ich eine einheitliche GroupId über alle Projekte hinweg. Gern hätte ich hier com.github.funthomas424242.dsl verwendet, doch das funktioniert nicht mehr falls ich mal ein Maven Plugin entwickeln sollte dann hätte ich nämlich gern die gropuId com.github.funthomas424242.maven.plugins verwendet. Damit bräuchte ich aber zwei groupId’s und das würde zwar gehen aber ist von bintray nicht gewünscht. Da man nie weiß wann solche Wünsche mal in Vorgaben umgewandelt werden (besonders wenn man die kostenlosen Services nutzt) habe ich mich also für die groupId com.github.funthomas424242 entschieden. Als Folge daraus muss ich meine Projekte mit dieser groupId versehen. Damit das funktioniert und ich trotzdem noch verschieden DSL Projekte verwalten kann gehe ich wie folgt weiter vor. 

Die nachfolgenden Einstellungen im Wizard werden am Beispiel meines Projektes ahnen.dsl auf github erklärt. Und so fülle ich die erste Dialogseite des Wizards aus:

Xtext Projekt Basisdaten

 

Ja, der Projektname ist richtig. Zwar wird dieser als groupId verwendet doch lässt sich das später manuell gut abändern.

Xtext Projekt Settings

 

Als Source Layout wurde Plain gewählt da eine andere Kombination mit der Einstellung Eclipse Plugin aktuell noch nicht unterstützt wird.

Nun werden diverse Projekte vom Wizard in der eclipse erzeugt.  Von jedem Projekt öffnen wir nun die pom.xml und korrigieren die groupId manuell auf z.B. com.github.funthomas424242 Anschließend selektieren wir alle Projekte und führen ein Maven update Projekt über das Kontext Menü in der eclipse durch. Nun sollten alle Projekte wieder fehlerlos erscheinen. Falls nicht einfach die Xtext Datei öffnen und noch mal alle Sourcen generieren lassen. 

Bevor wir einen commit durchführen sollten wir noch im parent Projekt eine .gitignore anlegen. Meine sieht wie folgt aus:

.settings/
target/
src-gen/
xtend-gen/
.project
.classpath
*_gen

Man beachte, dass ich hier die führenden / (Slashes) weggelassen habe damit die Regeln auch für die Unterprojekte gelten. Nun testen wir zunächst unser Projekt indem wir eine Eclipse Instanz mit Runtime Workspace starten:

Runtime Start

 

In der gestarteten Runtime Eclipse legen wir ein einfaches Projekt „Test“ an und darin eine Datei test.ahnen. Beim Öffnen dieser Datei können wir sehen ob unser Plugin prinzipiell schon funktioniert, denn es muß der entsprechende Editor zum Öffnen angeboten werden. In meinem Fall nennt sich dieser Ahnen Editor und ist vorhanden. Verwenden wir diesen Editor zum Öffnen werden wir gefragt ob das Projekt in ein Xtext Projekt konvertiert werden soll – ja natürlich. Wir müssen nichts dazu tun eclipse trägt nun ein paar Metadaten in die Projektbeschreibungsdatei .project ein und das scheint es gewesen zu sein. Den Editor prüfen wir indem wir seine Vorschlagsfunktion unter Ctrl+Space nutzen und den ganzen Beispieltext damit eingeben.

Das war es erstmal. Jetzt können wir die Runtime Instanz der eclipse schließen und unseren Projektstand commiten (aber noch nicht pushen). Wir müssen zwar noch alle Projekte ein Verzeichnis nach oben verschieben aber das sollte git als Verschiebung erkennen und somit sollte dies kein Problem ergeben. Also commited ist.

Jetzt löschen wir alle Projekte aus unserer eclipse aber nicht auf der lokalen Festplatte!!!

Nun unbedingt die eclipse schließen da sie meist die Projekte trotzdem noch lockt und dadurch nachfolgende Schritte fehlschlagen würden. 

In einer Shell navigieren wir jetzt zum Parent Projekt (in diesem ist die pom.xml des parents zu finden) von dort aus verschieben wir alle Verzeichnisse und Dateien ins übergeordnete Verzeichnis. Anschliessend navigieren wir selber in das übergeordnete Verzeichnis und löschen das nun leere alte parent Projekt.

Jetzt ist unser normales root Verzeichnis aus dem github repository das parent Projekt und wir können es ganz normal in  unsere Eclipse neu importieren. 

Diesen Stand commiten wir ebenfalls wobei wir ihn dem letzten Commit hinzufügen (amend commit). Jetzt noch ein kurzer Test mit der Runtime eclipse. Wenn alles noch so funktioniert wie vorher, dann können wir jetzt pushen.

Maven Build anpassen

Durch die manuelle Umbenennung der groupId haben wir unser Definitionsfile der target platform invalidisiert. Das sollten wir unverzüglich beheben. Das Problem wird deutlich wenn wir im Root Verzeichnis unseres Projektes ein mvn clean install ausführen.

Das Problem lässt sich leicht korrigieren durch eine Anpassung in der parent/pom.xml. Dort muss die groupId der TargetPlatform angepasst werden. Ich bevorzuge eine generische Lösung. Anbei der relevante Abschnitt aus der parent/pom.xml:

<plugin>
 <groupId>org.eclipse.tycho</groupId>
 <artifactId>target-platform-configuration</artifactId>
 <version>${tycho-version}</version>
 <configuration>
  <target>
   <artifact>
    <groupId>${project.groupId}</groupId>
    <artifactId>com.github.funthomas424242.dsl.ahnen.target</artifactId>
    <version>${project.version}</version>
   </artifact>
  </target>

So jetzt funktioniert der Maven Build wieder. Zeit für einen neuen commit. Aber mit dem Push ruhig noch warten, den wollen wir gleich durch das CI System schicken.

Das CI System aktivieren

Dazu gehen wir auf travis-ci.org und loggen uns mit unserem github.com Account per OAuth ein. In der rechten oberen Ecke wird der Nutzername angezeigt beim überstreichen mit der Maus ploppt ein Menü auf. Daraus wählen wir den Punkt Accounts aus. Da das Repository neu ist, wird es travis-ci noch nicht kennen und wir nutzen den Sync Button oben rechts um unsere github Projekte zu importieren. In der erscheinenden Liste an Projekten suchen wir unser Projekt und aktivieren den Schalter davor. Ab jetzt sucht travis-ci bei jedem push in das Projekt eine Datei .travis.yml und falls gefunden wird anschließend ein Build ausgeführt.

Natürlich müssen wir diese Datei noch ins Projekt einchecken. Sie gehört ins parent Projekt und muss wirklich mit einem Punkt beginnen (also ein Problem für alle Windows Freunde – aber ein lösbares 🙂 )

language:
 - java

jdk:
 - oraclejdk8

Nun noch ein commit und ein push und die Maschinerie springt an 🙂 Nach ungefähr 10 Minuten sollte das Projekt in travis erscheinen und der Build lässt sich prüfen. Es empfiehlt sich ein entsprechendes Build Icon von travis in die Projekt Readme zu integrieren. So kann man auf einem Blick erkennen wenn der Status auf rot geht. 

Bintray Deployment anbinden

Zu den Formalitäten wie Registrierung und ähnliches bei bintray.com möchte ich hier nicht eingehen. Nur eins dazu das Passwort für die oss.jfrog.org Seite ist Euer API Key von bintray.com. Möglicherweise müsst ihr Euch erst freischalten lassen etc. Aber das sollte sich jeder selbst durchlesen, da es teilweise auch Sicherheitsrelevant ist.

Weiterhin ist bei maven die settings.xml anzupassen. Hier sind die Zugangsdaten für den Server zu hinterlegen. Vorsicht – die Datei darf kein Anderer in die Hände bekommen. Idealerweise nutzt ihr die Verschlüsselungsmechanismen. 

Im Projekt ist auch noch eine Anpassung durchzuführen. Die Deplyoment Repositories sind im parent/pom.xml bekannt zu geben. Dazu fügen wir folgenden Eintrag in die parent/pom.xml ein.

<distributionManagement>
 <snapshotRepository>
  <id>snapshots</id>
  <name>oss-jfrog-artifactory-snapshots</name>
  <url>https://oss.jfrog.org/artifactory/oss-snapshot-local</url>
 </snapshotRepository>
 <repository>
  <id>bintray-funthomas424242-dsl</id>
  <name>oss-jfrog-artifactory-releases</name>
  <url>https://oss.jfrog.org/artifactory/oss-release-local</url>
 </repository>
</distributionManagement>

Mit einem mvn deploy lassen sich ab jetzt Snapshots und Releases nach oss.jfrog.org deployen. Von dort aus können diese im angemeldeten Zustand über das Kontextmenü nach bintray.com in ein beliebiges Package kopiert werden. Jedes Package muss auf bintray in einem Repository liegen. Ein Package welches im jCenter veröffentlicht werden soll muss einigen Anforderungen genügen (mindestens ein jar, ein src.zip, ein pom.xml und optional noch ein javadoc archive). Die Freischaltung für das jCenter dauert ein wenig Zeit – am besten rechnet man mit 24h – und erfolgt nur auf Antrag. Eine weitere Freischaltung für das maven central erfordert dann noch ein Sonatype Login. Parallel zur Beantragung der ganzen Accounts kann dann schon mal Fachlichkeit umgesetzt werden 🙂

Noch ein paar Tipps

  1. Tycho kann bereits in der Version 0.25.0 benutzt werden. Das muss man manuell in der parent/pom.xml in den Properties eintragen. 
  2. Um das Deployment zu verringern nutze ich in der parent/pom.xml:
    <maven.deploy.skip>true</maven.deploy.skip>
    und in der pom.xml des repository Subprojektes:
    <maven.deploy.skip>false</maven.deploy.skip>
    So wird nur das Zip mit der eclipse update site hochgeladen.

Soweit zum Aufsetzen eines DSL Projektes und viel  Spass beim Ausprobieren. Jetzt muss nur noch die Fachlichkeit umgesetzt werden 😉

 

Advertisements

eGIT – eclipse plugin


Flattr this

Motivation

Statt ständig den Artikel über die Konfiguration der Eclipse Arbeitsumgebung anzupassen habe ich mich entschlossen lieber die von mir verwendeten oder evaluierten Plugins kurz zu beschreiben.

Heute habe ich ein Eclipse Plugin gesucht um ein Gitrepository auf Github einzubinden.

Zum Plugin

Das Plugin eGit Team Provider steht im Eclipse Marketplace zur Installation bereit. Es eignet sich hervorragend um ein Git Repository zu klonen und zu bearbeiten. Die Installation läuft wie bei Eclipse üblich – nach einem Neustart der IDE steht die neue Team Perspektive zu Verfügung. Man kann damit im Prinzip genauso wie vorher mit der CVS oder der SVN Perspektive arbeiten.

Wünschenswert

Das Plugin verfügt leider über keine Revert Funktion. Das ist für Umsteiger von SVN durchaus gewöhnungsbedürftig. Daher habe ich mir auf meinem lokalen PC noch TortoiseGit und das Git mit GitGUI und GitBash installiert. In der Kombination lässt es sich prima arbeiten. Was in Eclipse nicht geht wird mit TortoiseGit erledigt und eine Shell habe ich parallel auch offen um ab und an ein git status abzusetzen.

Github – Pull Requests aktuell halten


Flattr this

Motivation

Auf Github kann jeder Nutzer auf einfachster Weise einen Fork von seinem Lieblingsprogramm erstellen und nach Lust und Laune auf diesem die gewünschten Features selbst implementieren. Sind diese fertiggestellt werden sie als Pull Request an den eigentlichen Projektowner gesendet.

In der Regel war dieser aber auch nicht untätig und hat sein Projekt auch weiterentwickelt. Oder er ist gerade mitten in der Entwicklung eines neuen Features und so bleibt der Pull Request eine ganze Weile liegen. In der Zeit häufen sich die Commits des Projektowners und der Stand auf dem der Pull Request basiert ist hoffnunglos veraltet.

Jetzt erst sieht der Projektowner den Pull Request und versucht in zu integrieren – doch leider hat sich das Projekt soweit weiter entwickelt, dass viele Versionskonflikte auftreten. Das möchte sich der Owner nicht antuen und fordert vom Ersteller des Pull Requests das er diesen bitte zunächst mit dem aktuellen Versionsstand abgleicht. Doch wie geht das? Genau das soll hier kurz beschrieben werden.

Vorraussetzungen

Bevor man einen Pull Request auf Github stellen kann, hat man in der Regel das Original Repository auf Github geforkt und davon einen Klone auf seinen lokalen Rechner gezogen.

Will man nun ein neues Feature implementieren sollte unbedingt ein neuer Branch für die Entwicklung des Features abgespalten werden. Dies hat den Vorteil, das man zeitgleich an verschiedenen neuen Features arbeiten kann ohne von der Fertigstellung oder der erfolgreichen Integration eines Features abhängig zu sein. Außerdem hält man sich so auch den master für eine stets lauffähige aktuelle Version frei. Letzteres ist gut, da es immer wieder mal Situationen gibt in denen man die gerade implementierte Lösung nach Fehlern durchsucht und dann ein Vergleich mit einer aktuellen, lauffähigen Version sehr hilfreich sein kann. Generell gilt aber auch auf Github pro Branch ist nur ein Pull Request möglich.

Aktualisierung des Branches

Die Lösung besteht im Prinzip darin bei der Entwicklung möglichst frühzeitig die neuen Änderungen des Owners in den eigenen featurebranch zu integrieren. Hierzu erzeugen wir uns einen Alias upstream im lokalen Git Repository.

(alles in eine Zeile schreiben, der Browser zeigt hier gern 2 Zeilen an)

git remote add –track master upstream git://github.com/owner/projectname.git

evtl. reicht auch die einfachere Variante

git remote add upstream git://github.com/owner/projectname.git

Als Werte für owner und projectname werden die Angaben des originalen Repositories verwendet von dem wir selbst unseren fork gezogen haben. Damit steht uns ein Alias für den Fetch bereit und diesen nutzen wir auch gleich. Wir befinden uns also aktuell im lokalen Projektverzeichnis und arbeiten auf dem Branch (also der Branch ist lokal ausgecheckt und in der Regel von uns auch schon editiert). Jetzt holen wir uns die Neuigkeiten vom Original Repository:

git fetch upstream

Wenn das funktioniert hat und das sollte immer funktionieren oder ihr habt Euch vorhin verschrieben oder das Internet ausgeschaltet, dann mergen wir die Neuigkeiten in unseren lokalen branch mit:

git merge upstream/master

oder die Variante ohne Auto Commit

git merge upstream/master –no-commit –no-ff

So jetzt noch ein bischen Konflikte lösen 😉 committen und falls nötig den Pull Request aktualisieren bzw. bitte auch dokumentieren. Kommunikation ist alles und hilft dem Projektowner bei der Bewertung und Einarbeitung Eures Pull Requests.

Also Happy Pulling 🙂

Und falls doch mal was schief geht und der ganze Branch zurück auf „Null“ – dem Stand des originalen Repositories – gebracht werden soll? Dann sollten diese Befehle helfen

git remote add upstream git://github.com/wp-cli/wp-cli.git (nur wenn wir den alias oben nicht schon angelegt haben)
git fetch upstream
git branch backup
git reset –hard upstream/master
git push –force

Damit habt ihr den aktuellen Branch zurück gesetzt.

Bei neueren Git Versionen scheint das Rücksetzen auf den upstream (er muss schon mit git remote add gesetzt wurden sein) wie folgt zu funktionieren:

git rebase –onto upstream/master

Diese Variante würde ich immer vorziehen, weil damit auch bereits veröffentlichte Dinge bearbeitet werden können.

 

Für Hinweise, Tipps, Anmerkungen und Kommentare bin ich stets dankbar.

 

Quellen:

http://gun.io/blog/how-to-github-fork-branch-and-pull-request/

http://scribu.net/blog/resetting-your-github-fork.html

http://www.senaeh.de/git-prinzip-beispiele/