selfcheck

command
v0.0.0-...-8c930d8 Latest Latest
Warning

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

Go to latest
Published: Nov 11, 2026 License: Apache-2.0 Imports: 18 Imported by: 0

Documentation

Overview

Command selfcheck holds the framework's own source to the rules golangci-lint cannot express, and prints each violation it finds.

Run it from the repository root through `make check`. The rules bind the framework alone: make check runs them over the framework, and a project is held to none of them.

Test placement

golangci-lint's testpackage makes a test file that joins the package it tests say so: its name ends in _internal_test.go. That settles the name but not the need, and this check makes the suffix true. A file can carry the suffix and still use nothing unexported of its package, or even declare the external test package; the check reports both, so an internal test is always one that could not be written from outside.

Thin forwarding

A function whose only work is handing its own parameters, unchanged and in order, to another function is a layer that adds a name and nothing else, and so is one whose whole body is a single call of a function of its own package, however it shapes the arguments. The check reports it where the layer can go: the function has a single use, which can call the other one itself, or, for a function passing its parameters on, the function it forwards to has no other use, so the two can be one. checkForwarding spells out what counts, and what the check leaves alone because it cannot count every use.

Source formatting

The code generators build the Go code they generate as syntax trees and print them through one formatting path. A generator that formats source text instead assembled its output as a string, and one that imports text/template renders it from a template, so a call to a source text formatter is reported anywhere in the generators but that one path, and an import of text/template anywhere in them. checkSourceFormat names the formatters, the generators and the path.

Import aliases

An import carries an alias in two cases alone: the package is one the importas section of .golangci.yml lists, spelt by that alias wherever it is imported, which golangci-lint holds; or another import of the same file binds the package's own name. An identifier named like the package is renamed instead. checkImportAlias reports every other alias, and a package spelt two ways anywhere in the tree.

Test doc comments

golangci-lint's godoclint holds the doc comment of every declaration to opening with the declaration's name, test files excepted: godoclint has a switch to include them that golangci-lint does not expose (v2.14.0 still exposes include-unexported alone). A doc comment opening with another name is one an insertion between a neighbor's comment and its declaration took along, and test files see as many insertions as any other, so checkTestDoc holds them to the same rule, read the way godoclint reads it, until a golangci-lint exposes the switch and a line of .golangci.yml replaces it.

Log fields

A log store that maps fields as they arrive types a key by the first entry carrying it and drops every later entry carrying the key with another type, so a key written two ways loses one writer's entries without a word. internal/logfield declares keys more than one stream writes, one constructor each, and checkLogFields holds the tree to them: a key of logfield's is written through its constructor alone, the module sources under internal/model and internal/service excepted, which are copied into projects that cannot import logfield; every other key, ip and user_agent among them, is written with one type wherever it appears, a key-value pair typed the way zap.Any types its value, and a value of interface type, typed at run time, is refused; zap.Object, zap.Dict, zap.Namespace and zap.Inline, which nest keys of their own under the entry, belong to logfield alone, whose key set is fixed. golangci-lint's loggercheck reads the key-value pairs for their shape alone, and no linter compares the type a key is given across the tree.

Test seams

A seam that exists for tests alone stays out of the implementation files: one its own package's tests use is an unexported variable beside the code it replaces, and one the tests of other packages use, which Go lets no package import from a test file, is exported from an internal package's testhooks.go alone, the file whose header says why no path the framework runs calls what it declares. checkTestSeams reports an exported function or variable of an internal package that only test files use anywhere in the module while being declared in another file, and one declared in testhooks.go that a non-test file uses. An export that is an API by design although only tests reach for it yet, the counterpart of one production does use or the constructor of a type it uses, says so in its doc comment, //gst:api <reason>, and the check holds the directive to its word: one without a reason, or on an export non-test code uses, is reported. Judged are the packages a non-test file imports: in a package kept for later, or a cache backend the framework keeps as an alternative, every export is used by tests alone without being a seam. A test support package, one with a non-test file importing testing, exports for tests by design and is left alone too, as are the module sources and the test support written as project code.

Test directory listing

go test keys a cached result on every entry of every directory a test lists, so a test listing the directory of another package, or the repository's, reruns whenever anything there moves, an editor saving a file or git writing .git, and its result is never reused. checkTestListing reports a listing in a test file, os.ReadDir, os.DirFS, filepath.WalkDir, filepath.Walk or filepath.Glob, unless it can follow the path back to the package's own directory or to a directory the test made; a test reads the files of another package through golist.Packages of internal/testutil/golist, which lists no directory.

Layout

Each check lives in the file named after it, testplacement.go for the check "testplacement", holding its run function and the helpers only it uses; helper.go holds what the checks share, and main.go runs them. TestEveryCheckIsDeclaredInAFileNamedAfterIt holds the layout.

Jump to

Keyboard shortcuts

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