Introduction to Paket
A predictable replacement for NuGet
Timothy McLane
iModules Software
NuGet
Packages fed from nuget.org
Similar to Maven or NPM
Package manager for .NET
Isn't Nuget "good enough"?
For simple apps, NuGet does a sufficient job...
But when you have lots of nested dependencies...
An Example...
- Charlie.NET depends on XRay.NET 2.0
- Bravo.NET depends on XRay.NET 1.2
- Alpha.NET depends on XRay.NET 1.1 (which means >= 1.1)
We need to install 3 different packages:
- Alpha.NET
- Bravo.NET
- Charlie.NET
Each of these depend upon XRay.NET
XRay.NET has versions 1.0, 1.1, 1.2, 2.0, 3.0 and 4.0 available
Example from NuGet versioning Part 2: the core algorithm " by Dave Ebbo is licensed under CC BY 2.5
How does NuGet resolve these dependencies?
The version resolution used by NuGet is to always pick the lowest version of a dependency that fits in the range. So let’s see what will happen in various scenarios:
- If you just install Alpha.NET, you’ll get XRay.NET 1.1
-
If you just install Bravo.NET, you’ll get XRay.NET 1.2
-
If you just install Charlie.NET, you’ll get XRay.NET 2.0
-
If you first install Alpha, then Bravo then Charlie
-
You’ll initially get XRay.NET 1.1 when you install Alpha
-
XRay.NET will be updated to 1.2 when you install Bravo
- XRay.NET will be updated to 2.0 when you install Charlie
Example from NuGet versioning Part 2: the core algorithm by Dave Ebbo is licensed under CC BY 2.5
So what's wrong with that?
- What if XRay.NET changed their public API between 1.2 and 2.0?
- What if Alpha.NET and Charlie.NET use APIs that aren't available across versions?
Caveats
- This is NuGet before MSBuild 15
- Some problems have been addressed by Microsoft
- Nuget Changes with MSBuild 15:
- https://docs.microsoft.com/en-us/nuget/consume-packages/dependency-resolution
- Removes packages.config
- Handle transitive dependencies (but not recorded explicitly)
So why Paket?
- Consistent dependency graph
- Predictable dependency resolution
- Framework-specific dependencies
- References over HTTP
-
Automatic removal of unused refs
...and some other nice-to-haves
Consistent Dependency Graph
- When you add a package to a project with Paket, it creates a paket.lock file
- This file specifies the project's dependencies, their versions, and any of their dependencies and versions
- Saved to the repository, making package restoration consistent and predictable
- Paket : NuGet :: Yarn : NPM
Framework-Specific Dependencies
- Do you have a project running an older version of .NET that you want to upgrade? Paket's ready for that.
- Package conditionals for framework version
- Out-of-the-box functionality
Unused Reference Cleanup
Paket keeps track of all our dependencies, including transitive dependencies, which means it knows what's being used—and what's not.
This means Paket can remove unused packages without breaking everything.
HTTP and Git References
Ever have a script or simple source file you copied from project to project?
Paket supports pulling those down from a local or remote location without copy pasta polluting your delicious code.
Dependencies with Paket
Consistent
Clean
Predictable
Getting Started
1 Initialization Step
2 Executables
3 Configuration Files
4 Commands
Installation Step
If you have Paket on your path
paket init
Invoke-WebRequest
-Uri https://github.com/fsprojects/Paket/releases/download/5.120.0/paket.bootstrapper.exe
-OutFile .paket/paket.exe; ./.paket/paket.exe init
Otherwise...
Paket Executables
-
paket.bootstrapper.exe
- Performs setup, including downloading paket.exe if necessary - "Magic mode"
-
paket.exe
- Base executable
- Does the actual magic
Paket Files
-
paket.dependencies
- Declares the dependencies for the whole solution
-
paket.references
- Declares the dependencies for a particular project
-
paket.lock
- Declares the resolved packages (name, version, etc.) and their dependencies
Some examples...
paket.dependencies
Text
source https://nuget.org/api/v2
// NuGet packages
nuget NUnit ~> 2.6.3
nuget FAKE ~> 3.4
nuget DotNetZip >= 1.9
// Files from GitHub repositories.
github forki/FsUnit FsUnit.fs
// Gist files.
gist Thorium/1972349 timestamp.fs
// HTTP resources.
http http://www.fssnip.net/1n decrypt.fs
Example from Paket's documentation on GitHub
paket.references
Text
Newtonsoft.Json
UnionArgParser
DotNetZip
RestSharp
group Test
NUnit
Example from Paket's documentation on GitHub
paket.lock
Text
NUGET
remote: https://nuget.org/api/v2
Castle.Core (3.3.0)
Castle.Core-log4net (3.3.0)
Castle.Core (>= 3.3.0)
log4net (1.2.10)
Castle.LoggingFacility (3.3.0)
Castle.Core (>= 3.3.0)
Castle.Windsor (>= 3.3.0)
Castle.Windsor (3.3.0)
Castle.Core (>= 3.3.0)
Castle.Windsor-log4net (3.3.0)
Castle.Core-log4net (>= 3.3.0)
Castle.LoggingFacility (>= 3.3.0)
Example from Paket's documentation on GitHub
Paket Commands
-
add
- Adds a new dependency to a solution
-
remove
- Removes a dependency from a solution
-
install
- Update .*proj and paket.lock files
- Resolves the dependency graph for a solution
- Only run after adding or removing a dependency
-
restore
- Downloads all declared dependencies
Some examples...
paket add
paket add Newtonsoft.JSON
paket add Newtonsoft.JSON --project JSONParser
paket remove
paket remove Newtonsoft.Json
paket remove Newtonsoft.Json --project XMLParser
paket install
paket install
paket restore
paket restore
- Nuget Versioning blog series by Dave Ebbo
- NuGet documentation at https://docs.microsoft.com/en-us/nuget/what-is-nuget
- Paket documentation at https://fsprojects.github.io/Paket/index.html
Sources and Documentation
Introduction to Paket
By tmclane
Introduction to Paket
- 632