From 94e2dbd7c6e7092b49d683a06d0cd4f755456895 Mon Sep 17 00:00:00 2001 From: David Bloss <david@opslevel.com> Date: Tue, 7 Jan 2025 09:15:34 -0600 Subject: [PATCH] generate unions (#505) * generate unions * drop unused TagOwner enums * union tpl clean up --- check.go | 5 ---- document.go | 5 ---- gen.go | 42 ++++++++++++++++++--------------- owner.go | 4 ---- tags.go | 7 ------ templates/unions.tpl | 40 +++++++++++++++++++++++++++++++ union.go | 56 ++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 119 insertions(+), 40 deletions(-) create mode 100644 templates/unions.tpl create mode 100644 union.go diff --git a/check.go b/check.go index f3a78845..716adbfc 100644 --- a/check.go +++ b/check.go @@ -10,11 +10,6 @@ import ( "github.com/relvacode/iso8601" ) -type CheckOwner struct { - Team TeamId `graphql:"... on Team"` - // User User `graphql:"... on User"` // TODO: will this be public? -} - type CheckInputConstructor func() any var CheckCreateConstructors = map[CheckType]CheckInputConstructor{ diff --git a/document.go b/document.go index 80316aab..7ca62cb8 100644 --- a/document.go +++ b/document.go @@ -1,10 +1,5 @@ package opslevel -type ServiceDocumentSource struct { - IntegrationId `graphql:"... on ApiDocIntegration"` - ServiceRepository `graphql:"... on ServiceRepository"` -} - type ServiceDocument struct { Id ID `graphql:"id" json:"id"` HtmlURL string `graphql:"htmlUrl" json:"htmUrl,omitempty"` diff --git a/gen.go b/gen.go index 9a0593d6..fe9934de 100644 --- a/gen.go +++ b/gen.go @@ -32,7 +32,6 @@ const ( mutationFile string = "mutation.go" payloadFile string = "payload.go" // scalarFile string = "scalar.go" // NOTE: probably not useful - // unionFile string = "union.go" // NOTE: probably not useful ) var knownTypeIsName = []string{ @@ -285,6 +284,7 @@ func main() { panic(fmt.Errorf("Unknown GraphQL type: %v", v)) } } + genUnions(unions) genObjects(objects) genEnums(schemaAst.Enums) genInputObjects(inputObjects) @@ -310,6 +310,28 @@ func sortedMapKeys[T any](schemaMap map[string]T) []string { return sortedNames } +func genUnions(unions map[string]*types.Union) { + var buf bytes.Buffer + + buf.WriteString(header + "\n\n") + + tmpl := template.New("unions") + tmpl.Funcs(sprig.TxtFuncMap()) + tmpl.Funcs(templFuncMap) + template.Must(tmpl.ParseFiles("./templates/unions.tpl")) + for _, union := range sortedMapKeys(unions) { + if err := tmpl.ExecuteTemplate(&buf, "union", unions[union]); err != nil { + panic(err) + } + } + + fmt.Println("writing union.go") + err := os.WriteFile("union.go", buf.Bytes(), 0o644) + if err != nil { + panic(err) + } +} + func genEnums(schemaEnums []*types.EnumTypeDefinition) { var buf bytes.Buffer @@ -472,8 +494,6 @@ func run() error { subSchema = objectSchema // case scalarFile: // subSchema = scalarSchema - // case unionFile: - // subSchema = unionSchema default: panic("Unknown file: " + filename) } @@ -867,21 +887,6 @@ var templates = map[string]*template.Template{ // func NewString(value string) *string { // return &value // }`), - // unionFile: t(header + ` - // {{range .Types | sortByName}}{{if and (eq .Kind "UNION") (not (internal .Name))}} - // {{template "union_object" .}} - // {{end}}{{end}} - - // {{- define "union_object" -}} - // // Union{{.Name}} {{ template "description" . }} - // type Union{{.Name}} interface { {{range .PossibleTypes }} - // - // {{.Name}}Fragment() {{.Name}}Fragment{{end}} - // } - // - // {{- end -}} - // - // `), } func t(text string) *template.Template { @@ -1252,7 +1257,6 @@ func firstCharLowered(s string) string { var templFuncMap = template.FuncMap{ "internal": func(s string) bool { return strings.HasPrefix(s, "__") }, "quote": strconv.Quote, - "join": strings.Join, "check_fragments": fragmentsForCheck, "custom_actions_ext_action_fragments": fragmentsForCustomActionsExtAction, "integration_fragments": fragmentsForIntegration, diff --git a/owner.go b/owner.go index 304ab664..050db146 100644 --- a/owner.go +++ b/owner.go @@ -5,10 +5,6 @@ type EntityOwnerTeam struct { Id ID `json:"id"` } -type EntityOwner struct { - OnTeam EntityOwnerTeam `graphql:"... on Team"` -} - func (entityOwner *EntityOwner) Alias() string { return entityOwner.OnTeam.Alias } diff --git a/tags.go b/tags.go index 9f106232..0c302430 100644 --- a/tags.go +++ b/tags.go @@ -7,13 +7,6 @@ import ( "slices" ) -type TagOwner string - -const ( - TagOwnerService TagOwner = "Service" - TagOwnerRepository TagOwner = "Repository" -) - type TaggableResourceInterface interface { GetTags(*Client, *PayloadVariables) (*TagConnection, error) ResourceId() ID diff --git a/templates/unions.tpl b/templates/unions.tpl new file mode 100644 index 00000000..9e7ab896 --- /dev/null +++ b/templates/unions.tpl @@ -0,0 +1,40 @@ +{{- define "union" }} +// {{ title .Name }} {{.Desc | clean | endSentence}} + {{- if eq "CheckOwner" .Name }} + {{ template "check_owner" }} + {{- else if eq "EntityOwner" .Name }} + {{ template "entity_owner" }} + {{- else if eq "ServiceDocumentSource" .Name }} + {{ template "service_document_source" }} + {{- else }} +type {{.Name}} struct { + {{ range .TypeNames }} + {{- if not (contains "Group" . ) }} + {{.}} {{. -}} + {{- if not (contains . (list "ApiDocIntegration" "InfrastructureResource" "ServiceRepository" | join " " )) -}}Id + {{- end }} `graphql:"... on {{.}}"` + {{- end }} + {{- end }} +} + {{- end }} +{{- end -}} + +{{- define "check_owner" -}} +type CheckOwner struct { + Team TeamId `graphql:"... on Team"` + // User UserId `graphql:"... on User"` // TODO: will this be public? +} +{{ end }} + +{{- define "entity_owner" -}} +type EntityOwner struct { + OnTeam EntityOwnerTeam `graphql:"... on Team"` +} +{{ end }} + +{{- define "service_document_source" -}} +type ServiceDocumentSource struct { + IntegrationId `graphql:"... on ApiDocIntegration"` + ServiceRepository `graphql:"... on ServiceRepository"` +} +{{ end }} diff --git a/union.go b/union.go new file mode 100644 index 00000000..ccbc7632 --- /dev/null +++ b/union.go @@ -0,0 +1,56 @@ +// Code generated by gen.go; DO NOT EDIT. + +package opslevel + +// CheckOwner represents the owner a check can belong to. +type CheckOwner struct { + Team TeamId `graphql:"... on Team"` + // User UserId `graphql:"... on User"` // TODO: will this be public? +} + +// CodeIssueProjectResource represents resource linked to the CodeIssueProject. Can be either Service or Repository. +type CodeIssueProjectResource struct { + Repository Repository `graphql:"... on Repository"` + Service Service `graphql:"... on Service"` +} + +// ContactOwner represents the owner of this contact. +type ContactOwner struct { + Team TeamId `graphql:"... on Team"` + User UserId `graphql:"... on User"` +} + +// CustomActionsAssociatedObject represents the object that an event was triggered on. +type CustomActionsAssociatedObject struct { + Service Service `graphql:"... on Service"` +} + +// EntityOwner represents the Group or Team owning the entity. +type EntityOwner struct { + OnTeam EntityOwnerTeam `graphql:"... on Team"` +} + +// RelationshipResource represents a resource that can have relationships to other resources. +type RelationshipResource struct { + Domain DomainId `graphql:"... on Domain"` + InfrastructureResource InfrastructureResource `graphql:"... on InfrastructureResource"` + Service Service `graphql:"... on Service"` + System SystemId `graphql:"... on System"` +} + +// ServiceDocumentSource represents the source of a document. +type ServiceDocumentSource struct { + IntegrationId `graphql:"... on ApiDocIntegration"` + ServiceRepository `graphql:"... on ServiceRepository"` +} + +// TagOwner represents a resource that a tag can be applied to. +type TagOwner struct { + Domain DomainId `graphql:"... on Domain"` + InfrastructureResource InfrastructureResource `graphql:"... on InfrastructureResource"` + Repository Repository `graphql:"... on Repository"` + Service Service `graphql:"... on Service"` + System SystemId `graphql:"... on System"` + Team TeamId `graphql:"... on Team"` + User UserId `graphql:"... on User"` +}