From 98c2f5c332698bb49716b5efc04912e21b0c86fe Mon Sep 17 00:00:00 2001 From: Oskar Hahn Date: Wed, 6 Jan 2021 11:32:16 +0100 Subject: [PATCH] Use openslides-models-to-go --- .github/workflows/models.yml | 2 +- .../{models => check}/check.go | 26 +- .../{models => check}/check_test.go | 11 +- .../{models => check}/error.go | 2 +- docs/modelsvalidator/go.mod | 4 +- docs/modelsvalidator/go.sum | 3 + .../{cmd/modelsvalidator => }/main.go | 5 +- docs/modelsvalidator/models/models.go | 239 ------------------ 8 files changed, 29 insertions(+), 263 deletions(-) rename docs/modelsvalidator/{models => check}/check.go (82%) rename docs/modelsvalidator/{models => check}/check_test.go (91%) rename docs/modelsvalidator/{models => check}/error.go (97%) rename docs/modelsvalidator/{cmd/modelsvalidator => }/main.go (86%) delete mode 100644 docs/modelsvalidator/models/models.go diff --git a/.github/workflows/models.yml b/.github/workflows/models.yml index 92703ebb2..1fbbfa09a 100644 --- a/.github/workflows/models.yml +++ b/.github/workflows/models.yml @@ -14,7 +14,7 @@ jobs: uses: actions/checkout@v2 - name: Build validator - run: go build ./cmd/modelsvalidator + run: go build working-directory: docs/modelsvalidator env: GO111MODULE: on diff --git a/docs/modelsvalidator/models/check.go b/docs/modelsvalidator/check/check.go similarity index 82% rename from docs/modelsvalidator/models/check.go rename to docs/modelsvalidator/check/check.go index 47b480a70..ad404b653 100644 --- a/docs/modelsvalidator/models/check.go +++ b/docs/modelsvalidator/check/check.go @@ -1,13 +1,15 @@ -package models +package check import ( "fmt" "strings" + + models "github.com/OpenSlides/openslides-models-to-go" ) // Check runs some checks on the given models. -func Check(models map[string]Model) error { - validators := []func(map[string]Model) error{ +func Check(data map[string]models.Model) error { + validators := []func(map[string]models.Model) error{ validateTypes, validateRelations, validateTemplatePrefixes, @@ -15,7 +17,7 @@ func Check(models map[string]Model) error { errors := new(ErrorList) for _, v := range validators { - if err := v(models); err != nil { + if err := v(data); err != nil { errors.append(err) } } @@ -26,14 +28,14 @@ func Check(models map[string]Model) error { return nil } -func validateTypes(models map[string]Model) error { +func validateTypes(data map[string]models.Model) error { scalar := scalarTypes() relation := relationTypes() errs := &ErrorList{ Name: "type validator", intent: 1, } - for modelName, model := range models { + for modelName, model := range data { for fieldName, field := range model.Fields { if scalar[strings.TrimSuffix(field.Type, "[]")] { continue @@ -52,13 +54,13 @@ func validateTypes(models map[string]Model) error { return errs } -func validateRelations(models map[string]Model) error { +func validateRelations(data map[string]models.Model) error { errs := &ErrorList{ Name: "relation validator", intent: 1, } relation := relationTypes() - for modelName, model := range models { + for modelName, model := range data { Next: for fieldName, field := range model.Fields { r := field.Relation() @@ -67,12 +69,12 @@ func validateRelations(models map[string]Model) error { } for _, c := range r.ToCollections() { - toModel, ok := models[c.Collection] + toModel, ok := data[c.Collection] if !ok { - errs.append(fmt.Errorf("%s/%s directs to nonexisting model `%s`", modelName, fieldName, c.Collection)) + errs.append(fmt.Errorf("%s/%s directs to nonexisting model `%s`", modelName, fieldName, c)) continue Next } - // fmt.Printf("Relation %s/%s to %s/%s\n", modelName, fieldName, c.Collection, c.ToField.Name) + toField, ok := toModel.Fields[c.ToField.Name] if !ok { errs.append(fmt.Errorf("%s/%s directs to nonexisting collectionfield `%s/%s`", modelName, fieldName, c.Collection, c.ToField.Name)) @@ -93,7 +95,7 @@ func validateRelations(models map[string]Model) error { return errs } -func validateTemplatePrefixes(models map[string]Model) error { +func validateTemplatePrefixes(models map[string]models.Model) error { errs := &ErrorList{ Name: "template prefixes validator", intent: 1, diff --git a/docs/modelsvalidator/models/check_test.go b/docs/modelsvalidator/check/check_test.go similarity index 91% rename from docs/modelsvalidator/models/check_test.go rename to docs/modelsvalidator/check/check_test.go index 72252329b..5ffa3a8a5 100644 --- a/docs/modelsvalidator/models/check_test.go +++ b/docs/modelsvalidator/check/check_test.go @@ -1,11 +1,12 @@ -package models_test +package check_test import ( "errors" "strings" "testing" - "github.com/OpenSlides/Openslides/modelsvalidator/models" + "github.com/OpenSlides/Openslides/modelsvalidator/check" + models "github.com/OpenSlides/openslides-models-to-go" ) const yamlUnknownFieldType = `--- @@ -86,7 +87,7 @@ func TestCheck(t *testing.T) { if err != nil { t.Fatalf("Can not unmarshal yaml: %v", err) } - gotErr := models.Check(data) + gotErr := check.Check(data) if tt.err == "" { if gotErr != nil { t.Errorf("Models.Check() returned an unexepcted error: %v", err) @@ -98,14 +99,14 @@ func TestCheck(t *testing.T) { t.Fatalf("Models.Check() did not return an error, expected: %v", tt.err) } - var errList *models.ErrorList + var errList *check.ErrorList if !errors.As(gotErr, &errList) { t.Fatalf("Models.Check() did not return a ListError, got: %v", gotErr) } var found bool for _, err := range errList.Errs { - var errList *models.ErrorList + var errList *check.ErrorList if !errors.As(err, &errList) { continue } diff --git a/docs/modelsvalidator/models/error.go b/docs/modelsvalidator/check/error.go similarity index 97% rename from docs/modelsvalidator/models/error.go rename to docs/modelsvalidator/check/error.go index c67aca452..4349acfe7 100644 --- a/docs/modelsvalidator/models/error.go +++ b/docs/modelsvalidator/check/error.go @@ -1,4 +1,4 @@ -package models +package check import ( "fmt" diff --git a/docs/modelsvalidator/go.mod b/docs/modelsvalidator/go.mod index f4b49fdda..dd145f79a 100644 --- a/docs/modelsvalidator/go.mod +++ b/docs/modelsvalidator/go.mod @@ -2,6 +2,4 @@ module github.com/OpenSlides/Openslides/modelsvalidator go 1.15 -require ( - gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 -) +require github.com/OpenSlides/openslides-models-to-go v0.2.0 diff --git a/docs/modelsvalidator/go.sum b/docs/modelsvalidator/go.sum index 76bb3135b..80592ada3 100644 --- a/docs/modelsvalidator/go.sum +++ b/docs/modelsvalidator/go.sum @@ -1,3 +1,6 @@ +github.com/OpenSlides/openslides-models-to-go v0.2.0 h1:1D+rD94GcUZAvmHLRyzJCIj7wklU+JBkoYifwtHH08s= +github.com/OpenSlides/openslides-models-to-go v0.2.0/go.mod h1:CriCefW5smTixhFfVLiuA8NgyMX4PAU5e3YpJHnaZx8= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 h1:tQIYjPdBoyREyB9XMu+nnTclpTYkz2zFM+lzLJFO4gQ= gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/docs/modelsvalidator/cmd/modelsvalidator/main.go b/docs/modelsvalidator/main.go similarity index 86% rename from docs/modelsvalidator/cmd/modelsvalidator/main.go rename to docs/modelsvalidator/main.go index 87eabf464..21980085f 100644 --- a/docs/modelsvalidator/cmd/modelsvalidator/main.go +++ b/docs/modelsvalidator/main.go @@ -8,7 +8,8 @@ import ( "os" "strings" - "github.com/OpenSlides/Openslides/modelsvalidator/models" + "github.com/OpenSlides/Openslides/modelsvalidator/check" + models "github.com/OpenSlides/openslides-models-to-go" ) func main() { @@ -27,7 +28,7 @@ func main() { log.Fatalf("Invalid model format: %v", err) } - if err := models.Check(data); err != nil { + if err := check.Check(data); err != nil { log.Fatalf("Invalid model structure:\n\n%v", err) } } diff --git a/docs/modelsvalidator/models/models.go b/docs/modelsvalidator/models/models.go deleted file mode 100644 index 56004ca36..000000000 --- a/docs/modelsvalidator/models/models.go +++ /dev/null @@ -1,239 +0,0 @@ -package models - -import ( - "fmt" - "io" - "strings" - - "gopkg.in/yaml.v3" -) - -// Unmarshal parses the content of models.yml to a datastruct.q -func Unmarshal(r io.Reader) (map[string]Model, error) { - var m map[string]Model - if err := yaml.NewDecoder(r).Decode(&m); err != nil { - return nil, fmt.Errorf("decoding models: %w", err) - } - return m, nil -} - -// Model replresents one model from models.yml. -type Model struct { - Fields map[string]Field -} - -// UnmarshalYAML decodes a yaml model to models.Model. -func (m *Model) UnmarshalYAML(node *yaml.Node) error { - return node.Decode(&m.Fields) -} - -// Field of a model. -type Field struct { - Type string - relation Relation - template *AttributeTemplate -} - -// Relation returns the relation object if the Field is a relation or a -// template with a relation. In other cases, it returns nil. -func (a *Field) Relation() Relation { - if a.relation != nil { - return a.relation - } - - if a.template != nil && a.template.Fields.relation != nil { - return a.template.Fields.relation - } - return nil -} - -// UnmarshalYAML decodes a model attribute from yaml. -func (a *Field) UnmarshalYAML(value *yaml.Node) error { - var s string - if err := value.Decode(&s); err == nil { - a.Type = s - return nil - } - - var typer struct { - Type string `yaml:"type"` - } - if err := value.Decode(&typer); err != nil { - return fmt.Errorf("field object without type: %w", err) - } - - a.Type = typer.Type - switch typer.Type { - case "relation": - fallthrough - case "relation-list": - var relation AttributeRelation - if err := value.Decode(&relation); err != nil { - return fmt.Errorf("invalid object of type %s at line %d object: %w", typer.Type, value.Line, err) - } - a.relation = &relation - case "generic-relation": - fallthrough - case "generic-relation-list": - var relation AttributeGenericRelation - if err := value.Decode(&relation); err != nil { - return fmt.Errorf("invalid object of type %s at line %d object: %w", typer.Type, value.Line, err) - } - a.relation = &relation - case "template": - var template AttributeTemplate - if err := value.Decode(&template); err != nil { - return fmt.Errorf("invalid object of type template object in line %d: %w", value.Line, err) - } - a.template = &template - } - return nil -} - -// Relation represents some kind of relation between fields. -type Relation interface { - ToCollections() []ToCollectionField -} - -// ToCollectionField represents a field and a collection -type ToCollectionField struct { - Collection string `yaml:"collection"` - ToField ToField `yaml:"field"` -} - -// UnmarshalYAML decodes the models.yml to a To object. -func (t *ToCollectionField) UnmarshalYAML(value *yaml.Node) error { - var s string - if err := value.Decode(&s); err == nil { - cf := strings.Split(s, "/") - if len(cf) != 2 { - return fmt.Errorf("invalid value of `to` in line %d, expected one `/`: %s", value.Line, s) - } - t.Collection = cf[0] - t.ToField.Name = cf[1] - return nil - } - - var d struct { - Collection string `yaml:"collection"` - Field ToField `yaml:"field"` - } - if err := value.Decode(&d); err != nil { - return fmt.Errorf("decoding to collection field at line %d: %w", value.Line, err) - } - t.Collection = d.Collection - t.ToField = d.Field - return nil -} - -type ToField struct { - Name string `yaml:"name"` - Type string `yaml:"type"` -} - -// UnmarshalYAML decodes the models.yml to a ToField object. -func (t *ToField) UnmarshalYAML(value *yaml.Node) error { - var s string - if err := value.Decode(&s); err == nil { - t.Name = s - t.Type = "normal" - return nil - } - - var d struct { - Name string `yaml:"name"` - Type string `yaml:"type"` - } - if err := value.Decode(&d); err != nil { - return fmt.Errorf("decoding to field at line %d: %w", value.Line, err) - } - t.Name = d.Name - t.Type = d.Type - return nil -} - -// AttributeRelation is a relation or relation-list field. -type AttributeRelation struct { - To To `yaml:"to"` -} - -// ToCollection returns the names of the collections there the attribute points -// to. It is allways a slice with one element. -func (r AttributeRelation) ToCollections() []ToCollectionField { - return []ToCollectionField{r.To.CollectionField} -} - -// To is shows a Relation where to point to. -type To struct { - CollectionField ToCollectionField -} - -// UnmarshalYAML decodes the models.yml to a To object. -func (t *To) UnmarshalYAML(value *yaml.Node) error { - var s string - if err := value.Decode(&s); err == nil { - cf := strings.Split(s, "/") - if len(cf) != 2 { - return fmt.Errorf("invalid value of `to` in line %d, expected one `/`: %s", value.Line, s) - } - t.CollectionField.Collection = cf[0] - t.CollectionField.ToField.Name = cf[1] - return nil - } - - if err := value.Decode(&(t.CollectionField)); err != nil { - return fmt.Errorf("decoding to field at line %d: %w", value.Line, err) - } - return nil -} - -// AttributeGenericRelation is a generic-relation or generic-relation-list field. -type AttributeGenericRelation struct { - To ToGeneric `yaml:"to"` -} - -// ToCollections returns all collection, where the generic field could point to. -func (r AttributeGenericRelation) ToCollections() []ToCollectionField { - return r.To.CollectionFields -} - -// AttributeTemplate represents a template field. -type AttributeTemplate struct { - Replacement string `yaml:"replacement"` - Fields Field `yaml:"fields"` -} - -// ToGeneric is like a To object, but for generic relations. -type ToGeneric struct { - CollectionFields []ToCollectionField -} - -func (t *ToGeneric) UnmarshalYAML(value *yaml.Node) error { - var d struct { - Collections []string `yaml:"collections"` - Field ToField `yaml:"field"` - } - if err := value.Decode(&d); err == nil { - t.CollectionFields = make([]ToCollectionField, len(d.Collections)) - for i, collection := range d.Collections { - t.CollectionFields[i].Collection = collection - t.CollectionFields[i].ToField = d.Field - } - return nil - } - - var e []string - if err := value.Decode(&e); err != nil { - return fmt.Errorf("decoding to generic field at line %d: %w", value.Line, err) - } - t.CollectionFields = make([]ToCollectionField, len(e)) - for i, collectionfield := range e { - cf := strings.Split(collectionfield, "/") - if len(cf) != 2 { - return fmt.Errorf("invalid value of `to` in line %d, expected one `/`: %s", value.Line, collectionfield) - } - t.CollectionFields[i].Collection = cf[0] - t.CollectionFields[i].ToField.Name = cf[1] - } - return nil -}