forked from shanselman/suavebootstrapper
-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathbuild.fsx
97 lines (80 loc) · 3.93 KB
/
build.fsx
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
// --------------------------------------------------------------------------------------
// A simple FAKE build script that:
// 1) Hosts Suave server locally & reloads web part that is defined in 'app.fsx'
// 2) Deploys the web application to Azure web sites when called with 'build deploy'
// --------------------------------------------------------------------------------------
#r "packages/FSharp.Compiler.Service/lib/net45/FSharp.Compiler.Service.dll"
#r "packages/Suave/lib/net40/Suave.dll"
#r "packages/FAKE/tools/FakeLib.dll"
open Fake
open System
open System.IO
open Suave
open Suave.Web
open Suave.Types
open Microsoft.FSharp.Compiler.Interactive.Shell
// --------------------------------------------------------------------------------------
// The following uses FileSystemWatcher to look for changes in 'app.fsx'. When
// the file changes, we run `#load "app.fsx"` using the F# Interactive service
// and then get the `App.app` value (top-level value defined using `let app = ...`).
// The loaded WebPart is then hosted at localhost:8083.
// --------------------------------------------------------------------------------------
let sbOut = new Text.StringBuilder()
let sbErr = new Text.StringBuilder()
let fsiSession =
let inStream = new StringReader("")
let outStream = new StringWriter(sbOut)
let errStream = new StringWriter(sbErr)
let fsiConfig = FsiEvaluationSession.GetDefaultConfiguration()
let argv = Array.append [|"/fake/fsi.exe"; "--quiet"; "--noninteractive"; "-d:DO_NOT_START_SERVER"|] [||]
FsiEvaluationSession.Create(fsiConfig, argv, inStream, outStream, errStream)
let reportFsiError (e:exn) =
traceError "Reloading app.fsx script failed."
traceError (sprintf "Message: %s\nError: %s" e.Message (sbErr.ToString().Trim()))
sbErr.Clear() |> ignore
let reloadScript () =
try
traceImportant "Reloading app.fsx script..."
let appFsx = __SOURCE_DIRECTORY__ @@ "app.fsx"
fsiSession.EvalInteraction(sprintf "#load @\"%s\"" appFsx)
fsiSession.EvalInteraction("open App")
match fsiSession.EvalExpression("app") with
| Some app -> Some(app.ReflectionValue :?> WebPart)
| None -> failwith "Couldn't get 'app' value"
with e -> reportFsiError e; None
// --------------------------------------------------------------------------------------
// Suave server that redirects all request to currently loaded version
// --------------------------------------------------------------------------------------
let currentApp = ref (fun _ -> async { return None })
let serverConfig =
{ defaultConfig with
homeFolder = Some __SOURCE_DIRECTORY__
logger = Logging.Loggers.saneDefaultsFor Logging.LogLevel.Debug
bindings = [ HttpBinding.mk' HTTP "127.0.0.1" 8083] }
let reloadAppServer () =
reloadScript() |> Option.iter (fun app ->
currentApp.Value <- app
traceImportant "New version of app.fsx loaded!" )
Target "run" (fun _ ->
let app ctx = currentApp.Value ctx
let _, server = startWebServerAsync serverConfig app
// Start Suave to host it on localhost
reloadAppServer()
Async.Start(server)
// Open web browser with the loaded file
System.Diagnostics.Process.Start("http://localhost:8083") |> ignore
// Watch for changes & reload when app.fsx changes
use watcher = {BaseDirectory = __SOURCE_DIRECTORY__; Includes = ["*.*"]; Excludes = []} |> WatchChanges (fun _ -> reloadAppServer())
traceImportant "Waiting for app.fsx edits. Press any key to stop."
System.Console.ReadLine() |> ignore
)
// --------------------------------------------------------------------------------------
// Minimal Azure deploy script - just overwrite old files with new ones
// --------------------------------------------------------------------------------------
Target "deploy" (fun _ ->
let sourceDirectory = __SOURCE_DIRECTORY__
let wwwrootDirectory = __SOURCE_DIRECTORY__ @@ "../wwwroot"
CleanDir wwwrootDirectory
CopyRecursive sourceDirectory wwwrootDirectory false |> ignore
)
RunTargetOrDefault "run"