Avoid deleting non-generated files when re-generating.
Is your feature request related to a problem? Please describe. Adding convenience methods to generated model types is possible, by locating a file alongside the generated file. This allows me to, for example, create
// foo_conversion.go beside /db/jet/my_db/public/model/foo.go
func (a *Foo) ToProto() *pb.FooMessage {
return &pb.FooMessage{
PropA: a.PropA,
EnumB: a.EnumB.String(),
SomeNumber: a.SomeNumber.BigInt().Uint64(),
//...
}
}
so in my code, when I'm transforming a database row (model type) into a proto for a gRPC response, I can just say myFoo.ToProto(). Dealing with model types becomes vastly cleaner in calling code, when I can add these methods to do conversions, or other operations on them.
However, when I regenerate the files, the generator just blows away the jet directory entirely, forcing me to ensure I don't have uncommitted/indexed changes in my files
Describe the solution you'd like I would like the generator, when re-generating, to be more careful about what it deletes - instead of a bulk deletion of the directory, scan the directory and delete empty directories and files which are marked as generated by jet.
An alternative would be a list of paths or globs to ignore.
Instead of os.RemoveAll(schemaPath) here we could do something along the lines of:
func deleteIf(rootPath string, shouldDeleteFn func(path string) (bool, error)) error {
// Add appropriate error handling and maybe some logging
walkErr := filepath.WalkDir(rootPath, func(path string, d fs.DirEntry, err error) error {
// do something with err
// Skip symbolic links to avoid infinite loops or deleting outside the intended scope
if d.Type()&fs.ModeSymlink != 0 {
return nil
}
// Can lookup the breadcrumbs,
shouldDelete, err := shouldDeleteFn(path)
if err != nil {
return nil // keep walking - probably log this.
}
if shouldDelete {
err := os.Remove(path)
if err != nil {
log.Printf("Failed to delete %q: %v\n", path, err)
}
} else {
log.Printf("Keeping file: %s \n", path)
}
return nil
})
return walkErr // Returns any non-nil error from WalkDir itself
}
And then implement the shouldDeleteFn appropriately.
It is generally considered bad practice to keep code-generated files and regular code files in the same directory.
Cleaner patter to extend generated model functionalities is to wrap generated models.
For instance, you create a new package called domain, and import it instead of model package. The rest of code remains the same.
package domain
type Foo struct{
model.Foo
}
func (a *Foo) ToProto() *pb.FooMessage {
return &pb.FooMessage{
PropA: a.PropA,
EnumB: a.EnumB.String(),
SomeNumber: a.SomeNumber.BigInt().Uint64(),
//...
}
}
From the jet perspective model.Foo and domain.Foo are the same type and can be used interchangeably.