Skip to content

Commit

Permalink
Merge pull request #2 from kirpi4ik/v1.2
Browse files Browse the repository at this point in the history
V1.2
  • Loading branch information
kirpi4ik authored Dec 6, 2022
2 parents c2ce604 + 971d69f commit eea1c40
Show file tree
Hide file tree
Showing 10 changed files with 73 additions and 24 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ build/
### IntelliJ IDEA ###
.DS_Store
.idea

### VSC
bin
19 changes: 12 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

[![License](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)

[![Version](https://badge.fury.io/gh/kirpi4ik%2Fgraphql-java-linter.svg)](https://badge.fury.io/gh/kirpi4ik%2Fgraphql-java-linter)
[![GitHub Release](https://img.shields.io/github/v/release/kirpi4ik/graphql-java-linter?include_prereleases)]()
[![Maven Central](https://img.shields.io/maven-central/v/org.myhab.tools/graphql-java-linter)]()
[![Build project](https://github.com/kirpi4ik/graphql-java-linter/actions/workflows/gradle.yml/badge.svg)](https://github.com/kirpi4ik/graphql-java-linter/actions/workflows/gradle.yml)
[![GitHub Release](https://img.shields.io/github/v/release/kirpi4ik/graphql-java-linter?include_prereleases)](https://github.com/kirpi4ik/graphql-java-linter/releases)
[![Maven Central](https://img.shields.io/maven-central/v/org.myhab.tools/graphql-java-linter)](https://search.maven.org/artifact/org.myhab.tools/graphql-java-linter)
[![Nexus snapshot](https://img.shields.io/nexus/s/org.myhab.tools/graphql-java-linter?server=https%3A%2F%2Fs01.oss.sonatype.org%2F)](https://s01.oss.sonatype.org/content/repositories/snapshots/org/myhab/tools/graphql-java-linter/)

### Usage
Expand Down Expand Up @@ -44,9 +44,9 @@ rules:
### Command line
#### Run from command line:
Download from [packages](https://github.com/kirpi4ik/graphql-java-linter/packages/1728805) the latest version.
```bash
java -jar graphql-java-linter-1.1-cli.jar linter.yaml
java -jar graphql-java-linter-1.2-cli.jar linter.yaml
```

### In CI/CD flow via unit tests
Expand All @@ -57,7 +57,7 @@ java -jar graphql-java-linter-1.1-cli.jar linter.yaml

```groovy
dependencies {
test 'org.myhab.tools:graphql-java-linter:1.1'
test 'org.myhab.tools:graphql-java-linter:1.2'
}
```

Expand All @@ -68,7 +68,7 @@ dependencies {
<dependency>
<groupId>org.myhab.tools</groupId>
<artifactId>graphql-java-linter</artifactId>
<version>1.1</version>
<version>1.2</version>
<scope>test</scope>
</dependency>
```
Expand Down Expand Up @@ -110,6 +110,11 @@ rule(["FIELD"]) {
}
}
```
File name will be used as the rule name.
Most important object/methods used during validation and available also in DSL are :
- `parent` - Parent element [[GraphQLNamedSchemaElement](https://github.com/graphql-java/graphql-java/blob/master/src/main/java/graphql/schema/GraphQLNamedSchemaElement.java)], in case of type - it will be null
- `node` - Current element [[GraphQLNamedSchemaElement](https://github.com/graphql-java/graphql-java/blob/master/src/main/java/graphql/schema/GraphQLNamedSchemaElement.java)]
- `fail(parent, node, message)` - Record the failure into execution context(validation queue will be not interrupted).

In configuration file you will have to specify folder location which contains the dsl rules

Expand Down
6 changes: 1 addition & 5 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ plugins {
}

group 'org.myhab.tools'
version '1.1'
version '1.2'

task cliJar(type: Jar) {
manifest {
Expand Down Expand Up @@ -52,9 +52,6 @@ publishing {
version = project.version

from project.components.java
artifact cliJar {
classifier "cli"
}

pom {
name = project.name
Expand Down Expand Up @@ -109,7 +106,6 @@ publishing {
signing {
useGpgCmd()
sign publishing.publications.mavenJava
sign publishing.publications.gpr
}
test {
useJUnitPlatform()
Expand Down
21 changes: 11 additions & 10 deletions src/main/groovy/graphql/linter/BasicResultHandler.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,31 @@ package graphql.linter

import graphql.linter.exception.RuleValidationError

class BasicResultHandler implements ResultHandler{
def handle(executionEnvironment, context){
class BasicResultHandler implements ResultHandler {
def handle(executionEnvironment, context) {
boolean hasErrors = context.errors.any { error -> error.value.any { it.level == FailLevel.ERROR } }
if (hasErrors) {
def failedRules = context.errors.findAll { error -> error.value.any { it.level == FailLevel.ERROR } }
throw new RuleValidationError(failedRules)
}
boolean hasWarnings = context.errors.any { error -> error.value.any { it.level == FailLevel.WARN } }
int rowLength = 160
if (hasWarnings) {
printf("#######################################################################################################################%n")
printf("################################################### FAILURES #####################################################%n")
printf("#######################################################################################################################%n")
printf "${'#' * rowLength}%n"
printf "${'#' * (rowLength / 2 - 5)} FAILURES ${'#' * (rowLength / 2 - 5)}%n"
printf "${'#' * rowLength}%n"
def failedRules = context.errors.findAll { error -> error.value.any { it.level == FailLevel.WARN } }
failedRules.each { ruleName, ruleWarn ->
printf("#---------------------------------------------------------------------------------------------------------------------#%n")
printf "# [ %-30s ] [ %-3d failures][%-6d runs] [%-4.3f sec/rule] #%n", ruleName, ruleWarn.size(), context.execution[ruleName]['count'], context.execution[ruleName]['time']
ruleWarn.each { error -> printf("# + %-100s #%n", error.message)
printf "#${'=' * (rowLength-2)}#%n"
printf "# * %-35s [ %-3d failures][%-6d runs] [%-3.3f sec/rule]${' ' * (rowLength - 87)}#%n", ruleName, ruleWarn.size(), context.execution[ruleName]['count'], context.execution[ruleName]['time']
ruleWarn.each { error -> printf("# + %-${rowLength - 19}s #%n", error.message)
}
def failWhenExceed = executionEnvironment.config['rules'][ruleName as String]?['failWhenExceed']
def failWhenExceed = executionEnvironment.config['rules'][ruleName as String] ?['failWhenExceed']
if (executionEnvironment.config['failWhenExceedWarningMax'] && (failWhenExceed && ruleWarn.size() > failWhenExceed)) {
throw new RuleValidationError("[${ruleName}] Exceeded number of failures. ${ruleWarn.size()} > ${failWhenExceed} ")
}
}
printf("#######################################################################################################################%n")
printf "${'#' * rowLength}%n"
}
}
}
10 changes: 10 additions & 0 deletions src/main/groovy/graphql/linter/registry/RulesRegistry.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package graphql.linter.registry
import graphql.linter.LinterConfiguration
import graphql.linter.rules.LintRule

import static java.util.stream.Collectors.toList

class RulesRegistry implements Registry {
private Set<LintRule> fieldRules = new HashSet<>()
private Set<LintRule> typeRules = new HashSet<>()
Expand All @@ -11,8 +13,16 @@ class RulesRegistry implements Registry {
def registryDynamic = new RulesRegistryDynamic(config)
fieldRules.addAll registryDynamic.fieldRuleSet
typeRules.addAll registryDynamic.typeRuleSet
//Allow only one rule with the same name,
//If there is already defined a DSL rule with same name, static rule will be ignored(overwritten)
def registryStatic = new RulesRegistryStatic()
if (registryStatic.fieldRuleSet.stream().anyMatch(fieldRules::contains)) {
println("WARNING: Duplicated field rules found: ${registryStatic.fieldRuleSet.stream().filter(fieldRules::contains).map(rule -> rule.name()).collect(toList())}")
}
fieldRules.addAll registryStatic.fieldRuleSet
if (registryStatic.typeRuleSet.stream().anyMatch(typeRules::contains)) {
println("WARNING: Duplicated type rules found: ${registryStatic.typeRuleSet.stream().filter(typeRules::contains).map(rule -> rule.name()).collect(toList())}")
}
typeRules.addAll registryStatic.typeRuleSet
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ class RulesRegistryStatic implements Registry {
register(ArgumentsHasDescriptions.class)
register(DeprecationHasReason.class)
register(EnumValueAllCaps.class)
register(TypeNameFirstCaps.class)
}

def register(Class<?> rule) {
Expand Down
10 changes: 10 additions & 0 deletions src/main/groovy/graphql/linter/rules/LintRule.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,14 @@ abstract class LintRule {
executionEnvironment.config.rules[name()] ?['level'] as FailLevel ?: executionEnvironment.config.level,
" ${message}")
}

@Override
boolean equals(Object obj) {
return obj instanceof LintRule && obj.name() == this.name()
}

@Override
int hashCode() {
return name().hashCode()
}
}
14 changes: 14 additions & 0 deletions src/main/groovy/graphql/linter/rules/TypeNameFirstCaps.groovy
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package graphql.linter.rules

import graphql.linter.registry.types.TypeRule
import graphql.schema.GraphQLNamedSchemaElement

@TypeRule
class TypeNameFirstCaps extends LintRule {
@Override
def validate(GraphQLNamedSchemaElement parent, GraphQLNamedSchemaElement node) {
if (!(node.name ==~ /^[A-Z].+/)) {
fail(parent, node, "Type `${node.name}` has invalid name, it should start with caps ")
}
}
}
2 changes: 1 addition & 1 deletion src/test/resources/rules/test_field_rule.groovy
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
rule(["FIELD", "TYPE"]) {
if (node.name ==~ /^[a-z].*/) {
fail(parent, node, "The fieldname `${parent.name}.${node.name}` starts with uppercase.")
fail(parent, node, "The fieldname `${parent?.name}.${node.name}` starts with uppercase.")
}
}
11 changes: 11 additions & 0 deletions src/test/resources/schema/file2.graphqls
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
extend type Query {
Camel:String
field(arg:invalidInputName):String
}

input invalidInputName {
id:String
}
type invalidTypeName{
id:String
}
enum invalidEnumName{
EN
}

0 comments on commit eea1c40

Please sign in to comment.