Skip to content

Commit

Permalink
transform spec
Browse files Browse the repository at this point in the history
  • Loading branch information
savme committed Jun 5, 2024
1 parent c6f5bbf commit d280509
Show file tree
Hide file tree
Showing 6 changed files with 102 additions and 2 deletions.
1 change: 1 addition & 0 deletions cli/internal/specs/v0/gen/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ func main() {
return reflect.VisibleFields(reflect.TypeOf(struct {
Source specs.Source
Destination specs.Destination
Transform specs.Transform
}{}))
}
return nil
Expand Down
2 changes: 2 additions & 0 deletions cli/internal/specs/v0/kind.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,14 @@ type Kind int
const (
KindSource Kind = iota
KindDestination
KindTransform
)

var (
AllKinds = [...]string{
KindSource: "source",
KindDestination: "destination",
KindTransform: "transform",
}
)

Expand Down
37 changes: 36 additions & 1 deletion cli/internal/specs/v0/schema.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

24 changes: 23 additions & 1 deletion cli/internal/specs/v0/spec.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ func (s *Spec) UnmarshalJSON(data []byte) error {
s.Spec = new(Source)
case KindDestination:
s.Spec = new(Destination)
case KindTransform:
s.Spec = new(Transform)
default:
return fmt.Errorf("unknown kind %s", s.Kind)
}
Expand All @@ -55,11 +57,12 @@ func (Spec) JSONSchemaExtend(sc *jsonschema.Schema) {
// delete & obtain the values
source, _ := sc.Properties.Delete("Source")
destination, _ := sc.Properties.Delete("Destination")
transform, _ := sc.Properties.Delete("Transform")

// update `spec` property
spec := sc.Properties.Value("spec")
// we can use `one_of because source & destination specs are mutually exclusive based on the kind
spec.OneOf = []*jsonschema.Schema{source, destination}
spec.OneOf = []*jsonschema.Schema{source, destination, transform}

sc.AllOf = []*jsonschema.Schema{
{
Expand Down Expand Up @@ -102,6 +105,25 @@ func (Spec) JSONSchemaExtend(sc *jsonschema.Schema) {
}(),
},
},
{
If: &jsonschema.Schema{
Properties: func() *orderedmap.OrderedMap[string, *jsonschema.Schema] {
properties := jsonschema.NewProperties()
kind := *sc.Properties.Value("kind")
kind.Const = "transform"
kind.Enum = nil
properties.Set("kind", &kind)
return properties
}(),
},
Then: &jsonschema.Schema{
Properties: func() *orderedmap.OrderedMap[string, *jsonschema.Schema] {
properties := jsonschema.NewProperties()
properties.Set("spec", transform)
return properties
}(),
},
},
}
}

Expand Down
18 changes: 18 additions & 0 deletions cli/internal/specs/v0/spec_reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,15 @@ import (
type SpecReader struct {
sourcesMap map[string]*Source
destinationsMap map[string]*Destination
transformsMap map[string]*Transform

sourceWarningsMap map[string]Warnings
destinationWarningsMap map[string]Warnings
transformWarningsMap map[string]Warnings

Sources []*Source
Destinations []*Destination
Transforms []*Transform
}

var fileRegex = regexp.MustCompile(`\$\{file:([^}]+)\}`)
Expand Down Expand Up @@ -96,6 +99,18 @@ func (r *SpecReader) loadSpecsFromFile(path string) error {
return fmt.Errorf("failed to unmarshal file %s: %w", path, err)
}
switch s.Kind {
case KindTransform:
transform := s.Spec.(*Transform)
if r.transformsMap[transform.Name] != nil {
return fmt.Errorf("duplicate transform name %s", transform.Name)
}
r.transformWarningsMap[transform.Name] = transform.GetWarnings()
transform.SetDefaults()
if err := transform.Validate(); err != nil {
return fmt.Errorf("failed to validate transform %s: %w", transform.Name, err)
}
r.transformsMap[transform.Name] = transform
r.Transforms = append(r.Transforms, transform)
case KindSource:
source := s.Spec.(*Source)
if r.sourcesMap[source.Name] != nil {
Expand Down Expand Up @@ -261,10 +276,13 @@ func newSpecReader(paths []string) (*SpecReader, error) {
reader := &SpecReader{
sourcesMap: make(map[string]*Source),
destinationsMap: make(map[string]*Destination),
transformsMap: make(map[string]*Transform),
Sources: make([]*Source, 0),
Destinations: make([]*Destination, 0),
Transforms: make([]*Transform, 0),
sourceWarningsMap: make(map[string]Warnings),
destinationWarningsMap: make(map[string]Warnings),
transformWarningsMap: make(map[string]Warnings),
}
for _, path := range paths {
file, err := os.Open(path)
Expand Down
22 changes: 22 additions & 0 deletions cli/internal/specs/v0/transform.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package specs

import "errors"

type Transform struct {
Name string `json:"name" jsonschema:"required,minLength=1"`
}

func (*Transform) GetWarnings() Warnings {
warnings := make(map[string]string)
return warnings
}

func (*Transform) SetDefaults() {}

func (t *Transform) Validate() error {
if t.Name == "" {
return errors.New("name is required")
}

return nil
}

0 comments on commit d280509

Please sign in to comment.