Skip to content

Commit

Permalink
add Void type
Browse files Browse the repository at this point in the history
Signed-off-by: Alex Suraci <alex@dagger.io>
  • Loading branch information
vito committed Jul 18, 2023
1 parent 114bff4 commit 51f5751
Show file tree
Hide file tree
Showing 11 changed files with 168 additions and 256 deletions.
7 changes: 5 additions & 2 deletions codegen/generator/go/templates/functions.go
Original file line number Diff line number Diff line change
Expand Up @@ -204,9 +204,12 @@ func fieldFunction(f introspection.Field) string {
signature += "(" + strings.Join(args, ", ") + ")"

retType := commonFunc.FormatReturnType(f)
if f.TypeRef.IsScalar() || f.TypeRef.IsList() {
switch {
case f.TypeRef.IsVoid():
retType = "error"
case f.TypeRef.IsScalar() || f.TypeRef.IsList():
retType = fmt.Sprintf("(%s, error)", retType)
} else {
default:
retType = "*" + retType
}
signature += " " + retType
Expand Down
214 changes: 102 additions & 112 deletions codegen/generator/go/templates/src/object.go.tmpl
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
{{- if ne .Name "Query" }}
{{ .Description | Comment }}
type {{ .Name | FormatName }} struct {
q *querybuilder.Selection
c graphql.Client

{{ range $field := .Fields }}
{{- if $field.TypeRef.IsScalar }}
{{ $field.Name }} *{{ $field.TypeRef | FormatOutputType }}
{{- end }}
{{- end }}
q *querybuilder.Selection
c graphql.Client
{{""}}
{{- range $field := .Fields }}
{{- if and $field.TypeRef.IsScalar (not $field.TypeRef.IsVoid) }}
{{ $field.Name }} *{{ $field.TypeRef | FormatOutputType }}
{{- end }}
{{- end }}
}
{{- end }}

Expand All @@ -20,139 +20,129 @@ type With{{ .Name | FormatName }}Func func(r *{{ .Name | FormatName }}) *{{ .Nam
//
// This is useful for reusability and readability by not breaking the calling chain.
func (r *{{ $.Name | FormatName }}) With(f With{{ .Name | FormatName }}Func) *{{ $.Name | FormatName }} {
return f(r)
return f(r)
}

{{- end }}

{{ range $field := .Fields }}
{{- if $field.Args.HasOptionals }}
{{- range $field := .Fields }}
{{- if $field.Args.HasOptionals }}
// {{ $field | FieldOptionsStructName }} contains options for {{ $.Name | FormatName }}.{{ $field.Name | FormatName }}
type {{ $field | FieldOptionsStructName }} struct {
{{- range $arg := $field.Args }}
{{- if $arg.TypeRef.IsOptional }}
{{ $arg.Description | Comment }}
{{- if and (eq $arg.Name "id") (eq $.Name "Query") }}
{{ $arg.Name | FormatName }} {{ $arg.TypeRef | FormatOutputType }}
{{- else }}
{{ $arg.Name | FormatName }} {{ $arg.TypeRef | FormatInputType }}
{{- end }}
{{- end }}
{{- end }}
{{- range $arg := $field.Args }}
{{- if $arg.TypeRef.IsOptional }}
{{ $arg.Description | Comment }}
{{- if and (eq $arg.Name "id") (eq $.Name "Query") }}
{{ $arg.Name | FormatName }} {{ $arg.TypeRef | FormatOutputType }}
{{- else }}
{{ $arg.Name | FormatName }} {{ $arg.TypeRef | FormatInputType }}
{{- end }}
{{- end }}
{{- end }}
}

{{- end }}
{{- end }}

{{ $field.Description | Comment }}
{{- if $field.IsDeprecated }}
{{- if $field.IsDeprecated }}
//
{{ $field.DeprecationReason | FormatDeprecation }}
{{- end }}
{{- $convertID := $field | ConvertID }}
{{- end }}
{{- $convertID := $field | ConvertID }}
{{ $field | FieldFunction }} {
{{- if and ($field.TypeRef.IsScalar) (ne $field.ParentObject.Name "Query") (not $convertID) }}
if r.{{ $field.Name }} != nil {
return *r.{{ $field.Name }}, nil
}
{{- if and ($field.TypeRef.IsScalar) (ne $field.ParentObject.Name "Query") (not $convertID) (not $field.TypeRef.IsVoid) }}
if r.{{ $field.Name }} != nil {
return *r.{{ $field.Name }}, nil
}
{{- end }}
q := r.q.Select("{{ $field.Name }}")
{{- if $field.Args.HasOptionals }}
for i := len(opts) - 1; i >= 0; i-- {
{{- range $arg := $field.Args }}
{{- if $arg.TypeRef.IsOptional }}
// `{{ $arg.Name }}` optional argument
if !querybuilder.IsZeroValue(opts[i].{{ $arg.Name | FormatName }}) {
q = q.Arg("{{ $arg.Name }}", opts[i].{{ $arg.Name | FormatName }})
}
{{- end }}
{{- end }}
q := r.q.Select("{{ $field.Name }}")

{{- if $field.Args.HasOptionals }}
for i := len(opts) - 1; i >= 0; i-- {
{{- range $arg := $field.Args }}
{{- if $arg.TypeRef.IsOptional }}
// `{{ $arg.Name }}` optional argument
if !querybuilder.IsZeroValue(opts[i].{{ $arg.Name | FormatName }}) {
q = q.Arg("{{ $arg.Name }}", opts[i].{{ $arg.Name | FormatName }})
}
{{- end }}
{{- end }}
}
{{- end }}


{{- range $arg := $field.Args }}
{{- if not $arg.TypeRef.IsOptional }}
q = q.Arg("{{ $arg.Name }}", {{ $arg.Name }})
{{- end }}
{{- end }}
{{ if $convertID }}
return r, q.Execute(ctx, r.c)

{{- else if $field.TypeRef.IsObject }}
{{ $typeName := $field.TypeRef | FormatOutputType }}
return &{{ $field.TypeRef | FormatOutputType }} {
q: q,
c: r.c,
}

{{- else if or $field.TypeRef.IsScalar $field.TypeRef.IsList }}
{{- if and $field.TypeRef.IsList (IsListOfObject $field.TypeRef) }}
q = q.Select("{{ range $i, $v := $field | GetArrayField }}{{ if $i }} {{ end }}{{ $v.Name }}{{ end }}")

type {{ $field.Name | ToLowerCase }} struct {
{{ range $v := $field | GetArrayField }}
{{ $v.Name | ToUpperCase }} {{ $v.TypeRef | FormatOutputType }}
{{- end }}
}
}
{{- end }}

convert := func(fields []{{ $field.Name | ToLowerCase }}) {{ $field.TypeRef | FormatOutputType }} {
out := {{ $field.TypeRef | FormatOutputType }}{}
{{- range $arg := $field.Args }}
{{- if not $arg.TypeRef.IsOptional }}
q = q.Arg("{{ $arg.Name }}", {{ $arg.Name }})
{{- end }}
{{- end }}

{{- if $convertID }}
return r, q.Execute(ctx, r.c)
{{- else if $field.TypeRef.IsObject }}
return &{{ $field.TypeRef | FormatOutputType }} {
q: q,
c: r.c,
}
{{- else if or $field.TypeRef.IsScalar $field.TypeRef.IsList }}
{{- if and $field.TypeRef.IsList (IsListOfObject $field.TypeRef) }}
q = q.Select("{{ range $i, $v := $field | GetArrayField }}{{ if $i }} {{ end }}{{ $v.Name }}{{ end }}")

for i := range fields {
out = append(out, {{ $field.TypeRef | FormatOutputType | FormatArrayToSingleType }}{{"{"}}{{ $field | GetArrayField | FormatArrayField }}{{"}"}})
}
type {{ $field.Name | ToLowerCase }} struct {
{{- range $v := $field | GetArrayField }}
{{ $v.Name | ToUpperCase }} {{ $v.TypeRef | FormatOutputType }}
{{- end }}
}

return out
}
convert := func(fields []{{ $field.Name | ToLowerCase }}) {{ $field.TypeRef | FormatOutputType }} {
out := {{ $field.TypeRef | FormatOutputType }}{}

{{- end }}
for i := range fields {
out = append(out, {{ $field.TypeRef | FormatOutputType | FormatArrayToSingleType }}{{"{"}}{{ $field | GetArrayField | FormatArrayField }}{{"}"}})
}

return out
}
{{- end }}

{{- if and $field.TypeRef.IsList (IsListOfObject $field.TypeRef) }}
var response []{{ $field.Name | ToLowerCase }}
{{- else }}
var response {{ $field.TypeRef | FormatOutputType }}
{{- end }}

q = q.Bind(&response)
{{- $typeName := $field.TypeRef | FormatOutputType }}
{{- if ne $typeName "Client" }}
{{- if and $field.TypeRef.IsList (IsListOfObject $field.TypeRef) }}

err := q.Execute(ctx, r.c)
if err != nil {
return nil, err
}

return convert(response), nil
{{- else }}
return response, q.Execute(ctx, r.c)
{{- end }}
{{- else }}
return response, q.Execute(ctx, r.gql)
{{- end }}
{{- end }}
var response []{{ $field.Name | ToLowerCase }}
{{- else }}
var response {{ $field.TypeRef | FormatOutputType }}
{{- end }}

q = q.Bind(&response)
{{- if $field.TypeRef.IsVoid }}
return q.Execute(ctx, r.c)
{{- else if $field.TypeRef.IsClient }}
return response, q.Execute(ctx, r.gql)
{{- else if and $field.TypeRef.IsList (IsListOfObject $field.TypeRef) }}
err := q.Execute(ctx, r.c)
if err != nil {
return nil, err
}

return convert(response), nil
{{- else }}
return response, q.Execute(ctx, r.c)
{{- end }}
{{- end }}
}

{{ if eq $field.Name "id" }}
{{- if eq $field.Name "id" }}
// XXX_GraphQLType is an internal function. It returns the native GraphQL type name
func (r *{{ $.Name | FormatName }}) XXX_GraphQLType() string {
return "{{ $.Name }}"
return "{{ $.Name }}"
}

// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object
func (r *{{ $.Name | FormatName }}) XXX_GraphQLIDType() string {
return "{{ $field.TypeRef | FormatOutputType }}"
return "{{ $field.TypeRef | FormatOutputType }}"
}

// XXX_GraphQLID is an internal function. It returns the underlying type ID
func (r *{{ $.Name | FormatName }}) XXX_GraphQLID(ctx context.Context) (string, error) {
id, err := r.ID(ctx)
if err != nil {
return "", err
}
return string(id), nil
id, err := r.ID(ctx)
if err != nil {
return "", err
}
return string(id), nil
}
{{ end }}
{{ end -}}
{{- end }}
{{- end -}}
2 changes: 1 addition & 1 deletion codegen/generator/nodejs/templates/src/method.ts.gtpl
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@

{{- /* Write return type. */ -}}
{{- "" }}){{- "" }}: {{ .TypeRef | FormatOutputType }} {

{{- if .TypeRef }}
return new {{ .TypeRef | FormatOutputType }}({
queryTree: [
Expand Down
22 changes: 22 additions & 0 deletions codegen/introspection/introspection.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,28 @@ func (r TypeRef) IsList() bool {
return false
}

func (r TypeRef) IsVoid() bool {
ref := r
if r.Kind == TypeKindNonNull {
ref = *ref.OfType
}
if ref.Kind != TypeKindScalar {
return false
}
return ref.Name == "Void"
}

func (r TypeRef) IsClient() bool {
ref := r
if r.Kind == TypeKindNonNull {
ref = *ref.OfType
}
if ref.Kind != TypeKindObject {
return false
}
return ref.Name == "Query"
}

type InputValues []InputValue

func (i InputValues) HasOptionals() bool {
Expand Down
12 changes: 12 additions & 0 deletions core/schema/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"github.com/dagger/dagger/core"
"github.com/dagger/dagger/core/pipeline"
"github.com/dagger/dagger/router"
"github.com/dagger/graphql/language/ast"
)

type querySchema struct {
Expand All @@ -25,6 +26,17 @@ func (s *querySchema) Resolvers() router.Resolvers {
"Query": router.ObjectResolver{
"pipeline": router.ToResolver(s.pipeline),
},
"Void": router.ScalarResolver{
Serialize: func(_ any) any {
return core.Void("")
},
ParseValue: func(_ any) any {
return core.Void("")
},
ParseLiteral: func(_ ast.Value) any {
return core.Void("")
},
},
}
}

Expand Down
3 changes: 3 additions & 0 deletions core/schema/query.graphqls
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,6 @@ input PipelineLabel {
"""
value: String!
}

"Nothing. Used by SDK codegen to skip the return value."
scalar Void
4 changes: 4 additions & 0 deletions core/void.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package core

// Void is returned by schema queries that have no return value.
type Void string
Loading

0 comments on commit 51f5751

Please sign in to comment.