Skip to content

Commit 7980d8d

Browse files
committed
(feature): Add support for changing output format
supporting both Markdown and JSON output formats. Signed-off-by: everettraven <everettraven@gmail.com>
1 parent 4c77772 commit 7980d8d

4 files changed

Lines changed: 98 additions & 13 deletions

File tree

pkg/cmd/root.go

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66

77
"github.com/everettraven/synkr/pkg/builtins"
88
"github.com/everettraven/synkr/pkg/engine"
9+
"github.com/everettraven/synkr/pkg/printers"
910
"github.com/spf13/cobra"
1011
"go.starlark.net/starlark"
1112
"go.starlark.net/syntax"
@@ -14,31 +15,42 @@ import (
1415
func NewSynkrCommand() *cobra.Command {
1516
eng := &engine.Engine{}
1617
var configFile string
18+
var outputFormat string
1719

1820
cmd := &cobra.Command{
19-
Use: "synkr [-c configFile]",
21+
Use: "synkr",
2022
Short: "synkr is an engine for syncing work items based on a Starlark configuration",
2123
Args: cobra.ExactArgs(0),
2224
RunE: func(cmd *cobra.Command, args []string) error {
23-
return run(cmd.Context(), eng, configFile)
25+
return run(cmd.Context(), eng, configFile, outputFormat)
2426
},
2527
}
2628

2729
cmd.Flags().StringVarP(&configFile, "config", "c", "synkr.star", "configures the Starlark file to be processed for configuration")
30+
cmd.Flags().StringVarP(&outputFormat, "output", "o", "markdown", "configures the output format. Allowed values are [markdown, json]")
2831

2932
return cmd
3033
}
3134

32-
func run(ctx context.Context, eng *engine.Engine, configFile string) error {
33-
thread, err := configureEngine(eng, configFile)
35+
func run(ctx context.Context, eng *engine.Engine, configFile, output string) error {
36+
thread, err := configureEngine(eng, configFile, output)
3437
if err != nil {
3538
return fmt.Errorf("configuring engine: %w", err)
3639
}
3740

3841
return eng.Run(ctx, thread)
3942
}
4043

41-
func configureEngine(eng *engine.Engine, configFile string) (*starlark.Thread, error) {
44+
func configureEngine(eng *engine.Engine, configFile, output string) (*starlark.Thread, error) {
45+
switch output {
46+
case "markdown":
47+
eng.SetPrinter(&printers.Markdown{})
48+
case "json":
49+
eng.SetPrinter(&printers.JSON{})
50+
default:
51+
return nil, fmt.Errorf("unknown output format %q", output)
52+
}
53+
4254
globals := starlark.StringDict{}
4355

4456
builtins.Github(globals, eng)

pkg/engine/engine.go

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package engine
22

33
import (
44
"context"
5-
"encoding/json"
65
"fmt"
76
"strings"
87

@@ -11,6 +10,7 @@ import (
1110

1211
type Engine struct {
1312
sources []Source
13+
printer Printer
1414
}
1515

1616
type Source interface {
@@ -19,21 +19,25 @@ type Source interface {
1919
Project() string
2020
}
2121

22-
type output struct {
22+
type Printer interface {
23+
Print(SourceResult) (string, error)
24+
}
25+
26+
type SourceResult struct {
2327
Source string `json:"source"`
2428
Project string `json:"project"`
2529
Items []any `json:"items"`
2630
}
2731

2832
func (e *Engine) Run(ctx context.Context, thread *starlark.Thread) error {
29-
outputs := []output{}
33+
outputs := []SourceResult{}
3034
for _, source := range e.sources {
3135
items, err := source.Fetch(ctx, thread)
3236
if err != nil {
3337
return err
3438
}
3539

36-
outputs = append(outputs, output{
40+
outputs = append(outputs, SourceResult{
3741
Source: source.Name(),
3842
Project: source.Project(),
3943
Items: items,
@@ -42,12 +46,11 @@ func (e *Engine) Run(ctx context.Context, thread *starlark.Thread) error {
4246

4347
outs := []string{}
4448
for _, output := range outputs {
45-
outBytes, err := json.Marshal(output)
49+
out, err := e.printer.Print(output)
4650
if err != nil {
47-
return fmt.Errorf("marshalling output %v to json: %w", output, err)
51+
return fmt.Errorf("printing source result %v: %w", output, err)
4852
}
49-
50-
outs = append(outs, string(outBytes))
53+
outs = append(outs, out)
5154
}
5255

5356
fmt.Print(strings.Join(outs, "\n"))
@@ -57,3 +60,7 @@ func (e *Engine) Run(ctx context.Context, thread *starlark.Thread) error {
5760
func (e *Engine) AddSource(source Source) {
5861
e.sources = append(e.sources, source)
5962
}
63+
64+
func (e *Engine) SetPrinter(printer Printer) {
65+
e.printer = printer
66+
}

pkg/printers/json.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package printers
2+
3+
import (
4+
"encoding/json"
5+
6+
"github.com/everettraven/synkr/pkg/engine"
7+
)
8+
9+
type JSON struct{}
10+
11+
func (j *JSON) Print(result engine.SourceResult) (string, error) {
12+
outBytes, err := json.Marshal(result)
13+
if err != nil {
14+
return "", err
15+
}
16+
17+
return string(outBytes), nil
18+
}

pkg/printers/markdown.go

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package printers
2+
3+
import (
4+
"fmt"
5+
"strings"
6+
7+
"github.com/everettraven/synkr/pkg/engine"
8+
"github.com/everettraven/synkr/pkg/sources/github"
9+
)
10+
11+
type Markdown struct{}
12+
13+
func (md *Markdown) Print(result engine.SourceResult) (string, error) {
14+
var out strings.Builder
15+
out.WriteString(fmt.Sprintf("# %s - %s\n", result.Source, result.Project))
16+
17+
for _, item := range result.Items {
18+
switch item := item.(type) {
19+
case github.RepoItem:
20+
out.WriteString(md.PrintGitHubRepoItem(item))
21+
default:
22+
out.WriteString(fmt.Sprintf("%v", item))
23+
}
24+
25+
out.WriteString("\n")
26+
}
27+
28+
return out.String(), nil
29+
}
30+
31+
func (md *Markdown) PrintGitHubRepoItem(item github.RepoItem) string {
32+
var out strings.Builder
33+
34+
out.WriteString(fmt.Sprintf("## [%s][%s]: %s \n", item.Type, item.State, item.Title))
35+
out.WriteString(fmt.Sprintf("**URL**: %s\n", item.URL))
36+
out.WriteString(fmt.Sprintf("**Author**: *%s*\n", item.Author))
37+
out.WriteString(fmt.Sprintf("**Assignees**: %s\n", strings.Join(item.Assignees, ",")))
38+
39+
out.WriteString("\n")
40+
labelStrs := []string{}
41+
for _, label := range item.Labels {
42+
labelStrs = append(labelStrs, fmt.Sprintf("`%s`", label))
43+
}
44+
out.WriteString(fmt.Sprintf("%s\n\n", strings.Join(labelStrs, " ")))
45+
out.WriteString(fmt.Sprintf("%s\n", item.Body))
46+
47+
return out.String()
48+
}

0 commit comments

Comments
 (0)