Open
Description
Describe the bug
To Reproduce
Steps to reproduce the behaviour:
- Start
dotnet fornax watch
- Wait for the first generation
- Change the content of one of the file
- See that the new generated file still have the old content
- Change the content of one of the file
- See that the new generated file is now using the correct content
- Change the content of one of the file
- See that the new generated file is now using the correct content
- etc. (From now, the generation will always be correct)
Expected behaviour
The file should always used the last loaded information even on the first change.
Screenshots
First generation (all good)
Loader and generator have the same informations
==== POST LOADER =====
"---
layout: post
title: Some nice post title
author: k_cieslak
published: 2020-02-19
tags: [ 'F#', 'blog']
---
# Introduction
First
"
==== POST GENERATOR =====
"# Introduction
First
"
[22:10:56] '/home/mmangel/Workspaces/GitHub/MangelMaxime/mangelmaxime.github.io/_public/posts/first.html' generated in 58ms
Generation time: 00:00:04.6666586
[22:10:56] Watch mode started. Press any key to exit.
[22:10:56 INF] Smooth! Suave listener started in 32.428ms with binding 127.0.0.1:8080
Second generation (not good) : first time user update a file
Loader is using the new file content while the generator still received the old informations.
[22:11:11] Changes detected: /home/mmangel/Workspaces/GitHub/MangelMaxime/mangelmaxime.github.io/posts/first.md
==== POST LOADER =====
"---
layout: post
title: Some nice post title
author: k_cieslak
published: 2020-02-19
tags: [ 'F#', 'blog']
---
# Introduction
File is updated
"
==== POST GENERATOR =====
"# Introduction
First
"
[22:11:12] '/home/mmangel/Workspaces/GitHub/MangelMaxime/mangelmaxime.github.io/_public/posts/first.html' generated in 0ms
Generation time: 00:00:00.7931652
Third and more generation (all good)
Loader and generator have the same informations
[22:12:07] Changes detected: /home/mmangel/Workspaces/GitHub/MangelMaxime/mangelmaxime.github.io/posts/first.md
==== POST LOADER =====
"---
layout: post
title: Some nice post title
author: k_cieslak
published: 2020-02-19
tags: [ 'F#', 'blog']
---
# Introduction
File is updated 2
"
==== POST GENERATOR =====
"# Introduction
File is updated 2
"
[22:12:08] '/home/mmangel/Workspaces/GitHub/MangelMaxime/mangelmaxime.github.io/_public/posts/first.html' generated in 49ms
Generation time: 00:00:01.0151255
Could it be caused by a cache mechanism?
Postloader.fsx
#r "../_lib/Fornax.Core.dll"
#load "../.paket/load/main.group.fsx"
#load "../utils/Log.fsx"
#load "../utils/Helpers.fsx"
open System
open System.IO
open System.Diagnostics
open System.Threading.Tasks
open Legivel.Serialization
open Helpers
type Post =
{
relativeFile: string
link : string
title: string
author: string option
published: DateTime option
tags: string list
content: string
}
type PostFrontMatter =
{
title: string
author: string option
published: DateTime option
tags: string list
}
let contentDir = "posts"
let private getLastModified (fileName: string) =
async {
let psi = ProcessStartInfo()
psi.FileName <- "git"
psi.Arguments <- $"--no-pager log -1 --format=%%ai \"%s{fileName}\""
psi.RedirectStandardError <- true
psi.RedirectStandardOutput <- true
psi.CreateNoWindow <- true
psi.WindowStyle <- ProcessWindowStyle.Hidden
psi.UseShellExecute <- false
use p = new Process()
p.StartInfo <- psi
p.Start() |> ignore
let outTask =
Task.WhenAll(
[|
p.StandardOutput.ReadToEndAsync()
p.StandardError.ReadToEndAsync()
|]
)
do! p.WaitForExitAsync() |> Async.AwaitTask
let! result = outTask |> Async.AwaitTask
if p.ExitCode = 0 then
// File is not in the git repo
if String.IsNullOrEmpty result[0] then
return DateTime.Now
else
return DateTime.Parse(result[0])
else
Log.error $"Failed to get last modified information %s{result[1]}"
return DateTime.Now
}
|> Async.RunSynchronously
let private loadFile (rootDir: string) (absolutePath: string) =
let text = File.ReadAllText absolutePath
printfn "==== POST LOADER ====="
printfn "%A" text
let relativePath =
Path.relativePath rootDir absolutePath
let lines = text.Replace("\r\n", "\n").Split("\n")
let x = getLastModified absolutePath
let firstLine = Array.tryHead lines
if firstLine <> Some "---" then
Log.error $"File '%s{relativePath}' does not have a front matter"
None
else
let lines = lines |> Array.skip 1
let frontMatterLines =
lines
|> Array.takeWhile (fun line -> line <> "---")
let markdownContent =
lines
|> Array.skip (frontMatterLines.Length + 1)
|> String.concat "\n"
let frontMatterContent = frontMatterLines |> String.concat "\n"
let frontMatterResult =
Deserialize<PostFrontMatter> frontMatterContent
|> List.head
match frontMatterResult with
| Error error ->
Log.error $"Error parsing front matter in file '%s{relativePath}': %A{error}"
None
| Success frontMatter ->
if not (frontMatter.Warn.IsEmpty) then
for warning in frontMatter.Warn do
Log.warn $"Warning in file '%s{relativePath}': %A{warning}"
let link =
Path.ChangeExtension(relativePath, "html")
{
relativeFile = relativePath
link = link
title = ""
author = None
published = frontMatter.Data.published
tags = frontMatter.Data.tags
content = markdownContent
}
|> Some
let loader (projectRoot: string) (siteContent: SiteContents) =
let postsPath = Path.Combine(projectRoot, contentDir)
let options = EnumerationOptions(RecurseSubdirectories = true)
let files = Directory.GetFiles(postsPath, "*", options)
files
|> Array.filter (fun n -> n.EndsWith ".md")
|> Array.map (loadFile projectRoot)
// Only keep the valid post to avoid to propagate errors
|> Array.filter Option.isSome
|> Array.map Option.get
|> Array.iter siteContent.Add
siteContent
Postloader.fsx
#r "../_lib/Fornax.Core.dll"
#load "layout.fsx"
open Giraffe.ViewEngine
let generate (ctx: SiteContents) (_projectRoot: string) (page: string) =
let postOpt =
ctx.TryGetValues<PostLoader.Post>()
|> Option.defaultValue Seq.empty
|> Seq.tryFind (fun post -> post.relativeFile = page)
match postOpt with
| None ->
let error =
{
Path = page
Message = $"Post %s{page} not found in the context"
Phase = Generating
}
ctx.AddError error
Layout.generationErrorPage ctx
| Some post ->
printfn "==== POST GENERATOR ====="
printfn "%A" post.content
div [] [ str post.content ] |> Layout.mainPage ctx
Activity