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.severity = warning
dotnet_naming_rule.private_instance_fields_rule.style = lower_camel_case_style 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_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.import_to_resharper = as_predefined
dotnet_naming_rule.private_static_fields_rule.resharper_style = AaBb, aaBb 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.severity = warning
dotnet_naming_rule.private_static_fields_rule.style = upper_camel_case_style 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.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.import_to_resharper = as_predefined
dotnet_naming_rule.private_static_readonly_rule.severity = warning dotnet_naming_rule.private_static_readonly_rule.severity = warning
dotnet_naming_rule.private_static_readonly_rule.style = upper_camel_case_style 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_constants_symbols.required_modifiers = const
dotnet_naming_symbols.private_instance_fields_symbols.applicable_accessibilities = private dotnet_naming_symbols.private_instance_fields_symbols.applicable_accessibilities = private
dotnet_naming_symbols.private_instance_fields_symbols.applicable_kinds = field 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_accessibilities = private
dotnet_naming_symbols.private_static_fields_symbols.applicable_kinds = field 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.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_accessibilities = private
dotnet_naming_symbols.private_static_readonly_symbols.applicable_kinds = field dotnet_naming_symbols.private_static_readonly_symbols.applicable_kinds = field
dotnet_naming_symbols.private_static_readonly_symbols.required_modifiers = static, readonly 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 properties
resharper_alignment_tab_fill_style = optimal_fill resharper_alignment_tab_fill_style = optimal_fill
resharper_align_multiline_binary_expressions_chain = false resharper_align_multiline_binary_expressions_chain = false
resharper_align_multiline_statement_conditions = false
resharper_apply_on_completion = true resharper_apply_on_completion = true
resharper_autodetect_indent_settings = true
resharper_blank_lines_after_control_transfer_statements = 1 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_auto_property = 1
resharper_blank_lines_around_single_line_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_blank_lines_before_single_line_comment = 1
resharper_braces_for_for = required resharper_braces_for_for = required
resharper_braces_for_foreach = 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_declaration_parens_arrangement = false
resharper_keep_existing_embedded_block_arrangement = true resharper_keep_existing_embedded_block_arrangement = true
resharper_keep_existing_enum_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_min_blank_lines_after_imports = 1
resharper_nested_ternary_style = expanded resharper_nested_ternary_style = expanded
resharper_new_line_before_while = true 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_protobuf_insert_final_newline = true
resharper_qualified_using_at_nested_scope = true resharper_qualified_using_at_nested_scope = true
resharper_resx_alignment_tab_fill_style = optimal_fill 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_t4_insert_final_newline = true
resharper_use_continuous_indent_inside_initializer_braces = false resharper_use_continuous_indent_inside_initializer_braces = false
resharper_use_indents_from_main_language_in_file = 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_first_type_parameter_constraint = true
resharper_wrap_before_type_parameter_langle = true resharper_wrap_before_type_parameter_langle = true
resharper_wrap_chained_binary_expressions = chop_if_long 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_wrap_object_and_collection_initializer_style = chop_always
resharper_xmldoc_alignment_tab_fill_style = optimal_fill resharper_xmldoc_alignment_tab_fill_style = optimal_fill
resharper_xmldoc_indent_child_elements = ZeroIndent 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_for_member_access_highlighting = hint
resharper_built_in_type_reference_style_highlighting = hint resharper_built_in_type_reference_style_highlighting = hint
resharper_check_namespace_highlighting = none resharper_check_namespace_highlighting = none
resharper_class_never_instantiated_global_highlighting = none
resharper_convert_to_auto_property_highlighting = none resharper_convert_to_auto_property_highlighting = none
resharper_localizable_element_highlighting = none resharper_localizable_element_highlighting = none
resharper_redundant_comma_in_attribute_list_highlighting = none resharper_redundant_comma_in_attribute_list_highlighting = none
@ -205,3 +230,8 @@ tab_width = 4
indent_style = space indent_style = space
indent_size = 4 indent_size = 4
tab_width = 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_CODE/@EntryValue">1</s:Int64>
<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/KEEP_BLANK_LINES_IN_DECLARATIONS/@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_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: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/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_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> <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_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: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: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_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/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/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> <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: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/CustomProperties/=minimumLanguageVersion/@EntryIndexedValue">2.0</s:String>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=F87CBA43E9CDCC41A45B39A2A2A25764/Scope/=2C285F182AC98D44B0B4F29D4D2149EC/Type/@EntryValue">InCSharpStatement</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> <s:Boolean x:Key="/Default/UserDictionary/Words/=Tocks/@EntryIndexedValue">True</s:Boolean>
</wpf:ResourceDictionary> </wpf:ResourceDictionary>

View file

@ -10,6 +10,11 @@ public class CopyFilesModule : Module
// This just registers all the non-static classes as singletons // This just registers all the non-static classes as singletons
// within the system. We use lifetimes in other components depending // within the system. We use lifetimes in other components depending
// on how they are used, but in this case, we don't need it. // 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: // read. Coming out of this, we will have one entity that fulfills:
// //
// entity.Get<UPath> == "/output/a.txt" // 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 // 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 // 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 // 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 // chain calls, ala Gulp's pipelines. The below code does this along
// with writing the files to the output. // 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 // If we are chaining this pipeline into another, we return the
// entities. Otherwise, we can just return an empty list. 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. // Figure out the paths for this test.
DirectoryInfo rootDir = DirectoryInfo rootDir =
typeof(CopyFilesProgram).GetDirectory()!.FindGitRoot()!.GetDirectory("examples/CopyFiles"); typeof(CopyFilesProgram).GetDirectory()!.FindGitRoot()!.GetDirectory("examples/CopyFiles");
DirectoryInfo outputDir = rootDir.GetDirectory("output"); DirectoryInfo outputDir = rootDir.GetDirectory("output");
FileInfo projectFile = rootDir.GetFile("CopyFiles.csproj"); 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. // Execute the generator. This will throw if there is an exception.
await Cli.Wrap("dotnet") 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(); .ExecuteAsync();
// Make sure we have our output. // Make sure we have our output.
@ -49,7 +55,8 @@ public class CopyFilesTest : NitrideTestBase
Assert.True(aFile.Exists); Assert.True(aFile.Exists);
string aText = aFile.ReadAllText().Trim(); string aText = aFile.ReadAllText()
.Trim();
Assert.Equal("This is the 'A' file.", aText); Assert.Equal("This is the 'A' file.", aText);
} }

View file

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

View file

@ -6,8 +6,13 @@ public class CreateCalendarValidator : AbstractValidator<CreateCalender>
{ {
public CreateCalendarValidator() public CreateCalendarValidator()
{ {
this.RuleFor(x => x.Path).NotNull(); this.RuleFor(x => x.Path)
this.RuleFor(x => x.GetEventSummary).NotNull(); .NotNull();
this.RuleFor(x => x.GetEventUrl).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; private readonly IValidator<CreateCalender> validator;
public CreateCalender(IValidator<CreateCalender> validator, Timekeeper clock) public CreateCalender(
IValidator<CreateCalender> validator,
Timekeeper clock)
{ {
this.validator = validator; this.validator = validator;
this.clock = clock; this.clock = clock;
@ -59,9 +61,12 @@ public partial class CreateCalender : OperationBase
{ {
this.validator.ValidateAndThrow(this); 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) private IEnumerable<Entity> CreateCalendarEntity(IEnumerable<Entity> entities)
@ -96,6 +101,7 @@ public partial class CreateCalender : OperationBase
var when = this.clock.ToDateTime(instant); var when = this.clock.ToDateTime(instant);
string summary = this.GetEventSummary!(entity); string summary = this.GetEventSummary!(entity);
Uri? url = this.GetEventUrl?.Invoke(entity); Uri? url = this.GetEventUrl?.Invoke(entity);
var calendarEvent = new CalendarEvent var calendarEvent = new CalendarEvent
{ {
Summary = summary, Summary = summary,

View file

@ -16,7 +16,7 @@
</ItemGroup> </ItemGroup>
<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="Ical.Net" Version="4.2.0"/>
<PackageReference Include="NodaTime" Version="3.1.0"/> <PackageReference Include="NodaTime" Version="3.1.0"/>
<PackageReference Include="Zio" Version="0.15.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) 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; private readonly IValidator<CreateAtomFeed> validator;
public CreateAtomFeed(ILogger logger, IValidator<CreateAtomFeed> validator) public CreateAtomFeed(
ILogger logger,
IValidator<CreateAtomFeed> validator)
{ {
this.logger = logger; this.logger = logger;
this.validator = validator; this.validator = validator;
@ -121,7 +123,9 @@ public partial class CreateAtomFeed : OperationBase
} }
// Create the feed entity and return both objects. // 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 }; return new[] { entity, feedEntity };
} }

View file

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

View file

@ -16,7 +16,7 @@
</ItemGroup> </ItemGroup>
<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="NodaTime" Version="3.1.0"/>
<PackageReference Include="Zio" Version="0.15.0"/> <PackageReference Include="Zio" Version="0.15.0"/>
</ItemGroup> </ItemGroup>

View file

@ -8,6 +8,7 @@ public static class NitrideFeedsBuilderExtensions
{ {
public static NitrideBuilder UseFeeds(this NitrideBuilder builder) 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> /// </summary>
public static class AtomHelper public static class AtomHelper
{ {
public static void AddIfSet(XElement root, XElement? elem) public static void AddIfSet(
XElement root,
XElement? elem)
{ {
if (elem != null) 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)) if (!string.IsNullOrWhiteSpace(text))
{ {

View file

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

View file

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

View file

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

View file

@ -6,8 +6,13 @@ public class ApplyStyleTemplateValidator<TModel> : AbstractValidator<ApplyStyleT
{ {
public ApplyStyleTemplateValidator() public ApplyStyleTemplateValidator()
{ {
this.RuleFor(x => x.Handlebars).NotNull(); this.RuleFor(x => x.Handlebars)
this.RuleFor(x => x.GetTemplateName).NotNull(); .NotNull();
this.RuleFor(x => x.CreateModelCallback).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() 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 /> /// <inheritdoc />
public IEnumerable<Entity> Run(IEnumerable<Entity> input) 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(); string text = content.GetText();

View file

@ -11,7 +11,7 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="Autofac" Version="6.4.0"/> <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="Handlebars.Net" Version="2.1.2"/>
<PackageReference Include="NodaTime.Testing" Version="3.1.0"/> <PackageReference Include="NodaTime.Testing" Version="3.1.0"/>
<PackageReference Include="Open.Threading" Version="2.2.0"/> <PackageReference Include="Open.Threading" Version="2.2.0"/>

View file

@ -10,8 +10,14 @@ public class NitrideHandlebarsModule : Module
builder.RegisterOperators(this); builder.RegisterOperators(this);
builder.RegisterValidators(this); builder.RegisterValidators(this);
builder.RegisterType<HandlebarsTemplateCache>().AsSelf().SingleInstance(); builder.RegisterType<HandlebarsTemplateCache>()
builder.RegisterGeneric(typeof(RenderContentTemplate<>)).As(typeof(RenderContentTemplate<>)); .AsSelf()
builder.RegisterGeneric(typeof(ApplyStyleTemplate<>)).As(typeof(ApplyStyleTemplate<>)); .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); this.validator.ValidateAndThrow(this);
return input.ForEachEntity<HasHandlebarsTemplate, ITextContent>(this.Apply); return input.SelectEntity<HasHandlebarsTemplate, ITextContent>(this.Apply);
} }
/// <summary> /// <summary>
@ -55,10 +55,14 @@ public class RenderContentTemplate<TModel> : OperationBase
public RenderContentTemplate<TModel> WithCreateModelCallback(Func<Entity, TModel>? callback) public RenderContentTemplate<TModel> WithCreateModelCallback(Func<Entity, TModel>? callback)
{ {
this.CreateModelCallback = callback; this.CreateModelCallback = callback;
return this; return this;
} }
private Entity Apply(Entity entity, HasHandlebarsTemplate _, ITextContent content) private Entity Apply(
Entity entity,
HasHandlebarsTemplate _,
ITextContent content)
{ {
// Create the model using the callback. // Create the model using the callback.
TModel model = this.CreateModelCallback!(entity); TModel model = this.CreateModelCallback!(entity);
@ -71,6 +75,7 @@ public class RenderContentTemplate<TModel> : OperationBase
// text. // text.
string result = template(model!); 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() 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 /> /// <inheritdoc />
public override IEnumerable<Entity> Run(IEnumerable<Entity> input) 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 text = content.GetText();
string resolved = WebUtility.HtmlDecode(text); string resolved = WebUtility.HtmlDecode(text);

View file

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

View file

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

View file

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

View file

@ -6,9 +6,16 @@ public class WriteFilesValidator : AbstractValidator<WriteFiles>
{ {
public WriteFilesValidator() public WriteFilesValidator()
{ {
this.RuleFor(x => x.StreamFactories).NotNull(); this.RuleFor(x => x.StreamFactories)
this.RuleFor(x => x.TextEncoding).NotNull(); .NotNull();
this.RuleFor(x => x.FileSystem).NotNull();
this.RuleFor(x => x.Logger).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; 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) : base(fileSystem)
{ {
this.Logger = logger; this.Logger = logger;
@ -87,6 +90,7 @@ public partial class ClearDirectory : FileSystemOperationBase, IOperation
public ClearDirectory WithFileSystem(IFileSystem value) public ClearDirectory WithFileSystem(IFileSystem value)
{ {
this.FileSystem = value; this.FileSystem = value;
return this; return this;
} }
} }

View file

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

View file

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

View file

@ -15,7 +15,9 @@ public partial class AddPathPrefix : OperationBase
private readonly IValidator<AddPathPrefix> validator; private readonly IValidator<AddPathPrefix> validator;
public AddPathPrefix(IValidator<AddPathPrefix> validator, ReplacePath replacePath) public AddPathPrefix(
IValidator<AddPathPrefix> validator,
ReplacePath replacePath)
{ {
this.validator = validator; this.validator = validator;
this.replacePath = replacePath; this.replacePath = replacePath;
@ -30,12 +32,17 @@ public partial class AddPathPrefix : OperationBase
{ {
this.validator.ValidateAndThrow(this); 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; return this.PathPrefix!.Value / innerRelativePath;
} }
} }

View file

@ -6,6 +6,7 @@ public class AddPathPrefixValidator : AbstractValidator<AddPathPrefix>
{ {
public AddPathPrefixValidator() 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; private readonly IValidator<ChangePathExtension> validator;
public ChangePathExtension(IValidator<ChangePathExtension> validator, ReplacePath replacePath) public ChangePathExtension(
IValidator<ChangePathExtension> validator,
ReplacePath replacePath)
{ {
this.validator = validator; this.validator = validator;
this.replacePath = replacePath; this.replacePath = replacePath;
@ -33,10 +35,13 @@ public partial class ChangePathExtension : IOperation
{ {
this.validator.ValidateAndThrow(this); 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!); return path.ChangeExtension(this.Extension!);
} }

View file

@ -6,6 +6,7 @@ public class ChangePathExtensionValidator : AbstractValidator<ChangePathExtensio
{ {
public ChangePathExtensionValidator() 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 public partial class LinkDirectChildren : CreateOrUpdateIndex
{ {
/// <inheritdoc /> /// <inheritdoc />
public LinkDirectChildren(ILogger logger, IValidator<CreateOrUpdateIndex> validator) public LinkDirectChildren(
ILogger logger,
IValidator<CreateOrUpdateIndex> validator)
: base(logger, validator) : base(logger, validator)
{ {
this.UpdateIndex = this.InternalUpdateIndex; this.UpdateIndex = this.InternalUpdateIndex;
this.GetIndexKey = e => e.Get<UPath>().GetDirectoryIndexPath();
this.GetIndexKey = e => e.Get<UPath>()
.GetDirectoryIndexPath();
} }
/// <inheritdoc /> /// <inheritdoc />
@ -34,12 +38,16 @@ public partial class LinkDirectChildren : CreateOrUpdateIndex
this.Scanner = new DirectChildPathScanner(new EntityScannerValidator()); this.Scanner = new DirectChildPathScanner(new EntityScannerValidator());
input = this.Scanner.Run(input).ToList(); input = this.Scanner.Run(input)
.ToList();
return base.Run(input); 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)); return entity.Add(new DirectChildEntityList(list));
} }

View file

@ -19,7 +19,9 @@ public partial class MoveToIndexPath : OperationBase
private readonly IValidator<MoveToIndexPath> validator; private readonly IValidator<MoveToIndexPath> validator;
public MoveToIndexPath(IValidator<MoveToIndexPath> validator, ReplacePath replacePath) public MoveToIndexPath(
IValidator<MoveToIndexPath> validator,
ReplacePath replacePath)
{ {
this.validator = validator; this.validator = validator;
this.replacePath = replacePath; this.replacePath = replacePath;
@ -54,10 +56,13 @@ public partial class MoveToIndexPath : OperationBase
{ {
this.validator.ValidateAndThrow(this); 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 // See if we are already an index. If that is true, then we don't
// have to move any further. // have to move any further.

View file

@ -6,6 +6,7 @@ public class MoveToIndexPathValidator : AbstractValidator<MoveToIndexPath>
{ {
public MoveToIndexPathValidator() 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; private readonly IValidator<RemovePathPrefix> validator;
public RemovePathPrefix(IValidator<RemovePathPrefix> validator, ReplacePath replacePath) public RemovePathPrefix(
IValidator<RemovePathPrefix> validator,
ReplacePath replacePath)
{ {
this.validator = validator; this.validator = validator;
this.replacePath = replacePath; this.replacePath = replacePath;
@ -33,17 +35,21 @@ public partial class RemovePathPrefix : IOperation
{ {
this.validator.ValidateAndThrow(this); 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 normalized = path.ToString();
string prefix = this.PathPrefix.ToString()!; string prefix = this.PathPrefix.ToString()!;
if (normalized.StartsWith(prefix)) if (normalized.StartsWith(prefix))
{ {
return (UPath)path.ToString().Substring(prefix.Length); return (UPath)path.ToString()
.Substring(prefix.Length);
} }
return path; return path;

View file

@ -6,6 +6,7 @@ public class RemovePathPrefixValidator : AbstractValidator<RemovePathPrefix>
{ {
public RemovePathPrefixValidator() 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); this.validator.ValidateAndThrow(this);
return input.ForEachEntity<UPath>( return input.SelectEntity<UPath>(
(entity, oldPath) => (
entity,
oldPath) =>
{ {
UPath newPath = this.Replacement(entity, oldPath); UPath newPath = this.Replacement(entity, oldPath);

View file

@ -6,6 +6,7 @@ public class ReplacePathValidator : AbstractValidator<ReplacePath>
{ {
public ReplacePathValidator() 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") if (path.GetNameWithoutExtension() == "index")
{ {
return path.GetDirectory().ToString().TrimEnd('/') + "/"; return path.GetDirectory()
.ToString()
.TrimEnd('/')
+ "/";
} }
return path.ToString(); return path.ToString();
@ -33,7 +36,9 @@ public static class UPathExtensions
parent = "/"; parent = "/";
} }
string parentPath = parent.ToString().TrimEnd('/') + "/"; string parentPath = parent.ToString()
.TrimEnd('/')
+ "/";
return parentPath; 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 along with various processes to manipulate paths. It contains three primary
components: components:
- File System I/O - File System I/O
- Path Normalization - Path Normalization
- Disk-Based Content - Disk-Based Content
## File System I/O ## File System I/O

View file

@ -41,8 +41,11 @@ public abstract partial class ConvertMarkdownToBase : IOperation
MarkdownPipeline options = builder.Build(); MarkdownPipeline options = builder.Build();
// Process the Markdown files (while passing everything on). // Process the Markdown files (while passing everything on).
return input.ForEachEntity<IsMarkdown, ITextContent>( return input.SelectEntity<IsMarkdown, ITextContent>(
(entity, _, content) => this.Convert(entity, content, options)); (
entity,
_,
content) => this.Convert(entity, content, options));
} }
/// <summary> /// <summary>
@ -52,5 +55,8 @@ public abstract partial class ConvertMarkdownToBase : IOperation
/// <param name="markdownContent">The content for this entity.</param> /// <param name="markdownContent">The content for this entity.</param>
/// <param name="options">The markdown pipeline.</param> /// <param name="options">The markdown pipeline.</param>
/// <returns>A converted entity.</returns> /// <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() 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) public override ConvertMarkdownToGemtext WithConfigureMarkdown(Action<MarkdownPipelineBuilder>? value)
{ {
base.WithConfigureMarkdown(value); base.WithConfigureMarkdown(value);
return this; return this;
} }
@ -39,13 +40,18 @@ public class ConvertMarkdownToGemtext : ConvertMarkdownToBase
/// <param name="markdownContent">The content for this entity.</param> /// <param name="markdownContent">The content for this entity.</param>
/// <param name="options">The markdown pipeline.</param> /// <param name="options">The markdown pipeline.</param>
/// <returns>A converted entity.</returns> /// <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 markdown = markdownContent.GetText();
string gemtext = MarkdownGemtext.ToGemtext(markdown, options); string gemtext = MarkdownGemtext.ToGemtext(markdown, options);
var content = new StringTextContent(gemtext); 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; return entity;
} }

View file

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

View file

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

View file

@ -14,7 +14,9 @@ public class IdentifyMarkdownFromPath : IdentifyMarkdown
this.IsMarkdownTest = DefaultIsMarkdown; 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 return (path.GetExtensionWithDot() ?? string.Empty).ToLowerInvariant() switch
{ {

View file

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

View file

@ -16,7 +16,7 @@
</ItemGroup> </ItemGroup>
<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="Markdig" Version="0.30.2"/>
<PackageReference Include="MfGames.Markdown.Gemtext" Version="1.2.1"/> <PackageReference Include="MfGames.Markdown.Gemtext" Version="1.2.1"/>
<PackageReference Include="Zio" Version="0.15.0"/> <PackageReference Include="Zio" Version="0.15.0"/>

View file

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

View file

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

View file

@ -34,7 +34,10 @@ public class UnicodeNormalizingSlugConverter : SimpleSlugConverter
// Normalize the Unicode objects. // Normalize the Unicode objects.
// Strip out the accents. This is a cheesy way of doing so. // 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); string normalized = new string(chars).Normalize(NormalizationForm.FormC);
// Return the base implementation. // Return the base implementation.

View file

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

View file

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

View file

@ -14,9 +14,14 @@ public class CreateDateIndexesValidator : AbstractValidator<CreateDateIndexes>
{ {
public CreateDateIndexesValidator() public CreateDateIndexesValidator()
{ {
this.RuleFor(a => a.Timekeeper).NotNull(); this.RuleFor(a => a.Timekeeper)
this.RuleFor(a => a.CreateIndex).NotNull(); .NotNull();
this.RuleFor(a => a.Formats).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; private readonly IValidator<CreateDateIndexes> validator;
public CreateDateIndexes(IValidator<CreateDateIndexes> validator, Timekeeper timekeeper) public CreateDateIndexes(
IValidator<CreateDateIndexes> validator,
Timekeeper timekeeper)
{ {
this.validator = validator; this.validator = validator;
this.Timekeeper = timekeeper; 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 // 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. // 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(); .ToList();
// Going in reverse order (most precise to less precise), we create the various indexes. // 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 // 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). // ones are new (these always go on the index).
var seenEntities = pair.Value.Where(a => seen.Contains(a)).ToList(); var seenEntities = pair.Value.Where(a => seen.Contains(a))
var newEntities = pair.Value.Where(a => !seen.Contains(a)).ToList(); .ToList();
var newEntities = pair.Value.Where(a => !seen.Contains(a))
.ToList();
seen.AddRange(newEntities); seen.AddRange(newEntities);
@ -126,14 +139,17 @@ public partial class CreateDateIndexes : OperationBase, IResolvingOperation
} }
Entity? first = pair.Value[0]; 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)) if (!indexes.ContainsKey(nextKey))
{ {
indexes[nextKey] = new List<Entity>(); 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) public CreateDateIndexes WithFormats(params string[] formats)
{ {
this.Formats = formats.ToList(); this.Formats = formats.ToList();
return this; 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); var dateTime = this.Timekeeper.ToDateTime(instant);
@ -155,12 +175,14 @@ public partial class CreateDateIndexes : OperationBase, IResolvingOperation
{ {
string? formatted = dateTime.ToString(this.Formats[i]); 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] = new List<Entity>();
} }
grouped[i][formatted].Add(entity); grouped[i][formatted]
.Add(entity);
} }
return entity; return entity;

View file

@ -6,7 +6,11 @@ namespace Nitride.Temporal;
public class DateIndex 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.Key = key;
this.Format = format; this.Format = format;

View file

@ -1,5 +1,4 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using FluentValidation; using FluentValidation;
@ -17,7 +16,9 @@ public partial class FilterOutExpiredInstant : OperationBase
{ {
private readonly IValidator<FilterOutExpiredInstant> validator; private readonly IValidator<FilterOutExpiredInstant> validator;
public FilterOutExpiredInstant(IValidator<FilterOutExpiredInstant> validator, Timekeeper clock) public FilterOutExpiredInstant(
IValidator<FilterOutExpiredInstant> validator,
Timekeeper clock)
{ {
this.validator = validator; this.validator = validator;
this.Timekeeper = clock; this.Timekeeper = clock;
@ -35,15 +36,17 @@ public partial class FilterOutExpiredInstant : OperationBase
return input; 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; Instant expiration = this.Timekeeper.Expiration!.Value;
bool isExpired = instant.CompareTo(expiration) < 0; 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() 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(); 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() public FilterOutFutureInstantValidator()
{ {
this.RuleFor(x => x.Timekeeper).NotNull(); this.RuleFor(x => x.Timekeeper)
.NotNull();
} }
} }

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -6,6 +6,7 @@ public class SetInstantFromPathValidator : AbstractValidator<SetInstantFromPath>
{ {
public SetInstantFromPathValidator() 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. /// Gets the instant when the files expire.
/// </summary> /// </summary>
public Instant? Expiration => this.Expires.HasValue 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; : null;
/// <summary> /// <summary>
@ -53,7 +54,10 @@ public class Timekeeper
/// <param name="month">The numerical month.</param> /// <param name="month">The numerical month.</param>
/// <param name="day">The numerical day of month.</param> /// <param name="day">The numerical day of month.</param>
/// <returns>An instant in the clock's time zone.</returns> /// <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); var date = new LocalDate(year, month, day);
@ -111,6 +115,8 @@ public class Timekeeper
/// <returns>A DateTime in the correct date and time.</returns> /// <returns>A DateTime in the correct date and time.</returns>
public DateTime ToDateTime(Instant instant) 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>
<ItemGroup> <ItemGroup>
<PackageReference Include="Gallium" Version="1.0.2"/> <PackageReference Include="Gallium" Version="1.2.0"/>
<PackageReference Include="YamlDotNet" Version="11.2.1"/> <PackageReference Include="YamlDotNet" Version="11.2.1"/>
</ItemGroup> </ItemGroup>

View file

@ -7,7 +7,9 @@ public class NitrideYamlModule : Module
/// <inheritdoc /> /// <inheritdoc />
protected override void Load(ContainerBuilder builder) protected override void Load(ContainerBuilder builder)
{ {
builder.RegisterGeneric(typeof(ParseYamlHeader<>)).As(typeof(ParseYamlHeader<>)); builder.RegisterGeneric(typeof(ParseYamlHeader<>))
.As(typeof(ParseYamlHeader<>));
builder.RegisterOperators(this); builder.RegisterOperators(this);
builder.RegisterValidators(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 // 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 // and we'll put a default TModel in for those that don't have a
// header. // header.
return input.ForEachEntity<ITextContent>((entity, content) => this.Parse(entity, content, deserializer)); return input.SelectEntity<ITextContent>(
(
entity,
content) => this.Parse(entity, content, deserializer));
} }
/// <summary> /// <summary>
@ -64,6 +67,7 @@ public class ParseYamlHeader<TModel> : OperationBase
public ParseYamlHeader<TModel> WithIgnoreUnmatchedProperties(bool value) public ParseYamlHeader<TModel> WithIgnoreUnmatchedProperties(bool value)
{ {
this.ignoreUnmatchedProperties = value; this.ignoreUnmatchedProperties = value;
return this; return this;
} }
@ -76,16 +80,21 @@ public class ParseYamlHeader<TModel> : OperationBase
public ParseYamlHeader<TModel> WithNamingConvention(INamingConvention value) public ParseYamlHeader<TModel> WithNamingConvention(INamingConvention value)
{ {
this.namingConvention = value; this.namingConvention = value;
return this; return this;
} }
public ParseYamlHeader<TModel> WithRemoveHeader(bool value) public ParseYamlHeader<TModel> WithRemoveHeader(bool value)
{ {
this.RemoveHeader = value; this.RemoveHeader = value;
return this; 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. // Get the textual input from the stream.
using TextReader reader = content.GetReader(); using TextReader reader = content.GetReader();
@ -148,6 +157,8 @@ public class ParseYamlHeader<TModel> : OperationBase
} }
// Set the model and return it. // 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; 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") : base("build", "Generate the website")
{ {
// Set up our simple member variables. // 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> /// <param name="content">The content to add to the entity.</param>
/// <typeparam name="TType">The base type of the content.</typeparam> /// <typeparam name="TType">The base type of the content.</typeparam>
/// <returns>The entity or a copy with the new component.</returns> /// <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 where TType : IBinaryContent
{ {
return entity.SetContent<IBinaryContent>(content); return entity.SetContent<IBinaryContent>(content);

View file

@ -19,7 +19,8 @@ public static class EntityContentExtensions
/// <returns>The one and only content component.</returns> /// <returns>The one and only content component.</returns>
public static IContent GetContent(this Entity entity) 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); return entity.Get<IContent>(type);
} }
@ -31,7 +32,8 @@ public static class EntityContentExtensions
/// <returns>True if there is a component extending `IContent`.</returns> /// <returns>True if there is a component extending `IContent`.</returns>
public static bool HasContent(this Entity entity) 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> /// <summary>
@ -42,10 +44,13 @@ public static class EntityContentExtensions
/// <param name="content">The content to add to the entity.</param> /// <param name="content">The content to add to the entity.</param>
/// <typeparam name="TType">The base type of the content.</typeparam> /// <typeparam name="TType">The base type of the content.</typeparam>
/// <returns>The entity or a copy with the new component.</returns> /// <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 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) 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> /// <param name="content">The content to add to the entity.</param>
/// <typeparam name="TType">The base type of the content.</typeparam> /// <typeparam name="TType">The base type of the content.</typeparam>
/// <returns>The entity or a copy with the new component.</returns> /// <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 where TType : ITextContent
{ {
return entity.SetContent<ITextContent>(content); return entity.SetContent<ITextContent>(content);
@ -41,7 +43,9 @@ public static class EntityTextContentExtensions
/// <param name="content">The content to add to the entity.</param> /// <param name="content">The content to add to the entity.</param>
/// <typeparam name="TType">The base type of the content.</typeparam> /// <typeparam name="TType">The base type of the content.</typeparam>
/// <returns>The entity or a copy with the new component.</returns> /// <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)); return entity.SetTextContent(new StringTextContent(content));
} }

View file

@ -28,7 +28,9 @@ public partial class CreateOrUpdateIndex : OperationBase
private readonly IValidator<CreateOrUpdateIndex> validator; private readonly IValidator<CreateOrUpdateIndex> validator;
public CreateOrUpdateIndex(ILogger logger, IValidator<CreateOrUpdateIndex> validator) public CreateOrUpdateIndex(
ILogger logger,
IValidator<CreateOrUpdateIndex> validator)
{ {
this.validator = validator; this.validator = validator;
this.logger = logger.ForContext(typeof(CreateOrUpdateIndex)); this.logger = logger.ForContext(typeof(CreateOrUpdateIndex));
@ -65,7 +67,8 @@ public partial class CreateOrUpdateIndex : OperationBase
this.validator.ValidateAndThrow(this); this.validator.ValidateAndThrow(this);
// Get the list of all the scanned entities. // 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 // 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 // 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() public CreateOrUpdateIndexValidator()
{ {
this.RuleFor(x => x.Scanner).NotNull(); this.RuleFor(x => x.Scanner)
this.RuleFor(x => x.GetIndexKey).NotNull(); .NotNull();
this.RuleFor(x => x.UpdateIndex).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() public IEnumerable<string> GetScannedKeys()
{ {
this.CheckDone(); this.CheckDone();
return this.results.Keys.ToImmutableList(); return this.results.Keys.ToImmutableList();
} }
@ -114,7 +115,10 @@ public partial class EntityScanner : OperationBase
this.results.AddOrUpdate( this.results.AddOrUpdate(
key, key,
_ => new List<Entity> { entity }, _ => 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() public EntityScannerValidator()
{ {
this.RuleFor(x => x.GetKeysFromEntity).NotNull(); this.RuleFor(x => x.GetKeysFromEntity)
.NotNull();
} }
} }

View file

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

View file

@ -20,8 +20,14 @@ public partial class LinkEntitySequence : OperationBase, IResolvingOperation
public LinkEntitySequence(IValidator<LinkEntitySequence> validator) public LinkEntitySequence(IValidator<LinkEntitySequence> validator)
{ {
this.validator = 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> /// <summary>

View file

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

View file

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

View file

@ -40,7 +40,10 @@ public class NitrideBuilder
this.configureSiteCallbacks = new List<Action<NitrideBuilder, ILifetimeScope>>(); this.configureSiteCallbacks = new List<Action<NitrideBuilder, ILifetimeScope>>();
this.configureContainerCallbacks = new List<Action<ContainerBuilder>>(); this.configureContainerCallbacks = new List<Action<ContainerBuilder>>();
this.nitrideModule = new NitrideModule(); this.nitrideModule = new NitrideModule();
this.nitrideModule.ApplicationName = Assembly.GetExecutingAssembly().GetName().Name!;
this.nitrideModule.ApplicationName = Assembly.GetExecutingAssembly()
.GetName()
.Name!;
} }
/// <summary> /// <summary>
@ -59,6 +62,7 @@ public class NitrideBuilder
public NitrideBuilder ConfigureContainer(Action<ContainerBuilder> callback) public NitrideBuilder ConfigureContainer(Action<ContainerBuilder> callback)
{ {
this.configureContainerCallbacks.Add(callback); this.configureContainerCallbacks.Add(callback);
return this; return this;
} }
@ -71,6 +75,7 @@ public class NitrideBuilder
public NitrideBuilder ConfigureSite(Action<NitrideBuilder, ILifetimeScope> callback) public NitrideBuilder ConfigureSite(Action<NitrideBuilder, ILifetimeScope> callback)
{ {
this.configureSiteCallbacks.Add(callback); this.configureSiteCallbacks.Add(callback);
return this; return this;
} }
@ -99,6 +104,7 @@ public class NitrideBuilder
public NitrideBuilder WithApplicationDescription(string value) public NitrideBuilder WithApplicationDescription(string value)
{ {
this.nitrideModule.Description = value; this.nitrideModule.Description = value;
return this; return this;
} }
@ -108,6 +114,7 @@ public class NitrideBuilder
public NitrideBuilder WithApplicationName(string value) public NitrideBuilder WithApplicationName(string value)
{ {
this.nitrideModule.ApplicationName = value; this.nitrideModule.ApplicationName = value;
return this; return this;
} }
@ -124,6 +131,7 @@ public class NitrideBuilder
public NitrideBuilder WithRootDirectory(DirectoryInfo directory) public NitrideBuilder WithRootDirectory(DirectoryInfo directory)
{ {
this.RootDirectory = directory; this.RootDirectory = directory;
return this; 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) if (this.RootDirectory == null)
{ {
logger.Verbose("No root directory is registered"); logger.Verbose("No root directory is registered");
return; return;
} }
@ -161,6 +172,8 @@ public class NitrideBuilder
var rootFileSystem = new PhysicalFileSystem(); var rootFileSystem = new PhysicalFileSystem();
var subFileSystem = new SubFileSystem(rootFileSystem, this.RootDirectory.FullName); 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 Autofac;
using Nitride.Commands; using Nitride.Commands;
using Nitride.Entities;
using Nitride.Pipelines; using Nitride.Pipelines;
namespace Nitride; namespace Nitride;
@ -22,15 +21,22 @@ public class NitrideModule : Module
protected override void Load(ContainerBuilder builder) protected override void Load(ContainerBuilder builder)
{ {
// Pipelines // Pipelines
builder.RegisterType<PipelineRunner>().AsSelf(); builder.RegisterType<PipelineRunner>()
builder.RegisterType<PipelineManager>().AsSelf().SingleInstance(); .AsSelf();
builder.RegisterType<PipelineManager>()
.AsSelf()
.SingleInstance();
// Operations // Operations
builder.RegisterValidators(this); builder.RegisterValidators(this);
builder.RegisterOperators(this); builder.RegisterOperators(this);
// Commands // 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 // MfGames.ToolBuilder requires the RootCommand to be registered. This is because
// of various things, mostly coordinating between different systems. // of various things, mostly coordinating between different systems.

View file

@ -6,13 +6,24 @@ namespace Nitride;
public static class NitrideModuleExtensions 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="input">The entities to perform the operation against.</param>
/// <param name="operation">The operation to run.</param> /// <param name="operation">The operation to run.</param>
/// <returns>The results of the operation.</returns> /// <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); return operation.Run(input);
} }

View file

@ -20,6 +20,7 @@ public abstract class PipelineBase : IPipeline
public PipelineBase AddDependency(IPipeline pipeline) public PipelineBase AddDependency(IPipeline pipeline)
{ {
this.dependencies.Add(pipeline); this.dependencies.Add(pipeline);
return this; return this;
} }
@ -35,6 +36,7 @@ public abstract class PipelineBase : IPipeline
/// <inheritdoc /> /// <inheritdoc />
public override string ToString() 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; 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.createEntry = createEntry;
this.logger = logger.ForContext<PipelineManager>(); this.logger = logger.ForContext<PipelineManager>();
@ -59,21 +62,26 @@ public class PipelineManager
// resulting tasks and then wait for all of them to end. // resulting tasks and then wait for all of them to end.
this.logger.Verbose("Starting {Count:l}", "pipeline".ToQuantity(this.pipelines.Count)); 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); var report = TimeSpan.FromSeconds(15);
while (!Task.WaitAll(tasks, report)) 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)); this.logger.Debug("Waiting for {Count:l} to finish running", "pipeline".ToQuantity(waiting.Count));
IOrderedEnumerable<IGrouping<PipelineRunnerState, PipelineRunner>> states = 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) 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( this.logger.Verbose(
"Waiting for {Count:l} in {State}: {List:l}", "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 // Wrap all the pipelines into entries. We do this before the next
// step so we can have the entries depend on the entries. // 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. // Go through and connect the pipelines together.
foreach (PipelineRunner? entry in this.entries) foreach (PipelineRunner? entry in this.entries)
{ {
var dependencies = entry.Pipeline.GetDependencies().ToList(); var dependencies = entry.Pipeline.GetDependencies()
.ToList();
foreach (IPipeline? dependency in dependencies) foreach (IPipeline? dependency in dependencies)
{ {

View file

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

View file

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

View file

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

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