10aday › tools
Type the Version of a <PackageReference> such as [1.0,2.0), 1.*, 1.0.0-* or 1.0, and the versions published for that package.
You see which versions match, in plain words, and which one dotnet restore will pick. The page runs a JavaScript copy of NuGet's own version code
(NuGet.Versioning), checked against the real library and against real dotnet restore runs.
npm, Cargo, pip and Maven take the highest version that matches a range. NuGet takes the lowest one (“lowest applicable version”).
So [1.0,2.0) does not mean “the newest 1.x”: it means “1.0.0 if it exists”. For the newest 1.x, write a floating version: 1.*.
We ran dotnet restore (.NET SDK 8.0.134, NuGet 6.8) against a local feed for each line below:
| Version="…" | Published | dotnet restore got | Why |
|---|---|---|---|
| [1.0,2.0) | 1.0.0, 1.5.0, 1.9.9, 2.0.0 | 1.0.0 | NuGet takes the lowest match, not the newest. |
| 1.0 | 1.0.1, 1.2.0, 3.0.0 | 1.0.1 (NU1603) | A bare version is a minimum. 1.0.0 is missing, so the next one up. |
| [1.0,2.0) | 1.5.0-beta, 1.6.0, 1.7.0 | 1.6.0 (NU1603) | 1.5.0-beta is skipped: no bound is a prerelease. |
| [1.0,2.0) | 1.5.0-beta | fails (NU1103) | Only a prerelease matches: restore fails. |
| [1.0.0-beta,2.0) | 1.0.0-alpha, 1.0.0-beta, 1.6.0 | 1.0.0-beta | A prerelease lower bound lets prereleases in. |
| (1.0,) | 1.0.0, 1.0.1, 5.0.0 | 1.0.1 (NU1604) | Lowest version above 1.0. |
| (,2.0] | 0.1.0, 1.0.0, 2.0.0 | 0.1.0 (NU1604) | No lower bound: the lowest version in the feed. |
| [1.0] | 1.0.1 | fails (NU1102) | Exact version missing: restore fails. |
| * | 1.0.0, 2.0.0, 3.0.0-beta | 2.0.0 | Highest stable version. |
| *-* | 1.0.0, 2.0.0, 3.0.0-beta | 3.0.0-beta | Highest version, prereleases included. |
| 1.* | 0.9.0, 1.0.0, 1.4.0, 1.9.9-beta, 2.0.0 | 1.4.0 | Highest stable 1.x. |
| 1.2.* | 1.1.0, 1.3.0, 1.4.0 | 1.3.0 | No 1.2.x at all: the lowest version above it. |
| 1.*-* | 1.0.0, 1.5.0-beta, 1.5.0, 2.0.0-beta | 1.5.0 | Highest 1.x, prereleases allowed. 1.5.0 is higher than 1.5.0-beta. |
| 1.0.0-beta* | 1.0.0-alpha, 1.0.0-beta.1, 1.0.0-beta.2, 1.0.0-rc.1 | 1.0.0-beta.2 | Highest 1.0.0 prerelease starting with beta. |
| [1.*,2.0) | 1.0.0, 1.5.0, 2.0.0, 2.1.0 | 1.5.0 | Floating inside a range: highest 1.x below 2.0. |
| ^1.0 | 1.0.0 | fails | Not NuGet syntax: rejected. |
| [1.0,2.0) | 0.9.0, 2.0.0 | fails (NU1102) | Nothing between 1.0 and 2.0: restore fails. |
| Write | Means | Restore picks (from 1.0.0, 1.2.0, 1.5.0-beta, 1.5.0, 2.0.0-rc.1, 2.0.0) |
|---|
The last column is computed in your browser by the same engine as the checker above.
A NuGet version has 3 or 4 numbers (1.2.3.4; missing ones are 0, so 1.0 = 1.0.0 = 1.0.0.0), then an optional prerelease label after -
and optional build metadata after +. A prerelease is lower than the same version without label: 2.0.0-rc.1 < 2.0.0.
Labels are compared part by part (split at dots): numbers as numbers (beta.2 < beta.10), words alphabetically and case-insensitively (RC = rc, unlike npm).
Build metadata is ignored.
For Go programs: the same rules as a library, github.com/Lawatch/10aday/verrange/nuget (open source, no dependencies, tested against NuGet.Versioning and real dotnet restore).
From a terminal, with Go installed: go run github.com/Lawatch/10aday/verrange/cmd/verrange@latest nuget "[1.0,2.0)" 1.0.0 1.9.9 2.0.0 prints yes or no for each version, then the one the tool would pick (command docs).
Related: Maven version range checker (same bracket syntax, but Maven takes the highest match) and Gradle dynamic version checker (1.+, ranges, latest.release).
For npm, Cargo, Composer, pip and RubyGems, use the Version Constraint Checker; to sort versions, the Version sorter;
for betas and release candidates, what each package manager installs when a beta is out.
NuGet uses the lowest applicable version: in a range it picks the lowest version that matches, unlike npm, Cargo or Maven, which pick the highest. We ran dotnet restore with 1.0.0, 1.5.0, 1.9.9 and 2.0.0 published: [1.0,2.0) restored 1.0.0. To get the newest 1.x, use a floating version: 1.* restored 1.4.0 out of 0.9.0, 1.0.0, 1.4.0, 1.9.9-beta and 2.0.0.
No. A bare version means 1.0 or higher. NuGet takes 1.0.0 if it exists. If it does not, it takes the next higher version and prints warning NU1603. For exactly 1.0, write [1.0]: if 1.0 is missing, restore fails with NU1102.
In a normal range, prerelease versions are only used if one of the bounds is itself a prerelease, or with a floating version ending in -*. [1.0,2.0) with 1.5.0-beta and 1.6.0 published restored 1.6.0. With only 1.5.0-beta published it failed with NU1103. [1.0.0-beta,2.0) or 1.*-* let prereleases in.
1.* takes the highest stable 1.x version. 1.*-* takes the highest 1.x version, prereleases included. *-* takes the highest version of all, prereleases included. * takes the highest stable version.
No. These are npm or Cargo notations. NuGet only understands a bare version (a minimum), brackets such as [1.0,2.0) and floating versions with *. dotnet restore rejects ^1.0, ~1.0 and >=1.0. The NuGet equivalent of ^1.2 is [1.2,2.0), but NuGet will still pick the lowest match.
NU1603: the lower bound of your range was not found, so NuGet used the next version up. NU1604: the range has no included lower bound, such as (,2.0] or (1.0,): the result depends on what the feed holds. (,2.0] restored 0.1.0, the lowest version available.