linter

package module
v0.1.0 Latest Latest
Warning

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

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

README

OpenAPI linter

openapilint is a standalone Go command and library for configurable OpenAPI and YAML-schema checks. Customer rules and bundled checks use the same public registry, analyzer, diagnostics, and suppression interfaces.

Run

Use Go 1.24.2 or newer:

go build -o openapilint ./cmd/openapilint
./openapilint --rules examples/rules.yaml examples/specs

Inputs are YAML or JSON files, or directories searched recursively. --root defaults to the working directory. Inputs and local reference targets must stay within that root, including symlinks. Remote and absolute reference targets are rejected. Use --kind schema for standalone YAML-schema files; directory inputs must contain only documents of the selected kind.

OpenAPI 3.0 and 3.1 are the supported document versions. The command builds the parsed model and reports parsing/reference errors; it does not claim complete OpenAPI specification conformance validation. Schemas and cross-file references are exposed through libopenapi. The loader permits array/polymorphic circular references, and model-build failures otherwise produce an execution error. Pure reference cycles may fail to build.

Rule packs

version: 1
rules:
  - id: customer.operation-style
    check: openapi.operation-id
    severity: error
    options:
      required: true
      pattern: '^[a-z][A-Za-z0-9]*$'

An explicit pack executes only its configured rules. The default OpenAPI pack requires operation IDs. Schema mode has an empty default pack; supply your schema checks explicitly. Use --only id,other-id to select from a validated pack. See rule-pack reference for checks, scope, and suppressions.

Text diagnostics contain file, line, rule ID, message, and JSON pointer. --format json returns a deterministic array of diagnostics. Exit codes: 0 for success (including warning/info findings), 1 for error findings, 2 for configuration or execution failure. Linting is read-only; this release has no autofix command.

Customer executable checks

YAML configures available checks. New executable logic is registered in a customer-built Go command; no executable plugins are downloaded or loaded from YAML. The custom example registers a check beside the stock registry:

go run ./examples/custom --rules examples/custom/rules.yaml examples/specs

Implement the public Analyzer, or adapt a Rule/SchemaRule visitor using rulepack.AdaptRule/AdaptSchemaRule. Pass.Documents contains the rule's selected inputs. Use Pass.Report for findings and Pass.ReportError for operational failures. Pass.Root supplies the filesystem boundary; custom code is trusted Go code, and must respect that boundary itself. Each check receives a separate pass; a composite analyzer can share data within its pass through SetData and Data.

LoadDocument and LoadSchemaDocument enforce the root/reference policy used by the command. The lower-level Linter.LoadSpec and LoadSchema APIs retain direct-caller filesystem semantics; applications using those APIs own their access policy. Standalone-schema checks inspect YAML structure rather than resolving schemas into OpenAPI models.

Install and remove

Install an exact version with go install github.com/portpowered/openapi-linter/cmd/openapilint@v0.1.0, or download the platform archive and checksums.txt from releases. Verify its SHA-256 checksum, unpack it, and put the executable on PATH. Archives cover Linux, macOS, and Windows on amd64 and arm64. Hosted CI executes tests on Linux, macOS, and Windows; other architectures receive cross-build verification.

Release archives report the tag through --version; a Go installation reports dev unless version linker flags are supplied. Uninstall by removing that executable. No background service is installed.

Development

See development. Tests and examples are self-contained and require no parent service repository or private credentials.

Documentation

Overview

Package linter provides an OpenAPI specification linter that validates API specs using independently registered checks.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func CheckPathRoot

func CheckPathRoot(root, target string) error

CheckPathRoot rejects paths outside root, including symlink escapes. Missing targets are checked through their nearest existing ancestor. An empty root leaves filesystem policy to the direct library caller.

func DiscoverSchemas

func DiscoverSchemas(dir string) ([]string, error)

DiscoverSchemas recursively finds all .yaml files under the given directory.

func PointerSegment

func PointerSegment(key string) string

PointerSegment escapes a key for use in a JSON pointer.

Types

type Analyzer

type Analyzer interface {
	ID() string
	Analyze(context.Context, *Pass)
}

Analyzer implements a stock or customer check over the selected input documents.

type Diagnostic

type Diagnostic struct {
	// Context preserves a check-specific human-readable location.
	Context  string
	Path     string
	Pointer  string
	Line     int
	RuleID   string
	Message  string
	Severity Severity
}

type Document

type Document struct {
	// Schema is populated for standalone YAML-schema inputs instead of Model.
	Schema *SchemaDocument
	Path   string
	Source []byte
	Model  *v3.Document
	Root   *yaml.Node
}

Document exposes both the parsed OpenAPI model and original source locations.

func LoadDocument

func LoadDocument(ctx context.Context, path, root string) (*Document, error)

LoadDocument reads an OpenAPI 3 document with local references confined to root. Remote references are rejected, including references in external schema files.

func LoadSchemaDocument

func LoadSchemaDocument(ctx context.Context, path, root string) (*Document, error)

LoadSchemaDocument loads a standalone YAML schema under the same reference policy.

func (*Document) Line

func (d *Document) Line(pointer string) int

Line resolves a JSON pointer into the original source. Zero means unavailable.

type Engine

type Engine struct {
	// contains filtered or unexported fields
}

Engine executes public visitor checks over an OpenAPI document.

func (*Engine) RegisterRule

func (e *Engine) RegisterRule(r Rule)

RegisterRule adds a REST API rule to the engine.

func (*Engine) Run

func (e *Engine) Run(doc *v3high.Document) []Violation

Run walks the document's schemas, paths, and operations, calling each registered rule's visitor methods and collecting all violations.

type Linter

type Linter struct {
	// contains filtered or unexported fields
}

Linter loads and holds a parsed OpenAPI document model for validation.

func (*Linter) Document

func (l *Linter) Document() *v3high.Document

Document returns the parsed high-level V3 document, or nil if no spec has been loaded.

func (*Linter) LoadSpec

func (l *Linter) LoadSpec(path string) error

LoadSpec reads an OpenAPI YAML file from the given path and parses it into a libopenapi high-level document model.

type Pass

type Pass struct {
	Documents []*Document
	Root      string
	// contains filtered or unexported fields
}

func NewPass

func NewPass(documents []*Document) *Pass

func (*Pass) Data

func (p *Pass) Data(key string) (any, bool)

func (*Pass) Diagnostics

func (p *Pass) Diagnostics() []Diagnostic

func (*Pass) Err

func (p *Pass) Err() error

func (*Pass) Report

func (p *Pass) Report(d Diagnostic)

func (*Pass) ReportError

func (p *Pass) ReportError(err error)

ReportError stops pack execution with an operational failure, rather than a lint finding.

func (*Pass) SetData

func (p *Pass) SetData(key string, value any)

type Rule

type Rule interface {
	// Name returns the unique identifier for this rule.
	Name() string

	// VisitSchema is called for each named schema component.
	// schemaName is the component name (e.g., "CreateWidgetRequest").
	// schema is the resolved schema object.
	VisitSchema(schemaName string, schema *base.Schema) []Violation

	// VisitPath is called for each path in the spec.
	// path is the URL path string (e.g., "/endpoints/{endpointId}").
	// pathItem is the path item object containing operations.
	VisitPath(path string, pathItem *v3high.PathItem) []Violation

	// VisitOperation is called for each operation on each path.
	// path is the URL path, method is the HTTP method (e.g., "GET"),
	// and operation is the operation object.
	VisitOperation(path string, method string, operation *v3high.Operation) []Violation
}

Rule defines a validation rule that can visit different parts of an OpenAPI spec. Implementations only need to provide logic for the visitor methods relevant to their rule; unused methods should return nil.

type SchemaDocument

type SchemaDocument struct {
	// Content holds the raw parsed YAML as a map of root-level keys.
	// x-extension fields (e.g., x-type, x-namespace) are accessible as string keys.
	Content map[string]any
}

SchemaDocument represents a parsed standalone schema YAML file.

func LoadSchema

func LoadSchema(path string) (*SchemaDocument, error)

LoadSchema reads and parses a YAML file into a SchemaDocument.

type SchemaRule

type SchemaRule interface {
	Name() string
	VisitSchema(string, *SchemaDocument) []Violation
}

SchemaRule checks a standalone YAML schema using the same public violation type.

type Severity

type Severity string
const (
	SeverityError   Severity = "error"
	SeverityWarning Severity = "warning"
	SeverityInfo    Severity = "info"
)

type Violation

type Violation struct {
	RuleName string
	// Pointer locates the finding in the OpenAPI document; Path preserves human context.
	Pointer string
	Path    string
	Message string
}

Violation represents a single rule violation found in the spec.

Directories

Path Synopsis
Package cli provides stock and customer-registry OpenAPI commands.
Package cli provides stock and customer-registry OpenAPI commands.
cmd
openapilint command
examples
custom command
A customer command with a check registered through the stock extension API.
A customer command with a check registered through the stock extension API.
Package rulepack configures built-in and customer analyzers through one registry.
Package rulepack configures built-in and customer analyzers through one registry.

Jump to

Keyboard shortcuts

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