diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index cadd1a0..698e8f8 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -20,6 +20,9 @@ on: push: branches: - main + pull_request: + branches: + - main jobs: ubuntu-latest: diff --git a/CHANGELOG.md b/CHANGELOG.md index b4fc45b..8195aed 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Added + +- Added import keyword to import templates into other templates +- Added 'Template.Parse()' method +- Added 'Template.ParseFromLines()' method + ### Changed - Log error instead of warning when a template file is not found diff --git a/build/Build.cs b/build/Build.cs index 02e561d..0086db4 100644 --- a/build/Build.cs +++ b/build/Build.cs @@ -22,6 +22,7 @@ [GitHubActions("tests", GitHubActionsImage.UbuntuLatest, OnPushBranches = new[] { "main" }, + OnPullRequestBranches = new[] { "main" }, InvokedTargets = new[] { nameof(Test) }, PublishCondition = "always()", EnableGitHubToken = true, diff --git a/build/build.csproj.DotSettings b/build/build.csproj.DotSettings index eb3f4c2..88a8824 100644 --- a/build/build.csproj.DotSettings +++ b/build/build.csproj.DotSettings @@ -17,6 +17,8 @@ False <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> + <Policy><Descriptor Staticness="Instance" AccessRightKinds="Private" Description="Instance fields (private)"><ElementKinds><Kind Name="FIELD" /><Kind Name="READONLY_FIELD" /></ElementKinds></Descriptor><Policy Inspect="True" WarnAboutPrefixesAndSuffixes="False" Prefix="" Suffix="" Style="AaBb" /></Policy> + <Policy><Descriptor Staticness="Static" AccessRightKinds="Private" Description="Static fields (private)"><ElementKinds><Kind Name="FIELD" /></ElementKinds></Descriptor><Policy Inspect="True" WarnAboutPrefixesAndSuffixes="False" Prefix="" Suffix="" Style="AaBb" /></Policy> True True True @@ -25,4 +27,5 @@ True True True - True + True + True diff --git a/src/Assets/SimpleCodeGenerator/Editor/IntermediateTemplate.cs b/src/Assets/SimpleCodeGenerator/Editor/IntermediateTemplate.cs index 30855ff..1f44e22 100644 --- a/src/Assets/SimpleCodeGenerator/Editor/IntermediateTemplate.cs +++ b/src/Assets/SimpleCodeGenerator/Editor/IntermediateTemplate.cs @@ -18,6 +18,18 @@ public IntermediateTemplate(IEnumerable template, object data) content = new List(template); } + public IntermediateTemplate RenderImports() + { + var result = new IntermediateTemplate(content, data); + + for (int i = 0; i < result.content.Count; i++) + { + result.content[i] = InsertImportedTemplates(result.content[i]); + } + + return result; + } + public IntermediateTemplate RenderStandaloneValues() { var result = new IntermediateTemplate(content, data); @@ -82,6 +94,23 @@ public IntermediateTemplate RenderForLoops() return result; } + private static string InsertImportedTemplates(string input) + { + while (true) + { + Match importMatch = Regex.Match(input, @"\{\{\s*import\s+(?\S+)\s*\}\}"); + + if (!importMatch.Success) + break; + + string templateName = importMatch.Groups["templateName"].Value; + + // TODO + } + + return input; + } + private static string InsertValuesFromObject(string input, object objectToInsert, string propertyRootPath = "") { while (true) diff --git a/src/Assets/SimpleCodeGenerator/Editor/Template.cs b/src/Assets/SimpleCodeGenerator/Editor/Template.cs index e45e17f..42c68d1 100644 --- a/src/Assets/SimpleCodeGenerator/Editor/Template.cs +++ b/src/Assets/SimpleCodeGenerator/Editor/Template.cs @@ -1,4 +1,7 @@ -using System.IO; +using System; +using System.Collections.Generic; +using System.IO; +using JetBrains.Annotations; using SimpleCodeGenerator.Core; using UnityEditor; using UnityEngine; @@ -8,20 +11,36 @@ namespace SimpleCodeGenerator.Editor public class Template { private readonly string[] content; + private readonly Dictionary importedTemplates = new(); private Template(string[] content) { this.content = content; } + [PublicAPI] public static Template ParseFromFile(string path) { return new Template(File.ReadAllLines(path)); } + [PublicAPI] + public static Template ParseFromLines(string[] lines) + { + return new Template(lines); + } + + [PublicAPI] + public static Template Parse(string contentWithLineBreaks) + { + return ParseFromLines(contentWithLineBreaks.Split(new[] { "\r\n", "\r", "\n" }, StringSplitOptions.None)); + } + + [PublicAPI] public string Render(object data) { return new IntermediateTemplate(content, data) + .RenderImports() .RenderStandaloneValues() .RenderForLoops() .Build(); @@ -32,6 +51,7 @@ internal static Template FindBuiltInTemplate(string templateName) return ParseFromFile(GetAbsolutePathToBuiltInTemplate(templateName)); } + [PublicAPI] public static bool TryFindTemplateInAssets(string templateAssetPath, out Template template) { if (!templateAssetPath.StartsWith("Assets/")) @@ -59,5 +79,12 @@ internal static AbsolutePath GetAbsolutePathToBuiltInTemplate(string templateNam { return GetPathToBuiltInTemplates() / $"{templateName}.txt"; } + + [PublicAPI] + public Template Import(string key, Template template) + { + importedTemplates.Add(key, template); + return this; + } } } \ No newline at end of file diff --git a/tests/TemplateTests.cs b/tests/TemplateTests.cs index a4f5913..a737741 100644 --- a/tests/TemplateTests.cs +++ b/tests/TemplateTests.cs @@ -7,6 +7,8 @@ namespace tests; public class TemplateTests { private const string TemplateFile1 = "Templates/Test_Template_1.txt"; + private const string TemplateFileImport = "Templates/Test_Template_Import.txt"; + private const string TemplateFileImportPartial = "Templates/Test_Template_Import_Partial.txt"; private const string StringDictionaryTemplateFile = "Templates/StringDictionary.txt"; private const string EnumTemplateFile = "Templates/Enum.txt"; @@ -83,4 +85,24 @@ public Task Render_RenderValidTemplate2_TemplateIsRenderedCorrectly() settings.UseDirectory("Verify"); return Verify(result, settings); } + + [Fact] + public Task Render_TemplateWithImportedTemplate_TemplateIsRenderedCorrectly() + { + Template template = Template.ParseFromFile(TemplateFileImport); + template.Import("Template_To_Import", Template.ParseFromFile(TemplateFileImportPartial)); + template.Import("This_Can_Be_Any_Key", Template.Parse("1234567890")); + + var data = new + { + Template = "Import", + SomeNumbers = new[] { 1, 2, 3, 4, 5 } + }; + + string result = template.Render(data); + + var settings = new VerifySettings(); + settings.UseDirectory("Verify"); + return Verify(result, settings); + } } \ No newline at end of file diff --git a/tests/Templates/Test_Template_Import.txt b/tests/Templates/Test_Template_Import.txt new file mode 100644 index 0000000..e7bc6d3 --- /dev/null +++ b/tests/Templates/Test_Template_Import.txt @@ -0,0 +1,10 @@ +{{ import "Template_To_Import" }} + +// Test Template {{ Template }} with imported template + +{{ import "Template_To_Import" }} +{{ import "This_Can_Be_Any_Key" }} + +{{ for number in SomeNumbers }} +// {{ number }} +{{ end }} \ No newline at end of file diff --git a/tests/Templates/Test_Template_Import_Partial.txt b/tests/Templates/Test_Template_Import_Partial.txt new file mode 100644 index 0000000..c4f7624 --- /dev/null +++ b/tests/Templates/Test_Template_Import_Partial.txt @@ -0,0 +1,7 @@ +// This is text from a partial template +// And this is more text from a partial template with a variable: {{ Variable }} + +// Let's also add a list of strings to the template +{{ for item in Strings }} +// {{ item }} +{{ end }} \ No newline at end of file diff --git a/tests/Verify/TemplateTests.Render_TemplateWithImportedTemplate_TemplateIsRenderedCorrectly.verified.txt b/tests/Verify/TemplateTests.Render_TemplateWithImportedTemplate_TemplateIsRenderedCorrectly.verified.txt new file mode 100644 index 0000000..abd2488 --- /dev/null +++ b/tests/Verify/TemplateTests.Render_TemplateWithImportedTemplate_TemplateIsRenderedCorrectly.verified.txt @@ -0,0 +1,24 @@ +// This is text from a partial template +// And this is more text from a partial template with a variable: this is a string + +// Let's also add a list of strings to the template +// hello +// world +// ! + +// Test Template Import with imported template + +// This is text from a partial template +// And this is more text from a partial template with a variable: this is a string + +// Let's also add a list of strings to the template +// hello +// world +// ! +1234567890 + +// 1 +// 2 +// 3 +// 4 +// 5 \ No newline at end of file