From d5408ab9e30149e1f98eeb997cca09c2df58b6cd Mon Sep 17 00:00:00 2001 From: Aldo Torres Date: Wed, 26 Feb 2025 15:27:52 -0500 Subject: [PATCH 1/4] fix: support basePath with dots --- .../openapi/checks/format/AbstractNamingConventionCheck.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/apiquality/sonar/openapi/checks/format/AbstractNamingConventionCheck.java b/src/main/java/apiquality/sonar/openapi/checks/format/AbstractNamingConventionCheck.java index 3227de84..0b0603a9 100644 --- a/src/main/java/apiquality/sonar/openapi/checks/format/AbstractNamingConventionCheck.java +++ b/src/main/java/apiquality/sonar/openapi/checks/format/AbstractNamingConventionCheck.java @@ -10,7 +10,7 @@ public abstract class AbstractNamingConventionCheck extends BaseCheck { private static final String CAMEL_REGEX = "[a-z]+([A-Z][a-z]+)*([A-Z])?"; private static final String SNAKE_REGEX = "^[a-z0-9_$]*$"; - private static final String KEBAB_REGEX = "^[a-z0-9-]*$"; + private static final String KEBAB_REGEX = "^[a-z0-9-.]*$"; private static final String UPPER_CAMEL_REGEX = "[A-Z]+([a-z]+)*([A-Z])?"; private static final String PASCAL_REGEX = "^[A-Z][a-z]*(?:[A-Z][a-z]*)*$"; From 09961344464e14d801ccc11caa75b445b5afc5e3 Mon Sep 17 00:00:00 2001 From: Aldo Torres Date: Fri, 16 May 2025 18:01:21 -0500 Subject: [PATCH 2/4] fix: custom regex to kebab case on rule oar011 --- .../format/AbstractNamingConventionCheck.java | 5 ++-- .../OAR011UrlNamingConventionCheck.java | 27 ++++++++++++++++++- 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/src/main/java/apiquality/sonar/openapi/checks/format/AbstractNamingConventionCheck.java b/src/main/java/apiquality/sonar/openapi/checks/format/AbstractNamingConventionCheck.java index 0b0603a9..b2099b64 100644 --- a/src/main/java/apiquality/sonar/openapi/checks/format/AbstractNamingConventionCheck.java +++ b/src/main/java/apiquality/sonar/openapi/checks/format/AbstractNamingConventionCheck.java @@ -1,16 +1,17 @@ package apiquality.sonar.openapi.checks.format; +import apiquality.sonar.openapi.checks.BaseCheck; + import java.util.HashSet; import java.util.Set; -import apiquality.sonar.openapi.checks.BaseCheck; import org.apiaddicts.apitools.dosonarapi.sslr.yaml.grammar.JsonNode; public abstract class AbstractNamingConventionCheck extends BaseCheck { private static final String CAMEL_REGEX = "[a-z]+([A-Z][a-z]+)*([A-Z])?"; private static final String SNAKE_REGEX = "^[a-z0-9_$]*$"; - private static final String KEBAB_REGEX = "^[a-z0-9-.]*$"; + private static final String KEBAB_REGEX = "^[a-z0-9-]*$"; private static final String UPPER_CAMEL_REGEX = "[A-Z]+([a-z]+)*([A-Z])?"; private static final String PASCAL_REGEX = "^[A-Z][a-z]*(?:[A-Z][a-z]*)*$"; diff --git a/src/main/java/apiquality/sonar/openapi/checks/format/OAR011UrlNamingConventionCheck.java b/src/main/java/apiquality/sonar/openapi/checks/format/OAR011UrlNamingConventionCheck.java index a67ae961..bee8464a 100644 --- a/src/main/java/apiquality/sonar/openapi/checks/format/OAR011UrlNamingConventionCheck.java +++ b/src/main/java/apiquality/sonar/openapi/checks/format/OAR011UrlNamingConventionCheck.java @@ -2,6 +2,7 @@ import com.google.common.collect.ImmutableSet; import com.sonar.sslr.api.AstNodeType; + import org.sonar.check.Rule; import org.sonar.check.RuleProperty; import org.apiaddicts.apitools.dosonarapi.api.v2.OpenApi2Grammar; @@ -12,6 +13,7 @@ import java.net.MalformedURLException; import java.net.URL; import java.util.Set; +import java.util.regex.Pattern; @Rule(key = OAR011UrlNamingConventionCheck.KEY) public class OAR011UrlNamingConventionCheck extends AbstractNamingConventionCheck { @@ -20,7 +22,8 @@ public class OAR011UrlNamingConventionCheck extends AbstractNamingConventionChec private static final String MESSAGE = "OAR011.error"; private static final String NAMING_CONVENTION = KEBAB_CASE; - + private static final Pattern KEBAB_SEGMENT = Pattern.compile("^[a-z0-9]+([-.][a-z0-9]+)*$"); + @RuleProperty( key = "naming-convention", description = "Naming convention (snake_case, kebab-case, camelCase or UpperCamelCase).", @@ -84,4 +87,26 @@ private void visitPathNode(JsonNode node) { String path = node.key().getTokenValue(); validateNamingConvention(path, node.key()); } + + @Override + protected void validateNamingConvention(String name, JsonNode nameNode) { + if (nameExceptions.contains(name)) return; + if (KEBAB_CASE.equalsIgnoreCase(namingConvention)) { + if (!isKebabCaseWithDots(name)) { + addIssue(KEY, translate(MESSAGE, KEBAB_CASE), nameNode.key()); + } + return; + } + super.validateNamingConvention(name, nameNode); + } + + private boolean isKebabCaseWithDots(String path) { + String[] segments = path.replaceAll("^/+", "").split("/"); + for (String segment : segments) { + if (segment.isEmpty()) return false; + if (segment.startsWith(".") || segment.endsWith(".")) return false; + if (!KEBAB_SEGMENT.matcher(segment).matches()) return false; + } + return true; + } } \ No newline at end of file From dafa8d324b53b2c9eeda1ee82217c08205e879e8 Mon Sep 17 00:00:00 2001 From: Aldo Torres Date: Fri, 16 May 2025 19:02:29 -0500 Subject: [PATCH 3/4] fix: resolving v2 and v3 test --- .../format/OAR011UrlNamingConventionCheck.java | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/src/main/java/apiquality/sonar/openapi/checks/format/OAR011UrlNamingConventionCheck.java b/src/main/java/apiquality/sonar/openapi/checks/format/OAR011UrlNamingConventionCheck.java index bee8464a..0ef7e494 100644 --- a/src/main/java/apiquality/sonar/openapi/checks/format/OAR011UrlNamingConventionCheck.java +++ b/src/main/java/apiquality/sonar/openapi/checks/format/OAR011UrlNamingConventionCheck.java @@ -13,7 +13,6 @@ import java.net.MalformedURLException; import java.net.URL; import java.util.Set; -import java.util.regex.Pattern; @Rule(key = OAR011UrlNamingConventionCheck.KEY) public class OAR011UrlNamingConventionCheck extends AbstractNamingConventionCheck { @@ -22,7 +21,7 @@ public class OAR011UrlNamingConventionCheck extends AbstractNamingConventionChec private static final String MESSAGE = "OAR011.error"; private static final String NAMING_CONVENTION = KEBAB_CASE; - private static final Pattern KEBAB_SEGMENT = Pattern.compile("^[a-z0-9]+([-.][a-z0-9]+)*$"); + private static final String KEBAB_SEGMENT ="^[a-z0-9-.]*$"; @RuleProperty( key = "naming-convention", @@ -101,12 +100,10 @@ protected void validateNamingConvention(String name, JsonNode nameNode) { } private boolean isKebabCaseWithDots(String path) { - String[] segments = path.replaceAll("^/+", "").split("/"); - for (String segment : segments) { - if (segment.isEmpty()) return false; - if (segment.startsWith(".") || segment.endsWith(".")) return false; - if (!KEBAB_SEGMENT.matcher(segment).matches()) return false; - } - return true; + if (path.contains("/")) { + path = path.replaceAll("\\{[^}{]*}", ""); + } + String transformed = path.replaceAll("/", "-"); + return transformed.matches(KEBAB_SEGMENT); } } \ No newline at end of file From ffe079382bc7fd45db9cf1d81c4e070a37a06b60 Mon Sep 17 00:00:00 2001 From: Adrian Palanques Date: Mon, 19 May 2025 16:32:30 +0200 Subject: [PATCH 4/4] chore: format --- .../checks/format/OAR011UrlNamingConventionCheck.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/apiaddicts/sonar/openapi/checks/format/OAR011UrlNamingConventionCheck.java b/src/main/java/apiaddicts/sonar/openapi/checks/format/OAR011UrlNamingConventionCheck.java index 6b3df404..b376ba4b 100644 --- a/src/main/java/apiaddicts/sonar/openapi/checks/format/OAR011UrlNamingConventionCheck.java +++ b/src/main/java/apiaddicts/sonar/openapi/checks/format/OAR011UrlNamingConventionCheck.java @@ -100,10 +100,10 @@ protected void validateNamingConvention(String name, JsonNode nameNode) { } private boolean isKebabCaseWithDots(String path) { - if (path.contains("/")) { - path = path.replaceAll("\\{[^}{]*}", ""); - } - String transformed = path.replaceAll("/", "-"); + if (path.contains("/")) { + path = path.replaceAll("\\{[^}{]*}", ""); + } + String transformed = path.replace("/", "-"); return transformed.matches(KEBAB_SEGMENT); } } \ No newline at end of file