Skip to content

Commit

Permalink
Intermediate commit
Browse files Browse the repository at this point in the history
  • Loading branch information
bdragon300 committed Dec 14, 2024
1 parent 22640f3 commit 731c00c
Show file tree
Hide file tree
Showing 109 changed files with 1,593 additions and 1,581 deletions.
16 changes: 8 additions & 8 deletions assets/default_config.yaml
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
render:
selections:
- objectKindRe: schema
file: schemas/{{.Name | toSnakeCase}}.go
file: schemas/{{. | goid | toSnakeCase}}.go
- objectKindRe: parameter
file: parameters/{{.Name | toSnakeCase}}.go
file: parameters/{{. | goid | toSnakeCase}}.go
- objectKindRe: channel
file: channels/{{.Name | toSnakeCase}}.go
file: channels/{{. | goid | toSnakeCase}}.go
- objectKindRe: protoChannel
file: channels/{{.Name | toSnakeCase}}.go
file: channels/{{. | goid | toSnakeCase}}.go
- objectKindRe: server
file: servers/{{.Name | toSnakeCase}}.go
file: servers/{{. | goid | toSnakeCase}}.go
- objectKindRe: protoServer
file: servers/{{.Name | toSnakeCase}}.go
file: servers/{{. | goid | toSnakeCase}}.go
- objectKindRe: message
file: messages/{{.Name | toSnakeCase}}.go
file: messages/{{. | goid | toSnakeCase}}.go
- objectKindRe: protoMessage
file: messages/{{.Name | toSnakeCase}}.go
file: messages/{{. | goid | toSnakeCase}}.go
31 changes: 20 additions & 11 deletions cmd/go-asyncapi/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ type GenerateCmd struct {
type generatePubSubArgs struct {
Spec string `arg:"required,positional" help:"AsyncAPI specification file path or url" placeholder:"PATH"`

ProjectModule string `arg:"-M,--project-module" help:"Project module name to use [default: extracted from go.mod file in the current working directory]" placeholder:"MODULE"`
ProjectModule string `arg:"-M,--module" help:"Module path to use [default: extracted from go.mod file in the current working directory concatenated with target dir]" placeholder:"MODULE"`
TemplateDir string `arg:"--template-dir" help:"Directory with custom templates" placeholder:"DIR"`
ConfigFile string `arg:"--config-file" help:"YAML configuration file path" placeholder:"PATH"`
generateObjectSelectionOpts
Expand Down Expand Up @@ -154,7 +154,7 @@ func generate(cmd *GenerateCmd) error {
}

// Rendering
files, err := writer.RenderPackages(mainModule, renderOpts)
files, err := writer.RenderFiles(mainModule, renderOpts)
if err != nil {
return fmt.Errorf("schema render: %w", err)
}
Expand Down Expand Up @@ -304,7 +304,7 @@ func generationWriteImplementations(selectedImpls map[string]string, protocols [
return nil
}

func getImportBase() (string, error) {
func getProjectModule() (string, error) {
pwd, err := os.Getwd()
if err != nil {
return "", fmt.Errorf("cannot get current working directory: %w", err)
Expand Down Expand Up @@ -437,7 +437,12 @@ func getRenderOpts(opts generatePubSubArgs, targetDir string) (common.RenderOpts
return res, err
}
for _, item := range conf.Render.Selections {
pkg, _ := lo.Coalesce(item.Package, lo.Ternary(targetDir != "", path.Base(targetDir), defaultPackage))
pkg, _ := lo.Coalesce(
item.Package,
lo.Ternary(path.Dir(item.File) != ".", path.Dir(item.File), ""),
lo.Ternary(targetDir != "", path.Base(targetDir), ""),
defaultPackage,
)
templateName, _ := lo.Coalesce(item.Template,defaultTemplate)
sel := common.RenderSelectionConfig{
Template: templateName,
Expand All @@ -453,16 +458,20 @@ func getRenderOpts(opts generatePubSubArgs, targetDir string) (common.RenderOpts
}

// ImportBase
importBase := opts.ProjectModule
if importBase == "" {
b, err := getImportBase()
res.ImportBase = opts.ProjectModule
if res.ImportBase == "" {
m, err := getProjectModule()
if err != nil {
return res, fmt.Errorf("determine project's module (use -M arg to override): %w", err)
return res, fmt.Errorf("getting project module from ./go.mod (use -M arg to override): %w", err)
}
importBase = b
// Clean path and remove empty, current and parent directories, leaving only names
// This is not a best solution, however, it should work for most cases. Moreover, user can always override it.
parts := lo.Filter(strings.Split(path.Clean(targetDir), string(os.PathSeparator)), func(s string, _ int) bool {
return !lo.Contains([]string{"", ".", ".."}, s)
})
res.ImportBase = path.Join(m, path.Join(parts...))
}
mainLogger.Debugf("Target import base is %s", importBase)
res.ImportBase = importBase
mainLogger.Debugf("Target import base is %s", res.ImportBase)

return res, nil
}
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ require (
github.com/gobwas/httphead v0.1.0 // indirect
github.com/gobwas/pool v0.2.1 // indirect
github.com/gorilla/websocket v1.5.1 // indirect
github.com/iancoleman/strcase v0.3.0 // indirect
github.com/klauspost/compress v1.17.8 // indirect
github.com/kr/pretty v0.3.1 // indirect
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWm
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY=
github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY=
github.com/iancoleman/strcase v0.3.0 h1:nTXanmYxhfFAMjZL34Ov6gkzEsSJZ5DbhxWjvSASxEI=
github.com/iancoleman/strcase v0.3.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho=
github.com/klauspost/compress v1.17.4 h1:Ej5ixsIri7BrIjBkRZLTo6ghwrEtHFk7ijlczPW4fZ4=
github.com/klauspost/compress v1.17.4/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM=
github.com/klauspost/compress v1.17.8 h1:YcnTYrq7MikUT7k0Yb5eceMmALQPYBW/Xltxn0NAMnU=
Expand Down
34 changes: 17 additions & 17 deletions internal/asyncapi/amqp/channel.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,9 @@ func (pb ProtoBuilder) BuildChannel(ctx *common.CompileContext, channel *asyncap

chanStruct.Fields = append(
chanStruct.Fields,
lang.GoStructField{Name: "exchange", Type: &lang.GoSimple{Name: "string"}},
lang.GoStructField{Name: "queue", Type: &lang.GoSimple{Name: "string"}},
lang.GoStructField{Name: "routingKey", Type: &lang.GoSimple{Name: "string"}},
lang.GoStructField{Name: "exchange", Type: &lang.GoSimple{OriginalName: "string"}},
lang.GoStructField{Name: "queue", Type: &lang.GoSimple{OriginalName: "string"}},
lang.GoStructField{Name: "routingKey", Type: &lang.GoSimple{OriginalName: "string"}},
)

return &render.ProtoChannel{
Expand All @@ -76,30 +76,30 @@ func (pb ProtoBuilder) BuildChannelBindings(ctx *common.CompileContext, rawData
return
}

vals = &lang.GoValue{Type: &lang.GoSimple{Name: "ChannelBindings", Import: ctx.RuntimeModule(pb.ProtoName)}, EmptyCurlyBrackets: true}
vals = &lang.GoValue{Type: &lang.GoSimple{OriginalName: "ChannelBindings", Import: ctx.RuntimeModule(pb.ProtoName)}, EmptyCurlyBrackets: true}
switch bindings.Is {
case "queue":
vals.StructValues.Set("ChannelType", &lang.GoSimple{Name: "ChannelTypeQueue", Import: ctx.RuntimeModule(pb.ProtoName)})
vals.StructValues.Set("ChannelType", &lang.GoSimple{OriginalName: "ChannelTypeQueue", Import: ctx.RuntimeModule(pb.ProtoName)})
default: // routingKey and any other value
vals.StructValues.Set("ChannelType", &lang.GoSimple{Name: "ChannelTypeRoutingKey", Import: ctx.RuntimeModule(pb.ProtoName)})
vals.StructValues.Set("ChannelType", &lang.GoSimple{OriginalName: "ChannelTypeRoutingKey", Import: ctx.RuntimeModule(pb.ProtoName)})
}
if bindings.Exchange != nil {
ecVals := lang.ConstructGoValue(*bindings.Exchange, []string{"Type"}, &lang.GoSimple{Name: "ExchangeConfiguration", Import: ctx.RuntimeModule(pb.ProtoName)})
ecVals := lang.ConstructGoValue(*bindings.Exchange, []string{"Type"}, &lang.GoSimple{OriginalName: "ExchangeConfiguration", Import: ctx.RuntimeModule(pb.ProtoName)})
switch bindings.Exchange.Type {
case "default":
ecVals.StructValues.Set("Type", &lang.GoSimple{Name: "ExchangeTypeDefault", Import: ctx.RuntimeModule(pb.ProtoName)})
ecVals.StructValues.Set("Type", &lang.GoSimple{OriginalName: "ExchangeTypeDefault", Import: ctx.RuntimeModule(pb.ProtoName)})
case "topic":
ecVals.StructValues.Set("Type", &lang.GoSimple{Name: "ExchangeTypeTopic", Import: ctx.RuntimeModule(pb.ProtoName)})
ecVals.StructValues.Set("Type", &lang.GoSimple{OriginalName: "ExchangeTypeTopic", Import: ctx.RuntimeModule(pb.ProtoName)})
case "direct":
ecVals.StructValues.Set("Type", &lang.GoSimple{Name: "ExchangeTypeDirect", Import: ctx.RuntimeModule(pb.ProtoName)})
ecVals.StructValues.Set("Type", &lang.GoSimple{OriginalName: "ExchangeTypeDirect", Import: ctx.RuntimeModule(pb.ProtoName)})
case "fanout":
ecVals.StructValues.Set("Type", &lang.GoSimple{Name: "ExchangeTypeFanout", Import: ctx.RuntimeModule(pb.ProtoName)})
ecVals.StructValues.Set("Type", &lang.GoSimple{OriginalName: "ExchangeTypeFanout", Import: ctx.RuntimeModule(pb.ProtoName)})
case "headers":
ecVals.StructValues.Set("Type", &lang.GoSimple{Name: "ExchangeTypeHeaders", Import: ctx.RuntimeModule(pb.ProtoName)})
ecVals.StructValues.Set("Type", &lang.GoSimple{OriginalName: "ExchangeTypeHeaders", Import: ctx.RuntimeModule(pb.ProtoName)})
}
vals.StructValues.Set("ExchangeConfiguration", ecVals)
}
qVals := lang.ConstructGoValue(*bindings.Queue, nil, &lang.GoSimple{Name: "QueueConfiguration", Import: ctx.RuntimeModule(pb.ProtoName)})
qVals := lang.ConstructGoValue(*bindings.Queue, nil, &lang.GoSimple{OriginalName: "QueueConfiguration", Import: ctx.RuntimeModule(pb.ProtoName)})
vals.StructValues.Set("QueueConfiguration", qVals)

return
Expand All @@ -112,16 +112,16 @@ func (pb ProtoBuilder) BuildOperationBindings(ctx *common.CompileContext, rawDat
return
}

vals = lang.ConstructGoValue(bindings, []string{"Expiration", "DeliveryMode"}, &lang.GoSimple{Name: "OperationBindings", Import: ctx.RuntimeModule(pb.ProtoName)})
vals = lang.ConstructGoValue(bindings, []string{"Expiration", "DeliveryMode"}, &lang.GoSimple{OriginalName: "OperationBindings", Import: ctx.RuntimeModule(pb.ProtoName)})
if bindings.Expiration > 0 {
v := lang.ConstructGoValue(bindings.Expiration*int(time.Millisecond), nil, &lang.GoSimple{Name: "Duration", Import: "time"})
v := lang.ConstructGoValue(bindings.Expiration*int(time.Millisecond), nil, &lang.GoSimple{OriginalName: "Duration", Import: "time"})
vals.StructValues.Set("Expiration", v)
}
switch bindings.DeliveryMode {
case 1:
vals.StructValues.Set("DeliveryMode", &lang.GoSimple{Name: "DeliveryModeTransient", Import: ctx.RuntimeModule(pb.ProtoName)})
vals.StructValues.Set("DeliveryMode", &lang.GoSimple{OriginalName: "DeliveryModeTransient", Import: ctx.RuntimeModule(pb.ProtoName)})
case 2:
vals.StructValues.Set("DeliveryMode", &lang.GoSimple{Name: "DeliveryModePersistent", Import: ctx.RuntimeModule(pb.ProtoName)})
vals.StructValues.Set("DeliveryMode", &lang.GoSimple{OriginalName: "DeliveryModePersistent", Import: ctx.RuntimeModule(pb.ProtoName)})
}

return
Expand Down
2 changes: 1 addition & 1 deletion internal/asyncapi/amqp/message.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,6 @@ func (pb ProtoBuilder) BuildMessageBindings(ctx *common.CompileContext, rawData
return
}

vals = lang.ConstructGoValue(bindings, nil, &lang.GoSimple{Name: "MessageBindings", Import: ctx.RuntimeModule(pb.ProtoName)})
vals = lang.ConstructGoValue(bindings, nil, &lang.GoSimple{OriginalName: "MessageBindings", Import: ctx.RuntimeModule(pb.ProtoName)})
return
}
4 changes: 2 additions & 2 deletions internal/asyncapi/bindings.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,12 @@ func (b *Bindings) build(
) (common.Renderable, error) {
if b.Ref != "" {
ctx.Logger.Trace("Ref", "$ref", b.Ref)
res := lang.NewRenderablePromise(b.Ref, common.PromiseOriginUser)
res := lang.NewUserPromise(b.Ref, bindingsKey, nil)
ctx.PutPromise(res)
return res, nil
}

res := render.Bindings{Name: bindingsKey}
res := render.Bindings{OriginalName: bindingsKey}
for _, e := range b.ProtocolValues.Entries() {
ctx.Logger.Trace("Bindings", "proto", e.Key)
builder, ok := ProtocolBuilders[e.Key]
Expand Down
50 changes: 26 additions & 24 deletions internal/asyncapi/channel.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,42 +27,44 @@ type Channel struct {

func (c Channel) Compile(ctx *common.CompileContext) error {
ctx.RegisterNameTop(ctx.Stack.Top().PathItem)
obj, err := c.buildChannels(ctx, ctx.Stack.Top().PathItem)
obj, err := c.build(ctx, ctx.Stack.Top().PathItem, ctx.Stack.Top().Flags)
if err != nil {
return err
}
ctx.PutObject(obj)
if v, ok := obj.(*render.ProtoChannel); ok {
ctx.Logger.Trace("ProtoObjects", "object", obj)
for _, protoObj := range v.ProtoChannels {
ctx.PutObject(protoObj)
}
}
//if v, ok := obj.(*render.Channel); ok {
// ctx.Logger.Trace("Objects", "object", obj)
// for _, protoObj := range v.ProtoChannels {
// ctx.PutObject(protoObj)
// }
//}
return nil
}

func (c Channel) buildChannels(ctx *common.CompileContext, channelKey string) (common.Renderable, error) {
func (c Channel) build(ctx *common.CompileContext, channelKey string, flags map[common.SchemaTag]string) (common.Renderable, error) {
ignore := c.XIgnore ||
(!ctx.CompileOpts.GeneratePublishers && !ctx.CompileOpts.GenerateSubscribers) // ||
//!ctx.CompileOpts.ChannelOpts.IsAllowedName(channelKey)
_, isComponent := flags[common.SchemaTagComponent]
if ignore {
ctx.Logger.Debug("Channel denoted to be ignored")
return &render.Channel{Dummy: true}, nil
}
if c.Ref != "" {
ctx.Logger.Trace("Ref", "$ref", c.Ref)
prm := lang.NewRenderablePromise(c.Ref, common.PromiseOriginUser)
// Set a channel to be rendered if we reference it from `channels` document section
// Always draw the promises that are located in the `channels` section
prm := lang.NewUserPromise(c.Ref, channelKey, lo.Ternary(isComponent, nil, lo.ToPtr(true)))
ctx.PutPromise(prm)
return prm, nil
}

chName, _ := lo.Coalesce(c.XGoName, channelKey)
// Render only the channels defined directly in `channels` document section, not in `components`
res := &render.Channel{
Name: chName,
TypeNamePrefix: ctx.GenerateObjName(chName, ""),
SpecKey: channelKey,
OriginalName: chName,
TypeNamePrefix: ctx.GenerateObjName(chName, ""),
SpecKey: channelKey,
IsComponent: isComponent,
}

// Channel parameters
Expand All @@ -71,14 +73,14 @@ func (c Channel) buildChannels(ctx *common.CompileContext, channelKey string) (c
ctx.Logger.NextCallLevel()
res.ParametersType = &lang.GoStruct{
BaseType: lang.BaseType{
Name: ctx.GenerateObjName(chName, "Parameters"),
OriginalName: ctx.GenerateObjName(chName, "Parameters"),
HasDefinition: true,
},
}
for _, paramName := range c.Parameters.Keys() {
ctx.Logger.Trace("Channel parameter", "name", paramName)
ref := ctx.PathStackRef("parameters", paramName)
prm := lang.NewGolangTypeAssignCbPromise(ref, common.PromiseOriginInternal, func(obj any) common.GolangType {
prm := lang.NewInternalGolangTypeAssignCbPromise(ref, func(obj any) common.GolangType {
return obj.(*render.Parameter).Type
})
ctx.PutPromise(prm)
Expand All @@ -100,7 +102,7 @@ func (c Channel) buildChannels(ctx *common.CompileContext, channelKey string) (c
if !ok {
return false
}
return lo.Contains(*c.Servers, srv.Name)
return lo.Contains(*c.Servers, srv.OriginalName)
})
res.ServersPromise = prm
ctx.PutListPromise(prm)
Expand All @@ -121,7 +123,7 @@ func (c Channel) buildChannels(ctx *common.CompileContext, channelKey string) (c
hasBindings = true

ref := ctx.PathStackRef("bindings")
res.BindingsChannelPromise = lang.NewPromise[*render.Bindings](ref, common.PromiseOriginInternal)
res.BindingsChannelPromise = lang.NewInternalPromise[*render.Bindings](ref)
ctx.PutPromise(res.BindingsChannelPromise)
}

Expand All @@ -134,13 +136,13 @@ func (c Channel) buildChannels(ctx *common.CompileContext, channelKey string) (c
hasBindings = true

ref := ctx.PathStackRef("publish", "bindings")
res.BindingsPublishPromise = lang.NewPromise[*render.Bindings](ref, common.PromiseOriginInternal)
res.BindingsPublishPromise = lang.NewInternalPromise[*render.Bindings](ref)
ctx.PutPromise(res.BindingsPublishPromise)
}
if c.Publish.Message != nil {
ctx.Logger.Trace("Found publish operation message")
ref := ctx.PathStackRef("publish", "message")
res.PublisherMessageTypePromise = lang.NewPromise[*render.Message](ref, common.PromiseOriginInternal)
res.PublisherMessageTypePromise = lang.NewInternalPromise[*render.Message](ref)
ctx.PutPromise(res.PublisherMessageTypePromise)
}
}
Expand All @@ -151,27 +153,27 @@ func (c Channel) buildChannels(ctx *common.CompileContext, channelKey string) (c
hasBindings = true

ref := ctx.PathStackRef("subscribe", "bindings")
res.BindingsSubscribePromise = lang.NewPromise[*render.Bindings](ref, common.PromiseOriginInternal)
res.BindingsSubscribePromise = lang.NewInternalPromise[*render.Bindings](ref)
ctx.PutPromise(res.BindingsSubscribePromise)
}
if c.Subscribe.Message != nil {
ctx.Logger.Trace("Channel subscribe operation message")
ref := ctx.PathStackRef("subscribe", "message")
res.SubscribeMessageTypePromise = lang.NewPromise[*render.Message](ref, common.PromiseOriginInternal)
ctx.PutPromise(res.SubscribeMessageTypePromise)
res.SubscriberMessageTypePromise = lang.NewInternalPromise[*render.Message](ref)
ctx.PutPromise(res.SubscriberMessageTypePromise)
}
}
if hasBindings {
res.BindingsType = &lang.GoStruct{
BaseType: lang.BaseType{
Name: ctx.GenerateObjName(chName, "Bindings"),
OriginalName: ctx.GenerateObjName(chName, "Bindings"),
HasDefinition: true,
},
}
}

// Build protocol-specific channels for all supported protocols
// Here we don't know yet which servers this channel is applied to, so we don't have the protocols list to compile.
// At this point we don't know yet which servers this channel is applied to, so we don't have the protocols list to compile.
// Servers will be known on rendering stage (after linking), but there we will already need to have proto
// channels to be compiled for certain protocols we want to render.
// As a solution, here we just build the proto channels for all supported protocols
Expand Down
4 changes: 2 additions & 2 deletions internal/asyncapi/correlationid.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ func (c CorrelationID) build(ctx *common.CompileContext, correlationIDKey string
// TODO: move this ref code from everywhere to single place?
if c.Ref != "" {
ctx.Logger.Trace("Ref", "$ref", c.Ref)
res := lang.NewRenderablePromise(c.Ref, common.PromiseOriginUser)
res := lang.NewUserPromise(c.Ref, correlationIDKey, nil)
ctx.PutPromise(res)
return res, nil
}
Expand Down Expand Up @@ -75,7 +75,7 @@ func (c CorrelationID) build(ctx *common.CompileContext, correlationIDKey string
ctx.Logger.Trace("CorrelationID object", "messageField", structField, "path", locationPath)

return &render.CorrelationID{
Name: correlationIDKey,
OriginalName: correlationIDKey,
Description: c.Description,
StructField: structField,
LocationPath: locationPath,
Expand Down
4 changes: 2 additions & 2 deletions internal/asyncapi/extra.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ func buildXGoType(xGoTypeValue *types.Union2[string, xGoType]) (golangType commo

switch xGoTypeValue.Selector {
case 0:
t.Name = xGoTypeValue.V0
t.OriginalName = xGoTypeValue.V0
case 1:
t.Name = xGoTypeValue.V1.Type
t.OriginalName = xGoTypeValue.V1.Type
t.Import = xGoTypeValue.V1.Import.Package
t.IsInterface = xGoTypeValue.V1.Hint.Kind == "interface"

Expand Down
2 changes: 1 addition & 1 deletion internal/asyncapi/http/channel.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ func (pb ProtoBuilder) BuildOperationBindings(ctx *common.CompileContext, rawDat
return
}

vals = lang.ConstructGoValue(bindings, []string{"Query"}, &lang.GoSimple{Name: "OperationBindings", Import: ctx.RuntimeModule(pb.ProtoName)})
vals = lang.ConstructGoValue(bindings, []string{"Query"}, &lang.GoSimple{OriginalName: "OperationBindings", Import: ctx.RuntimeModule(pb.ProtoName)})
if bindings.Query != nil {
v, err2 := json.Marshal(bindings.Query)
if err2 != nil {
Expand Down
Loading

0 comments on commit 731c00c

Please sign in to comment.