From 84632ee6d9770ce6b9fc2cc3515e2a7b45cb2a82 Mon Sep 17 00:00:00 2001 From: Richard Chen Date: Tue, 10 May 2022 11:57:03 -0700 Subject: [PATCH 1/5] Improved Camel Case linter to automatically detect if upper or lower camel should be enforced for consistency --- .../smithy/linters/CamelCaseValidator.java | 40 ++++++- ...-case-validator-defaults-test-lower.errors | 6 + ...el-case-validator-defaults-test-lower.json | 105 ++++++++++++++++++ ...-case-validator-defaults-test-upper.errors | 6 + ...el-case-validator-defaults-test-upper.json | 103 +++++++++++++++++ .../camel-case-validator-defaults-test.errors | 40 ++++--- .../camel-case-validator-defaults-test.json | 20 +++- 7 files changed, 300 insertions(+), 20 deletions(-) create mode 100644 smithy-linters/src/test/resources/software/amazon/smithy/linters/errorfiles/camel-case-validator-defaults-test-lower.errors create mode 100644 smithy-linters/src/test/resources/software/amazon/smithy/linters/errorfiles/camel-case-validator-defaults-test-lower.json create mode 100644 smithy-linters/src/test/resources/software/amazon/smithy/linters/errorfiles/camel-case-validator-defaults-test-upper.errors create mode 100644 smithy-linters/src/test/resources/software/amazon/smithy/linters/errorfiles/camel-case-validator-defaults-test-upper.json diff --git a/smithy-linters/src/main/java/software/amazon/smithy/linters/CamelCaseValidator.java b/smithy-linters/src/main/java/software/amazon/smithy/linters/CamelCaseValidator.java index cabe6d8d36d..763b7e99729 100644 --- a/smithy-linters/src/main/java/software/amazon/smithy/linters/CamelCaseValidator.java +++ b/smithy-linters/src/main/java/software/amazon/smithy/linters/CamelCaseValidator.java @@ -21,6 +21,7 @@ import java.util.List; import java.util.regex.Pattern; import software.amazon.smithy.model.Model; +import software.amazon.smithy.model.loader.Prelude; import software.amazon.smithy.model.node.NodeMapper; import software.amazon.smithy.model.shapes.MemberShape; import software.amazon.smithy.model.shapes.Shape; @@ -42,7 +43,7 @@ public final class CamelCaseValidator extends AbstractValidator { * CamelCase configuration settings. */ public static final class Config { - private MemberNameHandling memberNames = MemberNameHandling.LOWER; + private MemberNameHandling memberNames = MemberNameHandling.AUTO; /** * Gets how member names are to be cased. @@ -87,6 +88,21 @@ Pattern getRegex() { public String toString() { return "lower"; } + }, + + /** + * Will ensure it is either all lower camel or all upper camel, but not a mixture. + */ + AUTO { + Pattern getRegex() { + // No Pattern associated with auto setting + return null; + } + + @Override + public String toString() { + return "consistent"; + } }; abstract Pattern getRegex(); @@ -135,11 +151,27 @@ public List validate(Model model) { shape.getType(), shape.getId().getName()))) .forEach(events::add); - Pattern isValidMemberName = config.getMemberNames().getRegex(); + Pattern memberNamePattern; + if (MemberNameHandling.AUTO.equals(config.getMemberNames())) { + long upperMemberNameCount = model.shapes(MemberShape.class) + .filter(shape -> !shape.getContainer().getNamespace().equals(Prelude.NAMESPACE)) + .filter(shape -> MemberNameHandling.UPPER.getRegex().matcher(shape.getMemberName()).find()) + .count(); + long lowerMemberNameCount = model.shapes(MemberShape.class) + .filter(shape -> !shape.getContainer().getNamespace().equals(Prelude.NAMESPACE)) + .filter(shape -> MemberNameHandling.LOWER.getRegex().matcher(shape.getMemberName()).find()) + .count(); + + memberNamePattern = upperMemberNameCount > lowerMemberNameCount + ? MemberNameHandling.UPPER.getRegex() : MemberNameHandling.LOWER.getRegex(); + } else { + memberNamePattern = config.getMemberNames().getRegex(); + } + model.shapes(MemberShape.class) - .filter(shape -> !isValidMemberName.matcher(shape.getMemberName()).find()) + .filter(shape -> !memberNamePattern.matcher(shape.getMemberName()).find()) .map(shape -> danger(shape, format( - "Member shape member name, `%s`, is not %s camel case", + "Member shape member name, `%s`, is not %s camel case. (Member names must also all use consistent camel case)", shape.getMemberName(), config.getMemberNames()))) .forEach(events::add); diff --git a/smithy-linters/src/test/resources/software/amazon/smithy/linters/errorfiles/camel-case-validator-defaults-test-lower.errors b/smithy-linters/src/test/resources/software/amazon/smithy/linters/errorfiles/camel-case-validator-defaults-test-lower.errors new file mode 100644 index 00000000000..638ac39f719 --- /dev/null +++ b/smithy-linters/src/test/resources/software/amazon/smithy/linters/errorfiles/camel-case-validator-defaults-test-lower.errors @@ -0,0 +1,6 @@ +[DANGER] ns.foo#InvalidTrait: string trait definition, `InvalidTrait`, is not lower camel case | DefaultCamelCase +[DANGER] ns.foo#bam: string shape name, `bam`, is not upper camel case | DefaultCamelCase +[DANGER] ns.foo#snake_case: string shape name, `snake_case`, is not upper camel case | DefaultCamelCase +[DANGER] ns.foo#Structure$snake_case: Member shape member name, `snake_case`, is not consistent camel case. (Member names must also all use consistent camel case) | DefaultCamelCase +[DANGER] ns.foo#upperStructureTrait$UpperCamelCase: Member shape member name, `UpperCamelCase`, is not consistent camel case. (Member names must also all use consistent camel case) | DefaultCamelCase +[DANGER] ns.foo#upperStructureTrait$snake_case: Member shape member name, `snake_case`, is not consistent camel case. (Member names must also all use consistent camel case) | DefaultCamelCase diff --git a/smithy-linters/src/test/resources/software/amazon/smithy/linters/errorfiles/camel-case-validator-defaults-test-lower.json b/smithy-linters/src/test/resources/software/amazon/smithy/linters/errorfiles/camel-case-validator-defaults-test-lower.json new file mode 100644 index 00000000000..86014dd475c --- /dev/null +++ b/smithy-linters/src/test/resources/software/amazon/smithy/linters/errorfiles/camel-case-validator-defaults-test-lower.json @@ -0,0 +1,105 @@ +{ + "smithy": "1.0", + "shapes": { + "ns.foo#InvalidTrait": { + "type": "string", + "traits": { + "smithy.api#trait": {} + } + }, + "ns.foo#validTrait": { + "type": "string", + "traits": { + "smithy.api#trait": {} + } + }, + "ns.foo#lowerStructureTrait": { + "type": "structure", + "members": { + "lowerCamelCase": { + "target": "ns.foo#Foo" + } + }, + "traits": { + "smithy.api#trait": {} + } + }, + "ns.foo#upperStructureTrait": { + "type": "structure", + "members": { + "UpperCamelCase": { + "target": "ns.foo#Foo" + }, + "snake_case": { + "target": "ns.foo#Foo" + } + }, + "traits": { + "smithy.api#trait": {} + } + }, + "ns.foo#Foo": { + "type": "string" + }, + "ns.foo#BazBar": { + "type": "string" + }, + "ns.foo#bam": { + "type": "string" + }, + "ns.foo#snake_case": { + "type": "string" + }, + "ns.foo#Structure": { + "type": "structure", + "members": { + "lowerCamelCase": { + "target": "ns.foo#Foo" + }, + "snake_case": { + "target": "ns.foo#Foo" + } + } + }, + "foo.protocols#fooJson1_1": { + "type": "structure", + "members": { + "foo": { + "target": "smithy.api#String" + } + }, + "traits": { + "smithy.api#trait": { + "selector": "service" + }, + "smithy.api#protocolDefinition": { + "traits": [ + "smithy.api#jsonName" + ] + } + } + }, + "foo.auth#v1_1": { + "type": "structure", + "members": { + "name": { + "target": "smithy.api#String" + } + }, + "traits": { + "smithy.api#trait": { + "selector": "service" + }, + "smithy.api#authDefinition": {} + } + } + }, + "metadata": { + "validators": [ + { + "name": "CamelCase", + "id": "DefaultCamelCase" + } + ] + } +} diff --git a/smithy-linters/src/test/resources/software/amazon/smithy/linters/errorfiles/camel-case-validator-defaults-test-upper.errors b/smithy-linters/src/test/resources/software/amazon/smithy/linters/errorfiles/camel-case-validator-defaults-test-upper.errors new file mode 100644 index 00000000000..e6e186cd1ee --- /dev/null +++ b/smithy-linters/src/test/resources/software/amazon/smithy/linters/errorfiles/camel-case-validator-defaults-test-upper.errors @@ -0,0 +1,6 @@ +[DANGER] ns.foo#InvalidTrait: string trait definition, `InvalidTrait`, is not lower camel case | DefaultCamelCase +[DANGER] ns.foo#bam: string shape name, `bam`, is not upper camel case | DefaultCamelCase +[DANGER] ns.foo#snake_case: string shape name, `snake_case`, is not upper camel case | DefaultCamelCase +[DANGER] ns.foo#Structure$snake_case: Member shape member name, `snake_case`, is not consistent camel case. (Member names must also all use consistent camel case) | DefaultCamelCase +[DANGER] ns.foo#upperStructureTrait$snake_case: Member shape member name, `snake_case`, is not consistent camel case. (Member names must also all use consistent camel case) | DefaultCamelCase +[DANGER] ns.foo#Structure$lowerCamelCase: Member shape member name, `lowerCamelCase`, is not consistent camel case. (Member names must also all use consistent camel case) | DefaultCamelCase diff --git a/smithy-linters/src/test/resources/software/amazon/smithy/linters/errorfiles/camel-case-validator-defaults-test-upper.json b/smithy-linters/src/test/resources/software/amazon/smithy/linters/errorfiles/camel-case-validator-defaults-test-upper.json new file mode 100644 index 00000000000..dee5c116fc4 --- /dev/null +++ b/smithy-linters/src/test/resources/software/amazon/smithy/linters/errorfiles/camel-case-validator-defaults-test-upper.json @@ -0,0 +1,103 @@ +{ + "smithy": "1.0", + "shapes": { + "ns.foo#InvalidTrait": { + "type": "string", + "traits": { + "smithy.api#trait": {} + } + }, + "ns.foo#validTrait": { + "type": "string", + "traits": { + "smithy.api#trait": {} + } + }, + "ns.foo#lowerStructureTrait": { + "type": "structure", + "traits": { + "smithy.api#trait": {} + } + }, + "ns.foo#upperStructureTrait": { + "type": "structure", + "members": { + "UpperCamelCase": { + "target": "ns.foo#Foo" + }, + "snake_case": { + "target": "ns.foo#Foo" + } + }, + "traits": { + "smithy.api#trait": {} + } + }, + "ns.foo#Foo": { + "type": "string" + }, + "ns.foo#BazBar": { + "type": "string" + }, + "ns.foo#bam": { + "type": "string" + }, + "ns.foo#snake_case": { + "type": "string" + }, + "ns.foo#Structure": { + "type": "structure", + "members": { + "lowerCamelCase": { + "target": "ns.foo#Foo" + }, + "UpperCamelCase": { + "target": "ns.foo#Foo" + }, + "snake_case": { + "target": "ns.foo#Foo" + } + } + }, + "foo.protocols#fooJson1_1": { + "type": "structure", + "members": { + "Foo": { + "target": "smithy.api#String" + } + }, + "traits": { + "smithy.api#trait": { + "selector": "service" + }, + "smithy.api#protocolDefinition": { + "traits": [ + "smithy.api#jsonName" + ] + } + } + }, + "foo.auth#v1_1": { + "type": "structure", + "members": { + "Name": { + "target": "smithy.api#String" + } + }, + "traits": { + "smithy.api#trait": { + "selector": "service" + }, + "smithy.api#authDefinition": {} + } + } + }, + "metadata": { + "validators": [ + { + "name": "CamelCase", + "id": "DefaultCamelCase" + } + ] + } +} diff --git a/smithy-linters/src/test/resources/software/amazon/smithy/linters/errorfiles/camel-case-validator-defaults-test.errors b/smithy-linters/src/test/resources/software/amazon/smithy/linters/errorfiles/camel-case-validator-defaults-test.errors index fc082dd3034..95ed920719f 100644 --- a/smithy-linters/src/test/resources/software/amazon/smithy/linters/errorfiles/camel-case-validator-defaults-test.errors +++ b/smithy-linters/src/test/resources/software/amazon/smithy/linters/errorfiles/camel-case-validator-defaults-test.errors @@ -1,16 +1,28 @@ -[DANGER] ns.foo#Structure$UpperCamelCase: Member shape member name, `UpperCamelCase`, is not lower camel case | DefaultCamelCase -[DANGER] ns.foo#Structure$lowerCamelCase: Member shape member name, `lowerCamelCase`, is not upper camel case | OppositeOfDefaults -[DANGER] ns.foo#Structure$snake_case: Member shape member name, `snake_case`, is not lower camel case | DefaultCamelCase -[DANGER] ns.foo#Structure$snake_case: Member shape member name, `snake_case`, is not upper camel case | OppositeOfDefaults +[DANGER] ns.foo#Structure$UpperCamelCase: Member shape member name, `UpperCamelCase`, is not lower camel case. (Member names must also all use consistent camel case) | LowerCamelCase +[DANGER] ns.foo#Structure$snake_case: Member shape member name, `snake_case`, is not lower camel case. (Member names must also all use consistent camel case) | LowerCamelCase +[DANGER] ns.foo#bam: string shape name, `bam`, is not upper camel case | LowerCamelCase +[DANGER] ns.foo#snake_case: string shape name, `snake_case`, is not upper camel case | LowerCamelCase +[DANGER] ns.foo#InvalidTrait: string trait definition, `InvalidTrait`, is not lower camel case | LowerCamelCase +[DANGER] ns.foo#InvalidTrait: string trait definition, `InvalidTrait`, is not lower camel case | UpperCamelCase +[DANGER] ns.foo#upperStructureTrait$UpperCamelCase: Member shape member name, `UpperCamelCase`, is not lower camel case. (Member names must also all use consistent camel case) | LowerCamelCase +[DANGER] ns.foo#upperStructureTrait$snake_case: Member shape member name, `snake_case`, is not lower camel case. (Member names must also all use consistent camel case) | LowerCamelCase +[DANGER] ns.foo#Structure$SecondUpperCamelCase: Member shape member name, `SecondUpperCamelCase`, is not lower camel case. (Member names must also all use consistent camel case) | LowerCamelCase +[DANGER] ns.foo#Structure$ThirdUpperCamelCase: Member shape member name, `ThirdUpperCamelCase`, is not lower camel case. (Member names must also all use consistent camel case) | LowerCamelCase +[DANGER] ns.foo#Structure$FourthUpperCamelCase: Member shape member name, `FourthUpperCamelCase`, is not lower camel case. (Member names must also all use consistent camel case) | LowerCamelCase +[DANGER] ns.foo#Structure$lowerCamelCase: Member shape member name, `lowerCamelCase`, is not upper camel case. (Member names must also all use consistent camel case) | UpperCamelCase +[DANGER] ns.foo#Structure$snake_case: Member shape member name, `snake_case`, is not upper camel case. (Member names must also all use consistent camel case) | UpperCamelCase +[DANGER] ns.foo#bam: string shape name, `bam`, is not upper camel case | UpperCamelCase +[DANGER] ns.foo#snake_case: string shape name, `snake_case`, is not upper camel case | UpperCamelCase +[DANGER] ns.foo#upperStructureTrait$snake_case: Member shape member name, `snake_case`, is not upper camel case. (Member names must also all use consistent camel case) | UpperCamelCase +[DANGER] ns.foo#lowerStructureTrait$lowerCamelCase: Member shape member name, `lowerCamelCase`, is not upper camel case. (Member names must also all use consistent camel case) | UpperCamelCase +[DANGER] foo.protocols#fooJson1_1$foo: Member shape member name, `foo`, is not upper camel case. (Member names must also all use consistent camel case) | UpperCamelCase +[DANGER] foo.auth#v1_1$name: Member shape member name, `name`, is not upper camel case. (Member names must also all use consistent camel case) | UpperCamelCase +[DANGER] ns.foo#InvalidTrait: string trait definition, `InvalidTrait`, is not lower camel case | DefaultCamelCase +[DANGER] ns.foo#upperStructureTrait$snake_case: Member shape member name, `snake_case`, is not consistent camel case. (Member names must also all use consistent camel case) | DefaultCamelCase [DANGER] ns.foo#bam: string shape name, `bam`, is not upper camel case | DefaultCamelCase -[DANGER] ns.foo#bam: string shape name, `bam`, is not upper camel case | OppositeOfDefaults [DANGER] ns.foo#snake_case: string shape name, `snake_case`, is not upper camel case | DefaultCamelCase -[DANGER] ns.foo#snake_case: string shape name, `snake_case`, is not upper camel case | OppositeOfDefaults -[DANGER] ns.foo#InvalidTrait: string trait definition, `InvalidTrait`, is not lower camel case | DefaultCamelCase -[DANGER] ns.foo#InvalidTrait: string trait definition, `InvalidTrait`, is not lower camel case | OppositeOfDefaults -[DANGER] ns.foo#upperStructureTrait$UpperCamelCase: Member shape member name, `UpperCamelCase`, is not lower camel case | DefaultCamelCase -[DANGER] ns.foo#upperStructureTrait$snake_case: Member shape member name, `snake_case`, is not lower camel case | DefaultCamelCase -[DANGER] ns.foo#upperStructureTrait$snake_case: Member shape member name, `snake_case`, is not upper camel case | OppositeOfDefaults -[DANGER] ns.foo#lowerStructureTrait$lowerCamelCase: Member shape member name, `lowerCamelCase`, is not upper camel case | OppositeOfDefaults -[DANGER] foo.protocols#fooJson1_1$foo: Member shape member name, `foo`, is not upper camel case | OppositeOfDefaults -[DANGER] foo.auth#v1_1$name: Member shape member name, `name`, is not upper camel case | OppositeOfDefaults +[DANGER] ns.foo#Structure$snake_case: Member shape member name, `snake_case`, is not consistent camel case. (Member names must also all use consistent camel case) | DefaultCamelCase +[DANGER] ns.foo#lowerStructureTrait$lowerCamelCase: Member shape member name, `lowerCamelCase`, is not consistent camel case. (Member names must also all use consistent camel case) | DefaultCamelCase +[DANGER] ns.foo#Structure$lowerCamelCase: Member shape member name, `lowerCamelCase`, is not consistent camel case. (Member names must also all use consistent camel case) | DefaultCamelCase +[DANGER] foo.protocols#fooJson1_1$foo: Member shape member name, `foo`, is not consistent camel case. (Member names must also all use consistent camel case) | DefaultCamelCase +[DANGER] foo.auth#v1_1$name: Member shape member name, `name`, is not consistent camel case. (Member names must also all use consistent camel case) | DefaultCamelCase diff --git a/smithy-linters/src/test/resources/software/amazon/smithy/linters/errorfiles/camel-case-validator-defaults-test.json b/smithy-linters/src/test/resources/software/amazon/smithy/linters/errorfiles/camel-case-validator-defaults-test.json index 3433c992c04..1500e3cfb62 100644 --- a/smithy-linters/src/test/resources/software/amazon/smithy/linters/errorfiles/camel-case-validator-defaults-test.json +++ b/smithy-linters/src/test/resources/software/amazon/smithy/linters/errorfiles/camel-case-validator-defaults-test.json @@ -59,6 +59,15 @@ "UpperCamelCase": { "target": "ns.foo#Foo" }, + "SecondUpperCamelCase": { + "target": "ns.foo#Foo" + }, + "ThirdUpperCamelCase": { + "target": "ns.foo#Foo" + }, + "FourthUpperCamelCase": { + "target": "ns.foo#Foo" + }, "snake_case": { "target": "ns.foo#Foo" } @@ -101,14 +110,21 @@ "validators": [ { "name": "CamelCase", - "id": "DefaultCamelCase" + "id": "LowerCamelCase", + "configuration": { + "memberNames": "lower" + } }, { "name": "CamelCase", - "id": "OppositeOfDefaults", + "id": "UpperCamelCase", "configuration": { "memberNames": "upper" } + }, + { + "name": "CamelCase", + "id": "DefaultCamelCase" } ] } From b818a7f8d99193d1847c42ff2d4a059d7d15fa51 Mon Sep 17 00:00:00 2001 From: Richard Chen Date: Wed, 11 May 2022 10:21:42 -0700 Subject: [PATCH 2/5] optimizations on AUTO camel case validations --- .../smithy/linters/CamelCaseValidator.java | 66 +++++++++++++------ ...-case-validator-defaults-test-lower.errors | 6 +- ...-case-validator-defaults-test-upper.errors | 6 +- .../camel-case-validator-defaults-test.errors | 38 +++++------ 4 files changed, 72 insertions(+), 44 deletions(-) diff --git a/smithy-linters/src/main/java/software/amazon/smithy/linters/CamelCaseValidator.java b/smithy-linters/src/main/java/software/amazon/smithy/linters/CamelCaseValidator.java index 763b7e99729..bc61002de6d 100644 --- a/smithy-linters/src/main/java/software/amazon/smithy/linters/CamelCaseValidator.java +++ b/smithy-linters/src/main/java/software/amazon/smithy/linters/CamelCaseValidator.java @@ -18,8 +18,13 @@ import static java.lang.String.format; import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; import java.util.List; +import java.util.Set; import java.util.regex.Pattern; +import java.util.stream.Collectors; +import java.util.stream.Stream; import software.amazon.smithy.model.Model; import software.amazon.smithy.model.loader.Prelude; import software.amazon.smithy.model.node.NodeMapper; @@ -38,6 +43,16 @@ * desired camel casing format. */ public final class CamelCaseValidator extends AbstractValidator { + private static final Set EXCLUDED_NAMESPACES = new HashSet<>(Arrays.asList( + Prelude.NAMESPACE, + "aws.apigateway", + "aws.cloudformation", + "aws.iam", + "aws.api", + "aws.auth", + "aws.customizations", + "aws.protocols", + "smithy.test")); /** * CamelCase configuration settings. @@ -48,7 +63,7 @@ public static final class Config { /** * Gets how member names are to be cased. * - *

One of "upper" or "lower" (default). + *

One of "upper", "lower", or "auto" (default). * * @return returns member name casing. */ @@ -91,7 +106,7 @@ public String toString() { }, /** - * Will ensure it is either all lower camel or all upper camel, but not a mixture. + * Member names are serialized using either all lower camel or all upper camel, but not a mixture. */ AUTO { Pattern getRegex() { @@ -129,6 +144,10 @@ private CamelCaseValidator(Config config) { @Override public List validate(Model model) { List events = new ArrayList<>(); + int upperCamelMemberNamesCount = 0; + int lowerCamelMemberNamesCount = 0; + Set nonUpperCamelMemberShapes = new HashSet<>(); + Set nonLowerCamelMemberShapes = new HashSet<>(); // Normal shapes are expected to be upper camel. model.shapes() @@ -151,27 +170,36 @@ public List validate(Model model) { shape.getType(), shape.getId().getName()))) .forEach(events::add); - Pattern memberNamePattern; + Stream memberShapesToValidate = model.toSet(MemberShape.class).stream() + .filter(memberShape -> !EXCLUDED_NAMESPACES.contains(memberShape.getContainer().getNamespace())); + for (MemberShape memberShape : memberShapesToValidate.collect(Collectors.toList())) { + if (MemberNameHandling.UPPER.getRegex().matcher(memberShape.getMemberName()).find()) { + upperCamelMemberNamesCount++; + } else { + nonUpperCamelMemberShapes.add(memberShape); + } + if (MemberNameHandling.LOWER.getRegex().matcher(memberShape.getMemberName()).find()) { + lowerCamelMemberNamesCount++; + } else { + nonLowerCamelMemberShapes.add(memberShape); + } + } + + // Member shapes are expected to be either upper or lower, depending on the config (and in AUTO mode, the model) + Set violatingMemberShapes = new HashSet<>(); if (MemberNameHandling.AUTO.equals(config.getMemberNames())) { - long upperMemberNameCount = model.shapes(MemberShape.class) - .filter(shape -> !shape.getContainer().getNamespace().equals(Prelude.NAMESPACE)) - .filter(shape -> MemberNameHandling.UPPER.getRegex().matcher(shape.getMemberName()).find()) - .count(); - long lowerMemberNameCount = model.shapes(MemberShape.class) - .filter(shape -> !shape.getContainer().getNamespace().equals(Prelude.NAMESPACE)) - .filter(shape -> MemberNameHandling.LOWER.getRegex().matcher(shape.getMemberName()).find()) - .count(); - - memberNamePattern = upperMemberNameCount > lowerMemberNameCount - ? MemberNameHandling.UPPER.getRegex() : MemberNameHandling.LOWER.getRegex(); - } else { - memberNamePattern = config.getMemberNames().getRegex(); + violatingMemberShapes = upperCamelMemberNamesCount > lowerCamelMemberNamesCount + ? nonUpperCamelMemberShapes : nonLowerCamelMemberShapes; + } else if (MemberNameHandling.UPPER.equals(config.getMemberNames())) { + violatingMemberShapes = nonUpperCamelMemberShapes; + } else if (MemberNameHandling.LOWER.equals(config.getMemberNames())) { + violatingMemberShapes = nonLowerCamelMemberShapes; } - model.shapes(MemberShape.class) - .filter(shape -> !memberNamePattern.matcher(shape.getMemberName()).find()) + violatingMemberShapes.stream() .map(shape -> danger(shape, format( - "Member shape member name, `%s`, is not %s camel case. (Member names must also all use consistent camel case)", + "Member shape member name, `%s`, is not %s camel case. " + + "(Member names must all use the same type of camel case)", shape.getMemberName(), config.getMemberNames()))) .forEach(events::add); diff --git a/smithy-linters/src/test/resources/software/amazon/smithy/linters/errorfiles/camel-case-validator-defaults-test-lower.errors b/smithy-linters/src/test/resources/software/amazon/smithy/linters/errorfiles/camel-case-validator-defaults-test-lower.errors index 638ac39f719..029c01c8c62 100644 --- a/smithy-linters/src/test/resources/software/amazon/smithy/linters/errorfiles/camel-case-validator-defaults-test-lower.errors +++ b/smithy-linters/src/test/resources/software/amazon/smithy/linters/errorfiles/camel-case-validator-defaults-test-lower.errors @@ -1,6 +1,6 @@ [DANGER] ns.foo#InvalidTrait: string trait definition, `InvalidTrait`, is not lower camel case | DefaultCamelCase [DANGER] ns.foo#bam: string shape name, `bam`, is not upper camel case | DefaultCamelCase [DANGER] ns.foo#snake_case: string shape name, `snake_case`, is not upper camel case | DefaultCamelCase -[DANGER] ns.foo#Structure$snake_case: Member shape member name, `snake_case`, is not consistent camel case. (Member names must also all use consistent camel case) | DefaultCamelCase -[DANGER] ns.foo#upperStructureTrait$UpperCamelCase: Member shape member name, `UpperCamelCase`, is not consistent camel case. (Member names must also all use consistent camel case) | DefaultCamelCase -[DANGER] ns.foo#upperStructureTrait$snake_case: Member shape member name, `snake_case`, is not consistent camel case. (Member names must also all use consistent camel case) | DefaultCamelCase +[DANGER] ns.foo#Structure$snake_case: Member shape member name, `snake_case`, is not consistent camel case. (Member names must all use the same type of camel case) | DefaultCamelCase +[DANGER] ns.foo#upperStructureTrait$UpperCamelCase: Member shape member name, `UpperCamelCase`, is not consistent camel case. (Member names must all use the same type of camel case) | DefaultCamelCase +[DANGER] ns.foo#upperStructureTrait$snake_case: Member shape member name, `snake_case`, is not consistent camel case. (Member names must all use the same type of camel case) | DefaultCamelCase diff --git a/smithy-linters/src/test/resources/software/amazon/smithy/linters/errorfiles/camel-case-validator-defaults-test-upper.errors b/smithy-linters/src/test/resources/software/amazon/smithy/linters/errorfiles/camel-case-validator-defaults-test-upper.errors index e6e186cd1ee..0c64171f861 100644 --- a/smithy-linters/src/test/resources/software/amazon/smithy/linters/errorfiles/camel-case-validator-defaults-test-upper.errors +++ b/smithy-linters/src/test/resources/software/amazon/smithy/linters/errorfiles/camel-case-validator-defaults-test-upper.errors @@ -1,6 +1,6 @@ [DANGER] ns.foo#InvalidTrait: string trait definition, `InvalidTrait`, is not lower camel case | DefaultCamelCase [DANGER] ns.foo#bam: string shape name, `bam`, is not upper camel case | DefaultCamelCase [DANGER] ns.foo#snake_case: string shape name, `snake_case`, is not upper camel case | DefaultCamelCase -[DANGER] ns.foo#Structure$snake_case: Member shape member name, `snake_case`, is not consistent camel case. (Member names must also all use consistent camel case) | DefaultCamelCase -[DANGER] ns.foo#upperStructureTrait$snake_case: Member shape member name, `snake_case`, is not consistent camel case. (Member names must also all use consistent camel case) | DefaultCamelCase -[DANGER] ns.foo#Structure$lowerCamelCase: Member shape member name, `lowerCamelCase`, is not consistent camel case. (Member names must also all use consistent camel case) | DefaultCamelCase +[DANGER] ns.foo#Structure$snake_case: Member shape member name, `snake_case`, is not consistent camel case. (Member names must all use the same type of camel case) | DefaultCamelCase +[DANGER] ns.foo#upperStructureTrait$snake_case: Member shape member name, `snake_case`, is not consistent camel case. (Member names must all use the same type of camel case) | DefaultCamelCase +[DANGER] ns.foo#Structure$lowerCamelCase: Member shape member name, `lowerCamelCase`, is not consistent camel case. (Member names must all use the same type of camel case) | DefaultCamelCase diff --git a/smithy-linters/src/test/resources/software/amazon/smithy/linters/errorfiles/camel-case-validator-defaults-test.errors b/smithy-linters/src/test/resources/software/amazon/smithy/linters/errorfiles/camel-case-validator-defaults-test.errors index 95ed920719f..4de02fe50b5 100644 --- a/smithy-linters/src/test/resources/software/amazon/smithy/linters/errorfiles/camel-case-validator-defaults-test.errors +++ b/smithy-linters/src/test/resources/software/amazon/smithy/linters/errorfiles/camel-case-validator-defaults-test.errors @@ -1,28 +1,28 @@ -[DANGER] ns.foo#Structure$UpperCamelCase: Member shape member name, `UpperCamelCase`, is not lower camel case. (Member names must also all use consistent camel case) | LowerCamelCase -[DANGER] ns.foo#Structure$snake_case: Member shape member name, `snake_case`, is not lower camel case. (Member names must also all use consistent camel case) | LowerCamelCase +[DANGER] ns.foo#Structure$UpperCamelCase: Member shape member name, `UpperCamelCase`, is not lower camel case. (Member names must all use the same type of camel case) | LowerCamelCase +[DANGER] ns.foo#Structure$snake_case: Member shape member name, `snake_case`, is not lower camel case. (Member names must all use the same type of camel case) | LowerCamelCase [DANGER] ns.foo#bam: string shape name, `bam`, is not upper camel case | LowerCamelCase [DANGER] ns.foo#snake_case: string shape name, `snake_case`, is not upper camel case | LowerCamelCase [DANGER] ns.foo#InvalidTrait: string trait definition, `InvalidTrait`, is not lower camel case | LowerCamelCase [DANGER] ns.foo#InvalidTrait: string trait definition, `InvalidTrait`, is not lower camel case | UpperCamelCase -[DANGER] ns.foo#upperStructureTrait$UpperCamelCase: Member shape member name, `UpperCamelCase`, is not lower camel case. (Member names must also all use consistent camel case) | LowerCamelCase -[DANGER] ns.foo#upperStructureTrait$snake_case: Member shape member name, `snake_case`, is not lower camel case. (Member names must also all use consistent camel case) | LowerCamelCase -[DANGER] ns.foo#Structure$SecondUpperCamelCase: Member shape member name, `SecondUpperCamelCase`, is not lower camel case. (Member names must also all use consistent camel case) | LowerCamelCase -[DANGER] ns.foo#Structure$ThirdUpperCamelCase: Member shape member name, `ThirdUpperCamelCase`, is not lower camel case. (Member names must also all use consistent camel case) | LowerCamelCase -[DANGER] ns.foo#Structure$FourthUpperCamelCase: Member shape member name, `FourthUpperCamelCase`, is not lower camel case. (Member names must also all use consistent camel case) | LowerCamelCase -[DANGER] ns.foo#Structure$lowerCamelCase: Member shape member name, `lowerCamelCase`, is not upper camel case. (Member names must also all use consistent camel case) | UpperCamelCase -[DANGER] ns.foo#Structure$snake_case: Member shape member name, `snake_case`, is not upper camel case. (Member names must also all use consistent camel case) | UpperCamelCase +[DANGER] ns.foo#upperStructureTrait$UpperCamelCase: Member shape member name, `UpperCamelCase`, is not lower camel case. (Member names must all use the same type of camel case) | LowerCamelCase +[DANGER] ns.foo#upperStructureTrait$snake_case: Member shape member name, `snake_case`, is not lower camel case. (Member names must all use the same type of camel case) | LowerCamelCase +[DANGER] ns.foo#Structure$SecondUpperCamelCase: Member shape member name, `SecondUpperCamelCase`, is not lower camel case. (Member names must all use the same type of camel case) | LowerCamelCase +[DANGER] ns.foo#Structure$ThirdUpperCamelCase: Member shape member name, `ThirdUpperCamelCase`, is not lower camel case. (Member names must all use the same type of camel case) | LowerCamelCase +[DANGER] ns.foo#Structure$FourthUpperCamelCase: Member shape member name, `FourthUpperCamelCase`, is not lower camel case. (Member names must all use the same type of camel case) | LowerCamelCase +[DANGER] ns.foo#Structure$lowerCamelCase: Member shape member name, `lowerCamelCase`, is not upper camel case. (Member names must all use the same type of camel case) | UpperCamelCase +[DANGER] ns.foo#Structure$snake_case: Member shape member name, `snake_case`, is not upper camel case. (Member names must all use the same type of camel case) | UpperCamelCase [DANGER] ns.foo#bam: string shape name, `bam`, is not upper camel case | UpperCamelCase [DANGER] ns.foo#snake_case: string shape name, `snake_case`, is not upper camel case | UpperCamelCase -[DANGER] ns.foo#upperStructureTrait$snake_case: Member shape member name, `snake_case`, is not upper camel case. (Member names must also all use consistent camel case) | UpperCamelCase -[DANGER] ns.foo#lowerStructureTrait$lowerCamelCase: Member shape member name, `lowerCamelCase`, is not upper camel case. (Member names must also all use consistent camel case) | UpperCamelCase -[DANGER] foo.protocols#fooJson1_1$foo: Member shape member name, `foo`, is not upper camel case. (Member names must also all use consistent camel case) | UpperCamelCase -[DANGER] foo.auth#v1_1$name: Member shape member name, `name`, is not upper camel case. (Member names must also all use consistent camel case) | UpperCamelCase +[DANGER] ns.foo#upperStructureTrait$snake_case: Member shape member name, `snake_case`, is not upper camel case. (Member names must all use the same type of camel case) | UpperCamelCase +[DANGER] ns.foo#lowerStructureTrait$lowerCamelCase: Member shape member name, `lowerCamelCase`, is not upper camel case. (Member names must all use the same type of camel case) | UpperCamelCase +[DANGER] foo.protocols#fooJson1_1$foo: Member shape member name, `foo`, is not upper camel case. (Member names must all use the same type of camel case) | UpperCamelCase +[DANGER] foo.auth#v1_1$name: Member shape member name, `name`, is not upper camel case. (Member names must all use the same type of camel case) | UpperCamelCase [DANGER] ns.foo#InvalidTrait: string trait definition, `InvalidTrait`, is not lower camel case | DefaultCamelCase -[DANGER] ns.foo#upperStructureTrait$snake_case: Member shape member name, `snake_case`, is not consistent camel case. (Member names must also all use consistent camel case) | DefaultCamelCase +[DANGER] ns.foo#upperStructureTrait$snake_case: Member shape member name, `snake_case`, is not consistent camel case. (Member names must all use the same type of camel case) | DefaultCamelCase [DANGER] ns.foo#bam: string shape name, `bam`, is not upper camel case | DefaultCamelCase [DANGER] ns.foo#snake_case: string shape name, `snake_case`, is not upper camel case | DefaultCamelCase -[DANGER] ns.foo#Structure$snake_case: Member shape member name, `snake_case`, is not consistent camel case. (Member names must also all use consistent camel case) | DefaultCamelCase -[DANGER] ns.foo#lowerStructureTrait$lowerCamelCase: Member shape member name, `lowerCamelCase`, is not consistent camel case. (Member names must also all use consistent camel case) | DefaultCamelCase -[DANGER] ns.foo#Structure$lowerCamelCase: Member shape member name, `lowerCamelCase`, is not consistent camel case. (Member names must also all use consistent camel case) | DefaultCamelCase -[DANGER] foo.protocols#fooJson1_1$foo: Member shape member name, `foo`, is not consistent camel case. (Member names must also all use consistent camel case) | DefaultCamelCase -[DANGER] foo.auth#v1_1$name: Member shape member name, `name`, is not consistent camel case. (Member names must also all use consistent camel case) | DefaultCamelCase +[DANGER] ns.foo#Structure$snake_case: Member shape member name, `snake_case`, is not consistent camel case. (Member names must all use the same type of camel case) | DefaultCamelCase +[DANGER] ns.foo#lowerStructureTrait$lowerCamelCase: Member shape member name, `lowerCamelCase`, is not consistent camel case. (Member names must all use the same type of camel case) | DefaultCamelCase +[DANGER] ns.foo#Structure$lowerCamelCase: Member shape member name, `lowerCamelCase`, is not consistent camel case. (Member names must all use the same type of camel case) | DefaultCamelCase +[DANGER] foo.protocols#fooJson1_1$foo: Member shape member name, `foo`, is not consistent camel case. (Member names must all use the same type of camel case) | DefaultCamelCase +[DANGER] foo.auth#v1_1$name: Member shape member name, `name`, is not consistent camel case. (Member names must all use the same type of camel case) | DefaultCamelCase From cdc3955e2324a057325b0e516632e569eb776f79 Mon Sep 17 00:00:00 2001 From: Richard Chen Date: Thu, 12 May 2022 17:22:03 -0700 Subject: [PATCH 3/5] CamelCase validator refactor strategy for deciding dominant camelcase type --- .../smithy/linters/CamelCaseValidator.java | 60 ++++++---- ...l-case-validator-default-lower-test.errors | 2 + ...l-case-validator-default-lower-test.smithy | 36 ++++++ ...l-case-validator-default-upper-test.errors | 2 + ...l-case-validator-default-upper-test.smithy | 36 ++++++ ...-case-validator-defaults-test-lower.errors | 6 - ...el-case-validator-defaults-test-lower.json | 105 ------------------ ...-case-validator-defaults-test-upper.errors | 6 - ...el-case-validator-defaults-test-upper.json | 103 ----------------- .../camel-case-validator-defaults-test.errors | 18 ++- .../camel-case-validator-defaults-test.json | 57 +++++++++- 11 files changed, 180 insertions(+), 251 deletions(-) create mode 100644 smithy-linters/src/test/resources/software/amazon/smithy/linters/errorfiles/camel-case-validator-default-lower-test.errors create mode 100644 smithy-linters/src/test/resources/software/amazon/smithy/linters/errorfiles/camel-case-validator-default-lower-test.smithy create mode 100644 smithy-linters/src/test/resources/software/amazon/smithy/linters/errorfiles/camel-case-validator-default-upper-test.errors create mode 100644 smithy-linters/src/test/resources/software/amazon/smithy/linters/errorfiles/camel-case-validator-default-upper-test.smithy delete mode 100644 smithy-linters/src/test/resources/software/amazon/smithy/linters/errorfiles/camel-case-validator-defaults-test-lower.errors delete mode 100644 smithy-linters/src/test/resources/software/amazon/smithy/linters/errorfiles/camel-case-validator-defaults-test-lower.json delete mode 100644 smithy-linters/src/test/resources/software/amazon/smithy/linters/errorfiles/camel-case-validator-defaults-test-upper.errors delete mode 100644 smithy-linters/src/test/resources/software/amazon/smithy/linters/errorfiles/camel-case-validator-defaults-test-upper.json diff --git a/smithy-linters/src/main/java/software/amazon/smithy/linters/CamelCaseValidator.java b/smithy-linters/src/main/java/software/amazon/smithy/linters/CamelCaseValidator.java index bc61002de6d..8108b12ffd2 100644 --- a/smithy-linters/src/main/java/software/amazon/smithy/linters/CamelCaseValidator.java +++ b/smithy-linters/src/main/java/software/amazon/smithy/linters/CamelCaseValidator.java @@ -18,17 +18,18 @@ import static java.lang.String.format; import java.util.ArrayList; -import java.util.Arrays; import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Set; import java.util.regex.Pattern; import java.util.stream.Collectors; import java.util.stream.Stream; import software.amazon.smithy.model.Model; -import software.amazon.smithy.model.loader.Prelude; +import software.amazon.smithy.model.neighbor.Walker; import software.amazon.smithy.model.node.NodeMapper; import software.amazon.smithy.model.shapes.MemberShape; +import software.amazon.smithy.model.shapes.ServiceShape; import software.amazon.smithy.model.shapes.Shape; import software.amazon.smithy.model.traits.AuthDefinitionTrait; import software.amazon.smithy.model.traits.ProtocolDefinitionTrait; @@ -43,16 +44,6 @@ * desired camel casing format. */ public final class CamelCaseValidator extends AbstractValidator { - private static final Set EXCLUDED_NAMESPACES = new HashSet<>(Arrays.asList( - Prelude.NAMESPACE, - "aws.apigateway", - "aws.cloudformation", - "aws.iam", - "aws.api", - "aws.auth", - "aws.customizations", - "aws.protocols", - "smithy.test")); /** * CamelCase configuration settings. @@ -144,10 +135,6 @@ private CamelCaseValidator(Config config) { @Override public List validate(Model model) { List events = new ArrayList<>(); - int upperCamelMemberNamesCount = 0; - int lowerCamelMemberNamesCount = 0; - Set nonUpperCamelMemberShapes = new HashSet<>(); - Set nonLowerCamelMemberShapes = new HashSet<>(); // Normal shapes are expected to be upper camel. model.shapes() @@ -170,9 +157,38 @@ public List validate(Model model) { shape.getType(), shape.getId().getName()))) .forEach(events::add); - Stream memberShapesToValidate = model.toSet(MemberShape.class).stream() - .filter(memberShape -> !EXCLUDED_NAMESPACES.contains(memberShape.getContainer().getNamespace())); - for (MemberShape memberShape : memberShapesToValidate.collect(Collectors.toList())) { + // First validate all member shapes connected to services + Set serviceClosure = new HashSet<>(); + for (ServiceShape serviceShape : model.getServiceShapes()) { + Walker walker = new Walker(model); + walker.iterateShapes(serviceShape).forEachRemaining(serviceClosure::add); + } + Stream memberShapesFromServices = serviceClosure.stream() + .filter(Shape::isMemberShape) + .map(shape -> (MemberShape) shape); + + events.addAll(validateCamelCasing(memberShapesFromServices.collect(Collectors.toList()))); + + // Next get all other member shapes (ex. trait shape members) and validate per namespace grouping + Map> memberShapesByNamespace = model.toSet(MemberShape.class).stream() + .filter(memberShape -> !serviceClosure.contains(memberShape)) + .collect(Collectors.groupingBy( + memberShape -> memberShape.getContainer().getNamespace())); + + for (List memberShapeGrouping : memberShapesByNamespace.values()) { + events.addAll(validateCamelCasing(memberShapeGrouping)); + } + + return events; + } + + private List validateCamelCasing(List memberShapes) { + int upperCamelMemberNamesCount = 0; + int lowerCamelMemberNamesCount = 0; + Set nonUpperCamelMemberShapes = new HashSet<>(); + Set nonLowerCamelMemberShapes = new HashSet<>(); + + for (MemberShape memberShape : memberShapes) { if (MemberNameHandling.UPPER.getRegex().matcher(memberShape.getMemberName()).find()) { upperCamelMemberNamesCount++; } else { @@ -196,13 +212,11 @@ public List validate(Model model) { violatingMemberShapes = nonLowerCamelMemberShapes; } - violatingMemberShapes.stream() + return violatingMemberShapes.stream() .map(shape -> danger(shape, format( "Member shape member name, `%s`, is not %s camel case. " + "(Member names must all use the same type of camel case)", shape.getMemberName(), config.getMemberNames()))) - .forEach(events::add); - - return events; + .collect(Collectors.toList()); } } diff --git a/smithy-linters/src/test/resources/software/amazon/smithy/linters/errorfiles/camel-case-validator-default-lower-test.errors b/smithy-linters/src/test/resources/software/amazon/smithy/linters/errorfiles/camel-case-validator-default-lower-test.errors new file mode 100644 index 00000000000..93ebd8113db --- /dev/null +++ b/smithy-linters/src/test/resources/software/amazon/smithy/linters/errorfiles/camel-case-validator-default-lower-test.errors @@ -0,0 +1,2 @@ +[DANGER] smithy.example#GetLatestServiceResponse$UpperCamel: Member shape member name, `UpperCamel`, is not consistent camel case. (Member names must all use the same type of camel case) | DefaultCamelCase +[DANGER] smithy.example#MyStructure$snake_case: Member shape member name, `snake_case`, is not consistent camel case. (Member names must all use the same type of camel case) | DefaultCamelCase diff --git a/smithy-linters/src/test/resources/software/amazon/smithy/linters/errorfiles/camel-case-validator-default-lower-test.smithy b/smithy-linters/src/test/resources/software/amazon/smithy/linters/errorfiles/camel-case-validator-default-lower-test.smithy new file mode 100644 index 00000000000..d91e1aaca16 --- /dev/null +++ b/smithy-linters/src/test/resources/software/amazon/smithy/linters/errorfiles/camel-case-validator-default-lower-test.smithy @@ -0,0 +1,36 @@ +$version: "1.0" + +metadata validators = [ + {name: "CamelCase", + id: "DefaultCamelCase"} +] + +namespace smithy.example + +service Example { + version: "2020-09-21", + operations: [GetLatestService], +} + +operation GetLatestService { + input: GetLatestServiceRequest, + output: GetLatestServiceResponse, + errors: [], +} + +structure GetLatestServiceRequest { + lowerCamel: MyString, + secondLowerCamel: MyString, + thirdLowerCamel: MyString, + fourthLowerCamel: MyStructure +} + +structure GetLatestServiceResponse { + UpperCamel: MyString +} + +structure MyStructure { + snake_case: MyString +} + +string MyString diff --git a/smithy-linters/src/test/resources/software/amazon/smithy/linters/errorfiles/camel-case-validator-default-upper-test.errors b/smithy-linters/src/test/resources/software/amazon/smithy/linters/errorfiles/camel-case-validator-default-upper-test.errors new file mode 100644 index 00000000000..5720c19b9a8 --- /dev/null +++ b/smithy-linters/src/test/resources/software/amazon/smithy/linters/errorfiles/camel-case-validator-default-upper-test.errors @@ -0,0 +1,2 @@ +[DANGER] smithy.example#GetLatestServiceResponse$lowerCamel: Member shape member name, `lowerCamel`, is not consistent camel case. (Member names must all use the same type of camel case) | DefaultCamelCase +[DANGER] smithy.example#MyStructure$snake_case: Member shape member name, `snake_case`, is not consistent camel case. (Member names must all use the same type of camel case) | DefaultCamelCase diff --git a/smithy-linters/src/test/resources/software/amazon/smithy/linters/errorfiles/camel-case-validator-default-upper-test.smithy b/smithy-linters/src/test/resources/software/amazon/smithy/linters/errorfiles/camel-case-validator-default-upper-test.smithy new file mode 100644 index 00000000000..94fe61b94e0 --- /dev/null +++ b/smithy-linters/src/test/resources/software/amazon/smithy/linters/errorfiles/camel-case-validator-default-upper-test.smithy @@ -0,0 +1,36 @@ +$version: "1.0" + +metadata validators = [ + {name: "CamelCase", + id: "DefaultCamelCase"} +] + +namespace smithy.example + +service Example { + version: "2020-09-21", + operations: [GetLatestService], +} + +operation GetLatestService { + input: GetLatestServiceRequest, + output: GetLatestServiceResponse, + errors: [], +} + +structure GetLatestServiceRequest { + UpperCamel: MyString, + SecondUpperCamel: MyString, + ThirdUpperCamel: MyString, + FourthUpperCamel: MyStructure +} + +structure GetLatestServiceResponse { + lowerCamel: MyString +} + +structure MyStructure { + snake_case: MyString +} + +string MyString diff --git a/smithy-linters/src/test/resources/software/amazon/smithy/linters/errorfiles/camel-case-validator-defaults-test-lower.errors b/smithy-linters/src/test/resources/software/amazon/smithy/linters/errorfiles/camel-case-validator-defaults-test-lower.errors deleted file mode 100644 index 029c01c8c62..00000000000 --- a/smithy-linters/src/test/resources/software/amazon/smithy/linters/errorfiles/camel-case-validator-defaults-test-lower.errors +++ /dev/null @@ -1,6 +0,0 @@ -[DANGER] ns.foo#InvalidTrait: string trait definition, `InvalidTrait`, is not lower camel case | DefaultCamelCase -[DANGER] ns.foo#bam: string shape name, `bam`, is not upper camel case | DefaultCamelCase -[DANGER] ns.foo#snake_case: string shape name, `snake_case`, is not upper camel case | DefaultCamelCase -[DANGER] ns.foo#Structure$snake_case: Member shape member name, `snake_case`, is not consistent camel case. (Member names must all use the same type of camel case) | DefaultCamelCase -[DANGER] ns.foo#upperStructureTrait$UpperCamelCase: Member shape member name, `UpperCamelCase`, is not consistent camel case. (Member names must all use the same type of camel case) | DefaultCamelCase -[DANGER] ns.foo#upperStructureTrait$snake_case: Member shape member name, `snake_case`, is not consistent camel case. (Member names must all use the same type of camel case) | DefaultCamelCase diff --git a/smithy-linters/src/test/resources/software/amazon/smithy/linters/errorfiles/camel-case-validator-defaults-test-lower.json b/smithy-linters/src/test/resources/software/amazon/smithy/linters/errorfiles/camel-case-validator-defaults-test-lower.json deleted file mode 100644 index 86014dd475c..00000000000 --- a/smithy-linters/src/test/resources/software/amazon/smithy/linters/errorfiles/camel-case-validator-defaults-test-lower.json +++ /dev/null @@ -1,105 +0,0 @@ -{ - "smithy": "1.0", - "shapes": { - "ns.foo#InvalidTrait": { - "type": "string", - "traits": { - "smithy.api#trait": {} - } - }, - "ns.foo#validTrait": { - "type": "string", - "traits": { - "smithy.api#trait": {} - } - }, - "ns.foo#lowerStructureTrait": { - "type": "structure", - "members": { - "lowerCamelCase": { - "target": "ns.foo#Foo" - } - }, - "traits": { - "smithy.api#trait": {} - } - }, - "ns.foo#upperStructureTrait": { - "type": "structure", - "members": { - "UpperCamelCase": { - "target": "ns.foo#Foo" - }, - "snake_case": { - "target": "ns.foo#Foo" - } - }, - "traits": { - "smithy.api#trait": {} - } - }, - "ns.foo#Foo": { - "type": "string" - }, - "ns.foo#BazBar": { - "type": "string" - }, - "ns.foo#bam": { - "type": "string" - }, - "ns.foo#snake_case": { - "type": "string" - }, - "ns.foo#Structure": { - "type": "structure", - "members": { - "lowerCamelCase": { - "target": "ns.foo#Foo" - }, - "snake_case": { - "target": "ns.foo#Foo" - } - } - }, - "foo.protocols#fooJson1_1": { - "type": "structure", - "members": { - "foo": { - "target": "smithy.api#String" - } - }, - "traits": { - "smithy.api#trait": { - "selector": "service" - }, - "smithy.api#protocolDefinition": { - "traits": [ - "smithy.api#jsonName" - ] - } - } - }, - "foo.auth#v1_1": { - "type": "structure", - "members": { - "name": { - "target": "smithy.api#String" - } - }, - "traits": { - "smithy.api#trait": { - "selector": "service" - }, - "smithy.api#authDefinition": {} - } - } - }, - "metadata": { - "validators": [ - { - "name": "CamelCase", - "id": "DefaultCamelCase" - } - ] - } -} diff --git a/smithy-linters/src/test/resources/software/amazon/smithy/linters/errorfiles/camel-case-validator-defaults-test-upper.errors b/smithy-linters/src/test/resources/software/amazon/smithy/linters/errorfiles/camel-case-validator-defaults-test-upper.errors deleted file mode 100644 index 0c64171f861..00000000000 --- a/smithy-linters/src/test/resources/software/amazon/smithy/linters/errorfiles/camel-case-validator-defaults-test-upper.errors +++ /dev/null @@ -1,6 +0,0 @@ -[DANGER] ns.foo#InvalidTrait: string trait definition, `InvalidTrait`, is not lower camel case | DefaultCamelCase -[DANGER] ns.foo#bam: string shape name, `bam`, is not upper camel case | DefaultCamelCase -[DANGER] ns.foo#snake_case: string shape name, `snake_case`, is not upper camel case | DefaultCamelCase -[DANGER] ns.foo#Structure$snake_case: Member shape member name, `snake_case`, is not consistent camel case. (Member names must all use the same type of camel case) | DefaultCamelCase -[DANGER] ns.foo#upperStructureTrait$snake_case: Member shape member name, `snake_case`, is not consistent camel case. (Member names must all use the same type of camel case) | DefaultCamelCase -[DANGER] ns.foo#Structure$lowerCamelCase: Member shape member name, `lowerCamelCase`, is not consistent camel case. (Member names must all use the same type of camel case) | DefaultCamelCase diff --git a/smithy-linters/src/test/resources/software/amazon/smithy/linters/errorfiles/camel-case-validator-defaults-test-upper.json b/smithy-linters/src/test/resources/software/amazon/smithy/linters/errorfiles/camel-case-validator-defaults-test-upper.json deleted file mode 100644 index dee5c116fc4..00000000000 --- a/smithy-linters/src/test/resources/software/amazon/smithy/linters/errorfiles/camel-case-validator-defaults-test-upper.json +++ /dev/null @@ -1,103 +0,0 @@ -{ - "smithy": "1.0", - "shapes": { - "ns.foo#InvalidTrait": { - "type": "string", - "traits": { - "smithy.api#trait": {} - } - }, - "ns.foo#validTrait": { - "type": "string", - "traits": { - "smithy.api#trait": {} - } - }, - "ns.foo#lowerStructureTrait": { - "type": "structure", - "traits": { - "smithy.api#trait": {} - } - }, - "ns.foo#upperStructureTrait": { - "type": "structure", - "members": { - "UpperCamelCase": { - "target": "ns.foo#Foo" - }, - "snake_case": { - "target": "ns.foo#Foo" - } - }, - "traits": { - "smithy.api#trait": {} - } - }, - "ns.foo#Foo": { - "type": "string" - }, - "ns.foo#BazBar": { - "type": "string" - }, - "ns.foo#bam": { - "type": "string" - }, - "ns.foo#snake_case": { - "type": "string" - }, - "ns.foo#Structure": { - "type": "structure", - "members": { - "lowerCamelCase": { - "target": "ns.foo#Foo" - }, - "UpperCamelCase": { - "target": "ns.foo#Foo" - }, - "snake_case": { - "target": "ns.foo#Foo" - } - } - }, - "foo.protocols#fooJson1_1": { - "type": "structure", - "members": { - "Foo": { - "target": "smithy.api#String" - } - }, - "traits": { - "smithy.api#trait": { - "selector": "service" - }, - "smithy.api#protocolDefinition": { - "traits": [ - "smithy.api#jsonName" - ] - } - } - }, - "foo.auth#v1_1": { - "type": "structure", - "members": { - "Name": { - "target": "smithy.api#String" - } - }, - "traits": { - "smithy.api#trait": { - "selector": "service" - }, - "smithy.api#authDefinition": {} - } - } - }, - "metadata": { - "validators": [ - { - "name": "CamelCase", - "id": "DefaultCamelCase" - } - ] - } -} diff --git a/smithy-linters/src/test/resources/software/amazon/smithy/linters/errorfiles/camel-case-validator-defaults-test.errors b/smithy-linters/src/test/resources/software/amazon/smithy/linters/errorfiles/camel-case-validator-defaults-test.errors index 4de02fe50b5..1a8c81b3c62 100644 --- a/smithy-linters/src/test/resources/software/amazon/smithy/linters/errorfiles/camel-case-validator-defaults-test.errors +++ b/smithy-linters/src/test/resources/software/amazon/smithy/linters/errorfiles/camel-case-validator-defaults-test.errors @@ -3,12 +3,16 @@ [DANGER] ns.foo#bam: string shape name, `bam`, is not upper camel case | LowerCamelCase [DANGER] ns.foo#snake_case: string shape name, `snake_case`, is not upper camel case | LowerCamelCase [DANGER] ns.foo#InvalidTrait: string trait definition, `InvalidTrait`, is not lower camel case | LowerCamelCase -[DANGER] ns.foo#InvalidTrait: string trait definition, `InvalidTrait`, is not lower camel case | UpperCamelCase +[DANGER] ns.bar#upperStructureTrait$UpperCamelCase: Member shape member name, `UpperCamelCase`, is not lower camel case. (Member names must all use the same type of camel case) | LowerCamelCase +[DANGER] ns.bar#upperStructureTrait$SecondUpperCamelCase: Member shape member name, `SecondUpperCamelCase`, is not lower camel case. (Member names must all use the same type of camel case) | LowerCamelCase [DANGER] ns.foo#upperStructureTrait$UpperCamelCase: Member shape member name, `UpperCamelCase`, is not lower camel case. (Member names must all use the same type of camel case) | LowerCamelCase [DANGER] ns.foo#upperStructureTrait$snake_case: Member shape member name, `snake_case`, is not lower camel case. (Member names must all use the same type of camel case) | LowerCamelCase [DANGER] ns.foo#Structure$SecondUpperCamelCase: Member shape member name, `SecondUpperCamelCase`, is not lower camel case. (Member names must all use the same type of camel case) | LowerCamelCase [DANGER] ns.foo#Structure$ThirdUpperCamelCase: Member shape member name, `ThirdUpperCamelCase`, is not lower camel case. (Member names must all use the same type of camel case) | LowerCamelCase [DANGER] ns.foo#Structure$FourthUpperCamelCase: Member shape member name, `FourthUpperCamelCase`, is not lower camel case. (Member names must all use the same type of camel case) | LowerCamelCase +[DANGER] ns.baz#lowerStructureTrait$UpperCamelCase: Member shape member name, `UpperCamelCase`, is not lower camel case. (Member names must all use the same type of camel case) | LowerCamelCase + +[DANGER] ns.foo#InvalidTrait: string trait definition, `InvalidTrait`, is not lower camel case | UpperCamelCase [DANGER] ns.foo#Structure$lowerCamelCase: Member shape member name, `lowerCamelCase`, is not upper camel case. (Member names must all use the same type of camel case) | UpperCamelCase [DANGER] ns.foo#Structure$snake_case: Member shape member name, `snake_case`, is not upper camel case. (Member names must all use the same type of camel case) | UpperCamelCase [DANGER] ns.foo#bam: string shape name, `bam`, is not upper camel case | UpperCamelCase @@ -17,12 +21,16 @@ [DANGER] ns.foo#lowerStructureTrait$lowerCamelCase: Member shape member name, `lowerCamelCase`, is not upper camel case. (Member names must all use the same type of camel case) | UpperCamelCase [DANGER] foo.protocols#fooJson1_1$foo: Member shape member name, `foo`, is not upper camel case. (Member names must all use the same type of camel case) | UpperCamelCase [DANGER] foo.auth#v1_1$name: Member shape member name, `name`, is not upper camel case. (Member names must all use the same type of camel case) | UpperCamelCase +[DANGER] ns.bar#upperStructureTrait$lowerCamelCase: Member shape member name, `lowerCamelCase`, is not upper camel case. (Member names must all use the same type of camel case) | UpperCamelCase +[DANGER] ns.baz#lowerStructureTrait$lowerCamelCase: Member shape member name, `lowerCamelCase`, is not upper camel case. (Member names must all use the same type of camel case) | UpperCamelCase +[DANGER] ns.baz#lowerStructureTrait$secondLowerCamelCase: Member shape member name, `secondLowerCamelCase`, is not upper camel case. (Member names must all use the same type of camel case) | UpperCamelCase + [DANGER] ns.foo#InvalidTrait: string trait definition, `InvalidTrait`, is not lower camel case | DefaultCamelCase +[DANGER] ns.foo#upperStructureTrait$UpperCamelCase: Member shape member name, `UpperCamelCase`, is not consistent camel case. (Member names must all use the same type of camel case) | DefaultCamelCase [DANGER] ns.foo#upperStructureTrait$snake_case: Member shape member name, `snake_case`, is not consistent camel case. (Member names must all use the same type of camel case) | DefaultCamelCase +[DANGER] ns.bar#upperStructureTrait$lowerCamelCase: Member shape member name, `lowerCamelCase`, is not consistent camel case. (Member names must all use the same type of camel case) | DefaultCamelCase +[DANGER] ns.baz#lowerStructureTrait$UpperCamelCase: Member shape member name, `UpperCamelCase`, is not consistent camel case. (Member names must all use the same type of camel case) | DefaultCamelCase [DANGER] ns.foo#bam: string shape name, `bam`, is not upper camel case | DefaultCamelCase [DANGER] ns.foo#snake_case: string shape name, `snake_case`, is not upper camel case | DefaultCamelCase -[DANGER] ns.foo#Structure$snake_case: Member shape member name, `snake_case`, is not consistent camel case. (Member names must all use the same type of camel case) | DefaultCamelCase -[DANGER] ns.foo#lowerStructureTrait$lowerCamelCase: Member shape member name, `lowerCamelCase`, is not consistent camel case. (Member names must all use the same type of camel case) | DefaultCamelCase [DANGER] ns.foo#Structure$lowerCamelCase: Member shape member name, `lowerCamelCase`, is not consistent camel case. (Member names must all use the same type of camel case) | DefaultCamelCase -[DANGER] foo.protocols#fooJson1_1$foo: Member shape member name, `foo`, is not consistent camel case. (Member names must all use the same type of camel case) | DefaultCamelCase -[DANGER] foo.auth#v1_1$name: Member shape member name, `name`, is not consistent camel case. (Member names must all use the same type of camel case) | DefaultCamelCase +[DANGER] ns.foo#Structure$snake_case: Member shape member name, `snake_case`, is not consistent camel case. (Member names must all use the same type of camel case) | DefaultCamelCase diff --git a/smithy-linters/src/test/resources/software/amazon/smithy/linters/errorfiles/camel-case-validator-defaults-test.json b/smithy-linters/src/test/resources/software/amazon/smithy/linters/errorfiles/camel-case-validator-defaults-test.json index 1500e3cfb62..ee8ff103859 100644 --- a/smithy-linters/src/test/resources/software/amazon/smithy/linters/errorfiles/camel-case-validator-defaults-test.json +++ b/smithy-linters/src/test/resources/software/amazon/smithy/linters/errorfiles/camel-case-validator-defaults-test.json @@ -38,6 +38,40 @@ "smithy.api#trait": {} } }, + "ns.bar#upperStructureTrait": { + "type": "structure", + "members": { + "UpperCamelCase": { + "target": "ns.foo#Foo" + }, + "SecondUpperCamelCase": { + "target": "ns.foo#Foo" + }, + "lowerCamelCase": { + "target": "ns.foo#Foo" + } + }, + "traits": { + "smithy.api#trait": {} + } + }, + "ns.baz#lowerStructureTrait": { + "type": "structure", + "members": { + "lowerCamelCase": { + "target": "ns.foo#Foo" + }, + "secondLowerCamelCase": { + "target": "ns.foo#Foo" + }, + "UpperCamelCase": { + "target": "ns.foo#Foo" + } + }, + "traits": { + "smithy.api#trait": {} + } + }, "ns.foo#Foo": { "type": "string" }, @@ -63,13 +97,13 @@ "target": "ns.foo#Foo" }, "ThirdUpperCamelCase": { - "target": "ns.foo#Foo" + "target": "ns.foo#BazBar" }, "FourthUpperCamelCase": { - "target": "ns.foo#Foo" + "target": "ns.foo#bam" }, "snake_case": { - "target": "ns.foo#Foo" + "target": "ns.foo#snake_case" } } }, @@ -104,6 +138,23 @@ }, "smithy.api#authDefinition": {} } + }, + "ns.foo#MyService": { + "type": "service", + "operations": [ + { + "target": "ns.foo#MyOperation" + } + ] + }, + "ns.foo#MyOperation": { + "type": "operation", + "input": { + "target": "ns.foo#Structure" + }, + "output": { + "target": "ns.foo#Structure" + } } }, "metadata": { From 7f653c0fa323d699ae1abfaea86e8bb0148b81fe Mon Sep 17 00:00:00 2001 From: Richard Chen Date: Fri, 13 May 2022 17:01:49 -0700 Subject: [PATCH 4/5] Better validation message, perform validations per service closure --- .../smithy/linters/CamelCaseValidator.java | 44 ++++++++++------ ...l-case-validator-default-lower-test.errors | 2 - ...l-case-validator-default-lower-test.smithy | 36 ------------- ...l-case-validator-default-upper-test.errors | 6 ++- ...l-case-validator-default-upper-test.smithy | 36 ++++++++++--- .../camel-case-validator-defaults-test.errors | 52 ++++++++++--------- 6 files changed, 87 insertions(+), 89 deletions(-) delete mode 100644 smithy-linters/src/test/resources/software/amazon/smithy/linters/errorfiles/camel-case-validator-default-lower-test.errors delete mode 100644 smithy-linters/src/test/resources/software/amazon/smithy/linters/errorfiles/camel-case-validator-default-lower-test.smithy diff --git a/smithy-linters/src/main/java/software/amazon/smithy/linters/CamelCaseValidator.java b/smithy-linters/src/main/java/software/amazon/smithy/linters/CamelCaseValidator.java index 8108b12ffd2..f04a0cad06a 100644 --- a/smithy-linters/src/main/java/software/amazon/smithy/linters/CamelCaseValidator.java +++ b/smithy-linters/src/main/java/software/amazon/smithy/linters/CamelCaseValidator.java @@ -107,7 +107,7 @@ Pattern getRegex() { @Override public String toString() { - return "consistent"; + return "auto"; } }; @@ -157,32 +157,35 @@ public List validate(Model model) { shape.getType(), shape.getId().getName()))) .forEach(events::add); - // First validate all member shapes connected to services - Set serviceClosure = new HashSet<>(); + // First validate each service's closure's member shape member names + Set seenShapes = new HashSet<>(); for (ServiceShape serviceShape : model.getServiceShapes()) { + Set serviceClosure = new HashSet<>(); Walker walker = new Walker(model); walker.iterateShapes(serviceShape).forEachRemaining(serviceClosure::add); + List memberShapes = serviceClosure.stream() + .filter(Shape::isMemberShape) + .map(shape -> (MemberShape) shape) + .collect(Collectors.toList()); + events.addAll(validateCamelCasing(memberShapes, serviceShape.getId().getName())); + seenShapes.addAll(memberShapes); } - Stream memberShapesFromServices = serviceClosure.stream() - .filter(Shape::isMemberShape) - .map(shape -> (MemberShape) shape); - - events.addAll(validateCamelCasing(memberShapesFromServices.collect(Collectors.toList()))); // Next get all other member shapes (ex. trait shape members) and validate per namespace grouping Map> memberShapesByNamespace = model.toSet(MemberShape.class).stream() - .filter(memberShape -> !serviceClosure.contains(memberShape)) + .filter(memberShape -> !seenShapes.contains(memberShape)) .collect(Collectors.groupingBy( memberShape -> memberShape.getContainer().getNamespace())); - for (List memberShapeGrouping : memberShapesByNamespace.values()) { - events.addAll(validateCamelCasing(memberShapeGrouping)); + for (Map.Entry> memberShapeGrouping : memberShapesByNamespace.entrySet()) { + events.addAll(validateCamelCasing(memberShapeGrouping.getValue(), + memberShapeGrouping.getKey() + " namespace")); } return events; } - private List validateCamelCasing(List memberShapes) { + private List validateCamelCasing(List memberShapes, String scope) { int upperCamelMemberNamesCount = 0; int lowerCamelMemberNamesCount = 0; Set nonUpperCamelMemberShapes = new HashSet<>(); @@ -203,20 +206,27 @@ private List validateCamelCasing(List memberShapes // Member shapes are expected to be either upper or lower, depending on the config (and in AUTO mode, the model) Set violatingMemberShapes = new HashSet<>(); + String memberNameHandling = config.getMemberNames().toString(); if (MemberNameHandling.AUTO.equals(config.getMemberNames())) { - violatingMemberShapes = upperCamelMemberNamesCount > lowerCamelMemberNamesCount - ? nonUpperCamelMemberShapes : nonLowerCamelMemberShapes; + if (upperCamelMemberNamesCount > lowerCamelMemberNamesCount) { + violatingMemberShapes = nonUpperCamelMemberShapes; + memberNameHandling = MemberNameHandling.UPPER.toString(); + } else { + violatingMemberShapes = nonLowerCamelMemberShapes; + memberNameHandling = MemberNameHandling.LOWER.toString(); + } } else if (MemberNameHandling.UPPER.equals(config.getMemberNames())) { violatingMemberShapes = nonUpperCamelMemberShapes; } else if (MemberNameHandling.LOWER.equals(config.getMemberNames())) { violatingMemberShapes = nonLowerCamelMemberShapes; } + String finalMemberNameHandling = memberNameHandling; return violatingMemberShapes.stream() .map(shape -> danger(shape, format( - "Member shape member name, `%s`, is not %s camel case. " - + "(Member names must all use the same type of camel case)", - shape.getMemberName(), config.getMemberNames()))) + "Member shape member name, `%s`, is not %s camel case;" + + " members in the %s must all use %s camel case.", + shape.getMemberName(), finalMemberNameHandling, scope, finalMemberNameHandling))) .collect(Collectors.toList()); } } diff --git a/smithy-linters/src/test/resources/software/amazon/smithy/linters/errorfiles/camel-case-validator-default-lower-test.errors b/smithy-linters/src/test/resources/software/amazon/smithy/linters/errorfiles/camel-case-validator-default-lower-test.errors deleted file mode 100644 index 93ebd8113db..00000000000 --- a/smithy-linters/src/test/resources/software/amazon/smithy/linters/errorfiles/camel-case-validator-default-lower-test.errors +++ /dev/null @@ -1,2 +0,0 @@ -[DANGER] smithy.example#GetLatestServiceResponse$UpperCamel: Member shape member name, `UpperCamel`, is not consistent camel case. (Member names must all use the same type of camel case) | DefaultCamelCase -[DANGER] smithy.example#MyStructure$snake_case: Member shape member name, `snake_case`, is not consistent camel case. (Member names must all use the same type of camel case) | DefaultCamelCase diff --git a/smithy-linters/src/test/resources/software/amazon/smithy/linters/errorfiles/camel-case-validator-default-lower-test.smithy b/smithy-linters/src/test/resources/software/amazon/smithy/linters/errorfiles/camel-case-validator-default-lower-test.smithy deleted file mode 100644 index d91e1aaca16..00000000000 --- a/smithy-linters/src/test/resources/software/amazon/smithy/linters/errorfiles/camel-case-validator-default-lower-test.smithy +++ /dev/null @@ -1,36 +0,0 @@ -$version: "1.0" - -metadata validators = [ - {name: "CamelCase", - id: "DefaultCamelCase"} -] - -namespace smithy.example - -service Example { - version: "2020-09-21", - operations: [GetLatestService], -} - -operation GetLatestService { - input: GetLatestServiceRequest, - output: GetLatestServiceResponse, - errors: [], -} - -structure GetLatestServiceRequest { - lowerCamel: MyString, - secondLowerCamel: MyString, - thirdLowerCamel: MyString, - fourthLowerCamel: MyStructure -} - -structure GetLatestServiceResponse { - UpperCamel: MyString -} - -structure MyStructure { - snake_case: MyString -} - -string MyString diff --git a/smithy-linters/src/test/resources/software/amazon/smithy/linters/errorfiles/camel-case-validator-default-upper-test.errors b/smithy-linters/src/test/resources/software/amazon/smithy/linters/errorfiles/camel-case-validator-default-upper-test.errors index 5720c19b9a8..5da3eb3ae16 100644 --- a/smithy-linters/src/test/resources/software/amazon/smithy/linters/errorfiles/camel-case-validator-default-upper-test.errors +++ b/smithy-linters/src/test/resources/software/amazon/smithy/linters/errorfiles/camel-case-validator-default-upper-test.errors @@ -1,2 +1,4 @@ -[DANGER] smithy.example#GetLatestServiceResponse$lowerCamel: Member shape member name, `lowerCamel`, is not consistent camel case. (Member names must all use the same type of camel case) | DefaultCamelCase -[DANGER] smithy.example#MyStructure$snake_case: Member shape member name, `snake_case`, is not consistent camel case. (Member names must all use the same type of camel case) | DefaultCamelCase +[DANGER] smithy.example#UpperOperationResponse$lowerCamel: Member shape member name, `lowerCamel`, is not upper camel case; members in the UpperService must all use upper camel case. | DefaultCamelCase +[DANGER] smithy.example#LowerOperationResponse$UpperCamel: Member shape member name, `UpperCamel`, is not lower camel case; members in the LowerService must all use lower camel case. | DefaultCamelCase +[DANGER] smithy.example#MyStructure$snake_case: Member shape member name, `snake_case`, is not lower camel case; members in the LowerService must all use lower camel case. | DefaultCamelCase +[DANGER] smithy.example#MyStructure$snake_case: Member shape member name, `snake_case`, is not upper camel case; members in the UpperService must all use upper camel case. | DefaultCamelCase diff --git a/smithy-linters/src/test/resources/software/amazon/smithy/linters/errorfiles/camel-case-validator-default-upper-test.smithy b/smithy-linters/src/test/resources/software/amazon/smithy/linters/errorfiles/camel-case-validator-default-upper-test.smithy index 94fe61b94e0..6e2fa3d2690 100644 --- a/smithy-linters/src/test/resources/software/amazon/smithy/linters/errorfiles/camel-case-validator-default-upper-test.smithy +++ b/smithy-linters/src/test/resources/software/amazon/smithy/linters/errorfiles/camel-case-validator-default-upper-test.smithy @@ -7,28 +7,50 @@ metadata validators = [ namespace smithy.example -service Example { +service UpperService { version: "2020-09-21", - operations: [GetLatestService], + operations: [UpperOperation], } -operation GetLatestService { - input: GetLatestServiceRequest, - output: GetLatestServiceResponse, +operation UpperOperation { + input: UpperOperationRequest, + output: UpperOperationResponse, errors: [], } -structure GetLatestServiceRequest { +structure UpperOperationRequest { UpperCamel: MyString, SecondUpperCamel: MyString, ThirdUpperCamel: MyString, FourthUpperCamel: MyStructure } -structure GetLatestServiceResponse { +structure UpperOperationResponse { lowerCamel: MyString } +service LowerService { + version: "2020-09-21", + operations: [LowerOperation], +} + +operation LowerOperation { + input: LowerOperationRequest, + output: LowerOperationResponse, + errors: [], +} + +structure LowerOperationRequest { + lowerCamel: MyString, + secondLowerCamel: MyString, + thirdLowerCamel: MyString, + fourthLowerCamel: MyStructure +} + +structure LowerOperationResponse { + UpperCamel: MyString +} + structure MyStructure { snake_case: MyString } diff --git a/smithy-linters/src/test/resources/software/amazon/smithy/linters/errorfiles/camel-case-validator-defaults-test.errors b/smithy-linters/src/test/resources/software/amazon/smithy/linters/errorfiles/camel-case-validator-defaults-test.errors index 1a8c81b3c62..f6b8fb92916 100644 --- a/smithy-linters/src/test/resources/software/amazon/smithy/linters/errorfiles/camel-case-validator-defaults-test.errors +++ b/smithy-linters/src/test/resources/software/amazon/smithy/linters/errorfiles/camel-case-validator-defaults-test.errors @@ -1,36 +1,38 @@ -[DANGER] ns.foo#Structure$UpperCamelCase: Member shape member name, `UpperCamelCase`, is not lower camel case. (Member names must all use the same type of camel case) | LowerCamelCase -[DANGER] ns.foo#Structure$snake_case: Member shape member name, `snake_case`, is not lower camel case. (Member names must all use the same type of camel case) | LowerCamelCase [DANGER] ns.foo#bam: string shape name, `bam`, is not upper camel case | LowerCamelCase [DANGER] ns.foo#snake_case: string shape name, `snake_case`, is not upper camel case | LowerCamelCase [DANGER] ns.foo#InvalidTrait: string trait definition, `InvalidTrait`, is not lower camel case | LowerCamelCase -[DANGER] ns.bar#upperStructureTrait$UpperCamelCase: Member shape member name, `UpperCamelCase`, is not lower camel case. (Member names must all use the same type of camel case) | LowerCamelCase -[DANGER] ns.bar#upperStructureTrait$SecondUpperCamelCase: Member shape member name, `SecondUpperCamelCase`, is not lower camel case. (Member names must all use the same type of camel case) | LowerCamelCase -[DANGER] ns.foo#upperStructureTrait$UpperCamelCase: Member shape member name, `UpperCamelCase`, is not lower camel case. (Member names must all use the same type of camel case) | LowerCamelCase -[DANGER] ns.foo#upperStructureTrait$snake_case: Member shape member name, `snake_case`, is not lower camel case. (Member names must all use the same type of camel case) | LowerCamelCase -[DANGER] ns.foo#Structure$SecondUpperCamelCase: Member shape member name, `SecondUpperCamelCase`, is not lower camel case. (Member names must all use the same type of camel case) | LowerCamelCase -[DANGER] ns.foo#Structure$ThirdUpperCamelCase: Member shape member name, `ThirdUpperCamelCase`, is not lower camel case. (Member names must all use the same type of camel case) | LowerCamelCase -[DANGER] ns.foo#Structure$FourthUpperCamelCase: Member shape member name, `FourthUpperCamelCase`, is not lower camel case. (Member names must all use the same type of camel case) | LowerCamelCase -[DANGER] ns.baz#lowerStructureTrait$UpperCamelCase: Member shape member name, `UpperCamelCase`, is not lower camel case. (Member names must all use the same type of camel case) | LowerCamelCase +[DANGER] ns.foo#upperStructureTrait$UpperCamelCase: Member shape member name, `UpperCamelCase`, is not lower camel case; members in the ns.foo namespace must all use lower camel case. | LowerCamelCase +[DANGER] ns.bar#upperStructureTrait$UpperCamelCase: Member shape member name, `UpperCamelCase`, is not lower camel case; members in the ns.bar namespace must all use lower camel case. | LowerCamelCase +[DANGER] ns.bar#upperStructureTrait$SecondUpperCamelCase: Member shape member name, `SecondUpperCamelCase`, is not lower camel case; members in the ns.bar namespace must all use lower camel case. | LowerCamelCase +[DANGER] ns.foo#upperStructureTrait$snake_case: Member shape member name, `snake_case`, is not lower camel case; members in the ns.foo namespace must all use lower camel case. | LowerCamelCase +[DANGER] ns.baz#lowerStructureTrait$UpperCamelCase: Member shape member name, `UpperCamelCase`, is not lower camel case; members in the ns.baz namespace must all use lower camel case. | LowerCamelCase +[DANGER] ns.foo#Structure$UpperCamelCase: Member shape member name, `UpperCamelCase`, is not lower camel case; members in the MyService must all use lower camel case. | LowerCamelCase +[DANGER] ns.foo#Structure$SecondUpperCamelCase: Member shape member name, `SecondUpperCamelCase`, is not lower camel case; members in the MyService must all use lower camel case. | LowerCamelCase +[DANGER] ns.foo#Structure$ThirdUpperCamelCase: Member shape member name, `ThirdUpperCamelCase`, is not lower camel case; members in the MyService must all use lower camel case. | LowerCamelCase +[DANGER] ns.foo#Structure$FourthUpperCamelCase: Member shape member name, `FourthUpperCamelCase`, is not lower camel case; members in the MyService must all use lower camel case. | LowerCamelCase +[DANGER] ns.foo#Structure$snake_case: Member shape member name, `snake_case`, is not lower camel case; members in the MyService must all use lower camel case. | LowerCamelCase + [DANGER] ns.foo#InvalidTrait: string trait definition, `InvalidTrait`, is not lower camel case | UpperCamelCase -[DANGER] ns.foo#Structure$lowerCamelCase: Member shape member name, `lowerCamelCase`, is not upper camel case. (Member names must all use the same type of camel case) | UpperCamelCase -[DANGER] ns.foo#Structure$snake_case: Member shape member name, `snake_case`, is not upper camel case. (Member names must all use the same type of camel case) | UpperCamelCase [DANGER] ns.foo#bam: string shape name, `bam`, is not upper camel case | UpperCamelCase [DANGER] ns.foo#snake_case: string shape name, `snake_case`, is not upper camel case | UpperCamelCase -[DANGER] ns.foo#upperStructureTrait$snake_case: Member shape member name, `snake_case`, is not upper camel case. (Member names must all use the same type of camel case) | UpperCamelCase -[DANGER] ns.foo#lowerStructureTrait$lowerCamelCase: Member shape member name, `lowerCamelCase`, is not upper camel case. (Member names must all use the same type of camel case) | UpperCamelCase -[DANGER] foo.protocols#fooJson1_1$foo: Member shape member name, `foo`, is not upper camel case. (Member names must all use the same type of camel case) | UpperCamelCase -[DANGER] foo.auth#v1_1$name: Member shape member name, `name`, is not upper camel case. (Member names must all use the same type of camel case) | UpperCamelCase -[DANGER] ns.bar#upperStructureTrait$lowerCamelCase: Member shape member name, `lowerCamelCase`, is not upper camel case. (Member names must all use the same type of camel case) | UpperCamelCase -[DANGER] ns.baz#lowerStructureTrait$lowerCamelCase: Member shape member name, `lowerCamelCase`, is not upper camel case. (Member names must all use the same type of camel case) | UpperCamelCase -[DANGER] ns.baz#lowerStructureTrait$secondLowerCamelCase: Member shape member name, `secondLowerCamelCase`, is not upper camel case. (Member names must all use the same type of camel case) | UpperCamelCase +[DANGER] ns.foo#lowerStructureTrait$lowerCamelCase: Member shape member name, `lowerCamelCase`, is not upper camel case; members in the ns.foo namespace must all use upper camel case. | UpperCamelCase +[DANGER] ns.foo#upperStructureTrait$snake_case: Member shape member name, `snake_case`, is not upper camel case; members in the ns.foo namespace must all use upper camel case. | UpperCamelCase +[DANGER] ns.bar#upperStructureTrait$lowerCamelCase: Member shape member name, `lowerCamelCase`, is not upper camel case; members in the ns.bar namespace must all use upper camel case. | UpperCamelCase +[DANGER] ns.baz#lowerStructureTrait$lowerCamelCase: Member shape member name, `lowerCamelCase`, is not upper camel case; members in the ns.baz namespace must all use upper camel case. | UpperCamelCase +[DANGER] ns.baz#lowerStructureTrait$secondLowerCamelCase: Member shape member name, `secondLowerCamelCase`, is not upper camel case; members in the ns.baz namespace must all use upper camel case. | UpperCamelCase +[DANGER] ns.foo#Structure$snake_case: Member shape member name, `snake_case`, is not upper camel case; members in the MyService must all use upper camel case. | UpperCamelCase +[DANGER] foo.protocols#fooJson1_1$foo: Member shape member name, `foo`, is not upper camel case; members in the foo.protocols namespace must all use upper camel case. | UpperCamelCase +[DANGER] foo.auth#v1_1$name: Member shape member name, `name`, is not upper camel case; members in the foo.auth namespace must all use upper camel case. | UpperCamelCase +[DANGER] ns.foo#Structure$lowerCamelCase: Member shape member name, `lowerCamelCase`, is not upper camel case; members in the MyService must all use upper camel case. | UpperCamelCase + [DANGER] ns.foo#InvalidTrait: string trait definition, `InvalidTrait`, is not lower camel case | DefaultCamelCase -[DANGER] ns.foo#upperStructureTrait$UpperCamelCase: Member shape member name, `UpperCamelCase`, is not consistent camel case. (Member names must all use the same type of camel case) | DefaultCamelCase -[DANGER] ns.foo#upperStructureTrait$snake_case: Member shape member name, `snake_case`, is not consistent camel case. (Member names must all use the same type of camel case) | DefaultCamelCase -[DANGER] ns.bar#upperStructureTrait$lowerCamelCase: Member shape member name, `lowerCamelCase`, is not consistent camel case. (Member names must all use the same type of camel case) | DefaultCamelCase -[DANGER] ns.baz#lowerStructureTrait$UpperCamelCase: Member shape member name, `UpperCamelCase`, is not consistent camel case. (Member names must all use the same type of camel case) | DefaultCamelCase [DANGER] ns.foo#bam: string shape name, `bam`, is not upper camel case | DefaultCamelCase [DANGER] ns.foo#snake_case: string shape name, `snake_case`, is not upper camel case | DefaultCamelCase -[DANGER] ns.foo#Structure$lowerCamelCase: Member shape member name, `lowerCamelCase`, is not consistent camel case. (Member names must all use the same type of camel case) | DefaultCamelCase -[DANGER] ns.foo#Structure$snake_case: Member shape member name, `snake_case`, is not consistent camel case. (Member names must all use the same type of camel case) | DefaultCamelCase +[DANGER] ns.foo#upperStructureTrait$snake_case: Member shape member name, `snake_case`, is not lower camel case; members in the ns.foo namespace must all use lower camel case. | DefaultCamelCase +[DANGER] ns.foo#upperStructureTrait$UpperCamelCase: Member shape member name, `UpperCamelCase`, is not lower camel case; members in the ns.foo namespace must all use lower camel case. | DefaultCamelCase +[DANGER] ns.bar#upperStructureTrait$lowerCamelCase: Member shape member name, `lowerCamelCase`, is not upper camel case; members in the ns.bar namespace must all use upper camel case. | DefaultCamelCase +[DANGER] ns.baz#lowerStructureTrait$UpperCamelCase: Member shape member name, `UpperCamelCase`, is not lower camel case; members in the ns.baz namespace must all use lower camel case. | DefaultCamelCase +[DANGER] ns.foo#Structure$lowerCamelCase: Member shape member name, `lowerCamelCase`, is not upper camel case; members in the MyService must all use upper camel case. | DefaultCamelCase +[DANGER] ns.foo#Structure$snake_case: Member shape member name, `snake_case`, is not upper camel case; members in the MyService must all use upper camel case. | DefaultCamelCase From 84be42337f4c48b375072b15207b66b42393d3c8 Mon Sep 17 00:00:00 2001 From: Richard Chen Date: Fri, 13 May 2022 17:36:17 -0700 Subject: [PATCH 5/5] remove unused import --- .../java/software/amazon/smithy/linters/CamelCaseValidator.java | 1 - 1 file changed, 1 deletion(-) diff --git a/smithy-linters/src/main/java/software/amazon/smithy/linters/CamelCaseValidator.java b/smithy-linters/src/main/java/software/amazon/smithy/linters/CamelCaseValidator.java index f04a0cad06a..6760a963e1b 100644 --- a/smithy-linters/src/main/java/software/amazon/smithy/linters/CamelCaseValidator.java +++ b/smithy-linters/src/main/java/software/amazon/smithy/linters/CamelCaseValidator.java @@ -24,7 +24,6 @@ import java.util.Set; import java.util.regex.Pattern; import java.util.stream.Collectors; -import java.util.stream.Stream; import software.amazon.smithy.model.Model; import software.amazon.smithy.model.neighbor.Walker; import software.amazon.smithy.model.node.NodeMapper;