Skip to content

Commit 1cded2a

Browse files
committed
Add validation to options and use CommandException instead of custom one
1 parent 6f5dbee commit 1cded2a

19 files changed

+216
-58
lines changed

GitHubIssueFormsParser/.editorconfig

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,9 @@ dotnet_diagnostic.IDE0061.severity = silent # Use expression body fo
143143
# Expression-level preferences
144144
csharp_style_implicit_object_creation_when_type_is_apparent = false:silent
145145
dotnet_diagnostic.IDE0090.severity = suggestion
146+
# Expression-level preferences
147+
dotnet_diagnostic.IDE0046.severity = silent
148+
146149

147150
##########################################
148151
# Unnecessary Code Rules

GitHubIssueFormsParser/src/GitHubIssuesParserCli/CliCommands/ParseGitHubIssueFormCommandException.cs

Lines changed: 0 additions & 11 deletions
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
namespace GitHubIssuesParserCli.CliCommands.ParseIssueForm.OptionValidators;
2+
3+
#pragma warning disable CA1812 // Avoid uninstantiated internal classes. Referenced via typeof(IssueFormBodyOptionValidator) usage
4+
internal class IssueFormBodyOptionValidator : BindingValidator<string>
5+
{
6+
public override BindingValidationError? Validate(string? value)
7+
{
8+
return string.IsNullOrWhiteSpace(value)
9+
? new BindingValidationError("Cannot be null or whitespace.")
10+
: null;
11+
}
12+
}
13+
#pragma warning restore CA1812 // Avoid uninstantiated internal classes. Referenced via typeof(TemplateFilepathOptionValidator) usage
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
namespace GitHubIssuesParserCli.CliCommands.ParseIssueForm.OptionValidators;
2+
3+
#pragma warning disable CA1812 // Avoid uninstantiated internal classes. Referenced via typeof(TemplateFilepathOptionValidator) usage
4+
internal class TemplateFilepathOptionValidator : BindingValidator<string>
5+
{
6+
public override BindingValidationError? Validate(string? value)
7+
{
8+
if (string.IsNullOrWhiteSpace(value))
9+
{
10+
return new BindingValidationError("Cannot be null or whitespace.");
11+
}
12+
13+
return !File.Exists(value)
14+
? new BindingValidationError("File does not exist.")
15+
: null;
16+
}
17+
}
18+
#pragma warning restore CA1812 // Avoid uninstantiated internal classes. Referenced via typeof(TemplateFilepathOptionValidator) usage

GitHubIssueFormsParser/src/GitHubIssuesParserCli/CliCommands/ParseIssueFormCommand.cs renamed to GitHubIssueFormsParser/src/GitHubIssuesParserCli/CliCommands/ParseIssueForm/ParseIssueFormCommand.cs

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,22 @@
1-
namespace GitHubIssuesParserCli.CliCommands;
1+
namespace GitHubIssuesParserCli.CliCommands.ParseIssueForm;
22

33
[Command("parse-issue-form")]
44
public class ParseIssueFormCommand : ICommand
55
{
6-
[CommandOption("issue-body", 'i', IsRequired = true, Description = "The body of the GitHub issue form.")]
6+
[CommandOption(
7+
"issue-body",
8+
'i',
9+
IsRequired = true,
10+
Validators = new Type[] { typeof(IssueFormBodyOptionValidator) },
11+
Description = "The body of the GitHub issue form.")]
712
public string IssueFormBody { get; init; } = default!;
813

9-
[CommandOption("template-filepath", 't', IsRequired = true, Description = "The filepath for the GitHub issue form YAML template.")]
14+
[CommandOption(
15+
"template-filepath",
16+
't',
17+
IsRequired = true,
18+
Validators = new Type[] { typeof(TemplateFilepathOptionValidator) },
19+
Description = "The filepath for the GitHub issue form YAML template.")]
1020
public string TemplateFilepath { get; init; } = default!;
1121

1222
public async ValueTask ExecuteAsync(IConsole console)
@@ -27,7 +37,10 @@ public async ValueTask ExecuteAsync(IConsole console)
2737
}
2838
catch (Exception e)
2939
{
30-
throw new ParseGitHubIssueFormCommandException(e);
40+
var message = @$"An error occurred trying to execute the command to parse a GitHub issue form.
41+
Error:
42+
- {e.Message}";
43+
throw new CommandException(message, innerException: e);
3144
}
3245
}
3346
}

GitHubIssueFormsParser/src/GitHubIssuesParserCli/GitHubIssuesParserCli.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<Project Sdk="Microsoft.NET.Sdk">
1+
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
44
<OutputType>Exe</OutputType>

GitHubIssueFormsParser/src/GitHubIssuesParserCli/GlobalUsings.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,11 @@
44
global using System.Text.Json.Serialization;
55
global using CliFx;
66
global using CliFx.Attributes;
7+
global using CliFx.Exceptions;
8+
global using CliFx.Extensibility;
79
global using CliFx.Infrastructure;
810
global using GitHubIssuesParserCli.ArgumentValidations;
11+
global using GitHubIssuesParserCli.CliCommands.ParseIssueForm.OptionValidators;
912
global using GitHubIssuesParserCli.IssueFormBody;
1013
global using GitHubIssuesParserCli.IssueFormBody.IssueFormItems;
1114
global using GitHubIssuesParserCli.IssueFormBody.IssueFormItems.Checkboxes;
@@ -15,4 +18,5 @@
1518
global using GitHubIssuesParserCli.IssueFormTemplates;
1619
global using GitHubIssuesParserCli.IssueFormTemplates.Parsing;
1720
global using SlugGenerator;
21+
global using YamlDotNet.Core;
1822
global using YamlDotNet.Serialization;

GitHubIssueFormsParser/src/GitHubIssuesParserCli/IssueFormTemplates/Parsing/IssueFormYamlTemplateParser.cs

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,7 @@ internal static class IssueFormYamlTemplateParser
55
public static IssueFormYamlTemplate Parse(IssueFormYamlTemplateText yamlTemplate)
66
{
77
yamlTemplate.NotNull();
8-
var deserializer = new DeserializerBuilder()
9-
.IgnoreUnmatchedProperties()
10-
.Build();
11-
var templateDto = deserializer.Deserialize<IssueFormYamlTemplateDto>(yamlTemplate);
8+
var templateDto = DeserializeYaml(yamlTemplate);
129
if (templateDto?.Body is null)
1310
{
1411
throw IssueFormYamlTemplateParserException.InvalidYmlTemplate();
@@ -37,4 +34,19 @@ public static IssueFormYamlTemplate Parse(IssueFormYamlTemplateText yamlTemplate
3734
.ToList();
3835
return new IssueFormYamlTemplate(items);
3936
}
37+
38+
public static IssueFormYamlTemplateDto? DeserializeYaml(this string yamlTemplate)
39+
{
40+
try
41+
{
42+
var deserializer = new DeserializerBuilder()
43+
.IgnoreUnmatchedProperties()
44+
.Build();
45+
return deserializer.Deserialize<IssueFormYamlTemplateDto>(yamlTemplate);
46+
}
47+
catch (YamlException)
48+
{
49+
return null;
50+
}
51+
}
4052
}
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
{
22
"profiles": {
33
"GitHubIssuesParserCli": {
4-
"commandName": "Project"
4+
"commandName": "Project",
5+
"commandLineArgs": "parse-issue-form --issue-body some --template-filepath D:/Dev/edumserrano/github-issue-forms-parser/GitHubIssueFormsParser/src/GitHubIssuesParserCli/bin/Debug/net6.0/test.txt"
56
}
67
}
78
}

GitHubIssueFormsParser/tests/GitHubIssuesParserCli.Tests/CliCommands/ParseIssueFormCommandTests.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,12 @@ public async Task ParseIssueFormCommandTest1()
3838

3939
/// <summary>
4040
/// Tests that the <see cref="ParseIssueFormCommand"/> produces the expected JSON output
41-
/// when the line endings are only newLine.
41+
/// regardless of the line endings on the issue form body.
4242
/// </summary>
4343
[Theory]
4444
[InlineData(CR)]
4545
[InlineData(LF)]
46+
[InlineData(CR + LF)]
4647
public async Task ParseIssueFormCommandTest2(string newLine)
4748
{
4849
var issueFormBody = $"### What NuGet package do you want to release?{newLine}{newLine}dotnet-sdk-extensions{newLine}{newLine}### What is the new version for the NuGet package?{newLine}{newLine}1.0.13-alpha{newLine}{newLine}### Auto-generate release notes?{newLine}{newLine}Yes{newLine}{newLine}### Push to NuGet.org?{newLine}{newLine}_No response_{newLine}{newLine}### Custom release notes?{newLine}{newLine}## Custom release notes {newLine}{newLine}Test 123{newLine}{newLine}Another line:{newLine}- point 1{newLine}- point 2{newLine}- point 3{newLine}{newLine}### Which operating systems have you used?{newLine}{newLine}- [X] macOS{newLine}- [X] Windows{newLine}- [ ] Linux{newLine}- [ ] I don't know{newLine}";

0 commit comments

Comments
 (0)