Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

restructure the cli codebase #143

Merged
merged 3 commits into from
Sep 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ jobs:
skip-cache: true
- name: Run Go unit tests for the SDK
run: |
cp go.work.testing go.work
rm cmd/hasura-ndc-go/go.mod
rm cmd/hasura-ndc-go/go.sum
go mod tidy
Expand Down
14 changes: 7 additions & 7 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ test: test-sdk test-hasura-ndc-go test-example-codegen
go-tidy:
go mod tidy
cd $(ROOT_DIR)/cmd/hasura-ndc-go && go mod tidy
cd $(ROOT_DIR)/cmd/hasura-ndc-go/testdata/basic/source && go mod tidy
cd $(ROOT_DIR)/cmd/hasura-ndc-go/testdata/empty/source && go mod tidy
cd $(ROOT_DIR)/cmd/hasura-ndc-go/command/internal/testdata/basic/source && go mod tidy
cd $(ROOT_DIR)/cmd/hasura-ndc-go/command/internal/testdata/empty/source && go mod tidy
cd $(ROOT_DIR)/example/codegen && go mod tidy

# Install golangci-lint tool to run lint locally
Expand All @@ -46,11 +46,11 @@ lint:
.PHONY: clean
clean:
rm -rf "$(OUTPUT_DIR)"
rm -f cmd/hasura-ndc-go/testdata/*/source/connector.generated.go
rm -f cmd/hasura-ndc-go/testdata/*/source/**/connector.generated.go
rm -f cmd/hasura-ndc-go/testdata/*/source/schema.generated.json
rm -f cmd/hasura-ndc-go/testdata/*/source/**/schema.generated.json
rm -f cmd/hasura-ndc-go/testdata/*/source/**/types.generated.go
rm -f cmd/hasura-ndc-go/command/internal/testdata/*/source/connector.generated.go
rm -f cmd/hasura-ndc-go/command/internal/testdata/*/source/**/connector.generated.go
rm -f cmd/hasura-ndc-go/command/internal/testdata/*/source/schema.generated.json
rm -f cmd/hasura-ndc-go/command/internal/testdata/*/source/**/schema.generated.json
rm -f cmd/hasura-ndc-go/command/internal/testdata/*/source/**/types.generated.go
rm -rf cmd/hasura-ndc-go/testdata/**/testdata

.PHONY: build-codegen
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
package main
package internal

import (
"bufio"
"context"
_ "embed"
"encoding/json"
"fmt"
"io"
Expand All @@ -18,6 +17,15 @@ import (
"github.com/rs/zerolog/log"
)

// ConnectorGenerationArguments represent input arguments of the ConnectorGenerator
type ConnectorGenerationArguments struct {
Path string `help:"The path of the root directory where the go.mod file is present" short:"p" env:"HASURA_PLUGIN_CONNECTOR_CONTEXT_PATH" default:"."`
ConnectorDir string `help:"The directory where the connector.go file is placed" default:"."`
PackageTypes string `help:"The name of types package where the State struct is in"`
Directories []string `help:"Folders contain NDC operation functions" short:"d"`
Trace string `help:"Enable tracing and write to target file path."`
}

type connectorTypeBuilder struct {
packageName string
packagePath string
Expand Down Expand Up @@ -76,11 +84,12 @@ func NewConnectorGenerator(basePath string, connectorDir string, moduleName stri
}
}

func parseAndGenerateConnector(args *UpdateArguments, moduleName string) error {
if cli.Generate.Trace != "" {
w, err := os.Create(cli.Generate.Trace)
// ParseAndGenerateConnector parses and generate connector codes
func ParseAndGenerateConnector(args ConnectorGenerationArguments, moduleName string) error {
if args.Trace != "" {
w, err := os.Create(args.Trace)
if err != nil {
return fmt.Errorf("failed to create trace file at %s", cli.Generate.Trace)
return fmt.Errorf("failed to create trace file at %s", args.Trace)
}
defer func() {
_ = w.Close()
Expand All @@ -92,7 +101,7 @@ func parseAndGenerateConnector(args *UpdateArguments, moduleName string) error {
}

parseCtx, parseTask := trace.NewTask(context.TODO(), "parse")
sm, err := parseRawConnectorSchemaFromGoCode(parseCtx, moduleName, ".", args)
sm, err := parseRawConnectorSchemaFromGoCode(parseCtx, moduleName, ".", &args)
if err != nil {
parseTask.End()
return err
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package main
package internal

import (
"encoding/json"
Expand All @@ -8,7 +8,6 @@ import (
"strings"
"testing"

"github.com/hasura/ndc-sdk-go/cmd/hasura-ndc-go/command"
"github.com/hasura/ndc-sdk-go/schema"
"github.com/stretchr/testify/assert"
)
Expand Down Expand Up @@ -91,8 +90,7 @@ func TestConnectorGeneration(t *testing.T) {

srcDir := path.Join(tc.BasePath, "source")
assert.NoError(t, os.Chdir(srcDir))

err = parseAndGenerateConnector(&UpdateArguments{
err = ParseAndGenerateConnector(ConnectorGenerationArguments{
ConnectorDir: tc.ConnectorDir,
PackageTypes: tc.PackageTypes,
Directories: tc.Directories,
Expand Down Expand Up @@ -134,12 +132,6 @@ func TestConnectorGeneration(t *testing.T) {
assert.NoError(t, err)
}
}

// generate test cases
assert.NoError(t, command.GenTestSnapshots(&command.GenTestSnapshotArguments{
Dir: "testdata",
Schema: path.Join("source", tc.ConnectorDir, "schema.generated.json"),
}))
})
}
}
192 changes: 192 additions & 0 deletions cmd/hasura-ndc-go/command/internal/constant.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
package internal

import (
_ "embed"
"fmt"
"regexp"
"text/template"

"github.com/hasura/ndc-sdk-go/schema"
)

const (
connectorOutputFile = "connector.generated.go"
schemaOutputFile = "schema.generated.json"
typeMethodsOutputFile = "types.generated.go"
)

//go:embed templates/connector/connector.go.tmpl
var connectorTemplateStr string
var connectorTemplate *template.Template

func init() {
var err error
connectorTemplate, err = template.New(connectorOutputFile).Parse(connectorTemplateStr)
if err != nil {
panic(fmt.Errorf("failed to parse connector template: %s", err))
}
}

type ScalarName string

const (
ScalarBoolean ScalarName = "Boolean"
ScalarString ScalarName = "String"
ScalarInt8 ScalarName = "Int8"
ScalarInt16 ScalarName = "Int16"
ScalarInt32 ScalarName = "Int32"
ScalarInt64 ScalarName = "Int64"
ScalarFloat32 ScalarName = "Float32"
ScalarFloat64 ScalarName = "Float64"
ScalarBigInt ScalarName = "BigInt"
ScalarBigDecimal ScalarName = "BigDecimal"
ScalarUUID ScalarName = "UUID"
ScalarDate ScalarName = "Date"
ScalarTimestamp ScalarName = "Timestamp"
ScalarTimestampTZ ScalarName = "TimestampTZ"
ScalarGeography ScalarName = "Geography"
ScalarBytes ScalarName = "Bytes"
ScalarJSON ScalarName = "JSON"
// ScalarRawJSON is a special scalar for raw json data serialization.
// The underlying Go type for this scalar is json.RawMessage.
// Note: we don't recommend to use this scalar for function arguments
// because the decoder will re-encode the value to []byte that isn't performance-wise.
ScalarRawJSON ScalarName = "RawJSON"
)

var defaultScalarTypes = map[ScalarName]schema.ScalarType{
ScalarBoolean: {
AggregateFunctions: schema.ScalarTypeAggregateFunctions{},
ComparisonOperators: map[string]schema.ComparisonOperatorDefinition{},
Representation: schema.NewTypeRepresentationBoolean().Encode(),
},
ScalarString: {
AggregateFunctions: schema.ScalarTypeAggregateFunctions{},
ComparisonOperators: map[string]schema.ComparisonOperatorDefinition{},
Representation: schema.NewTypeRepresentationString().Encode(),
},
ScalarInt8: {
AggregateFunctions: schema.ScalarTypeAggregateFunctions{},
ComparisonOperators: map[string]schema.ComparisonOperatorDefinition{},
Representation: schema.NewTypeRepresentationInt8().Encode(),
},
ScalarInt16: {
AggregateFunctions: schema.ScalarTypeAggregateFunctions{},
ComparisonOperators: map[string]schema.ComparisonOperatorDefinition{},
Representation: schema.NewTypeRepresentationInt16().Encode(),
},
ScalarInt32: {
AggregateFunctions: schema.ScalarTypeAggregateFunctions{},
ComparisonOperators: map[string]schema.ComparisonOperatorDefinition{},
Representation: schema.NewTypeRepresentationInt32().Encode(),
},
ScalarInt64: {
AggregateFunctions: schema.ScalarTypeAggregateFunctions{},
ComparisonOperators: map[string]schema.ComparisonOperatorDefinition{},
Representation: schema.NewTypeRepresentationInt64().Encode(),
},
ScalarFloat32: {
AggregateFunctions: schema.ScalarTypeAggregateFunctions{},
ComparisonOperators: map[string]schema.ComparisonOperatorDefinition{},
Representation: schema.NewTypeRepresentationFloat32().Encode(),
},
ScalarFloat64: {
AggregateFunctions: schema.ScalarTypeAggregateFunctions{},
ComparisonOperators: map[string]schema.ComparisonOperatorDefinition{},
Representation: schema.NewTypeRepresentationFloat64().Encode(),
},
ScalarBigInt: {
AggregateFunctions: schema.ScalarTypeAggregateFunctions{},
ComparisonOperators: map[string]schema.ComparisonOperatorDefinition{},
Representation: schema.NewTypeRepresentationBigInteger().Encode(),
},
ScalarBigDecimal: {
AggregateFunctions: schema.ScalarTypeAggregateFunctions{},
ComparisonOperators: map[string]schema.ComparisonOperatorDefinition{},
Representation: schema.NewTypeRepresentationBigDecimal().Encode(),
},
ScalarUUID: {
AggregateFunctions: schema.ScalarTypeAggregateFunctions{},
ComparisonOperators: map[string]schema.ComparisonOperatorDefinition{},
Representation: schema.NewTypeRepresentationUUID().Encode(),
},
ScalarDate: {
AggregateFunctions: schema.ScalarTypeAggregateFunctions{},
ComparisonOperators: map[string]schema.ComparisonOperatorDefinition{},
Representation: schema.NewTypeRepresentationDate().Encode(),
},
ScalarTimestamp: {
AggregateFunctions: schema.ScalarTypeAggregateFunctions{},
ComparisonOperators: map[string]schema.ComparisonOperatorDefinition{},
Representation: schema.NewTypeRepresentationTimestamp().Encode(),
},
ScalarTimestampTZ: {
AggregateFunctions: schema.ScalarTypeAggregateFunctions{},
ComparisonOperators: map[string]schema.ComparisonOperatorDefinition{},
Representation: schema.NewTypeRepresentationTimestampTZ().Encode(),
},
ScalarGeography: {
AggregateFunctions: schema.ScalarTypeAggregateFunctions{},
ComparisonOperators: map[string]schema.ComparisonOperatorDefinition{},
Representation: schema.NewTypeRepresentationGeography().Encode(),
},
ScalarBytes: {
AggregateFunctions: schema.ScalarTypeAggregateFunctions{},
ComparisonOperators: map[string]schema.ComparisonOperatorDefinition{},
Representation: schema.NewTypeRepresentationBytes().Encode(),
},
ScalarJSON: {
AggregateFunctions: schema.ScalarTypeAggregateFunctions{},
ComparisonOperators: map[string]schema.ComparisonOperatorDefinition{},
Representation: schema.NewTypeRepresentationJSON().Encode(),
},
ScalarRawJSON: {
AggregateFunctions: schema.ScalarTypeAggregateFunctions{},
ComparisonOperators: map[string]schema.ComparisonOperatorDefinition{},
Representation: schema.NewTypeRepresentationJSON().Encode(),
},
}

var ndcOperationNameRegex = regexp.MustCompile(`^(Function|Procedure)([A-Z][A-Za-z0-9]*)$`)
var ndcOperationCommentRegex = regexp.MustCompile(`^@(function|procedure)(\s+([A-Za-z]\w*))?`)
var ndcScalarNameRegex = regexp.MustCompile(`^Scalar([A-Z]\w*)$`)
var ndcScalarCommentRegex = regexp.MustCompile(`^@scalar(\s+(\w+))?(\s+([a-z]+))?$`)
var ndcEnumCommentRegex = regexp.MustCompile(`^@enum\s+([\w-.,!@#$%^&*()+=~\s\t]+)$`)

type nativeScalarPackageConfig struct {
PackageName string
Pattern *regexp.Regexp
}

var fieldNameRegex = regexp.MustCompile(`[^\w]`)

var nativeScalarPackages map[string]nativeScalarPackageConfig = map[string]nativeScalarPackageConfig{
"scalar": {
PackageName: "github.com/hasura/ndc-sdk-go/scalar",
Pattern: regexp.MustCompile(`^(\[\]|\*)*github\.com\/hasura\/ndc-sdk-go\/scalar\.`),
},
"json": {
PackageName: "encoding/json",
Pattern: regexp.MustCompile(`^(\[\]|\*)*encoding\/json\.`),
},
"uuid": {
PackageName: "github.com/google/uuid",
Pattern: regexp.MustCompile(`^(\[\]|\*)*github\.com\/google\/uuid\.`),
},
"time": {
PackageName: "time",
Pattern: regexp.MustCompile(`^(\[\]|\*)*time\.`),
},
}

const textBlockErrorCheck = `
if err != nil {
return err
}
`

const textBlockErrorCheck2 = `
if err != nil {
return nil, err
}
`
Loading