Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rendering constants #37

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ public CSharpScriptCodeGeneratorContext(ConfigurationCodeGenerationMetadata meta

public IReadOnlyCollection<TemplateCodeGenerationMetadata> Templates => _metadata.Metadata;

public IReadOnlyCollection<RenderingCodeGenerationMetadata> Renderings => _metadata.RenderingMetadata;

public string ConfigurationName => _metadata.Configuration.Name;

public string GenericRootNamespace => _metadata.RootNamespace;
Expand Down
31 changes: 31 additions & 0 deletions src/Leprechaun.CodeGen.Roslyn/Scripts/RenderingConstants.csx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Generates Glass Constants File

Log.Debug($"Emitting Rendering constants for {ConfigurationName}...");

public string RenderRenderings()
{
var localCode = new System.Text.StringBuilder();

localCode.Append($@"
public struct Renderings
{{
");

foreach (var rendering in Renderings)
{
localCode.AppendLine($@" public static readonly ID {rendering.CodeName} = new ID(""{rendering.Id}"");");
}

localCode.Append(@"
}");

return localCode.ToString();
}

Code.AppendLine($@"
namespace {GenericRootNamespace}
{{
using global::Sitecore.Data;
{RenderRenderings()}

}}");
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml;
using Leprechaun.Adapters;
using Leprechaun.Filters;
using Leprechaun.InputProviders.Rainbow.Adapters;
using Leprechaun.InputProviders.Rainbow.Filters;
using Leprechaun.Model;
using Leprechaun.RenderingReaders;
using Leprechaun.TemplateReaders;
using Rainbow.Storage;

namespace Leprechaun.InputProviders.Rainbow.RenderingReaders
{
public class DataStoreRenderingReader : IRenderingReader
{
internal static readonly Guid ControllerRenderingTemplateId = new Guid("{2A3E91A0-7987-44B5-AB34-35C2D9DE83B9}");
internal static readonly Guid ViewRenderingTemplateId = new Guid("{99F8905D-4A87-4EB8-9F8B-A9BEBFB3ADD6}");

private IDataStore _dataStore;

public DataStoreRenderingReader(XmlNode configNode, IDataStore dataStore)
{
_dataStore = dataStore;
}

public RenderingInfo[] GetRenderings(ITemplatePredicate predicate)
{
if (predicate is StandardTemplatePredicate standardPredicate)
{
return GetRenderings(standardPredicate.GetRootPaths());
}
return new RenderingInfo[0];
}

public RenderingInfo[] GetRenderings(params TreeRoot[] rootPaths)
{
return rootPaths
.AsParallel()
.SelectMany(root =>
{
var rootItem = _dataStore.GetByPath(root.Path, root.DatabaseName)?.Select(itemData => new RainbowItemDataAdapter(itemData));

if (rootItem == null) return Enumerable.Empty<RenderingInfo>();

// because a path could match more than one item we have to SelectMany again
return rootItem.SelectMany(ParseRenderings);
})
.ToArray();
}

protected virtual IEnumerable<RenderingInfo> ParseRenderings(IItemDataAdapter root)
{
var processQueue = new Queue<IItemDataAdapter>();

processQueue.Enqueue(root);

while (processQueue.Count > 0)
{
var currentTemplate = processQueue.Dequeue();

// if it's a viewrendering or controller rendering we parse it and skip adding children (nested templates not really allowed)
if (currentTemplate.TemplateId == ControllerRenderingTemplateId || currentTemplate.TemplateId == ViewRenderingTemplateId)
{
yield return ParseRendering(currentTemplate);
continue;
}

// it's not a template (e.g. a template folder) so we want to scan its children for templates to parse
var children = currentTemplate.GetChildren();
foreach (var child in children)
{
processQueue.Enqueue(child);
}
}
}

protected virtual RenderingInfo ParseRendering(IItemDataAdapter templateItem)
{
if (templateItem == null) throw new ArgumentException("Template item passed to parse was null", nameof(templateItem));
if (templateItem.TemplateId != ControllerRenderingTemplateId) throw new ArgumentException("Template item passed to parse was not a Template item", nameof(templateItem));

var result = new RenderingInfo()
{
Id = templateItem.Id,
Name = templateItem.Name,
Path = templateItem.Path
};

return result;
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
using Leprechaun.InputProviders;
using Leprechaun.Logging;
using Leprechaun.MetadataGeneration;
using Leprechaun.RenderingReaders;
using Leprechaun.TemplateReaders;
using Leprechaun.Validation;
using Newtonsoft.Json;
Expand Down Expand Up @@ -81,6 +82,7 @@ protected virtual void LoadConfigurations()
configuration.AssertSingleton(typeof(ITemplatePredicate));
configuration.AssertSingleton(typeof(ITypeNameGenerator));
configuration.AssertSingleton(typeof(ITemplateReader));
//configuration.AssertSingleton(typeof(IRenderingReader));
configuration.Assert(typeof(ICodeGenerator));

// register the container with itself. how meta!
Expand Down
6 changes: 3 additions & 3 deletions src/Leprechaun/Filters/BaseTemplatePredicate.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ protected BaseTemplatePredicate(XmlNode configNode, IContainer configuration, st
/// <summary>
/// Checks if a preset includes a given item
/// </summary>
protected virtual bool Includes(ITemplateTreeRoot entry, TemplateInfo itemData)
protected virtual bool Includes(ITemplateTreeRoot entry, IItemInfo itemData)
{
// check for path match
var unescapedPath = entry.Path.Replace(@"\*", "*");
Expand All @@ -41,7 +41,7 @@ protected virtual bool Includes(ITemplateTreeRoot entry, TemplateInfo itemData)
// check excludes
return ExcludeMatches(entry, itemData);
}
protected virtual bool ExcludeMatches(ITemplateTreeRoot entry, TemplateInfo itemData)
protected virtual bool ExcludeMatches(ITemplateTreeRoot entry, IItemInfo itemData)
{
foreach (var exclude in entry.Exclusions)
{
Expand Down Expand Up @@ -76,7 +76,7 @@ protected IList<ITemplateTreeRoot> ParsePreset(XmlNode configuration)
return presets;
}

public virtual bool Includes(TemplateInfo template)
public virtual bool Includes(IItemInfo template)
{
Assert.ArgumentNotNull(template, nameof(template));

Expand Down
2 changes: 1 addition & 1 deletion src/Leprechaun/Filters/ITemplatePredicate.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ namespace Leprechaun.Filters
{
public interface ITemplatePredicate
{
bool Includes(TemplateInfo template);
bool Includes(IItemInfo template);

/// <param name="template">Template to get a root NS for. MAY BE NULL, in which case a general root NS should be returned.</param>
string GetRootNamespace(TemplateInfo template);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,13 @@ public virtual IReadOnlyList<ConfigurationCodeGenerationMetadata> Generate(param
.Select(template => CreateTemplate(nameGenerator, predicate, template))
.OrderBy(template => template.Name, StringComparer.Ordinal)
.ToArray();
var renderings =configuration.Renderings
.Where(rendering => predicate.Includes(rendering))
.Select(rendering => CreateRendering(nameGenerator, predicate, rendering))
.OrderBy(rendering => rendering.Name, StringComparer.Ordinal)
.ToArray();

results.Add(new ConfigurationCodeGenerationMetadata(configuration.Configuration, templates));
results.Add(new ConfigurationCodeGenerationMetadata(configuration.Configuration, templates, renderings));
}

ApplyBaseTemplates(results);
Expand All @@ -42,6 +47,12 @@ protected virtual TemplateCodeGenerationMetadata CreateTemplate(ITypeNameGenerat
return new TemplateCodeGenerationMetadata(template, fullName, predicate.GetRootNamespace(template), fields);
}

protected virtual RenderingCodeGenerationMetadata CreateRendering(ITypeNameGenerator nameGenerator, ITemplatePredicate predicate, RenderingInfo rendering)
{
var fullName = nameGenerator.GetFullTypeName(rendering.Path);
return new RenderingCodeGenerationMetadata(rendering, fullName, predicate.GetRootNamespace(null));
}

protected virtual IEnumerable<TemplateFieldCodeGenerationMetadata> CreateTemplateFields(TemplateInfo template, ITypeNameGenerator nameGenerator)
{
var fields = new List<TemplateFieldCodeGenerationMetadata>(template.OwnFields.Length);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,10 @@ public virtual string ConvertToIdentifier(string name)
if (char.IsDigit(name[0]))
name = "_" + name;

//keep spaces as undescores
name = name.Replace(" ", "_");


// replace invalid chars for an identifier with nothing (removes spaces, etc)
return Regex.Replace(name, "[^a-zA-Z0-9_\\.]+", string.Empty);
}
Expand Down
30 changes: 30 additions & 0 deletions src/Leprechaun/Model/BaseCodeGenerationMetadata.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using System.Diagnostics;

namespace Leprechaun.Model
{
[DebuggerDisplay("{FullTypeName} ({Id})")]
public class BaseCodeGenerationMetadata
{
protected readonly string _fullTypeName;

protected BaseCodeGenerationMetadata(string fullTypeName, string rootNamespace)
{
RootNamespace = rootNamespace;
_fullTypeName = fullTypeName;
}

/// <summary>
/// A unique name for this template, usable as a name for a C# class. e.g. for "Foo Bar" this would be "FooBar"
/// </summary>
public virtual string CodeName => _fullTypeName.Contains(".") ? _fullTypeName.Substring(_fullTypeName.LastIndexOf('.') + 1) : _fullTypeName;

/// <summary>
/// Gets the full type name, qualified by namespace, of this template
/// e.g. RootNamespace.RelativeNamespace.CodeName
/// </summary>
public virtual string FullTypeName => $"{RootNamespace}.{_fullTypeName}";

public virtual string RootNamespace { get; }
}

}
5 changes: 4 additions & 1 deletion src/Leprechaun/Model/ConfigurationCodeGenerationMetadata.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,19 @@ namespace Leprechaun.Model
[DebuggerDisplay("{Configuration.Name}")]
public class ConfigurationCodeGenerationMetadata
{
public ConfigurationCodeGenerationMetadata(IContainer configuration, IReadOnlyCollection<TemplateCodeGenerationMetadata> metadata)
public ConfigurationCodeGenerationMetadata(IContainer configuration, IReadOnlyCollection<TemplateCodeGenerationMetadata> metadata, RenderingCodeGenerationMetadata[] renderings)
{
Configuration = configuration;
Metadata = metadata;
RenderingMetadata = renderings;
}

public IContainer Configuration { get; }

public string RootNamespace => Configuration.Resolve<ITemplatePredicate>().GetRootNamespace(null);

public IReadOnlyCollection<TemplateCodeGenerationMetadata> Metadata { get; }

public IReadOnlyCollection<RenderingCodeGenerationMetadata> RenderingMetadata { get; }
}
}
11 changes: 11 additions & 0 deletions src/Leprechaun/Model/IItemInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using System;

namespace Leprechaun.Model
{
public interface IItemInfo
{
string Path { get; set; }
Guid Id { get; set; }
string Name { get; set; }
}
}
13 changes: 13 additions & 0 deletions src/Leprechaun/Model/ItemInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using System;
using System.Diagnostics;

namespace Leprechaun.Model
{
[DebuggerDisplay("{Path} ({Id})")]
public class ItemInfo : IItemInfo
{
public string Path { get; set; }
public Guid Id { get; set; }
public string Name { get; set; }
}
}
21 changes: 21 additions & 0 deletions src/Leprechaun/Model/RenderingCodeGenerationMetadata.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using System;
using System.Diagnostics;

namespace Leprechaun.Model
{
[DebuggerDisplay("{FullTypeName} ({Id})")]
public class RenderingCodeGenerationMetadata : BaseCodeGenerationMetadata
{

private readonly RenderingInfo _renderingInfo;

public RenderingCodeGenerationMetadata(RenderingInfo renderingInfo, string fullTypeName, string rootNamespace):
base(fullTypeName, rootNamespace)
{
_renderingInfo = renderingInfo;
}
public virtual Guid Id => _renderingInfo.Id;

public virtual string Name => _renderingInfo.Name;
}
}
6 changes: 6 additions & 0 deletions src/Leprechaun/Model/RenderingInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace Leprechaun.Model
{
public class RenderingInfo:ItemInfo
{
}
}
28 changes: 7 additions & 21 deletions src/Leprechaun/Model/TemplateCodeGenerationMetadata.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,18 @@
namespace Leprechaun.Model
{
[DebuggerDisplay("{FullTypeName} ({Id})")]
public class TemplateCodeGenerationMetadata
public class TemplateCodeGenerationMetadata : BaseCodeGenerationMetadata
{
private readonly string _fullTypeName;

public TemplateCodeGenerationMetadata(TemplateInfo templateInfo, string fullTypeName, string rootNamespace, IEnumerable<TemplateFieldCodeGenerationMetadata> ownFields)

public TemplateCodeGenerationMetadata(TemplateInfo templateInfo, string fullTypeName, string rootNamespace, IEnumerable<TemplateFieldCodeGenerationMetadata> ownFields):
base(fullTypeName,rootNamespace)
{
TemplateInfo = templateInfo;
RootNamespace = rootNamespace;
_fullTypeName = fullTypeName;
OwnFields = ownFields.ToArray();
}

public virtual TemplateInfo TemplateInfo { get; }

public virtual string RootNamespace { get; }


public virtual string Path => TemplateInfo.Path;

public virtual Guid Id => TemplateInfo.Id;
Expand All @@ -30,11 +26,7 @@ public TemplateCodeGenerationMetadata(TemplateInfo templateInfo, string fullType

public virtual string HelpText => string.IsNullOrWhiteSpace(TemplateInfo.HelpText) ? $"Represents the {TemplateInfo.Name} field ({Id})." : TemplateInfo.HelpText;

/// <summary>
/// A unique name for this template, usable as a name for a C# class. e.g. for "Foo Bar" this would be "FooBar"
/// </summary>
public virtual string CodeName => _fullTypeName.Contains(".") ? _fullTypeName.Substring(_fullTypeName.LastIndexOf('.') + 1) : _fullTypeName;


/// <summary>
/// Gets a namespace-formatted relative path from the root template path to this template
/// e.g. if root is /Foo, and this template's path is /Foo/Bar/Baz/Quux, this would be "Bar.Baz"
Expand All @@ -55,13 +47,7 @@ public virtual string Namespace
return RootNamespace;
}
}

/// <summary>
/// Gets the full type name, qualified by namespace, of this template
/// e.g. RootNamespace.RelativeNamespace.CodeName
/// </summary>
public virtual string FullTypeName => $"{RootNamespace}.{_fullTypeName}";


/// <summary>
/// The template's fields that should get passed to code generation
/// </summary>
Expand Down
Loading