Skip to content

Commit 0461c6e

Browse files
Merge pull request #507 from bilal-fazlani/modernize
modernize code and fix or ignore all warnings
2 parents 059ad3c + 0a5cb05 commit 0461c6e

File tree

481 files changed

+25672
-26951
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

481 files changed

+25672
-26951
lines changed

CommandDotNet.DataAnnotations/DataAnnotationsMiddleware.cs

Lines changed: 137 additions & 138 deletions
Original file line numberDiff line numberDiff line change
@@ -6,187 +6,186 @@
66
using CommandDotNet.Execution;
77
using CommandDotNet.Extensions;
88

9-
namespace CommandDotNet.DataAnnotations
9+
namespace CommandDotNet.DataAnnotations;
10+
11+
public static class DataAnnotationsMiddleware
1012
{
11-
public static class DataAnnotationsMiddleware
13+
public static AppRunner UseDataAnnotationValidations(this AppRunner appRunner, bool showHelpOnError = false,
14+
Resources? resourcesOverride = null)
1215
{
13-
public static AppRunner UseDataAnnotationValidations(this AppRunner appRunner, bool showHelpOnError = false,
14-
Resources? resourcesOverride = null)
16+
return appRunner.Configure(c =>
1517
{
16-
return appRunner.Configure(c =>
18+
var localizationAppSettings = appRunner.AppSettings.Localization;
19+
if (resourcesOverride != null)
1720
{
18-
var localizationAppSettings = appRunner.AppSettings.Localization;
19-
if (resourcesOverride != null)
20-
{
21-
Resources.A = resourcesOverride;
22-
}
23-
else if (localizationAppSettings.Localize != null)
24-
{
25-
Resources.A = new ResourcesProxy(
26-
localizationAppSettings.Localize,
27-
localizationAppSettings.UseMemberNamesAsKeys);
28-
}
29-
c.UseMiddleware(DataAnnotationsValidation, MiddlewareSteps.DataAnnotations);
30-
c.Services.Add(new Config(showHelpOnError));
31-
});
32-
}
33-
34-
private class Config
35-
{
36-
public bool ShowHelpOnError { get; }
37-
38-
public Config(bool showHelpOnError)
21+
Resources.A = resourcesOverride;
22+
}
23+
else if (localizationAppSettings.Localize != null)
3924
{
40-
ShowHelpOnError = showHelpOnError;
25+
Resources.A = new ResourcesProxy(
26+
localizationAppSettings.Localize,
27+
localizationAppSettings.UseMemberNamesAsKeys);
4128
}
42-
}
29+
c.UseMiddleware(DataAnnotationsValidation, MiddlewareSteps.DataAnnotations);
30+
c.Services.Add(new Config(showHelpOnError));
31+
});
32+
}
4333

44-
private static Task<int> DataAnnotationsValidation(CommandContext ctx, ExecutionDelegate next)
34+
private class Config
35+
{
36+
public bool ShowHelpOnError { get; }
37+
38+
public Config(bool showHelpOnError)
4539
{
46-
var errors = ctx.InvocationPipeline.All
47-
.SelectMany(ValidateStep)
48-
.ToList();
40+
ShowHelpOnError = showHelpOnError;
41+
}
42+
}
4943

50-
if (errors.Any())
51-
{
52-
var console = ctx.Console;
53-
errors.ForEach(error =>
54-
{
55-
console.Error.WriteLine(error);
56-
});
44+
private static Task<int> DataAnnotationsValidation(CommandContext ctx, ExecutionDelegate next)
45+
{
46+
var errors = ctx.InvocationPipeline.All
47+
.SelectMany(ValidateStep)
48+
.ToList();
5749

58-
ctx.ShowHelpOnExit = ctx.AppConfig.Services.GetOrThrow<Config>().ShowHelpOnError;
50+
if (errors.Any())
51+
{
52+
var console = ctx.Console;
53+
errors.ForEach(error =>
54+
{
55+
console.Error.WriteLine(error);
56+
});
5957

60-
if (ctx.ShowHelpOnExit)
61-
{
62-
console.Error.WriteLine();
63-
}
58+
ctx.ShowHelpOnExit = ctx.AppConfig.Services.GetOrThrow<Config>().ShowHelpOnError;
6459

65-
return ExitCodes.ValidationErrorAsync;
60+
if (ctx.ShowHelpOnExit)
61+
{
62+
console.Error.WriteLine();
6663
}
67-
68-
return next(ctx);
64+
65+
return ExitCodes.ValidationErrorAsync;
6966
}
67+
68+
return next(ctx);
69+
}
7070

71-
private static IEnumerable<string> ValidateStep(InvocationStep step)
72-
{
73-
var phrasesToReplace = Resources.A
74-
.Error_DataAnnotation_phrases_to_replace_with_argument_name()
75-
.Split('|');
71+
private static IEnumerable<string> ValidateStep(InvocationStep step)
72+
{
73+
var phrasesToReplace = Resources.A
74+
.Error_DataAnnotation_phrases_to_replace_with_argument_name()
75+
.Split('|');
7676

77-
var propertyArgumentErrors = step.Invocation.Arguments
78-
.Select(argument => GetParameterArgumentErrors(argument, phrasesToReplace));
77+
var propertyArgumentErrors = step.Invocation.Arguments
78+
.Select(argument => GetParameterArgumentErrors(argument, phrasesToReplace));
7979

80-
var argumentModelErrors = step.Invocation.FlattenedArgumentModels
81-
.Select(m => GetArgumentModelErrors(m, step.Invocation.Arguments, phrasesToReplace));
80+
var argumentModelErrors = step.Invocation.FlattenedArgumentModels
81+
.Select(m => GetArgumentModelErrors(m, step.Invocation.Arguments, phrasesToReplace));
8282

83-
return propertyArgumentErrors
84-
.Concat(argumentModelErrors)
85-
.SelectMany(e => e);
86-
}
83+
return propertyArgumentErrors
84+
.Concat(argumentModelErrors)
85+
.SelectMany(e => e);
86+
}
8787

88-
private static IEnumerable<string> GetArgumentModelErrors(IArgumentModel model,
89-
IReadOnlyCollection<IArgument> arguments, string[] phrasesToReplace)
88+
private static IEnumerable<string> GetArgumentModelErrors(IArgumentModel model,
89+
IReadOnlyCollection<IArgument> arguments, string[] phrasesToReplace)
90+
{
91+
var validationContext = new ValidationContext(model);
92+
var results = new List<ValidationResult>();
93+
if (Validator.TryValidateObject(model, validationContext, results, validateAllProperties: true))
9094
{
91-
var validationContext = new ValidationContext(model);
92-
var results = new List<ValidationResult>();
93-
if (Validator.TryValidateObject(model, validationContext, results, validateAllProperties: true))
94-
{
95-
return Enumerable.Empty<string>();
96-
}
95+
return [];
96+
}
9797

98-
IArgument? GetArgument(string propertyName)
98+
return results
99+
.Select(SanitizedErrorMessage)
100+
.Where(m => m != null)!;
101+
102+
IArgument? GetArgument(string propertyName)
103+
{
104+
return arguments.FirstOrDefault(a =>
99105
{
100-
return arguments.FirstOrDefault(a =>
101-
{
102-
var info = a.Services.GetOrDefault<PropertyInfo>();
103-
return info != null
104-
&& (info.DeclaringType?.IsInstanceOfType(model) ?? false)
105-
&& propertyName.Equals(info.Name);
106-
});
107-
}
106+
var info = a.Services.GetOrDefault<PropertyInfo>();
107+
return info != null
108+
&& (info.DeclaringType?.IsInstanceOfType(model) ?? false)
109+
&& propertyName.Equals(info.Name);
110+
});
111+
}
108112

109-
string? SanitizedErrorMessage(ValidationResult validationResult)
113+
string? SanitizedErrorMessage(ValidationResult validationResult)
114+
{
115+
var errorMessage = validationResult.ErrorMessage;
116+
if (errorMessage is not null)
110117
{
111-
var errorMessage = validationResult.ErrorMessage;
112-
if (errorMessage is not null)
118+
foreach (var memberName in validationResult.MemberNames)
113119
{
114-
foreach (var memberName in validationResult.MemberNames)
120+
var argument = GetArgument(memberName);
121+
if (argument is not null)
115122
{
116-
var argument = GetArgument(memberName);
117-
if (argument is { })
118-
{
119-
errorMessage = errorMessage.RemoveFieldTerminology(memberName, argument, phrasesToReplace);
120-
}
123+
errorMessage = errorMessage.RemoveFieldTerminology(memberName, argument, phrasesToReplace);
121124
}
122125
}
123-
return errorMessage;
124126
}
125-
126-
return results
127-
.Select(SanitizedErrorMessage)
128-
.Where(m => m != null)!;
127+
return errorMessage;
129128
}
129+
}
130130

131-
private static IEnumerable<string> GetParameterArgumentErrors(IArgument argument,
132-
string[] phrasesToReplace)
131+
private static IEnumerable<string> GetParameterArgumentErrors(IArgument argument,
132+
string[] phrasesToReplace)
133+
{
134+
var parameterInfo = argument.Services.GetOrDefault<ParameterInfo>();
135+
if (parameterInfo is null)
133136
{
134-
var parameterInfo = argument.Services.GetOrDefault<ParameterInfo>();
135-
if (parameterInfo is null)
136-
{
137-
return Enumerable.Empty<string>();
138-
}
137+
return [];
138+
}
139139

140-
var validationAttributes = argument.CustomAttributes
141-
.GetCustomAttributes(true)
142-
.OfType<ValidationAttribute>()
143-
.OrderBy(a => a is RequiredAttribute ? 0 : 1)
144-
.ToList();
140+
var validationAttributes = argument.CustomAttributes
141+
.GetCustomAttributes(true)
142+
.OfType<ValidationAttribute>()
143+
.OrderBy(a => a is RequiredAttribute ? 0 : 1)
144+
.ToList();
145145

146-
List<string>? errors = null;
146+
List<string>? errors = null;
147147

148-
foreach (var validationAttribute in validationAttributes)
148+
foreach (var validationAttribute in validationAttributes)
149+
{
150+
if (!validationAttribute.IsValid(argument.Value))
149151
{
150-
if (!validationAttribute.IsValid(argument.Value))
152+
// the user expects the name to map to an argument, not a field.
153+
// update the terminology. This is naive and will need to change
154+
// when we handle localization
155+
var message = validationAttribute
156+
.FormatErrorMessage(argument.Name)
157+
.RemoveFieldTerminology(parameterInfo.Name, argument, phrasesToReplace);
158+
(errors ??= []).Add(message);
159+
160+
if (validationAttribute is RequiredAttribute)
151161
{
152-
// the user expects the name to map to an argument, not a field.
153-
// update the terminology. This is naive and will need to change
154-
// when we handle localization
155-
var message = validationAttribute
156-
.FormatErrorMessage(argument.Name)
157-
.RemoveFieldTerminology(parameterInfo.Name, argument, phrasesToReplace);
158-
(errors ??= new List<string>()).Add(message);
159-
160-
if (validationAttribute is RequiredAttribute)
161-
{
162-
// If the value is not provided and it is required, no other validation needs to be performed.
163-
// this is why the RequiredAttribute is first.
164-
break;
165-
}
162+
// If the value is not provided and it is required, no other validation needs to be performed.
163+
// this is why the RequiredAttribute is first.
164+
break;
166165
}
167166
}
168-
169-
return errors ?? Enumerable.Empty<string>();
170167
}
168+
169+
return errors ?? Enumerable.Empty<string>();
170+
}
171171

172-
/// <summary>the user expects the name to map to an argument, not a field.</summary>
173-
/// <remarks>
174-
/// This is naive and will need to change when we handle localization
175-
/// </remarks>
176-
private static string RemoveFieldTerminology(this string error, string? memberName, IArgument argument, IEnumerable<string> phrasesToReplace)
172+
/// <summary>the user expects the name to map to an argument, not a field.</summary>
173+
/// <remarks>
174+
/// This is naive and will need to change when we handle localization
175+
/// </remarks>
176+
private static string RemoveFieldTerminology(this string error, string? memberName, IArgument argument, IEnumerable<string> phrasesToReplace)
177+
{
178+
memberName = argument.GetCustomAttribute<DisplayAttribute>()?.Name ?? memberName;
179+
if (memberName is null)
177180
{
178-
memberName = argument.GetCustomAttribute<DisplayAttribute>()?.Name ?? memberName;
179-
if (memberName is null)
180-
{
181-
return error;
182-
}
183-
184-
var argName = $"'{argument.Name}'";
185-
foreach (var phrase in phrasesToReplace.Select(p => string.Format(p, memberName)))
186-
{
187-
error = error.Replace(phrase, argName);
188-
}
189181
return error;
190182
}
183+
184+
var argName = $"'{argument.Name}'";
185+
foreach (var phrase in phrasesToReplace.Select(p => string.Format(p, memberName)))
186+
{
187+
error = error.Replace(phrase, argName);
188+
}
189+
return error;
191190
}
192191
}
Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
using CommandDotNet.Execution;
22

3-
namespace CommandDotNet.DataAnnotations
3+
namespace CommandDotNet.DataAnnotations;
4+
5+
public static class MiddlewareSteps
46
{
5-
public static class MiddlewareSteps
6-
{
7-
public static MiddlewareStep DataAnnotations { get; set; } = Execution.MiddlewareSteps.ValidateArity - 1100;
8-
}
7+
public static MiddlewareStep DataAnnotations { get; set; } = Execution.MiddlewareSteps.ValidateArity - 1100;
98
}
Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
1-
namespace CommandDotNet.DataAnnotations
1+
namespace CommandDotNet.DataAnnotations;
2+
3+
public class Resources
24
{
3-
public class Resources
4-
{
5-
public static Resources A = new();
5+
public static Resources A = new();
66

7-
public virtual string Error_DataAnnotation_phrases_to_replace_with_argument_name() =>
8-
"The {0} field|The field {0}|The {0} property|The property {0}";
9-
}
7+
public virtual string Error_DataAnnotation_phrases_to_replace_with_argument_name() =>
8+
"The {0} field|The field {0}|The {0} property|The property {0}";
109
}

CommandDotNet.DataAnnotations/ResourcesProxy.cs

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,21 @@
11
// this file generated by ResourceGenerators.RegenerateProxyClasses
22

33
using System;
4+
using JetBrains.Annotations;
45

56
namespace CommandDotNet.DataAnnotations
67
{
78
// this class generated by ResourcesDef.GenerateProxyClass
8-
public class ResourcesProxy : Resources
9+
[PublicAPI]
10+
public class ResourcesProxy(Func<string, string?> localize, bool memberNameAsKey = false) : Resources
911
{
10-
private readonly Func<string, string?> _localize;
11-
private readonly bool _memberNameAsKey;
12-
13-
public ResourcesProxy(Func<string, string?> localize, bool memberNameAsKey = false)
14-
{
15-
_localize = localize ?? throw new ArgumentNullException(nameof(localize));
16-
_memberNameAsKey = memberNameAsKey;
17-
}
12+
private readonly Func<string, string?> _localize = localize ?? throw new ArgumentNullException(nameof(localize));
1813

1914
private static string? Format(string? value, params object?[] args) =>
2015
value is null ? null : string.Format(value, args);
2116

2217
public override string Error_DataAnnotation_phrases_to_replace_with_argument_name() =>
23-
_localize(_memberNameAsKey
18+
_localize(memberNameAsKey
2419
? "Error_DataAnnotation_phrases_to_replace_with_argument_name"
2520
: base.Error_DataAnnotation_phrases_to_replace_with_argument_name())
2621
?? base.Error_DataAnnotation_phrases_to_replace_with_argument_name();

0 commit comments

Comments
 (0)