Repository navigation
Expand file tree
/
Copy pathbuild.fsx
More file actions
254 lines (214 loc) · 9.18 KB
/
Copy pathbuild.fsx
File metadata and controls
254 lines (214 loc) · 9.18 KB
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
open System
open System.Diagnostics
open System.IO
open System.Collections.Generic
[<Literal>]
let project = "Owin.Compression"
[<Literal>]
let summary = "Compression (Deflate / GZip / Brotli) and eTag caching module for Microsoft OWIN self-host and ASP.NET Core/Kestrel."
[<Literal>]
let description = "Compression (Deflate / GZip / Brotli) module for Microsoft OWIN self-host and ASP.NET Core/Kestrel web servers with built-in eTag caching. With this module you can compress large files (like concatenated *.js or *.css files) to reduce the amount of web traffic."
let authors = [ "Tuomas Hietanen" ]
[<Literal>]
let tags = "OWIN SelfHost GZip Deflate Brotli AspNetCore Kestrel compress pack self host file system pipeline Microsoft"
[<Literal>]
let solutionFile = "Owin.Compression.sln"
[<Literal>]
let testProject = "tests/Owin.Compression.Tests/Owin.Compression.Tests.fsproj"
[<Literal>]
let legacyProject = "src/Owin.Compression/Owin.Compression.fsproj"
[<Literal>]
let coreProject = "src/Owin.Compression.Standard/Owin.Compression.Standard.fsproj"
[<Literal>]
let paketExecutable = ".paket/paket.exe"
[<Literal>]
let paketTemplate = "src/Owin.Compression/paket.template"
[<Literal>]
let assemblyInfoFile = "src/Owin.Compression/AssemblyInfo.fs"
[<Literal>]
let docsOutput = "docs/output"
[<Literal>]
let fsdocsTemp = ".fsdocs"
[<Literal>]
let packageOutput = "bin"
let fsdocsParameters =
[
"fsdocs-logo-src"; "https://github.com/Thorium/Owin.Compression/raw/master/docs/files/img/logo.png"
"fsdocs-navbar-position"; "fixed-right"
"fsdocs-repository-link"; "https://github.com/Thorium/Owin.Compression"
"fsdocs-list-of-namespaces"; "-"
]
[<Literal>]
let gitOwner = "Thorium"
[<Literal>]
let gitName = "Owin.Compression"
let gitHome = "https://github.com/" + gitOwner
let gitRaw =
match Environment.GetEnvironmentVariable("gitRaw") with
| null | "" -> "https://raw.github.com/Thorium"
| value -> value
let run exe (args: string list) =
let psi =
ProcessStartInfo(
FileName = exe,
WorkingDirectory = (Directory.GetCurrentDirectory()),
UseShellExecute = false
)
for arg in args do
psi.ArgumentList.Add arg
use proc = Process.Start(psi)
proc.WaitForExit()
if proc.ExitCode <> 0 then
let renderedArgs = String.concat " " args
failwithf "Command failed: %s %s" exe renderedArgs
let cleanDir path =
if Directory.Exists(path) then
Directory.Delete(path, true)
let cleanDirs paths =
for path in paths do
cleanDir path
let getPackageFiles () =
if Directory.Exists(packageOutput) then
Directory.GetFiles(packageOutput, "*.nupkg", SearchOption.TopDirectoryOnly)
|> Array.filter (fun path -> not (path.EndsWith(".snupkg", StringComparison.OrdinalIgnoreCase)))
|> Array.sort
|> Array.toList
else
[]
let runPaket args =
run paketExecutable args
let parseReleaseNotes () =
let lines = File.ReadAllLines("RELEASE_NOTES.md") |> Array.toList
let firstHeader =
lines
|> List.tryFind (fun line -> line.StartsWith "### ")
|> Option.defaultWith (fun () -> failwith "Could not find a version header in RELEASE_NOTES.md")
let version =
firstHeader.Substring(4).Split([|" - "|], StringSplitOptions.None).[0].Trim()
let notes =
lines
|> List.skipWhile (fun line -> line <> firstHeader)
|> List.skip 1
|> List.takeWhile (fun line -> not (line.StartsWith "### "))
|> List.filter (String.IsNullOrWhiteSpace >> not)
version, notes
let releaseVersion, releaseNotes = parseReleaseNotes ()
let writeAssemblyInfo () =
let content =
String.concat Environment.NewLine [
"// Auto-Generated by build.fsx; do not edit"
"namespace System"
"open System.Reflection"
""
$"[<assembly: AssemblyTitleAttribute(\"%s{project}\")>]"
$"[<assembly: AssemblyProductAttribute(\"%s{project}\")>]"
$"[<assembly: AssemblyDescriptionAttribute(\"%s{summary}\")>]"
sprintf "[<assembly: AssemblyMetadataAttribute(\"Authors\", \"%s\")>]" (String.concat ", " authors)
$"[<assembly: AssemblyMetadataAttribute(\"Description\", \"%s{description}\")>]"
$"[<assembly: AssemblyMetadataAttribute(\"Tags\", \"%s{tags}\")>]"
$"[<assembly: AssemblyMetadataAttribute(\"RepositoryUrl\", \"%s{gitHome}/%s{gitName}\")>]"
$"[<assembly: AssemblyMetadataAttribute(\"RepositoryRaw\", \"%s{gitRaw}\")>]"
$"[<assembly: AssemblyVersionAttribute(\"%s{releaseVersion}\")>]"
$"[<assembly: AssemblyFileVersionAttribute(\"%s{releaseVersion}\")>]"
"do ()"
""
"module internal AssemblyVersionInformation ="
$" let [<Literal>] AssemblyTitle = \"%s{project}\""
$" let [<Literal>] AssemblyProduct = \"%s{project}\""
$" let [<Literal>] AssemblyDescription = \"%s{summary}\""
$" let [<Literal>] AssemblyVersion = \"%s{releaseVersion}\""
$" let [<Literal>] AssemblyFileVersion = \"%s{releaseVersion}\""
]
File.WriteAllText(assemblyInfoFile, content + Environment.NewLine)
let targetActions = Dictionary<string, unit -> unit>(StringComparer.OrdinalIgnoreCase)
let targetDependencies = Dictionary<string, string list>(StringComparer.OrdinalIgnoreCase)
let completedTargets = HashSet<string>(StringComparer.OrdinalIgnoreCase)
let addTarget name dependencies action =
targetActions[name] <- action
targetDependencies[name] <- dependencies
let rec runTarget name =
if not (targetActions.ContainsKey name) then
let available = targetActions.Keys |> Seq.sort |> String.concat ", "
failwithf "Unknown target '%s'. Available targets: %s" name available
if completedTargets.Add name then
for dependency in targetDependencies[name] do
runTarget dependency
printfn "Running target %s" name
targetActions[name]()
addTarget "Clean" [] (fun () ->
cleanDirs [ "bin"; "temp"; "obj" ]
)
addTarget "Restore" [] (fun () ->
run "dotnet" [ "tool"; "restore" ]
runPaket [ "restore" ]
run "dotnet" [ "restore"; solutionFile ]
run "dotnet" [ "restore"; legacyProject ]
run "dotnet" [ "restore"; coreProject ]
)
addTarget "AssemblyInfo" [ "Restore" ] (fun () ->
writeAssemblyInfo ()
)
addTarget "Build" [ "AssemblyInfo" ] (fun () ->
run "dotnet" [ "build"; solutionFile; "-c"; "Release"; "--no-restore" ]
)
addTarget "BuildLegacy" [ "AssemblyInfo" ] (fun () ->
run "dotnet" [ "build"; legacyProject; "-c"; "Release" ]
)
addTarget "BuildCore" [ "AssemblyInfo" ] (fun () ->
run "dotnet" [ "build"; coreProject; "-c"; "Release"; "--no-restore" ]
)
addTarget "RunTests" [ "BuildCore" ] (fun () ->
run "dotnet" [ "test"; testProject; "-c"; "Release"; "--no-build"; "--no-restore" ]
)
addTarget "CleanDocs" [] (fun () ->
cleanDirs [ docsOutput ]
)
addTarget "GenerateDocs" [ "RunTests" ] (fun () ->
cleanDirs [ fsdocsTemp ]
run "dotnet" ([ "fsdocs"; "build"; "--output"; docsOutput; "--input"; "docs/content"; "--noapidocs"; "--clean"; "--parameters" ] @ fsdocsParameters)
)
addTarget "WatchLocalDocs" [ "BuildCore" ] (fun () ->
cleanDirs [ fsdocsTemp ]
run "dotnet" ([ "fsdocs"; "watch"; "--output"; docsOutput; "--input"; "docs/content"; "--noapidocs"; "--clean"; "--parameters"; "fsdocs-package-project-url"; "http://localhost:8901/" ] @ fsdocsParameters)
)
addTarget "All" [ "GenerateDocs" ] (fun () -> ())
addTarget "NuGet" [] (fun () ->
cleanDirs [ "bin"; "temp"; "obj" ]
run "dotnet" [ "tool"; "restore" ]
runPaket [ "restore" ]
run "dotnet" [ "restore"; solutionFile ]
run "dotnet" [ "restore"; legacyProject ]
run "dotnet" [ "restore"; coreProject ]
writeAssemblyInfo ()
run "dotnet" [ "build"; legacyProject; "-c"; "Release" ]
run "dotnet" [ "build"; coreProject; "-c"; "Release"; "--no-restore" ]
runPaket [ "pack"; packageOutput; "--template"; paketTemplate; "--version"; releaseVersion; "--release-notes"; String.concat Environment.NewLine releaseNotes ]
)
addTarget "BuildPackage" [ "NuGet" ] (fun () -> ())
addTarget "PublishNuget" [ "BuildPackage" ] (fun () ->
match getPackageFiles () with
| [] -> failwith "No NuGet packages were found in bin. Run BuildPackage first."
| packageFiles ->
for packageFile in packageFiles do
runPaket [ "push"; packageFile ]
)
addTarget "ReleaseDocs" [ "GenerateDocs" ] (fun () ->
printfn "Documentation generated in %s" docsOutput
)
addTarget "Release" [ "BuildPackage" ] (fun () ->
let packageFiles = getPackageFiles ()
if List.isEmpty packageFiles then
failwith "No NuGet packages were produced."
printfn "Release artifacts ready:"
for packageFile in packageFiles do
printfn " - %s" packageFile
)
let commandLineArgs = fsi.CommandLineArgs |> Array.skip 1 |> Array.toList
let targetName =
match commandLineArgs with
| [] -> "All"
| [ single ] when not (single.StartsWith "-") -> single
| "--target" :: value :: _ -> value
| "target" :: value :: _ -> value
| _ -> failwith "Usage: dotnet fsi build.fsx -- [--target] <TargetName>"
runTarget targetName