1 Home
Virgil edited this page 2026-03-11 12:14:40 +00:00

Lint

Module: forge.lthn.ai/core/lint Binary: core-lint

Pattern-based lint tool for Go, PHP, TypeScript, JavaScript, Python, and C++. Rules are defined in embedded YAML catalog files with regex detection, severity levels, and auto-fix suggestions. Includes Go AST cyclomatic complexity analysis, test coverage tracking, govulncheck integration, and a full PHP quality pipeline (Pint, PHPStan, Psalm, security auditing, mutation testing).

Architecture

The lint engine has three layers:

  1. Catalog — YAML rule files loaded from embedded filesystem or external paths.
  2. Matcher — Compiled regex rules applied line-by-line to source files.
  3. Scanner — Directory walker that detects file languages and dispatches to matcher.

Key Types

Rule

type Rule struct {
    ID             string   // unique identifier
    Title          string   // human-readable name
    Severity       string   // info, low, medium, high, critical
    Languages      []string // target languages (go, php, ts, js, cpp, py)
    Tags           []string // categorisation tags
    Pattern        string   // regex or AST pattern
    ExcludePattern string   // lines/files matching this are skipped
    Fix            string   // suggested fix description
    Detection      string   // "regex" or "ast"
    AutoFixable    bool     // whether automatic fix is possible
    ExampleBad     string   // bad code example
    ExampleGood    string   // good code example
}

Validate() checks required fields and compiles regex patterns.

Finding

type Finding struct {
    RuleID   string
    Title    string
    Severity string
    File     string
    Line     int
    Match    string
    Fix      string
    Repo     string
}

Matcher

Holds compiled rules. NewMatcher(rules) (*Matcher, error) compiles regex-detection rules. Match(filename, content) []Finding scans line-by-line, checking exclude patterns on both lines and filenames.

Scanner

NewScanner(rules) (*Scanner, error) creates a scanner with default directory exclusions (vendor, node_modules, .git, testdata, .core).

  • ScanDir(root) ([]Finding, error) — walks directory tree, detects language by extension, matches rules.
  • ScanFile(path) ([]Finding, error) — scans single file.

Language detection: .go->go, .php->php, .ts/.tsx->ts, .js/.jsx->js, .cpp/.cc/.c/.h->cpp, .py->py.

Catalog

LoadFS(fs, dir) (*Catalog, error) loads rules from embedded or external filesystem. LoadEmbeddedCatalog() loads from catalog/*.yaml.

Shipped catalogs:

  • go-correctness.yaml
  • go-modernise.yaml
  • go-security.yaml

Additional Packages

pkg/lint/

File Description
complexity.go Go AST cyclomatic complexity analysis
coverage.go Test coverage snapshot, regression tracking
vulncheck.go govulncheck JSON output parsing
tools.go Toolkit subprocess wrappers (external tools)
report.go Output formatting (JSON, JSONL, text)

pkg/detect/

Project type detection: Detect(path) string identifies project type from files present (go.mod, composer.json, package.json, etc.).

pkg/php/

Full PHP quality pipeline:

File Description
format.go Laravel Pint code formatting
analyse.go PHPStan + Psalm static analysis
audit.go Composer security auditing
security.go Security checks
test.go Pest/PHPUnit test runner
refactor.go Rector refactoring
mutation.go Infection mutation testing
pipeline.go Orchestrated QA pipeline
runner.go Pipeline execution engine

CLI

Entry point: cmd/core-lint/. Also cmd/qa/ for quality assurance commands.

Dependencies

Direct: core/cli, go-i18n, go-io, go-log, go-scm, testify, yaml.v3.

Usage

catalog, _ := lint.LoadEmbeddedCatalog()
scanner, _ := lint.NewScanner(catalog.Rules())
findings, _ := scanner.ScanDir("./src")