refactor: code cleanup

This commit is contained in:
Dylan R. E. Moonfire 2022-07-08 23:52:10 -05:00
parent 7fca466dbb
commit 01fe15d772
120 changed files with 910 additions and 359 deletions

View File

@ -31,11 +31,22 @@ dotnet_naming_rule.private_instance_fields_rule.import_to_resharper = as_predefi
dotnet_naming_rule.private_instance_fields_rule.severity = warning
dotnet_naming_rule.private_instance_fields_rule.style = lower_camel_case_style
dotnet_naming_rule.private_instance_fields_rule.symbols = private_instance_fields_symbols
dotnet_naming_rule.private_static_fields_override_rule.import_to_resharper = False
dotnet_naming_rule.private_static_fields_override_rule.severity = warning
dotnet_naming_rule.private_static_fields_override_rule.style = upper_camel_case_style
dotnet_naming_rule.private_static_fields_override_rule.symbols = private_static_fields_override_symbols
dotnet_naming_rule.private_static_fields_rule.import_to_resharper = as_predefined
dotnet_naming_rule.private_static_fields_rule.resharper_style = AaBb, aaBb
dotnet_naming_rule.private_static_fields_rule.severity = warning
dotnet_naming_rule.private_static_fields_rule.style = upper_camel_case_style
dotnet_naming_rule.private_static_fields_rule.symbols = private_static_fields_symbols
dotnet_naming_rule.private_static_fields_rule_1.import_to_resharper = True
dotnet_naming_rule.private_static_fields_rule_1.resharper_description = PrivateStaticFields
dotnet_naming_rule.private_static_fields_rule_1.resharper_guid = 2ec29786-2764-45cc-849e-7a476ce55db8
dotnet_naming_rule.private_static_fields_rule_1.resharper_style = AaBb, aaBb
dotnet_naming_rule.private_static_fields_rule_1.severity = warning
dotnet_naming_rule.private_static_fields_rule_1.style = upper_camel_case_style
dotnet_naming_rule.private_static_fields_rule_1.symbols = private_static_fields_symbols_1
dotnet_naming_rule.private_static_readonly_rule.import_to_resharper = as_predefined
dotnet_naming_rule.private_static_readonly_rule.severity = warning
dotnet_naming_rule.private_static_readonly_rule.style = upper_camel_case_style
@ -54,9 +65,17 @@ dotnet_naming_symbols.private_constants_symbols.applicable_kinds = field
dotnet_naming_symbols.private_constants_symbols.required_modifiers = const
dotnet_naming_symbols.private_instance_fields_symbols.applicable_accessibilities = private
dotnet_naming_symbols.private_instance_fields_symbols.applicable_kinds = field
dotnet_naming_symbols.private_static_fields_override_symbols.applicable_accessibilities = local, private
dotnet_naming_symbols.private_static_fields_override_symbols.applicable_kinds = field
dotnet_naming_symbols.private_static_fields_override_symbols.required_modifiers = const, static
dotnet_naming_symbols.private_static_fields_symbols.applicable_accessibilities = private
dotnet_naming_symbols.private_static_fields_symbols.applicable_kinds = field
dotnet_naming_symbols.private_static_fields_symbols.required_modifiers = static
dotnet_naming_symbols.private_static_fields_symbols_1.applicable_accessibilities = local, private
dotnet_naming_symbols.private_static_fields_symbols_1.applicable_kinds = field
dotnet_naming_symbols.private_static_fields_symbols_1.required_modifiers = static
dotnet_naming_symbols.private_static_fields_symbols_1.resharper_applicable_kinds = field
dotnet_naming_symbols.private_static_fields_symbols_1.resharper_required_modifiers = static
dotnet_naming_symbols.private_static_readonly_symbols.applicable_accessibilities = private
dotnet_naming_symbols.private_static_readonly_symbols.applicable_kinds = field
dotnet_naming_symbols.private_static_readonly_symbols.required_modifiers = static, readonly
@ -75,11 +94,14 @@ dotnet_style_require_accessibility_modifiers = for_non_interface_members:suggest
# ReSharper properties
resharper_alignment_tab_fill_style = optimal_fill
resharper_align_multiline_binary_expressions_chain = false
resharper_align_multiline_statement_conditions = false
resharper_apply_on_completion = true
resharper_autodetect_indent_settings = true
resharper_blank_lines_after_control_transfer_statements = 1
resharper_blank_lines_after_multiline_statements = 1
resharper_blank_lines_around_single_line_auto_property = 1
resharper_blank_lines_around_single_line_property = 1
resharper_blank_lines_before_control_transfer_statements = 1
resharper_blank_lines_before_multiline_statements = 1
resharper_blank_lines_before_single_line_comment = 1
resharper_braces_for_for = required
resharper_braces_for_foreach = required
@ -124,6 +146,8 @@ resharper_keep_existing_declaration_block_arrangement = true
resharper_keep_existing_declaration_parens_arrangement = false
resharper_keep_existing_embedded_block_arrangement = true
resharper_keep_existing_enum_arrangement = true
resharper_keep_existing_linebreaks = true
resharper_keep_user_linebreaks = true
resharper_min_blank_lines_after_imports = 1
resharper_nested_ternary_style = expanded
resharper_new_line_before_while = true
@ -133,7 +157,7 @@ resharper_place_type_constraints_on_same_line = false
resharper_protobuf_insert_final_newline = true
resharper_qualified_using_at_nested_scope = true
resharper_resx_alignment_tab_fill_style = optimal_fill
resharper_T4_alignment_tab_fill_style = optimal_fill
resharper_t4_alignment_tab_fill_style = optimal_fill
resharper_t4_insert_final_newline = true
resharper_use_continuous_indent_inside_initializer_braces = false
resharper_use_indents_from_main_language_in_file = false
@ -146,7 +170,7 @@ resharper_wrap_before_extends_colon = true
resharper_wrap_before_first_type_parameter_constraint = true
resharper_wrap_before_type_parameter_langle = true
resharper_wrap_chained_binary_expressions = chop_if_long
resharper_wrap_chained_method_calls = chop_if_long
resharper_wrap_chained_method_calls = chop_always
resharper_wrap_object_and_collection_initializer_style = chop_always
resharper_xmldoc_alignment_tab_fill_style = optimal_fill
resharper_xmldoc_indent_child_elements = ZeroIndent
@ -162,6 +186,7 @@ resharper_arrange_type_modifiers_highlighting = hint
resharper_built_in_type_reference_style_for_member_access_highlighting = hint
resharper_built_in_type_reference_style_highlighting = hint
resharper_check_namespace_highlighting = none
resharper_class_never_instantiated_global_highlighting = none
resharper_convert_to_auto_property_highlighting = none
resharper_localizable_element_highlighting = none
resharper_redundant_comma_in_attribute_list_highlighting = none
@ -205,3 +230,8 @@ tab_width = 4
indent_style = space
indent_size = 4
tab_width = 4
[*.{appxmanifest,asax,ascx,aspx,axaml,build,c,c++,cc,cginc,compute,cp,cpp,cs,cshtml,cu,cuh,cxx,dtd,fx,fxh,h,hh,hlsl,hlsli,hlslinc,hpp,hxx,inc,inl,ino,ipp,master,mpp,mq4,mq5,mqh,nuspec,paml,razor,resw,resx,skin,tpp,usf,ush,vb,xaml,xamlx,xoml,xsd}]
indent_style = space
indent_size = 4
tab_width = 4

View File

@ -85,7 +85,10 @@
<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/KEEP_BLANK_LINES_IN_CODE/@EntryValue">1</s:Int64>
<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/KEEP_BLANK_LINES_IN_DECLARATIONS/@EntryValue">1</s:Int64>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/KEEP_EXISTING_DECLARATION_PARENS_ARRANGEMENT/@EntryValue">False</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/KEEP_EXISTING_INVOCATION_PARENS_ARRANGEMENT/@EntryValue">False</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/LINE_FEED_AT_FILE_END/@EntryValue">True</s:Boolean>
<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/MAX_ENUM_MEMBERS_ON_LINE/@EntryValue">1</s:Int64>
<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/MAX_FORMAL_PARAMETERS_ON_LINE/@EntryValue">1</s:Int64>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/NESTED_TERNARY_STYLE/@EntryValue">EXPANDED</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_ACCESSOR_ATTRIBUTE_ON_SAME_LINE_EX/@EntryValue">NEVER</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_ACCESSORHOLDER_ATTRIBUTE_ON_SAME_LINE_EX/@EntryValue">NEVER</s:String>
@ -115,7 +118,9 @@
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_CHAINED_METHOD_CALLS/@EntryValue">CHOP_IF_LONG</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_EXTENDS_LIST_STYLE/@EntryValue">CHOP_IF_LONG</s:String>
<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_LIMIT/@EntryValue">80</s:Int64>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_MULTIPLE_TYPE_PARAMEER_CONSTRAINTS_STYLE/@EntryValue">CHOP_ALWAYS</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_PARAMETERS_STYLE/@EntryValue">CHOP_IF_LONG</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_VERBATIM_INTERPOLATED_STRINGS/@EntryValue">CHOP_IF_LONG</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CssFormatter/ALIGNMENT_TAB_FILL_STYLE/@EntryValue">OPTIMAL_FILL</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/HtmlFormatter/ALIGNMENT_TAB_FILL_STYLE/@EntryValue">OPTIMAL_FILL</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/JavaScriptCodeFormatting/ALIGNMENT_TAB_FILL_STYLE/@EntryValue">OPTIMAL_FILL</s:String>
@ -1366,6 +1371,5 @@ using(DataAccessAdapter dataAccessAdapter = new DataAccessAdapter(ConnectionStri
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=F87CBA43E9CDCC41A45B39A2A2A25764/Scope/=2C285F182AC98D44B0B4F29D4D2149EC/@KeyIndexDefined">True</s:Boolean>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=F87CBA43E9CDCC41A45B39A2A2A25764/Scope/=2C285F182AC98D44B0B4F29D4D2149EC/CustomProperties/=minimumLanguageVersion/@EntryIndexedValue">2.0</s:String>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=F87CBA43E9CDCC41A45B39A2A2A25764/Scope/=2C285F182AC98D44B0B4F29D4D2149EC/Type/@EntryValue">InCSharpStatement</s:String>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Gemtext/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Tocks/@EntryIndexedValue">True</s:Boolean>
</wpf:ResourceDictionary>

View File

@ -10,6 +10,11 @@ public class CopyFilesModule : Module
// This just registers all the non-static classes as singletons
// within the system. We use lifetimes in other components depending
// on how they are used, but in this case, we don't need it.
builder.RegisterAssemblyTypes(this.GetType().Assembly).AsSelf().AsImplementedInterfaces().SingleInstance();
builder.RegisterAssemblyTypes(
this.GetType()
.Assembly)
.AsSelf()
.AsImplementedInterfaces()
.SingleInstance();
}
}

View File

@ -74,7 +74,8 @@ public class CopyFilesPipeline : PipelineBase
// read. Coming out of this, we will have one entity that fulfills:
//
// entity.Get<UPath> == "/output/a.txt"
entities = entities.Run(this.removePathPrefix).Run(this.addPathPrefix);
entities = entities.Run(this.removePathPrefix)
.Run(this.addPathPrefix);
// Then we write out the files to the output. First we make sure we
// clear out the output. This operation performs an action when it
@ -95,7 +96,8 @@ public class CopyFilesPipeline : PipelineBase
// The third way is to use an extension on entities which lets us
// chain calls, ala Gulp's pipelines. The below code does this along
// with writing the files to the output.
entities = entities.Run(this.clearDirectory).Run(this.writeFiles);
entities = entities.Run(this.clearDirectory)
.Run(this.writeFiles);
// If we are chaining this pipeline into another, we return the
// entities. Otherwise, we can just return an empty list. The

View File

@ -28,6 +28,7 @@ public class CopyFilesTest : NitrideTestBase
// Figure out the paths for this test.
DirectoryInfo rootDir =
typeof(CopyFilesProgram).GetDirectory()!.FindGitRoot()!.GetDirectory("examples/CopyFiles");
DirectoryInfo outputDir = rootDir.GetDirectory("output");
FileInfo projectFile = rootDir.GetFile("CopyFiles.csproj");
@ -41,7 +42,12 @@ public class CopyFilesTest : NitrideTestBase
// Execute the generator. This will throw if there is an exception.
await Cli.Wrap("dotnet")
.WithArguments(x => x.Add("run").Add("--project").Add(projectFile.FullName).Add("--").Add("build"))
.WithArguments(
x => x.Add("run")
.Add("--project")
.Add(projectFile.FullName)
.Add("--")
.Add("build"))
.ExecuteAsync();
// Make sure we have our output.
@ -49,7 +55,8 @@ public class CopyFilesTest : NitrideTestBase
Assert.True(aFile.Exists);
string aText = aFile.ReadAllText().Trim();
string aText = aFile.ReadAllText()
.Trim();
Assert.Equal("This is the 'A' file.", aText);
}

View File

@ -7,9 +7,6 @@ pre-push:
pre-commit:
parallel: true
commands:
dotnet-format-style:
glob: "*.cs"
run: dotnet format
prettier:
run: prettier . --write --loglevel warn
nixfmt:

View File

@ -6,8 +6,13 @@ public class CreateCalendarValidator : AbstractValidator<CreateCalender>
{
public CreateCalendarValidator()
{
this.RuleFor(x => x.Path).NotNull();
this.RuleFor(x => x.GetEventSummary).NotNull();
this.RuleFor(x => x.GetEventUrl).NotNull();
this.RuleFor(x => x.Path)
.NotNull();
this.RuleFor(x => x.GetEventSummary)
.NotNull();
this.RuleFor(x => x.GetEventUrl)
.NotNull();
}
}

View File

@ -31,7 +31,9 @@ public partial class CreateCalender : OperationBase
private readonly IValidator<CreateCalender> validator;
public CreateCalender(IValidator<CreateCalender> validator, Timekeeper clock)
public CreateCalender(
IValidator<CreateCalender> validator,
Timekeeper clock)
{
this.validator = validator;
this.clock = clock;
@ -59,9 +61,12 @@ public partial class CreateCalender : OperationBase
{
this.validator.ValidateAndThrow(this);
IEnumerable<Entity> output = input.ForEntities<Instant>(this.CreateCalendarEntity);
input = input.ToList();
IEnumerable<Entity> dated = input.WhereAllComponents<Instant>();
IEnumerable<Entity> others = input.WhereNotComponent<Instant>();
IEnumerable<Entity> datedAndCalendars = this.CreateCalendarEntity(dated);
return output;
return datedAndCalendars.Union(others);
}
private IEnumerable<Entity> CreateCalendarEntity(IEnumerable<Entity> entities)
@ -96,6 +101,7 @@ public partial class CreateCalender : OperationBase
var when = this.clock.ToDateTime(instant);
string summary = this.GetEventSummary!(entity);
Uri? url = this.GetEventUrl?.Invoke(entity);
var calendarEvent = new CalendarEvent
{
Summary = summary,

View File

@ -16,7 +16,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Gallium" Version="1.0.2"/>
<PackageReference Include="Gallium" Version="1.2.0"/>
<PackageReference Include="Ical.Net" Version="4.2.0"/>
<PackageReference Include="NodaTime" Version="3.1.0"/>
<PackageReference Include="Zio" Version="0.15.0"/>

View File

@ -8,6 +8,7 @@ public static class NitrideCalendarBuilderExtensions
{
public static NitrideBuilder UseCalendar(this NitrideBuilder builder)
{
return builder.UseTemporal().ConfigureContainer(x => x.RegisterModule<NitrideCalendarModule>());
return builder.UseTemporal()
.ConfigureContainer(x => x.RegisterModule<NitrideCalendarModule>());
}
}

View File

@ -27,7 +27,9 @@ public partial class CreateAtomFeed : OperationBase
private readonly IValidator<CreateAtomFeed> validator;
public CreateAtomFeed(ILogger logger, IValidator<CreateAtomFeed> validator)
public CreateAtomFeed(
ILogger logger,
IValidator<CreateAtomFeed> validator)
{
this.logger = logger;
this.validator = validator;
@ -121,7 +123,9 @@ public partial class CreateAtomFeed : OperationBase
}
// Create the feed entity and return both objects.
Entity feedEntity = new Entity().Set(IsFeed.Instance).Set(this.GetPath!(entity)).SetTextContent(feed + "\n");
Entity feedEntity = new Entity().Set(IsFeed.Instance)
.Set(this.GetPath!(entity))
.SetTextContent(feed + "\n");
return new[] { entity, feedEntity };
}

View File

@ -6,8 +6,13 @@ public class CreateAtomFeedValidator : AbstractValidator<CreateAtomFeed>
{
public CreateAtomFeedValidator()
{
this.RuleFor(x => x.GetEntries).NotNull();
this.RuleFor(x => x.GetPath).NotNull();
this.RuleFor(x => x.GetTitle).NotNull();
this.RuleFor(x => x.GetEntries)
.NotNull();
this.RuleFor(x => x.GetPath)
.NotNull();
this.RuleFor(x => x.GetTitle)
.NotNull();
}
}

View File

@ -16,7 +16,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Gallium" Version="1.0.2"/>
<PackageReference Include="Gallium" Version="1.2.0"/>
<PackageReference Include="NodaTime" Version="3.1.0"/>
<PackageReference Include="Zio" Version="0.15.0"/>
</ItemGroup>

View File

@ -8,6 +8,7 @@ public static class NitrideFeedsBuilderExtensions
{
public static NitrideBuilder UseFeeds(this NitrideBuilder builder)
{
return builder.UseTemporal().ConfigureContainer(x => x.RegisterModule<NitrideFeedsModule>());
return builder.UseTemporal()
.ConfigureContainer(x => x.RegisterModule<NitrideFeedsModule>());
}
}

View File

@ -7,7 +7,9 @@ namespace Nitride.Feeds.Structure;
/// </summary>
public static class AtomHelper
{
public static void AddIfSet(XElement root, XElement? elem)
public static void AddIfSet(
XElement root,
XElement? elem)
{
if (elem != null)
{
@ -15,7 +17,10 @@ public static class AtomHelper
}
}
public static void AddIfSet(XElement elem, string name, string? text)
public static void AddIfSet(
XElement elem,
string name,
string? text)
{
if (!string.IsNullOrWhiteSpace(text))
{

View File

@ -10,7 +10,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Gallium" Version="1.0.2"/>
<PackageReference Include="Gallium" Version="1.2.0"/>
<PackageReference Include="Microsoft.CodeAnalysis.Common" Version="4.1.0"/>
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.1.0"/>
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="4.1.0"/>

View File

@ -61,7 +61,9 @@ public class WithPropertySourceGenerator : ISourceGenerator
context.RegisterForSyntaxNotifications(() => new WithPropertySyntaxReceiver(context));
}
private void GenerateClassFile(GeneratorExecutionContext context, WithPropertyClass unit)
private void GenerateClassFile(
GeneratorExecutionContext context,
WithPropertyClass unit)
{
// Pull out some fields.
ClassDeclarationSyntax? cds = unit.ClassDeclaration;
@ -88,6 +90,7 @@ public class WithPropertySourceGenerator : ISourceGenerator
IEnumerable<PropertyDeclarationSyntax> properties = cds.Members
.Where(m => m.Kind() == SyntaxKind.PropertyDeclaration)
.Cast<PropertyDeclarationSyntax>();
bool first = true;
foreach (PropertyDeclarationSyntax pds in properties)
@ -112,10 +115,12 @@ public class WithPropertySourceGenerator : ISourceGenerator
// Write some documentation.
buffer.AppendLine(" /// <summary>");
buffer.AppendLine(
string.Format(
" /// Sets the {0} value and returns the operation for chaining.",
pds.Identifier.ToString()));
buffer.AppendLine(" /// </summary>");
// We have the components for writing out a setter.
@ -125,6 +130,7 @@ public class WithPropertySourceGenerator : ISourceGenerator
cds.Identifier,
pds.Identifier,
pds.Type));
buffer.AppendLine(" {");
buffer.AppendLine(string.Format(" this.{0} = value;", pds.Identifier));
buffer.AppendLine(" return this;");

View File

@ -37,15 +37,19 @@ internal class WithPropertySyntaxReceiver : ISyntaxReceiver
// Reset everything.
this.Namespace = null!;
this.UsingDirectiveList = new List<UsingDirectiveSyntax>();
break;
case NamespaceDeclarationSyntax syntax:
this.Namespace = syntax.Name.ToString();
return;
case FileScopedNamespaceDeclarationSyntax syntax:
this.Namespace = syntax.Name.ToString();
return;
case UsingDirectiveSyntax syntax:
this.UsingDirectiveList.Add(syntax);
return;
case ClassDeclarationSyntax:
break;

View File

@ -52,7 +52,7 @@ public class ApplyStyleTemplate<TModel> : OperationBase
this.validator.ValidateAndThrow(this);
// Create and set up the Handlebars.
return input.ForEachEntity<ITextContent>(this.Apply);
return input.SelectEntity<ITextContent>(this.Apply);
}
/// <summary>
@ -64,22 +64,27 @@ public class ApplyStyleTemplate<TModel> : OperationBase
public ApplyStyleTemplate<TModel> WithCreateModelCallback(Func<Entity, TModel>? callback)
{
this.CreateModelCallback = callback;
return this;
}
public ApplyStyleTemplate<TModel> WithGetTemplateName(Func<Entity, string>? callback)
{
this.GetTemplateName = callback;
return this;
}
public ApplyStyleTemplate<TModel> WithHandlebars(IHandlebars? handlebars)
{
this.Handlebars = handlebars;
return this;
}
private Entity Apply(Entity entity, ITextContent content)
private Entity Apply(
Entity entity,
ITextContent content)
{
TModel model = this.CreateModelCallback!(entity);
string name = this.GetTemplateName!(entity);

View File

@ -6,8 +6,13 @@ public class ApplyStyleTemplateValidator<TModel> : AbstractValidator<ApplyStyleT
{
public ApplyStyleTemplateValidator()
{
this.RuleFor(x => x.Handlebars).NotNull();
this.RuleFor(x => x.GetTemplateName).NotNull();
this.RuleFor(x => x.CreateModelCallback).NotNull();
this.RuleFor(x => x.Handlebars)
.NotNull();
this.RuleFor(x => x.GetTemplateName)
.NotNull();
this.RuleFor(x => x.CreateModelCallback)
.NotNull();
}
}

View File

@ -6,6 +6,7 @@ public class IdentifyHandlebarsFromComponentValidator : AbstractValidator<Identi
{
public IdentifyHandlebarsFromComponentValidator()
{
this.RuleFor(x => x.HasHandlebarsTest).NotNull();
this.RuleFor(x => x.HasHandlebarsTest)
.NotNull();
}
}

View File

@ -15,10 +15,12 @@ public class IdentifyHandlebarsFromContent : IOperation
/// <inheritdoc />
public IEnumerable<Entity> Run(IEnumerable<Entity> input)
{
return input.ForEachEntity<ITextContent>(this.ScanContent);
return input.SelectEntity<ITextContent>(this.ScanContent);
}
private Entity ScanContent(Entity entity, ITextContent content)
private Entity ScanContent(
Entity entity,
ITextContent content)
{
string text = content.GetText();

View File

@ -11,7 +11,7 @@
<ItemGroup>
<PackageReference Include="Autofac" Version="6.4.0"/>
<PackageReference Include="Gallium" Version="1.0.2"/>
<PackageReference Include="Gallium" Version="1.2.0"/>
<PackageReference Include="Handlebars.Net" Version="2.1.2"/>
<PackageReference Include="NodaTime.Testing" Version="3.1.0"/>
<PackageReference Include="Open.Threading" Version="2.2.0"/>

View File

@ -10,8 +10,14 @@ public class NitrideHandlebarsModule : Module
builder.RegisterOperators(this);
builder.RegisterValidators(this);
builder.RegisterType<HandlebarsTemplateCache>().AsSelf().SingleInstance();
builder.RegisterGeneric(typeof(RenderContentTemplate<>)).As(typeof(RenderContentTemplate<>));
builder.RegisterGeneric(typeof(ApplyStyleTemplate<>)).As(typeof(ApplyStyleTemplate<>));
builder.RegisterType<HandlebarsTemplateCache>()
.AsSelf()
.SingleInstance();
builder.RegisterGeneric(typeof(RenderContentTemplate<>))
.As(typeof(RenderContentTemplate<>));
builder.RegisterGeneric(typeof(ApplyStyleTemplate<>))
.As(typeof(ApplyStyleTemplate<>));
}
}

View File

@ -43,7 +43,7 @@ public class RenderContentTemplate<TModel> : OperationBase
{
this.validator.ValidateAndThrow(this);
return input.ForEachEntity<HasHandlebarsTemplate, ITextContent>(this.Apply);
return input.SelectEntity<HasHandlebarsTemplate, ITextContent>(this.Apply);
}
/// <summary>
@ -55,10 +55,14 @@ public class RenderContentTemplate<TModel> : OperationBase
public RenderContentTemplate<TModel> WithCreateModelCallback(Func<Entity, TModel>? callback)
{
this.CreateModelCallback = callback;
return this;
}
private Entity Apply(Entity entity, HasHandlebarsTemplate _, ITextContent content)
private Entity Apply(
Entity entity,
HasHandlebarsTemplate _,
ITextContent content)
{
// Create the model using the callback.
TModel model = this.CreateModelCallback!(entity);
@ -71,6 +75,7 @@ public class RenderContentTemplate<TModel> : OperationBase
// text.
string result = template(model!);
return entity.Remove<HasHandlebarsTemplate>().SetTextContent(new StringTextContent(result));
return entity.Remove<HasHandlebarsTemplate>()
.SetTextContent(new StringTextContent(result));
}
}

View File

@ -6,6 +6,7 @@ public class RenderContentTemplateValidator<TModel> : AbstractValidator<RenderCo
{
public RenderContentTemplateValidator()
{
this.RuleFor(x => x.CreateModelCallback).NotNull();
this.RuleFor(x => x.CreateModelCallback)
.NotNull();
}
}

View File

@ -16,10 +16,12 @@ public class ConvertHtmlEntitiesToUnicode : OperationBase
/// <inheritdoc />
public override IEnumerable<Entity> Run(IEnumerable<Entity> input)
{
return input.ForEachEntity<ITextContent>(this.ResolveHtmlEntities);
return input.SelectEntity<ITextContent>(this.ResolveHtmlEntities);
}
private Entity ResolveHtmlEntities(Entity entity, ITextContent content)
private Entity ResolveHtmlEntities(
Entity entity,
ITextContent content)
{
string text = content.GetText();
string resolved = WebUtility.HtmlDecode(text);

View File

@ -25,7 +25,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Gallium" Version="1.0.2"/>
<PackageReference Include="Gallium" Version="1.2.0"/>
</ItemGroup>
</Project>

View File

@ -24,7 +24,9 @@ public partial class ReadFiles : FileSystemOperationBase
{
private readonly IValidator<ReadFiles> validator;
public ReadFiles(IValidator<ReadFiles> validator, IFileSystem fileSystem)
public ReadFiles(
IValidator<ReadFiles> validator,
IFileSystem fileSystem)
: base(fileSystem)
{
this.validator = validator;
@ -56,8 +58,10 @@ public partial class ReadFiles : FileSystemOperationBase
this.validator.ValidateAndThrow(this);
var glob = Glob.Parse(this.Pattern);
IEnumerable<FileEntry> files = this.FileSystem.EnumerateFileEntries("/", "*", SearchOption.AllDirectories)
.Where(x => glob.IsMatch(x.Path.ToString()));
IEnumerable<Entity> entities = files.Select(this.ToEntity);
return entities;
@ -66,6 +70,7 @@ public partial class ReadFiles : FileSystemOperationBase
public ReadFiles WithFileSystem(IFileSystem value)
{
this.FileSystem = value;
return this;
}
@ -78,7 +83,8 @@ public partial class ReadFiles : FileSystemOperationBase
/// <returns>An Entity with appropriate content.</returns>
private Entity ToEntity(FileEntry file)
{
Entity entity = new Entity().Set(file.Path).SetBinaryContent(new FileEntryBinaryContent(file));
Entity entity = new Entity().Set(file.Path)
.SetBinaryContent(new FileEntryBinaryContent(file));
return entity;
}

View File

@ -6,7 +6,10 @@ public class ReadFilesValidator : AbstractValidator<ReadFiles>
{
public ReadFilesValidator()
{
this.RuleFor(x => x.Pattern).NotNull();
this.RuleFor(x => x.FileSystem).NotNull();
this.RuleFor(x => x.Pattern)
.NotNull();
this.RuleFor(x => x.FileSystem)
.NotNull();
}
}

View File

@ -26,12 +26,16 @@ public partial class WriteFiles : FileSystemOperationBase, IOperation
private Dictionary<Type, Func<IContent, Stream>> factories;
public WriteFiles(IValidator<WriteFiles> validator, ILogger logger, IFileSystem fileSystem)
public WriteFiles(
IValidator<WriteFiles> validator,
ILogger logger,
IFileSystem fileSystem)
: base(fileSystem)
{
this.Logger = logger;
this.validator = validator;
this.TextEncoding = Encoding.UTF8;
this.factories = new Dictionary<Type, Func<IContent, Stream>>
{
[typeof(IBinaryContent)] = GetBinaryStream,
@ -63,7 +67,8 @@ public partial class WriteFiles : FileSystemOperationBase, IOperation
{
this.validator.ValidateAndThrow(this);
IEnumerable<Entity> results = entities.ForEachEntity<UPath>(this.Process).ToList();
IEnumerable<Entity> results = entities.SelectEntity<UPath>(this.Process)
.ToList();
return results;
}
@ -71,6 +76,7 @@ public partial class WriteFiles : FileSystemOperationBase, IOperation
public WriteFiles WithFileSystem(IFileSystem fileSystem)
{
this.FileSystem = fileSystem;
return this;
}
@ -85,12 +91,16 @@ public partial class WriteFiles : FileSystemOperationBase, IOperation
// we don't have to load it entirely in memory.
if (content is IBinaryContentConvertable convertable)
{
return convertable.ToBinaryContent().GetStream();
return convertable.ToBinaryContent()
.GetStream();
}
// We have the load the text into memory and convert it.
var textContent = (ITextContent)content;
string text = textContent.GetReader().ReadToEnd();
string text = textContent.GetReader()
.ReadToEnd();
var stream = new MemoryStream();
var writer = new StreamWriter(stream, this.TextEncoding ?? Encoding.UTF8);
@ -109,7 +119,9 @@ public partial class WriteFiles : FileSystemOperationBase, IOperation
/// <param name="entity">The entity to write out.</param>
/// <param name="path">The path of the entity.</param>
/// <returns>The entity passed in.</returns>
private Entity Process(Entity entity, UPath path)
private Entity Process(
Entity entity,
UPath path)
{
// See if we have any content. If we don't, then there is nothing
// to do.
@ -178,7 +190,8 @@ public partial class WriteFiles : FileSystemOperationBase, IOperation
"Cannot write out entity "
+ path
+ " because cannot determine how to get a stream out content type "
+ content.GetType().FullName
+ content.GetType()
.FullName
+ ". To resolve, register a function to this.StreamFactories.");
}
@ -189,7 +202,10 @@ public partial class WriteFiles : FileSystemOperationBase, IOperation
/// <param name="path">The path to write out, directories will be created.</param>
/// <param name="stream">The stream to write out.</param>
/// <returns>The entity passed in.</returns>
private Entity Process(Entity entity, UPath path, Stream stream)
private Entity Process(
Entity entity,
UPath path,
Stream stream)
{
// Make sure we have the directory structure.
UPath directory = path.GetDirectory();

View File

@ -6,9 +6,16 @@ public class WriteFilesValidator : AbstractValidator<WriteFiles>
{
public WriteFilesValidator()
{
this.RuleFor(x => x.StreamFactories).NotNull();
this.RuleFor(x => x.TextEncoding).NotNull();
this.RuleFor(x => x.FileSystem).NotNull();
this.RuleFor(x => x.Logger).NotNull();
this.RuleFor(x => x.StreamFactories)
.NotNull();
this.RuleFor(x => x.TextEncoding)
.NotNull();
this.RuleFor(x => x.FileSystem)
.NotNull();
this.RuleFor(x => x.Logger)
.NotNull();
}
}

View File

@ -22,7 +22,10 @@ public partial class ClearDirectory : FileSystemOperationBase, IOperation
{
private readonly IValidator<ClearDirectory> validator;
public ClearDirectory(IValidator<ClearDirectory> validator, IFileSystem fileSystem, ILogger logger)
public ClearDirectory(
IValidator<ClearDirectory> validator,
IFileSystem fileSystem,
ILogger logger)
: base(fileSystem)
{
this.Logger = logger;
@ -87,6 +90,7 @@ public partial class ClearDirectory : FileSystemOperationBase, IOperation
public ClearDirectory WithFileSystem(IFileSystem value)
{
this.FileSystem = value;
return this;
}
}

View File

@ -6,8 +6,13 @@ public class ClearDirectoryValidator : AbstractValidator<ClearDirectory>
{
public ClearDirectoryValidator()
{
this.RuleFor(x => x.Path).NotNull();
this.RuleFor(x => x.FileSystem).NotNull();
this.RuleFor(x => x.Logger).NotNull();
this.RuleFor(x => x.Path)
.NotNull();
this.RuleFor(x => x.FileSystem)
.NotNull();
this.RuleFor(x => x.Logger)
.NotNull();
}
}

View File

@ -8,16 +8,16 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Autofac" Version="6.4.0" />
<PackageReference Include="DotNet.Glob" Version="3.1.3" />
<PackageReference Include="FluentValidation" Version="11.0.2" />
<PackageReference Include="Gallium" Version="1.0.2" />
<PackageReference Include="Serilog" Version="2.11.0" />
<PackageReference Include="Zio" Version="0.15.0" />
<PackageReference Include="Autofac" Version="6.4.0"/>
<PackageReference Include="DotNet.Glob" Version="3.1.3"/>
<PackageReference Include="FluentValidation" Version="11.1.0"/>
<PackageReference Include="Gallium" Version="1.2.0"/>
<PackageReference Include="Serilog" Version="2.11.0"/>
<PackageReference Include="Zio" Version="0.15.0"/>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Nitride\Nitride.csproj" />
<ProjectReference Include="..\Nitride\Nitride.csproj"/>
</ItemGroup>
<!-- Include the source generator -->

View File

@ -15,7 +15,9 @@ public partial class AddPathPrefix : OperationBase
private readonly IValidator<AddPathPrefix> validator;
public AddPathPrefix(IValidator<AddPathPrefix> validator, ReplacePath replacePath)
public AddPathPrefix(
IValidator<AddPathPrefix> validator,
ReplacePath replacePath)
{
this.validator = validator;
this.replacePath = replacePath;
@ -30,12 +32,17 @@ public partial class AddPathPrefix : OperationBase
{
this.validator.ValidateAndThrow(this);
return this.replacePath.WithReplacement(this.RunReplacement).Run(input);
return this.replacePath.WithReplacement(this.RunReplacement)
.Run(input);
}
private UPath RunReplacement(Entity _, UPath path)
private UPath RunReplacement(
Entity _,
UPath path)
{
string innerRelativePath = path.ToString().TrimStart('/');
string innerRelativePath = path.ToString()
.TrimStart('/');
return this.PathPrefix!.Value / innerRelativePath;
}
}

View File

@ -6,6 +6,7 @@ public class AddPathPrefixValidator : AbstractValidator<AddPathPrefix>
{
public AddPathPrefixValidator()
{
this.RuleFor(x => x.PathPrefix).NotNull();
this.RuleFor(x => x.PathPrefix)
.NotNull();
}
}

View File

@ -18,7 +18,9 @@ public partial class ChangePathExtension : IOperation
private readonly IValidator<ChangePathExtension> validator;
public ChangePathExtension(IValidator<ChangePathExtension> validator, ReplacePath replacePath)
public ChangePathExtension(
IValidator<ChangePathExtension> validator,
ReplacePath replacePath)
{
this.validator = validator;
this.replacePath = replacePath;
@ -33,10 +35,13 @@ public partial class ChangePathExtension : IOperation
{
this.validator.ValidateAndThrow(this);
return this.replacePath.WithReplacement(this.RunReplacement).Run(input);
return this.replacePath.WithReplacement(this.RunReplacement)
.Run(input);
}
private UPath RunReplacement(Entity _, UPath path)
private UPath RunReplacement(
Entity _,
UPath path)
{
return path.ChangeExtension(this.Extension!);
}

View File

@ -6,6 +6,7 @@ public class ChangePathExtensionValidator : AbstractValidator<ChangePathExtensio
{
public ChangePathExtensionValidator()
{
this.RuleFor(x => x.Extension).NotNull();
this.RuleFor(x => x.Extension)
.NotNull();
}
}

View File

@ -17,11 +17,15 @@ namespace Nitride.IO.Paths;
public partial class LinkDirectChildren : CreateOrUpdateIndex
{
/// <inheritdoc />
public LinkDirectChildren(ILogger logger, IValidator<CreateOrUpdateIndex> validator)
public LinkDirectChildren(
ILogger logger,
IValidator<CreateOrUpdateIndex> validator)
: base(logger, validator)
{
this.UpdateIndex = this.InternalUpdateIndex;
this.GetIndexKey = e => e.Get<UPath>().GetDirectoryIndexPath();
this.GetIndexKey = e => e.Get<UPath>()
.GetDirectoryIndexPath();
}
/// <inheritdoc />
@ -34,12 +38,16 @@ public partial class LinkDirectChildren : CreateOrUpdateIndex
this.Scanner = new DirectChildPathScanner(new EntityScannerValidator());
input = this.Scanner.Run(input).ToList();
input = this.Scanner.Run(input)
.ToList();
return base.Run(input);
}
private Entity InternalUpdateIndex(Entity entity, string _, IEnumerable<Entity> list)
private Entity InternalUpdateIndex(
Entity entity,
string _,
IEnumerable<Entity> list)
{
return entity.Add(new DirectChildEntityList(list));
}

View File

@ -19,7 +19,9 @@ public partial class MoveToIndexPath : OperationBase
private readonly IValidator<MoveToIndexPath> validator;
public MoveToIndexPath(IValidator<MoveToIndexPath> validator, ReplacePath replacePath)
public MoveToIndexPath(
IValidator<MoveToIndexPath> validator,
ReplacePath replacePath)
{
this.validator = validator;
this.replacePath = replacePath;
@ -54,10 +56,13 @@ public partial class MoveToIndexPath : OperationBase
{
this.validator.ValidateAndThrow(this);
return this.replacePath.WithReplacement(this.RunReplacement).Run(input);
return this.replacePath.WithReplacement(this.RunReplacement)
.Run(input);
}
private UPath RunReplacement(Entity _, UPath path)
private UPath RunReplacement(
Entity _,
UPath path)
{
// See if we are already an index. If that is true, then we don't
// have to move any further.

View File

@ -6,6 +6,7 @@ public class MoveToIndexPathValidator : AbstractValidator<MoveToIndexPath>
{
public MoveToIndexPathValidator()
{
this.RuleFor(x => x.CanMoveCallback).NotNull();
this.RuleFor(x => x.CanMoveCallback)
.NotNull();
}
}

View File

@ -18,7 +18,9 @@ public partial class RemovePathPrefix : IOperation
private readonly IValidator<RemovePathPrefix> validator;
public RemovePathPrefix(IValidator<RemovePathPrefix> validator, ReplacePath replacePath)
public RemovePathPrefix(
IValidator<RemovePathPrefix> validator,
ReplacePath replacePath)
{
this.validator = validator;
this.replacePath = replacePath;
@ -33,17 +35,21 @@ public partial class RemovePathPrefix : IOperation
{
this.validator.ValidateAndThrow(this);
return this.replacePath.WithReplacement(this.RunReplacement).Run(input);
return this.replacePath.WithReplacement(this.RunReplacement)
.Run(input);
}
private UPath RunReplacement(Entity _, UPath path)
private UPath RunReplacement(
Entity _,
UPath path)
{
string normalized = path.ToString();
string prefix = this.PathPrefix.ToString()!;
if (normalized.StartsWith(prefix))
{
return (UPath)path.ToString().Substring(prefix.Length);
return (UPath)path.ToString()
.Substring(prefix.Length);
}
return path;

View File

@ -6,6 +6,7 @@ public class RemovePathPrefixValidator : AbstractValidator<RemovePathPrefix>
{
public RemovePathPrefixValidator()
{
this.RuleFor(x => x.PathPrefix).NotNull();
this.RuleFor(x => x.PathPrefix)
.NotNull();
}
}

View File

@ -40,8 +40,10 @@ public partial class ReplacePath : IOperation
{
this.validator.ValidateAndThrow(this);
return input.ForEachEntity<UPath>(
(entity, oldPath) =>
return input.SelectEntity<UPath>(
(
entity,
oldPath) =>
{
UPath newPath = this.Replacement(entity, oldPath);

View File

@ -6,6 +6,7 @@ public class ReplacePathValidator : AbstractValidator<ReplacePath>
{
public ReplacePathValidator()
{
this.RuleFor(x => x.Replacement).NotNull();
this.RuleFor(x => x.Replacement)
.NotNull();
}
}

View File

@ -17,7 +17,10 @@ public static class UPathExtensions
{
if (path.GetNameWithoutExtension() == "index")
{
return path.GetDirectory().ToString().TrimEnd('/') + "/";
return path.GetDirectory()
.ToString()
.TrimEnd('/')
+ "/";
}
return path.ToString();
@ -33,7 +36,9 @@ public static class UPathExtensions
parent = "/";
}
string parentPath = parent.ToString().TrimEnd('/') + "/";
string parentPath = parent.ToString()
.TrimEnd('/')
+ "/";
return parentPath;
}

View File

@ -4,9 +4,9 @@ This assembly contains the primary system for reading and writing from the disk,
along with various processes to manipulate paths. It contains three primary
components:
- File System I/O
- Path Normalization
- Disk-Based Content
- File System I/O
- Path Normalization
- Disk-Based Content
## File System I/O

View File

@ -41,8 +41,11 @@ public abstract partial class ConvertMarkdownToBase : IOperation
MarkdownPipeline options = builder.Build();
// Process the Markdown files (while passing everything on).
return input.ForEachEntity<IsMarkdown, ITextContent>(
(entity, _, content) => this.Convert(entity, content, options));
return input.SelectEntity<IsMarkdown, ITextContent>(
(
entity,
_,
content) => this.Convert(entity, content, options));
}
/// <summary>
@ -52,5 +55,8 @@ public abstract partial class ConvertMarkdownToBase : IOperation
/// <param name="markdownContent">The content for this entity.</param>
/// <param name="options">The markdown pipeline.</param>
/// <returns>A converted entity.</returns>
protected abstract Entity Convert(Entity entity, ITextContent markdownContent, MarkdownPipeline options);
protected abstract Entity Convert(
Entity entity,
ITextContent markdownContent,
MarkdownPipeline options);
}

View File

@ -6,6 +6,7 @@ public class ConvertMarkdownToBaseValidator : AbstractValidator<ConvertMarkdownT
{
public ConvertMarkdownToBaseValidator()
{
this.RuleFor(x => x.ConfigureMarkdown).NotNull();
this.RuleFor(x => x.ConfigureMarkdown)
.NotNull();
}
}

View File

@ -29,6 +29,7 @@ public class ConvertMarkdownToGemtext : ConvertMarkdownToBase
public override ConvertMarkdownToGemtext WithConfigureMarkdown(Action<MarkdownPipelineBuilder>? value)
{
base.WithConfigureMarkdown(value);
return this;
}
@ -39,13 +40,18 @@ public class ConvertMarkdownToGemtext : ConvertMarkdownToBase
/// <param name="markdownContent">The content for this entity.</param>
/// <param name="options">The markdown pipeline.</param>
/// <returns>A converted entity.</returns>
protected override Entity Convert(Entity entity, ITextContent markdownContent, MarkdownPipeline options)
protected override Entity Convert(
Entity entity,
ITextContent markdownContent,
MarkdownPipeline options)
{
string markdown = markdownContent.GetText();
string gemtext = MarkdownGemtext.ToGemtext(markdown, options);
var content = new StringTextContent(gemtext);
entity = entity.SetTextContent(content).Remove<IsMarkdown>().Set(IsGemtext.Instance);
entity = entity.SetTextContent(content)
.Remove<IsMarkdown>()
.Set(IsGemtext.Instance);
return entity;
}

View File

@ -26,6 +26,7 @@ public class ConvertMarkdownToHtml : ConvertMarkdownToBase
public override ConvertMarkdownToHtml WithConfigureMarkdown(Action<MarkdownPipelineBuilder>? value)
{
base.WithConfigureMarkdown(value);
return this;
}
@ -36,14 +37,19 @@ public class ConvertMarkdownToHtml : ConvertMarkdownToBase
/// <param name="markdownContent">The content for this entity.</param>
/// <param name="options">The markdown pipeline.</param>
/// <returns>A converted entity.</returns>
protected override Entity Convert(Entity entity, ITextContent markdownContent, MarkdownPipeline options)
protected override Entity Convert(
Entity entity,
ITextContent markdownContent,
MarkdownPipeline options)
{
// Convert the entity to Html.
string markdown = markdownContent.GetText();
string html = Markdig.Markdown.ToHtml(markdown, options);
var htmlContent = new StringTextContent(html);
entity = entity.SetTextContent(htmlContent).Remove<IsMarkdown>().Set(IsHtml.Instance);
entity = entity.SetTextContent(htmlContent)
.Remove<IsMarkdown>()
.Set(IsHtml.Instance);
// Return the resulting entity.
return entity;

View File

@ -33,11 +33,14 @@ public partial class IdentifyMarkdown : IOperation
{
this.validator.ValidateAndThrow(this);
return input.ForEachEntity<UPath, ITextContent>(this.MarkTextEntities)
.ForEachEntity<UPath, IBinaryContent>(this.MarkBinaryEntities);
return input.SelectEntity<UPath, ITextContent>(this.MarkTextEntities)
.SelectEntity<UPath, IBinaryContent>(this.MarkBinaryEntities);
}
private Entity MarkBinaryEntities(Entity entity, UPath path, IBinaryContent binary)
private Entity MarkBinaryEntities(
Entity entity,
UPath path,
IBinaryContent binary)
{
// If we aren't a Markdown file, then there is nothing we can do about that.
if (!this.IsMarkdownTest(entity, path))
@ -48,7 +51,8 @@ public partial class IdentifyMarkdown : IOperation
// Convert the file as a binary.
if (binary is ITextContentConvertable textConvertable)
{
entity = entity.SetTextContent(textConvertable.ToTextContent()).Set(IsMarkdown.Instance);
entity = entity.SetTextContent(textConvertable.ToTextContent())
.Set(IsMarkdown.Instance);
}
else
{
@ -59,7 +63,10 @@ public partial class IdentifyMarkdown : IOperation
return entity;
}
private Entity MarkTextEntities(Entity entity, UPath path, ITextContent _)
private Entity MarkTextEntities(
Entity entity,
UPath path,
ITextContent _)
{
// If we aren't a Markdown file, then there is nothing
// we can do about that.

View File

@ -14,7 +14,9 @@ public class IdentifyMarkdownFromPath : IdentifyMarkdown
this.IsMarkdownTest = DefaultIsMarkdown;
}
private static bool DefaultIsMarkdown(Entity entity, UPath path)
private static bool DefaultIsMarkdown(
Entity entity,
UPath path)
{
return (path.GetExtensionWithDot() ?? string.Empty).ToLowerInvariant() switch
{

View File

@ -6,6 +6,7 @@ public class IdentifyMarkdownValidator : AbstractValidator<IdentifyMarkdown>
{
public IdentifyMarkdownValidator()
{
this.RuleFor(x => x.IsMarkdownTest).NotNull();
this.RuleFor(x => x.IsMarkdownTest)
.NotNull();
}
}

View File

@ -16,7 +16,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Gallium" Version="1.0.2"/>
<PackageReference Include="Gallium" Version="1.2.0"/>
<PackageReference Include="Markdig" Version="0.30.2"/>
<PackageReference Include="MfGames.Markdown.Gemtext" Version="1.2.1"/>
<PackageReference Include="Zio" Version="0.15.0"/>

View File

@ -6,7 +6,9 @@ namespace Nitride.Slugs;
public static class NitrideSlugsBuilderExtensions
{
public static NitrideBuilder UseSlugs(this NitrideBuilder builder, ISlugConverter slugs)
public static NitrideBuilder UseSlugs(
this NitrideBuilder builder,
ISlugConverter slugs)
{
if (slugs == null)
{
@ -16,7 +18,10 @@ public static class NitrideSlugsBuilderExtensions
return builder.ConfigureContainer(
x =>
{
x.RegisterInstance(slugs).As<ISlugConverter>().SingleInstance();
x.RegisterInstance(slugs)
.As<ISlugConverter>()
.SingleInstance();
x.RegisterModule<NitrideSlugsModule>();
});
}

View File

@ -52,7 +52,8 @@ public class SimpleSlugConverter : ISlugConverter, IEnumerable<string>
/// <inheritdoc />
public IEnumerator<string> GetEnumerator()
{
return this.replacements.Select(x => x.Item1).GetEnumerator();
return this.replacements.Select(x => x.Item1)
.GetEnumerator();
}
/// <inheritdoc />

View File

@ -34,7 +34,10 @@ public class UnicodeNormalizingSlugConverter : SimpleSlugConverter
// Normalize the Unicode objects.
// Strip out the accents. This is a cheesy way of doing so.
char[] chars = input.Normalize(NormalizationForm.FormD).Where(this.IsNonSpacingMark).ToArray();
char[] chars = input.Normalize(NormalizationForm.FormD)
.Where(this.IsNonSpacingMark)
.ToArray();
string normalized = new string(chars).Normalize(NormalizationForm.FormC);
// Return the base implementation.

View File

@ -22,10 +22,13 @@ public class DatePipelineCommandOption : IPipelineCommandOption
private readonly Timekeeper timekeeper;
public DatePipelineCommandOption(ILogger logger, Timekeeper timekeeper)
public DatePipelineCommandOption(
ILogger logger,
Timekeeper timekeeper)
{
this.logger = logger.ForContext<Instant>();
this.timekeeper = timekeeper;
this.Option = new Option<DateTime>("--date")
{
Description = "Sets the date to something other than now",

View File

@ -22,10 +22,14 @@ public class ExpiresPipelineCommandOption : IPipelineCommandOption
private readonly ILogger logger;
public ExpiresPipelineCommandOption(ILogger logger, Timekeeper clock, string? defaultValue = null)
public ExpiresPipelineCommandOption(
ILogger logger,
Timekeeper clock,
string? defaultValue = null)
{
this.logger = logger.ForContext<Instant>();
this.clock = clock;
this.Option = new Option<string?>("--expires", () => defaultValue)
{
Description = "Sets the expiration time as time before the current date",
@ -54,6 +58,7 @@ public class ExpiresPipelineCommandOption : IPipelineCommandOption
if (this.clock.Expiration == null)
{
this.logger.Information("No entities will be expired");
return;
}

View File

@ -14,9 +14,14 @@ public class CreateDateIndexesValidator : AbstractValidator<CreateDateIndexes>
{
public CreateDateIndexesValidator()
{
this.RuleFor(a => a.Timekeeper).NotNull();
this.RuleFor(a => a.CreateIndex).NotNull();
this.RuleFor(a => a.Formats).NotNull();
this.RuleFor(a => a.Timekeeper)
.NotNull();
this.RuleFor(a => a.CreateIndex)
.NotNull();
this.RuleFor(a => a.Formats)
.NotNull();
}
}
@ -31,7 +36,9 @@ public partial class CreateDateIndexes : OperationBase, IResolvingOperation
{
private readonly IValidator<CreateDateIndexes> validator;
public CreateDateIndexes(IValidator<CreateDateIndexes> validator, Timekeeper timekeeper)
public CreateDateIndexes(
IValidator<CreateDateIndexes> validator,
Timekeeper timekeeper)
{
this.validator = validator;
this.Timekeeper = timekeeper;
@ -77,7 +84,10 @@ public partial class CreateDateIndexes : OperationBase, IResolvingOperation
// Go through the inputs and group each one. We also use `ToList` to force the enumeration to completely
// resolve and we can get everything we need. We will append the created indexes to the end of this list.
var output = input.ForEachEntity<Instant>((entity, instant) => this.GroupOnFormats(instant, entries, entity))
var output = input.SelectEntity<Instant>(
(
entity,
instant) => this.GroupOnFormats(instant, entries, entity))
.ToList();
// Going in reverse order (most precise to less precise), we create the various indexes.
@ -96,8 +106,11 @@ public partial class CreateDateIndexes : OperationBase, IResolvingOperation
// Get all the entities at this level and split them into ones we've seen (at a lower level) and which
// ones are new (these always go on the index).
var seenEntities = pair.Value.Where(a => seen.Contains(a)).ToList();
var newEntities = pair.Value.Where(a => !seen.Contains(a)).ToList();
var seenEntities = pair.Value.Where(a => seen.Contains(a))
.ToList();
var newEntities = pair.Value.Where(a => !seen.Contains(a))
.ToList();
seen.AddRange(newEntities);
@ -126,14 +139,17 @@ public partial class CreateDateIndexes : OperationBase, IResolvingOperation
}
Entity? first = pair.Value[0];
string? nextKey = this.Timekeeper.ToDateTime(first.Get<Instant>()).ToString(this.Formats[i + 1]);
string? nextKey = this.Timekeeper.ToDateTime(first.Get<Instant>())
.ToString(this.Formats[i + 1]);
if (!indexes.ContainsKey(nextKey))
{
indexes[nextKey] = new List<Entity>();
}
indexes[nextKey].Add(indexEntity);
indexes[nextKey]
.Add(indexEntity);
}
}
@ -144,10 +160,14 @@ public partial class CreateDateIndexes : OperationBase, IResolvingOperation
public CreateDateIndexes WithFormats(params string[] formats)
{
this.Formats = formats.ToList();
return this;
}
private Entity GroupOnFormats(Instant instant, List<Dictionary<string, List<Entity>>> grouped, Entity entity)
private Entity GroupOnFormats(
Instant instant,
List<Dictionary<string, List<Entity>>> grouped,
Entity entity)
{
var dateTime = this.Timekeeper.ToDateTime(instant);
@ -155,12 +175,14 @@ public partial class CreateDateIndexes : OperationBase, IResolvingOperation
{
string? formatted = dateTime.ToString(this.Formats[i]);
if (!grouped[i].ContainsKey(formatted))
if (!grouped[i]
.ContainsKey(formatted))
{
grouped[i][formatted] = new List<Entity>();
}
grouped[i][formatted].Add(entity);
grouped[i][formatted]
.Add(entity);
}
return entity;

View File

@ -6,7 +6,11 @@ namespace Nitride.Temporal;
public class DateIndex
{
public DateIndex(string key, string format, IReadOnlyList<Entity> entries, IReadOnlyList<Entity> indexes)
public DateIndex(
string key,
string format,
IReadOnlyList<Entity> entries,
IReadOnlyList<Entity> indexes)
{
this.Key = key;
this.Format = format;

View File

@ -1,5 +1,4 @@
using System.Collections.Generic;
using System.Linq;
using FluentValidation;
@ -17,7 +16,9 @@ public partial class FilterOutExpiredInstant : OperationBase
{
private readonly IValidator<FilterOutExpiredInstant> validator;
public FilterOutExpiredInstant(IValidator<FilterOutExpiredInstant> validator, Timekeeper clock)
public FilterOutExpiredInstant(
IValidator<FilterOutExpiredInstant> validator,
Timekeeper clock)
{
this.validator = validator;
this.Timekeeper = clock;
@ -35,15 +36,17 @@ public partial class FilterOutExpiredInstant : OperationBase
return input;
}
return input.ForEntities<Instant, CanExpire>(x => x.Where(this.IsNotExpired));
return input.SelectEntity<Instant, CanExpire>(this.IsNotExpired);
}
private bool IsNotExpired(Entity entity)
private Entity? IsNotExpired(
Entity entity,
Instant instant,
CanExpire _)
{
Instant instant = entity.Get<Instant>();
Instant expiration = this.Timekeeper.Expiration!.Value;
bool isExpired = instant.CompareTo(expiration) < 0;
return !isExpired;
return isExpired ? null : entity;
}
}

View File

@ -6,6 +6,7 @@ public class FilterOutExpiredInstantValidator : AbstractValidator<FilterOutExpir
{
public FilterOutExpiredInstantValidator()
{
this.RuleFor(x => x.Timekeeper).NotNull();
this.RuleFor(x => x.Timekeeper)
.NotNull();
}
}

View File

@ -25,6 +25,9 @@ public partial class FilterOutFutureInstant : OperationBase
{
Instant now = this.Timekeeper.Clock.GetCurrentInstant();
return input.WhereEntities<Instant>((_, instant) => instant.CompareTo(now) <= 0);
return input.SelectEntity<Instant>(
(
entity,
instant) => instant.CompareTo(now) <= 0 ? null : entity);
}
}

View File

@ -6,6 +6,7 @@ public class FilterOutFutureInstantValidator : AbstractValidator<FilterOutFuture
{
public FilterOutFutureInstantValidator()
{
this.RuleFor(x => x.Timekeeper).NotNull();
this.RuleFor(x => x.Timekeeper)
.NotNull();
}
}

View File

@ -11,18 +11,18 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Autofac" Version="6.4.0" />
<PackageReference Include="Gallium" Version="1.0.2" />
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="6.0.0" />
<PackageReference Include="NodaTime" Version="3.1.0" />
<PackageReference Include="NodaTime.Testing" Version="3.1.0" />
<PackageReference Include="Serilog" Version="2.11.0" />
<PackageReference Include="TimeSpanParserUtil" Version="1.2.0" />
<PackageReference Include="Zio" Version="0.15.0" />
<PackageReference Include="Autofac" Version="6.4.0"/>
<PackageReference Include="Gallium" Version="1.2.0"/>
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="6.0.0"/>
<PackageReference Include="NodaTime" Version="3.1.0"/>
<PackageReference Include="NodaTime.Testing" Version="3.1.0"/>
<PackageReference Include="Serilog" Version="2.11.0"/>
<PackageReference Include="TimeSpanParserUtil" Version="1.2.0"/>
<PackageReference Include="Zio" Version="0.15.0"/>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Nitride\Nitride.csproj" />
<ProjectReference Include="..\Nitride\Nitride.csproj"/>
</ItemGroup>
<!-- Include the source generator -->

View File

@ -36,7 +36,8 @@ public static class NitrideTemporalBuilderExtensions
// Add in the CLI options.
if (config.AddDateOptionToCommandLine)
{
x.RegisterType<DatePipelineCommandOption>().As<IPipelineCommandOption>();
x.RegisterType<DatePipelineCommandOption>()
.As<IPipelineCommandOption>();
}
if (config.AddExpireOptionToCommandLine && config.Expiration != null)
@ -56,7 +57,9 @@ public static class NitrideTemporalBuilderExtensions
if (config.DateTimeZone != null)
{
builder.ConfigureSite(
(_, scope) =>
(
_,
scope) =>
{
ILogger logger = scope.Resolve<ILogger>();
Timekeeper timekeeper = scope.Resolve<Timekeeper>();

View File

@ -33,6 +33,7 @@ public partial class NitrideTemporalConfiguration
public NitrideTemporalConfiguration WithDateTimeZone(string zoneName)
{
this.DateTimeZone = DateTimeZoneProviders.Tzdb[zoneName];
return this;
}

View File

@ -9,7 +9,12 @@ public class NitrideTemporalModule : Module
{
builder.RegisterOperators(this);
builder.RegisterValidators(this);
builder.RegisterType<Timekeeper>().AsSelf().SingleInstance();
builder.RegisterGeneric(typeof(SetInstantFromComponent<>)).As(typeof(SetInstantFromComponent<>));
builder.RegisterType<Timekeeper>()
.AsSelf()
.SingleInstance();
builder.RegisterGeneric(typeof(SetInstantFromComponent<>))
.As(typeof(SetInstantFromComponent<>));
}
}

View File

@ -42,7 +42,7 @@ public class SetInstantFromComponent<TComponent> : OperationBase
{
this.validator.ValidateAndThrow(this);
return input.ForEachEntity<TComponent>(this.Set);
return input.SelectEntity<TComponent>(this.Set);
}
/// <summary>
@ -53,10 +53,13 @@ public class SetInstantFromComponent<TComponent> : OperationBase
public SetInstantFromComponent<TComponent> WithGetDateTimeObject(Func<Entity, TComponent, object?>? callback)
{
this.GetDateTimeObject = callback;
return this;
}
private Entity Set(Entity entity, TComponent component)
private Entity Set(
Entity entity,
TComponent component)
{
object? temporal = this.GetDateTimeObject!(entity, component);
Instant instant;
@ -67,22 +70,27 @@ public class SetInstantFromComponent<TComponent> : OperationBase
return entity;
case Instant direct:
instant = direct;
break;
case LocalDate other:
instant = this.clock.CreateInstant(other);
break;
case DateTime other:
instant = this.clock.CreateInstant(other);
break;
case DateTimeOffset other:
instant = this.clock.CreateInstant(other);
break;
default:
throw new InvalidOperationException(
"Did not get a date time object from the callback. "
+ "Can only handle DateTime, DateTimeOffset, LocalDate, "
+ "and Instant. Got a "
+ temporal.GetType().Name
+ temporal.GetType()
.Name
+ " instead.");
}

View File

@ -6,6 +6,7 @@ public class SetInstantFromComponentValidator<TComponent> : AbstractValidator<Se
{
public SetInstantFromComponentValidator()
{
this.RuleFor(x => x.GetDateTimeObject).NotNull();
this.RuleFor(x => x.GetDateTimeObject)
.NotNull();
}
}

View File

@ -25,7 +25,9 @@ public partial class SetInstantFromPath : OperationBase
private readonly IValidator<SetInstantFromPath> validator;
public SetInstantFromPath(IValidator<SetInstantFromPath> validator, Timekeeper clock)
public SetInstantFromPath(
IValidator<SetInstantFromPath> validator,
Timekeeper clock)
{
this.validator = validator;
this.clock = clock;
@ -43,10 +45,12 @@ public partial class SetInstantFromPath : OperationBase
{
this.validator.ValidateAndThrow(this);
return input.ForEachEntity<UPath>(this.Set);
return input.SelectEntity<UPath>(this.Set);
}
private Entity Set(Entity entity, UPath path)
private Entity Set(
Entity entity,
UPath path)
{
// See if the path matches the given expression.
Match match = this.PathRegex!.Match(path.ToString());
@ -58,9 +62,15 @@ public partial class SetInstantFromPath : OperationBase
// Create an Instant from this.
Instant instant = this.clock.CreateInstant(
Convert.ToInt32(match.Groups["year"].Value),
Convert.ToInt32(match.Groups["month"].Value),
Convert.ToInt32(match.Groups["day"].Value));
Convert.ToInt32(
match.Groups["year"]
.Value),
Convert.ToInt32(
match.Groups["month"]
.Value),
Convert.ToInt32(
match.Groups["day"]
.Value));
return entity.Set(instant);
}

View File

@ -6,6 +6,7 @@ public class SetInstantFromPathValidator : AbstractValidator<SetInstantFromPath>
{
public SetInstantFromPathValidator()
{
this.RuleFor(x => x.PathRegex).NotNull();
this.RuleFor(x => x.PathRegex)
.NotNull();
}
}

View File

@ -37,7 +37,8 @@ public class Timekeeper
/// Gets the instant when the files expire.
/// </summary>
public Instant? Expiration => this.Expires.HasValue
? this.Clock.GetCurrentInstant().Minus(Duration.FromTimeSpan(this.Expires.Value))
? this.Clock.GetCurrentInstant()
.Minus(Duration.FromTimeSpan(this.Expires.Value))
: null;
/// <summary>
@ -53,7 +54,10 @@ public class Timekeeper
/// <param name="month">The numerical month.</param>
/// <param name="day">The numerical day of month.</param>
/// <returns>An instant in the clock's time zone.</returns>
public Instant CreateInstant(int year, int month, int day)
public Instant CreateInstant(
int year,
int month,
int day)
{
var date = new LocalDate(year, month, day);
@ -111,6 +115,8 @@ public class Timekeeper
/// <returns>A DateTime in the correct date and time.</returns>
public DateTime ToDateTime(Instant instant)
{
return instant.InZone(this.DateTimeZone).ToDateTimeOffset().DateTime;
return instant.InZone(this.DateTimeZone)
.ToDateTimeOffset()
.DateTime;
}
}

View File

@ -14,7 +14,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Gallium" Version="1.0.2"/>
<PackageReference Include="Gallium" Version="1.2.0"/>
<PackageReference Include="YamlDotNet" Version="11.2.1"/>
</ItemGroup>

View File

@ -7,7 +7,9 @@ public class NitrideYamlModule : Module
/// <inheritdoc />
protected override void Load(ContainerBuilder builder)
{
builder.RegisterGeneric(typeof(ParseYamlHeader<>)).As(typeof(ParseYamlHeader<>));
builder.RegisterGeneric(typeof(ParseYamlHeader<>))
.As(typeof(ParseYamlHeader<>));
builder.RegisterOperators(this);
builder.RegisterValidators(this);
}

View File

@ -52,7 +52,10 @@ public class ParseYamlHeader<TModel> : OperationBase
// Process through the files. We only care about the text ones
// and we'll put a default TModel in for those that don't have a
// header.
return input.ForEachEntity<ITextContent>((entity, content) => this.Parse(entity, content, deserializer));
return input.SelectEntity<ITextContent>(
(
entity,
content) => this.Parse(entity, content, deserializer));
}
/// <summary>
@ -64,6 +67,7 @@ public class ParseYamlHeader<TModel> : OperationBase
public ParseYamlHeader<TModel> WithIgnoreUnmatchedProperties(bool value)
{
this.ignoreUnmatchedProperties = value;
return this;
}
@ -76,16 +80,21 @@ public class ParseYamlHeader<TModel> : OperationBase
public ParseYamlHeader<TModel> WithNamingConvention(INamingConvention value)
{
this.namingConvention = value;
return this;
}
public ParseYamlHeader<TModel> WithRemoveHeader(bool value)
{
this.RemoveHeader = value;
return this;
}
private Entity Parse(Entity entity, ITextContent content, IDeserializer deserializer)
private Entity Parse(
Entity entity,
ITextContent content,
IDeserializer deserializer)
{
// Get the textual input from the stream.
using TextReader reader = content.GetReader();
@ -148,6 +157,8 @@ public class ParseYamlHeader<TModel> : OperationBase
}
// Set the model and return it.
return entity.Set(model).SetTextContent(new StringTextContent(buffer.ToString())).Set(HasYamlModel.Instance);
return entity.Set(model)
.SetTextContent(new StringTextContent(buffer.ToString()))
.Set(HasYamlModel.Instance);
}
}

View File

@ -20,7 +20,10 @@ public class BuildCommand : Command, ICommandHandler
private readonly PipelineManager pipelines;
public BuildCommand(ILogger logger, PipelineManager pipelines, IList<IPipelineCommandOption> pipelineOptions)
public BuildCommand(
ILogger logger,
PipelineManager pipelines,
IList<IPipelineCommandOption> pipelineOptions)
: base("build", "Generate the website")
{
// Set up our simple member variables.

View File

@ -36,7 +36,9 @@ public static class EntityBinaryContentExtensions
/// <param name="content">The content to add to the entity.</param>
/// <typeparam name="TType">The base type of the content.</typeparam>
/// <returns>The entity or a copy with the new component.</returns>
public static Entity SetBinaryContent<TType>(this Entity entity, TType content)
public static Entity SetBinaryContent<TType>(
this Entity entity,
TType content)
where TType : IBinaryContent
{
return entity.SetContent<IBinaryContent>(content);

View File

@ -19,7 +19,8 @@ public static class EntityContentExtensions
/// <returns>The one and only content component.</returns>
public static IContent GetContent(this Entity entity)
{
Type type = entity.GetComponentTypes().Single(x => typeof(IContent).IsAssignableFrom(x));
Type type = entity.GetComponentTypes()
.Single(x => typeof(IContent).IsAssignableFrom(x));
return entity.Get<IContent>(type);
}
@ -31,7 +32,8 @@ public static class EntityContentExtensions
/// <returns>True if there is a component extending `IContent`.</returns>
public static bool HasContent(this Entity entity)
{
return entity.GetComponentTypes().Any(x => typeof(IContent).IsAssignableFrom(x));
return entity.GetComponentTypes()
.Any(x => typeof(IContent).IsAssignableFrom(x));
}
/// <summary>
@ -42,10 +44,13 @@ public static class EntityContentExtensions
/// <param name="content">The content to add to the entity.</param>
/// <typeparam name="TType">The base type of the content.</typeparam>
/// <returns>The entity or a copy with the new component.</returns>
public static Entity SetContent<TType>(this Entity entity, TType content)
public static Entity SetContent<TType>(
this Entity entity,
TType content)
where TType : IContent
{
IEnumerable<Type>? existing = entity.GetComponentTypes().Where(x => typeof(IContent).IsAssignableFrom(x));
IEnumerable<Type>? existing = entity.GetComponentTypes()
.Where(x => typeof(IContent).IsAssignableFrom(x));
foreach (Type? component in existing)
{

View File

@ -26,7 +26,9 @@ public static class EntityTextContentExtensions
/// <param name="content">The content to add to the entity.</param>
/// <typeparam name="TType">The base type of the content.</typeparam>
/// <returns>The entity or a copy with the new component.</returns>
public static Entity SetTextContent<TType>(this Entity entity, TType content)
public static Entity SetTextContent<TType>(
this Entity entity,
TType content)
where TType : ITextContent
{
return entity.SetContent<ITextContent>(content);
@ -41,7 +43,9 @@ public static class EntityTextContentExtensions
/// <param name="content">The content to add to the entity.</param>
/// <typeparam name="TType">The base type of the content.</typeparam>
/// <returns>The entity or a copy with the new component.</returns>
public static Entity SetTextContent(this Entity entity, string content)
public static Entity SetTextContent(
this Entity entity,
string content)
{
return entity.SetTextContent(new StringTextContent(content));
}

View File

@ -28,7 +28,9 @@ public partial class CreateOrUpdateIndex : OperationBase
private readonly IValidator<CreateOrUpdateIndex> validator;
public CreateOrUpdateIndex(ILogger logger, IValidator<CreateOrUpdateIndex> validator)
public CreateOrUpdateIndex(
ILogger logger,
IValidator<CreateOrUpdateIndex> validator)
{
this.validator = validator;
this.logger = logger.ForContext(typeof(CreateOrUpdateIndex));
@ -65,7 +67,8 @@ public partial class CreateOrUpdateIndex : OperationBase
this.validator.ValidateAndThrow(this);
// Get the list of all the scanned entities.
var scanned = this.Scanner.GetScannedResults().ToDictionary(x => x.Key, x => x.Value);
var scanned = this.Scanner.GetScannedResults()
.ToDictionary(x => x.Key, x => x.Value);
// We loop through the results and look for index entities. Any one we
// find, we update with the existing entries. If we get to the end and

View File

@ -6,8 +6,13 @@ public class CreateOrUpdateIndexValidator : AbstractValidator<CreateOrUpdateInde
{
public CreateOrUpdateIndexValidator()
{
this.RuleFor(x => x.Scanner).NotNull();
this.RuleFor(x => x.GetIndexKey).NotNull();
this.RuleFor(x => x.UpdateIndex).NotNull();
this.RuleFor(x => x.Scanner)
.NotNull();
this.RuleFor(x => x.GetIndexKey)
.NotNull();
this.RuleFor(x => x.UpdateIndex)
.NotNull();
}
}

View File

@ -74,6 +74,7 @@ public partial class EntityScanner : OperationBase
public IEnumerable<string> GetScannedKeys()
{
this.CheckDone();
return this.results.Keys.ToImmutableList();
}
@ -114,7 +115,10 @@ public partial class EntityScanner : OperationBase
this.results.AddOrUpdate(
key,
_ => new List<Entity> { entity },
(_, list) => list.Union(new[] { entity }).ToList());
(
_,
list) => list.Union(new[] { entity })
.ToList());
}
}

View File

@ -6,6 +6,7 @@ public class EntityScannerValidator : AbstractValidator<EntityScanner>
{
public EntityScannerValidator()
{
this.RuleFor(x => x.GetKeysFromEntity).NotNull();
this.RuleFor(x => x.GetKeysFromEntity)
.NotNull();
}
}

View File

@ -9,7 +9,9 @@ namespace Nitride.Entities;
/// </summary>
public class EntitySequence
{
public EntitySequence(IReadOnlyList<Entity> sequence, int index)
public EntitySequence(
IReadOnlyList<Entity> sequence,
int index)
{
this.Sequence = sequence;
this.Index = index;

View File

@ -20,8 +20,14 @@ public partial class LinkEntitySequence : OperationBase, IResolvingOperation
public LinkEntitySequence(IValidator<LinkEntitySequence> validator)
{
this.validator = validator;
this.CreateSequenceIndex = (list, index) => new EntitySequence(list, index);
this.AddSequenceIndex = (entity, sequence) => entity.Add(sequence);
this.CreateSequenceIndex = (
list,
index) => new EntitySequence(list, index);
this.AddSequenceIndex = (
entity,
sequence) => entity.Add(sequence);
}
/// <summary>

View File

@ -6,7 +6,10 @@ public class LinkEntitySequenceValidator : AbstractValidator<LinkEntitySequence>
{
public LinkEntitySequenceValidator()
{
this.RuleFor(x => x.CreateSequenceIndex).NotNull();
this.RuleFor(x => x.AddSequenceIndex).NotNull();
this.RuleFor(x => x.CreateSequenceIndex)
.NotNull();
this.RuleFor(x => x.AddSequenceIndex)
.NotNull();
}
}

View File

@ -15,21 +15,21 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Autofac" Version="6.4.0" />
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="8.0.0" />
<PackageReference Include="FluentValidation" Version="11.0.2" />
<PackageReference Include="Gallium" Version="1.0.2" />
<PackageReference Include="Humanizer.Core" Version="2.14.1" />
<PackageReference Include="MfGames.ToolBuilder" Version="4.0.2" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="6.0.1" />
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="6.0.0" />
<PackageReference Include="Serilog" Version="2.11.0" />
<PackageReference Include="Serilog.Extensions.Autofac.DependencyInjection" Version="5.0.0" />
<PackageReference Include="Serilog.Extensions.Hosting" Version="4.2.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="4.0.1" />
<PackageReference Include="SerilogAnalyzer" Version="0.15.0" />
<PackageReference Include="System.CommandLine" Version="[2.0.0-beta3.22114.1,)" />
<PackageReference Include="Zio" Version="0.15.0" />
<PackageReference Include="Autofac" Version="6.4.0"/>
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="8.0.0"/>
<PackageReference Include="FluentValidation" Version="11.1.0"/>
<PackageReference Include="Gallium" Version="1.2.0"/>
<PackageReference Include="Humanizer.Core" Version="2.14.1"/>
<PackageReference Include="MfGames.ToolBuilder" Version="4.0.2"/>
<PackageReference Include="Microsoft.Extensions.Hosting" Version="6.0.1"/>
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="6.0.0"/>
<PackageReference Include="Serilog" Version="2.11.0"/>
<PackageReference Include="Serilog.Extensions.Autofac.DependencyInjection" Version="5.0.0"/>
<PackageReference Include="Serilog.Extensions.Hosting" Version="4.2.0"/>
<PackageReference Include="Serilog.Sinks.Console" Version="4.0.1"/>
<PackageReference Include="SerilogAnalyzer" Version="0.15.0"/>
<PackageReference Include="System.CommandLine" Version="[2.0.0-beta3.22114.1,)"/>
<PackageReference Include="Zio" Version="0.15.0"/>
</ItemGroup>
<!-- Include the source generator -->

View File

@ -40,7 +40,10 @@ public class NitrideBuilder
this.configureSiteCallbacks = new List<Action<NitrideBuilder, ILifetimeScope>>();
this.configureContainerCallbacks = new List<Action<ContainerBuilder>>();
this.nitrideModule = new NitrideModule();
this.nitrideModule.ApplicationName = Assembly.GetExecutingAssembly().GetName().Name!;
this.nitrideModule.ApplicationName = Assembly.GetExecutingAssembly()
.GetName()
.Name!;
}
/// <summary>
@ -59,6 +62,7 @@ public class NitrideBuilder
public NitrideBuilder ConfigureContainer(Action<ContainerBuilder> callback)
{
this.configureContainerCallbacks.Add(callback);
return this;
}
@ -71,6 +75,7 @@ public class NitrideBuilder
public NitrideBuilder ConfigureSite(Action<NitrideBuilder, ILifetimeScope> callback)
{
this.configureSiteCallbacks.Add(callback);
return this;
}
@ -99,6 +104,7 @@ public class NitrideBuilder
public NitrideBuilder WithApplicationDescription(string value)
{
this.nitrideModule.Description = value;
return this;
}
@ -108,6 +114,7 @@ public class NitrideBuilder
public NitrideBuilder WithApplicationName(string value)
{
this.nitrideModule.ApplicationName = value;
return this;
}
@ -124,6 +131,7 @@ public class NitrideBuilder
public NitrideBuilder WithRootDirectory(DirectoryInfo directory)
{
this.RootDirectory = directory;
return this;
}
@ -148,11 +156,14 @@ public class NitrideBuilder
}
}
private void RegisterRootDirectory(ILogger logger, ContainerBuilder builder)
private void RegisterRootDirectory(
ILogger logger,
ContainerBuilder builder)
{
if (this.RootDirectory == null)
{
logger.Verbose("No root directory is registered");
return;
}
@ -161,6 +172,8 @@ public class NitrideBuilder
var rootFileSystem = new PhysicalFileSystem();
var subFileSystem = new SubFileSystem(rootFileSystem, this.RootDirectory.FullName);
builder.RegisterInstance(subFileSystem).As<IFileSystem>().SingleInstance();
builder.RegisterInstance(subFileSystem)
.As<IFileSystem>()
.SingleInstance();
}
}

View File

@ -4,7 +4,6 @@ using System.CommandLine;
using Autofac;
using Nitride.Commands;
using Nitride.Entities;
using Nitride.Pipelines;
namespace Nitride;
@ -22,15 +21,22 @@ public class NitrideModule : Module
protected override void Load(ContainerBuilder builder)
{
// Pipelines
builder.RegisterType<PipelineRunner>().AsSelf();
builder.RegisterType<PipelineManager>().AsSelf().SingleInstance();
builder.RegisterType<PipelineRunner>()
.AsSelf();
builder.RegisterType<PipelineManager>()
.AsSelf()
.SingleInstance();
// Operations
builder.RegisterValidators(this);
builder.RegisterOperators(this);
// Commands
builder.RegisterType<BuildCommand>().AsSelf().As<Command>().SingleInstance();
builder.RegisterType<BuildCommand>()
.AsSelf()
.As<Command>()
.SingleInstance();
// MfGames.ToolBuilder requires the RootCommand to be registered. This is because
// of various things, mostly coordinating between different systems.

View File

@ -6,13 +6,24 @@ namespace Nitride;
public static class NitrideModuleExtensions
{
public static void RegisterOperators(this ContainerBuilder builder, Module module)
public static void RegisterOperators(
this ContainerBuilder builder,
Module module)
{
builder.RegisterAssemblyTypes(module.GetType().Assembly).Where(x => x.IsAssignableTo<IOperation>()).AsSelf();
builder.RegisterAssemblyTypes(
module.GetType()
.Assembly)
.Where(x => x.IsAssignableTo<IOperation>())
.AsSelf();
}
public static void RegisterValidators(this ContainerBuilder builder, Module module)
public static void RegisterValidators(
this ContainerBuilder builder,
Module module)
{
builder.RegisterAssemblyTypes(module.GetType().Assembly).AsClosedTypesOf(typeof(IValidator<>));
builder.RegisterAssemblyTypes(
module.GetType()
.Assembly)
.AsClosedTypesOf(typeof(IValidator<>));
}
}

View File

@ -16,7 +16,9 @@ public static class NitrideOperationExtensions
/// <param name="input">The entities to perform the operation against.</param>
/// <param name="operation">The operation to run.</param>
/// <returns>The results of the operation.</returns>
public static IEnumerable<Entity> Run(this IEnumerable<Entity> input, IOperation operation)
public static IEnumerable<Entity> Run(
this IEnumerable<Entity> input,
IOperation operation)
{
return operation.Run(input);
}

View File

@ -20,6 +20,7 @@ public abstract class PipelineBase : IPipeline
public PipelineBase AddDependency(IPipeline pipeline)
{
this.dependencies.Add(pipeline);
return this;
}
@ -35,6 +36,7 @@ public abstract class PipelineBase : IPipeline
/// <inheritdoc />
public override string ToString()
{
return this.GetType().Name;
return this.GetType()
.Name;
}
}

View File

@ -26,7 +26,10 @@ public class PipelineManager
private ICollection<IPipeline> pipelines;
public PipelineManager(ILogger logger, IEnumerable<IPipeline> pipelines, PipelineRunner.Factory createEntry)
public PipelineManager(
ILogger logger,
IEnumerable<IPipeline> pipelines,
PipelineRunner.Factory createEntry)
{
this.createEntry = createEntry;
this.logger = logger.ForContext<PipelineManager>();
@ -59,21 +62,26 @@ public class PipelineManager
// resulting tasks and then wait for all of them to end.
this.logger.Verbose("Starting {Count:l}", "pipeline".ToQuantity(this.pipelines.Count));
Task[] tasks = this.entries.Select(x => Task.Run(async () => await x.RunAsync())).ToArray();
Task[] tasks = this.entries.Select(x => Task.Run(async () => await x.RunAsync()))
.ToArray();
var report = TimeSpan.FromSeconds(15);
while (!Task.WaitAll(tasks, report))
{
var waiting = this.entries.Where(x => !x.IsFinished).ToList();
var waiting = this.entries.Where(x => !x.IsFinished)
.ToList();
this.logger.Debug("Waiting for {Count:l} to finish running", "pipeline".ToQuantity(waiting.Count));
IOrderedEnumerable<IGrouping<PipelineRunnerState, PipelineRunner>> states =
waiting.GroupBy(x => x.State, x => x).OrderBy(x => (int)x.Key);
waiting.GroupBy(x => x.State, x => x)
.OrderBy(x => (int)x.Key);
foreach (IGrouping<PipelineRunnerState, PipelineRunner>? state in states)
{
var statePipelines = state.OrderBy(x => x.Pipeline.ToString()).ToList();
var statePipelines = state.OrderBy(x => x.Pipeline.ToString())
.ToList();
this.logger.Verbose(
"Waiting for {Count:l} in {State}: {List:l}",
@ -120,12 +128,14 @@ public class PipelineManager
// Wrap all the pipelines into entries. We do this before the next
// step so we can have the entries depend on the entries.
this.entries = this.pipelines.Select(x => this.createEntry(x)).ToList();
this.entries = this.pipelines.Select(x => this.createEntry(x))
.ToList();
// Go through and connect the pipelines together.
foreach (PipelineRunner? entry in this.entries)
{
var dependencies = entry.Pipeline.GetDependencies().ToList();
var dependencies = entry.Pipeline.GetDependencies()
.ToList();
foreach (IPipeline? dependency in dependencies)
{

View File

@ -46,7 +46,9 @@ public class PipelineRunner
/// </summary>
private int waitingOnConsumers;
public PipelineRunner(ILogger logger, IPipeline pipeline)
public PipelineRunner(
ILogger logger,
IPipeline pipeline)
{
this.Pipeline = pipeline ?? throw new ArgumentNullException(nameof(pipeline));
this.Incoming = new List<PipelineRunner>();
@ -159,6 +161,7 @@ public class PipelineRunner
+ " state (not Initialized or Finalized)",
this.Pipeline,
this.State);
break;
}
@ -175,6 +178,7 @@ public class PipelineRunner
if (this.WaitForDependencies())
{
this.SignalDoneWithInputs();
return;
}
@ -233,6 +237,7 @@ public class PipelineRunner
newState,
this.ElapsedFromInitialized,
this.ElapsedFromState);
this.changed = DateTime.Now;
this.State = newState;
}
@ -250,7 +255,8 @@ public class PipelineRunner
this.Pipeline,
this.Incoming.Count);
var input = this.Incoming.SelectMany(x => x.Outputs).ToList();
var input = this.Incoming.SelectMany(x => x.Outputs)
.ToList();
this.logger.Debug(
"{Pipeline:l}: Got {Count:l} from dependencies",
@ -324,6 +330,7 @@ public class PipelineRunner
// Wait for the dependencies to run first.
this.ChangeState(PipelineRunnerState.Waiting);
this.logger.Verbose(
"{Pipeline:l}: Waiting for {Count:l} to complete",
this.Pipeline,

View File

@ -2,8 +2,8 @@
## Immediate
- Switch the various operations to be async
- ReadFiles
- WriteFiles
- Implement mime type determination
- Implement a convert to text content based on mime type
- Switch the various operations to be async
- ReadFiles
- WriteFiles
- Implement mime type determination
- Implement a convert to text content based on mime type

View File

@ -6,22 +6,22 @@
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Nitride.IO\Nitride.IO.csproj" />
<ProjectReference Include="..\Nitride.Tests\Nitride.Tests.csproj" />
<ProjectReference Include="..\..\src\Nitride.IO\Nitride.IO.csproj"/>
<ProjectReference Include="..\Nitride.Tests\Nitride.Tests.csproj"/>
</ItemGroup>
<ItemGroup>
<PackageReference Include="CompareNETObjects" Version="4.77.0" />
<PackageReference Include="Gallium" Version="1.0.2" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.2.0" />
<PackageReference Include="JunitXml.TestLogger" Version="3.0.114" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="CompareNETObjects" Version="4.77.0"/>
<PackageReference Include="Gallium" Version="1.2.0"/>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.2.0"/>
<PackageReference Include="JunitXml.TestLogger" Version="3.0.114"/>
<PackageReference Include="Newtonsoft.Json" Version="13.0.1"/>
<PackageReference Include="xunit" Version="2.4.1"/>
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Zio" Version="0.15.0" />
<PackageReference Include="Zio" Version="0.15.0"/>
<PackageReference Include="coverlet.collector" Version="3.1.2">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>

Some files were not shown because too many files have changed in this diff Show More