diff --git a/.github/algorithm-format-check.mjs b/.github/algorithm-format-check.mjs index 13a31ece9..592d721de 100644 --- a/.github/algorithm-format-check.mjs +++ b/.github/algorithm-format-check.mjs @@ -23,13 +23,16 @@ for (const filename of filenames) { { // Is it an algorithm definition? const matches = line.match(/^([a-z0-9A-Z]+)(\s*)\(([^)]*)\)(\s*):(\s*)$/); + const grammarMatches = + filename === "Section 2 -- Language.md" && + line.match(/^([A-Za-z0-9]+) :\s+((\S).*)$/); if (matches) { const [, algorithmName, ns1, _args, ns2, ns3] = matches; if (ns1 || ns2 || ns3) { console.log( `Bad whitespace in definition of ${algorithmName} in '${filename}':` ); - console.log(line); + console.dir(line); console.log(); process.exitCode = 1; } @@ -47,7 +50,7 @@ for (const filename of filenames) { console.log( `Bad algorithm ${algorithmName} step in '${filename}':` ); - console.log(step); + console.dir(step); console.log(); process.exitCode = 1; } @@ -57,7 +60,7 @@ for (const filename of filenames) { console.log( `Bad formatting for '${algorithmName}' step (does not end in '.' or ':') in '${filename}':` ); - console.log(step); + console.dir(step); console.log(); process.exitCode = 1; } @@ -65,7 +68,7 @@ for (const filename of filenames) { console.log( `Bad formatting of '${algorithmName}' step (should start with a capital) in '${filename}':` ); - console.log(step); + console.dir(step); console.log(); process.exitCode = 1; } @@ -79,7 +82,67 @@ for (const filename of filenames) { console.log( `Potential bad formatting of '${algorithmName}' step (true/false/null should be wrapped in curly braces, e.g. '{true}') in '${filename}':` ); - console.log(step); + console.dir(step); + console.log(); + process.exitCode = 1; + } + } + } else if (grammarMatches) { + // This is super loosey-goosey + const [, grammarName, rest] = grammarMatches; + if (rest.trim() === "one of") { + // Still grammar, not algorithm + continue; + } + if (rest.trim() === "" && lines[i + 1] !== "") { + console.log( + `No empty space after grammar ${grammarName} header in '${filename}'` + ); + console.log(); + process.exitCode = 1; + } + if (!lines[i + 2].startsWith("- ")) { + // Not an algorithm; probably more grammar + continue; + } + for (let j = i + 2; j < l; j++) { + const step = lines[j]; + if (!step.match(/^\s*(-|[0-9]+\.) /)) { + if (step !== "") { + console.log(`Bad grammar ${grammarName} step in '${filename}':`); + console.dir(step); + console.log(); + process.exitCode = 1; + } + break; + } + if (!step.match(/[.:]$/)) { + console.log( + `Bad formatting for '${grammarName}' step (does not end in '.' or ':') in '${filename}':` + ); + console.dir(step); + console.log(); + process.exitCode = 1; + } + if (step.match(/^\s*(-|[0-9]\.)\s+[a-z]/)) { + console.log( + `Bad formatting of '${grammarName}' step (should start with a capital) in '${filename}':` + ); + console.dir(step); + console.log(); + process.exitCode = 1; + } + const trimmedInnerLine = step.replace(/\s+/g, " "); + if ( + trimmedInnerLine.match( + /(?:[rR]eturn|is (?:not )?)(true|false|null)\b/ + ) && + !trimmedInnerLine.match(/null or empty/) + ) { + console.log( + `Potential bad formatting of '${grammarName}' step (true/false/null should be wrapped in curly braces, e.g. '{true}') in '${filename}':` + ); + console.dir(step); console.log(); process.exitCode = 1; } diff --git a/cspell.yml b/cspell.yml index e8aa73355..e03ec4a09 100644 --- a/cspell.yml +++ b/cspell.yml @@ -21,3 +21,6 @@ words: - tatooine - zuck - zuckerberg + # Alternative spellings + - !implementor + - !implementors diff --git a/spec/Section 5 -- Validation.md b/spec/Section 5 -- Validation.md index 1c75080bb..75af96ffd 100644 --- a/spec/Section 5 -- Validation.md +++ b/spec/Section 5 -- Validation.md @@ -362,7 +362,7 @@ fragment aliasedLyingFieldTargetNotDefined on Dog { ``` For interfaces, direct field selection can only be done on fields. Fields of -concrete implementors are not relevant to the validity of the given +concrete implementers are not relevant to the validity of the given interface-typed selection set. For example, the following is valid: @@ -376,7 +376,7 @@ fragment interfaceFieldSelection on Pet { and the following is invalid: ```graphql counter-example -fragment definedOnImplementorsButNotInterface on Pet { +fragment definedOnImplementersButNotInterface on Pet { nickname } ``` diff --git a/spec/Section 7 -- Response.md b/spec/Section 7 -- Response.md index aef4359b1..bd9448293 100644 --- a/spec/Section 7 -- Response.md +++ b/spec/Section 7 -- Response.md @@ -23,7 +23,7 @@ request failed before execution, due to a syntax error, missing information, or validation error, this entry must not be present. The response map may also contain an entry with key `extensions`. This entry, if -set, must have a map as its value. This entry is reserved for implementors to +set, must have a map as its value. This entry is reserved for implementers to extend the protocol however they see fit, and hence there are no additional restrictions on its contents. @@ -203,7 +203,7 @@ be the same: GraphQL services may provide an additional entry to errors with key `extensions`. This entry, if set, must have a map as its value. This entry is -reserved for implementors to add additional information to errors however they +reserved for implementers to add additional information to errors however they see fit, and there are no additional restrictions on its contents. ```json example