NuPack – eigene Packages erstellen
Eigene Packages für NuPack zu erstellen ist eigentlich recht simpel. Man benötigt lediglich Mercurial um die Sourcen von http://nupackpackages.codeplex.com/ herunter zu laden. Möchte man seine Packages nicht der Allgemeinheit zur Verfügung stellen, sondern Packages für den internen Gebrauch erstellen ist das ebenfalls möglich. Die Packages müssen nicht über das öffentliche RSS Feed publiziert werden, sondern können von einem Lokalen oder einem Netzwerkpfad geladen werden.
In den Options (“Tools => Options…”) gibt es einen Konfigurationspunkt für die Bezugsquellen der Packages. Neben dem bereits vorhandenen Feed können hier weitere Feeds oder Verzeichnisse eingetragen werden welche die Packages enthalten.
Am Beispiel der LightCore Packages, die ich den NuPack Packages zur Verfügung gestellt habe, möchte ich hier kurz demonstrieren wie man eigene Packages erstellt und auf Codeplex zur Verfügung stellt.
Eine Dokumentation gibt es selber schon auf Codeplex unter http://nupackpackages.codeplex.com/. Desweiteren sollte man sich bereits vorhandene Packages anschauen, um zu sehen wie es dort umgesetzt worden ist.
Mercurial
Die NuPack Packages werden mit dem Source Code Managemant System Mercurial über Codeplex bereitgestellt. Dafür sollte am besten der Client TortoiseHG installiert werden der hier zur Verfügung gestellt wird: http://mercurial.selenic.com/downloads/
Grundkenntnisse zu Mercurial setze ich hier voraus. Wer Mercurial nicht kennt sollte sich also entweder die Doku anschauen oder schon mal zuvor mit TortoiseHG herumgespielt haben.
Um die Struktur der Packages kennen zu lernen ist es sinnvoll sich zuvor die Sourcen zu laden. Hierfür sollte das Repository von Codeplex “geklont” werden. Die URL lautet wie folgt: https://hg01.codeplex.com/nupackpackages
Die Strukturn
Es sollte folgende Ordnerstruktur aufgebaut werden:
(hier verwende ich zu Demozwecken die Struktur von LightCore )
LightCore
|-- 1.4.1
|—Content
|—Lib
|-- Tools
Der erste Ordner hat den Namen des Packages, der zweite ist die Version und in der dritten Ebene enthält folgende Ordner:
- Content: Enthält Files die in das Projektverzeichnis kopiert werden, wie Beispiele, Configs, etc.
- Lib: enthält die eigentlichen Assemblies die als Referenz eingefügt werden sollen
- Tools: enthält Tools für die Libraries (das können Test-Runner, LogParser, etc. sein) dafür wird ein Ordner “Tools” im Projektverzeichnis angelegt
Um Assemblies für verschiedene Frameworks und Plattformen bereitzustellen, kann der Ordner “Lib” weiter unterteilt werden. Es müssen Unterordner erstellt werden mit denen die Plattformen und Frameworks unterschieden werden können. Eine Detaillierte Beschreibung der Ordnernamen ist hier zu finden: Creating a Package
Lizenzdateien und ähnliches können in den Ordner mit der Versionsnummer abgelegt werden. Dort muss zudem noch eine XML Datei mit dem Namen “LightCore.nuspec” liegen (wobei hier wieder der Package-Name genutzt wird) Diese Datei enthält Metadaten zu dem Package, wie Autor, Beschreibung, etc. Im Falle von LightCore sieht das XML wie folgt aus:
<?xml version="1.0" encoding="utf-8"?>
<package>
<metadata>
<id>LightCore</id>
<version>1.4.1</version>
<description>LightCore is a lightweight dependency injection container which can be used as a service locator, too. Despite its simplicity and its lightness there are lots of features to explore.</description>
<authors>
<author>Peter Bucher</author>
</authors>
<language>en-US</language>
</metadata>
</package>
Die Assembly “LightCore.Integration.Web.dll” habe ich in einem separaten Package untergebracht, welches das LightCore Package benötigt. Hierfür wird eine Abhängigkeit zum LightCore Package in der *.nuspec-Datei eingelegt:
<?xml version="1.0" encoding="utf-8"?>
<package>
<metadata>
<id>LightCore.WebIntegration</id>
<version>1.4.1</version>
<description>LightCore is a lightweight dependency injection container which can be used as a service locator, too. Despite its simplicity and its lightness there are lots of features to explore. This package integrates implementations to use in ASP.NET WebForms and ASP.NET MVC</description>
<authors>
<author>Peter Bucher</author>
</authors>
<language>en-US</language>
</metadata>
<dependencies>
<dependency id="LightCore" version="1.4.1" />
</dependencies>
</package>
Wichtig ist zu beachten, dass die anderen LightCore Assemblies nicht im zweiten Package enthalten sein dürfen, damit es nicht zu doppelten Referenzierungen kommt. Damit die benötigten Assemblies dennoch referenziert werden, wird die Abhängigkeit zu einem anderen Package definiert.
Das Package testen
Ist das Package also nun angelegt, sind alle Files enthalten und ist die entsprechende *.nuspec-Datei erstellt, kann das Package getestet werden. Hierfür muss das Package nur in das mit Mercurial geklonte Repository gelegt werden. Im Root des Repositories befindet sich eine Datei namens “RebuildPackages.cmd” die nun aufgerufen werden muss. Diese Command-Datei erstellt nun ein Verzeichnis mit dem Namen “NuPackPackages” und legt dort alle Packages aufbereitet und verzippt ab. Die Packages haben die Endung “*.nupkg”
Nun kann wie oben beschrieben der Pfad zu diesem Verzeichnis als Source im Package Manager (unter “Tools => Options… => Package Manager”) angegeben werden. Die Packages können jetzt wie unter NuPack - externen Libraries einfach einbinden beschrieben genutzt werden.
Das Package publizieren
Um das eigene Package zu publizieren und der Öffentlichkeit zugänglich zu machen, muss es in das Repository aufgenommen werden. Das passiert mit einem festgelegtem Workflow:
- Es muss unter http://nupackpackages.codeplex.com/ ein eigener Fork erstellt werden. Dafür wird ein Account auf Codeplex benötigt.
- Ist dieser Fork erstellt, muss dieser mit Mercurial auf den lokalen Rechner geklont werden. Nun kann man dort das Package (entsprechend den bereits vorhandenen) einfügen, mit TortoiseHG in den Clone einfügen und in den erstellte Fork auf Codeplex publizieren.
- Auf Codeplex muss nun ein sogenannter “Pull Request” gestartet werden (Den Link dazu findet man auf Codeplex rechts vom eigenen Fork). Hier sollte eine Aussagekräftige Beschreibung (auf English) und falls vorhanden der Twittername eingefügt werden.
- Die Koordinatoren des Projektes prüfen nun den Pull Request und entscheiden ob das neue Package in das Projekt eingebunden wird oder nicht. Das kann mehrere Stunden in Anspruch dauern.
- Wird das Package im ersten Anlauf nicht akzeptiert, erhält man eine E-Mail mit einer aussagekräftigen Begründung. So ging es mir beim Einfügen von LightCore. Ich hatte doppelte Assemblies und Abhängigkeiten vergessen.
- Nach der Behebung des Fehlers kann der Pull Request einfach noch einmal gestartet werden, sobald die Änderungen in Fork sind.
- Läuft alles glatt, so wird das Package akzeptiert und wird nun im offiziellen Feed veröffentlicht und kann wie unter NuPack - externen Libraries einfach einbinden beschrieben genutzt werden.
Fazit
Man sieht, dass es im Grunde recht einfach ist ein eigenes Package zu erstellen und zu veröffentlichen. Um LightCore noch ein bisschen mehr zu puschen, habe ich mich entschlossen, zwei Packages für LightCore zu erstellen und zu veröffentlichen.
Ich bin allerdings nicht sicher, in wie weit die Projektverantwortlichen darauf achten werden, dass nicht jede blöde Assembly als Package angeboten wird, sondern nur Tools die wirklich relevant sind. Von daher war ich eigentlich überrascht das LightCore so einfach und schnell akzeptiert worden ist. Entweder werden gerade zu Anfang noch relativ viele Assemblies einfach so akzeptiert oder LightCore ist tatsächlich schon in den USA zu einer gewissen Bekanntheit gelangt. Vielleicht hat aber auch nur die Überprüfung der Assembly und der Projektseite http://lightcore.ch/ ergeben, dass es sich hier um eine relevante und nützliche Assembiel handelt.
Wie auch immer, hoffe ich, dass nicht jede beliebige Assembly als Package angeboten wird und das Angebot zumüllen wird.
Was bei NuPack noch fehlt, gerade das es im Moment immer mehr wächst, sind Kategorien die das Browsen und suchen nach Tools vereinfachen. Natürlich nutzt man in erster Linie nur bekannte Assemblies und sucht speziell nach denen. Allerdings ist NuPack auch Ideal um neue und unbekannte Tools kennen zu lernen. Ich würde mir also wünschen, wenn ich speziell nach Test-Frameworks, DI-Containern oder OR-Mappern schauen könnte.