Tak jak pisałem w jednym z poprzednich postów, zdecydowałem się użyć Paket do zarządzania zależnościami w projekcie. Dlaczego? Ponieważ poza zależnościami NuGetowymi, mam jedną dużą, niestandardową - standalone binarki bazy neo4j. Tak jak pisałem, Paket poza źródłami z serwerów NuGetowych potrafi korzystać ze źródeł Gita oraz po prostu zasobów dostępnych przez HTTP. Ostatnio trochę oszukałem, mówiąc, że neo4j jest dostępny w samowystarczalnym pliku ZIP pod adresem http://neo4j.com/download-thanks/?edition=community&flavour=winzip. Stronka ta jedynie rozpozczyna auto-download pliku pod adresem http://neo4j.com/artifact.php?name=neo4j-community-3.0.1-windows.zip i to ten plik będę musiał wskazać jako zależność HTTP.
Ten wpis opisuje natomiast sposób konwersji klasycznej solucji opartej o Nugety (i plik packages.config) do wersji używającej Paketa.
1. Instalacja Paketa
Podążając za instrukcją na stronach Paketa, aby go zainstalować należy:
- stworzyć w głównym katalogu projektu folder .paket
$ mkdir .paket
$ cd .paket
$ wget "https://github.com/fsprojects/Paket/releases/download/2.64.3/paket.bootstrapper.exe"
- uruchomić rzeczonego execa, co ściągnie Paketa
2. Konwersja
Sama konwersja jest banalnie prosta, przynajmniej w przypadku mojego projektu nie sprawiła problemów:
$ .paket/paket.exe convert-from-nuget
W efekcie w głównym katalogu powstał nowy plik opisujący zależności:
$ more paket.dependencies
source https://www.myget.org/F/roslyn-nightly/
source https://www.myget.org/F/dotnet-core
source https://www.nuget.org/api/v2/
framework >= net45
nuget FsXaml.Wpf 0.9.9
nuget Microsoft.Diagnostics.Runtime 0.8.31-beta
A w każdym folderze projektu (w moim przypadku, na razie, jedynego) powstał plik z referencjami w tym konkretnym projekcie:
$ more src\MemoryVisualizer.UI\paket.references
FsXaml.Wpf
Microsoft.Diagnostics.Runtime
Ostatecznie cała ta rewolucja powoduje następujące zmiany w repozytorium:
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes not staged for commit:
(use "git add/rm <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: src/MemoryVisualizer.UI/MemoryVisualizer.UI.fsproj
deleted: src/MemoryVisualizer.UI/packages.config
modified: src/MemoryVisualizer.sln
Untracked files:
(use "git add <file>..." to include in what will be committed)
.paket/
paket.dependencies
paket.lock
src/MemoryVisualizer.UI/paket.references
no changes added to commit (use "git add" and/or "git commit -a")
3. Używanie
I co teraz? Po wykonaniu konwersji możemy zacząć używać Paket w standardowy sposób:
$ .paket\paket.exe install.\paket
Krok ten tworzy jeszcze jeden plik (zresztą pojawia się on w naszym przypadku już po konwersji), zawierający ostateczny wynik wszystkich zależności w projekcie:
$ more paket.lock
FRAMEWORK: >= NET45
NUGET
remote: https://www.nuget.org/api/v2
specs:
Expression.Blend.Sdk (1.0.2)
FsXaml.Wpf (0.9.9)
Expression.Blend.Sdk (>= 1.0.2)
Microsoft.Diagnostics.Runtime (0.8.31-beta)
Teraz zaś możemy za pomocą jednej komendy ściągnąc wszystkie zależności:
$ .paket\paket.exe update
Paket version 2.64.3.0
Resolving packages for group Main:
- FsXaml.Wpf is pinned to 0.9.9
- Microsoft.Diagnostics.Runtime is pinned to 0.8.31-beta
- Expression.Blend.Sdk 1.0.2
c:\Projects\MemoryVisualizer\paket.lock is already up-to-date
2 seconds - ready.
Gratuluję (sobie)!
Właśnie zamieniłem nugeta na Paketa.
Pozostają jeszcze dwie ważne kwestie.
1. A jak to się ma do VisualStudio?!
Teraz zależnościami zarządza Paket, więc czy po usunięciu katalogu packages nie trzeba będzie restorować wszystkiego ręcznie, spoza Visual Studio? Otóż nie, ponieważ Paket w trakcie wcześniej wykonanej konwersji wpina się w projekty, dbając w trakcie kompilacji o restore paczek oraz za ściągnięcie samego Paketa:
$ more src\MemoryVisualizer.UI\MemoryVisualizer.UI.fsproj | findstr paket
<Content Include="paket.references" />
<Import Project="..\..\.paket\paket.targets" />
$ more .paket\paket.targets
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<!-- Enable the restore command to run before builds -->
<RestorePackages Condition=" '$(RestorePackages)' == '' ">true</RestorePackages>
<!-- Download Paket.exe if it does not already exist -->
<DownloadPaket Condition=" '$(DownloadPaket)' == '' ">true</DownloadPaket>
...
Nie musimy się zatem bać o dodatkową ręczną robotę. Co więcej, konwersja dodaje też katalog do solucji, dzięki czemu mamy go pod ręką również w samym Visual Studio:
2. A co tu wysłać do repozytorium?!
Drugie ciekawe pytanie dotyczy wątpliwości, co tak naprawdę z tych wszystkich nowych plików “wcommitować” do repozytorium? Pytanie nie tylko w mojej głowie się zrodziło, bo bezpośrednią odpowiedź znajdziemy w FAQ. Commitujemy:
- paket.dependencies
- wszystkie paket.references
- paket.template - jeśli używamy (jeszcze nie wiem co to jest więc nie używam)
- paket.lock - choć generuje się automatycznie, zalecane jest by również commitować ze względu na spójność używanych wersji
- .paket/paket.targets - by śmigała integracja z Visual Studio/MSBuildem
- .paket/paket.bootstrapper.exe - bo bez niego nie zadziała automatyczne ściąganie Paketa z poprzedniego punktu
Nie commitujemy zaś .paket/paket.exe bo to bez sensu, jest duże i ściągnie się samo. Ale oczywiście modyfikujemy z tego powodu .gitignore. W efekcie zrodził się commit a467d4d5.