Documentation
¶
Overview ¶
Package ggprune works out what gg prune deletes from a project's service and pb directories, and deletes it: the service files of disabled actions, the unmanaged files of service directories no model owns, the files under pb/ gg gen would not write now (see PlanPBFiles), and the directories that leaves empty. Asking before deleting and printing what happened stay with the gg command; gg gen plans with it, too, the Go files under pb/ it deletes as it writes. cmd/gg/PRUNE.md lays out the whole cleanup, step by step, with flowcharts.
Of the ignore rules, only gst.yaml's prune.ignore keeps a path from being deleted, and under pb/ it keeps the definitions alone. The service directory belongs to gg and is kept clean: a file there that nothing needs is litter even when the project's Git ignore rules or the go command's ignores (testdata, vendor, names beginning with "." or "_", nested modules, the directories go.mod ignores) cover it. So prune reads what it deletes whole, and prune.ignore is the one way to keep a path on purpose. Which code still uses a service directory, though, prune reads the way gg check and gg gen read the project (see gghelper.ProjectIgnore): code the project ignores is not its code and keeps no directory alive, so prune leaves behind no directory it could never clean.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func RemoveEmptyDirs ¶
func RemoveEmptyDirs(rootDir string, protect ggconfig.PruneConfig, report func(dir string))
RemoveEmptyDirs removes the empty directories below rootDir, deepest first, keeping those a gst.yaml prune.ignore entry in protect covers, and reports each one it removes to report. Nothing else keeps a directory: an empty testdata directory, or one the project's Git ignore rules exclude, is removed like any other.
func RemoveFiles ¶
RemoveFiles deletes paths in order and reports each one to report, with the error when it could not be deleted; a failure does not stop the rest.
func ScanPBFiles ¶
ScanPBFiles lists the files gg gen writes under pbDir, the directory the protobuf definitions, the Go files serving them and the Go files compiled from them go to, in walk order: pb/pb.gen.go, pb/record/item.gen.go, pb/record/item.pb.go, pb/record/item.proto, pb/record/item_grpc.pb.go, pb/record/pb.gen.go, pb/record.gen.go, pb/record.pb.go, pb/record.proto and pb/record_grpc.pb.go for a project serving Record and its child Item over gRPC. Only the .proto, .gen.go and .pb.go files are listed, the kinds gg gen writes. Like ScanServiceFiles it reads the directory whole, the directory being gg's: a file the project's Git ignore rules cover, or one below a directory the go command leaves out, is listed like any other. A missing directory lists nothing.
func ScanServiceFiles ¶
ScanServiceFiles lists the service files under serviceDir that gg manages: the standard phase files such as create.go and list.go, and any other .go file embedding service.Base[...], which a DSL Service("x") produces. Only test files are left out; a file the project's Git ignore rules or the go command ignore is listed like any other. A walk error ends the scan, and the files found before it come back with it.
Types ¶
type FilePlan ¶
type FilePlan struct {
// Delete lists the files to delete, in the order they were scanned, each
// service file followed by its test files.
Delete []string
// Ignored lists the files a gst.yaml prune.ignore entry keeps.
Ignored []string
}
FilePlan is what prune intends for one kind of file it manages: the service files of disabled actions with the test files paired with them (see PlanFiles), or the files under pb/ gg gen would not write now (see PlanPBFiles).
func PlanFiles ¶
func PlanFiles(existing []string, models []*modelinfo.Model, kept map[string]bool, protect ggconfig.PruneConfig) FilePlan
PlanFiles works out which existing service files prune deletes: the ones no enabled action of models expects any more, except the ones in kept, which belong to gst.yaml-ignored actions and must stay on disk, and the ones a prune.ignore entry in protect covers, which it lists as ignored instead. The test files paired with a deleted service file, create_test.go and create_internal_test.go beside create.go, go with it: once the service file is gone they test nothing, and the service test organization check refuses a test file without a source file. A prune.ignore entry covering a test file keeps it like any other file.
func PlanPBFiles ¶
func PlanPBFiles(existing, generated []string, protect ggconfig.PruneConfig) (FilePlan, error)
PlanPBFiles works out which of the existing files under pb/ prune deletes: the ones gg gen would not write now, generated being the paths it writes, slash-separated as pb.Generate and pb.Compile hand them out. Of existing [pb/record.proto pb/record.pb.go pb/note.proto pb/legacy/item.proto pb/legacy/item.pb.go] and generated [pb/record.proto pb/record.pb.go], the plan deletes pb/note.proto and pb/legacy/item.pb.go and, with a gst.yaml prune.ignore entry pb/legacy in protect, keeps pb/legacy/item.proto under Ignored: an entry keeps the definitions alone. The files are the models' mirror, rewritten by every gg gen, so unlike a service file nothing in them is the project's to keep, but for the numbers and names a definition reserves: gg gen deletes the stale Go files itself, as it writes, and leaves the definitions to prune, which warns of the reservations going with them.
Only a file opening with the header gg gen writes, "// Code generated by gst; DO NOT EDIT.", is gg's to delete; one opening with anything else, the stubs a project compiled itself for a service it calls, fails the plan, naming every such file. Of existing [pb/record.proto pb/upstream/upstream.pb.go pb/upstream/upstream_grpc.pb.go pb/legacy/client.proto], none of the last three opening with the header, and generated pb/record.proto, with the entry pb/legacy in protect, the plan fails with
files under pb/ named like the ones gg gen writes but not generated by gst: pb/upstream/upstream.pb.go, pb/upstream/upstream_grpc.pb.go; gg deletes only its own files there, so rename these or move them out of pb/
pb/legacy/client.proto being kept under the entry without being read.
type OrphanDir ¶
OrphanDir is a service directory no model owns, with the unmanaged files in it: the files cleaning it deletes, or, for a helper directory kept because live project code imports it, the files it holds.
func FindOrphanDirs ¶
func FindOrphanDirs(allModels []*modelinfo.Model, keptDirs map[string]bool, deleting []string, modulePath string, ignore gghelper.ProjectIgnore, protect ggconfig.PruneConfig) (orphans, keptHelpers []OrphanDir, keptFiles []string, err error)
FindOrphanDirs resolves service directory ownership and returns the orphan directories plus the helper directories kept because live project code still imports them, and the files of deleting kept along with those directories: a file inside a kept directory is part of the package the import needs, whatever it is named, and deleting it would break the build the directory is kept for. It reads the project's code through ignore, as gg check and gg gen do: code the project ignores keeps nothing. Directories in keptDirs hold service files of gst.yaml-ignored actions and are treated as owned; keptDirs may be nil. deleting are the files prune deletes besides the orphans' own, the service files of disabled actions and the middleware a removed module left behind; what they import keeps nothing. What the gst.yaml prune.ignore entries in protect cover is never an orphan. It returns an error, and no directories, when the imports of part of the code it reads cannot be read, because a directory or a file cannot be opened or its imports do not parse: an import it could not see might be all that keeps a directory.