diff --git a/Makefile b/Makefile index 0ba69163..2e663d13 100644 --- a/Makefile +++ b/Makefile @@ -22,7 +22,7 @@ GO_FILES=$(shell find . -type f -name '*.go') # Standard dependencies are installed via go get DEPEND=\ golang.org/x/tools/cmd/goimports@latest \ - honnef.co/go/tools/cmd/staticcheck@latest \ + github.com/golangci/golangci-lint/cmd/golangci-lint@latest \ github.com/mjibson/esc@latest all: lint check-generated test @@ -41,8 +41,8 @@ ifneq ($(GOOS),windows) @if [ "`goimports -l $(GO_FILES) | tee /dev/stderr`" ]; then \ echo "^ - Repo contains improperly formatted go files" && echo && exit 1; \ fi - @if [ "`staticcheck ./... | tee /dev/stderr`" ]; then \ - echo "^ - staticcheck errors!" && echo && exit 1; \ + @if [ "`golangci-lint run ./... | tee /dev/stderr`" ]; then \ + echo "^ - golangci-lint errors!" && echo && exit 1; \ fi endif @@ -52,12 +52,12 @@ check-generated: generate fi test: - env GO111MODULE=on go test ./... + go test ./... release: # First make sure all is clean @git diff-index --quiet HEAD - @go mod tidy --compat=1.17 + @go mod tidy # Bump version number @sed 's/Major = .*/Major = $(MAJOR)/' pkg/version.go > _tmp && mv _tmp pkg/version.go diff --git a/cmd/mdl/main.go b/cmd/mdl/main.go index 21fd9e1e..49369b7a 100644 --- a/cmd/mdl/main.go +++ b/cmd/mdl/main.go @@ -62,13 +62,19 @@ func main() { switch cmd { case "gen": addGlobals(genset) - genset.Parse(os.Args[idx:]) + if err := genset.Parse(os.Args[idx:]); err != nil { + fail(err.Error()) + } case "serve": addGlobals(svrset) - svrset.Parse(os.Args[idx:]) + if err := svrset.Parse(os.Args[idx:]); err != nil { + fail(err.Error()) + } default: addGlobals(gset) - gset.Parse(os.Args[idx:]) + if err := gset.Parse(os.Args[idx:]); err != nil { + fail(err.Error()) + } } if *h || *help { @@ -154,7 +160,7 @@ func printUsage(fss ...*flag.FlagSet) { } } -func fail(format string, args ...interface{}) { +func fail(format string, args ...any) { fmt.Fprintf(os.Stderr, format+"\n", args...) os.Exit(1) } diff --git a/cmd/mdl/serve.go b/cmd/mdl/serve.go index ac36eeae..438331ff 100644 --- a/cmd/mdl/serve.go +++ b/cmd/mdl/serve.go @@ -31,7 +31,7 @@ type ( } // Layout is position info saved for one view (diagram) - Layout = map[string]interface{} + Layout = map[string]any // Layouts is a map from view key to the view Layout Layouts = map[string]Layout @@ -81,7 +81,7 @@ func (s *Server) Serve(outDir string, devmode bool, port int) error { http.HandleFunc("/data/save", func(w http.ResponseWriter, r *http.Request) { id := r.URL.Query().Get("id") if id == "" { - http.Error(w, "Param id is missing", http.StatusBadRequest) + handleError(w, fmt.Errorf("missing id")) return } @@ -91,9 +91,7 @@ func (s *Server) Serve(outDir string, devmode bool, port int) error { svgFile := path.Join(outDir, id+".svg") f, err := os.Create(svgFile) if err != nil { - msg := fmt.Sprintf("Saving failed, can't write to %s: %s!\n", svgFile, err) - fmt.Println(msg) - http.Error(w, msg, http.StatusInternalServerError) + handleError(w, err) return } defer func() { _ = f.Close() }() @@ -123,6 +121,12 @@ func (s *Server) SetDesign(d *mdl.Design) { s.design = b } +// handleError writes the given error to stderr and http.Error. +func handleError(w http.ResponseWriter, err error) { + fmt.Fprintln(os.Stderr, err.Error()) + http.Error(w, err.Error(), http.StatusInternalServerError) +} + // loadLayouts lists out directory and reads layout info from SVG files // for backwards compatibility, fallback to layout.json func loadLayouts(dir string) ([]byte, error) { @@ -164,7 +168,7 @@ func loadLayouts(dir string) ([]byte, error) { end := bytes.Index(b, endMark) b = b[begin:end] - var l Layout = make(map[string]interface{}) + var l Layout = make(map[string]any) err = json.Unmarshal(b, &l) if err != nil { return nil, err diff --git a/cmd/mdl/webapp.go b/cmd/mdl/webapp.go index da3bf787..22de2aa9 100644 --- a/cmd/mdl/webapp.go +++ b/cmd/mdl/webapp.go @@ -145,7 +145,7 @@ func (f *_escFile) IsDir() bool { return f.isDir } -func (f *_escFile) Sys() interface{} { +func (f *_escFile) Sys() any { return f } diff --git a/cmd/stz/main.go b/cmd/stz/main.go index 66504ee6..ef05a10a 100644 --- a/cmd/stz/main.go +++ b/cmd/stz/main.go @@ -46,7 +46,9 @@ func main() { } } done: - fs.Parse(os.Args[idx:]) + if err := fs.Parse(os.Args[idx:]); err != nil { + fail(err.Error()) + } pathOrDefault := func(p string) string { if p == "" { @@ -208,7 +210,7 @@ func put(path, wid, key, secret string, debug bool) error { return c.Put(wid, local) } -func fail(format string, args ...interface{}) { +func fail(format string, args ...any) { fmt.Fprintf(os.Stderr, format+"\n", args...) os.Exit(1) } diff --git a/dsl/deployment.go b/dsl/deployment.go index 117b5f25..2c7d1d90 100644 --- a/dsl/deployment.go +++ b/dsl/deployment.go @@ -90,7 +90,7 @@ func DeploymentEnvironment(name string, dsl func()) { // }) // }) // }) -func DeploymentNode(name string, args ...interface{}) *expr.DeploymentNode { +func DeploymentNode(name string, args ...any) *expr.DeploymentNode { if strings.Contains(name, "/") { eval.ReportError("DeploymentNode: name cannot include slashes") } @@ -168,7 +168,7 @@ func DeploymentNode(name string, args ...interface{}) *expr.DeploymentNode { // }) // }) // }) -func InfrastructureNode(name string, args ...interface{}) *expr.InfrastructureNode { +func InfrastructureNode(name string, args ...any) *expr.InfrastructureNode { d, ok := eval.Current().(*expr.DeploymentNode) if !ok { eval.IncompatibleDSL() @@ -241,7 +241,7 @@ func InfrastructureNode(name string, args ...interface{}) *expr.InfrastructureNo // }) // }) // }) -func ContainerInstance(container interface{}, dsl ...func()) *expr.ContainerInstance { +func ContainerInstance(container any, dsl ...func()) *expr.ContainerInstance { d, ok := eval.Current().(*expr.DeploymentNode) if !ok { eval.IncompatibleDSL() diff --git a/dsl/design.go b/dsl/design.go index 2a074ef2..f5424a79 100644 --- a/dsl/design.go +++ b/dsl/design.go @@ -44,7 +44,7 @@ import ( // var _ = Design("My Design", "A great architecture.", func() { // SoftwareSystem("My Software System") // }) -func Design(args ...interface{}) *expr.Design { +func Design(args ...any) *expr.Design { _, ok := eval.Current().(eval.TopExpr) if !ok { eval.IncompatibleDSL() diff --git a/dsl/doc.go b/dsl/doc.go index 235e3eb3..4a677db1 100644 --- a/dsl/doc.go +++ b/dsl/doc.go @@ -34,7 +34,7 @@ general shape of the DSL is: │ ├── Prop │ ├── AutoLayout │ ├── Uses │ ├── AnimationStep │ ├── Delivers │ ├── PaperSize - │ └─── Container │ └── EnterpriseBoundaryVisible + │ └── Container │ └── EnterpriseBoundaryVisible │ ├── Tag ├── SystemContextView │ ├── URL │ └── ... (same as SystemLandsapeView) │ ├── Prop ├── ContainerView diff --git a/dsl/elements.go b/dsl/elements.go index 00e9480f..566a8d57 100644 --- a/dsl/elements.go +++ b/dsl/elements.go @@ -39,7 +39,7 @@ import ( // Delivers("Customer", "Delivers emails to", "SMTP", Synchronous) // }) // }) -func SoftwareSystem(name string, args ...interface{}) *expr.SoftwareSystem { +func SoftwareSystem(name string, args ...any) *expr.SoftwareSystem { w, ok := eval.Current().(*expr.Design) if !ok { eval.IncompatibleDSL() @@ -112,7 +112,7 @@ func SoftwareSystem(name string, args ...interface{}) *expr.SoftwareSystem { // }) // }) // }) -func Container(args ...interface{}) *expr.Container { +func Container(args ...any) *expr.Container { system, ok := eval.Current().(*expr.SoftwareSystem) if !ok { eval.IncompatibleDSL() @@ -209,7 +209,7 @@ func Container(args ...interface{}) *expr.Container { // }) // }) // }) -func Component(name string, args ...interface{}) *expr.Component { +func Component(name string, args ...any) *expr.Component { container, ok := eval.Current().(*expr.Container) if !ok { eval.IncompatibleDSL() @@ -243,7 +243,7 @@ func Component(name string, args ...interface{}) *expr.Component { // func() // "[description]", func() // "[description]", "[technology]", func() -func parseElementArgs(args ...interface{}) (description, technology string, dsl func(), err error) { +func parseElementArgs(args ...any) (description, technology string, dsl func(), err error) { if len(args) == 0 { return } diff --git a/dsl/person.go b/dsl/person.go index 12cb75a2..b0f6ef8a 100644 --- a/dsl/person.go +++ b/dsl/person.go @@ -37,7 +37,7 @@ import ( // InteractsWith(Employee) // }) // }) -func Person(name string, args ...interface{}) *expr.Person { +func Person(name string, args ...any) *expr.Person { w, ok := eval.Current().(*expr.Design) if !ok { eval.IncompatibleDSL() diff --git a/dsl/relationship.go b/dsl/relationship.go index 499f5aa2..1282e136 100644 --- a/dsl/relationship.go +++ b/dsl/relationship.go @@ -84,7 +84,7 @@ const ( // InteractsWith("Customer", "Sends invoices to", Synchronous) // }) // }) -func Uses(element interface{}, description string, args ...interface{}) { +func Uses(element any, description string, args ...any) { var src *expr.Element switch e := eval.Current().(type) { case *expr.Person: @@ -142,7 +142,7 @@ func Uses(element interface{}, description string, args ...interface{}) { // InteractsWith(Employee, "Sends requests to", "email") // }) // }) -func InteractsWith(person interface{}, description string, args ...interface{}) { +func InteractsWith(person any, description string, args ...any) { src, ok := eval.Current().(*expr.Person) if !ok { eval.IncompatibleDSL() @@ -205,7 +205,7 @@ func InteractsWith(person interface{}, description string, args ...interface{}) // Delivers(Customer, "Sends requests to", "email") // }) // }) -func Delivers(person interface{}, description string, args ...interface{}) { +func Delivers(person any, description string, args ...any) { var src *expr.Element switch e := eval.Current().(type) { case *expr.SoftwareSystem: @@ -258,7 +258,7 @@ func Description(desc string) { // uses adds a relationship between the given source and destination. The caller // must make sure that the relationship is valid. -func uses(src *expr.Element, dest interface{}, desc string, args ...interface{}) error { +func uses(src *expr.Element, dest any, desc string, args ...any) error { var ( technology string style InteractionStyleKind diff --git a/dsl/views.go b/dsl/views.go index a2fdc937..de283273 100644 --- a/dsl/views.go +++ b/dsl/views.go @@ -103,7 +103,7 @@ const ( // Views(func() { // SystemContext(System, "SystemContext", "An example of a System Context diagram.", func() { // AddAll() -// AutoLayout() +// AutoLayout(RankTopBottom) // }) // }) // }) @@ -145,14 +145,14 @@ func Views(dsl func()) { // Title("Overview of system") // AddAll() // Remove(OtherSystem) -// AutoLayout() +// AutoLayout(RankTopBottom) // AnimationStep(System) // PaperSize(SizeSlide4X3) // EnterpriseBoundaryVisible() // }) // }) // }) -func SystemLandscapeView(key string, args ...interface{}) { +func SystemLandscapeView(key string, args ...any) { vs, ok := eval.Current().(*expr.Views) if !ok { eval.IncompatibleDSL() @@ -205,14 +205,14 @@ func SystemLandscapeView(key string, args ...interface{}) { // Title("Overview of system") // AddAll() // Remove(OtherSystem) -// AutoLayout() +// AutoLayout(RankTopBottom) // AnimationStep(System) // PaperSize(SizeSlide4X3) // EnterpriseBoundaryVisible() // }) // }) // }) -func SystemContextView(system interface{}, key string, args ...interface{}) { +func SystemContextView(system any, key string, args ...any) { vs, ok := eval.Current().(*expr.Views) if !ok { eval.IncompatibleDSL() @@ -282,14 +282,14 @@ func SystemContextView(system interface{}, key string, args ...interface{}) { // AddAll() // Remove(OtherSystem) // // Alternatively to AddAll + Remove: Add -// AutoLayout() +// AutoLayout(RankTopBottom) // AnimationStep(System) // PaperSize(SizeSlide4X3) // SystemBoundariesVisible() // }) // }) // }) -func ContainerView(system interface{}, key string, args ...interface{}) { +func ContainerView(system any, key string, args ...any) { vs, ok := eval.Current().(*expr.Views) if !ok { eval.IncompatibleDSL() @@ -364,14 +364,14 @@ func ContainerView(system interface{}, key string, args ...interface{}) { // Title("Overview of container") // AddAll() // Remove("Other System") -// AutoLayout() +// AutoLayout(RankTopBottom) // AnimationStep("Software System") // PaperSize(SizeSlide4X3) // ContainerBoundariesVisible() // }) // }) // }) -func ComponentView(container interface{}, key string, args ...interface{}) { +func ComponentView(container any, key string, args ...any) { vs, ok := eval.Current().(*expr.Views) if !ok { eval.IncompatibleDSL() @@ -418,8 +418,8 @@ func ComponentView(container interface{}, key string, args ...interface{}) { // // FilteredView must appear in Views. // -// FilteredView accepts 2 arguments: the view being filtered and a function -// describing additional properties. +// FilteredView accepts 2 arguments: the view being filtered or its key and a +// function describing additional properties. // // Example: // @@ -428,7 +428,7 @@ func ComponentView(container interface{}, key string, args ...interface{}) { // Views(func() { // SystemContextView(SoftwareSystem, "context", "An overview diagram.", func() { // AddAll() -// AutoLayout() +// AutoLayout(RankTopBottom) // }) // FilteredView(SystemContextView, func() { // FilterTag("infra") @@ -436,24 +436,27 @@ func ComponentView(container interface{}, key string, args ...interface{}) { // }) // }) // }) -func FilteredView(view interface{}, dsl func()) { +func FilteredView(view any, dsl func()) { vs, ok := eval.Current().(*expr.Views) if !ok { eval.IncompatibleDSL() return } - var key string - if v, ok := view.(expr.View); ok { - key = v.Props().Key - } else { + var baseKey string + switch actual := view.(type) { + case string: + baseKey = actual + case expr.View: + baseKey = actual.Props().Key + default: eval.IncompatibleDSL() return } - if key == "" { + if baseKey == "" { eval.ReportError("Filtered view applied on a view with no key. Make sure the view given as argument defines a key.") return } - fv := &expr.FilteredView{BaseKey: key} + fv := &expr.FilteredView{BaseKey: baseKey} eval.Execute(dsl, fv) vs.FilteredViews = append(vs.FilteredViews, fv) } @@ -535,12 +538,12 @@ func FilterTag(tag string, tags ...string) { // DynamicView(Global, "dynamic", "A dynamic diagram.", func() { // Title("Overview of system") // Link(FirstSystem, SecondSystem) -// AutoLayout() +// AutoLayout(RankTopBottom) // PaperSize(SizeSlide4X3) // }) // }) // }) -func DynamicView(scope interface{}, key string, args ...interface{}) { +func DynamicView(scope any, key string, args ...any) { vs, ok := eval.Current().(*expr.Views) if !ok { eval.IncompatibleDSL() @@ -648,20 +651,20 @@ func DynamicView(scope interface{}, key string, args ...interface{}) { // Title("Overview of deployment") // AddAll() // Remove("System/OtherContainer") -// AutoLayout() +// AutoLayout(RankTopBottom) // AnimationStep("System/Container") // PaperSize(SizeSlide4X3) // }) // }) // }) -func DeploymentView(scope interface{}, env, key string, args ...interface{}) { +func DeploymentView(scope any, env, key string, args ...any) { vs, ok := eval.Current().(*expr.Views) if !ok { eval.IncompatibleDSL() return } missing := true - expr.Iterate(func(e interface{}) { + expr.Iterate(func(e any) { if dn, ok := e.(*expr.DeploymentNode); ok { if dn.Environment == env { missing = false @@ -840,7 +843,7 @@ func Title(t string) { // }) // }) // }) -func Add(element interface{}, dsl ...func()) { +func Add(element any, dsl ...func()) { var ( eh expr.ElementHolder err error @@ -972,7 +975,7 @@ func Add(element interface{}, dsl ...func()) { // }) // }) // }) -func Link(source, destination interface{}, args ...interface{}) { +func Link(source, destination any, args ...any) { v, ok := eval.Current().(expr.View) if !ok { eval.IncompatibleDSL() @@ -1074,7 +1077,7 @@ func AddAll() { // }) // }) // }) -func AddNeighbors(element interface{}) { +func AddNeighbors(element any) { v, ok := eval.Current().(expr.View) if !ok { eval.IncompatibleDSL() @@ -1134,10 +1137,10 @@ func AddDefault() { func AddContainers() { switch v := eval.Current().(type) { case *expr.ContainerView: - v.AddElements(expr.Registry[v.SoftwareSystemID].(*expr.SoftwareSystem).Containers.Elements()...) + v.AddElements(expr.Registry[v.SoftwareSystemID].(*expr.SoftwareSystem).Containers.Elements()...) // nolint: errcheck case *expr.ComponentView: c := expr.Registry[v.ContainerID].(*expr.Container) - v.AddElements(c.System.Containers.Elements()...) + v.AddElements(c.System.Containers.Elements()...) // nolint: errcheck default: eval.IncompatibleDSL() } @@ -1167,7 +1170,7 @@ func AddInfluencers() { // AddComponents takes no argument func AddComponents() { if cv, ok := eval.Current().(*expr.ComponentView); ok { - cv.AddElements(expr.Registry[cv.ContainerID].(*expr.Container).Components.Elements()...) + cv.AddElements(expr.Registry[cv.ContainerID].(*expr.Container).Components.Elements()...) // nolint: errcheck return } eval.IncompatibleDSL() @@ -1227,7 +1230,7 @@ func AddComponents() { // }) // }) // }) -func Remove(element interface{}) { +func Remove(element any) { v, ok := eval.Current().(expr.View) if !ok { eval.IncompatibleDSL() @@ -1334,14 +1337,14 @@ func RemoveTagged(tag string) { // }) // }) // }) -func Unlink(source, destination interface{}, description ...string) { +func Unlink(source, destination any, description ...string) { v, ok := eval.Current().(expr.View) if !ok { eval.IncompatibleDSL() } - var args []interface{} + var args []any if len(description) > 0 { - args = []interface{}{description[0]} + args = []any{description[0]} if len(description) > 1 { eval.ReportError("Unlink: too many arguments") } @@ -1394,7 +1397,7 @@ func Unlink(source, destination interface{}, description ...string) { // }) // }) // }) -func RemoveUnreachable(element interface{}) { +func RemoveUnreachable(element any) { v, ok := eval.Current().(expr.View) if !ok { eval.IncompatibleDSL() @@ -1439,6 +1442,15 @@ func RemoveUnrelated() { eval.IncompatibleDSL() } +// DefaultRankSeparation sets the default rank separation for auto layout. +var DefaultRankSeparation = 300 + +// DefaultNodeSeparation sets the default node separation for auto layout. +var DefaultNodeSeparation = 600 + +// DefaultEdgeSeparation sets the default edge separation for auto layout. +var DefaultEdgeSeparation = 200 + // AutoLayout enables automatic layout mode for the diagram. The // first argument indicates the rank direction, it must be one of // RankTopBottom, RankBottomTop, RankLeftRight or RankRightLeft @@ -1483,12 +1495,11 @@ func AutoLayout(rank RankDirectionKind, args ...func()) { eval.ReportError("AutoLayout: too many arguments") } } - r, n, e := 300, 600, 200 layout := &expr.AutoLayout{ RankDirection: expr.RankDirectionKind(rank), - RankSep: &r, - NodeSep: &n, - EdgeSep: &e, + RankSep: &DefaultRankSeparation, + NodeSep: &DefaultNodeSeparation, + EdgeSep: &DefaultEdgeSeparation, } if dsl != nil { eval.Execute(dsl, layout) @@ -1530,7 +1541,7 @@ func AutoLayout(rank RankDirectionKind, args ...func()) { // }) // }) // }) -func AnimationStep(elements ...interface{}) { +func AnimationStep(elements ...any) { v, ok := eval.Current().(expr.ViewAdder) if !ok { eval.IncompatibleDSL() @@ -1730,7 +1741,10 @@ func Vertices(args ...int) { eval.IncompatibleDSL() } for i := 0; i < len(args); i += 2 { - rv.Vertices = append(rv.Vertices, &expr.Vertex{args[i], args[i+1]}) + rv.Vertices = append(rv.Vertices, &expr.Vertex{ + X: args[i], + Y: args[i+1], + }) } } @@ -1932,7 +1946,7 @@ func RenderVertices() { // // func() // "[description]", func() -func parseView(args ...interface{}) (description string, dsl func(), err error) { +func parseView(args ...any) (description string, dsl func(), err error) { if len(args) == 0 { err = fmt.Errorf("missing argument") return @@ -1967,7 +1981,7 @@ func parseView(args ...interface{}) (description string, dsl func(), err error) // findViewElement returns the element identifed by element that // is in scope for the given view. See model.FindElement for details. -func findViewElement(view expr.View, element interface{}) (expr.ElementHolder, error) { +func findViewElement(view expr.View, element any) (expr.ElementHolder, error) { if eh, ok := element.(expr.ElementHolder); ok { return eh, nil } @@ -2044,7 +2058,7 @@ func findDeploymentViewElement(env, path string) (expr.ElementHolder, error) { return nil, fmt.Errorf("could not find %q in path %q", name, path) } -func parseLinkArgs(v expr.View, source interface{}, destination interface{}, args []interface{}) (src, dest expr.ElementHolder, desc string, dsl func(), err error) { +func parseLinkArgs(v expr.View, source any, destination any, args []any) (src, dest expr.ElementHolder, desc string, dsl func(), err error) { var ok bool if len(args) > 0 { if dsl, ok = args[len(args)-1].(func()); ok { diff --git a/expr/component.go b/expr/component.go index 2efa687b..81e914ea 100644 --- a/expr/component.go +++ b/expr/component.go @@ -16,6 +16,9 @@ type ( Components []*Component ) +// ComponentTags lists the tags that are added to all components. +var ComponentTags = []string{"Element", "Component"} + // EvalName returns the generic expression name used in error messages. func (c *Component) EvalName() string { if c.Name == "" { @@ -26,7 +29,7 @@ func (c *Component) EvalName() string { // Finalize adds the 'Component' tag ands finalizes relationships. func (c *Component) Finalize() { - c.PrefixTags("Element", "Component") + c.PrefixTags(ComponentTags...) c.Element.Finalize() } diff --git a/expr/container.go b/expr/container.go index 7419929c..9676391c 100644 --- a/expr/container.go +++ b/expr/container.go @@ -18,6 +18,9 @@ type ( Containers []*Container ) +// ContainerTags lists the tags that are added to all containers. +var ContainerTags = []string{"Element", "Container"} + // EvalName returns the generic expression name used in error messages. func (c *Container) EvalName() string { if c.Name == "" { @@ -28,7 +31,7 @@ func (c *Container) EvalName() string { // Finalize adds the 'Container' tag ands finalizes relationships. func (c *Container) Finalize() { - c.PrefixTags("Element", "Container") + c.PrefixTags(ContainerTags...) c.Element.Finalize() } diff --git a/expr/deployment.go b/expr/deployment.go index b601409b..50aff469 100644 --- a/expr/deployment.go +++ b/expr/deployment.go @@ -60,6 +60,18 @@ type ( } ) +// DeploymentNodeTags list the tags that are automatically added to all +// deployment nodes. +var DeploymentNodeTags = []string{"Element", "Deployment Node"} + +// InfrastructureNodeTags list the tags that are automatically added to all +// infrastructure nodes. +var InfrastructureNodeTags = []string{"Element", "Infrastructure Node"} + +// ContainerInstanceTags list the tags that are automatically added to all +// container instances. +var ContainerInstanceTags = []string{"Container Instance"} + // EvalName returns the generic expression name used in error messages. func (d *DeploymentEnvironment) EvalName() string { return fmt.Sprintf("deployment environment %q", d.Name) @@ -70,7 +82,7 @@ func (d *DeploymentNode) EvalName() string { return fmt.Sprintf("deployment node // Finalize adds the 'Deployment Node' tag ands finalizes relationships. func (d *DeploymentNode) Finalize() { - d.PrefixTags("Element", "Deployment Node") + d.PrefixTags(DeploymentNodeTags...) d.Element.Finalize() } @@ -218,7 +230,7 @@ func (i *InfrastructureNode) EvalName() string { // Finalize adds the 'Infrastructure Node' tag ands finalizes relationships. func (i *InfrastructureNode) Finalize() { - i.PrefixTags("Element", "Infrastructure Node") + i.PrefixTags(InfrastructureNodeTags...) i.Element.Finalize() } @@ -233,7 +245,7 @@ func (ci *ContainerInstance) EvalName() string { // Finalize adds the "Container Instance" tag if not present. func (ci *ContainerInstance) Finalize() { - ci.PrefixTags("Container Instance") + ci.PrefixTags(ContainerInstanceTags...) ci.Element.Finalize() } diff --git a/expr/design.go b/expr/design.go index 023d708f..1be1d0e8 100644 --- a/expr/design.go +++ b/expr/design.go @@ -24,7 +24,7 @@ var Root = &Design{Model: &Model{}, Views: &Views{}} // Register design root with eval engine. func init() { - eval.Register(Root) + eval.Register(Root) // nolint: errcheck } // WalkSets iterates over the elements and views. diff --git a/expr/element.go b/expr/element.go index 9eaec8b7..413b9501 100644 --- a/expr/element.go +++ b/expr/element.go @@ -85,6 +85,9 @@ func mergeTags(existing string, tags []string) string { } } for _, tag := range tags { + if tag == "" { + continue + } found := false for _, o := range merged { if tag == o { diff --git a/expr/model.go b/expr/model.go index b5b01cae..7e1e8f7a 100644 --- a/expr/model.go +++ b/expr/model.go @@ -92,7 +92,7 @@ func (m *Model) Validate() error { // Finalize adds all implied relationships if needed. func (m *Model) Finalize() { // Add relationships between container instances. - Iterate(func(e interface{}) { + Iterate(func(e any) { if ci, ok := e.(*ContainerInstance); ok { c := Registry[ci.ContainerID].(*Container) for _, r := range c.Relationships { @@ -100,7 +100,7 @@ func (m *Model) Finalize() { if !ok { continue } - Iterate(func(e interface{}) { + Iterate(func(e any) { eci, ok := e.(*ContainerInstance) if !ok { return @@ -118,7 +118,7 @@ func (m *Model) Finalize() { return } // Add relationship between element parents. - Iterate(func(e interface{}) { + Iterate(func(e any) { if r, ok := e.(*Relationship); ok { src := Registry[r.Source.ID].(ElementHolder) switch s := src.(type) { diff --git a/expr/model_test.go b/expr/model_test.go index 28808320..8fc85fc2 100644 --- a/expr/model_test.go +++ b/expr/model_test.go @@ -566,7 +566,7 @@ func Test_AddImpliedRelationship(t *testing.T) { } for i, tt := range tests { tt := tt - t.Run(fmt.Sprint(i), func(t *testing.T) { + t.Run(fmt.Sprint(i), func(_ *testing.T) { addImpliedRelationships(tt.src, tt.dst, tt.existing) }) } @@ -689,7 +689,7 @@ func TestModelFinalize(t *testing.T) { {}, } for i := range tests { - t.Run(fmt.Sprint(i), func(t *testing.T) { + t.Run(fmt.Sprint(i), func(_ *testing.T) { m.Finalize() }) } diff --git a/expr/person.go b/expr/person.go index 27b7c500..8444b46c 100644 --- a/expr/person.go +++ b/expr/person.go @@ -15,6 +15,9 @@ type ( People []*Person ) +// PersonTags list the tags that are automatically added to all people. +var PersonTags = []string{"Element", "Person"} + // EvalName returns the generic expression name used in error messages. func (p *Person) EvalName() string { if p.Name == "" { @@ -25,7 +28,7 @@ func (p *Person) EvalName() string { // Finalize adds the 'Person' tag ands finalizes relationships. func (p *Person) Finalize() { - p.PrefixTags("Element", "Person") + p.PrefixTags(PersonTags...) p.Element.Finalize() } diff --git a/expr/registry.go b/expr/registry.go index 17036af5..940f5fa5 100644 --- a/expr/registry.go +++ b/expr/registry.go @@ -8,11 +8,11 @@ import ( ) // Registry captures all the elements, people and relationships. -var Registry = make(map[string]interface{}) +var Registry = make(map[string]any) // Iterate iterates through all elements, people and relationships in the // registry in a consistent order. -func Iterate(visitor func(elem interface{})) { +func Iterate(visitor func(elem any)) { keys := make([]string, len(Registry)) i := 0 for k := range Registry { @@ -28,7 +28,7 @@ func Iterate(visitor func(elem interface{})) { // IterateRelationships iterates through all relationships in the registry in a // consistent order. func IterateRelationships(visitor func(r *Relationship)) { - Iterate(func(e interface{}) { + Iterate(func(e any) { if r, ok := e.(*Relationship); ok { visitor(r) } @@ -39,7 +39,7 @@ func IterateRelationships(visitor func(r *Relationship)) { // it with the global registery. The algorithm first compute a unique moniker // for the element or relatioship (based on names and parent scope ID) then // hashes and base36 encodes the result. -func Identify(element interface{}) { +func Identify(element any) { switch e := element.(type) { case *Person: e.ID = idify(e.Name) diff --git a/expr/relationship.go b/expr/relationship.go index 5105bb17..e2d995c2 100644 --- a/expr/relationship.go +++ b/expr/relationship.go @@ -2,6 +2,7 @@ package expr import ( "fmt" + "strings" ) type ( @@ -42,6 +43,9 @@ const ( InteractionAsynchronous ) +// RelationshipTags lists the tags that are added to all relationships. +var RelationshipTags = []string{"Relationship", "Asynchronous", "Synchronous"} + // EvalName is the qualified name of the expression. func (r *Relationship) EvalName() string { var src, dest = "", "" @@ -58,11 +62,12 @@ func (r *Relationship) EvalName() string { func (r *Relationship) Finalize() { // prefix tags if r.InteractionStyle == InteractionAsynchronous { - r.Tags = mergeTags("Asynchronous", []string{r.Tags}) + r.Tags = mergeTags("Asynchronous", strings.Split(r.Tags, ",")) } - r.Tags = mergeTags("Relationship", []string{r.Tags}) + r.Tags = mergeTags(RelationshipTags[0], strings.Split(r.Tags, ",")) } +// PrefixTags adds the given tags to the beginning of the comm // Dup creates a new relationship with identical description, tags, URL, // technology and interaction style as r. Dup also creates a new ID for the // result. diff --git a/expr/relationship_test.go b/expr/relationship_test.go index c5fed364..471b98a1 100644 --- a/expr/relationship_test.go +++ b/expr/relationship_test.go @@ -40,8 +40,8 @@ func Test_Relationship_Finalize(t *testing.T) { InteractionStyle InteractionStyleKind want string }{ - {InteractionStyle: InteractionAsynchronous, want: "Relationship,Asynchronous,"}, - {InteractionStyle: InteractionSynchronous, want: "Relationship,"}, + {InteractionStyle: InteractionAsynchronous, want: "Relationship,Asynchronous"}, + {InteractionStyle: InteractionSynchronous, want: "Relationship"}, } for i, tt := range tests { mRelationship.InteractionStyle = tt.InteractionStyle diff --git a/expr/render.go b/expr/render.go index 987cae74..a8d66467 100644 --- a/expr/render.go +++ b/expr/render.go @@ -11,26 +11,27 @@ func addAllElements(view View) { m := Root.Model switch v := view.(type) { case *LandscapeView: - v.AddElements(m.People.Elements()...) - v.AddElements(m.Systems.Elements()...) + v.AddElements(m.People.Elements()...) // nolint: errcheck + v.AddElements(m.Systems.Elements()...) // nolint: errcheck case *ContextView: - v.AddElements(m.People.Elements()...) - v.AddElements(m.Systems.Elements()...) + v.AddElements(m.People.Elements()...) // nolint: errcheck + v.AddElements(m.Systems.Elements()...) // nolint: errcheck case *ContainerView: - v.AddElements(m.People.Elements()...) - v.AddElements(m.Systems.Elements()...) - v.AddElements(Registry[v.SoftwareSystemID].(*SoftwareSystem).Containers.Elements()...) - removeElements(v.Props(), Registry[v.SoftwareSystemID].(*SoftwareSystem).Element) + v.AddElements(m.People.Elements()...) // nolint: errcheck + v.AddElements(m.Systems.Elements()...) // nolint: errcheck + s := Registry[v.SoftwareSystemID].(*SoftwareSystem) + v.AddElements(s.Containers.Elements()...) // nolint: errcheck + removeElements(v.Props(), s.Element) // nolint: errcheck case *ComponentView: - v.AddElements(m.People.Elements()...) - v.AddElements(m.Systems.Elements()...) + v.AddElements(m.People.Elements()...) // nolint: errcheck + v.AddElements(m.Systems.Elements()...) // nolint: errcheck c := Registry[v.ContainerID].(*Container) - v.AddElements(c.System.Containers.Elements()...) - v.AddElements(c.Components.Elements()...) + v.AddElements(c.System.Containers.Elements()...) // nolint: errcheck + v.AddElements(c.Components.Elements()...) // nolint: errcheck case *DeploymentView: for _, n := range m.DeploymentNodes { if n.Environment == "" || n.Environment == v.Environment { - v.AddElements(n) + v.AddElements(n) // nolint: errcheck } } default: @@ -47,22 +48,22 @@ func addDefaultElements(view View) { addAllElements(v) case *ContextView: s := Registry[v.SoftwareSystemID].(*SoftwareSystem) - v.AddElements(s) + v.AddElements(s) // nolint: errcheck addNeighbors(s.Element, v) case *ContainerView: s := Registry[v.SoftwareSystemID].(*SoftwareSystem) - v.AddElements(s.Containers.Elements()...) + v.AddElements(s.Containers.Elements()...) // nolint: errcheck for _, c := range s.Containers { - v.AddElements(relatedSoftwareSystems(c.Element).Elements()...) - v.AddElements(relatedPeople(c.Element).Elements()...) + v.AddElements(relatedSoftwareSystems(c.Element).Elements()...) // nolint: errcheck + v.AddElements(relatedPeople(c.Element).Elements()...) // nolint: errcheck } case *ComponentView: c := Registry[v.ContainerID].(*Container) - v.AddElements(c.Components.Elements()...) + v.AddElements(c.Components.Elements()...) // nolint: errcheck for _, c := range c.Components { - v.AddElements(relatedContainers(c.Element).Elements()...) - v.AddElements(relatedSoftwareSystems(c.Element).Elements()...) - v.AddElements(relatedPeople(c.Element).Elements()...) + v.AddElements(relatedContainers(c.Element).Elements()...) // nolint: errcheck + v.AddElements(relatedSoftwareSystems(c.Element).Elements()...) // nolint: errcheck + v.AddElements(relatedPeople(c.Element).Elements()...) // nolint: errcheck } case *DeploymentView: addAllElements(v) @@ -146,23 +147,23 @@ func addMissingElementsAndRelationships(vp *ViewProps) { func addNeighbors(e *Element, view View) { switch v := view.(type) { case *LandscapeView: - v.AddElements(relatedPeople(e).Elements()...) - v.AddElements(relatedSoftwareSystems(e).Elements()...) + v.AddElements(relatedPeople(e).Elements()...) // nolint: errcheck + v.AddElements(relatedSoftwareSystems(e).Elements()...) // nolint: errcheck case *ContextView: - v.AddElements(relatedPeople(e).Elements()...) - v.AddElements(relatedSoftwareSystems(e).Elements()...) + v.AddElements(relatedPeople(e).Elements()...) // nolint: errcheck + v.AddElements(relatedSoftwareSystems(e).Elements()...) // nolint: errcheck case *ContainerView: - v.AddElements(relatedPeople(e).Elements()...) - v.AddElements(relatedSoftwareSystems(e).Elements()...) - v.AddElements(relatedContainers(e).Elements()...) + v.AddElements(relatedPeople(e).Elements()...) // nolint: errcheck + v.AddElements(relatedSoftwareSystems(e).Elements()...) // nolint: errcheck + v.AddElements(relatedContainers(e).Elements()...) // nolint: errcheck case *ComponentView: - v.AddElements(relatedPeople(e).Elements()...) - v.AddElements(relatedSoftwareSystems(e).Elements()...) - v.AddElements(relatedContainers(e).Elements()...) - v.AddElements(relatedComponents(e).Elements()...) + v.AddElements(relatedPeople(e).Elements()...) // nolint: errcheck + v.AddElements(relatedSoftwareSystems(e).Elements()...) // nolint: errcheck + v.AddElements(relatedContainers(e).Elements()...) // nolint: errcheck + v.AddElements(relatedComponents(e).Elements()...) // nolint: errcheck case *DeploymentView: - v.AddElements(relatedInfrastructureNodes(e).Elements()...) - v.AddElements(relatedContainerInstances(e).Elements()...) + v.AddElements(relatedInfrastructureNodes(e).Elements()...) // nolint: errcheck + v.AddElements(relatedContainerInstances(e).Elements()...) // nolint: errcheck } } @@ -173,12 +174,12 @@ func addInfluencers(cv *ContainerView) { for _, s := range m.Systems { for _, r := range s.Relationships { if r.Destination.ID == cv.SoftwareSystemID { - cv.AddElements(s) + cv.AddElements(s) // nolint: errcheck } } for _, r := range system.Relationships { if r.Destination.ID == s.ID { - cv.AddElements(s) + cv.AddElements(s) // nolint: errcheck } } } @@ -186,12 +187,12 @@ func addInfluencers(cv *ContainerView) { for _, p := range m.People { for _, r := range p.Relationships { if r.Destination.ID == cv.SoftwareSystemID { - cv.AddElements(p) + cv.AddElements(p) // nolint: errcheck } } for _, r := range system.Relationships { if r.Destination.ID == p.ID { - cv.AddElements(p) + cv.AddElements(p) // nolint: errcheck } } } diff --git a/expr/render_test.go b/expr/render_test.go index 27a7eb9d..64d6aa64 100644 --- a/expr/render_test.go +++ b/expr/render_test.go @@ -40,7 +40,7 @@ func Test_AddAllElements(t *testing.T) { {in: &mDeploymentView}, } for i, tt := range tests { - t.Run(fmt.Sprint(i), func(t *testing.T) { + t.Run(fmt.Sprint(i), func(_ *testing.T) { addAllElements(tt.in) }) } @@ -89,7 +89,7 @@ func Test_AddDefaultElements(t *testing.T) { {in: &mDeploymentView}, } for i, tt := range tests { - t.Run(fmt.Sprint(i), func(t *testing.T) { + t.Run(fmt.Sprint(i), func(_ *testing.T) { addDefaultElements(tt.in) }) } @@ -139,7 +139,7 @@ func Test_AddNeighbors(t *testing.T) { {el: mContainer.Element, in: &mDeploymentView}, } for i, tt := range tests { - t.Run(fmt.Sprint(i), func(t *testing.T) { + t.Run(fmt.Sprint(i), func(_ *testing.T) { addNeighbors(tt.el, tt.in) }) } @@ -290,7 +290,7 @@ func Test_AddInfluencers(t *testing.T) { {el: &mContainerView}, } for i, tt := range tests { - t.Run(fmt.Sprint(i), func(t *testing.T) { + t.Run(fmt.Sprint(i), func(_ *testing.T) { addInfluencers(tt.el) }) } diff --git a/expr/system.go b/expr/system.go index 62668ea5..bc34a874 100644 --- a/expr/system.go +++ b/expr/system.go @@ -18,6 +18,9 @@ type ( SoftwareSystems []*SoftwareSystem ) +// SoftwareSystemTags lists the tags that are added to all software systems. +var SoftwareSystemTags = []string{"Element", "Software System"} + // EvalName returns the generic expression name used in error messages. func (s *SoftwareSystem) EvalName() string { if s.Name == "" { @@ -28,7 +31,7 @@ func (s *SoftwareSystem) EvalName() string { // Finalize adds the 'SoftwareSystem' tag ands finalizes relationships. func (s *SoftwareSystem) Finalize() { - s.PrefixTags("Element", "Software System") + s.PrefixTags(SoftwareSystemTags...) s.Element.Finalize() } diff --git a/expr/views.go b/expr/views.go index e2a238f7..24058429 100644 --- a/expr/views.go +++ b/expr/views.go @@ -621,3 +621,53 @@ func validateElementInView(v *ViewProps, e *Element, title string, verr *eval.Va } verr.Add(v, "%T %q used in %s not added to the view %q", e, e.Name, title, v.Key) } + +// Name returns then name of the shape. +func (s ShapeKind) Name() string { + switch s { + case ShapeBox: + return "ShapeBox" + case ShapeCircle: + return "ShapeCircle" + case ShapeCylinder: + return "ShapeCylinder" + case ShapeEllipse: + return "ShapeEllipse" + case ShapeHexagon: + return "ShapeHexagon" + case ShapeRoundedBox: + return "ShapeRoundedBox" + case ShapeComponent: + return "ShapeComponent" + case ShapeFolder: + return "ShapeFolder" + case ShapeMobileDeviceLandscape: + return "ShapeMobileDeviceLandscape" + case ShapeMobileDevicePortrait: + return "ShapeMobileDevicePortrait" + case ShapePerson: + return "ShapePerson" + case ShapePipe: + return "ShapePipe" + case ShapeRobot: + return "ShapeRobot" + case ShapeWebBrowser: + return "ShapeWebBrowser" + default: + return "ShapeUndefined" + } +} + +// Name returns the name of the border kind. +func (b BorderKind) Name() string { + switch b { + case BorderSolid: + return "BorderSolid" + case BorderDashed: + return "BorderDashed" + case BorderDotted: + return "BorderDotted" + default: + return "BorderUndefined" + } +} diff --git a/go.mod b/go.mod index 0836724d..181cb75b 100644 --- a/go.mod +++ b/go.mod @@ -6,21 +6,25 @@ require ( github.com/fsnotify/fsnotify v1.6.0 github.com/jaschaephraim/lrserver v0.0.0-20171129202958-50d19f603f71 github.com/kylelemons/godebug v1.1.0 + github.com/stretchr/testify v1.8.4 goa.design/goa/v3 v3.13.2 golang.org/x/tools v0.14.0 ) require ( github.com/AnatolyRugalev/goregen v0.1.0 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect github.com/dimfeld/httppath v0.0.0-20170720192232-ee938bf73598 // indirect github.com/go-chi/chi/v5 v5.0.10 // indirect github.com/google/uuid v1.3.1 // indirect github.com/gorilla/websocket v1.5.0 // indirect github.com/manveru/faker v0.0.0-20171103152722-9fbc68a78c4d // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect github.com/sergi/go-diff v1.3.1 // indirect github.com/smartystreets/goconvey v1.8.1 // indirect golang.org/x/mod v0.13.0 // indirect golang.org/x/sys v0.13.0 // indirect golang.org/x/text v0.13.0 // indirect gopkg.in/fsnotify.v1 v1.4.7 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index e8be78ab..dd154157 100644 --- a/go.sum +++ b/go.sum @@ -19,8 +19,10 @@ github.com/jaschaephraim/lrserver v0.0.0-20171129202958-50d19f603f71 h1:24NdJ5N6 github.com/jaschaephraim/lrserver v0.0.0-20171129202958-50d19f603f71/go.mod h1:ozZLfjiLmXytkIUh200wMeuoQJ4ww06wN+KZtFP6j3g= github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= @@ -42,25 +44,19 @@ github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcU github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= goa.design/goa/v3 v3.13.2 h1:RclNIpo7891ZqGRVO4fpBjT7Fs7LjBNm78i8J41KHrI= goa.design/goa/v3 v3.13.2/go.mod h1:VvZsuC8CSIUQOHVqk6Ep3MFSFz21OjOv87UPqCHiB94= -golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= -golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.13.0 h1:I/DsJXRlw/8l/0c24sM9yb0T4z9liZTduXvdAWYiysY= golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= -golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ= +golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o= -golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ= -golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= golang.org/x/tools v0.14.0 h1:jvNa2pY0M4r62jkRQ6RwEZZyPcymeL9XZMLBbV7U2nc= golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= diff --git a/mdl/elements.go b/mdl/elements.go index b79e67ea..2ce2e140 100644 --- a/mdl/elements.go +++ b/mdl/elements.go @@ -14,8 +14,6 @@ type ( Name string `json:"name,omitempty"` // Description of element if any. Description string `json:"description,omitempty"` - // Technology used by element if any - not applicable to Person. - Technology string `json:"technology,omitempty"` // Tags attached to element as comma separated list if any. Tags string `json:"tags,omitempty"` // URL where more information about this element can be found. @@ -37,8 +35,6 @@ type ( Name string `json:"name,omitempty"` // Description of element if any. Description string `json:"description,omitempty"` - // Technology used by element if any - not applicable to Person. - Technology string `json:"technology,omitempty"` // Tags attached to element as comma separated list if any. Tags string `json:"tags,omitempty"` // URL where more information about this element can be found. @@ -75,8 +71,6 @@ type ( Relationships []*Relationship `json:"relationships,omitempty"` // Components list the components within the container. Components []*Component `json:"components,omitempty"` - // Endpoints list the endpoints exposed by the container. - Endpoints []*Endpoint `json:"endpoints,omitempty"` } // Component represents a component. @@ -100,16 +94,6 @@ type ( Relationships []*Relationship `json:"relationships,omitempty"` } - // Endpoint describes a container endpoint. - // - // Note: Endpoint information is not used directly in diagrams instead - // it is serialized in the system JSON representation for other tools to - // consume. - Endpoint struct { - Name string `json:"name"` - Description string `json:"description,omitempty"` - } - // LocationKind is the enum for possible locations. LocationKind int ) diff --git a/mdl/eval.go b/mdl/eval.go index 07207f68..c0c58075 100644 --- a/mdl/eval.go +++ b/mdl/eval.go @@ -124,7 +124,6 @@ func modelizePerson(p *expr.Person) *Person { ID: p.Element.ID, Name: p.Element.Name, Description: p.Element.Description, - Technology: p.Element.Technology, Tags: p.Element.Tags, URL: p.Element.URL, Properties: p.Element.Properties, @@ -156,7 +155,6 @@ func modelizeSystem(sys *expr.SoftwareSystem) *SoftwareSystem { ID: sys.ID, Name: sys.Name, Description: sys.Description, - Technology: sys.Technology, Tags: sys.Tags, URL: sys.URL, Properties: sys.Properties, diff --git a/mdl/views.go b/mdl/views.go index d562eb0c..d41d6e2e 100644 --- a/mdl/views.go +++ b/mdl/views.go @@ -419,6 +419,56 @@ func (s *Styles) MarshalJSON() ([]byte, error) { return json.Marshal(&ss) } +// Name is the name of the paper size kind as it appears in the DSL. +func (p PaperSizeKind) Name() string { + switch p { + case SizeA0Landscape: + return "SizeA0Landscape" + case SizeA0Portrait: + return "SizeA0Portrait" + case SizeA1Landscape: + return "SizeA1Landscape" + case SizeA1Portrait: + return "SizeA1Portrait" + case SizeA2Landscape: + return "SizeA2Landscape" + case SizeA2Portrait: + return "SizeA2Portrait" + case SizeA3Landscape: + return "SizeA3Landscape" + case SizeA3Portrait: + return "SizeA3Portrait" + case SizeA4Landscape: + return "SizeA4Landscape" + case SizeA4Portrait: + return "SizeA4Portrait" + case SizeA5Landscape: + return "SizeA5Landscape" + case SizeA5Portrait: + return "SizeA5Portrait" + case SizeA6Landscape: + return "SizeA6Landscape" + case SizeA6Portrait: + return "SizeA6Portrait" + case SizeLegalLandscape: + return "SizeLegalLandscape" + case SizeLegalPortrait: + return "SizeLegalPortrait" + case SizeLetterLandscape: + return "SizeLetterLandscape" + case SizeLetterPortrait: + return "SizeLetterPortrait" + case SizeSlide16X10: + return "SizeSlide16X10" + case SizeSlide16X9: + return "SizeSlide16X9" + case SizeSlide4X3: + return "SizeSlide4X3" + default: + return "SizeUndefined" + } +} + // MarshalJSON replaces the constant value with the proper string value. func (p PaperSizeKind) MarshalJSON() ([]byte, error) { buf := bytes.NewBufferString(`"`) @@ -525,6 +575,22 @@ func (p *PaperSizeKind) UnmarshalJSON(data []byte) error { return nil } +// Name returns the name of the rank direction is specified in the DSL. +func (r RankDirectionKind) Name() string { + switch r { + case RankTopBottom: + return "RankTopBottom" + case RankBottomTop: + return "RankBottomTop" + case RankLeftRight: + return "RankLeftRight" + case RankRightLeft: + return "RankRightLeft" + default: + return "RankUndefined" + } +} + // MarshalJSON replaces the constant value with the proper string value. func (r RoutingKind) MarshalJSON() ([]byte, error) { buf := bytes.NewBufferString(`"`) diff --git a/plugin/generate.go b/plugin/generate.go index cbd58eb2..2a454796 100644 --- a/plugin/generate.go +++ b/plugin/generate.go @@ -46,7 +46,7 @@ func Generate(_ string, roots []eval.Root, files []*codegen.File) ([]*codegen.Fi return files, nil } -func toJSON(d interface{}) string { +func toJSON(d any) string { b, err := json.MarshalIndent(d, "", " ") if err != nil { panic("design: " + err.Error()) // bug diff --git a/stz/client.go b/stz/client.go index 1957e2d3..919e1895 100644 --- a/stz/client.go +++ b/stz/client.go @@ -143,7 +143,7 @@ func (c *Client) lockUnlock(id string, lock bool) error { if resp.StatusCode != http.StatusOK { var res Response - json.NewDecoder(resp.Body).Decode(&res) // ignore error, just trying + json.NewDecoder(resp.Body).Decode(&res) // nolint: errcheck err = fmt.Errorf("service error: %s", resp.Status) if res.Message != "" { err = errors.New(res.Message) diff --git a/stz/client_test.go b/stz/client_test.go index 2d1a725e..463b81a1 100644 --- a/stz/client_test.go +++ b/stz/client_test.go @@ -23,7 +23,9 @@ func TestGet(t *testing.T) { validateHeaders(t, req) rw.Header().Add("Content-Type", "application/json") rw.WriteHeader(http.StatusOK) - json.NewEncoder(rw).Encode(wkspc) + if err := json.NewEncoder(rw).Encode(wkspc); err != nil { + t.Fatalf("failed to encode response: %s", err) + } })) defer server.Close()