diff --git a/types/executable/executable.go b/types/executable/executable.go index e34dcb2a..1fa67997 100644 --- a/types/executable/executable.go +++ b/types/executable/executable.go @@ -63,9 +63,16 @@ func (e *ExecExecutableType) GetLogFields() map[string]interface{} { type enrichedExecutableList struct { Executables []*enrichedExecutable `json:"executables" yaml:"executables"` } + type enrichedExecutable struct { - ID string `json:"id" yaml:"id"` - Spec *Executable `json:"spec" yaml:"spec"` + *Executable + + ID string `json:"id" yaml:"id"` + Ref string `json:"ref" yaml:"ref"` + Namespace string `json:"namespace" yaml:"namespace"` + Workspace string `json:"workspace" yaml:"workspace"` + Flowfile string `json:"flowfile" yaml:"flowfile"` + FullDescription string `json:"fullDescription" yaml:"fullDescription"` } func (e *Executable) SetContext(workspaceName, workspacePath, namespace, flowFilePath string) { @@ -93,12 +100,20 @@ func (e *Executable) SetInheritedFields(flowFile *FlowFile) { e.inheritedDescription = strings.Join([]string{flowFile.Description, descFromFIle}, "\n") } -func (e *Executable) YAML() (string, error) { - enriched := &enrichedExecutable{ - ID: e.ID(), - Spec: e, +func (e *Executable) enriched() *enrichedExecutable { + return &enrichedExecutable{ + Executable: e, + ID: e.ID(), + Ref: e.Ref().String(), + Namespace: e.Namespace(), + Workspace: e.Workspace(), + Flowfile: e.FlowFilePath(), + FullDescription: strings.TrimSpace(execDescriptionMarkdown(e, false)), } - yamlBytes, err := yaml.Marshal(enriched) +} + +func (e *Executable) YAML() (string, error) { + yamlBytes, err := yaml.Marshal(e.enriched()) if err != nil { return "", fmt.Errorf("failed to marshal executable - %w", err) } @@ -106,11 +121,7 @@ func (e *Executable) YAML() (string, error) { } func (e *Executable) JSON() (string, error) { - enriched := &enrichedExecutable{ - ID: e.ID(), - Spec: e, - } - jsonBytes, err := json.MarshalIndent(enriched, "", " ") + jsonBytes, err := json.MarshalIndent(e.enriched(), "", " ") if err != nil { return "", fmt.Errorf("failed to marshal executable - %w", err) } @@ -316,10 +327,7 @@ func (e *Executable) IsExecutableFromWorkspace(workspaceFilter string) bool { func (l ExecutableList) YAML() (string, error) { enriched := &enrichedExecutableList{} for _, exec := range l { - enriched.Executables = append(enriched.Executables, &enrichedExecutable{ - ID: exec.ID(), - Spec: exec, - }) + enriched.Executables = append(enriched.Executables, exec.enriched()) } yamlBytes, err := yaml.Marshal(enriched) if err != nil { @@ -331,10 +339,7 @@ func (l ExecutableList) YAML() (string, error) { func (l ExecutableList) JSON() (string, error) { enriched := &enrichedExecutableList{} for _, exec := range l { - enriched.Executables = append(enriched.Executables, &enrichedExecutable{ - ID: exec.ID(), - Spec: exec, - }) + enriched.Executables = append(enriched.Executables, exec.enriched()) } jsonBytes, err := json.MarshalIndent(enriched, "", " ") if err != nil { @@ -526,3 +531,73 @@ func NewExecutableID(workspace, namespace, name string) string { return "" } } + +func (e *Executable) MarshalJSON() ([]byte, error) { + type Alias Executable + aux := &struct { + *Alias + Timeout string `json:"timeout,omitempty"` + }{ + Alias: (*Alias)(e), + } + if e.Timeout != 0 { + aux.Timeout = e.Timeout.String() + } + return json.Marshal(aux) +} + +func (e *Executable) UnmarshalJSON(data []byte) error { + type Alias Executable + aux := &struct { + *Alias + Timeout string `json:"timeout,omitempty"` + }{ + Alias: (*Alias)(e), + } + if err := json.Unmarshal(data, &aux); err != nil { + return err + } + if aux.Timeout != "" { + duration, err := time.ParseDuration(aux.Timeout) + if err != nil { + return err + } + e.Timeout = duration + } + return nil +} + +func (r *RequestExecutableType) MarshalJSON() ([]byte, error) { + type Alias RequestExecutableType + aux := &struct { + *Alias + Timeout string `json:"timeout,omitempty"` + }{ + Alias: (*Alias)(r), + } + if r.Timeout != 0 { + aux.Timeout = r.Timeout.String() + } + return json.Marshal(aux) +} + +func (r *RequestExecutableType) UnmarshalJSON(data []byte) error { + type Alias RequestExecutableType + aux := &struct { + *Alias + Timeout string `json:"timeout,omitempty"` + }{ + Alias: (*Alias)(r), + } + if err := json.Unmarshal(data, &aux); err != nil { + return err + } + if aux.Timeout != "" { + duration, err := time.ParseDuration(aux.Timeout) + if err != nil { + return err + } + r.Timeout = duration + } + return nil +} diff --git a/types/executable/executable_md.go b/types/executable/executable_md.go index c117f6ef..9b7c9eb3 100644 --- a/types/executable/executable_md.go +++ b/types/executable/executable_md.go @@ -10,7 +10,7 @@ import ( func execMarkdown(e *Executable) string { var mkdwn string mkdwn += fmt.Sprintf("# [Executable] %s\n", e.Ref()) - mkdwn += execDescriptionMarkdown(e) + mkdwn += execDescriptionMarkdown(e, true) if e.Visibility != nil { mkdwn += fmt.Sprintf("**Visibility:** %s\n", *e.Visibility) } @@ -38,12 +38,16 @@ func execMarkdown(e *Executable) string { return mkdwn } -func execDescriptionMarkdown(e *Executable) string { +func execDescriptionMarkdown(e *Executable, withPrefix bool) string { if e.Description == "" && e.inheritedDescription == "" { return "" } var mkdwn string - const prefix = "│ " + + prefix := "" + if withPrefix { + prefix = "│ " + } if d := strings.TrimSpace(e.Description); d != "" { mkdwn += prefix + "\n" mkdwn += addPrefx(d, prefix) diff --git a/types/workspace/workspace.go b/types/workspace/workspace.go index bf2a7100..93c2f94a 100644 --- a/types/workspace/workspace.go +++ b/types/workspace/workspace.go @@ -3,6 +3,7 @@ package workspace import ( "encoding/json" "fmt" + "strings" "github.com/jahvon/tuikit/types" "gopkg.in/yaml.v3" @@ -15,8 +16,24 @@ import ( type WorkspaceList []*Workspace -type enrichedWorkspaceConfigList struct { - Workspaces WorkspaceList `json:"workspaces" yaml:"workspaces"` +type enrichedWorkspaceList struct { + Workspaces []*enrichedWorkspace `json:"workspaces" yaml:"workspaces"` +} + +type enrichedWorkspace struct { + *Workspace + Name string `json:"name" yaml:"name"` + Path string `json:"path" yaml:"path"` + FullDescription string `json:"fullDescription" yaml:"fullDescription"` +} + +func (w *Workspace) enriched() *enrichedWorkspace { + return &enrichedWorkspace{ + Workspace: w, + Name: w.AssignedName(), + Path: w.Location(), + FullDescription: strings.TrimSpace(workspaceDescription(w, false)), + } } func (w *Workspace) AssignedName() string { @@ -33,7 +50,7 @@ func (w *Workspace) SetContext(name, location string) { } func (w *Workspace) YAML() (string, error) { - yamlBytes, err := yaml.Marshal(w) + yamlBytes, err := yaml.Marshal(w.enriched()) if err != nil { return "", fmt.Errorf("failed to marshal workspace config - %w", err) } @@ -41,7 +58,7 @@ func (w *Workspace) YAML() (string, error) { } func (w *Workspace) JSON() (string, error) { - jsonBytes, err := json.MarshalIndent(w, "", " ") + jsonBytes, err := json.MarshalIndent(w.enriched(), "", " ") if err != nil { return "", fmt.Errorf("failed to marshal workspace config - %w", err) } @@ -57,7 +74,10 @@ func DefaultWorkspaceConfig(name string) *Workspace { } func (l WorkspaceList) YAML() (string, error) { - enriched := enrichedWorkspaceConfigList{Workspaces: l} + enriched := enrichedWorkspaceList{Workspaces: make([]*enrichedWorkspace, 0, len(l))} + for _, ws := range l { + enriched.Workspaces = append(enriched.Workspaces, ws.enriched()) + } yamlBytes, err := yaml.Marshal(enriched) if err != nil { return "", fmt.Errorf("failed to marshal workspace config list - %w", err) @@ -66,7 +86,10 @@ func (l WorkspaceList) YAML() (string, error) { } func (l WorkspaceList) JSON() (string, error) { - enriched := enrichedWorkspaceConfigList{Workspaces: l} + enriched := enrichedWorkspaceList{Workspaces: make([]*enrichedWorkspace, 0, len(l))} + for _, ws := range l { + enriched.Workspaces = append(enriched.Workspaces, ws.enriched()) + } jsonBytes, err := json.MarshalIndent(enriched, "", " ") if err != nil { return "", fmt.Errorf("failed to marshal workspace config list - %w", err) diff --git a/types/workspace/workspace_md.go b/types/workspace/workspace_md.go index c1547bc2..7375782a 100644 --- a/types/workspace/workspace_md.go +++ b/types/workspace/workspace_md.go @@ -14,7 +14,7 @@ func workspaceMarkdown(w *Workspace) string { } else { mkdwn = fmt.Sprintf("# [Workspace] %s\n", w.AssignedName()) } - mkdwn += workspaceDescription(w) + mkdwn += workspaceDescription(w, true) if len(w.Tags) > 0 { mkdwn += "**Tags**\n" for _, tag := range w.Tags { @@ -40,29 +40,42 @@ func workspaceMarkdown(w *Workspace) string { return mkdwn } -func workspaceDescription(w *Workspace) string { +func workspaceDescription(w *Workspace, withPrefix bool) string { + if w.Description == "" && w.DescriptionFile == "" { + return "" + } var mkdwn string - const descSpacer = "> \n" - if w.Description != "" { - mkdwn += descSpacer - lines := strings.Split(w.Description, "\n") - for _, line := range lines { - mkdwn += fmt.Sprintf("> %s\n", line) - } - mkdwn += descSpacer + + prefix := "" + if withPrefix { + prefix = "> " + } + if d := strings.TrimSpace(w.Description); d != "" { + mkdwn += prefix + "\n" + mkdwn += addPrefix(d, prefix) } if w.DescriptionFile != "" { - mdBytes, err := os.ReadFile(filepath.Clean(w.DescriptionFile)) + wsFile := filepath.Join(w.Location(), w.DescriptionFile) + mdBytes, err := os.ReadFile(filepath.Clean(wsFile)) if err != nil { - mkdwn += fmt.Sprintf("> **error rendering description file**: %s\n", err) - } else { - lines := strings.Split(string(mdBytes), "\n") - for _, line := range lines { - mkdwn += fmt.Sprintf("> %s\n", line) - } + mkdwn += addPrefix(fmt.Sprintf("**error rendering description file**: %s", err), prefix) + } else if d := strings.TrimSpace(string(mdBytes)); d != "" { + mkdwn += prefix + "\n" + mkdwn += addPrefix(d, prefix) } - mkdwn += descSpacer + } + if mkdwn != "" { + mkdwn += prefix + "\n" } mkdwn += "\n" return mkdwn } + +func addPrefix(s, prefix string) string { + lines := strings.Split(s, "\n") + var final string + for _, line := range lines { + final += prefix + line + "\n" + } + return final +}