Skip to content

Commit d866b9c

Browse files
committed
Added initial cut
0 parents  commit d866b9c

21 files changed

+474
-0
lines changed

.gitattributes

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Disable LF normalization for all files
2+
* -text

.gitignore

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
obj
2+
bin
3+
_ReSharper.*
4+
*.user
5+
*.ReSharper
6+
*.TeamCity.user
7+
*.suo
8+
~$*
9+
*~
10+
*.log
11+
packages
12+
*.received.*
13+
.vs
14+
*.nupkg

MSBuildRazorCompiler.sln

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
2+
Microsoft Visual Studio Solution File, Format Version 12.00
3+
# Visual Studio Version 16
4+
VisualStudioVersion = 16.0.29806.167
5+
MinimumVisualStudioVersion = 10.0.40219.1
6+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MSBuildRazorCompiler", "MSBuildRazorCompiler\MSBuildRazorCompiler.csproj", "{B6E0F478-239F-41DD-9808-00E3F6C72061}"
7+
EndProject
8+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Test", "Test\Test.csproj", "{9AE93D01-82DC-444F-9B00-997A52C43EA1}"
9+
EndProject
10+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RazorRenderer", "RazorRenderer\RazorRenderer.csproj", "{24E7F601-6B61-4C07-95A8-F52A6937BF3A}"
11+
EndProject
12+
Global
13+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
14+
Debug|Any CPU = Debug|Any CPU
15+
Release|Any CPU = Release|Any CPU
16+
EndGlobalSection
17+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
18+
{B6E0F478-239F-41DD-9808-00E3F6C72061}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
19+
{B6E0F478-239F-41DD-9808-00E3F6C72061}.Debug|Any CPU.Build.0 = Debug|Any CPU
20+
{B6E0F478-239F-41DD-9808-00E3F6C72061}.Release|Any CPU.ActiveCfg = Release|Any CPU
21+
{B6E0F478-239F-41DD-9808-00E3F6C72061}.Release|Any CPU.Build.0 = Release|Any CPU
22+
{9AE93D01-82DC-444F-9B00-997A52C43EA1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
23+
{9AE93D01-82DC-444F-9B00-997A52C43EA1}.Debug|Any CPU.Build.0 = Debug|Any CPU
24+
{9AE93D01-82DC-444F-9B00-997A52C43EA1}.Release|Any CPU.ActiveCfg = Release|Any CPU
25+
{9AE93D01-82DC-444F-9B00-997A52C43EA1}.Release|Any CPU.Build.0 = Release|Any CPU
26+
{24E7F601-6B61-4C07-95A8-F52A6937BF3A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
27+
{24E7F601-6B61-4C07-95A8-F52A6937BF3A}.Debug|Any CPU.Build.0 = Debug|Any CPU
28+
{24E7F601-6B61-4C07-95A8-F52A6937BF3A}.Release|Any CPU.ActiveCfg = Release|Any CPU
29+
{24E7F601-6B61-4C07-95A8-F52A6937BF3A}.Release|Any CPU.Build.0 = Release|Any CPU
30+
EndGlobalSection
31+
GlobalSection(SolutionProperties) = preSolution
32+
HideSolutionNode = FALSE
33+
EndGlobalSection
34+
GlobalSection(ExtensibilityGlobals) = postSolution
35+
SolutionGuid = {BEB06A00-8640-4E88-84AA-961FF23F8EA6}
36+
EndGlobalSection
37+
EndGlobal
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFramework>netcoreapp3.1</TargetFramework>
6+
</PropertyGroup>
7+
8+
<ItemGroup>
9+
<PackageReference Include="RazorLight" Version="2.0.0-beta7" />
10+
</ItemGroup>
11+
12+
</Project>

MSBuildRazorCompiler/Program.cs

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
using System;
2+
using System.IO;
3+
using System.Reflection;
4+
using System.Text;
5+
using System.Text.RegularExpressions;
6+
using RazorLight;
7+
using RazorLight.Generation;
8+
9+
namespace MSBuildRazorCompiler
10+
{
11+
class Program
12+
{
13+
private static readonly Regex LeadingSlash = new Regex(@"^[\\/]", RegexOptions.Compiled);
14+
15+
static int Main(string[] args)
16+
{
17+
var directoryToApply = args.Length > 0 ? args[0] : null;
18+
var rootNamespace = args.Length > 1 ? args[1] : null;
19+
20+
if (string.IsNullOrEmpty(directoryToApply) || !Directory.Exists(directoryToApply) || !Path.IsPathFullyQualified(directoryToApply))
21+
{
22+
Console.Error.WriteLine($"Invalid directory passed in as commandline argument: {directoryToApply}");
23+
return 1;
24+
}
25+
26+
if (string.IsNullOrEmpty(rootNamespace))
27+
{
28+
Console.Error.WriteLine($"Invalid namespace passed in as commandline argument: {rootNamespace}");
29+
}
30+
31+
var engine = new RazorLightEngineBuilder()
32+
.UseFileSystemProject(directoryToApply, ".cshtml")
33+
.Build();
34+
35+
// todo: submit PR to RazorGenerator to remove the need for reflection
36+
var sourceGenerator = (RazorSourceGenerator)(engine.Handler.Compiler.GetType()
37+
.GetField("_razorSourceGenerator", BindingFlags.Instance | BindingFlags.NonPublic)
38+
.GetValue(engine.Handler.Compiler));
39+
40+
foreach(var file in Directory.EnumerateFiles(directoryToApply, "*.cshtml", SearchOption.AllDirectories))
41+
{
42+
Console.WriteLine($"Processing {file}...");
43+
44+
var itemKey = LeadingSlash.Replace(file.Replace(directoryToApply, ""), "");
45+
var source = sourceGenerator.GenerateCodeAsync(itemKey).GetAwaiter().GetResult();
46+
47+
var (namespacePath, className) = GetNamespaceAndClassName(itemKey, rootNamespace);
48+
Console.WriteLine($" Classname will be `{className}` and namespace will be `{namespacePath}`");
49+
50+
var code = source.GeneratedCode
51+
.Replace("public class GeneratedTemplate", $"public class {className}")
52+
.Replace("namespace RazorLight.CompiledTemplates", $"namespace {namespacePath}")
53+
.Replace("typeof(RazorLight.CompiledTemplates.GeneratedTemplate)", $"typeof({namespacePath}.{className})");
54+
55+
Console.WriteLine($" Writing {file}.generated.cs");
56+
File.WriteAllText(file + ".generated.cs", code, Encoding.UTF8);
57+
}
58+
59+
return 0;
60+
}
61+
62+
// todo: implement this as a Razor Feature (as pe https://github.com/toddams/RazorLight/blob/master/src/RazorLight/DefaultRazorEngine.cs)
63+
private static (string, string) GetNamespaceAndClassName(string itemKey, string rootNamespace)
64+
{
65+
var finalSlash = itemKey.LastIndexOf(Path.DirectorySeparatorChar);
66+
var className = "";
67+
var namespacePath = "";
68+
if (finalSlash > -1)
69+
{
70+
className = itemKey.Substring(finalSlash + 1).Replace(".cshtml", "");
71+
namespacePath = rootNamespace + "." + itemKey.Substring(0, finalSlash).Replace(Path.DirectorySeparatorChar, '.');
72+
}
73+
else
74+
{
75+
className = itemKey.Replace(".cshtml", "");
76+
namespacePath = rootNamespace;
77+
}
78+
className = className[0].ToString().ToUpper() + className.Substring(1);
79+
80+
return (namespacePath, className);
81+
}
82+
}
83+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"profiles": {
3+
"MSBuildRazorCompiler": {
4+
"commandName": "Project",
5+
"commandLineArgs": "c:\\dev\\oss\\MSBuildRazorCompiler\\Test Test"
6+
}
7+
}
8+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
using System;
2+
using System.Threading.Tasks;
3+
using RazorLight.Compilation;
4+
5+
namespace RazorRenderer
6+
{
7+
internal class NullRazorTemplateCompiler : IRazorTemplateCompiler
8+
{
9+
public Task<CompiledTemplateDescriptor> CompileAsync(string templateKey)
10+
{
11+
throw new NotImplementedException();
12+
}
13+
14+
public ICompilationService CompilationService { get; }
15+
}
16+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
using System;
2+
using RazorLight;
3+
using RazorLight.Compilation;
4+
5+
namespace RazorRenderer
6+
{
7+
internal class NullTemplateFactoryProvider : ITemplateFactoryProvider
8+
{
9+
public Func<ITemplatePage> CreateFactory(CompiledTemplateDescriptor templateDescriptor)
10+
{
11+
throw new NotImplementedException();
12+
}
13+
}
14+
}

RazorRenderer/RazorRenderer.csproj

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>netcoreapp3.1</TargetFramework>
5+
</PropertyGroup>
6+
7+
<ItemGroup>
8+
<PackageReference Include="RazorLight" Version="2.0.0-beta7" />
9+
</ItemGroup>
10+
11+
</Project>
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
using System.Dynamic;
2+
using System.Threading.Tasks;
3+
using Microsoft.AspNetCore.Html;
4+
using RazorLight;
5+
6+
namespace RazorRenderer
7+
{
8+
public static class TemplateFileExtensions
9+
{
10+
public static IHtmlContent Render<TModel>(this ITemplatePage template, TModel model, ExpandoObject viewBag = null)
11+
{
12+
return RenderAsync(template, model, viewBag).GetAwaiter().GetResult();
13+
}
14+
15+
public static async Task<IHtmlContent> RenderAsync<TModel>(this ITemplatePage template, TModel model, ExpandoObject viewBag = null)
16+
{
17+
var content = await TemplateFileRenderer.RenderTemplateAsync(template, model, viewBag ?? new ExpandoObject()).ConfigureAwait(false);
18+
return new HtmlString(content);
19+
}
20+
}
21+
}

0 commit comments

Comments
 (0)