Skip to content

Commit 2e0e6d8

Browse files
aaronctac0turtlekocubinski
authored
refactor(depinject/appconfig): remove api module dependency (#20931)
Co-authored-by: Marko <marko@baricevic.me> Co-authored-by: Matt Kocubinski <mkocubinski@gmail.com>
1 parent 64b3ebf commit 2e0e6d8

24 files changed

Lines changed: 2539 additions & 66 deletions

File tree

depinject/appconfig/config.go

Lines changed: 42 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,28 @@ import (
1010
"google.golang.org/protobuf/encoding/protojson"
1111
protov2 "google.golang.org/protobuf/proto"
1212
"google.golang.org/protobuf/reflect/protoreflect"
13+
"google.golang.org/protobuf/types/dynamicpb"
1314
"google.golang.org/protobuf/types/known/anypb"
1415
"sigs.k8s.io/yaml"
1516

16-
appv1alpha1 "cosmossdk.io/api/cosmos/app/v1alpha1"
1717
"cosmossdk.io/depinject"
18+
"cosmossdk.io/depinject/appconfig/v1alpha1"
1819
internal "cosmossdk.io/depinject/internal/appconfig"
1920
)
2021

2122
// LoadJSON loads an app config in JSON format.
2223
func LoadJSON(bz []byte) depinject.Config {
23-
config := &appv1alpha1.Config{}
24-
err := protojson.UnmarshalOptions{
24+
// in order to avoid a direct dependency on api types, but in order to also be able to support
25+
// either gogo or google.golang.org/protobuf types, we use protojson and dynamicpb to unmarshal
26+
// from JSON
27+
resolver := gogoproto.HybridResolver
28+
desc, err := resolver.FindDescriptorByName(protoreflect.FullName(gogoproto.MessageName(&v1alpha1.Config{})))
29+
if err != nil {
30+
return depinject.Error(err)
31+
}
32+
33+
config := dynamicpb.NewMessage(desc.(protoreflect.MessageDescriptor))
34+
err = protojson.UnmarshalOptions{
2535
Resolver: dynamicTypeResolver{resolver: gogoproto.HybridResolver},
2636
}.Unmarshal(bz, config)
2737
if err != nil {
@@ -51,9 +61,27 @@ func WrapAny(config protoreflect.ProtoMessage) *anypb.Any {
5161
return cfg
5262
}
5363

54-
// Compose composes a v1alpha1 app config into a container option by resolving
55-
// the required modules and composing their options.
56-
func Compose(appConfig *appv1alpha1.Config) depinject.Config {
64+
// Compose composes an app config into a container option by resolving
65+
// the required modules and composing their options. appConfig should be an instance
66+
// of cosmos.app.v1alpha1.Config (it doesn't matter whether you use gogo proto or
67+
// google.golang.org/protobuf types).
68+
func Compose(appConfig gogoproto.Message) depinject.Config {
69+
appConfigConcrete, ok := appConfig.(*v1alpha1.Config)
70+
if !ok {
71+
// we convert any other proto type that was passed (such as an api module type) to the concrete
72+
// type we're using here
73+
appConfigConcrete = &v1alpha1.Config{}
74+
bz, err := gogoproto.Marshal(appConfig)
75+
if err != nil {
76+
return depinject.Error(err)
77+
}
78+
79+
err = gogoproto.Unmarshal(bz, appConfigConcrete)
80+
if err != nil {
81+
return depinject.Error(err)
82+
}
83+
}
84+
5785
opts := []depinject.Config{
5886
depinject.Supply(appConfig),
5987
}
@@ -63,7 +91,7 @@ func Compose(appConfig *appv1alpha1.Config) depinject.Config {
6391
return depinject.Error(err)
6492
}
6593

66-
for _, module := range appConfig.Modules {
94+
for _, module := range appConfigConcrete.Modules {
6795
if module.Name == "" {
6896
return depinject.Error(fmt.Errorf("module is missing name"))
6997
}
@@ -84,10 +112,14 @@ func Compose(appConfig *appv1alpha1.Config) depinject.Config {
84112
init, ok := modules[msgName]
85113
if !ok {
86114
if msgDesc, err := gogoproto.HybridResolver.FindDescriptorByName(protoreflect.FullName(msgName)); err == nil {
87-
modDesc := protov2.GetExtension(msgDesc.Options(), appv1alpha1.E_Module).(*appv1alpha1.ModuleDescriptor)
115+
modDesc, err := internal.GetModuleDescriptor(msgDesc)
116+
if err != nil {
117+
return depinject.Error(err)
118+
}
119+
88120
if modDesc == nil {
89121
return depinject.Error(fmt.Errorf("no module registered for type URL %s and that protobuf type does not have the option %s\n\n%s",
90-
module.Config.TypeUrl, appv1alpha1.E_Module.TypeDescriptor().FullName(), dumpRegisteredModules(modules)))
122+
module.Config.TypeUrl, v1alpha1.E_Module.Name, dumpRegisteredModules(modules)))
91123
}
92124

93125
return depinject.Error(fmt.Errorf("no module registered for type URL %s, did you forget to import %s: find more information on how to make a module ready for app wiring: https://docs.cosmos.network/main/building-modules/depinject\n\n%s",
@@ -122,7 +154,7 @@ func Compose(appConfig *appv1alpha1.Config) depinject.Config {
122154
}
123155
}
124156

125-
for _, binding := range appConfig.GolangBindings {
157+
for _, binding := range appConfigConcrete.GolangBindings {
126158
opts = append(opts, depinject.BindInterface(binding.InterfaceType, binding.Implementation))
127159
}
128160

0 commit comments

Comments
 (0)