Generowanie paczek NuGeta przy użyciu FAKE
Efektem tworzenia frameworka (oprócz kodu źródłowego) powinny być oczywiście paczki NuGeta zawierające biblioteki dll. Samo ich stworzenie nie jest problemem, wszakże wystarczy kompilacja i nuget.exe
wywołany z wiersza poleceń. Oczywiście można to robić ręcznie, ale ponieważ jestem leniwym programistą, wolę, aby działo się to automatycznie.
Dlaczego FAKE?
Chyba nie ma nic dziwnego w tym, że pracując samodzielnie nie korzystam z żadnego systemu continous integration. Początkowo kompilowałem projekt, a następnie budowałem paczkę po prostu ręcznie wywołując nugeta z konsoli. Działało to ślicznie, póki nie aktualizowałem zależności oraz nie podzieliłem jednej dllki na cztery. (A w planach mam jeszcze kilka.) Wówczas stwierdziłem, że tak dalej nie da się żyć i postanowiłem zaprząc do tego jakiś automat.
Nie znałem za bardzo takich rozwiązań - w pracy zawsze było TeamCity, które w moim przypadku byłoby strzelaniem z armaty do komara. Poza tym konfigurowanie go jest nudne, a ja nie mam ani środków na zatrudnienie studenta w tym celu. Istnieje MSBuild, który jest jakiś dziwny i wymaga jakiejś dziwnej konfiguracji przez XML. Jest psake, które jest napisane w PowerShellu. Trochę już w życiu pisałem w tym języku - nie jest zły, ma więcej dolarów niż PHP, no ale ma sporo wad typu niewrażliwość na wielkość liter, brak kompilacji oraz typowania. Poza tym już go znam i trochę mi się znudził. Z tego powodu wybrałem FAKE. Nie mam pojęcia o F#, więc w moim przypadku to wybór idealny, przynajmniej się czegoś nauczę.
Cel
Czego oczekuję od systemu automatycznego buildowania i publikowania pakietów?
- Kompilacja wszystkich modułów (bibliotek dll) wchodzących w skład Pizzy.
- Automatyczne wygenerowanie plików
*.nuspec
dla każdego modułu (np. na podstawie szablonu). - W ramach każdego modułu wyszukanie zależności od bibliotek systemowych .NET frameworka i umieszczenie ich w odpowiednim miejscu w pliku
*.nuspec
. - W ramach każdego modułu wyszukanie zależności od innych paczek nugetowych i umieszczenie ich w odpowiednim miejscu w pliku
*.nuspec
. - W ramach każdego modułu wyszukanie zależnośći od innych modułów Pizzy i dodanie ich do listy zależności nugetowych.
- Umieszczenie w paczce treści release notes.
- Wersjonowanie paczki na podstawie numeru z release notes.
- Możliwość wrzucenia paczek na
nuget.org
.
Wykonanie
Co tu dużo mówić - wziąłem jakiś przykładowy skrypt FAKE i zacząłem go dostosowywać do swoich potrzeb. FAKE niemalże wszystkie powyższe wymagania spełnia standardowo. Na przykład, jeśli mamy release notes w formacie zgodnym z:
## New in 0.2.1 (Released 2016/03/13)
* Fixed sorting by nullable enums in grid.
* Audit works also with not authenticated users.
* JS and CSS files moved to framework.
to taki kod: let releaseNotes = LoadReleaseNotes releaseNotesPath
pozwala nam na dobranie się do zapisanej wersji po prostu za pomocą odwołania do wartości: releaseNotes.NugetVersion
.
Podobnie, funkcja getDependencies
przyjmująca ścieżkę do pliku packages.config
wyciąga z niego listę zależności.
Właściwie jedyne rzeczy, które musiałem sam napisać, to znalezienie referencji do bibliotek .NET frameworka. W pliku *.csproj
mają one postać takich węzłów: <Reference Include="System.ComponentModel.DataAnnotations" />
. Zaimplementowałem to w postaci takiej funkcji:
Kod jest chyba tak prosty, że nie wymaga tłumaczenia.
Z kolei odwołania do pozostałych modułów Pizzy wyglądają w pliku projektu następująco:
A funkcja je parsująca tak:
Reszta mojego zadania to poskładanie tego do kupy. Cały kod można zobaczyć tutaj