refactor: code cleanup
This commit is contained in:
parent
7fca466dbb
commit
01fe15d772
120 changed files with 910 additions and 359 deletions
|
@ -31,11 +31,22 @@ dotnet_naming_rule.private_instance_fields_rule.import_to_resharper = as_predefi
|
|||
dotnet_naming_rule.private_instance_fields_rule.severity = warning
|
||||
dotnet_naming_rule.private_instance_fields_rule.style = lower_camel_case_style
|
||||
dotnet_naming_rule.private_instance_fields_rule.symbols = private_instance_fields_symbols
|
||||
dotnet_naming_rule.private_static_fields_override_rule.import_to_resharper = False
|
||||
dotnet_naming_rule.private_static_fields_override_rule.severity = warning
|
||||
dotnet_naming_rule.private_static_fields_override_rule.style = upper_camel_case_style
|
||||
dotnet_naming_rule.private_static_fields_override_rule.symbols = private_static_fields_override_symbols
|
||||
dotnet_naming_rule.private_static_fields_rule.import_to_resharper = as_predefined
|
||||
dotnet_naming_rule.private_static_fields_rule.resharper_style = AaBb, aaBb
|
||||
dotnet_naming_rule.private_static_fields_rule.severity = warning
|
||||
dotnet_naming_rule.private_static_fields_rule.style = upper_camel_case_style
|
||||
dotnet_naming_rule.private_static_fields_rule.symbols = private_static_fields_symbols
|
||||
dotnet_naming_rule.private_static_fields_rule_1.import_to_resharper = True
|
||||
dotnet_naming_rule.private_static_fields_rule_1.resharper_description = PrivateStaticFields
|
||||
dotnet_naming_rule.private_static_fields_rule_1.resharper_guid = 2ec29786-2764-45cc-849e-7a476ce55db8
|
||||
dotnet_naming_rule.private_static_fields_rule_1.resharper_style = AaBb, aaBb
|
||||
dotnet_naming_rule.private_static_fields_rule_1.severity = warning
|
||||
dotnet_naming_rule.private_static_fields_rule_1.style = upper_camel_case_style
|
||||
dotnet_naming_rule.private_static_fields_rule_1.symbols = private_static_fields_symbols_1
|
||||
dotnet_naming_rule.private_static_readonly_rule.import_to_resharper = as_predefined
|
||||
dotnet_naming_rule.private_static_readonly_rule.severity = warning
|
||||
dotnet_naming_rule.private_static_readonly_rule.style = upper_camel_case_style
|
||||
|
@ -54,9 +65,17 @@ dotnet_naming_symbols.private_constants_symbols.applicable_kinds = field
|
|||
dotnet_naming_symbols.private_constants_symbols.required_modifiers = const
|
||||
dotnet_naming_symbols.private_instance_fields_symbols.applicable_accessibilities = private
|
||||
dotnet_naming_symbols.private_instance_fields_symbols.applicable_kinds = field
|
||||
dotnet_naming_symbols.private_static_fields_override_symbols.applicable_accessibilities = local, private
|
||||
dotnet_naming_symbols.private_static_fields_override_symbols.applicable_kinds = field
|
||||
dotnet_naming_symbols.private_static_fields_override_symbols.required_modifiers = const, static
|
||||
dotnet_naming_symbols.private_static_fields_symbols.applicable_accessibilities = private
|
||||
dotnet_naming_symbols.private_static_fields_symbols.applicable_kinds = field
|
||||
dotnet_naming_symbols.private_static_fields_symbols.required_modifiers = static
|
||||
dotnet_naming_symbols.private_static_fields_symbols_1.applicable_accessibilities = local, private
|
||||
dotnet_naming_symbols.private_static_fields_symbols_1.applicable_kinds = field
|
||||
dotnet_naming_symbols.private_static_fields_symbols_1.required_modifiers = static
|
||||
dotnet_naming_symbols.private_static_fields_symbols_1.resharper_applicable_kinds = field
|
||||
dotnet_naming_symbols.private_static_fields_symbols_1.resharper_required_modifiers = static
|
||||
dotnet_naming_symbols.private_static_readonly_symbols.applicable_accessibilities = private
|
||||
dotnet_naming_symbols.private_static_readonly_symbols.applicable_kinds = field
|
||||
dotnet_naming_symbols.private_static_readonly_symbols.required_modifiers = static, readonly
|
||||
|
@ -75,11 +94,14 @@ dotnet_style_require_accessibility_modifiers = for_non_interface_members:suggest
|
|||
# ReSharper properties
|
||||
resharper_alignment_tab_fill_style = optimal_fill
|
||||
resharper_align_multiline_binary_expressions_chain = false
|
||||
resharper_align_multiline_statement_conditions = false
|
||||
resharper_apply_on_completion = true
|
||||
resharper_autodetect_indent_settings = true
|
||||
resharper_blank_lines_after_control_transfer_statements = 1
|
||||
resharper_blank_lines_after_multiline_statements = 1
|
||||
resharper_blank_lines_around_single_line_auto_property = 1
|
||||
resharper_blank_lines_around_single_line_property = 1
|
||||
resharper_blank_lines_before_control_transfer_statements = 1
|
||||
resharper_blank_lines_before_multiline_statements = 1
|
||||
resharper_blank_lines_before_single_line_comment = 1
|
||||
resharper_braces_for_for = required
|
||||
resharper_braces_for_foreach = required
|
||||
|
@ -124,6 +146,8 @@ resharper_keep_existing_declaration_block_arrangement = true
|
|||
resharper_keep_existing_declaration_parens_arrangement = false
|
||||
resharper_keep_existing_embedded_block_arrangement = true
|
||||
resharper_keep_existing_enum_arrangement = true
|
||||
resharper_keep_existing_linebreaks = true
|
||||
resharper_keep_user_linebreaks = true
|
||||
resharper_min_blank_lines_after_imports = 1
|
||||
resharper_nested_ternary_style = expanded
|
||||
resharper_new_line_before_while = true
|
||||
|
@ -133,7 +157,7 @@ resharper_place_type_constraints_on_same_line = false
|
|||
resharper_protobuf_insert_final_newline = true
|
||||
resharper_qualified_using_at_nested_scope = true
|
||||
resharper_resx_alignment_tab_fill_style = optimal_fill
|
||||
resharper_T4_alignment_tab_fill_style = optimal_fill
|
||||
resharper_t4_alignment_tab_fill_style = optimal_fill
|
||||
resharper_t4_insert_final_newline = true
|
||||
resharper_use_continuous_indent_inside_initializer_braces = false
|
||||
resharper_use_indents_from_main_language_in_file = false
|
||||
|
@ -146,7 +170,7 @@ resharper_wrap_before_extends_colon = true
|
|||
resharper_wrap_before_first_type_parameter_constraint = true
|
||||
resharper_wrap_before_type_parameter_langle = true
|
||||
resharper_wrap_chained_binary_expressions = chop_if_long
|
||||
resharper_wrap_chained_method_calls = chop_if_long
|
||||
resharper_wrap_chained_method_calls = chop_always
|
||||
resharper_wrap_object_and_collection_initializer_style = chop_always
|
||||
resharper_xmldoc_alignment_tab_fill_style = optimal_fill
|
||||
resharper_xmldoc_indent_child_elements = ZeroIndent
|
||||
|
@ -162,6 +186,7 @@ resharper_arrange_type_modifiers_highlighting = hint
|
|||
resharper_built_in_type_reference_style_for_member_access_highlighting = hint
|
||||
resharper_built_in_type_reference_style_highlighting = hint
|
||||
resharper_check_namespace_highlighting = none
|
||||
resharper_class_never_instantiated_global_highlighting = none
|
||||
resharper_convert_to_auto_property_highlighting = none
|
||||
resharper_localizable_element_highlighting = none
|
||||
resharper_redundant_comma_in_attribute_list_highlighting = none
|
||||
|
@ -205,3 +230,8 @@ tab_width = 4
|
|||
indent_style = space
|
||||
indent_size = 4
|
||||
tab_width = 4
|
||||
|
||||
[*.{appxmanifest,asax,ascx,aspx,axaml,build,c,c++,cc,cginc,compute,cp,cpp,cs,cshtml,cu,cuh,cxx,dtd,fx,fxh,h,hh,hlsl,hlsli,hlslinc,hpp,hxx,inc,inl,ino,ipp,master,mpp,mq4,mq5,mqh,nuspec,paml,razor,resw,resx,skin,tpp,usf,ush,vb,xaml,xamlx,xoml,xsd}]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
tab_width = 4
|
|
@ -85,7 +85,10 @@
|
|||
<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/KEEP_BLANK_LINES_IN_CODE/@EntryValue">1</s:Int64>
|
||||
<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/KEEP_BLANK_LINES_IN_DECLARATIONS/@EntryValue">1</s:Int64>
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/KEEP_EXISTING_DECLARATION_PARENS_ARRANGEMENT/@EntryValue">False</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/KEEP_EXISTING_INVOCATION_PARENS_ARRANGEMENT/@EntryValue">False</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/LINE_FEED_AT_FILE_END/@EntryValue">True</s:Boolean>
|
||||
<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/MAX_ENUM_MEMBERS_ON_LINE/@EntryValue">1</s:Int64>
|
||||
<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/MAX_FORMAL_PARAMETERS_ON_LINE/@EntryValue">1</s:Int64>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/NESTED_TERNARY_STYLE/@EntryValue">EXPANDED</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_ACCESSOR_ATTRIBUTE_ON_SAME_LINE_EX/@EntryValue">NEVER</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_ACCESSORHOLDER_ATTRIBUTE_ON_SAME_LINE_EX/@EntryValue">NEVER</s:String>
|
||||
|
@ -115,7 +118,9 @@
|
|||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_CHAINED_METHOD_CALLS/@EntryValue">CHOP_IF_LONG</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_EXTENDS_LIST_STYLE/@EntryValue">CHOP_IF_LONG</s:String>
|
||||
<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_LIMIT/@EntryValue">80</s:Int64>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_MULTIPLE_TYPE_PARAMEER_CONSTRAINTS_STYLE/@EntryValue">CHOP_ALWAYS</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_PARAMETERS_STYLE/@EntryValue">CHOP_IF_LONG</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_VERBATIM_INTERPOLATED_STRINGS/@EntryValue">CHOP_IF_LONG</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CssFormatter/ALIGNMENT_TAB_FILL_STYLE/@EntryValue">OPTIMAL_FILL</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/HtmlFormatter/ALIGNMENT_TAB_FILL_STYLE/@EntryValue">OPTIMAL_FILL</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/JavaScriptCodeFormatting/ALIGNMENT_TAB_FILL_STYLE/@EntryValue">OPTIMAL_FILL</s:String>
|
||||
|
@ -1366,6 +1371,5 @@ using(DataAccessAdapter dataAccessAdapter = new DataAccessAdapter(ConnectionStri
|
|||
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=F87CBA43E9CDCC41A45B39A2A2A25764/Scope/=2C285F182AC98D44B0B4F29D4D2149EC/@KeyIndexDefined">True</s:Boolean>
|
||||
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=F87CBA43E9CDCC41A45B39A2A2A25764/Scope/=2C285F182AC98D44B0B4F29D4D2149EC/CustomProperties/=minimumLanguageVersion/@EntryIndexedValue">2.0</s:String>
|
||||
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=F87CBA43E9CDCC41A45B39A2A2A25764/Scope/=2C285F182AC98D44B0B4F29D4D2149EC/Type/@EntryValue">InCSharpStatement</s:String>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Gemtext/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Tocks/@EntryIndexedValue">True</s:Boolean>
|
||||
</wpf:ResourceDictionary>
|
||||
|
|
|
@ -10,6 +10,11 @@ public class CopyFilesModule : Module
|
|||
// This just registers all the non-static classes as singletons
|
||||
// within the system. We use lifetimes in other components depending
|
||||
// on how they are used, but in this case, we don't need it.
|
||||
builder.RegisterAssemblyTypes(this.GetType().Assembly).AsSelf().AsImplementedInterfaces().SingleInstance();
|
||||
builder.RegisterAssemblyTypes(
|
||||
this.GetType()
|
||||
.Assembly)
|
||||
.AsSelf()
|
||||
.AsImplementedInterfaces()
|
||||
.SingleInstance();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -74,7 +74,8 @@ public class CopyFilesPipeline : PipelineBase
|
|||
// read. Coming out of this, we will have one entity that fulfills:
|
||||
//
|
||||
// entity.Get<UPath> == "/output/a.txt"
|
||||
entities = entities.Run(this.removePathPrefix).Run(this.addPathPrefix);
|
||||
entities = entities.Run(this.removePathPrefix)
|
||||
.Run(this.addPathPrefix);
|
||||
|
||||
// Then we write out the files to the output. First we make sure we
|
||||
// clear out the output. This operation performs an action when it
|
||||
|
@ -95,7 +96,8 @@ public class CopyFilesPipeline : PipelineBase
|
|||
// The third way is to use an extension on entities which lets us
|
||||
// chain calls, ala Gulp's pipelines. The below code does this along
|
||||
// with writing the files to the output.
|
||||
entities = entities.Run(this.clearDirectory).Run(this.writeFiles);
|
||||
entities = entities.Run(this.clearDirectory)
|
||||
.Run(this.writeFiles);
|
||||
|
||||
// If we are chaining this pipeline into another, we return the
|
||||
// entities. Otherwise, we can just return an empty list. The
|
||||
|
|
|
@ -28,6 +28,7 @@ public class CopyFilesTest : NitrideTestBase
|
|||
// Figure out the paths for this test.
|
||||
DirectoryInfo rootDir =
|
||||
typeof(CopyFilesProgram).GetDirectory()!.FindGitRoot()!.GetDirectory("examples/CopyFiles");
|
||||
|
||||
DirectoryInfo outputDir = rootDir.GetDirectory("output");
|
||||
FileInfo projectFile = rootDir.GetFile("CopyFiles.csproj");
|
||||
|
||||
|
@ -41,7 +42,12 @@ public class CopyFilesTest : NitrideTestBase
|
|||
|
||||
// Execute the generator. This will throw if there is an exception.
|
||||
await Cli.Wrap("dotnet")
|
||||
.WithArguments(x => x.Add("run").Add("--project").Add(projectFile.FullName).Add("--").Add("build"))
|
||||
.WithArguments(
|
||||
x => x.Add("run")
|
||||
.Add("--project")
|
||||
.Add(projectFile.FullName)
|
||||
.Add("--")
|
||||
.Add("build"))
|
||||
.ExecuteAsync();
|
||||
|
||||
// Make sure we have our output.
|
||||
|
@ -49,7 +55,8 @@ public class CopyFilesTest : NitrideTestBase
|
|||
|
||||
Assert.True(aFile.Exists);
|
||||
|
||||
string aText = aFile.ReadAllText().Trim();
|
||||
string aText = aFile.ReadAllText()
|
||||
.Trim();
|
||||
|
||||
Assert.Equal("This is the 'A' file.", aText);
|
||||
}
|
||||
|
|
|
@ -7,9 +7,6 @@ pre-push:
|
|||
pre-commit:
|
||||
parallel: true
|
||||
commands:
|
||||
dotnet-format-style:
|
||||
glob: "*.cs"
|
||||
run: dotnet format
|
||||
prettier:
|
||||
run: prettier . --write --loglevel warn
|
||||
nixfmt:
|
||||
|
|
|
@ -6,8 +6,13 @@ public class CreateCalendarValidator : AbstractValidator<CreateCalender>
|
|||
{
|
||||
public CreateCalendarValidator()
|
||||
{
|
||||
this.RuleFor(x => x.Path).NotNull();
|
||||
this.RuleFor(x => x.GetEventSummary).NotNull();
|
||||
this.RuleFor(x => x.GetEventUrl).NotNull();
|
||||
this.RuleFor(x => x.Path)
|
||||
.NotNull();
|
||||
|
||||
this.RuleFor(x => x.GetEventSummary)
|
||||
.NotNull();
|
||||
|
||||
this.RuleFor(x => x.GetEventUrl)
|
||||
.NotNull();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,7 +31,9 @@ public partial class CreateCalender : OperationBase
|
|||
|
||||
private readonly IValidator<CreateCalender> validator;
|
||||
|
||||
public CreateCalender(IValidator<CreateCalender> validator, Timekeeper clock)
|
||||
public CreateCalender(
|
||||
IValidator<CreateCalender> validator,
|
||||
Timekeeper clock)
|
||||
{
|
||||
this.validator = validator;
|
||||
this.clock = clock;
|
||||
|
@ -59,9 +61,12 @@ public partial class CreateCalender : OperationBase
|
|||
{
|
||||
this.validator.ValidateAndThrow(this);
|
||||
|
||||
IEnumerable<Entity> output = input.ForEntities<Instant>(this.CreateCalendarEntity);
|
||||
input = input.ToList();
|
||||
IEnumerable<Entity> dated = input.WhereAllComponents<Instant>();
|
||||
IEnumerable<Entity> others = input.WhereNotComponent<Instant>();
|
||||
IEnumerable<Entity> datedAndCalendars = this.CreateCalendarEntity(dated);
|
||||
|
||||
return output;
|
||||
return datedAndCalendars.Union(others);
|
||||
}
|
||||
|
||||
private IEnumerable<Entity> CreateCalendarEntity(IEnumerable<Entity> entities)
|
||||
|
@ -96,6 +101,7 @@ public partial class CreateCalender : OperationBase
|
|||
var when = this.clock.ToDateTime(instant);
|
||||
string summary = this.GetEventSummary!(entity);
|
||||
Uri? url = this.GetEventUrl?.Invoke(entity);
|
||||
|
||||
var calendarEvent = new CalendarEvent
|
||||
{
|
||||
Summary = summary,
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Gallium" Version="1.0.2"/>
|
||||
<PackageReference Include="Gallium" Version="1.2.0"/>
|
||||
<PackageReference Include="Ical.Net" Version="4.2.0"/>
|
||||
<PackageReference Include="NodaTime" Version="3.1.0"/>
|
||||
<PackageReference Include="Zio" Version="0.15.0"/>
|
||||
|
|
|
@ -8,6 +8,7 @@ public static class NitrideCalendarBuilderExtensions
|
|||
{
|
||||
public static NitrideBuilder UseCalendar(this NitrideBuilder builder)
|
||||
{
|
||||
return builder.UseTemporal().ConfigureContainer(x => x.RegisterModule<NitrideCalendarModule>());
|
||||
return builder.UseTemporal()
|
||||
.ConfigureContainer(x => x.RegisterModule<NitrideCalendarModule>());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,7 +27,9 @@ public partial class CreateAtomFeed : OperationBase
|
|||
|
||||
private readonly IValidator<CreateAtomFeed> validator;
|
||||
|
||||
public CreateAtomFeed(ILogger logger, IValidator<CreateAtomFeed> validator)
|
||||
public CreateAtomFeed(
|
||||
ILogger logger,
|
||||
IValidator<CreateAtomFeed> validator)
|
||||
{
|
||||
this.logger = logger;
|
||||
this.validator = validator;
|
||||
|
@ -121,7 +123,9 @@ public partial class CreateAtomFeed : OperationBase
|
|||
}
|
||||
|
||||
// Create the feed entity and return both objects.
|
||||
Entity feedEntity = new Entity().Set(IsFeed.Instance).Set(this.GetPath!(entity)).SetTextContent(feed + "\n");
|
||||
Entity feedEntity = new Entity().Set(IsFeed.Instance)
|
||||
.Set(this.GetPath!(entity))
|
||||
.SetTextContent(feed + "\n");
|
||||
|
||||
return new[] { entity, feedEntity };
|
||||
}
|
||||
|
|
|
@ -6,8 +6,13 @@ public class CreateAtomFeedValidator : AbstractValidator<CreateAtomFeed>
|
|||
{
|
||||
public CreateAtomFeedValidator()
|
||||
{
|
||||
this.RuleFor(x => x.GetEntries).NotNull();
|
||||
this.RuleFor(x => x.GetPath).NotNull();
|
||||
this.RuleFor(x => x.GetTitle).NotNull();
|
||||
this.RuleFor(x => x.GetEntries)
|
||||
.NotNull();
|
||||
|
||||
this.RuleFor(x => x.GetPath)
|
||||
.NotNull();
|
||||
|
||||
this.RuleFor(x => x.GetTitle)
|
||||
.NotNull();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Gallium" Version="1.0.2"/>
|
||||
<PackageReference Include="Gallium" Version="1.2.0"/>
|
||||
<PackageReference Include="NodaTime" Version="3.1.0"/>
|
||||
<PackageReference Include="Zio" Version="0.15.0"/>
|
||||
</ItemGroup>
|
||||
|
|
|
@ -8,6 +8,7 @@ public static class NitrideFeedsBuilderExtensions
|
|||
{
|
||||
public static NitrideBuilder UseFeeds(this NitrideBuilder builder)
|
||||
{
|
||||
return builder.UseTemporal().ConfigureContainer(x => x.RegisterModule<NitrideFeedsModule>());
|
||||
return builder.UseTemporal()
|
||||
.ConfigureContainer(x => x.RegisterModule<NitrideFeedsModule>());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,9 @@ namespace Nitride.Feeds.Structure;
|
|||
/// </summary>
|
||||
public static class AtomHelper
|
||||
{
|
||||
public static void AddIfSet(XElement root, XElement? elem)
|
||||
public static void AddIfSet(
|
||||
XElement root,
|
||||
XElement? elem)
|
||||
{
|
||||
if (elem != null)
|
||||
{
|
||||
|
@ -15,7 +17,10 @@ public static class AtomHelper
|
|||
}
|
||||
}
|
||||
|
||||
public static void AddIfSet(XElement elem, string name, string? text)
|
||||
public static void AddIfSet(
|
||||
XElement elem,
|
||||
string name,
|
||||
string? text)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(text))
|
||||
{
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Gallium" Version="1.0.2"/>
|
||||
<PackageReference Include="Gallium" Version="1.2.0"/>
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.Common" Version="4.1.0"/>
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.1.0"/>
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="4.1.0"/>
|
||||
|
|
|
@ -61,7 +61,9 @@ public class WithPropertySourceGenerator : ISourceGenerator
|
|||
context.RegisterForSyntaxNotifications(() => new WithPropertySyntaxReceiver(context));
|
||||
}
|
||||
|
||||
private void GenerateClassFile(GeneratorExecutionContext context, WithPropertyClass unit)
|
||||
private void GenerateClassFile(
|
||||
GeneratorExecutionContext context,
|
||||
WithPropertyClass unit)
|
||||
{
|
||||
// Pull out some fields.
|
||||
ClassDeclarationSyntax? cds = unit.ClassDeclaration;
|
||||
|
@ -88,6 +90,7 @@ public class WithPropertySourceGenerator : ISourceGenerator
|
|||
IEnumerable<PropertyDeclarationSyntax> properties = cds.Members
|
||||
.Where(m => m.Kind() == SyntaxKind.PropertyDeclaration)
|
||||
.Cast<PropertyDeclarationSyntax>();
|
||||
|
||||
bool first = true;
|
||||
|
||||
foreach (PropertyDeclarationSyntax pds in properties)
|
||||
|
@ -112,10 +115,12 @@ public class WithPropertySourceGenerator : ISourceGenerator
|
|||
|
||||
// Write some documentation.
|
||||
buffer.AppendLine(" /// <summary>");
|
||||
|
||||
buffer.AppendLine(
|
||||
string.Format(
|
||||
" /// Sets the {0} value and returns the operation for chaining.",
|
||||
pds.Identifier.ToString()));
|
||||
|
||||
buffer.AppendLine(" /// </summary>");
|
||||
|
||||
// We have the components for writing out a setter.
|
||||
|
@ -125,6 +130,7 @@ public class WithPropertySourceGenerator : ISourceGenerator
|
|||
cds.Identifier,
|
||||
pds.Identifier,
|
||||
pds.Type));
|
||||
|
||||
buffer.AppendLine(" {");
|
||||
buffer.AppendLine(string.Format(" this.{0} = value;", pds.Identifier));
|
||||
buffer.AppendLine(" return this;");
|
||||
|
|
|
@ -37,15 +37,19 @@ internal class WithPropertySyntaxReceiver : ISyntaxReceiver
|
|||
// Reset everything.
|
||||
this.Namespace = null!;
|
||||
this.UsingDirectiveList = new List<UsingDirectiveSyntax>();
|
||||
|
||||
break;
|
||||
case NamespaceDeclarationSyntax syntax:
|
||||
this.Namespace = syntax.Name.ToString();
|
||||
|
||||
return;
|
||||
case FileScopedNamespaceDeclarationSyntax syntax:
|
||||
this.Namespace = syntax.Name.ToString();
|
||||
|
||||
return;
|
||||
case UsingDirectiveSyntax syntax:
|
||||
this.UsingDirectiveList.Add(syntax);
|
||||
|
||||
return;
|
||||
case ClassDeclarationSyntax:
|
||||
break;
|
||||
|
|
|
@ -52,7 +52,7 @@ public class ApplyStyleTemplate<TModel> : OperationBase
|
|||
this.validator.ValidateAndThrow(this);
|
||||
|
||||
// Create and set up the Handlebars.
|
||||
return input.ForEachEntity<ITextContent>(this.Apply);
|
||||
return input.SelectEntity<ITextContent>(this.Apply);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -64,22 +64,27 @@ public class ApplyStyleTemplate<TModel> : OperationBase
|
|||
public ApplyStyleTemplate<TModel> WithCreateModelCallback(Func<Entity, TModel>? callback)
|
||||
{
|
||||
this.CreateModelCallback = callback;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public ApplyStyleTemplate<TModel> WithGetTemplateName(Func<Entity, string>? callback)
|
||||
{
|
||||
this.GetTemplateName = callback;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public ApplyStyleTemplate<TModel> WithHandlebars(IHandlebars? handlebars)
|
||||
{
|
||||
this.Handlebars = handlebars;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
private Entity Apply(Entity entity, ITextContent content)
|
||||
private Entity Apply(
|
||||
Entity entity,
|
||||
ITextContent content)
|
||||
{
|
||||
TModel model = this.CreateModelCallback!(entity);
|
||||
string name = this.GetTemplateName!(entity);
|
||||
|
|
|
@ -6,8 +6,13 @@ public class ApplyStyleTemplateValidator<TModel> : AbstractValidator<ApplyStyleT
|
|||
{
|
||||
public ApplyStyleTemplateValidator()
|
||||
{
|
||||
this.RuleFor(x => x.Handlebars).NotNull();
|
||||
this.RuleFor(x => x.GetTemplateName).NotNull();
|
||||
this.RuleFor(x => x.CreateModelCallback).NotNull();
|
||||
this.RuleFor(x => x.Handlebars)
|
||||
.NotNull();
|
||||
|
||||
this.RuleFor(x => x.GetTemplateName)
|
||||
.NotNull();
|
||||
|
||||
this.RuleFor(x => x.CreateModelCallback)
|
||||
.NotNull();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ public class IdentifyHandlebarsFromComponentValidator : AbstractValidator<Identi
|
|||
{
|
||||
public IdentifyHandlebarsFromComponentValidator()
|
||||
{
|
||||
this.RuleFor(x => x.HasHandlebarsTest).NotNull();
|
||||
this.RuleFor(x => x.HasHandlebarsTest)
|
||||
.NotNull();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,10 +15,12 @@ public class IdentifyHandlebarsFromContent : IOperation
|
|||
/// <inheritdoc />
|
||||
public IEnumerable<Entity> Run(IEnumerable<Entity> input)
|
||||
{
|
||||
return input.ForEachEntity<ITextContent>(this.ScanContent);
|
||||
return input.SelectEntity<ITextContent>(this.ScanContent);
|
||||
}
|
||||
|
||||
private Entity ScanContent(Entity entity, ITextContent content)
|
||||
private Entity ScanContent(
|
||||
Entity entity,
|
||||
ITextContent content)
|
||||
{
|
||||
string text = content.GetText();
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Autofac" Version="6.4.0"/>
|
||||
<PackageReference Include="Gallium" Version="1.0.2"/>
|
||||
<PackageReference Include="Gallium" Version="1.2.0"/>
|
||||
<PackageReference Include="Handlebars.Net" Version="2.1.2"/>
|
||||
<PackageReference Include="NodaTime.Testing" Version="3.1.0"/>
|
||||
<PackageReference Include="Open.Threading" Version="2.2.0"/>
|
||||
|
|
|
@ -10,8 +10,14 @@ public class NitrideHandlebarsModule : Module
|
|||
builder.RegisterOperators(this);
|
||||
builder.RegisterValidators(this);
|
||||
|
||||
builder.RegisterType<HandlebarsTemplateCache>().AsSelf().SingleInstance();
|
||||
builder.RegisterGeneric(typeof(RenderContentTemplate<>)).As(typeof(RenderContentTemplate<>));
|
||||
builder.RegisterGeneric(typeof(ApplyStyleTemplate<>)).As(typeof(ApplyStyleTemplate<>));
|
||||
builder.RegisterType<HandlebarsTemplateCache>()
|
||||
.AsSelf()
|
||||
.SingleInstance();
|
||||
|
||||
builder.RegisterGeneric(typeof(RenderContentTemplate<>))
|
||||
.As(typeof(RenderContentTemplate<>));
|
||||
|
||||
builder.RegisterGeneric(typeof(ApplyStyleTemplate<>))
|
||||
.As(typeof(ApplyStyleTemplate<>));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@ public class RenderContentTemplate<TModel> : OperationBase
|
|||
{
|
||||
this.validator.ValidateAndThrow(this);
|
||||
|
||||
return input.ForEachEntity<HasHandlebarsTemplate, ITextContent>(this.Apply);
|
||||
return input.SelectEntity<HasHandlebarsTemplate, ITextContent>(this.Apply);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -55,10 +55,14 @@ public class RenderContentTemplate<TModel> : OperationBase
|
|||
public RenderContentTemplate<TModel> WithCreateModelCallback(Func<Entity, TModel>? callback)
|
||||
{
|
||||
this.CreateModelCallback = callback;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
private Entity Apply(Entity entity, HasHandlebarsTemplate _, ITextContent content)
|
||||
private Entity Apply(
|
||||
Entity entity,
|
||||
HasHandlebarsTemplate _,
|
||||
ITextContent content)
|
||||
{
|
||||
// Create the model using the callback.
|
||||
TModel model = this.CreateModelCallback!(entity);
|
||||
|
@ -71,6 +75,7 @@ public class RenderContentTemplate<TModel> : OperationBase
|
|||
// text.
|
||||
string result = template(model!);
|
||||
|
||||
return entity.Remove<HasHandlebarsTemplate>().SetTextContent(new StringTextContent(result));
|
||||
return entity.Remove<HasHandlebarsTemplate>()
|
||||
.SetTextContent(new StringTextContent(result));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ public class RenderContentTemplateValidator<TModel> : AbstractValidator<RenderCo
|
|||
{
|
||||
public RenderContentTemplateValidator()
|
||||
{
|
||||
this.RuleFor(x => x.CreateModelCallback).NotNull();
|
||||
this.RuleFor(x => x.CreateModelCallback)
|
||||
.NotNull();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,10 +16,12 @@ public class ConvertHtmlEntitiesToUnicode : OperationBase
|
|||
/// <inheritdoc />
|
||||
public override IEnumerable<Entity> Run(IEnumerable<Entity> input)
|
||||
{
|
||||
return input.ForEachEntity<ITextContent>(this.ResolveHtmlEntities);
|
||||
return input.SelectEntity<ITextContent>(this.ResolveHtmlEntities);
|
||||
}
|
||||
|
||||
private Entity ResolveHtmlEntities(Entity entity, ITextContent content)
|
||||
private Entity ResolveHtmlEntities(
|
||||
Entity entity,
|
||||
ITextContent content)
|
||||
{
|
||||
string text = content.GetText();
|
||||
string resolved = WebUtility.HtmlDecode(text);
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Gallium" Version="1.0.2"/>
|
||||
<PackageReference Include="Gallium" Version="1.2.0"/>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
@ -24,7 +24,9 @@ public partial class ReadFiles : FileSystemOperationBase
|
|||
{
|
||||
private readonly IValidator<ReadFiles> validator;
|
||||
|
||||
public ReadFiles(IValidator<ReadFiles> validator, IFileSystem fileSystem)
|
||||
public ReadFiles(
|
||||
IValidator<ReadFiles> validator,
|
||||
IFileSystem fileSystem)
|
||||
: base(fileSystem)
|
||||
{
|
||||
this.validator = validator;
|
||||
|
@ -56,8 +58,10 @@ public partial class ReadFiles : FileSystemOperationBase
|
|||
this.validator.ValidateAndThrow(this);
|
||||
|
||||
var glob = Glob.Parse(this.Pattern);
|
||||
|
||||
IEnumerable<FileEntry> files = this.FileSystem.EnumerateFileEntries("/", "*", SearchOption.AllDirectories)
|
||||
.Where(x => glob.IsMatch(x.Path.ToString()));
|
||||
|
||||
IEnumerable<Entity> entities = files.Select(this.ToEntity);
|
||||
|
||||
return entities;
|
||||
|
@ -66,6 +70,7 @@ public partial class ReadFiles : FileSystemOperationBase
|
|||
public ReadFiles WithFileSystem(IFileSystem value)
|
||||
{
|
||||
this.FileSystem = value;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -78,7 +83,8 @@ public partial class ReadFiles : FileSystemOperationBase
|
|||
/// <returns>An Entity with appropriate content.</returns>
|
||||
private Entity ToEntity(FileEntry file)
|
||||
{
|
||||
Entity entity = new Entity().Set(file.Path).SetBinaryContent(new FileEntryBinaryContent(file));
|
||||
Entity entity = new Entity().Set(file.Path)
|
||||
.SetBinaryContent(new FileEntryBinaryContent(file));
|
||||
|
||||
return entity;
|
||||
}
|
||||
|
|
|
@ -6,7 +6,10 @@ public class ReadFilesValidator : AbstractValidator<ReadFiles>
|
|||
{
|
||||
public ReadFilesValidator()
|
||||
{
|
||||
this.RuleFor(x => x.Pattern).NotNull();
|
||||
this.RuleFor(x => x.FileSystem).NotNull();
|
||||
this.RuleFor(x => x.Pattern)
|
||||
.NotNull();
|
||||
|
||||
this.RuleFor(x => x.FileSystem)
|
||||
.NotNull();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,12 +26,16 @@ public partial class WriteFiles : FileSystemOperationBase, IOperation
|
|||
|
||||
private Dictionary<Type, Func<IContent, Stream>> factories;
|
||||
|
||||
public WriteFiles(IValidator<WriteFiles> validator, ILogger logger, IFileSystem fileSystem)
|
||||
public WriteFiles(
|
||||
IValidator<WriteFiles> validator,
|
||||
ILogger logger,
|
||||
IFileSystem fileSystem)
|
||||
: base(fileSystem)
|
||||
{
|
||||
this.Logger = logger;
|
||||
this.validator = validator;
|
||||
this.TextEncoding = Encoding.UTF8;
|
||||
|
||||
this.factories = new Dictionary<Type, Func<IContent, Stream>>
|
||||
{
|
||||
[typeof(IBinaryContent)] = GetBinaryStream,
|
||||
|
@ -63,7 +67,8 @@ public partial class WriteFiles : FileSystemOperationBase, IOperation
|
|||
{
|
||||
this.validator.ValidateAndThrow(this);
|
||||
|
||||
IEnumerable<Entity> results = entities.ForEachEntity<UPath>(this.Process).ToList();
|
||||
IEnumerable<Entity> results = entities.SelectEntity<UPath>(this.Process)
|
||||
.ToList();
|
||||
|
||||
return results;
|
||||
}
|
||||
|
@ -71,6 +76,7 @@ public partial class WriteFiles : FileSystemOperationBase, IOperation
|
|||
public WriteFiles WithFileSystem(IFileSystem fileSystem)
|
||||
{
|
||||
this.FileSystem = fileSystem;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -85,12 +91,16 @@ public partial class WriteFiles : FileSystemOperationBase, IOperation
|
|||
// we don't have to load it entirely in memory.
|
||||
if (content is IBinaryContentConvertable convertable)
|
||||
{
|
||||
return convertable.ToBinaryContent().GetStream();
|
||||
return convertable.ToBinaryContent()
|
||||
.GetStream();
|
||||
}
|
||||
|
||||
// We have the load the text into memory and convert it.
|
||||
var textContent = (ITextContent)content;
|
||||
string text = textContent.GetReader().ReadToEnd();
|
||||
|
||||
string text = textContent.GetReader()
|
||||
.ReadToEnd();
|
||||
|
||||
var stream = new MemoryStream();
|
||||
var writer = new StreamWriter(stream, this.TextEncoding ?? Encoding.UTF8);
|
||||
|
||||
|
@ -109,7 +119,9 @@ public partial class WriteFiles : FileSystemOperationBase, IOperation
|
|||
/// <param name="entity">The entity to write out.</param>
|
||||
/// <param name="path">The path of the entity.</param>
|
||||
/// <returns>The entity passed in.</returns>
|
||||
private Entity Process(Entity entity, UPath path)
|
||||
private Entity Process(
|
||||
Entity entity,
|
||||
UPath path)
|
||||
{
|
||||
// See if we have any content. If we don't, then there is nothing
|
||||
// to do.
|
||||
|
@ -178,7 +190,8 @@ public partial class WriteFiles : FileSystemOperationBase, IOperation
|
|||
"Cannot write out entity "
|
||||
+ path
|
||||
+ " because cannot determine how to get a stream out content type "
|
||||
+ content.GetType().FullName
|
||||
+ content.GetType()
|
||||
.FullName
|
||||
+ ". To resolve, register a function to this.StreamFactories.");
|
||||
}
|
||||
|
||||
|
@ -189,7 +202,10 @@ public partial class WriteFiles : FileSystemOperationBase, IOperation
|
|||
/// <param name="path">The path to write out, directories will be created.</param>
|
||||
/// <param name="stream">The stream to write out.</param>
|
||||
/// <returns>The entity passed in.</returns>
|
||||
private Entity Process(Entity entity, UPath path, Stream stream)
|
||||
private Entity Process(
|
||||
Entity entity,
|
||||
UPath path,
|
||||
Stream stream)
|
||||
{
|
||||
// Make sure we have the directory structure.
|
||||
UPath directory = path.GetDirectory();
|
||||
|
|
|
@ -6,9 +6,16 @@ public class WriteFilesValidator : AbstractValidator<WriteFiles>
|
|||
{
|
||||
public WriteFilesValidator()
|
||||
{
|
||||
this.RuleFor(x => x.StreamFactories).NotNull();
|
||||
this.RuleFor(x => x.TextEncoding).NotNull();
|
||||
this.RuleFor(x => x.FileSystem).NotNull();
|
||||
this.RuleFor(x => x.Logger).NotNull();
|
||||
this.RuleFor(x => x.StreamFactories)
|
||||
.NotNull();
|
||||
|
||||
this.RuleFor(x => x.TextEncoding)
|
||||
.NotNull();
|
||||
|
||||
this.RuleFor(x => x.FileSystem)
|
||||
.NotNull();
|
||||
|
||||
this.RuleFor(x => x.Logger)
|
||||
.NotNull();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,7 +22,10 @@ public partial class ClearDirectory : FileSystemOperationBase, IOperation
|
|||
{
|
||||
private readonly IValidator<ClearDirectory> validator;
|
||||
|
||||
public ClearDirectory(IValidator<ClearDirectory> validator, IFileSystem fileSystem, ILogger logger)
|
||||
public ClearDirectory(
|
||||
IValidator<ClearDirectory> validator,
|
||||
IFileSystem fileSystem,
|
||||
ILogger logger)
|
||||
: base(fileSystem)
|
||||
{
|
||||
this.Logger = logger;
|
||||
|
@ -87,6 +90,7 @@ public partial class ClearDirectory : FileSystemOperationBase, IOperation
|
|||
public ClearDirectory WithFileSystem(IFileSystem value)
|
||||
{
|
||||
this.FileSystem = value;
|
||||
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,8 +6,13 @@ public class ClearDirectoryValidator : AbstractValidator<ClearDirectory>
|
|||
{
|
||||
public ClearDirectoryValidator()
|
||||
{
|
||||
this.RuleFor(x => x.Path).NotNull();
|
||||
this.RuleFor(x => x.FileSystem).NotNull();
|
||||
this.RuleFor(x => x.Logger).NotNull();
|
||||
this.RuleFor(x => x.Path)
|
||||
.NotNull();
|
||||
|
||||
this.RuleFor(x => x.FileSystem)
|
||||
.NotNull();
|
||||
|
||||
this.RuleFor(x => x.Logger)
|
||||
.NotNull();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,8 +10,8 @@
|
|||
<ItemGroup>
|
||||
<PackageReference Include="Autofac" Version="6.4.0"/>
|
||||
<PackageReference Include="DotNet.Glob" Version="3.1.3"/>
|
||||
<PackageReference Include="FluentValidation" Version="11.0.2" />
|
||||
<PackageReference Include="Gallium" Version="1.0.2" />
|
||||
<PackageReference Include="FluentValidation" Version="11.1.0"/>
|
||||
<PackageReference Include="Gallium" Version="1.2.0"/>
|
||||
<PackageReference Include="Serilog" Version="2.11.0"/>
|
||||
<PackageReference Include="Zio" Version="0.15.0"/>
|
||||
</ItemGroup>
|
||||
|
|
|
@ -15,7 +15,9 @@ public partial class AddPathPrefix : OperationBase
|
|||
|
||||
private readonly IValidator<AddPathPrefix> validator;
|
||||
|
||||
public AddPathPrefix(IValidator<AddPathPrefix> validator, ReplacePath replacePath)
|
||||
public AddPathPrefix(
|
||||
IValidator<AddPathPrefix> validator,
|
||||
ReplacePath replacePath)
|
||||
{
|
||||
this.validator = validator;
|
||||
this.replacePath = replacePath;
|
||||
|
@ -30,12 +32,17 @@ public partial class AddPathPrefix : OperationBase
|
|||
{
|
||||
this.validator.ValidateAndThrow(this);
|
||||
|
||||
return this.replacePath.WithReplacement(this.RunReplacement).Run(input);
|
||||
return this.replacePath.WithReplacement(this.RunReplacement)
|
||||
.Run(input);
|
||||
}
|
||||
|
||||
private UPath RunReplacement(Entity _, UPath path)
|
||||
private UPath RunReplacement(
|
||||
Entity _,
|
||||
UPath path)
|
||||
{
|
||||
string innerRelativePath = path.ToString().TrimStart('/');
|
||||
string innerRelativePath = path.ToString()
|
||||
.TrimStart('/');
|
||||
|
||||
return this.PathPrefix!.Value / innerRelativePath;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ public class AddPathPrefixValidator : AbstractValidator<AddPathPrefix>
|
|||
{
|
||||
public AddPathPrefixValidator()
|
||||
{
|
||||
this.RuleFor(x => x.PathPrefix).NotNull();
|
||||
this.RuleFor(x => x.PathPrefix)
|
||||
.NotNull();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,7 +18,9 @@ public partial class ChangePathExtension : IOperation
|
|||
|
||||
private readonly IValidator<ChangePathExtension> validator;
|
||||
|
||||
public ChangePathExtension(IValidator<ChangePathExtension> validator, ReplacePath replacePath)
|
||||
public ChangePathExtension(
|
||||
IValidator<ChangePathExtension> validator,
|
||||
ReplacePath replacePath)
|
||||
{
|
||||
this.validator = validator;
|
||||
this.replacePath = replacePath;
|
||||
|
@ -33,10 +35,13 @@ public partial class ChangePathExtension : IOperation
|
|||
{
|
||||
this.validator.ValidateAndThrow(this);
|
||||
|
||||
return this.replacePath.WithReplacement(this.RunReplacement).Run(input);
|
||||
return this.replacePath.WithReplacement(this.RunReplacement)
|
||||
.Run(input);
|
||||
}
|
||||
|
||||
private UPath RunReplacement(Entity _, UPath path)
|
||||
private UPath RunReplacement(
|
||||
Entity _,
|
||||
UPath path)
|
||||
{
|
||||
return path.ChangeExtension(this.Extension!);
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ public class ChangePathExtensionValidator : AbstractValidator<ChangePathExtensio
|
|||
{
|
||||
public ChangePathExtensionValidator()
|
||||
{
|
||||
this.RuleFor(x => x.Extension).NotNull();
|
||||
this.RuleFor(x => x.Extension)
|
||||
.NotNull();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,11 +17,15 @@ namespace Nitride.IO.Paths;
|
|||
public partial class LinkDirectChildren : CreateOrUpdateIndex
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public LinkDirectChildren(ILogger logger, IValidator<CreateOrUpdateIndex> validator)
|
||||
public LinkDirectChildren(
|
||||
ILogger logger,
|
||||
IValidator<CreateOrUpdateIndex> validator)
|
||||
: base(logger, validator)
|
||||
{
|
||||
this.UpdateIndex = this.InternalUpdateIndex;
|
||||
this.GetIndexKey = e => e.Get<UPath>().GetDirectoryIndexPath();
|
||||
|
||||
this.GetIndexKey = e => e.Get<UPath>()
|
||||
.GetDirectoryIndexPath();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
@ -34,12 +38,16 @@ public partial class LinkDirectChildren : CreateOrUpdateIndex
|
|||
|
||||
this.Scanner = new DirectChildPathScanner(new EntityScannerValidator());
|
||||
|
||||
input = this.Scanner.Run(input).ToList();
|
||||
input = this.Scanner.Run(input)
|
||||
.ToList();
|
||||
|
||||
return base.Run(input);
|
||||
}
|
||||
|
||||
private Entity InternalUpdateIndex(Entity entity, string _, IEnumerable<Entity> list)
|
||||
private Entity InternalUpdateIndex(
|
||||
Entity entity,
|
||||
string _,
|
||||
IEnumerable<Entity> list)
|
||||
{
|
||||
return entity.Add(new DirectChildEntityList(list));
|
||||
}
|
||||
|
|
|
@ -19,7 +19,9 @@ public partial class MoveToIndexPath : OperationBase
|
|||
|
||||
private readonly IValidator<MoveToIndexPath> validator;
|
||||
|
||||
public MoveToIndexPath(IValidator<MoveToIndexPath> validator, ReplacePath replacePath)
|
||||
public MoveToIndexPath(
|
||||
IValidator<MoveToIndexPath> validator,
|
||||
ReplacePath replacePath)
|
||||
{
|
||||
this.validator = validator;
|
||||
this.replacePath = replacePath;
|
||||
|
@ -54,10 +56,13 @@ public partial class MoveToIndexPath : OperationBase
|
|||
{
|
||||
this.validator.ValidateAndThrow(this);
|
||||
|
||||
return this.replacePath.WithReplacement(this.RunReplacement).Run(input);
|
||||
return this.replacePath.WithReplacement(this.RunReplacement)
|
||||
.Run(input);
|
||||
}
|
||||
|
||||
private UPath RunReplacement(Entity _, UPath path)
|
||||
private UPath RunReplacement(
|
||||
Entity _,
|
||||
UPath path)
|
||||
{
|
||||
// See if we are already an index. If that is true, then we don't
|
||||
// have to move any further.
|
||||
|
|
|
@ -6,6 +6,7 @@ public class MoveToIndexPathValidator : AbstractValidator<MoveToIndexPath>
|
|||
{
|
||||
public MoveToIndexPathValidator()
|
||||
{
|
||||
this.RuleFor(x => x.CanMoveCallback).NotNull();
|
||||
this.RuleFor(x => x.CanMoveCallback)
|
||||
.NotNull();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,7 +18,9 @@ public partial class RemovePathPrefix : IOperation
|
|||
|
||||
private readonly IValidator<RemovePathPrefix> validator;
|
||||
|
||||
public RemovePathPrefix(IValidator<RemovePathPrefix> validator, ReplacePath replacePath)
|
||||
public RemovePathPrefix(
|
||||
IValidator<RemovePathPrefix> validator,
|
||||
ReplacePath replacePath)
|
||||
{
|
||||
this.validator = validator;
|
||||
this.replacePath = replacePath;
|
||||
|
@ -33,17 +35,21 @@ public partial class RemovePathPrefix : IOperation
|
|||
{
|
||||
this.validator.ValidateAndThrow(this);
|
||||
|
||||
return this.replacePath.WithReplacement(this.RunReplacement).Run(input);
|
||||
return this.replacePath.WithReplacement(this.RunReplacement)
|
||||
.Run(input);
|
||||
}
|
||||
|
||||
private UPath RunReplacement(Entity _, UPath path)
|
||||
private UPath RunReplacement(
|
||||
Entity _,
|
||||
UPath path)
|
||||
{
|
||||
string normalized = path.ToString();
|
||||
string prefix = this.PathPrefix.ToString()!;
|
||||
|
||||
if (normalized.StartsWith(prefix))
|
||||
{
|
||||
return (UPath)path.ToString().Substring(prefix.Length);
|
||||
return (UPath)path.ToString()
|
||||
.Substring(prefix.Length);
|
||||
}
|
||||
|
||||
return path;
|
||||
|
|
|
@ -6,6 +6,7 @@ public class RemovePathPrefixValidator : AbstractValidator<RemovePathPrefix>
|
|||
{
|
||||
public RemovePathPrefixValidator()
|
||||
{
|
||||
this.RuleFor(x => x.PathPrefix).NotNull();
|
||||
this.RuleFor(x => x.PathPrefix)
|
||||
.NotNull();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,8 +40,10 @@ public partial class ReplacePath : IOperation
|
|||
{
|
||||
this.validator.ValidateAndThrow(this);
|
||||
|
||||
return input.ForEachEntity<UPath>(
|
||||
(entity, oldPath) =>
|
||||
return input.SelectEntity<UPath>(
|
||||
(
|
||||
entity,
|
||||
oldPath) =>
|
||||
{
|
||||
UPath newPath = this.Replacement(entity, oldPath);
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ public class ReplacePathValidator : AbstractValidator<ReplacePath>
|
|||
{
|
||||
public ReplacePathValidator()
|
||||
{
|
||||
this.RuleFor(x => x.Replacement).NotNull();
|
||||
this.RuleFor(x => x.Replacement)
|
||||
.NotNull();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,7 +17,10 @@ public static class UPathExtensions
|
|||
{
|
||||
if (path.GetNameWithoutExtension() == "index")
|
||||
{
|
||||
return path.GetDirectory().ToString().TrimEnd('/') + "/";
|
||||
return path.GetDirectory()
|
||||
.ToString()
|
||||
.TrimEnd('/')
|
||||
+ "/";
|
||||
}
|
||||
|
||||
return path.ToString();
|
||||
|
@ -33,7 +36,9 @@ public static class UPathExtensions
|
|||
parent = "/";
|
||||
}
|
||||
|
||||
string parentPath = parent.ToString().TrimEnd('/') + "/";
|
||||
string parentPath = parent.ToString()
|
||||
.TrimEnd('/')
|
||||
+ "/";
|
||||
|
||||
return parentPath;
|
||||
}
|
||||
|
|
|
@ -41,8 +41,11 @@ public abstract partial class ConvertMarkdownToBase : IOperation
|
|||
MarkdownPipeline options = builder.Build();
|
||||
|
||||
// Process the Markdown files (while passing everything on).
|
||||
return input.ForEachEntity<IsMarkdown, ITextContent>(
|
||||
(entity, _, content) => this.Convert(entity, content, options));
|
||||
return input.SelectEntity<IsMarkdown, ITextContent>(
|
||||
(
|
||||
entity,
|
||||
_,
|
||||
content) => this.Convert(entity, content, options));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -52,5 +55,8 @@ public abstract partial class ConvertMarkdownToBase : IOperation
|
|||
/// <param name="markdownContent">The content for this entity.</param>
|
||||
/// <param name="options">The markdown pipeline.</param>
|
||||
/// <returns>A converted entity.</returns>
|
||||
protected abstract Entity Convert(Entity entity, ITextContent markdownContent, MarkdownPipeline options);
|
||||
protected abstract Entity Convert(
|
||||
Entity entity,
|
||||
ITextContent markdownContent,
|
||||
MarkdownPipeline options);
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ public class ConvertMarkdownToBaseValidator : AbstractValidator<ConvertMarkdownT
|
|||
{
|
||||
public ConvertMarkdownToBaseValidator()
|
||||
{
|
||||
this.RuleFor(x => x.ConfigureMarkdown).NotNull();
|
||||
this.RuleFor(x => x.ConfigureMarkdown)
|
||||
.NotNull();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@ public class ConvertMarkdownToGemtext : ConvertMarkdownToBase
|
|||
public override ConvertMarkdownToGemtext WithConfigureMarkdown(Action<MarkdownPipelineBuilder>? value)
|
||||
{
|
||||
base.WithConfigureMarkdown(value);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -39,13 +40,18 @@ public class ConvertMarkdownToGemtext : ConvertMarkdownToBase
|
|||
/// <param name="markdownContent">The content for this entity.</param>
|
||||
/// <param name="options">The markdown pipeline.</param>
|
||||
/// <returns>A converted entity.</returns>
|
||||
protected override Entity Convert(Entity entity, ITextContent markdownContent, MarkdownPipeline options)
|
||||
protected override Entity Convert(
|
||||
Entity entity,
|
||||
ITextContent markdownContent,
|
||||
MarkdownPipeline options)
|
||||
{
|
||||
string markdown = markdownContent.GetText();
|
||||
string gemtext = MarkdownGemtext.ToGemtext(markdown, options);
|
||||
var content = new StringTextContent(gemtext);
|
||||
|
||||
entity = entity.SetTextContent(content).Remove<IsMarkdown>().Set(IsGemtext.Instance);
|
||||
entity = entity.SetTextContent(content)
|
||||
.Remove<IsMarkdown>()
|
||||
.Set(IsGemtext.Instance);
|
||||
|
||||
return entity;
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ public class ConvertMarkdownToHtml : ConvertMarkdownToBase
|
|||
public override ConvertMarkdownToHtml WithConfigureMarkdown(Action<MarkdownPipelineBuilder>? value)
|
||||
{
|
||||
base.WithConfigureMarkdown(value);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -36,14 +37,19 @@ public class ConvertMarkdownToHtml : ConvertMarkdownToBase
|
|||
/// <param name="markdownContent">The content for this entity.</param>
|
||||
/// <param name="options">The markdown pipeline.</param>
|
||||
/// <returns>A converted entity.</returns>
|
||||
protected override Entity Convert(Entity entity, ITextContent markdownContent, MarkdownPipeline options)
|
||||
protected override Entity Convert(
|
||||
Entity entity,
|
||||
ITextContent markdownContent,
|
||||
MarkdownPipeline options)
|
||||
{
|
||||
// Convert the entity to Html.
|
||||
string markdown = markdownContent.GetText();
|
||||
string html = Markdig.Markdown.ToHtml(markdown, options);
|
||||
var htmlContent = new StringTextContent(html);
|
||||
|
||||
entity = entity.SetTextContent(htmlContent).Remove<IsMarkdown>().Set(IsHtml.Instance);
|
||||
entity = entity.SetTextContent(htmlContent)
|
||||
.Remove<IsMarkdown>()
|
||||
.Set(IsHtml.Instance);
|
||||
|
||||
// Return the resulting entity.
|
||||
return entity;
|
||||
|
|
|
@ -33,11 +33,14 @@ public partial class IdentifyMarkdown : IOperation
|
|||
{
|
||||
this.validator.ValidateAndThrow(this);
|
||||
|
||||
return input.ForEachEntity<UPath, ITextContent>(this.MarkTextEntities)
|
||||
.ForEachEntity<UPath, IBinaryContent>(this.MarkBinaryEntities);
|
||||
return input.SelectEntity<UPath, ITextContent>(this.MarkTextEntities)
|
||||
.SelectEntity<UPath, IBinaryContent>(this.MarkBinaryEntities);
|
||||
}
|
||||
|
||||
private Entity MarkBinaryEntities(Entity entity, UPath path, IBinaryContent binary)
|
||||
private Entity MarkBinaryEntities(
|
||||
Entity entity,
|
||||
UPath path,
|
||||
IBinaryContent binary)
|
||||
{
|
||||
// If we aren't a Markdown file, then there is nothing we can do about that.
|
||||
if (!this.IsMarkdownTest(entity, path))
|
||||
|
@ -48,7 +51,8 @@ public partial class IdentifyMarkdown : IOperation
|
|||
// Convert the file as a binary.
|
||||
if (binary is ITextContentConvertable textConvertable)
|
||||
{
|
||||
entity = entity.SetTextContent(textConvertable.ToTextContent()).Set(IsMarkdown.Instance);
|
||||
entity = entity.SetTextContent(textConvertable.ToTextContent())
|
||||
.Set(IsMarkdown.Instance);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -59,7 +63,10 @@ public partial class IdentifyMarkdown : IOperation
|
|||
return entity;
|
||||
}
|
||||
|
||||
private Entity MarkTextEntities(Entity entity, UPath path, ITextContent _)
|
||||
private Entity MarkTextEntities(
|
||||
Entity entity,
|
||||
UPath path,
|
||||
ITextContent _)
|
||||
{
|
||||
// If we aren't a Markdown file, then there is nothing
|
||||
// we can do about that.
|
||||
|
|
|
@ -14,7 +14,9 @@ public class IdentifyMarkdownFromPath : IdentifyMarkdown
|
|||
this.IsMarkdownTest = DefaultIsMarkdown;
|
||||
}
|
||||
|
||||
private static bool DefaultIsMarkdown(Entity entity, UPath path)
|
||||
private static bool DefaultIsMarkdown(
|
||||
Entity entity,
|
||||
UPath path)
|
||||
{
|
||||
return (path.GetExtensionWithDot() ?? string.Empty).ToLowerInvariant() switch
|
||||
{
|
||||
|
|
|
@ -6,6 +6,7 @@ public class IdentifyMarkdownValidator : AbstractValidator<IdentifyMarkdown>
|
|||
{
|
||||
public IdentifyMarkdownValidator()
|
||||
{
|
||||
this.RuleFor(x => x.IsMarkdownTest).NotNull();
|
||||
this.RuleFor(x => x.IsMarkdownTest)
|
||||
.NotNull();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Gallium" Version="1.0.2"/>
|
||||
<PackageReference Include="Gallium" Version="1.2.0"/>
|
||||
<PackageReference Include="Markdig" Version="0.30.2"/>
|
||||
<PackageReference Include="MfGames.Markdown.Gemtext" Version="1.2.1"/>
|
||||
<PackageReference Include="Zio" Version="0.15.0"/>
|
||||
|
|
|
@ -6,7 +6,9 @@ namespace Nitride.Slugs;
|
|||
|
||||
public static class NitrideSlugsBuilderExtensions
|
||||
{
|
||||
public static NitrideBuilder UseSlugs(this NitrideBuilder builder, ISlugConverter slugs)
|
||||
public static NitrideBuilder UseSlugs(
|
||||
this NitrideBuilder builder,
|
||||
ISlugConverter slugs)
|
||||
{
|
||||
if (slugs == null)
|
||||
{
|
||||
|
@ -16,7 +18,10 @@ public static class NitrideSlugsBuilderExtensions
|
|||
return builder.ConfigureContainer(
|
||||
x =>
|
||||
{
|
||||
x.RegisterInstance(slugs).As<ISlugConverter>().SingleInstance();
|
||||
x.RegisterInstance(slugs)
|
||||
.As<ISlugConverter>()
|
||||
.SingleInstance();
|
||||
|
||||
x.RegisterModule<NitrideSlugsModule>();
|
||||
});
|
||||
}
|
||||
|
|
|
@ -52,7 +52,8 @@ public class SimpleSlugConverter : ISlugConverter, IEnumerable<string>
|
|||
/// <inheritdoc />
|
||||
public IEnumerator<string> GetEnumerator()
|
||||
{
|
||||
return this.replacements.Select(x => x.Item1).GetEnumerator();
|
||||
return this.replacements.Select(x => x.Item1)
|
||||
.GetEnumerator();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
|
|
@ -34,7 +34,10 @@ public class UnicodeNormalizingSlugConverter : SimpleSlugConverter
|
|||
|
||||
// Normalize the Unicode objects.
|
||||
// Strip out the accents. This is a cheesy way of doing so.
|
||||
char[] chars = input.Normalize(NormalizationForm.FormD).Where(this.IsNonSpacingMark).ToArray();
|
||||
char[] chars = input.Normalize(NormalizationForm.FormD)
|
||||
.Where(this.IsNonSpacingMark)
|
||||
.ToArray();
|
||||
|
||||
string normalized = new string(chars).Normalize(NormalizationForm.FormC);
|
||||
|
||||
// Return the base implementation.
|
||||
|
|
|
@ -22,10 +22,13 @@ public class DatePipelineCommandOption : IPipelineCommandOption
|
|||
|
||||
private readonly Timekeeper timekeeper;
|
||||
|
||||
public DatePipelineCommandOption(ILogger logger, Timekeeper timekeeper)
|
||||
public DatePipelineCommandOption(
|
||||
ILogger logger,
|
||||
Timekeeper timekeeper)
|
||||
{
|
||||
this.logger = logger.ForContext<Instant>();
|
||||
this.timekeeper = timekeeper;
|
||||
|
||||
this.Option = new Option<DateTime>("--date")
|
||||
{
|
||||
Description = "Sets the date to something other than now",
|
||||
|
|
|
@ -22,10 +22,14 @@ public class ExpiresPipelineCommandOption : IPipelineCommandOption
|
|||
|
||||
private readonly ILogger logger;
|
||||
|
||||
public ExpiresPipelineCommandOption(ILogger logger, Timekeeper clock, string? defaultValue = null)
|
||||
public ExpiresPipelineCommandOption(
|
||||
ILogger logger,
|
||||
Timekeeper clock,
|
||||
string? defaultValue = null)
|
||||
{
|
||||
this.logger = logger.ForContext<Instant>();
|
||||
this.clock = clock;
|
||||
|
||||
this.Option = new Option<string?>("--expires", () => defaultValue)
|
||||
{
|
||||
Description = "Sets the expiration time as time before the current date",
|
||||
|
@ -54,6 +58,7 @@ public class ExpiresPipelineCommandOption : IPipelineCommandOption
|
|||
if (this.clock.Expiration == null)
|
||||
{
|
||||
this.logger.Information("No entities will be expired");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -14,9 +14,14 @@ public class CreateDateIndexesValidator : AbstractValidator<CreateDateIndexes>
|
|||
{
|
||||
public CreateDateIndexesValidator()
|
||||
{
|
||||
this.RuleFor(a => a.Timekeeper).NotNull();
|
||||
this.RuleFor(a => a.CreateIndex).NotNull();
|
||||
this.RuleFor(a => a.Formats).NotNull();
|
||||
this.RuleFor(a => a.Timekeeper)
|
||||
.NotNull();
|
||||
|
||||
this.RuleFor(a => a.CreateIndex)
|
||||
.NotNull();
|
||||
|
||||
this.RuleFor(a => a.Formats)
|
||||
.NotNull();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -31,7 +36,9 @@ public partial class CreateDateIndexes : OperationBase, IResolvingOperation
|
|||
{
|
||||
private readonly IValidator<CreateDateIndexes> validator;
|
||||
|
||||
public CreateDateIndexes(IValidator<CreateDateIndexes> validator, Timekeeper timekeeper)
|
||||
public CreateDateIndexes(
|
||||
IValidator<CreateDateIndexes> validator,
|
||||
Timekeeper timekeeper)
|
||||
{
|
||||
this.validator = validator;
|
||||
this.Timekeeper = timekeeper;
|
||||
|
@ -77,7 +84,10 @@ public partial class CreateDateIndexes : OperationBase, IResolvingOperation
|
|||
|
||||
// Go through the inputs and group each one. We also use `ToList` to force the enumeration to completely
|
||||
// resolve and we can get everything we need. We will append the created indexes to the end of this list.
|
||||
var output = input.ForEachEntity<Instant>((entity, instant) => this.GroupOnFormats(instant, entries, entity))
|
||||
var output = input.SelectEntity<Instant>(
|
||||
(
|
||||
entity,
|
||||
instant) => this.GroupOnFormats(instant, entries, entity))
|
||||
.ToList();
|
||||
|
||||
// Going in reverse order (most precise to less precise), we create the various indexes.
|
||||
|
@ -96,8 +106,11 @@ public partial class CreateDateIndexes : OperationBase, IResolvingOperation
|
|||
|
||||
// Get all the entities at this level and split them into ones we've seen (at a lower level) and which
|
||||
// ones are new (these always go on the index).
|
||||
var seenEntities = pair.Value.Where(a => seen.Contains(a)).ToList();
|
||||
var newEntities = pair.Value.Where(a => !seen.Contains(a)).ToList();
|
||||
var seenEntities = pair.Value.Where(a => seen.Contains(a))
|
||||
.ToList();
|
||||
|
||||
var newEntities = pair.Value.Where(a => !seen.Contains(a))
|
||||
.ToList();
|
||||
|
||||
seen.AddRange(newEntities);
|
||||
|
||||
|
@ -126,14 +139,17 @@ public partial class CreateDateIndexes : OperationBase, IResolvingOperation
|
|||
}
|
||||
|
||||
Entity? first = pair.Value[0];
|
||||
string? nextKey = this.Timekeeper.ToDateTime(first.Get<Instant>()).ToString(this.Formats[i + 1]);
|
||||
|
||||
string? nextKey = this.Timekeeper.ToDateTime(first.Get<Instant>())
|
||||
.ToString(this.Formats[i + 1]);
|
||||
|
||||
if (!indexes.ContainsKey(nextKey))
|
||||
{
|
||||
indexes[nextKey] = new List<Entity>();
|
||||
}
|
||||
|
||||
indexes[nextKey].Add(indexEntity);
|
||||
indexes[nextKey]
|
||||
.Add(indexEntity);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -144,10 +160,14 @@ public partial class CreateDateIndexes : OperationBase, IResolvingOperation
|
|||
public CreateDateIndexes WithFormats(params string[] formats)
|
||||
{
|
||||
this.Formats = formats.ToList();
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
private Entity GroupOnFormats(Instant instant, List<Dictionary<string, List<Entity>>> grouped, Entity entity)
|
||||
private Entity GroupOnFormats(
|
||||
Instant instant,
|
||||
List<Dictionary<string, List<Entity>>> grouped,
|
||||
Entity entity)
|
||||
{
|
||||
var dateTime = this.Timekeeper.ToDateTime(instant);
|
||||
|
||||
|
@ -155,12 +175,14 @@ public partial class CreateDateIndexes : OperationBase, IResolvingOperation
|
|||
{
|
||||
string? formatted = dateTime.ToString(this.Formats[i]);
|
||||
|
||||
if (!grouped[i].ContainsKey(formatted))
|
||||
if (!grouped[i]
|
||||
.ContainsKey(formatted))
|
||||
{
|
||||
grouped[i][formatted] = new List<Entity>();
|
||||
}
|
||||
|
||||
grouped[i][formatted].Add(entity);
|
||||
grouped[i][formatted]
|
||||
.Add(entity);
|
||||
}
|
||||
|
||||
return entity;
|
||||
|
|
|
@ -6,7 +6,11 @@ namespace Nitride.Temporal;
|
|||
|
||||
public class DateIndex
|
||||
{
|
||||
public DateIndex(string key, string format, IReadOnlyList<Entity> entries, IReadOnlyList<Entity> indexes)
|
||||
public DateIndex(
|
||||
string key,
|
||||
string format,
|
||||
IReadOnlyList<Entity> entries,
|
||||
IReadOnlyList<Entity> indexes)
|
||||
{
|
||||
this.Key = key;
|
||||
this.Format = format;
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
using FluentValidation;
|
||||
|
||||
|
@ -17,7 +16,9 @@ public partial class FilterOutExpiredInstant : OperationBase
|
|||
{
|
||||
private readonly IValidator<FilterOutExpiredInstant> validator;
|
||||
|
||||
public FilterOutExpiredInstant(IValidator<FilterOutExpiredInstant> validator, Timekeeper clock)
|
||||
public FilterOutExpiredInstant(
|
||||
IValidator<FilterOutExpiredInstant> validator,
|
||||
Timekeeper clock)
|
||||
{
|
||||
this.validator = validator;
|
||||
this.Timekeeper = clock;
|
||||
|
@ -35,15 +36,17 @@ public partial class FilterOutExpiredInstant : OperationBase
|
|||
return input;
|
||||
}
|
||||
|
||||
return input.ForEntities<Instant, CanExpire>(x => x.Where(this.IsNotExpired));
|
||||
return input.SelectEntity<Instant, CanExpire>(this.IsNotExpired);
|
||||
}
|
||||
|
||||
private bool IsNotExpired(Entity entity)
|
||||
private Entity? IsNotExpired(
|
||||
Entity entity,
|
||||
Instant instant,
|
||||
CanExpire _)
|
||||
{
|
||||
Instant instant = entity.Get<Instant>();
|
||||
Instant expiration = this.Timekeeper.Expiration!.Value;
|
||||
bool isExpired = instant.CompareTo(expiration) < 0;
|
||||
|
||||
return !isExpired;
|
||||
return isExpired ? null : entity;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ public class FilterOutExpiredInstantValidator : AbstractValidator<FilterOutExpir
|
|||
{
|
||||
public FilterOutExpiredInstantValidator()
|
||||
{
|
||||
this.RuleFor(x => x.Timekeeper).NotNull();
|
||||
this.RuleFor(x => x.Timekeeper)
|
||||
.NotNull();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,6 +25,9 @@ public partial class FilterOutFutureInstant : OperationBase
|
|||
{
|
||||
Instant now = this.Timekeeper.Clock.GetCurrentInstant();
|
||||
|
||||
return input.WhereEntities<Instant>((_, instant) => instant.CompareTo(now) <= 0);
|
||||
return input.SelectEntity<Instant>(
|
||||
(
|
||||
entity,
|
||||
instant) => instant.CompareTo(now) <= 0 ? null : entity);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ public class FilterOutFutureInstantValidator : AbstractValidator<FilterOutFuture
|
|||
{
|
||||
public FilterOutFutureInstantValidator()
|
||||
{
|
||||
this.RuleFor(x => x.Timekeeper).NotNull();
|
||||
this.RuleFor(x => x.Timekeeper)
|
||||
.NotNull();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Autofac" Version="6.4.0"/>
|
||||
<PackageReference Include="Gallium" Version="1.0.2" />
|
||||
<PackageReference Include="Gallium" Version="1.2.0"/>
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="6.0.0"/>
|
||||
<PackageReference Include="NodaTime" Version="3.1.0"/>
|
||||
<PackageReference Include="NodaTime.Testing" Version="3.1.0"/>
|
||||
|
|
|
@ -36,7 +36,8 @@ public static class NitrideTemporalBuilderExtensions
|
|||
// Add in the CLI options.
|
||||
if (config.AddDateOptionToCommandLine)
|
||||
{
|
||||
x.RegisterType<DatePipelineCommandOption>().As<IPipelineCommandOption>();
|
||||
x.RegisterType<DatePipelineCommandOption>()
|
||||
.As<IPipelineCommandOption>();
|
||||
}
|
||||
|
||||
if (config.AddExpireOptionToCommandLine && config.Expiration != null)
|
||||
|
@ -56,7 +57,9 @@ public static class NitrideTemporalBuilderExtensions
|
|||
if (config.DateTimeZone != null)
|
||||
{
|
||||
builder.ConfigureSite(
|
||||
(_, scope) =>
|
||||
(
|
||||
_,
|
||||
scope) =>
|
||||
{
|
||||
ILogger logger = scope.Resolve<ILogger>();
|
||||
Timekeeper timekeeper = scope.Resolve<Timekeeper>();
|
||||
|
|
|
@ -33,6 +33,7 @@ public partial class NitrideTemporalConfiguration
|
|||
public NitrideTemporalConfiguration WithDateTimeZone(string zoneName)
|
||||
{
|
||||
this.DateTimeZone = DateTimeZoneProviders.Tzdb[zoneName];
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,12 @@ public class NitrideTemporalModule : Module
|
|||
{
|
||||
builder.RegisterOperators(this);
|
||||
builder.RegisterValidators(this);
|
||||
builder.RegisterType<Timekeeper>().AsSelf().SingleInstance();
|
||||
builder.RegisterGeneric(typeof(SetInstantFromComponent<>)).As(typeof(SetInstantFromComponent<>));
|
||||
|
||||
builder.RegisterType<Timekeeper>()
|
||||
.AsSelf()
|
||||
.SingleInstance();
|
||||
|
||||
builder.RegisterGeneric(typeof(SetInstantFromComponent<>))
|
||||
.As(typeof(SetInstantFromComponent<>));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@ public class SetInstantFromComponent<TComponent> : OperationBase
|
|||
{
|
||||
this.validator.ValidateAndThrow(this);
|
||||
|
||||
return input.ForEachEntity<TComponent>(this.Set);
|
||||
return input.SelectEntity<TComponent>(this.Set);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -53,10 +53,13 @@ public class SetInstantFromComponent<TComponent> : OperationBase
|
|||
public SetInstantFromComponent<TComponent> WithGetDateTimeObject(Func<Entity, TComponent, object?>? callback)
|
||||
{
|
||||
this.GetDateTimeObject = callback;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
private Entity Set(Entity entity, TComponent component)
|
||||
private Entity Set(
|
||||
Entity entity,
|
||||
TComponent component)
|
||||
{
|
||||
object? temporal = this.GetDateTimeObject!(entity, component);
|
||||
Instant instant;
|
||||
|
@ -67,22 +70,27 @@ public class SetInstantFromComponent<TComponent> : OperationBase
|
|||
return entity;
|
||||
case Instant direct:
|
||||
instant = direct;
|
||||
|
||||
break;
|
||||
case LocalDate other:
|
||||
instant = this.clock.CreateInstant(other);
|
||||
|
||||
break;
|
||||
case DateTime other:
|
||||
instant = this.clock.CreateInstant(other);
|
||||
|
||||
break;
|
||||
case DateTimeOffset other:
|
||||
instant = this.clock.CreateInstant(other);
|
||||
|
||||
break;
|
||||
default:
|
||||
throw new InvalidOperationException(
|
||||
"Did not get a date time object from the callback. "
|
||||
+ "Can only handle DateTime, DateTimeOffset, LocalDate, "
|
||||
+ "and Instant. Got a "
|
||||
+ temporal.GetType().Name
|
||||
+ temporal.GetType()
|
||||
.Name
|
||||
+ " instead.");
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ public class SetInstantFromComponentValidator<TComponent> : AbstractValidator<Se
|
|||
{
|
||||
public SetInstantFromComponentValidator()
|
||||
{
|
||||
this.RuleFor(x => x.GetDateTimeObject).NotNull();
|
||||
this.RuleFor(x => x.GetDateTimeObject)
|
||||
.NotNull();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,7 +25,9 @@ public partial class SetInstantFromPath : OperationBase
|
|||
|
||||
private readonly IValidator<SetInstantFromPath> validator;
|
||||
|
||||
public SetInstantFromPath(IValidator<SetInstantFromPath> validator, Timekeeper clock)
|
||||
public SetInstantFromPath(
|
||||
IValidator<SetInstantFromPath> validator,
|
||||
Timekeeper clock)
|
||||
{
|
||||
this.validator = validator;
|
||||
this.clock = clock;
|
||||
|
@ -43,10 +45,12 @@ public partial class SetInstantFromPath : OperationBase
|
|||
{
|
||||
this.validator.ValidateAndThrow(this);
|
||||
|
||||
return input.ForEachEntity<UPath>(this.Set);
|
||||
return input.SelectEntity<UPath>(this.Set);
|
||||
}
|
||||
|
||||
private Entity Set(Entity entity, UPath path)
|
||||
private Entity Set(
|
||||
Entity entity,
|
||||
UPath path)
|
||||
{
|
||||
// See if the path matches the given expression.
|
||||
Match match = this.PathRegex!.Match(path.ToString());
|
||||
|
@ -58,9 +62,15 @@ public partial class SetInstantFromPath : OperationBase
|
|||
|
||||
// Create an Instant from this.
|
||||
Instant instant = this.clock.CreateInstant(
|
||||
Convert.ToInt32(match.Groups["year"].Value),
|
||||
Convert.ToInt32(match.Groups["month"].Value),
|
||||
Convert.ToInt32(match.Groups["day"].Value));
|
||||
Convert.ToInt32(
|
||||
match.Groups["year"]
|
||||
.Value),
|
||||
Convert.ToInt32(
|
||||
match.Groups["month"]
|
||||
.Value),
|
||||
Convert.ToInt32(
|
||||
match.Groups["day"]
|
||||
.Value));
|
||||
|
||||
return entity.Set(instant);
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ public class SetInstantFromPathValidator : AbstractValidator<SetInstantFromPath>
|
|||
{
|
||||
public SetInstantFromPathValidator()
|
||||
{
|
||||
this.RuleFor(x => x.PathRegex).NotNull();
|
||||
this.RuleFor(x => x.PathRegex)
|
||||
.NotNull();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,7 +37,8 @@ public class Timekeeper
|
|||
/// Gets the instant when the files expire.
|
||||
/// </summary>
|
||||
public Instant? Expiration => this.Expires.HasValue
|
||||
? this.Clock.GetCurrentInstant().Minus(Duration.FromTimeSpan(this.Expires.Value))
|
||||
? this.Clock.GetCurrentInstant()
|
||||
.Minus(Duration.FromTimeSpan(this.Expires.Value))
|
||||
: null;
|
||||
|
||||
/// <summary>
|
||||
|
@ -53,7 +54,10 @@ public class Timekeeper
|
|||
/// <param name="month">The numerical month.</param>
|
||||
/// <param name="day">The numerical day of month.</param>
|
||||
/// <returns>An instant in the clock's time zone.</returns>
|
||||
public Instant CreateInstant(int year, int month, int day)
|
||||
public Instant CreateInstant(
|
||||
int year,
|
||||
int month,
|
||||
int day)
|
||||
{
|
||||
var date = new LocalDate(year, month, day);
|
||||
|
||||
|
@ -111,6 +115,8 @@ public class Timekeeper
|
|||
/// <returns>A DateTime in the correct date and time.</returns>
|
||||
public DateTime ToDateTime(Instant instant)
|
||||
{
|
||||
return instant.InZone(this.DateTimeZone).ToDateTimeOffset().DateTime;
|
||||
return instant.InZone(this.DateTimeZone)
|
||||
.ToDateTimeOffset()
|
||||
.DateTime;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Gallium" Version="1.0.2"/>
|
||||
<PackageReference Include="Gallium" Version="1.2.0"/>
|
||||
<PackageReference Include="YamlDotNet" Version="11.2.1"/>
|
||||
</ItemGroup>
|
||||
|
||||
|
|
|
@ -7,7 +7,9 @@ public class NitrideYamlModule : Module
|
|||
/// <inheritdoc />
|
||||
protected override void Load(ContainerBuilder builder)
|
||||
{
|
||||
builder.RegisterGeneric(typeof(ParseYamlHeader<>)).As(typeof(ParseYamlHeader<>));
|
||||
builder.RegisterGeneric(typeof(ParseYamlHeader<>))
|
||||
.As(typeof(ParseYamlHeader<>));
|
||||
|
||||
builder.RegisterOperators(this);
|
||||
builder.RegisterValidators(this);
|
||||
}
|
||||
|
|
|
@ -52,7 +52,10 @@ public class ParseYamlHeader<TModel> : OperationBase
|
|||
// Process through the files. We only care about the text ones
|
||||
// and we'll put a default TModel in for those that don't have a
|
||||
// header.
|
||||
return input.ForEachEntity<ITextContent>((entity, content) => this.Parse(entity, content, deserializer));
|
||||
return input.SelectEntity<ITextContent>(
|
||||
(
|
||||
entity,
|
||||
content) => this.Parse(entity, content, deserializer));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -64,6 +67,7 @@ public class ParseYamlHeader<TModel> : OperationBase
|
|||
public ParseYamlHeader<TModel> WithIgnoreUnmatchedProperties(bool value)
|
||||
{
|
||||
this.ignoreUnmatchedProperties = value;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -76,16 +80,21 @@ public class ParseYamlHeader<TModel> : OperationBase
|
|||
public ParseYamlHeader<TModel> WithNamingConvention(INamingConvention value)
|
||||
{
|
||||
this.namingConvention = value;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public ParseYamlHeader<TModel> WithRemoveHeader(bool value)
|
||||
{
|
||||
this.RemoveHeader = value;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
private Entity Parse(Entity entity, ITextContent content, IDeserializer deserializer)
|
||||
private Entity Parse(
|
||||
Entity entity,
|
||||
ITextContent content,
|
||||
IDeserializer deserializer)
|
||||
{
|
||||
// Get the textual input from the stream.
|
||||
using TextReader reader = content.GetReader();
|
||||
|
@ -148,6 +157,8 @@ public class ParseYamlHeader<TModel> : OperationBase
|
|||
}
|
||||
|
||||
// Set the model and return it.
|
||||
return entity.Set(model).SetTextContent(new StringTextContent(buffer.ToString())).Set(HasYamlModel.Instance);
|
||||
return entity.Set(model)
|
||||
.SetTextContent(new StringTextContent(buffer.ToString()))
|
||||
.Set(HasYamlModel.Instance);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,7 +20,10 @@ public class BuildCommand : Command, ICommandHandler
|
|||
|
||||
private readonly PipelineManager pipelines;
|
||||
|
||||
public BuildCommand(ILogger logger, PipelineManager pipelines, IList<IPipelineCommandOption> pipelineOptions)
|
||||
public BuildCommand(
|
||||
ILogger logger,
|
||||
PipelineManager pipelines,
|
||||
IList<IPipelineCommandOption> pipelineOptions)
|
||||
: base("build", "Generate the website")
|
||||
{
|
||||
// Set up our simple member variables.
|
||||
|
|
|
@ -36,7 +36,9 @@ public static class EntityBinaryContentExtensions
|
|||
/// <param name="content">The content to add to the entity.</param>
|
||||
/// <typeparam name="TType">The base type of the content.</typeparam>
|
||||
/// <returns>The entity or a copy with the new component.</returns>
|
||||
public static Entity SetBinaryContent<TType>(this Entity entity, TType content)
|
||||
public static Entity SetBinaryContent<TType>(
|
||||
this Entity entity,
|
||||
TType content)
|
||||
where TType : IBinaryContent
|
||||
{
|
||||
return entity.SetContent<IBinaryContent>(content);
|
||||
|
|
|
@ -19,7 +19,8 @@ public static class EntityContentExtensions
|
|||
/// <returns>The one and only content component.</returns>
|
||||
public static IContent GetContent(this Entity entity)
|
||||
{
|
||||
Type type = entity.GetComponentTypes().Single(x => typeof(IContent).IsAssignableFrom(x));
|
||||
Type type = entity.GetComponentTypes()
|
||||
.Single(x => typeof(IContent).IsAssignableFrom(x));
|
||||
|
||||
return entity.Get<IContent>(type);
|
||||
}
|
||||
|
@ -31,7 +32,8 @@ public static class EntityContentExtensions
|
|||
/// <returns>True if there is a component extending `IContent`.</returns>
|
||||
public static bool HasContent(this Entity entity)
|
||||
{
|
||||
return entity.GetComponentTypes().Any(x => typeof(IContent).IsAssignableFrom(x));
|
||||
return entity.GetComponentTypes()
|
||||
.Any(x => typeof(IContent).IsAssignableFrom(x));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -42,10 +44,13 @@ public static class EntityContentExtensions
|
|||
/// <param name="content">The content to add to the entity.</param>
|
||||
/// <typeparam name="TType">The base type of the content.</typeparam>
|
||||
/// <returns>The entity or a copy with the new component.</returns>
|
||||
public static Entity SetContent<TType>(this Entity entity, TType content)
|
||||
public static Entity SetContent<TType>(
|
||||
this Entity entity,
|
||||
TType content)
|
||||
where TType : IContent
|
||||
{
|
||||
IEnumerable<Type>? existing = entity.GetComponentTypes().Where(x => typeof(IContent).IsAssignableFrom(x));
|
||||
IEnumerable<Type>? existing = entity.GetComponentTypes()
|
||||
.Where(x => typeof(IContent).IsAssignableFrom(x));
|
||||
|
||||
foreach (Type? component in existing)
|
||||
{
|
||||
|
|
|
@ -26,7 +26,9 @@ public static class EntityTextContentExtensions
|
|||
/// <param name="content">The content to add to the entity.</param>
|
||||
/// <typeparam name="TType">The base type of the content.</typeparam>
|
||||
/// <returns>The entity or a copy with the new component.</returns>
|
||||
public static Entity SetTextContent<TType>(this Entity entity, TType content)
|
||||
public static Entity SetTextContent<TType>(
|
||||
this Entity entity,
|
||||
TType content)
|
||||
where TType : ITextContent
|
||||
{
|
||||
return entity.SetContent<ITextContent>(content);
|
||||
|
@ -41,7 +43,9 @@ public static class EntityTextContentExtensions
|
|||
/// <param name="content">The content to add to the entity.</param>
|
||||
/// <typeparam name="TType">The base type of the content.</typeparam>
|
||||
/// <returns>The entity or a copy with the new component.</returns>
|
||||
public static Entity SetTextContent(this Entity entity, string content)
|
||||
public static Entity SetTextContent(
|
||||
this Entity entity,
|
||||
string content)
|
||||
{
|
||||
return entity.SetTextContent(new StringTextContent(content));
|
||||
}
|
||||
|
|
|
@ -28,7 +28,9 @@ public partial class CreateOrUpdateIndex : OperationBase
|
|||
|
||||
private readonly IValidator<CreateOrUpdateIndex> validator;
|
||||
|
||||
public CreateOrUpdateIndex(ILogger logger, IValidator<CreateOrUpdateIndex> validator)
|
||||
public CreateOrUpdateIndex(
|
||||
ILogger logger,
|
||||
IValidator<CreateOrUpdateIndex> validator)
|
||||
{
|
||||
this.validator = validator;
|
||||
this.logger = logger.ForContext(typeof(CreateOrUpdateIndex));
|
||||
|
@ -65,7 +67,8 @@ public partial class CreateOrUpdateIndex : OperationBase
|
|||
this.validator.ValidateAndThrow(this);
|
||||
|
||||
// Get the list of all the scanned entities.
|
||||
var scanned = this.Scanner.GetScannedResults().ToDictionary(x => x.Key, x => x.Value);
|
||||
var scanned = this.Scanner.GetScannedResults()
|
||||
.ToDictionary(x => x.Key, x => x.Value);
|
||||
|
||||
// We loop through the results and look for index entities. Any one we
|
||||
// find, we update with the existing entries. If we get to the end and
|
||||
|
|
|
@ -6,8 +6,13 @@ public class CreateOrUpdateIndexValidator : AbstractValidator<CreateOrUpdateInde
|
|||
{
|
||||
public CreateOrUpdateIndexValidator()
|
||||
{
|
||||
this.RuleFor(x => x.Scanner).NotNull();
|
||||
this.RuleFor(x => x.GetIndexKey).NotNull();
|
||||
this.RuleFor(x => x.UpdateIndex).NotNull();
|
||||
this.RuleFor(x => x.Scanner)
|
||||
.NotNull();
|
||||
|
||||
this.RuleFor(x => x.GetIndexKey)
|
||||
.NotNull();
|
||||
|
||||
this.RuleFor(x => x.UpdateIndex)
|
||||
.NotNull();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -74,6 +74,7 @@ public partial class EntityScanner : OperationBase
|
|||
public IEnumerable<string> GetScannedKeys()
|
||||
{
|
||||
this.CheckDone();
|
||||
|
||||
return this.results.Keys.ToImmutableList();
|
||||
}
|
||||
|
||||
|
@ -114,7 +115,10 @@ public partial class EntityScanner : OperationBase
|
|||
this.results.AddOrUpdate(
|
||||
key,
|
||||
_ => new List<Entity> { entity },
|
||||
(_, list) => list.Union(new[] { entity }).ToList());
|
||||
(
|
||||
_,
|
||||
list) => list.Union(new[] { entity })
|
||||
.ToList());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ public class EntityScannerValidator : AbstractValidator<EntityScanner>
|
|||
{
|
||||
public EntityScannerValidator()
|
||||
{
|
||||
this.RuleFor(x => x.GetKeysFromEntity).NotNull();
|
||||
this.RuleFor(x => x.GetKeysFromEntity)
|
||||
.NotNull();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,9 @@ namespace Nitride.Entities;
|
|||
/// </summary>
|
||||
public class EntitySequence
|
||||
{
|
||||
public EntitySequence(IReadOnlyList<Entity> sequence, int index)
|
||||
public EntitySequence(
|
||||
IReadOnlyList<Entity> sequence,
|
||||
int index)
|
||||
{
|
||||
this.Sequence = sequence;
|
||||
this.Index = index;
|
||||
|
|
|
@ -20,8 +20,14 @@ public partial class LinkEntitySequence : OperationBase, IResolvingOperation
|
|||
public LinkEntitySequence(IValidator<LinkEntitySequence> validator)
|
||||
{
|
||||
this.validator = validator;
|
||||
this.CreateSequenceIndex = (list, index) => new EntitySequence(list, index);
|
||||
this.AddSequenceIndex = (entity, sequence) => entity.Add(sequence);
|
||||
|
||||
this.CreateSequenceIndex = (
|
||||
list,
|
||||
index) => new EntitySequence(list, index);
|
||||
|
||||
this.AddSequenceIndex = (
|
||||
entity,
|
||||
sequence) => entity.Add(sequence);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -6,7 +6,10 @@ public class LinkEntitySequenceValidator : AbstractValidator<LinkEntitySequence>
|
|||
{
|
||||
public LinkEntitySequenceValidator()
|
||||
{
|
||||
this.RuleFor(x => x.CreateSequenceIndex).NotNull();
|
||||
this.RuleFor(x => x.AddSequenceIndex).NotNull();
|
||||
this.RuleFor(x => x.CreateSequenceIndex)
|
||||
.NotNull();
|
||||
|
||||
this.RuleFor(x => x.AddSequenceIndex)
|
||||
.NotNull();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,8 +17,8 @@
|
|||
<ItemGroup>
|
||||
<PackageReference Include="Autofac" Version="6.4.0"/>
|
||||
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="8.0.0"/>
|
||||
<PackageReference Include="FluentValidation" Version="11.0.2" />
|
||||
<PackageReference Include="Gallium" Version="1.0.2" />
|
||||
<PackageReference Include="FluentValidation" Version="11.1.0"/>
|
||||
<PackageReference Include="Gallium" Version="1.2.0"/>
|
||||
<PackageReference Include="Humanizer.Core" Version="2.14.1"/>
|
||||
<PackageReference Include="MfGames.ToolBuilder" Version="4.0.2"/>
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="6.0.1"/>
|
||||
|
|
|
@ -40,7 +40,10 @@ public class NitrideBuilder
|
|||
this.configureSiteCallbacks = new List<Action<NitrideBuilder, ILifetimeScope>>();
|
||||
this.configureContainerCallbacks = new List<Action<ContainerBuilder>>();
|
||||
this.nitrideModule = new NitrideModule();
|
||||
this.nitrideModule.ApplicationName = Assembly.GetExecutingAssembly().GetName().Name!;
|
||||
|
||||
this.nitrideModule.ApplicationName = Assembly.GetExecutingAssembly()
|
||||
.GetName()
|
||||
.Name!;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -59,6 +62,7 @@ public class NitrideBuilder
|
|||
public NitrideBuilder ConfigureContainer(Action<ContainerBuilder> callback)
|
||||
{
|
||||
this.configureContainerCallbacks.Add(callback);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -71,6 +75,7 @@ public class NitrideBuilder
|
|||
public NitrideBuilder ConfigureSite(Action<NitrideBuilder, ILifetimeScope> callback)
|
||||
{
|
||||
this.configureSiteCallbacks.Add(callback);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -99,6 +104,7 @@ public class NitrideBuilder
|
|||
public NitrideBuilder WithApplicationDescription(string value)
|
||||
{
|
||||
this.nitrideModule.Description = value;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -108,6 +114,7 @@ public class NitrideBuilder
|
|||
public NitrideBuilder WithApplicationName(string value)
|
||||
{
|
||||
this.nitrideModule.ApplicationName = value;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -124,6 +131,7 @@ public class NitrideBuilder
|
|||
public NitrideBuilder WithRootDirectory(DirectoryInfo directory)
|
||||
{
|
||||
this.RootDirectory = directory;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -148,11 +156,14 @@ public class NitrideBuilder
|
|||
}
|
||||
}
|
||||
|
||||
private void RegisterRootDirectory(ILogger logger, ContainerBuilder builder)
|
||||
private void RegisterRootDirectory(
|
||||
ILogger logger,
|
||||
ContainerBuilder builder)
|
||||
{
|
||||
if (this.RootDirectory == null)
|
||||
{
|
||||
logger.Verbose("No root directory is registered");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -161,6 +172,8 @@ public class NitrideBuilder
|
|||
var rootFileSystem = new PhysicalFileSystem();
|
||||
var subFileSystem = new SubFileSystem(rootFileSystem, this.RootDirectory.FullName);
|
||||
|
||||
builder.RegisterInstance(subFileSystem).As<IFileSystem>().SingleInstance();
|
||||
builder.RegisterInstance(subFileSystem)
|
||||
.As<IFileSystem>()
|
||||
.SingleInstance();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@ using System.CommandLine;
|
|||
using Autofac;
|
||||
|
||||
using Nitride.Commands;
|
||||
using Nitride.Entities;
|
||||
using Nitride.Pipelines;
|
||||
|
||||
namespace Nitride;
|
||||
|
@ -22,15 +21,22 @@ public class NitrideModule : Module
|
|||
protected override void Load(ContainerBuilder builder)
|
||||
{
|
||||
// Pipelines
|
||||
builder.RegisterType<PipelineRunner>().AsSelf();
|
||||
builder.RegisterType<PipelineManager>().AsSelf().SingleInstance();
|
||||
builder.RegisterType<PipelineRunner>()
|
||||
.AsSelf();
|
||||
|
||||
builder.RegisterType<PipelineManager>()
|
||||
.AsSelf()
|
||||
.SingleInstance();
|
||||
|
||||
// Operations
|
||||
builder.RegisterValidators(this);
|
||||
builder.RegisterOperators(this);
|
||||
|
||||
// Commands
|
||||
builder.RegisterType<BuildCommand>().AsSelf().As<Command>().SingleInstance();
|
||||
builder.RegisterType<BuildCommand>()
|
||||
.AsSelf()
|
||||
.As<Command>()
|
||||
.SingleInstance();
|
||||
|
||||
// MfGames.ToolBuilder requires the RootCommand to be registered. This is because
|
||||
// of various things, mostly coordinating between different systems.
|
||||
|
|
|
@ -6,13 +6,24 @@ namespace Nitride;
|
|||
|
||||
public static class NitrideModuleExtensions
|
||||
{
|
||||
public static void RegisterOperators(this ContainerBuilder builder, Module module)
|
||||
public static void RegisterOperators(
|
||||
this ContainerBuilder builder,
|
||||
Module module)
|
||||
{
|
||||
builder.RegisterAssemblyTypes(module.GetType().Assembly).Where(x => x.IsAssignableTo<IOperation>()).AsSelf();
|
||||
builder.RegisterAssemblyTypes(
|
||||
module.GetType()
|
||||
.Assembly)
|
||||
.Where(x => x.IsAssignableTo<IOperation>())
|
||||
.AsSelf();
|
||||
}
|
||||
|
||||
public static void RegisterValidators(this ContainerBuilder builder, Module module)
|
||||
public static void RegisterValidators(
|
||||
this ContainerBuilder builder,
|
||||
Module module)
|
||||
{
|
||||
builder.RegisterAssemblyTypes(module.GetType().Assembly).AsClosedTypesOf(typeof(IValidator<>));
|
||||
builder.RegisterAssemblyTypes(
|
||||
module.GetType()
|
||||
.Assembly)
|
||||
.AsClosedTypesOf(typeof(IValidator<>));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,7 +16,9 @@ public static class NitrideOperationExtensions
|
|||
/// <param name="input">The entities to perform the operation against.</param>
|
||||
/// <param name="operation">The operation to run.</param>
|
||||
/// <returns>The results of the operation.</returns>
|
||||
public static IEnumerable<Entity> Run(this IEnumerable<Entity> input, IOperation operation)
|
||||
public static IEnumerable<Entity> Run(
|
||||
this IEnumerable<Entity> input,
|
||||
IOperation operation)
|
||||
{
|
||||
return operation.Run(input);
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ public abstract class PipelineBase : IPipeline
|
|||
public PipelineBase AddDependency(IPipeline pipeline)
|
||||
{
|
||||
this.dependencies.Add(pipeline);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -35,6 +36,7 @@ public abstract class PipelineBase : IPipeline
|
|||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
return this.GetType().Name;
|
||||
return this.GetType()
|
||||
.Name;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,7 +26,10 @@ public class PipelineManager
|
|||
|
||||
private ICollection<IPipeline> pipelines;
|
||||
|
||||
public PipelineManager(ILogger logger, IEnumerable<IPipeline> pipelines, PipelineRunner.Factory createEntry)
|
||||
public PipelineManager(
|
||||
ILogger logger,
|
||||
IEnumerable<IPipeline> pipelines,
|
||||
PipelineRunner.Factory createEntry)
|
||||
{
|
||||
this.createEntry = createEntry;
|
||||
this.logger = logger.ForContext<PipelineManager>();
|
||||
|
@ -59,21 +62,26 @@ public class PipelineManager
|
|||
// resulting tasks and then wait for all of them to end.
|
||||
this.logger.Verbose("Starting {Count:l}", "pipeline".ToQuantity(this.pipelines.Count));
|
||||
|
||||
Task[] tasks = this.entries.Select(x => Task.Run(async () => await x.RunAsync())).ToArray();
|
||||
Task[] tasks = this.entries.Select(x => Task.Run(async () => await x.RunAsync()))
|
||||
.ToArray();
|
||||
|
||||
var report = TimeSpan.FromSeconds(15);
|
||||
|
||||
while (!Task.WaitAll(tasks, report))
|
||||
{
|
||||
var waiting = this.entries.Where(x => !x.IsFinished).ToList();
|
||||
var waiting = this.entries.Where(x => !x.IsFinished)
|
||||
.ToList();
|
||||
|
||||
this.logger.Debug("Waiting for {Count:l} to finish running", "pipeline".ToQuantity(waiting.Count));
|
||||
|
||||
IOrderedEnumerable<IGrouping<PipelineRunnerState, PipelineRunner>> states =
|
||||
waiting.GroupBy(x => x.State, x => x).OrderBy(x => (int)x.Key);
|
||||
waiting.GroupBy(x => x.State, x => x)
|
||||
.OrderBy(x => (int)x.Key);
|
||||
|
||||
foreach (IGrouping<PipelineRunnerState, PipelineRunner>? state in states)
|
||||
{
|
||||
var statePipelines = state.OrderBy(x => x.Pipeline.ToString()).ToList();
|
||||
var statePipelines = state.OrderBy(x => x.Pipeline.ToString())
|
||||
.ToList();
|
||||
|
||||
this.logger.Verbose(
|
||||
"Waiting for {Count:l} in {State}: {List:l}",
|
||||
|
@ -120,12 +128,14 @@ public class PipelineManager
|
|||
|
||||
// Wrap all the pipelines into entries. We do this before the next
|
||||
// step so we can have the entries depend on the entries.
|
||||
this.entries = this.pipelines.Select(x => this.createEntry(x)).ToList();
|
||||
this.entries = this.pipelines.Select(x => this.createEntry(x))
|
||||
.ToList();
|
||||
|
||||
// Go through and connect the pipelines together.
|
||||
foreach (PipelineRunner? entry in this.entries)
|
||||
{
|
||||
var dependencies = entry.Pipeline.GetDependencies().ToList();
|
||||
var dependencies = entry.Pipeline.GetDependencies()
|
||||
.ToList();
|
||||
|
||||
foreach (IPipeline? dependency in dependencies)
|
||||
{
|
||||
|
|
|
@ -46,7 +46,9 @@ public class PipelineRunner
|
|||
/// </summary>
|
||||
private int waitingOnConsumers;
|
||||
|
||||
public PipelineRunner(ILogger logger, IPipeline pipeline)
|
||||
public PipelineRunner(
|
||||
ILogger logger,
|
||||
IPipeline pipeline)
|
||||
{
|
||||
this.Pipeline = pipeline ?? throw new ArgumentNullException(nameof(pipeline));
|
||||
this.Incoming = new List<PipelineRunner>();
|
||||
|
@ -159,6 +161,7 @@ public class PipelineRunner
|
|||
+ " state (not Initialized or Finalized)",
|
||||
this.Pipeline,
|
||||
this.State);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -175,6 +178,7 @@ public class PipelineRunner
|
|||
if (this.WaitForDependencies())
|
||||
{
|
||||
this.SignalDoneWithInputs();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -233,6 +237,7 @@ public class PipelineRunner
|
|||
newState,
|
||||
this.ElapsedFromInitialized,
|
||||
this.ElapsedFromState);
|
||||
|
||||
this.changed = DateTime.Now;
|
||||
this.State = newState;
|
||||
}
|
||||
|
@ -250,7 +255,8 @@ public class PipelineRunner
|
|||
this.Pipeline,
|
||||
this.Incoming.Count);
|
||||
|
||||
var input = this.Incoming.SelectMany(x => x.Outputs).ToList();
|
||||
var input = this.Incoming.SelectMany(x => x.Outputs)
|
||||
.ToList();
|
||||
|
||||
this.logger.Debug(
|
||||
"{Pipeline:l}: Got {Count:l} from dependencies",
|
||||
|
@ -324,6 +330,7 @@ public class PipelineRunner
|
|||
|
||||
// Wait for the dependencies to run first.
|
||||
this.ChangeState(PipelineRunnerState.Waiting);
|
||||
|
||||
this.logger.Verbose(
|
||||
"{Pipeline:l}: Waiting for {Count:l} to complete",
|
||||
this.Pipeline,
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
<ItemGroup>
|
||||
<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="JunitXml.TestLogger" Version="3.0.114"/>
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1"/>
|
||||
|
|
|
@ -1,14 +1,6 @@
|
|||
using System;
|
||||
using System.Text;
|
||||
|
||||
using KellermanSoftware.CompareNetObjects;
|
||||
|
||||
using MfGames.TestSetup;
|
||||
|
||||
using Newtonsoft.Json;
|
||||
|
||||
using Xunit.Abstractions;
|
||||
using Xunit.Sdk;
|
||||
|
||||
namespace Nitride.IO.Tests;
|
||||
|
||||
|
|
|
@ -2,8 +2,6 @@ using Autofac;
|
|||
|
||||
using Nitride.Tests;
|
||||
|
||||
using Serilog;
|
||||
|
||||
using Zio;
|
||||
using Zio.FileSystems;
|
||||
|
||||
|
@ -19,6 +17,8 @@ public class NitrideIOTestContext : NitrideTestContext
|
|||
base.ConfigureContainer(builder);
|
||||
builder.RegisterModule<NitrideIOModule>();
|
||||
|
||||
builder.RegisterInstance(new MemoryFileSystem()).As<IFileSystem>().SingleInstance();
|
||||
builder.RegisterInstance(new MemoryFileSystem())
|
||||
.As<IFileSystem>()
|
||||
.SingleInstance();
|
||||
}
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Reference in a new issue