|
| 1 | +#I @"packages/FsReveal/fsreveal/" |
| 2 | +#I @"packages/FAKE/tools/" |
| 3 | +#I @"packages/Suave/lib/net40" |
| 4 | + |
| 5 | +#r "FakeLib.dll" |
| 6 | +#r "suave.dll" |
| 7 | + |
| 8 | +#load "fsreveal.fsx" |
| 9 | + |
| 10 | +// Git configuration (used for publishing documentation in gh-pages branch) |
| 11 | +// The profile where the project is posted |
| 12 | +let gitOwner = "Kottans" |
| 13 | +let gitHome = "https://github.com/" + gitOwner |
| 14 | +// The name of the project on GitHub |
| 15 | +let gitProjectName = "csharp-slides" |
| 16 | + |
| 17 | +open FsReveal |
| 18 | +open Fake |
| 19 | +open Fake.Git |
| 20 | +open Fake.XMLHelper |
| 21 | +open System.IO |
| 22 | +open System.Diagnostics |
| 23 | +open Suave |
| 24 | +open Suave.Web |
| 25 | +open Suave.Http |
| 26 | +open Suave.Http.Files |
| 27 | + |
| 28 | +let toWebCompliantName (original:string) = |
| 29 | + original.Replace(" ", "-").ToLower() |
| 30 | + |
| 31 | +let topic = (getBuildParam "slides").Trim '"' |
| 32 | +let topicWebCompliant = topic |> toWebCompliantName |
| 33 | +let outDir = __SOURCE_DIRECTORY__ @@ "output" @@ topicWebCompliant |
| 34 | +let slidesDir = __SOURCE_DIRECTORY__ @@ "slides" @@ topic |
| 35 | + |
| 36 | +let ghPagesDir = __SOURCE_DIRECTORY__ @@ "gh-pages" |
| 37 | +let publishDir = ghPagesDir @@ "presentations" @@ topicWebCompliant |
| 38 | + |
| 39 | +Target "Clean" (fun _ -> |
| 40 | + CleanDirs [outDir] |
| 41 | +) |
| 42 | + |
| 43 | +let fsiEvaluator = |
| 44 | + let evaluator = FSharp.Literate.FsiEvaluator() |
| 45 | + evaluator.EvaluationFailed.Add(fun err -> |
| 46 | + traceImportant <| sprintf "Evaluating F# snippet failed:\n%s\nThe snippet evaluated:\n%s" err.StdErr err.Text ) |
| 47 | + evaluator |
| 48 | + |
| 49 | +let copyStylesheet() = |
| 50 | + try |
| 51 | + CopyFile (outDir @@ "css" @@ "custom.css") (slidesDir @@ "custom.css") |
| 52 | + with |
| 53 | + | exn -> traceImportant <| sprintf "Could not copy stylesheet: %s" exn.Message |
| 54 | + |
| 55 | +let copyPics() = |
| 56 | + try |
| 57 | + CopyDir (outDir @@ "images") (slidesDir @@ "images") (fun f -> true) |
| 58 | + with |
| 59 | + | exn -> traceImportant <| sprintf "Could not copy picture: %s" exn.Message |
| 60 | + |
| 61 | +let generateFor (file:FileInfo) = |
| 62 | + try |
| 63 | + copyPics() |
| 64 | + let rec tryGenerate trials = |
| 65 | + try |
| 66 | + FsReveal.GenerateFromFile(file.FullName, outDir, fsiEvaluator = fsiEvaluator) |
| 67 | + with |
| 68 | + | exn when trials > 0 -> tryGenerate (trials - 1) |
| 69 | + | exn -> |
| 70 | + traceImportant <| sprintf "Could not generate slides for: %s" file.FullName |
| 71 | + traceImportant exn.Message |
| 72 | + |
| 73 | + tryGenerate 3 |
| 74 | + |
| 75 | + copyStylesheet() |
| 76 | + with |
| 77 | + | :? FileNotFoundException as exn -> |
| 78 | + traceImportant <| sprintf "Could not copy file: %s" exn.FileName |
| 79 | + |
| 80 | +let handleWatcherEvents (events:FileChange seq) = |
| 81 | + for e in events do |
| 82 | + let fi = fileInfo e.FullPath |
| 83 | + traceImportant <| sprintf "%s was changed." fi.Name |
| 84 | + match fi.Attributes.HasFlag FileAttributes.Hidden || fi.Attributes.HasFlag FileAttributes.Directory with |
| 85 | + | true -> () |
| 86 | + | _ -> generateFor fi |
| 87 | + |
| 88 | +let startWebServer () = |
| 89 | + let serverConfig = |
| 90 | + { defaultConfig with |
| 91 | + homeFolder = Some (FullName outDir) |
| 92 | + } |
| 93 | + let app = |
| 94 | + Writers.setHeader "Cache-Control" "no-cache, no-store, must-revalidate" |
| 95 | + >>= Writers.setHeader "Pragma" "no-cache" |
| 96 | + >>= Writers.setHeader "Expires" "0" |
| 97 | + >>= browseHome |
| 98 | + startWebServerAsync serverConfig app |> snd |> Async.Start |
| 99 | + Process.Start "http://localhost:8083/index.html" |> ignore |
| 100 | + |
| 101 | +Target "GenerateSlides" (fun _ -> |
| 102 | + !! (slidesDir @@ "*.md") |
| 103 | + ++ (slidesDir @@ "*.fsx") |
| 104 | + |> Seq.map fileInfo |
| 105 | + |> Seq.iter generateFor |
| 106 | +) |
| 107 | + |
| 108 | +Target "KeepRunning" (fun _ -> |
| 109 | + use watcher = !! (slidesDir + "/**/*.*") |> WatchChanges (fun changes -> |
| 110 | + handleWatcherEvents changes |
| 111 | + ) |
| 112 | + |
| 113 | + startWebServer () |
| 114 | + |
| 115 | + traceImportant "Waiting for slide edits. Press any key to stop." |
| 116 | + |
| 117 | + System.Console.ReadKey() |> ignore |
| 118 | + |
| 119 | + watcher.Dispose() |
| 120 | +) |
| 121 | + |
| 122 | +Target "SetReleaseTemplate" (fun _ -> |
| 123 | + let templateFile = __SOURCE_DIRECTORY__ @@ "shared" @@ "template.html" |
| 124 | + FsRevealHelper.TemplateFile <- templateFile |
| 125 | +) |
| 126 | + |
| 127 | +Target "ReleaseSlides" (fun _ -> |
| 128 | + if gitOwner = "myGitUser" || gitProjectName = "MyProject" then |
| 129 | + failwith "You need to specify the gitOwner and gitProjectName in build.fsx" |
| 130 | + |
| 131 | + DeleteDir ghPagesDir |
| 132 | + |
| 133 | + Repository.cloneSingleBranch "" (gitHome + "/" + gitProjectName + ".git") "gh-pages" ghPagesDir |
| 134 | + |
| 135 | + let outputImagesDir = outDir @@ "images" |
| 136 | + let publishImagesDir = publishDir @@ "images" |
| 137 | + if TestDir outputImagesDir then |
| 138 | + CreateDir publishImagesDir |
| 139 | + CleanDir publishImagesDir |
| 140 | + CopyRecursive outputImagesDir publishImagesDir true |> tracefn "%A" |
| 141 | + |
| 142 | + CopyFile publishDir (outDir @@ "index.html") |> tracefn "%A" |
| 143 | + |
| 144 | + StageAll ghPagesDir |
| 145 | + Git.Commit.Commit ghPagesDir (sprintf "Update generated slides for %s" topic) |
| 146 | + Branches.push ghPagesDir |
| 147 | +) |
| 148 | + |
| 149 | + |
| 150 | + |
| 151 | +"Clean" |
| 152 | + ==> "GenerateSlides" |
| 153 | + ==> "KeepRunning" |
| 154 | + |
| 155 | +"SetReleaseTemplate" |
| 156 | + <=> "GenerateSlides" |
| 157 | + ==> "ReleaseSlides" |
| 158 | + |
| 159 | +RunTargetOrDefault "KeepRunning" |
0 commit comments