statiqdev / Statiq.Web

Statiq Web is a flexible static site generator written in .NET.
https://statiq.dev/web
Other
1.64k stars 234 forks source link

Strict run and add document metadata in runtime #1011

Open ruslan-mogilevskiy opened 1 year ago

ruslan-mogilevskiy commented 1 year ago

Hi @daveaglick,

First of all, thanks for the cool engine for static sites. Playing with it for a while and it looks very promising. Could you please guide me in the following questions:

1) I've enabled Strict mode for the bootstrapper:

Bootstrapper.Factory.CreateWeb(args)
   .AddSetting(WebKeys.Strict, true)

and according to the documentation I expected that Statiq will throw an exception in runtime or at least stop/exit when some error occurred but it didn't. By the error, I mean smth like an invalid LESS file content (thrown by dotless), etc. but Statiq just logged the error in the control when started and that's all. Q: How to terminate Statiq with a not-0 exit error code when something has failed on start?

2) Is it possible to add custom metadata to a document in run-time (in the pipeline code, etc)? I see that the document inherits IMetadata which is read-only. My goal is to add the metadata in one of my pipelines and process it in another.

Thanks.

daveaglick commented 1 year ago

How to terminate Statiq with a not-0 exit error code when something has failed on start?

It should already be doing this. It'll try to continue processing files within certain modules that run concurrently if it can, that way you don't have to play whack-a-mole by fixing one file, running, fixing the next error, running, fixing the next error, running, etc. If you can see all the errors from a given module like Razor at once, it's a lot faster to fix things. But then at the end, if any errors/exceptions were logged, it'll exit with a non-zero exit code. I've got lots of CI code that runs Statiq and relies on this behavior, is it not doing that for you?

I've enabled Strict mode for the bootstrapper

It actually looks like "strict mode" is a holdover from Wyam code and isn't used in Statiq at all. In general, Statiq should be behaving as if it were in "strict mode" all the time. There is a FailureLogLevel setting you can set which is probably what Strict used to do, but provides more control. Try setting this:

Bootstrapper.Factory.CreateWeb(args)
   .AddSetting(Keys.FailureLogLevel, LogLevel.Warning)

Is it possible to add custom metadata to a document in run-time (in the pipeline code, etc)?

Absolutely - if writing a custom module, there are a series of extensions that can do this. A document is immutable, so you create a new document, passing any additional metadata you want, and the original is cloned with that new metadata. The CreateDocument() extensions exist for both the IExecutionContext and IDocument to make them easy to find.

There's a bunch of ways to write your own module code, from creating a whole module to doing something like this using the ExecuteConfig module:

await Bootstrapper.Factory
    .CreateWeb(args)
    .BuildPipeline(
        "MyPipeline",
        builder => builder.WithProcessModules(
            new ReadFiles("*.foo"),
            new ExecuteConfig(
                Config.FromDocument((ctx, doc) =>
                    doc.CreateDocument(new MetadataItems
                    {
                        { "Foo", "Bar" }
                    })))))

You don't even need to go that far though if you just want to add some metadata during the pipeline - the SetMetadata module has your back:

await Bootstrapper.Factory
    .CreateWeb(args)
    .BuildPipeline(
        "MyPipeline",
        builder => builder.WithProcessModules(
            new ReadFiles("*.foo"),
            new SetMetadata("Foo", Config.FromDocument(doc => "Bar")))