cliapp

package module
v0.4.13 Latest Latest
Warning

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

Go to latest
Published: Aug 24, 2026 License: MIT Imports: 6 Imported by: 0

README

Documentation

Overview

Package cliapp provides a go/analysis analyzer enforcing the app tier of the opinionated three-tier CLI layout, for every command package beneath internal/app/commands/ at any depth. A command package declares itself by exporting a command entry point; for each such package the command file (the one declaring the entry point whose verb is the package name) leads with a const block, every entry point's verb IS the package name — so a second verb belongs in its own nested package, as the reference layout demonstrates with config/{get,list,set} — and the package's own domain package is bound to the name "domain".

The package's own domain package is its COUNTERPART, the domain package corresponding segment for segment: internal/app/commands/tenant/create is backed by internal/domain/tenant/create. No other import is ever judged, and nothing stands in for a counterpart a file does not import. "domain" is a file-scoped name and a file has exactly one, so a rule reaching a second import at or beneath the tier would prescribe a redeclaration — and a command file legitimately names the shared vocabulary package beside its counterpart, or a type package nested under its own group.

The shared vocabulary package at internal/domain is the obvious stand-in and is the wrong one. It is every tier's vocabulary and nobody's counterpart, so standing it in would report a mount-only parent command that names domain.Argument, and the SECOND FILE of a command package whose counterpart is imported in the first — and taking that instruction makes "domain" mean two different packages inside one package, which is the collision this rule exists not to prescribe.

The name is what the import BINDS, not what it spells: an import with no alias binds the imported package's own name, so an unaliased import of a package named domain already reads domain.X at every call site. A blank import is exempt because there is no name in it to bind. Where some other import in the file already binds "domain", the diagnostic names that import instead of prescribing a redeclaration — the domain package cannot take a name that is spoken for, and the remedy is to rename the holder first.

What that leaves reachable is stated rather than claimed away, and it is not forgeable: the counterpart path comes from the analyzed package's own import path, which no judged file can rewrite, so silence has to be bought by not importing the counterpart at all. Two ways exist and NEITHER is free.

Move the command's logic to a domain package that is not its counterpart: the import is then out of this rule, and stickler/clilayout reports the correspondence — "domain verb X has no command package Y", or the converse. Or stop declaring an entry point, which takes the package out of every check here for one identifier; that is the cheapest move in reach, and it is also the one clilayout is watching. Measured 2026-08-16: renaming Command to New in a conforming module takes yze/cliapp to silence and draws "domain verb internal/domain/greet has no command package internal/app/commands/greet declaring a Command entry point" from stickler/clilayout, which is why this analyzer does not restate correspondence and must not be read as the whole gate for it.

Test files are judged by none of this. They carry no command source, and a test naming several packages the command file does not may alias the domain import to disambiguate.

A package beneath the tree that declares no entry point — a helper nested under a command, or a shared grouping package — carries none of these obligations. Whether every self-declaring command has its domain counterpart (and vice versa) is cross-package correspondence, which is stickler/clilayout's job; the domain package's own contract is yze/clidomain's.

Index

Constants

This section is empty.

Variables

View Source
var Analyzer = &analysis.Analyzer{
	Name: "cliapp",
	Doc:  "reports command packages that violate the app tier of the opinionated three-tier CLI layout",
	Run:  run,
}

Analyzer reports per-package violations of the three-tier command-package layout.

View Source
var Registration = goyze.Registration{
	Precision:  goyze.PrecisionExact,
	Name:       "cliapp",
	Categories: []goyze.Category{"cli", "structure"},
	URL:        "https://docs.gomatic.dev/yze/cliapp",
	Analyzer:   Analyzer,
}

Registration declares this analyzer to the yze framework.

Functions

This section is empty.

Types

This section is empty.

Jump to

Keyboard shortcuts

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