-
Notifications
You must be signed in to change notification settings - Fork 373
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add snake_case ValueForm support #8563
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -877,7 +877,8 @@ | |
"firstUpperCase", | ||
"firstUpperCaseInvariant", | ||
"titleCase", | ||
"kebabCase" | ||
"kebabCase", | ||
"snakeCase" | ||
] | ||
} | ||
} | ||
|
@@ -1051,6 +1052,14 @@ | |
"enum": ["kebabCase"] | ||
} | ||
} | ||
}, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for adding this! Post-PR can you also update the canonical schema at schemastore? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Absolutely. Is there some documentation on this process that I can read up on? I have not contributed here before so want to make sure I am doing it correctly. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There's no heavy process here - it's just that many tools (including VSCode) integrate easily with Schemastore so we also have the schema mirrored there at https://github.com/SchemaStore/schemastore/blob/master/src/schemas/json/template.json - you can submit changes to it same as you did here and tag me on the PR and I'll approve it. The one here in the repo is the 'most correct' one, but the one in Schemastore is the most tooling-friendly one. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @baronfel I opened SchemaStore/schemastore#4230 |
||
{ | ||
"description": "Converts the value to snake case using the casing rules of the invariant culture.", | ||
"properties": { | ||
"identifier": { | ||
"enum": ["snakeCase"] | ||
} | ||
} | ||
} | ||
] | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
|
||
using System.Text.RegularExpressions; | ||
|
||
namespace Microsoft.TemplateEngine.Orchestrator.RunnableProjects.ValueForms | ||
{ | ||
internal class SnakeCaseValueFormFactory : ActionableValueFormFactory | ||
{ | ||
internal const string FormIdentifier = "snakeCase"; | ||
|
||
internal SnakeCaseValueFormFactory() : base(FormIdentifier) { } | ||
|
||
protected override string Process(string value) | ||
{ | ||
if (string.IsNullOrWhiteSpace(value)) | ||
{ | ||
return string.Empty; | ||
} | ||
|
||
Regex pattern = new(@"(?:\p{Lu}\p{M}*)?(?:\p{Ll}\p{M}*)+|(?:\p{Lu}\p{M}*)+(?!\p{Ll})|\p{N}+|[^\p{C}\p{P}\p{Z}]+|[\u2700-\u27BF]"); | ||
return string.Join("_", pattern.Matches(value).Cast<Match>().Select(m => m.Value)).ToLowerInvariant(); | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
|
||
using Microsoft.TemplateEngine.Orchestrator.RunnableProjects.ValueForms; | ||
|
||
namespace Microsoft.TemplateEngine.Orchestrator.RunnableProjects.UnitTests.ValueFormTests | ||
{ | ||
public class SnakeCaseValueFormTests | ||
{ | ||
[Theory] | ||
[InlineData("I", "i")] | ||
[InlineData("IO", "io")] | ||
[InlineData("FileIO", "file_io")] | ||
[InlineData("SignalR", "signal_r")] | ||
[InlineData("IOStream", "io_stream")] | ||
[InlineData("COMObject", "com_object")] | ||
[InlineData("WebAPI", "web_api")] | ||
[InlineData("XProjectX", "x_project_x")] | ||
[InlineData("NextXXXProject", "next_xxx_project")] | ||
[InlineData("NoNewProject", "no_new_project")] | ||
[InlineData("NONewProject", "no_new_project")] | ||
[InlineData("NewProjectName", "new_project_name")] | ||
[InlineData("ABBREVIATIONAndSomeName", "abbreviation_and_some_name")] | ||
[InlineData("NoNoNoNoNoNoNoName", "no_no_no_no_no_no_no_name")] | ||
[InlineData("AnotherNewNewNewNewNewProjectName", "another_new_new_new_new_new_project_name")] | ||
[InlineData("Param1TestValue", "param_1_test_value")] | ||
[InlineData("Windows10", "windows_10")] | ||
[InlineData("WindowsServer2016R2", "windows_server_2016_r_2")] | ||
[InlineData("", "")] | ||
[InlineData(";MyWord;", "my_word")] | ||
[InlineData("My Word", "my_word")] | ||
[InlineData("My Word", "my_word")] | ||
[InlineData(";;;;;", "")] | ||
[InlineData(" ", "")] | ||
[InlineData("Simple TEXT_here", "simple_text_here")] | ||
[InlineData("НоваяПеременная", "новая_переменная")] | ||
public void SnakeCaseWorksAsExpected(string input, string expected) | ||
{ | ||
IValueForm? model = new SnakeCaseValueFormFactory().Create("test"); | ||
string actual = model.Process(input, new Dictionary<string, IValueForm>()); | ||
Assert.Equal(expected, actual); | ||
} | ||
|
||
[Fact] | ||
public void CanHandleNullValue() | ||
{ | ||
IValueForm model = new SnakeCaseValueFormFactory().Create("test"); | ||
Assert.Throws<ArgumentNullException>(() => model.Process(null!, new Dictionary<string, IValueForm>())); | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This PR is targeting main, which right now is for .NET 10 development, so this would need to be updated. Once we merge this we can backport it to 9.0.200 pretty easily with a /backport command.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am open to backporting it to whatever versions are available. Technically it should be able to be backported as far back as
.NET 5.0.300
since I patterned all of my code after thekebabCase
just above it.I am not sure how that is done though, and will require some assistance. This is my first contribution to this repo.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At this point in time the only real options are:
We don't generally add new features to an already-published release except for very special circumstances.
Once this PR is merged we'll take care of the back-porting, no worries :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
9.0.200 would be fantastic but I can understand not doing it as well. I do have selfish motives for wanting to more easily
snake_case
my.proto
file names in my template, but whatever timeline the dotnet team determines is fine by me. I'm just happy to contribute 😄