Repository Interface and destination in different packages from Model
Nice generator package!
Is your feature request related to a problem? Please describe. With dependency injection pattern, it's common that controller package defines the repository interface and accept it as input. However current implementation requires that repository interface and model type located within the same package.
Describe the solution you'd like It would be nice if it could support the setup like this.
examples/ref_exp
├── ctrl
│ └── ctrl.go
├── repo
│ └── user_repo.go // generated
└── user.go
// ctrl.go
package ctrl
//go:generate repogen -pkg=.. -dest=../repo/user_repo.go -model=UserModel -repo=UserRepository
// UserRepository is an interface that describes the specification of querying
// user data in the database.
type UserRepository interface {
// InsertOne stores userModel into the database and returns inserted ID
// if insertion succeeds and returns error if insertion fails.
InsertOne(ctx context.Context, userModel *ref_exp.UserModel) (interface{}, error)
// FindByUsername queries user by username. If a user with specified
// username exists, the user will be returned. Otherwise, error will be
// returned.
FindByUsername(ctx context.Context, username string) (*ref_exp.UserModel, error)
...
}
func NewController(userRepo UserRepository ... )...
Additional context Just play around the code base. For this feature these might be related:
-
Package ID of where
Modellocated. (to be used inRepositoryGenerator.Imports()) - in
interfaceMethodParserthere are some operation mode checking. And about the type comparison. Not sure how to allow imported types like*ref_exp.UserModelin args and return. (Currently it will check withp.StructModel).
Great improvement proposal! I was trying to do that but for my use case, I don't need that at the moment. However, if you can work on this, here are the high-level specification that I want:
- When the model struct and the repository interface are in the different package,
-pkgflag should reference the package of the repository interface, not the model struct. The generator should be able to derive the location of the model struct automatically. -
-modelflag should be able to read the imported type, e.g.ref_exp.UserModel.
And for the detailed specification, I want to separate the responsibilities as follows:
-
internal/codepackage should be able to provide the imported packages (lazily is ok) -
internal/specpackage should be able to validate the referencing fields -
internal/mongopackage should be able to derive bson tags and construct the query
Thanks for the specification!
What I am thinking is:
-
package.Package- ~add field
Importsand collect all imports from extractedFile~ - add field
Pathto locate itself
- ~add field
- in
generateFromRequest, checkstructModelNameif it's from the same package.- if not, then parse package for structModel's package to read
structModel(roughly)
- if not, then parse package for structModel's package to read
- mongo generator will need additional import provide by
package.Path
However in step 2, I am not sure: given -mode=ref_exp.UserModel and package.Imports, how to locate the model go file ? go/parser need a file path, but what I got is package path.
(Update) might need something like go list -f '{{.Dir}}' "modelPackagePath"
would it be more feasible if provide the option flag like modelDirPtr ? inspired by https://github.com/dobyte/mongo-dao-generator
For step 1, how does it need to be changed? Are there any concerns?
And for step 2, I've just noticed that concern. In my opinion, -model-dir flag should be a possible option. I have ever thought about -pkgs flag that read multiple packages and construct references by itself. It should be able to support the case that the model references a struct in a third package, but it may be too complicated.
thanks for the prompt reply
Then I will add -model-dir as flag.
for step 1,
-
Pathis required for model pkg import in generated code (step 3). - no need
Importsanymore since-model-dirshould be enough
I also found destPkgName := flag.String("dest-pkg", "", "destination package name") might also needed :P
Resolved in https://github.com/sunboyy/repogen/pull/49