config

package
v2.40.0-rc.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 1, 2026 License: Apache-2.0 Imports: 5 Imported by: 0

Documentation

Overview

Package config loads scripts/devbase.yaml, the per-repo configuration file consulted by devbase lint graphql for exclude patterns and per-rule severity/option overrides.

Index

Constants

View Source
const (
	// RuleUniqueDirectiveNames requires directive definitions to have
	// unique names.
	RuleUniqueDirectiveNames = "unique-directive-names"

	// RuleUniqueFieldDefinitionNames requires fields within a type to
	// have unique names.
	RuleUniqueFieldDefinitionNames = "unique-field-definition-names"

	// RuleUniqueOperationTypes requires at most one query, mutation,
	// and subscription root type.
	RuleUniqueOperationTypes = "unique-operation-types"

	// RuleUniqueTypeNames requires type definitions to have unique
	// names.
	RuleUniqueTypeNames = "unique-type-names"

	// RuleKnownArgumentNames requires arguments to be defined in the
	// schema.
	RuleKnownArgumentNames = "known-argument-names"

	// RuleKnownDirectives requires directives to be defined and used
	// in a valid location.
	RuleKnownDirectives = "known-directives"

	// RuleKnownTypeNames requires referenced types to exist in the
	// schema.
	RuleKnownTypeNames = "known-type-names"

	// RuleProvidedRequiredArguments requires required arguments to be
	// provided.
	RuleProvidedRequiredArguments = "provided-required-arguments"

	// RuleLoneSchemaDefinition allows at most one schema definition.
	RuleLoneSchemaDefinition = "lone-schema-definition"

	// RuleUniqueEnumValueNames requires enum values within an enum to
	// have unique names.
	RuleUniqueEnumValueNames = "unique-enum-value-names"
)

Names of the 10 Tier 1 rules: spec validations gqlparser performs for free while parsing SDL. Named as constants so internal/graphql/lint can tag violations with the same identifiers this package validates against.

RuleUniqueEnumValueNames belongs here, not among the gap-fill rules in internal/graphql/lint, because the gqlparser/v2 version pinned in go.mod already rejects a duplicate enum value on its own, the same way it already rejects a duplicate field name for RuleUniqueFieldDefinitionNames -- no custom code needed.

View Source
const (
	// RuleUniqueDirectiveNamesPerLocation requires a non-repeatable
	// directive to appear at most once per location in SDL.
	RuleUniqueDirectiveNamesPerLocation = "unique-directive-names-per-location"

	// RulePossibleTypeExtension requires a type extension to reference
	// a type that is actually defined somewhere.
	RulePossibleTypeExtension = "possible-type-extension"
)

Names of the 2 remaining Tier 2 gap-fill rules: gqlparser partially covers each, but a custom pass is still needed to fill the gap. Unlike the Tier 1 rules, scripts/devbase.yaml may override their severity.

View Source
const (
	// RuleRequireDescription requires a description on the kinds of
	// definition its options enable it for.
	RuleRequireDescription = "require-description"

	// RuleDescriptionStyle requires every description in a schema to
	// use the same quoting style: inline "..." or block """...""",
	// per its "style" option.
	RuleDescriptionStyle = "description-style"

	// RuleNoHashtagDescription forbids a "#" comment immediately
	// preceding a definition, field, argument, or enum value, in favor
	// of a "..." or """...""" description.
	RuleNoHashtagDescription = "no-hashtag-description"

	// RuleRequireDeprecationReason requires every applied @deprecated
	// directive to have a non-empty "reason" argument.
	RuleRequireDeprecationReason = "require-deprecation-reason"

	// RuleRequireDeprecationDate requires every applied @deprecated
	// directive to have a valid, not-yet-passed deletion date, per its
	// "argumentName" option (default "deletionDate").
	RuleRequireDeprecationDate = "require-deprecation-date"

	// RuleNoTypenamePrefix forbids a field on an object or interface
	// type from starting with that type's own name.
	RuleNoTypenamePrefix = "no-typename-prefix"

	// RuleNamingConvention requires names to follow the casing,
	// prefix/suffix, and underscore conventions its options configure
	// per kind of definition.
	RuleNamingConvention = "naming-convention"

	// RuleNoCaseInsensitiveEnumValuesDuplicates forbids two enum values
	// on the same enum whose names differ only by casing.
	RuleNoCaseInsensitiveEnumValuesDuplicates = "no-case-insensitive-enum-values-duplicates"

	// RuleAlphabetize requires alphabetical order among the fields,
	// enum values, and/or arguments its "fields", "values", and
	// "arguments" options select.
	RuleAlphabetize = "alphabetize"

	// RuleNoUnreachableTypes forbids a type or directive definition
	// that no root operation type's fields can ever reach.
	RuleNoUnreachableTypes = "no-unreachable-types"
)

Names of all 10 Tier 3 custom style/convention rules. Unlike Tier 1 and Tier 2, no part of a Tier 3 rule is enforced by gqlparser -- each is entirely custom Go code. Like the Tier 2 gap-fill rules above, a Tier 3 rule never runs unless scripts/devbase.yaml gives it a severity other than SeverityOff -- see Lint.Enabled. Each rule's options (for example require-description's "types" and "FieldDefinition" keys, or require-deprecation-date's "argumentName") are read from Rule.Options by internal/graphql/lint, not validated here -- this package treats every rule's options as opaque, leaving their shape to the rule implementation.

Variables

View Source
var ErrInvalidRule = errors.New("invalid rule config")

ErrInvalidRule is wrapped by errors returned when a rule entry in scripts/devbase.yaml is neither the short form (a severity scalar) nor the long form (a [severity, options] sequence), or names an unknown severity.

View Source
var ErrTier1RuleNotConfigurable = errors.New("tier 1 rule severity cannot be overridden")

ErrTier1RuleNotConfigurable is wrapped by the error returned when scripts/devbase.yaml overrides a Tier 1 rule's severity. Tier 1 rules are enforced by gqlparser while parsing SDL, always at "error" severity, and cannot be turned off or downgraded.

Functions

func Tier1RuleNames

func Tier1RuleNames() []string

Tier1RuleNames returns the 10 Tier 1 rule names above, in the order they are declared.

Types

type Lint

type Lint struct {
	// Exclude is a list of glob patterns for files to skip, relative
	// to the directory Load found scripts/devbase.yaml in.
	Exclude []string `yaml:"exclude"`

	// Rules overrides the severity (and, for some rules, options) of
	// individual lint rules, keyed by rule name. Tier 1 rules always
	// stay at "error" (gqlparser enforces them unconditionally, and
	// this map can never target one -- see ErrTier1RuleNotConfigurable).
	// Every other rule absent from this map, or explicitly set to
	// SeverityOff, does not run at all -- matching @graphql-eslint's own
	// behavior, where a rule is inert until a config opts into it.
	Rules map[string]Rule `yaml:"rules"`

	// Federation, if set, is the Apollo Federation subgraph spec
	// version (for example "v2.3") this repo's own schema links
	// against via `extend schema @link(url: "...", import: [...])`.
	// See internal/graphql/lint/federation.go for the supported
	// versions and directives, and how a mismatched or unrecognized
	// import is reported.
	Federation string `yaml:"federation"`

	// Scalars lists custom scalar type names that are registered
	// outside this repo's *.graphql files -- for example, at runtime
	// in application code -- and so are never declared via `scalar X`
	// SDL. Each name is merged into the schema as a bare `scalar X`
	// declaration.
	Scalars []string `yaml:"scalars"`
}

Lint is the graphql.lint section of scripts/devbase.yaml.

func Load

func Load(startDir string) (*Lint, string, error)

Load discovers and parses scripts/devbase.yaml for the repository containing startDir, and returns the directory it was found in. Load walks up from startDir, checking each directory for scripts/devbase.yaml, until either the file is found or the enclosing git repository's top-level directory is reached (whichever comes first); the walk never crosses git repository boundaries.

Callers should resolve Lint.Exclude patterns relative to the returned directory, not the process's working directory -- matching how ESLint, Biome, and Oxlint resolve their own ignore patterns relative to the config file rather than cwd.

If no config file is found, Load returns the built-in defaults (no excludes, no rule overrides, so every Tier 1 rule stays at "error" and every other rule stays off) alongside an empty directory.

func (*Lint) Enabled

func (c *Lint) Enabled(rule string) bool

Enabled reports whether the rule should run at all. A Tier 2 or Tier 3 rule is enabled only once scripts/devbase.yaml gives it a severity other than SeverityOff -- it does not run by default, matching @graphql-eslint's own behavior of a rule staying inert until a config opts into it. c may be nil (no config file found), in which case every rule this method is asked about is disabled.

This method is never consulted for Tier 1 rules: gqlparser enforces them unconditionally while parsing SDL, so Files runs them regardless of any config.

func (*Lint) MergeExcludes

func (c *Lint) MergeExcludes(extra ...string) []string

MergeExcludes returns the config's exclude patterns extended with extra patterns, e.g. from repeatable --exclude CLI flags. The config file's list is always kept, never replaced.

func (*Lint) Options

func (c *Lint) Options(rule string) map[string]any

Options returns rule's Rule.Options, or nil if c is nil or has no override for rule -- the rule's options are opaque to this package, which leaves their shape to the rule implementation.

func (*Lint) SeverityOf

func (c *Lint) SeverityOf(rule string) Severity

SeverityOf resolves the severity that applies to a violation tagged with rule. A Tier 2/3 rule present in c.Rules is always configured to SeverityWarn or SeverityError -- Enabled has already ruled out SeverityOff, since a rule at that severity never produces a violation -- so its configured severity is used directly. Every other rule -- a Tier 1 rule, which scripts/devbase.yaml can never override, or an unclassified gqlparser violation -- defaults to SeverityError. c may be nil (no config file found), in which case every rule defaults to SeverityError.

type Rule

type Rule struct {
	// Severity overrides the rule's default severity.
	Severity Severity

	// Options carries rule-specific options from the long form. It is
	// nil when the short form was used.
	Options map[string]any
}

Rule is the per-rule override for a single lint rule. It accepts two YAML shapes:

# Short form: severity only.
rule-name: warn

# Long form: severity plus rule-specific options.
rule-name:
  - error
  - someOption: true

func (*Rule) UnmarshalYAML

func (r *Rule) UnmarshalYAML(value *yaml.Node) error

UnmarshalYAML implements yaml.Unmarshaler for Rule, decoding both shapes described above.

type Severity

type Severity string

Severity is the severity level of a lint rule.

const (
	// SeverityOff disables a rule.
	SeverityOff Severity = "off"

	// SeverityWarn reports a rule's violations without failing the lint run.
	SeverityWarn Severity = "warn"

	// SeverityError reports a rule's violations and fails the lint run.
	SeverityError Severity = "error"
)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL