Skip to content

Commit

Permalink
Add edgeql to go code generator (#236)
Browse files Browse the repository at this point in the history
related to #182
  • Loading branch information
fmoor authored Oct 24, 2022
1 parent a7d49fb commit 49aa101
Show file tree
Hide file tree
Showing 170 changed files with 5,338 additions and 1,640 deletions.
2 changes: 2 additions & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ run:

# list of build tags, all linters use it. Default is empty list.
build-tags:
- tools

# which dirs to skip: issues from them won't be reported;
# can use regexp here: generated.*, regexp is applied on full path;
Expand All @@ -39,6 +40,7 @@ run:
# on Windows.
skip-files:
- doc_test.go
- cmd/edgeql-go/doc.go

# by default isn't set. If set we pass it to "go list -mod={option}". From "go help modules":
# If invoked with -mod=readonly, the go command is disallowed from the implicit
Expand Down
2 changes: 1 addition & 1 deletion .licence-header.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
This source file is part of the EdgeDB open source project.

Copyright 2020-present EdgeDB Inc. and the EdgeDB authors.
Copyright EdgeDB Inc. and the EdgeDB authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down
5 changes: 3 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ errors:
exit 1 \
)
edb gen-errors-json --client | \
go run internal/cmd/generr/*.go > \
generatederrors.go
go run internal/cmd/generr/definition.go > internal/client/errors_gen.go
edb gen-errors-json --client | \
go run internal/cmd/generr/export.go > errors_gen.go
make format
37 changes: 37 additions & 0 deletions cmd/edgeql-go/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// This source file is part of the EdgeDB open source project.
//
// Copyright EdgeDB Inc. and the EdgeDB authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// edgeql-go is a tool to generate go functions from edgeql queries. When run
// in an EdgeDB project directory (or subdirectory) a *_edgeql.go source file
// will be generated for each *.edgeql file. The generated go will have an
// edgeqlFileName and edgeqlFileNameJSON function with typed arguments and
// return value matching the query's arguments and result shape.
//
// # Install
//
// go install github.com/edgedb/edgedb-go/cmd/edgeql-go@latest
//
// See also [pinning tool dependencies].
//
// # Usage
//
// Typically this process would be run using [go generate] like this:
//
// //go:generate edgeql-go
//
// [pinning tool dependencies]: https://github.com/golang/go/wiki/Modules#how-can-i-track-tool-dependencies-for-a-module
// [go generate]: https://go.dev/blog/generate
package main
178 changes: 178 additions & 0 deletions cmd/edgeql-go/endtoend_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
// This source file is part of the EdgeDB open source project.
//
// Copyright EdgeDB Inc. and the EdgeDB authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package main

import (
"fmt"
"io"
"io/fs"
"log"
"os"
"os/exec"
"path/filepath"
"strings"
"sync"
"testing"

edgedb "github.com/edgedb/edgedb-go/internal/client"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

var dsn string

func TestMain(m *testing.M) {
o := edgedb.TestClientOptions()
pwd, ok := o.Password.Get()
if !ok {
log.Fatal("missing password")
}
dsn = fmt.Sprintf(
"edgedb://%s:%s@%s:%d?tls_security=%s&tls_ca_file=%s",
o.User,
pwd,
o.Host,
o.Port,
o.TLSOptions.SecurityMode,
o.TLSOptions.CAFile,
)
os.Exit(m.Run())
}

func TestEdgeQLGo(t *testing.T) {
dir, err := os.MkdirTemp("", "edgeql-go-*")
require.NoError(t, err)
defer func() {
assert.NoError(t, os.RemoveAll(dir))
}()

t.Log("building edgeql-go")
edgeqlGo := filepath.Join(dir, "edgeql-go")
run(t, ".", "go", "build", "-o", edgeqlGo)

var wg sync.WaitGroup
err = filepath.WalkDir(
"testdata",
func(src string, d fs.DirEntry, e error) error {
require.NoError(t, e)
if src == "testdata" {
return nil
}

dst := filepath.Join(dir, strings.TrimPrefix(src, "testdata"))
if d.IsDir() {
e = os.Mkdir(dst, os.ModePerm)
require.NoError(t, e)
} else {
wg.Add(1)
go func() {
defer wg.Done()
copyFile(t, dst, src)
}()
}
return nil
},
)
require.NoError(t, err)
wg.Wait()

entries, err := os.ReadDir(dir)
require.NoError(t, err)
for _, entry := range entries {
if entry.Name() == "edgeql-go" {
continue
}

t.Run(entry.Name(), func(t *testing.T) {
projectDir := filepath.Join(dir, entry.Name())
run(t, projectDir, edgeqlGo)
run(t, projectDir, "go", "run", "./...")
er := filepath.WalkDir(
projectDir,
func(f string, d fs.DirEntry, e error) error {
require.NoError(t, e)
if strings.HasSuffix(f, ".go.assert") {
checkAssertFile(t, f)
}
if strings.HasSuffix(f, ".go") &&
!strings.HasSuffix(f, "ignore.go") {
checkGoFile(t, f)
}
return nil
},
)
require.NoError(t, er)
})
}
}

func checkAssertFile(t *testing.T, file string) {
t.Helper()
goFile := strings.TrimSuffix(file, ".assert")
if assert.FileExistsf(t, goFile, "missing .go file for %s", file) {
assertEqualFiles(t, file, goFile)
}
}

func checkGoFile(t *testing.T, file string) {
t.Helper()
assertFile := file + ".assert"
if assert.FileExistsf(t, assertFile,
"missing .go.assert file for %s", file,
) {
assertEqualFiles(t, assertFile, file)
}
}

func assertEqualFiles(t *testing.T, left, right string) {
t.Helper()
leftData, err := os.ReadFile(left)
require.NoErrorf(t, err, "reading %s", left)

rightData, err := os.ReadFile(right)
require.NoErrorf(t, err, "reading %s", right)

assert.Equal(t, string(leftData), string(rightData),
"files are not equal: %s != %s", left, right,
)
}

func copyFile(t *testing.T, to, from string) {
toFd, err := os.Create(to)
require.NoError(t, err)
defer func() {
assert.NoError(t, toFd.Close())
}()

fromFd, err := os.Open(from)
require.NoError(t, err)
defer func() {
assert.NoError(t, fromFd.Close())
}()

_, err = io.Copy(toFd, fromFd)
require.NoError(t, err)
}

func run(t *testing.T, dir, name string, args ...string) {
cmd := exec.Command(name, args...)
cmd.Dir = dir
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
cmd.Env = append(os.Environ(), fmt.Sprintf("EDGEDB_DSN=%s", dsn))
require.NoError(t, cmd.Run())
}
Loading

0 comments on commit 49aa101

Please sign in to comment.