requireddepsgen

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Jun 7, 2026 License: MIT Imports: 14 Imported by: 0

Documentation

Overview

Package requireddepsgen generates validateRequired() methods for Service structs by reading gocell:"required" struct field tags.

Usage:

out, err := requireddepsgen.Generate("/path/to/slice")
// out contains the formatted Go source for service_required_gen.go

Primary Tag

Mark a Service struct field as required:

type Service struct {
    repo domain.Repository `gocell:"required"`
}

The generator emits a validateRequired() method that checks each tagged field and returns an errcode.Error on the first nil dependency found.

Sub-Tags (all optional)

Sub-tags customize the generated error for a specific field. They have no effect on fields without gocell:"required".

gocellKind   errcode.Kind constant name (default: KindInternal)
              e.g. gocellKind:"KindInvalid"

gocellCode   errcode error code constant (default: ErrCellInvalidConfig)
              e.g. gocellCode:"ErrValidationFailed"

gocellErr    error message string literal
              (default: "{pkg}.NewService: {field} required")
              e.g. gocellErr:"slicepkg: TxRunner required; use WithTxManager"

Typical case (default KindInternal/ErrCellInvalidConfig with custom message):

txRunner persistence.CellTxManager `gocell:"required" gocellErr:"mypkg: TxRunner required; use WithTxManager"`

Overriding all three sub-tags (rare — different HTTP status intentional):

codec *query.CursorCodec `gocell:"required" gocellCode:"ErrCellMissingCodec" gocellErr:"mypkg: cursor codec required"`

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrNoServiceStruct is returned when service.go contains no
	// "type Service struct" declaration.
	ErrNoServiceStruct = errcode.New(errcode.KindInvalid, errcode.ErrValidationFailed,
		"requireddepsgen: no Service struct in service.go")

	// ErrUnknownTagValue is returned when a struct field has a gocell tag
	// whose value is not "" or "required", or when gocellKind/gocellCode tags
	// contain values that do not match the errcode identifier whitelist.
	ErrUnknownTagValue = errcode.New(errcode.KindInvalid, errcode.ErrValidationFailed,
		"requireddepsgen: unknown gocell tag value (allowed: \"\", \"required\")")

	// ErrBadTagSyntax is returned when a struct field carries a malformed
	// struct tag (one reflect.StructTag.Lookup would silently drop). Surfacing
	// it fail-closed prevents a typo'd tag from silently skipping a required
	// dependency guard.
	ErrBadTagSyntax = errcode.New(errcode.KindInvalid, errcode.ErrValidationFailed,
		"requireddepsgen: malformed struct tag")
)

Sentinel errors returned by Generate. Declared via errcode.New (not errors.New) so exported package-scope sentinels participate in the project error taxonomy — EXPORTED-ERROR-NEW-01 bans exported errors.New sentinels module-wide, tools/ included. They keep stable pointer identity (single package-var construction), so errors.Is against them is unaffected.

Functions

func FindSlicePaths

func FindSlicePaths(modRoot string) ([]string, error)

FindSlicePaths discovers all slice directories containing a service.go under modRoot. Exported so the REQUIRED-DEP-NIL-GUARD-01 A1 archtest regen-diffs the exact same set of gen files the generator emits — generator and verifier share one discovery, so no gen file can escape the byte-granularity Hard check.

func Generate

func Generate(slicePath string) ([]byte, error)

Generate reads slicePath/service.go, scans the Service struct for gocell:"required" field tags, and returns the formatted Go source for service_required_gen.go.

Returns byte-identical output for identical inputs (no map iteration order dependency). Field guards appear in struct declaration order.

func GenerateAll

func GenerateAll(modRoot string) (map[string][]byte, error)

GenerateAll walks modRoot for all cells/*/slices/*/service.go files and returns a map from slice directory path to generated file contents.

Slices whose service.go does not declare a "Service" struct are silently skipped (ErrNoServiceStruct). All other errors are fatal.

func GenerateWithOpts

func GenerateWithOpts(slicePath string, opts Opts) ([]byte, error)

GenerateWithOpts is the option-aware variant of Generate. See Opts.

func TagSyntaxValid

func TagSyntaxValid(raw string) bool

TagSyntaxValid reports whether raw (the unquoted struct-tag body, e.g. `json:"x" gocell:"required"`) is a well-formed sequence of conventional key:"value" pairs. It mirrors the scan loop of reflect.StructTag.Lookup but, unlike Lookup — which silently stops at the first malformed pair and reports the key as absent — returns false on any malformation so callers can fail closed. Exported so the REQUIRED-DEP-NIL-GUARD-01 A4 archtest shares this single malformed-tag definition rather than re-deriving it. ref: Go src reflect/type.go StructTag.Lookup.

Types

type Opts

type Opts struct {
	BuildTag string
}

Opts controls optional generator behavior.

BuildTag, when non-empty, emits a `//go:build <BuildTag>` header at the top of the generated file. Used for archtest fixtures that must carry //go:build archtest_fixture. Production calls leave it empty.

Jump to

Keyboard shortcuts

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