diff --git a/docs/content/commands/pack.md b/docs/content/commands/pack.md
new file mode 100644
index 0000000000..6f7a70fccb
--- /dev/null
+++ b/docs/content/commands/pack.md
@@ -0,0 +1,56 @@
+## Creating NuGet-Packages
+
+Consider the following [`paket.dependencies` file][depfile] in your project's root:
+
+ source https://nuget.org/api/v2
+
+ nuget Castle.Windsor ~> 3.2
+ nuget NUnit
+
+And one of your projects having a [`paket.references` file][reffile] like this:
+
+ Castle.Windsor
+
+Now, when you run `paket install`, your [`paket.lock` file][lockfile] would look like this:
+
+ NUGET
+ remote: https://nuget.org/api/v2
+ specs:
+ Castle.Core (3.3.3)
+ Castle.Windsor (3.3.0)
+ Castle.Core (>= 3.3.0)
+ NUnit (2.6.4)
+
+Now, when you are done programming and wish to create a NuGet-Package of your project, create a [`paket.template`][templatefile] file with `type project` and run:
+
+ [lang=batch]
+ paket pack output nugets version 1.0.0
+
+Or, you could run:
+
+ [lang=batch]
+ paket pack output nugets version 1.0.0 lock-dependencies
+
+Depending on which command you issue, Paket creates different version requirements of the packages you depend on in the resulting `.nuspec` file of your package:
+
+
+
+ Dependency |
+ Default |
+ With locked dependencies |
+
+
+
+ Castle.Windsor |
+ [3.2,4.0) |
+ [3.3.0] |
+
+
+
+
+As you see here, the first command (without the `lock-dependencies` parameter) creates version requirements as specified in your [`paket.dependencies` file][depfile]. The second command takes the currently resolved versions from your [`paket.lock` file][lockfile] and "locks" them to these specific versions.
+
+ [lockfile]: lock-file.html
+ [depfile]: dependencies-file.html
+ [reffile]: references-files.html
+ [templatefile]: template-files.html
diff --git a/src/Paket.Core/PackageMetaData.fs b/src/Paket.Core/PackageMetaData.fs
index d9f8abb5fe..692535ea32 100644
--- a/src/Paket.Core/PackageMetaData.fs
+++ b/src/Paket.Core/PackageMetaData.fs
@@ -137,7 +137,7 @@ let addFile (source : string) (target : string) (templateFile : TemplateFile) =
| IncompleteTemplate ->
failwith "You should only try and add dependencies to template files with complete metadata."
-let findDependencies (dependencies : DependenciesFile) config (template : TemplateFile) (project : ProjectFile) (map : Map) =
+let findDependencies (dependencies : DependenciesFile) config (template : TemplateFile) (project : ProjectFile) lockDependencies (map : Map) =
let targetDir =
match project.OutputType with
| ProjectOutputType.Exe -> "tools/"
@@ -183,7 +183,12 @@ let findDependencies (dependencies : DependenciesFile) config (template : Templa
match templateFile with
| CompleteTemplate(core, opt) ->
match core.Version with
- | Some v -> core.Id, VersionRequirement(Minimum(v), PreReleaseStatus.All)
+ | Some v ->
+ let versionConstraint =
+ if not lockDependencies
+ then Minimum v
+ else Specific v
+ core.Id, VersionRequirement(versionConstraint, PreReleaseStatus.All)
| none ->failwithf "There was no version given for %s." templateFile.FileName
| IncompleteTemplate -> failwithf "You cannot create a dependency on a template file (%s) with incomplete metadata." templateFile.FileName)
|> List.fold addDependency templateWithOutput
@@ -215,17 +220,27 @@ let findDependencies (dependencies : DependenciesFile) config (template : Templa
with
| _ -> true)
|> List.map (fun np ->
+ let getDependencyVersionRequirement package =
+ if not lockDependencies then
+ Map.tryFind package dependencies.DirectDependencies
+ |> function
+ | Some direct -> Some direct
+ | None ->
+ // If it's a transient dependency, try to
+ // find it in `paket.lock` and set min version
+ // to current locked version
+ lockFile.ResolvedPackages
+ |> Map.tryFind (NormalizedPackageName package)
+ |> Option.map (fun transient -> transient.Version)
+ |> Option.map (fun v -> VersionRequirement(Minimum v, PreReleaseStatus.All))
+ else
+ Map.tryFind (NormalizedPackageName package) lockFile.ResolvedPackages
+ |> Option.map (fun resolvedPackage -> resolvedPackage.Version)
+ |> Option.map (fun version -> VersionRequirement(Specific version, PreReleaseStatus.All))
let dep =
- match Map.tryFind np.Name dependencies.DirectDependencies with
- | Some direct -> direct
- // If it's a transient dependency set
- // min version to current locked version
- | None ->
- let resolved =
- lockFile.ResolvedPackages
- |> Map.find (NormalizedPackageName np.Name)
-
- VersionRequirement(Minimum resolved.Version, PreReleaseStatus.All)
+ match getDependencyVersionRequirement np.Name with
+ | Some installed -> installed
+ | None -> failwithf "No package with id '%A' installed." np.Name
np.Name.Id, dep)
|> List.fold addDependency withDepsAndIncluded
| None -> withDepsAndIncluded
diff --git a/src/Paket.Core/PackageProcess.fs b/src/Paket.Core/PackageProcess.fs
index bd9a7c9052..7c3f1b1ca3 100644
--- a/src/Paket.Core/PackageProcess.fs
+++ b/src/Paket.Core/PackageProcess.fs
@@ -10,9 +10,9 @@ open System.Collections.Generic
open Paket.PackageMetaData
open Chessie.ErrorHandling
-let Pack(workingDir,dependencies : DependenciesFile, packageOutputPath, buildConfig, version, releaseNotes, templateFile) =
- let buildConfig = defaultArg buildConfig "Release"
- let packageOutputPath = if Path.IsPathRooted(packageOutputPath) then packageOutputPath else Path.Combine(workingDir,packageOutputPath)
+let Pack(workingDir,dependencies : DependenciesFile, packageOutputPath, buildConfig, version, releaseNotes, templateFile, lockDependencies) =
+ let buildConfig = defaultArg buildConfig "Release"
+ let packageOutputPath = if Path.IsPathRooted(packageOutputPath) then packageOutputPath else Path.Combine(workingDir,packageOutputPath)
Utils.createDir packageOutputPath |> returnOrFail
let version = version |> Option.map SemVer.Parse
@@ -98,7 +98,7 @@ let Pack(workingDir,dependencies : DependenciesFile, packageOutputPath, buildCon
// add dependencies
let allTemplates =
projectTemplates
- |> Map.map (fun _ (t, p) -> p,findDependencies dependencies buildConfig t p projectTemplates)
+ |> Map.map (fun _ (t, p) -> p,findDependencies dependencies buildConfig t p lockDependencies projectTemplates)
|> Map.toList
|> List.map (fun (_,(_,x)) -> x)
|> List.append [for fileName in allTemplateFiles -> TemplateFile.Load(fileName,version)]
diff --git a/src/Paket.Core/PublicAPI.fs b/src/Paket.Core/PublicAPI.fs
index f90831f4ff..31c7416c47 100644
--- a/src/Paket.Core/PublicAPI.fs
+++ b/src/Paket.Core/PublicAPI.fs
@@ -371,10 +371,11 @@ type Dependencies(dependenciesFileName: string) =
FindReferences.FindReferencesForPackage (PackageName package) |> this.Process
// Packs all paket.template files.
- member this.Pack(outputPath, ?buildConfig, ?version, ?releaseNotes, ?templateFile, ?workingDir) =
+ member this.Pack(outputPath, ?buildConfig, ?version, ?releaseNotes, ?templateFile, ?workingDir, ?lockDependencies) =
let dependenciesFile = DependenciesFile.ReadFromFile dependenciesFileName
let workingDir = defaultArg workingDir (dependenciesFile.FileName |> Path.GetDirectoryName)
- PackageProcess.Pack(workingDir, dependenciesFile, outputPath, buildConfig, version, releaseNotes, templateFile)
+ let lockDependencies = defaultArg lockDependencies false
+ PackageProcess.Pack(workingDir, dependenciesFile, outputPath, buildConfig, version, releaseNotes, templateFile, lockDependencies)
/// Pushes a nupkg file.
static member Push(packageFileName, ?url, ?apiKey, (?endPoint: string), ?maxTrials) =
diff --git a/src/Paket/Commands.fs b/src/Paket/Commands.fs
index 5c5c7c4cda..4ef400b395 100644
--- a/src/Paket/Commands.fs
+++ b/src/Paket/Commands.fs
@@ -251,6 +251,7 @@ type PackArgs =
| [] Version of string
| [] TemplateFile of string
| [] ReleaseNotes of string
+ | [] LockDependencies
with
interface IArgParserTemplate with
member this.Usage =
@@ -260,6 +261,7 @@ with
| Version(_) -> "Specify version of the package."
| TemplateFile(_) -> "Allows to specify a single template file."
| ReleaseNotes(_) -> "Specify relase notes for the package."
+ | LockDependencies -> "Get the version requirements from paket.lock instead of paket.dependencies."
type PushArgs =
| [][] Url of string
diff --git a/src/Paket/Program.fs b/src/Paket/Program.fs
index 08278c6bf7..92513ca8a0 100644
--- a/src/Paket/Program.fs
+++ b/src/Paket/Program.fs
@@ -180,7 +180,8 @@ let pack (results : ArgParseResults<_>) =
?version = results.TryGetResult <@ PackArgs.Version @>,
?releaseNotes = results.TryGetResult <@ PackArgs.ReleaseNotes @>,
?templateFile = results.TryGetResult <@ PackArgs.TemplateFile @>,
- workingDir = Environment.CurrentDirectory)
+ workingDir = Environment.CurrentDirectory,
+ lockDependencies = results.Contains <@ PackArgs.LockDependencies @>)
let findPackages (results : ArgParseResults<_>) =
let maxResults = defaultArg (results.TryGetResult <@ FindPackagesArgs.MaxResults @>) 10000