requiredfield

package module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Mar 29, 2023 License: MIT Imports: 9 Imported by: 0

README

requiredfield

Introduction

Go Reference CI codecov

requiredfield is a linter for Go that verifies that required fields of a struct are filled when it is initialized. Whether a field is required is specified with a comment.

For example:

type BufWriter struct {
    W      io.Writer     // required
    Buffer *bytes.Buffer
}

The linter will return an error on the following snippet:

w := BufWriter{Buffer: b}
// ERROR: missing required fields: W

To read more about the motivation for this linter, see Motivation.

Installation

Install the binary from source by running:

go install go.abhg.dev/requiredfield/cmd/requiredfield@latest

Usage

To use the linter, run the binary directly:

requiredfield ./...

Alternatively, use it with go vet:

go vet -vettool=$(which requiredfield) ./...

Overview

To indicate that a field is required, add a // required comment next to it.

type BufWriter struct {
    W      io.Writer     // required
    Buffer *bytes.Buffer
}

This indicates that the W field is required.

All instantiations of BufWriter using the T{...} form will be required to set the W field explicitly.

For example:

w := BufWriter{Buffer: b}
// ERROR: missing required fields: W
Syntax

Fields are marked as required by adding a comment in one of the following forms next to them:

// required
// required<sep><description>

Where <sep> is a non-alphanumeric character, and <description> is an optional description.

For example:

type User struct {
    Name  string // required: must be non-empty
    Email string
}

The description is for the benefit of other readers only. requiredfield will ignore it.

Positioning

The // required comment must be on the line where the field is defined.

GOOD                         | BAD
-----------------------------+-------------------
type User struct {           | type User struct {
    Name string // required  |     // required
}                            |     Name string
                             | }

If the field definition is spread across multiple lines, the comment must be on the last of these. For example,

type Watcher struct {
    Callback func(
        ctx context.Context,
        req *Request,
    ) // required
}
Behavior

Any time a struct is initialized in the form T{..}, requiredfield will ensure that all its required fields are set explicitly.

u := User{
    Email: email,
}
// ERROR: missing required fields: Name

Required fields can be set to the zero value of their type, but that choice must be made explicitly.

u := User{
    Name: "", // computed below
    Email: email,
}
// ...
u.Name = name

FAQ

Why a comment instead of a struct tag?

The reasons for this choice are both, philosophical and cosmetic.

First, the philosophical reason: requiredfield is a linter that runs at compile-time, and therefore wants its footprint limited to compile-time only. Struct tags get compiled into your binary and are available at runtime via reflection. It would become possible for someone to change how the program behaves based on the value of those struct tags. requiredfield considers that a violation of the linter's boundaries, and aims to prevent that by using comments instead.

The cosmetic reason is much easier to explain: Struct tags are uglier than line comments.

Author ID `required:"true"`

// versus

Author ID // required

Documentation

Overview

Package requiredfield implements a linter that checks for required fields during struct initialization.

Fields can be marked as required by adding a comment in the form "// required" next to the field, optionally followed by a description. For example:

type T struct {
	A string // required
	B int    // required: must be positive
	C bool   // required because reasons
}

The analyzer will report an error when an instance of the struct is initialized without setting one or more of the required fields explicitly. For example:

T{A: "foo"} // error: missing required fields: B, C

The explicit value can be the zero value of the field type, but it must be set explicitly.

T{A: "foo", B: 0, C: false}

Index

Constants

This section is empty.

Variables

View Source
var Analyzer = &analysis.Analyzer{
	Name: "requiredfield",
	Doc:  "check for required fields during struct initialization",
	Run:  run,
	Requires: []*analysis.Analyzer{
		inspect.Analyzer,
	},
	FactTypes: []analysis.Fact{
		new(isRequiredField),
		new(hasRequiredFields),
	},
}

Analyzer implements the requiredfield linter.

See package documentation for details.

Functions

This section is empty.

Types

This section is empty.

Directories

Path Synopsis
cmd
requiredfield
requiredfield is a linter for Go code that checks for missing required fields in struct literals.
requiredfield is a linter for Go code that checks for missing required fields in struct literals.

Jump to

Keyboard shortcuts

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