Skip to content
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

Escape all special suffixes in go file names #4540

Merged
merged 3 commits into from
Apr 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added

- Suppress CS1591 when generating CSharp code and documentation is not available
- Added file name suffix escaping in Go to avoid generating files with reserved suffixes. [#4407](https://github.com/microsoft/kiota/issues/4407)

### Changed

Expand Down
9 changes: 9 additions & 0 deletions src/Kiota.Builder/Extensions/StringExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,15 @@ public static string ShortenFileName(this string name, int length = 251) =>
(!string.IsNullOrEmpty(name) && name.Length > length) ? HashString(name).ToLowerInvariant() : name;
#pragma warning restore CA1308

public static string EscapeSuffix(this string? name, HashSet<string> specialFileNameSuffixes, char separator = '_')
{
ArgumentNullException.ThrowIfNull(specialFileNameSuffixes);
if (string.IsNullOrEmpty(name)) return string.Empty;

var last = name.Split(separator)[^1];
return specialFileNameSuffixes.Contains(last) ? $"{name}_escaped" : name;
}

public static string ToSnakeCase(this string? name, char separator = '_')
{
if (string.IsNullOrEmpty(name)) return string.Empty;
Expand Down
67 changes: 65 additions & 2 deletions src/Kiota.Builder/PathSegmenters/GoPathSegmenter.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Linq;

using Kiota.Builder.CodeDOM;
Expand All @@ -7,6 +8,67 @@
namespace Kiota.Builder.PathSegmenters;
public class GoPathSegmenter : CommonPathSegmenter
{
private static readonly HashSet<string> specialFileNameSuffixes = new(StringComparer.OrdinalIgnoreCase) {
"test" ,

"aix" ,
"android" ,
"darwin" ,
"dragonfly" ,
"freebsd" ,
"hurd" ,
"illumos" ,
"ios" ,
"js" ,
"linux" ,
"nacl" ,
"netbsd" ,
"openbsd" ,
"plan9" ,
"solaris" ,
"wasip1" ,
"windows" ,
"zos" ,

"aix" ,
"android" ,
"darwin" ,
"dragonfly" ,
"freebsd" ,
"hurd" ,
"illumos" ,
"ios" ,
"linux" ,
"netbsd" ,
"openbsd" ,
"solaris" ,

"386" ,
"amd64" ,
"amd64p32" ,
"arm" ,
"armbe" ,
"arm64" ,
"arm64be" ,
"loong64" ,
"mips" ,
"mipsle" ,
"mips64" ,
"mips64le" ,
"mips64p32" ,
"mips64p32le" ,
"ppc" ,
"ppc64" ,
"ppc64le" ,
"riscv" ,
"riscv64" ,
"s390" ,
"s390x" ,
"sparc" ,
"sparc64" ,
"wasm" ,
};

public GoPathSegmenter(string rootPath, string clientNamespaceName) : base(rootPath, clientNamespaceName) { }
public override string FileSuffix => ".go";
public override IEnumerable<string> GetAdditionalSegment(CodeElement currentElement, string fileName)
Expand All @@ -17,12 +79,13 @@ public override IEnumerable<string> GetAdditionalSegment(CodeElement currentElem
_ => Enumerable.Empty<string>(),
};
}

public override string NormalizeFileName(CodeElement currentElement)
{
return currentElement switch
{
CodeNamespace => "go",
_ => GetLastFileNameSegment(currentElement).ToSnakeCase().ShortenFileName(),
_ => GetLastFileNameSegment(currentElement).ToSnakeCase().EscapeSuffix(specialFileNameSuffixes).ShortenFileName(),
};
}
public override string NormalizeNamespaceSegment(string segmentName) => segmentName?.ToLowerInvariant() ?? string.Empty;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
using Kiota.Builder.CodeDOM;
using Kiota.Builder.PathSegmenters;
using Xunit;

namespace Kiota.Builder.Tests.PathSegmenters;

public class GoPathSegmenterTests
{
private readonly GoPathSegmenter segmenter;
public GoPathSegmenterTests()
{
segmenter = new GoPathSegmenter("D:\\source\\repos\\kiota-sample", "client");
}

[Fact]
public void GoPathSegmenterGeneratesCorrectFileName()
{
var fileName = segmenter.NormalizeFileName(new CodeClass
{
Name = "testClass"
});
Assert.Equal("test_class", fileName); // file name should be snake case
}

[Fact]
public void GoPathSegmenterGeneratesEscapedSpecialClassName()
{
var fileName = segmenter.NormalizeFileName(new CodeClass
{
Name = "adminWindows"
});
Assert.Equal("admin_windows_escaped", fileName); // file name should be snake case and escaped
}

[Fact]
public void GoPathSegmenterGeneratesNamespaceFolderName()
{
var namespaceName = "Microsoft.Graph";
var normalizedNamespace = segmenter.NormalizeNamespaceSegment(namespaceName);
Assert.Equal("microsoft.graph", normalizedNamespace);// the file name should be lower case
}
}
Loading