diff --git a/docs/content/Dependencies_file.md b/docs/content/Dependencies_file.md index 5f3a79d612..90deed44b7 100644 --- a/docs/content/Dependencies_file.md +++ b/docs/content/Dependencies_file.md @@ -1,50 +1,208 @@ The paket.dependencies file =========================== -The `paket.dependencies` file is used to specify rules regarding your application's dependencies. +The `paket.dependencies` file is used to specify rules regarding your application's dependencies. + +The give you an overview, this is what Paket's `paket.dependencies` file looks like as of the time of writing: -It uses a similar syntax to that of [bundler](http://bundler.io/)'s [Gemfile](http://bundler.io/gemfile.html): - source "http://nuget.org/api/v2" - nuget "Castle.Windsor-log4net" "~> 3.2" - nuget "Rx-Main" "~> 2.0" + nuget "Newtonsoft.Json" "~> 6.0" + nuget "UnionArgParser" "~> 0.7" + nuget "NUnit.Runners" "~> 2.6.3" + nuget "NUnit" "~> 2.6.3" + nuget "FAKE" "~> 3.4" + nuget "FSharp.Formatting" "~> 2.4" + nuget "DotNetZip" "~> 1.9.3" + nuget "SourceLink.Fake" "~> 0.3" + +The syntax looks familiar to users of Ruby's [bundler](http://bundler.io/) [Gemfile](http://bundler.io/gemfile.html). This is intended because it proved to work well for the authors of Paket. + +The file specifies that Paket's dependencies should be downloaded from [nuget.org](http://nuget.org) and that we need e.g. [`FAKE`](http://fsharp.github.io/FAKE/) [in version `3.4 <= x < 3.5`](#pessimistic-version-constraint) as a build tool. + +Only direct dependencies should be listed. Paket uses this definition to compute a concrete dependency resolution, which also includes indirect dependencies. The resulting dependency graph is then persisted to the [`paket.lock` file](lock_file.html). -Only direct dependencies should be listed in this file. +## Sources -Paket uses this definition to compute a concrete package resolution, which also includes indirect dependencies, in a [paket.lock](lock_file.html) file. +Sources are defined by the `source "
"` statement. -Sources -------- +Paket supports several source types and multiple sources per `paket.dependencies`. It's recommended to put all `source` statements at the top of `paket.dependencies`. The ordering of sources is important, since the first `source` a [dependency](#package-id) is found in will be the one used for download. -It's possible to use multiple sources: +The [`paket.lock` file](lock_file.html) will reflect the sources used for dependency resolution. - source "http://nuget.org/api/v2" // nuget.org +### NuGet sources - nuget "Castle.Windsor-log4net" "~> 3.2" - nuget "Rx-Main" "~> 2.0" +Paket supports NuGet feeds like [nuget.org](http://nuget.org) or [TeamCity](http://www.jetbrains.com/teamcity/). +Please note that you need to specify all NuGet sources, including the official feed from [nuget.org](http://nuget.org). Paket does not take the NuGet Package Sources configuration into account (that you set up e.g. using Visual Studio). + + source "http://nuget.org/api/v2" // nuget.org source "http://myserver/nuget/api/v2" // custom feed - - nuget "CustomLib" "~> 1.5" // downloaded from the custom feed The [paket.lock](lock_file.html) will also reflect these settings. -Path sources ------------- +### Path sources -Paket supports NuGet feeds like [nuget.org](http://nuget.org) or [TeamCity](http://www.jetbrains.com/teamcity/), but it also supports paths: +Paket supports paths like local directories or SMB shares: source "C:\Nugets" + source "~/project/nugets" source "\\server\nugets" - nuget "FAKE" "~> 3.2" +
+## Dependencies + +The dependencies of your project are defined by the `nuget "" ""` statement. + +Paket currently supports only NuGet packages, but [we're evaluating other options](https://github.com/fsprojects/Paket/issues/9). + +
+### Package ID + +The `package ID` parameter is the same as you find in NuGet's `packages.config` or on [nuget.org](http://nuget.org). + +
+### Version constraints + +One key feature of Paket is that it separates the definition of dependencies from the actual resolution. NuGet does both using `packages.config` where both package IDs and their respective pinned version are listed. + +With Paket you do not need to pin specific versions (although you can). Paket allows you to leverage [semantic versioning](http://semver.org) and define version constraints in a very flexible manner. + +Please also see below how you can [influence the resolution of indirect dependencies](#nuget-style-dependency-resolution). + +#### Pinned version constraint + + nuget "Example" "= 1.2.3" + nuget "Example" "1.2.3" // same as above + + nuget "Example" "1.2.3-alpha001" + +This is the strictest version constraint. Use the `=` operator to specify an exact version match. The `=` is optional. + +#### Greater-than-or-equal version constraint + + nuget "Example" ">= 1.2.3" + + nuget "Example" ">= 1.2.3-alpha001" + +Use the `>=` operator to denote that you want the latest version available, as long as it's newer that what follows the `>=` operator. + +#### TODO Greater-than version constraint + + nuget "Example" "> 1.2.3" + +NOT SUPPORTED YET + +#### TODO Less-than-or-equal version constraint + + nuget "Example" "<= 1.2.3" + +NOT SUPPORTED YET + +#### TODO Less-than version constraint + + nuget "Example" "< 1.2.3" + +NOT SUPPORTED YET + +#### TODO Compound version constraint + + nuget "Example" ">= 1.2.3" "< 1.5" + +NOT SUPPORTED YET + +
+#### Pessimistic version constraint + + nuget "Example" "~> 1.2.3" + +The `~>` "twiddle-wakka" operator is borrowed from [bundler](http://bundler.io/). It is used to specifiy a version range. It translates to "use the minimum version specified, but allow upgrades to `, last part chopped off, last number incremented by 1`". Let us illustrate: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ConstraintVersion range
~> 0
0 <= x < 1
~> 1.0
1.0 <= x < 2.0
~> 1.2
1.2 <= x < 2.0
~> 1.2.3
1.2.3 <= x < 1.3
~> 1.2.3.4
1.2.3.4 <= x < 1.2.4
~> 1.2.3-alpha001
1.2.3-alpha001 <= x < 1.3
+ +#### TODO Pessimistic version constraint with compound + +NOT SUPPORTED YET + +If want to allow never backward-compatible versions but also need a specific fix version within the allowed range, use a compound constraint. + + nuget "Example" "~> 1.2" ">= 1.2.3" + +The example above translates to `1.2.3 <= x < 2.0`. + +### Controlling dependency resolution + +#### A word on NuGet + +The NuGet dependency resolution strategy was a major motivation for us to develop Paket in the first place. + +NuGet made the decision very early that if package `A` depends on package `B`, you will always get the *lowest matching version* of package `B`, regardless of available newer versions. One side effect of this decision is that after you install `A` (and `B`), you will be able to immediately update `B` to a newer version as long as it satisfies the version constraint defined by `A`. + +Installing packages like this is almost always a two-step operation: install and then try to update. We found it very hard to keep our project's dependencies at the latest version, that's why we chose to handle things differently. + +#### How Paket works by default + +Paket uses the definitions from `paket.dependencies` to compute the dependency graph. + +The resolution algorithm balances direct and indirect dependencies such that you will get the *latest matching versions* of direct dependencies (defined using the [`nuget` statement](#dependencies)) and indirect dependencies (defined by your direct dependency's [nuspec](http://docs.nuget.org/docs/reference/nuspec-reference)). Paket checks compatibility by comparing available versions to the constraints of either source, `paket.dependencies`, or [nuspec](http://docs.nuget.org/docs/reference/nuspec-reference). + +As stated above, the algorithm defaults to downloading the latest versions matching the constraints. + +As long as everybody follows [SemVer](http://semver.org) and you define sane version constraints (e.g. within a major version) for your direct dependencies the system is very likely to work well. + +While developing Paket we found that many packages available on [NuGet](http://nuget.org) today (September 2014) don't follow [SemVer](http://semver.org) very well with regard to specifying their own dependencies. + +#### A real-world example + +For example, an assembly inside a NuGet package `A` might have a reference to a strong-named assembly that is pulled from another NuGet package `B`. Despite strong-naming the `B` assembly, `A` still specifies an open version constraint (`> `). + +This might be due to the fact that the [nuspec file format](http://docs.nuget.org/docs/reference/nuspec-reference) requires you to pin the dependency version using double brackets: ``. Even the authors of Paket made the mistake of omitting the brackets, effectively specifying `> 1.2.3`. Newer releases of `B` package might still work together with `A` using [assembly binding redirects](http://msdn.microsoft.com/en-us/library/7wd6ex19(v=vs.110).aspx), a feature of .NET that the authors of Paket are not very fond of. Even if you are OK with binding redirects, what would happen after `B` `2.0` is released? If you imply that `B` follows [SemVer](http://semver.org), the `2.0` version *will have* breaking changes. + +
+#### Paket's NuGet-style dependency resolution for indirect dependencies + +To make your transition to Paket easier and to allow package authors to correct their version constraints you can have Paket behave like NuGet when resolving indirect dependencies (i.e. defaulting to lowest matching versions). + +To let Paket use NuGet-style dependency resolution for indirect dependencies, use the `!` operator in your version constraint. + + source "http://nuget.org/api/v2" + + nuget "Example-A" "!~> 1.2" // use "min" version resolution strategy -NuGet-style pessimistic version constraints -------------------------------------------- +This effectively will get you the *lowest matching versions* of `Example`'s dependencies. Still, you will get the *latest matching version* of `Example` itself according to its [version constraint of `1.2 <= x < 2`](#pessimistic-version-constraint). -NuGet uses a pessimistic version resolution strategy. In order to make the transition easier, Paket allows you to apply NuGet's dependency resolution strategy by prefixing your version constraint with **`!`**. +The `!` operator is applicable to all [version constraints](#version-constraints): source "http://nuget.org/api/v2" - nuget "Nancy.Bootstrappers.Windsor" "!~> 0.23" // use pessimistic version resolution strategy + nuget "Example-B" "!= 1.2" // use "min" version resolution strategy + nuget "Example-C" "!>= 1.2" // use "min" version resolution strategy