-
Notifications
You must be signed in to change notification settings - Fork 588
/
Copy pathPaket.fs
280 lines (245 loc) · 11.8 KB
/
Paket.fs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
/// Contains helper functions and task which allow to inspect, create and publish [NuGet](https://www.nuget.org/) packages with [Paket](http://fsprojects.github.io/Paket/index.html).
[<RequireQualifiedAccess>]
module Fake.DotNet.Paket
open System
open System.IO
open System.Xml.Linq
open System.Text.RegularExpressions
open Fake.IO.Globbing
open Fake.Core
open Fake.IO
open Fake.IO.FileSystemOperators
open Fake.IO.Globbing.Operators
/// Paket pack parameter type
type PaketPackParams =
{ ToolPath : string
TimeOut : TimeSpan
Version : string
SpecificVersions : (string * string) list
LockDependencies : bool
ReleaseNotes : string
BuildConfig : string
BuildPlatform : string
TemplateFile : string
ExcludedTemplates : string list
WorkingDir : string
OutputPath : string
ProjectUrl : string
Symbols : bool
IncludeReferencedProjects : bool
MinimumFromLockFile : bool
PinProjectReferences : bool }
let internal findPaketExecutable (baseDir) =
ProcessUtils.findLocalTool "PAKET" "paket" [ Path.Combine(baseDir, ".paket") ]
/// Paket pack default parameters
let PaketPackDefaults() : PaketPackParams =
{ ToolPath = findPaketExecutable ""
TimeOut = TimeSpan.FromMinutes 5.
Version = null
SpecificVersions = []
LockDependencies = false
ReleaseNotes = null
BuildConfig = null
BuildPlatform = null
TemplateFile = null
ProjectUrl = null
ExcludedTemplates = []
WorkingDir = "."
OutputPath = "./temp"
Symbols = false
IncludeReferencedProjects = false
MinimumFromLockFile = false
PinProjectReferences = false }
/// Paket push parameter type
type PaketPushParams =
{ ToolPath : string
TimeOut : TimeSpan
PublishUrl : string
EndPoint : string
WorkingDir : string
DegreeOfParallelism : int
ApiKey : string }
/// Paket push default parameters
let PaketPushDefaults() : PaketPushParams =
{ ToolPath = findPaketExecutable ""
TimeOut = System.TimeSpan.MaxValue
PublishUrl = null
EndPoint = null
WorkingDir = "./temp"
DegreeOfParallelism = 8
ApiKey = null }
/// Paket restore packages type
type PaketRestoreParams =
{ ToolPath : string
TimeOut : TimeSpan
WorkingDir : string
ForceDownloadOfPackages : bool
OnlyReferencedFiles: bool
Group: string
ReferenceFiles: string list }
/// Paket restore default parameters
let PaketRestoreDefaults() : PaketRestoreParams =
{ ToolPath = findPaketExecutable ""
TimeOut = System.TimeSpan.MaxValue
WorkingDir = "."
ForceDownloadOfPackages = false
OnlyReferencedFiles = false
ReferenceFiles = []
Group = "" }
let inline private startPaket toolPath workDir (info:ProcStartInfo) =
{ info with
FileName = toolPath
WorkingDirectory = workDir }
let inline private withArgs args (info:ProcStartInfo) =
{ info with Arguments = args }
/// Creates a new NuGet package by using Paket pack on all paket.template files in the working directory.
/// ## Parameters
///
/// - `setParams` - Function used to manipulate the default parameters.
let pack setParams =
let parameters : PaketPackParams = PaketPackDefaults() |> setParams
use __ = Trace.traceTask "PaketPack" parameters.WorkingDir
let xmlEncode (notEncodedText : string) =
if String.IsNullOrWhiteSpace notEncodedText then ""
else XText(notEncodedText).ToString().Replace("ß", "ß")
let version = if String.IsNullOrWhiteSpace parameters.Version then "" else " --version " + Process.toParam parameters.Version
let buildConfig = if String.IsNullOrWhiteSpace parameters.BuildConfig then "" else " --build-config " + Process.toParam parameters.BuildConfig
let buildPlatform = if String.IsNullOrWhiteSpace parameters.BuildPlatform then "" else " --build-platform " + Process.toParam parameters.BuildPlatform
let templateFile = if String.IsNullOrWhiteSpace parameters.TemplateFile then "" else " --template " + Process.toParam parameters.TemplateFile
let lockDependencies = if parameters.LockDependencies then " --lock-dependencies" else ""
let excludedTemplates = parameters.ExcludedTemplates |> Seq.map (fun t -> " --exclude " + t) |> String.concat " "
let specificVersions = parameters.SpecificVersions |> Seq.map (fun (id,v) -> sprintf " --specific-version %s %s" id v) |> String.concat " "
let releaseNotes = if String.IsNullOrWhiteSpace parameters.ReleaseNotes then "" else " --release-notes " + Process.toParam (xmlEncode parameters.ReleaseNotes)
let minimumFromLockFile = if parameters.MinimumFromLockFile then " --minimum-from-lock-file" else ""
let pinProjectReferences = if parameters.PinProjectReferences then " --pin-project-references" else ""
let symbols = if parameters.Symbols then " --symbols" else ""
let includeReferencedProjects = if parameters.IncludeReferencedProjects then " --include-referenced-projects" else ""
let projectUrl = if String.IsNullOrWhiteSpace parameters.ProjectUrl then "" else " --project-url " + Process.toParam parameters.ProjectUrl
let packResult =
let cmdArgs =
sprintf "%s%s%s%s%s%s%s%s%s%s%s%s%s"
version specificVersions releaseNotes buildConfig buildPlatform templateFile lockDependencies excludedTemplates
symbols includeReferencedProjects minimumFromLockFile pinProjectReferences projectUrl
Process.execSimple
(startPaket parameters.ToolPath parameters.WorkingDir
>> withArgs (sprintf "pack \"%s\" %s" parameters.OutputPath cmdArgs)
>> Process.withFramework)
parameters.TimeOut
if packResult <> 0 then failwithf "Error during packing %s." parameters.WorkingDir
__.MarkSuccess()
/// Pushes the given NuGet packages to the server by using Paket push.
/// ## Parameters
///
/// - `setParams` - Function used to manipulate the default parameters.
/// - `files` - The files to be pushed to the server.
let pushFiles setParams files =
let parameters : PaketPushParams = PaketPushDefaults() |> setParams
TraceSecrets.register parameters.ApiKey "<PaketApiKey>"
match Environment.environVarOrNone "nugetkey" with
| Some k -> TraceSecrets.register k "<PaketApiKey>"
| None -> ()
match Environment.environVarOrNone "nuget-key" with
| Some k -> TraceSecrets.register k "<PaketApiKey>"
| None -> ()
let packages = Seq.toList files
let url = if String.IsNullOrWhiteSpace parameters.PublishUrl then "" else " --url " + Process.toParam parameters.PublishUrl
let endpoint = if String.IsNullOrWhiteSpace parameters.EndPoint then "" else " --endpoint " + Process.toParam parameters.EndPoint
let key = if String.IsNullOrWhiteSpace parameters.ApiKey then "" else " --api-key " + Process.toParam parameters.ApiKey
use __ = Trace.traceTask "PaketPush" (String.separated ", " packages)
if parameters.DegreeOfParallelism > 0 then
/// Returns a sequence that yields chunks of length n.
/// Each chunk is returned as a list.
let split length (xs: seq<'T>) =
let rec loop xs =
[
yield Seq.truncate length xs |> Seq.toList
match Seq.length xs <= length with
| false -> yield! loop (Seq.skip length xs)
| true -> ()
]
loop xs
for chunk in split parameters.DegreeOfParallelism packages do
let tasks =
chunk
|> Seq.toArray
|> Array.map (fun package -> async {
let pushResult =
Process.execSimple
(startPaket parameters.ToolPath parameters.WorkingDir
>> withArgs (sprintf "push %s%s%s%s" url endpoint key (Process.toParam package))
>> Process.withFramework)
parameters.TimeOut
if pushResult <> 0 then failwithf "Error during pushing %s." package })
Async.Parallel tasks
|> Async.RunSynchronously
|> ignore
else
for package in packages do
let pushResult =
Process.execSimple
(startPaket parameters.ToolPath parameters.WorkingDir
>> withArgs (sprintf "push %s%s%s%s" url endpoint key (Process.toParam package))
>> Process.withFramework)
parameters.TimeOut
if pushResult <> 0 then failwithf "Error during pushing %s." package
__.MarkSuccess()
/// Pushes all NuGet packages in the working dir to the server by using Paket push.
/// ## Parameters
///
/// - `setParams` - Function used to manipulate the default parameters.
let push setParams =
let parameters : PaketPushParams = PaketPushDefaults() |> setParams
!! (parameters.WorkingDir @@ "/**/*.nupkg")
|> pushFiles (fun _ -> parameters)
/// Returns the dependencies from specified paket.references file
let getDependenciesForReferencesFile (referencesFile:string) =
let getReferenceFilePackages =
let isSingleFile (line: string) = line.StartsWith "File:"
let isGroupLine (line: string) = line.StartsWith "group "
let notEmpty (line: string) = not <| String.IsNullOrWhiteSpace line
let parsePackageName (line: string) =
let parts = line.Split(' ')
parts.[0]
File.ReadAllLines
>> Array.filter notEmpty
>> Array.map (fun s -> s.Trim())
>> Array.filter (isSingleFile >> not)
>> Array.filter (isGroupLine >> not)
>> Array.map parsePackageName
let getLockFilePackages =
let getPaketLockFile referencesFile =
let rec find dir =
let fi = FileInfo(dir </> "paket.lock")
if fi.Exists then fi.FullName else find fi.Directory.Parent.FullName
find <| FileInfo(referencesFile).Directory.FullName
let breakInParts (line : string) = match Regex.Match(line,"^[ ]{4}([^ ].+) \((.+)\)") with
| m when m.Success && m.Groups.Count = 3 -> Some (m.Groups.[1].Value, m.Groups.[2].Value)
| _ -> None
getPaketLockFile
>> File.ReadAllLines
>> Array.choose breakInParts
let refLines = getReferenceFilePackages referencesFile
getLockFilePackages referencesFile
|> Array.filter (fun (n, _) -> refLines |> Array.exists (fun pn -> pn.Equals(n, StringComparison.OrdinalIgnoreCase)))
/// Restores all packages referenced in either a paket.dependencies or a paket.references file using Paket
/// ## Parameters
///
/// - `setParams` - Function used to manipulate the default parameters.
let restore setParams =
let parameters : PaketRestoreParams = PaketRestoreDefaults() |> setParams
let forceRestore = if parameters.ForceDownloadOfPackages then " --force " else ""
let onlyReferenced = if parameters.OnlyReferencedFiles then " --only-referenced " else ""
let groupArg = if parameters.Group <> "" then (sprintf " --group %s " parameters.Group) else ""
let referencedFiles =
if parameters.ReferenceFiles |> List.isEmpty |> not
then (sprintf " --references-files %s " (System.String.Join(" ", parameters.ReferenceFiles)))
else ""
use __ = Trace.traceTask "PaketRestore" parameters.WorkingDir
let restoreResult =
Process.execSimple
(startPaket parameters.ToolPath parameters.WorkingDir
>> withArgs (sprintf "restore %s%s%s%s" forceRestore onlyReferenced groupArg referencedFiles)
>> Process.withFramework)
parameters.TimeOut
if restoreResult <> 0 then failwithf "Error during restore %s." parameters.WorkingDir
__.MarkSuccess()