Nuke.Unreal
Build Unreal apps in Style.
Loading...
Searching...
No Matches
BoilerplateGenerator.cs
1using System;
2using System.Linq;
3using System.Reflection;
4using System.IO;
5using Nuke.Common;
6using Nuke.Common.IO;
7using Scriban;
8using Serilog;
9
11{
13 {
14 public static AbsolutePath DefaultTemplateFolder => BuildCommon.GetContentsFolder() / "Templates";
15
16 protected static void CheckErrors(Template template)
17 {
18 if(!template.HasErrors) return;
19 throw new ScribanParseException(template);
20 }
21
22 /// <summary>
23 /// Render a file from a scriban template.
24 /// </summary>
25 /// <param name="templateRoot"></param>
26 /// <param name="source"></param>
27 /// <param name="destinationFolder"></param>
28 /// <param name="model"></param>
29 protected static void RenderFile(AbsolutePath templateRoot, RelativePath source, AbsolutePath destinationFolder, object model)
30 {
31 var relFileTemplate = Template.Parse(source, templateRoot / source);
32 CheckErrors(relFileTemplate);
33
34 var textTemplate = Template.Parse(File.ReadAllText(templateRoot / source), templateRoot / source);
35 CheckErrors(textTemplate);
36
37 var renderedRelFilePath = relFileTemplate.Render(model);
38 var renderedText = textTemplate.Render(model);
39
40 var resultPath = destinationFolder / renderedRelFilePath;
41 var resultFilename = Path.GetFileNameWithoutExtension(resultPath);
42 var resultExt = Path.GetExtension(resultPath).Replace("sbn", "");
43
44 if(!Directory.Exists(resultPath.Parent))
45 Directory.CreateDirectory(resultPath.Parent);
46
47 resultFilename = (resultFilename + resultExt).Replace("___", "");
48
49 var outPath = resultPath.Parent / resultFilename;
50
51 Log.Debug($"Rendering to: {resultFilename}");
52
53 File.WriteAllText(outPath, renderedText);
54 }
55
56 /// <summary>
57 /// Render scriban templated scaffoldings and files to destination folder.
58 /// </summary>
59 /// <param name="templateRoot"></param>
60 /// <param name="destinationFolder"></param>
61 /// <param name="model"></param>
62 /// <param name="currentFolder">This is != the current Working Directory! It should be only used by subsequent recursive function calls</param>
63 protected static void RenderFolder(AbsolutePath templateRoot, AbsolutePath destinationFolder, object model, AbsolutePath? currentFolder = null)
64 {
65 currentFolder ??= templateRoot;
66 foreach(var file in Directory.EnumerateFiles(currentFolder))
67 {
68 var relPath = (RelativePath) Path.GetRelativePath(templateRoot, file);
69 RenderFile(templateRoot, relPath, destinationFolder, model);
70 }
71
72 foreach(var dir in Directory.EnumerateDirectories(currentFolder))
73 {
74 RenderFolder(templateRoot, destinationFolder, model, (AbsolutePath) dir);
75 }
76 }
77 }
78
79 public record CommonModelBase(string Name, string? Copyright);
80
81 public class ScribanParseException : Exception
82 {
83 public ScribanParseException(Template template) : base(GetMessage(template))
84 {
85 }
86
87 private static string GetMessage(Template template)
88 {
89 var nl = Environment.NewLine;
90 var errors = string.Join(nl + " ", template.Messages.Select(m => m.ToString()));
91 return
92 $"""
93 Parsing scriban template threw an error:
94 at {template.SourceFilePath}:
95 {errors}
96 """;
97 }
98 }
99}
static void RenderFile(AbsolutePath templateRoot, RelativePath source, AbsolutePath destinationFolder, object model)
Render a file from a scriban template.
static void RenderFolder(AbsolutePath templateRoot, AbsolutePath destinationFolder, object model, AbsolutePath? currentFolder=null)
Render scriban templated scaffoldings and files to destination folder.
Extra build related utilities not necessarily associated with Unreal tasks.
static AbsolutePath GetContentsFolder()
Get the contents folder Nuke.Unreal is shipped with. This is usually contained in the local nuget ins...