Documentation
¶
Overview ¶
Package lint runs the Tier 1, Tier 2, and (so far, partially) Tier 3 rule tiers against a repository's *.graphql files. Tier 1 is 10 rules that gqlparser/v2 enforces for free while parsing SDL, needing no custom rule code. FindGraphQLFiles discovers the files to lint, respecting scripts/devbase.yaml's exclude patterns; Files parses them as one combined schema and turns any resulting parse error into a Violation tagged with the Tier 1 rule name it corresponds to, using the classification verified in lint_test.go.
Schema validation stops at the first Tier 1 error it finds, so Files can only ever report one Tier 1 violation per run; fixing it and re-running surfaces the next one, the same behavior a contributor would see running gqlparser-based tooling directly. Once a schema validates cleanly, Files runs the Tier 2 gap-fill passes (directives.go) and the Tier 3 custom rules implemented so far (descriptions.go) against it and can report any number of their violations in one run, since those are ordinary Go code walking the parsed schema rather than a stop-at-first-error parser.
federation.go is the one exception to "no custom rule code" for Tier 1: Apollo Federation directives and repo-specific custom scalars are never declared via SDL that a subgraph owns, so scripts/devbase.yaml's federation and scalars settings tell Files what to synthesize and merge in before validation, instead of gqlparser rejecting them as undefined.
go.mod pins github.com/vektah/gqlparser/v2 to v2.5.36 (the latest v2.5.x release as of 2026-08-21) so this behavior is stable and reviewable across releases. gqlparser/v2 also performs a set of spec-mandated schema validations beyond the 10 rules classified here (for example, rejecting a reserved "__" name prefix, or a zero-field object type); those surface as violations tagged UnclassifiedRule.
Index ¶
Constants ¶
const UnclassifiedRule = "gqlparser"
UnclassifiedRule tags a violation that gqlparser raises while parsing SDL but that does not correspond to one of the 10 named Tier 1 rules -- one of gqlparser's other spec-mandated schema validations (for example, a reserved "__" name prefix, or a zero-field object type).
Variables ¶
var ErrDescriptionTokenMismatch = errors.New("description-style: mismatched description token count")
ErrDescriptionTokenMismatch is wrapped by the error tier3Descriptions returns if a file's count of non-empty descriptions in the parsed schema doesn't match descriptionTokens' count of description-like string tokens in that file's raw source -- description-style cannot safely pair them up in that case. This should never happen for valid SDL; see description_style.go's package doc comment for why descriptionTokens is expected to find exactly one token per description.
var ErrFederationVersionMismatch = errors.New("federation version mismatch")
ErrFederationVersionMismatch is wrapped by the error returned when a repository's own `@link` names a Federation version other than the one scripts/devbase.yaml configures.
var ErrUnsupportedFederationDirective = errors.New("unsupported federation directive import")
ErrUnsupportedFederationDirective is wrapped by the error returned when a repository's `@link` import list names something this package cannot classify as one of the directives in federationDirectives.
var ErrUnsupportedFederationVersion = errors.New("unsupported federation version")
ErrUnsupportedFederationVersion is wrapped by the error returned when scripts/devbase.yaml's graphql.lint.federation names a version this package does not ship a directive prelude for.
Functions ¶
func FindGraphQLFiles ¶
FindGraphQLFiles walks each of paths, collecting every *.graphql file found (in deterministic, lexically sorted order) that does not match an exclude pattern. A path naming a file directly is included as-is, regardless of extension; a path naming a directory is walked recursively. Patterns are matched with doublestar semantics ("**" matches zero or more path segments), consistent with the exclude examples in scripts/devbase.yaml.
Types ¶
type Violation ¶
type Violation struct {
Rule string
// contains filtered or unexported fields
}
Violation is a single Tier 1 lint finding, formatted as "<file>:<line>:<col>: <message> [<rule>]".
func Files ¶
Files reads paths from disk and lints them as one combined GraphQL schema via FilesFromSources. cfg supplies scripts/devbase.yaml's federation and scalars settings, merged into the parsed sources before validation; a nil cfg parses paths exactly as written, with no merged prelude.
func FilesFromSources ¶
FilesFromSources parses fileSources as one combined GraphQL schema, returning the Tier 1 violation gqlparser raised, if any, or -- once the schema validates cleanly -- any Tier 2 gap-fill and Tier 3 violations found in it. fileSources are parsed together, not independently, so that a type defined in one source is visible when validating a reference to it in another. Unlike Files, fileSources' content is supplied directly rather than read from disk -- used by --diff mode to lint a merge-base commit's file content without a checkout.
cfg supplies scripts/devbase.yaml's federation and scalars settings, merged into the parsed sources before validation; a nil cfg parses fileSources exactly as given, with no merged prelude.
func New ¶
New returns the violations in current that are not also present in baseline, comparing by file, rule, and message but ignoring line and column. Ignoring position keeps the result stable across unrelated line shifts elsewhere in a file; a violation is "new" only when its file/rule/message combination didn't already exist at the baseline, not merely when it moved. baseline and current are typically the same files linted at the merge-base and working-tree commits, respectively.
A message appearing more times in current than in baseline reports only the excess occurrences, so a genuinely repeated violation isn't masked by a single matching baseline occurrence.
func (Violation) File ¶
File returns the name of the source the violation was found in, as given to the *ast.Source that produced it.