aboutsummaryrefslogtreecommitdiff
path: root/main.go
blob: b238ff0672069bf9443d11d2ddb96412ec48e5a8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
package main

import (
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"os"

	"gopkg.in/yaml.v3"
)

var cfg = flag.String("f", "config.yml", "configuration file")

type ConfigMap map[string]interface{}

type configFeed struct {
	Name      string
	Url       string
	MinFreq   int `yaml:"min-frequency"`
	ConfigMap `yaml:",inline"`
}

type configGroup struct {
	Group string
	Feeds []configGroupFeed
}

type configGroupFeed struct {
	Target      *string
	configFeed  `yaml:",inline"`
	configGroup `yaml:",inline"`
}

func (grpFeed *configGroupFeed) isGroup() bool {
	return grpFeed.configGroup.Group != ""
}

func (grpFeed *configGroupFeed) isFeed() bool {
	return grpFeed.configFeed.Name != ""
}

func (grpFeed *configGroupFeed) target() string {
	if grpFeed.Target != nil {
		return *grpFeed.Target
	}
	if grpFeed.Name != "" {
		return grpFeed.Name
	}

	return grpFeed.Group
}

type config struct {
	GlobalConfig ConfigMap `yaml:",inline"`
	Feeds        []configGroupFeed
}

type feed struct {
	name    string
	target  string
	url     string
	minFreq int
	config  ConfigMap
}

var feeds = make(map[string]*feed)

func appTarget(target, app string) string {
	if target == "" {
		return app
	}

	if app == "" {
		return target
	}

	return target + "/" + app
}

func buildFeeds(cfg []configGroupFeed, target string) error {
	for _, f := range cfg {
		target := appTarget(target, f.target())
		switch {
		case f.isFeed() && f.isGroup():
			return fmt.Errorf("Entry with Target %s is both a feed and a group", target)
		case f.isFeed():
			name := f.Name
			if _, ok := feeds[name]; !ok {
				return fmt.Errorf("Duplicate feed name '%s'", name)
			}
			feeds[name] = &feed{
				name:    name,
				target:  target,
				url:     f.Url,
				minFreq: f.MinFreq,
				config:  f.ConfigMap,
			}
		case f.isGroup():
			if err := buildFeeds(f.Feeds, target); err != nil {
				return err
			}
		}
	}

	return nil
}

func run() error {
	log.Print("Starting up...")
	flag.Parse()

	log.Printf("Reading configuration file '%s'", *cfg)
	buf, err := ioutil.ReadFile(*cfg)
	if err != nil {
		return fmt.Errorf("while reading '%s': %w", *cfg, err)
	}

	var parsedCfg config
	if err := yaml.Unmarshal(buf, &parsedCfg); err != nil {
		return fmt.Errorf("while unmarshalling: %w", err)
	}
	fmt.Printf("--- parsedCfg:\n%+v\n\n", parsedCfg)

	if err := buildFeeds(parsedCfg.Feeds, ""); err != nil {
		return fmt.Errorf("while parsing: %w", err)
	}

	return nil
}

func main() {
	if err := run(); err != nil {
		log.SetOutput(os.Stderr)
		log.Print("Error: ", err)
		os.Exit(1)
	}
}