対象スクリプトの修正を検知して再ロードする
参考://https://github.com/tpetricek/suave-xplat-gettingstarted/blob/master/build.fsx
下記を参考にFSharp環境を整備する
https://gist.github.com/asufana/b64f280fe5e442a45253
$ paket init
$ vim paket.dependencies
source https://www.nuget.org/api/v2
nuget FAKE
nuget Suave
nuget FSharp.Compiler.Service
$ paket install
#r "packages/Suave/lib/net40/Suave.dll"
open Suave
open Suave.Web
open Suave.Http.Successful
let app = OK "Welcome"
#r "packages/Suave/lib/net40/Suave.dll"
#r "packages/FAKE/tools/FakeLib.dll"
#r "packages/FSharp.Compiler.Service/lib/net45/FSharp.Compiler.Service.dll"
#load "App.fsx"
open App
open Fake
open System
open System.IO
open Suave
open Suave.Web
open Suave.Types
open Microsoft.FSharp.Compiler.Interactive.Shell
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 fsx script failed."
traceError (sprintf "Message: %s\nError: %s" e.Message (sbErr.ToString().Trim()))
sbErr.Clear() |> ignore
let reloadScript () =
try
//traceImportant "Reloading fsx scripts..."
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
let serverConfig =
{ defaultConfig with
homeFolder = Some __SOURCE_DIRECTORY__
logger = Logging.Loggers.saneDefaultsFor Logging.LogLevel.Warn
bindings = [ Types.HttpBinding.mk' Types.HTTP "127.0.0.1" 8083 ] }
let currentApp =
ref (fun _ -> async { return None })
let reloadAppServer () =
reloadScript()
|> Option.iter (fun app ->
currentApp.Value <- app
traceImportant "fsx scripts reloaded.")
//-------------------
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)
// Watch for changes & reload when app.fsx changes
use watcher =
!! (__SOURCE_DIRECTORY__ @@ "*.*")
|> WatchChanges (fun _ -> reloadAppServer())
traceImportant "Waiting for fsx scripts edits. Press any key to stop."
System.Console.ReadLine() |> ignore
)
RunTargetOrDefault "run"
$ fakerun suave.fsx
Paket version 2.38.0.0
0 seconds - ready.
FakePath: /Users/hana/Dropbox/Develop/FSharp/LightningTalks/packages/FAKE/tools/FakeLib.dll
FAKE - F# Make "4.11.3"
Running Buildscript: suave.fsx
Cache doesn't exist
Building project with version: LocalBuild
Shortened DependencyGraph for Target run:
<== run
The resulting target order is:
- run
Starting Target: run
fsx scripts reloaded.
dirs to watch: ["/Users/hana/Dropbox/Develop/FSharp/LightningTalks"]
watching dir: /Users/hana/Dropbox/Develop/FSharp/LightningTalks
Waiting for fsx scripts edits. Press any key to stop.
App.fsx を修正保存すると、自動リロードされ fsx scripts reloaded.
とコンソール出力される