Skip to content

Commit

Permalink
refactor: rewrite code using Go 1.23 iterators (#911)
Browse files Browse the repository at this point in the history
  • Loading branch information
favonia committed Aug 31, 2024
1 parent 11d9705 commit 319e6a0
Show file tree
Hide file tree
Showing 34 changed files with 727 additions and 818 deletions.
3 changes: 3 additions & 0 deletions .golangci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ linters-settings:
settings:
printf:
funcs:
- github.com/favonia/cloudflare-ddns/internal/message.NewMonitorMessagef
- github.com/favonia/cloudflare-ddns/internal/message.NewNotifierMessagef
- (github.com/favonia/cloudflare-ddns/internal/pp.PP).Infof
- (github.com/favonia/cloudflare-ddns/internal/pp.PP).Noticef
- (github.com/favonia/cloudflare-ddns/internal/pp.PP).Hintf
Expand Down Expand Up @@ -39,6 +41,7 @@ linters:
disable:
- execinquery # deprecated
- gomnd # deprecated
- exportloopref # deprecated

- cyclop # can detect complicated code, but never leads to actual code changes
- funlen # can detect complicated code, but never leads to actual code changes
Expand Down
30 changes: 15 additions & 15 deletions cmd/ddns/ddns.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,8 @@ func initConfig(ppfmt pp.PP) (*config.Config, setter.Setter, bool) {
func stopUpdating(ctx context.Context, ppfmt pp.PP, c *config.Config, s setter.Setter) {
if c.DeleteOnStop {
msg := updater.DeleteIPs(ctx, ppfmt, c, s)
monitor.LogMessageAll(ctx, ppfmt, c.Monitors, msg.MonitorMessage)
notifier.SendMessageAll(ctx, ppfmt, c.Notifiers, msg.NotifierMessage)
c.Monitor.Log(ctx, ppfmt, msg.MonitorMessage)
c.Notifier.Send(ctx, ppfmt, msg.NotifierMessage)
}
}

Expand Down Expand Up @@ -89,18 +89,18 @@ func realMain() int { //nolint:funlen
// Read the config and get the handler and the setter
c, s, configOK := initConfig(ppfmt)
// Ping monitors regardless of whether initConfig succeeded
monitor.StartAll(ctx, ppfmt, c.Monitors, formatName())
c.Monitor.Start(ctx, ppfmt, formatName())
// Bail out now if initConfig failed
if !configOK {
monitor.ExitStatusAll(ctx, ppfmt, c.Monitors, 1, "Configuration errors")
notifier.SendAll(ctx, ppfmt, c.Notifiers,
"Cloudflare DDNS was misconfigured and could not start. Please check the logging for details.")
c.Monitor.Ping(ctx, ppfmt, monitor.NewMessagef(false, "Configuration errors"))
c.Notifier.Send(ctx, ppfmt, notifier.NewMessagef(
"Cloudflare DDNS was misconfigured and could not start. Please check the logging for details."))
ppfmt.Infof(pp.EmojiBye, "Bye!")
return 1
}
// If UPDATE_CRON is not `@once` (not single-run mode), then send a notification to signal the start.
if c.UpdateCron != nil {
notifier.SendAll(ctx, ppfmt, c.Notifiers, "Started running Cloudflare DDNS.")
c.Notifier.Send(ctx, ppfmt, notifier.NewMessagef("Started running Cloudflare DDNS."))
}

// Without the following line, the quiet mode can be too quiet, and some system (Portainer)
Expand All @@ -122,11 +122,11 @@ func realMain() int { //nolint:funlen

// Update the IP addresses
if first && !c.UpdateOnStart {
monitor.SuccessAll(ctx, ppfmt, c.Monitors, "Started (no action)")
c.Monitor.Ping(ctx, ppfmt, monitor.NewMessagef(true, "Started (no action)"))
} else {
msg := updater.UpdateIPs(ctxWithSignals, ppfmt, c, s)
monitor.PingMessageAll(ctx, ppfmt, c.Monitors, msg.MonitorMessage)
notifier.SendMessageAll(ctx, ppfmt, c.Notifiers, msg.NotifierMessage)
c.Monitor.Ping(ctx, ppfmt, msg.MonitorMessage)
c.Notifier.Send(ctx, ppfmt, msg.NotifierMessage)
}

if ctxWithSignals.Err() != nil {
Expand All @@ -148,9 +148,9 @@ func realMain() int { //nolint:funlen
cron.DescribeSchedule(c.UpdateCron),
)
stopUpdating(ctx, ppfmt, c, s)
monitor.ExitStatusAll(ctx, ppfmt, c.Monitors, 1, "No scheduled updates")
notifier.SendAll(ctx, ppfmt, c.Notifiers,
fmt.Sprintf(
c.Monitor.Ping(ctx, ppfmt, monitor.NewMessagef(false, "No scheduled updates"))
c.Notifier.Send(ctx, ppfmt,
notifier.NewMessagef(
"Cloudflare DDNS stopped because there are no scheduled updates in near future. "+
"Consider changing the value of UPDATE_CRON (%s).",
cron.DescribeSchedule(c.UpdateCron),
Expand All @@ -167,9 +167,9 @@ func realMain() int { //nolint:funlen
// Wait for the next signal or the alarm, whichever comes first
if sig.WaitForSignalsUntil(ppfmt, next) {
stopUpdating(ctx, ppfmt, c, s)
monitor.ExitStatusAll(ctx, ppfmt, c.Monitors, 0, "Stopped")
c.Monitor.Exit(ctx, ppfmt, "Stopped")
if c.UpdateCron != nil {
notifier.SendAll(ctx, ppfmt, c.Notifiers, "Stopped running Cloudflare DDNS.")
c.Notifier.Send(ctx, ppfmt, notifier.NewMessagef("Stopped running Cloudflare DDNS."))
}
ppfmt.Infof(pp.EmojiBye, "Bye!")
return 0
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ require (
github.com/stretchr/testify v1.9.0
go.uber.org/mock v0.4.0
golang.org/x/net v0.28.0
golang.org/x/text v0.17.0
)

require (
Expand All @@ -24,7 +25,6 @@ require (
github.com/pmezard/go-difflib v1.0.0 // indirect
golang.org/x/sync v0.8.0 // indirect
golang.org/x/sys v0.23.0 // indirect
golang.org/x/text v0.17.0 // indirect
golang.org/x/time v0.5.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
8 changes: 4 additions & 4 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ type Config struct {
WAFListDescription string
DetectionTimeout time.Duration
UpdateTimeout time.Duration
Monitors []monitor.Monitor
Notifiers []notifier.Notifier
Monitor monitor.Monitor
Notifier notifier.Notifier
}

// Default gives the default configuration.
Expand All @@ -59,7 +59,7 @@ func Default() *Config {
WAFListDescription: "",
DetectionTimeout: time.Second * 5, //nolint:mnd
UpdateTimeout: time.Second * 30, //nolint:mnd
Monitors: nil,
Notifiers: nil,
Monitor: nil,
Notifier: nil,
}
}
18 changes: 8 additions & 10 deletions internal/config/config_print.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ import (
"github.com/favonia/cloudflare-ddns/internal/cron"
"github.com/favonia/cloudflare-ddns/internal/domain"
"github.com/favonia/cloudflare-ddns/internal/ipnet"
"github.com/favonia/cloudflare-ddns/internal/monitor"
"github.com/favonia/cloudflare-ddns/internal/notifier"
"github.com/favonia/cloudflare-ddns/internal/pp"
"github.com/favonia/cloudflare-ddns/internal/provider"
)
Expand Down Expand Up @@ -88,17 +86,17 @@ func (c *Config) Print(ppfmt pp.PP) {
item("IP detection:", "%v", c.DetectionTimeout)
item("Record/list updating:", "%v", c.UpdateTimeout)

if len(c.Monitors) > 0 {
if c.Monitor != nil {
section("Monitors:")
monitor.DescribeAll(func(service, params string) {
item(service+":", "%s", params)
}, c.Monitors)
for name, params := range c.Monitor.Describe {
item(name+":", "%s", params)
}
}

if len(c.Notifiers) > 0 {
if c.Notifier != nil {
section("Notification services (via shoutrrr):")
notifier.DescribeAll(func(service, params string) {
item(service+":", "%s", params)
}, c.Notifiers)
for name, params := range c.Notifier.Describe {
item(name+":", "%s", params)
}
}
}
10 changes: 4 additions & 6 deletions internal/config/config_print_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ import (
"github.com/favonia/cloudflare-ddns/internal/domain"
"github.com/favonia/cloudflare-ddns/internal/ipnet"
"github.com/favonia/cloudflare-ddns/internal/mocks"
"github.com/favonia/cloudflare-ddns/internal/monitor"
"github.com/favonia/cloudflare-ddns/internal/notifier"
"github.com/favonia/cloudflare-ddns/internal/pp"
)

Expand Down Expand Up @@ -114,17 +112,17 @@ func TestPrintValues(t *testing.T) {

m := mocks.NewMockMonitor(mockCtrl)
m.EXPECT().Describe(gomock.Any()).
DoAndReturn(func(f func(string, string)) {
DoAndReturn(func(f func(string, string) bool) {
f("Meow", "purrrr")
}).AnyTimes()
c.Monitors = []monitor.Monitor{m}
c.Monitor = m

n := mocks.NewMockNotifier(mockCtrl)
n.EXPECT().Describe(gomock.Any()).
DoAndReturn(func(f func(string, string)) {
DoAndReturn(func(f func(string, string) bool) {
f("Snake", "hissss")
}).AnyTimes()
c.Notifiers = []notifier.Notifier{n}
c.Notifier = n

c.Print(mockPP)
}
Expand Down
6 changes: 3 additions & 3 deletions internal/config/config_read.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@ func (c *Config) ReadEnv(ppfmt pp.PP) bool {
!ReadString(ppfmt, "WAF_LIST_DESCRIPTION", &c.WAFListDescription) ||
!ReadNonnegDuration(ppfmt, "DETECTION_TIMEOUT", &c.DetectionTimeout) ||
!ReadNonnegDuration(ppfmt, "UPDATE_TIMEOUT", &c.UpdateTimeout) ||
!ReadAndAppendHealthchecksURL(ppfmt, "HEALTHCHECKS", &c.Monitors) ||
!ReadAndAppendUptimeKumaURL(ppfmt, "UPTIMEKUMA", &c.Monitors) ||
!ReadAndAppendShoutrrrURL(ppfmt, "SHOUTRRR", &c.Notifiers) {
!ReadAndAppendHealthchecksURL(ppfmt, "HEALTHCHECKS", &c.Monitor) ||
!ReadAndAppendUptimeKumaURL(ppfmt, "UPTIMEKUMA", &c.Monitor) ||
!ReadAndAppendShoutrrrURL(ppfmt, "SHOUTRRR", &c.Notifier) {
return false
}

Expand Down
8 changes: 4 additions & 4 deletions internal/config/env_monitor.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (
)

// ReadAndAppendHealthchecksURL reads the base URL of a Healthchecks endpoint.
func ReadAndAppendHealthchecksURL(ppfmt pp.PP, key string, field *[]monitor.Monitor) bool {
func ReadAndAppendHealthchecksURL(ppfmt pp.PP, key string, field *monitor.Monitor) bool {
val := Getenv(key)

if val == "" {
Expand All @@ -19,12 +19,12 @@ func ReadAndAppendHealthchecksURL(ppfmt pp.PP, key string, field *[]monitor.Moni
}

// Append the new monitor to the existing list
*field = append(*field, h)
*field = monitor.NewComposed(*field, h)
return true
}

// ReadAndAppendUptimeKumaURL reads the URL of a Push Monitor of an Uptime Kuma server.
func ReadAndAppendUptimeKumaURL(ppfmt pp.PP, key string, field *[]monitor.Monitor) bool {
func ReadAndAppendUptimeKumaURL(ppfmt pp.PP, key string, field *monitor.Monitor) bool {
val := Getenv(key)

if val == "" {
Expand All @@ -37,6 +37,6 @@ func ReadAndAppendUptimeKumaURL(ppfmt pp.PP, key string, field *[]monitor.Monito
}

// Append the new monitor to the existing list
*field = append(*field, h)
*field = monitor.NewComposed(*field, h)
return true
}
36 changes: 18 additions & 18 deletions internal/config/env_monitor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ func TestReadAndAppendHealthchecksURL(t *testing.T) {
for name, tc := range map[string]struct {
set bool
val string
oldField []mon
newField []mon
oldField mon
newField mon
ok bool
prepareMockPP func(*mocks.MockPP)
}{
Expand All @@ -35,30 +35,30 @@ func TestReadAndAppendHealthchecksURL(t *testing.T) {
"example": {
true, "https://hi.org/1234",
nil,
[]mon{monitor.Healthchecks{
monitor.NewComposed(monitor.Healthchecks{
BaseURL: urlMustParse(t, "https://hi.org/1234"),
Timeout: monitor.HealthchecksDefaultTimeout,
}},
}),
true,
nil,
},
"password": {
true, "https://me:pass@hi.org/1234",
nil,
[]mon{monitor.Healthchecks{
monitor.NewComposed(monitor.Healthchecks{
BaseURL: urlMustParse(t, "https://me:pass@hi.org/1234"),
Timeout: monitor.HealthchecksDefaultTimeout,
}},
}),
true,
nil,
},
"fragment": {
true, "https://hi.org/1234#fragment",
nil,
[]mon{monitor.Healthchecks{
monitor.NewComposed(monitor.Healthchecks{
BaseURL: urlMustParse(t, "https://hi.org/1234#fragment"),
Timeout: monitor.HealthchecksDefaultTimeout,
}},
}),
true,
nil,
},
Expand Down Expand Up @@ -118,8 +118,8 @@ func TestReadAndAppendUptimeKumaURL(t *testing.T) {
for name, tc := range map[string]struct {
set bool
val string
oldField []mon
newField []mon
oldField mon
newField mon
ok bool
prepareMockPP func(*mocks.MockPP)
}{
Expand All @@ -132,40 +132,40 @@ func TestReadAndAppendUptimeKumaURL(t *testing.T) {
"example": {
true, "https://hi.org/1234",
nil,
[]mon{monitor.UptimeKuma{
monitor.NewComposed(monitor.UptimeKuma{
BaseURL: urlMustParse(t, "https://hi.org/1234"),
Timeout: monitor.UptimeKumaDefaultTimeout,
}},
}),
true,
nil,
},
"password": {
true, "https://me:pass@hi.org/1234",
nil,
[]mon{monitor.UptimeKuma{
monitor.NewComposed(monitor.UptimeKuma{
BaseURL: urlMustParse(t, "https://me:pass@hi.org/1234"),
Timeout: monitor.UptimeKumaDefaultTimeout,
}},
}),
true,
nil,
},
"fragment": {
true, "https://hi.org/1234#fragment",
nil,
[]mon{monitor.UptimeKuma{
monitor.NewComposed(monitor.UptimeKuma{
BaseURL: urlMustParse(t, "https://hi.org/1234#fragment"),
Timeout: monitor.UptimeKumaDefaultTimeout,
}},
}),
true,
nil,
},
"query": {
true, "https://hi.org/1234?hello=123",
nil,
[]mon{monitor.UptimeKuma{
monitor.NewComposed(monitor.UptimeKuma{
BaseURL: urlMustParse(t, "https://hi.org/1234"),
Timeout: monitor.UptimeKumaDefaultTimeout,
}},
}),
true,
func(m *mocks.MockPP) {
m.EXPECT().Noticef(pp.EmojiUserError,
Expand Down
4 changes: 2 additions & 2 deletions internal/config/env_notifier.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (
)

// ReadAndAppendShoutrrrURL reads the URLs separated by the newline.
func ReadAndAppendShoutrrrURL(ppfmt pp.PP, key string, field *[]notifier.Notifier) bool {
func ReadAndAppendShoutrrrURL(ppfmt pp.PP, key string, field *notifier.Notifier) bool {
vals := GetenvAsList(key, "\n")
if len(vals) == 0 {
return true
Expand All @@ -18,6 +18,6 @@ func ReadAndAppendShoutrrrURL(ppfmt pp.PP, key string, field *[]notifier.Notifie
}

// Append the new monitor to the existing list
*field = append(*field, s)
*field = s
return true
}
Loading

0 comments on commit 319e6a0

Please sign in to comment.