The linter blocks the changing of public fields. Unwritable fields help to avoid validation. The linter is useful when:
- A project is migrated to Domain Model from Anemic.
- Business logic should not be broken by a direct variable assigning.
- You don't want to use snapshot pattern to get data from model and want to protect business logic in the project.
Installation
go install github.com/maranqz/gopublicfield/cmd/gopublicfield@latest
--packageGlobs
- list of glob packages, in which public fields can be written by other packages in the same glob pattern. By default, all fields in all external packages should be unwritable except local, tests.--packageGlobsOnly
- only public fields in glob packages cannot be written by other packages, tests.
Bad | Good |
---|---|
package main
import (
"bad"
)
func main() {
u := &bad.User{}
u.UpdatedAt = time.Now() // Field 'ID' in bad.User can be changed only inside nested package.`
} package bad
import "time"
type User struct {
UpdatedAt time.Time
} |
package main
import (
"good"
)
func main() {
u := &good.User{}
u.Update()
} package user
import "time"
type User struct {
UpdatedAt time.Time
}
func (u *User) Update() {
u.UpdatedAt = time.Now()
} |
All examples shows in unimplemented directory.
- Type assertion, type declaration and type underlying, tests.
- Unreadable fields.
- Updating of slice, map items.
- Updating by pointer to the unwritable field.
//.. n := nested.Struct{} fieldPtr := &n.Int (*fieldPtr)++ //..