Repository: favonia/cloudflare-ddns
Pull request #787 (2024-07-07 07:00:20)

refactor(pp): various tweaks to logging
Changes extracted from the PR #785.

codecov[bot]: ## [Codecov](https://app.codecov.io/gh/favonia/cloudflare-ddns/pull/787?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=favonia) Report
All modified and coverable lines are covered by tests :white_check_mark:
> Project coverage is 90.46%. Comparing base [(`d724a60`)](https://app.codecov.io/gh/favonia/cloudflare-ddns/commit/d724a60fd0b1866bfb0920feab4446f831605ac3?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=favonia) to head [(`49d65ea`)](https://app.codecov.io/gh/favonia/cloudflare-ddns/commit/49d65ead725a02e513b3bca2b57563b29564c97a?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=favonia).

<details><summary>Additional details and impacted files</summary>


```diff
@@            Coverage Diff             @@
##             main     #787      +/-   ##
==========================================
- Coverage   90.48%   90.46%   -0.02%     
==========================================
  Files          52       52              
  Lines        2196     2193       -3     
==========================================
- Hits         1987     1984       -3     
  Misses        198      198              
  Partials       11       11              
```

| [Flag](https://app.codecov.io/gh/favonia/cloudflare-ddns/pull/787/flags?src=pr&el=flags&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=favonia) | Coverage Δ | |
|---|---|---|
| [unittests](https://app.codecov.io/gh/favonia/cloudflare-ddns/pull/787/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=favonia) | `90.46% <100.00%> (-0.02%)` | :arrow_down: |

Flags with carried forward coverage won't be shown. [Click here](https://docs.codecov.io/docs/carryforward-flags?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=favonia#carryforward-flags-in-the-pull-request-comment) to find out more.

</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/favonia/cloudflare-ddns/pull/787?dropdown=coverage&src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=favonia).   
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=favonia).


Patch:
diff --git a/internal/config/config_print.go b/internal/config/config_print.go
index 7a8012d..0b66222 100644
--- a/internal/config/config_print.go
+++ b/internal/config/config_print.go
@@ -85,7 +85,7 @@ func (c *Config) Print(ppfmt pp.PP) {
 	item("Delete on stop?", "%t", c.DeleteOnStop)
 	item("Cache expiration:", "%v", c.CacheExpiration)
 
-	section("New DNS records:")
+	section("Parameters of new DNS records:")
 	item("TTL:", "%s", c.TTL.Describe())
 	{
 		_, inverseMap := getInverseMap(c.Proxied)
@@ -106,7 +106,7 @@ func (c *Config) Print(ppfmt pp.PP) {
 	}
 
 	if len(c.Notifiers) > 0 {
-		section("Notifiers (via shoutrrr):")
+		section("Notification services (via shoutrrr):")
 		notifier.DescribeAll(func(service, params string) {
 			item(service+":", "%s", params)
 		}, c.Notifiers)
diff --git a/internal/config/env_base.go b/internal/config/env_base.go
index 1a57614..970ee60 100644
--- a/internal/config/env_base.go
+++ b/internal/config/env_base.go
@@ -73,9 +73,9 @@ func ReadQuiet(key string, ppfmt *pp.PP) bool {
 	}
 
 	if quiet {
-		*ppfmt = (*ppfmt).SetLevel(pp.Quiet)
+		*ppfmt = (*ppfmt).SetVerbosity(pp.Quiet)
 	} else {
-		*ppfmt = (*ppfmt).SetLevel(pp.Verbose)
+		*ppfmt = (*ppfmt).SetVerbosity(pp.Verbose)
 	}
 
 	return true
diff --git a/internal/mocks/mock_pp.go b/internal/mocks/mock_pp.go
index 51695a2..14e8e19 100644
--- a/internal/mocks/mock_pp.go
+++ b/internal/mocks/mock_pp.go
@@ -159,7 +159,7 @@ func (c *PPInfofCall) DoAndReturn(f func(pp.Emoji, string, ...any)) *PPInfofCall
 }
 
 // IsEnabledFor mocks base method.
-func (m *MockPP) IsEnabledFor(arg0 pp.Level) bool {
+func (m *MockPP) IsEnabledFor(arg0 pp.Verbosity) bool {
 	m.ctrl.T.Helper()
 	ret := m.ctrl.Call(m, "IsEnabledFor", arg0)
 	ret0, _ := ret[0].(bool)
@@ -185,13 +185,13 @@ func (c *PPIsEnabledForCall) Return(arg0 bool) *PPIsEnabledForCall {
 }
 
 // Do rewrite *gomock.Call.Do
-func (c *PPIsEnabledForCall) Do(f func(pp.Level) bool) *PPIsEnabledForCall {
+func (c *PPIsEnabledForCall) Do(f func(pp.Verbosity) bool) *PPIsEnabledForCall {
 	c.Call = c.Call.Do(f)
 	return c
 }
 
 // DoAndReturn rewrite *gomock.Call.DoAndReturn
-func (c *PPIsEnabledForCall) DoAndReturn(f func(pp.Level) bool) *PPIsEnabledForCall {
+func (c *PPIsEnabledForCall) DoAndReturn(f func(pp.Verbosity) bool) *PPIsEnabledForCall {
 	c.Call = c.Call.DoAndReturn(f)
 	return c
 }
@@ -275,40 +275,40 @@ func (c *PPSetEmojiCall) DoAndReturn(f func(bool) pp.PP) *PPSetEmojiCall {
 	return c
 }
 
-// SetLevel mocks base method.
-func (m *MockPP) SetLevel(arg0 pp.Level) pp.PP {
+// SetVerbosity mocks base method.
+func (m *MockPP) SetVerbosity(arg0 pp.Verbosity) pp.PP {
 	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "SetLevel", arg0)
+	ret := m.ctrl.Call(m, "SetVerbosity", arg0)
 	ret0, _ := ret[0].(pp.PP)
 	return ret0
 }
 
-// SetLevel indicates an expected call of SetLevel.
-func (mr *MockPPMockRecorder) SetLevel(arg0 any) *PPSetLevelCall {
+// SetVerbosity indicates an expected call of SetVerbosity.
+func (mr *MockPPMockRecorder) SetVerbosity(arg0 any) *PPSetVerbosityCall {
 	mr.mock.ctrl.T.Helper()
-	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetLevel", reflect.TypeOf((*MockPP)(nil).SetLevel), arg0)
-	return &PPSetLevelCall{Call: call}
+	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetVerbosity", reflect.TypeOf((*MockPP)(nil).SetVerbosity), arg0)
+	return &PPSetVerbosityCall{Call: call}
 }
 
-// PPSetLevelCall wrap *gomock.Call
-type PPSetLevelCall struct {
+// PPSetVerbosityCall wrap *gomock.Call
+type PPSetVerbosityCall struct {
 	*gomock.Call
 }
 
 // Return rewrite *gomock.Call.Return
-func (c *PPSetLevelCall) Return(arg0 pp.PP) *PPSetLevelCall {
+func (c *PPSetVerbosityCall) Return(arg0 pp.PP) *PPSetVerbosityCall {
 	c.Call = c.Call.Return(arg0)
 	return c
 }
 
 // Do rewrite *gomock.Call.Do
-func (c *PPSetLevelCall) Do(f func(pp.Level) pp.PP) *PPSetLevelCall {
+func (c *PPSetVerbosityCall) Do(f func(pp.Verbosity) pp.PP) *PPSetVerbosityCall {
 	c.Call = c.Call.Do(f)
 	return c
 }
 
 // DoAndReturn rewrite *gomock.Call.DoAndReturn
-func (c *PPSetLevelCall) DoAndReturn(f func(pp.Level) pp.PP) *PPSetLevelCall {
+func (c *PPSetVerbosityCall) DoAndReturn(f func(pp.Verbosity) pp.PP) *PPSetVerbosityCall {
 	c.Call = c.Call.DoAndReturn(f)
 	return c
 }
diff --git a/internal/pp/base.go b/internal/pp/base.go
index 84b160b..d74873f 100644
--- a/internal/pp/base.go
+++ b/internal/pp/base.go
@@ -8,11 +8,11 @@ type PP interface {
 	// SetEmoji sets whether emojis should be used.
 	SetEmoji(emoji bool) PP
 
-	// SetLevel sets the level under which messages will be hidden.
-	SetLevel(level Level) PP
+	// SetVerbosity sets the level under which messages will be hidden.
+	SetVerbosity(v Verbosity) PP
 
 	// IsEnabledFor checks whether a message of a certain level will be displayed.
-	IsEnabledFor(level Level) bool
+	IsEnabledFor(v Verbosity) bool
 
 	// IncIndent returns a new pretty-printer with more indentation.
 	IncIndent() PP
diff --git a/internal/pp/fmt.go b/internal/pp/fmt.go
index 153297f..4b95709 100644
--- a/internal/pp/fmt.go
+++ b/internal/pp/fmt.go
@@ -7,46 +7,43 @@ import (
 )
 
 type formatter struct {
-	writer io.Writer
-	emoji  bool
-	indent int
-	level  Level
+	writer    io.Writer
+	emoji     bool
+	indent    int
+	verbosity Verbosity
 }
 
 // New creates a new pretty printer.
 func New(writer io.Writer) PP {
-	return &formatter{
-		writer: writer,
-		emoji:  true,
-		indent: 0,
-		level:  DefaultLevel,
+	return formatter{
+		writer:    writer,
+		emoji:     true,
+		indent:    0,
+		verbosity: DefaultVerbosity,
 	}
 }
 
-func (f *formatter) SetEmoji(emoji bool) PP {
-	fmt := *f
-	fmt.emoji = emoji
-	return &fmt
+func (f formatter) SetEmoji(emoji bool) PP {
+	f.emoji = emoji
+	return f
 }
 
-func (f *formatter) SetLevel(lvl Level) PP {
-	fmt := *f
-	fmt.level = lvl
-	return &fmt
+func (f formatter) SetVerbosity(v Verbosity) PP {
+	f.verbosity = v
+	return f
 }
 
-func (f *formatter) IsEnabledFor(lvl Level) bool {
-	return lvl >= f.level
+func (f formatter) IsEnabledFor(v Verbosity) bool {
+	return v >= f.verbosity
 }
 
-func (f *formatter) IncIndent() PP {
-	fmt := *f
-	fmt.indent++
-	return &fmt
+func (f formatter) IncIndent() PP {
+	f.indent++
+	return f
 }
 
-func (f *formatter) output(lvl Level, emoji Emoji, msg string) {
-	if lvl < f.level {
+func (f formatter) output(v Verbosity, emoji Emoji, msg string) {
+	if v < f.verbosity {
 		return
 	}
 
@@ -65,22 +62,22 @@ func (f *formatter) output(lvl Level, emoji Emoji, msg string) {
 	fmt.Fprintln(f.writer, line)
 }
 
-func (f *formatter) printf(lvl Level, emoji Emoji, format string, args ...any) {
-	f.output(lvl, emoji, fmt.Sprintf(format, args...))
+func (f formatter) printf(v Verbosity, emoji Emoji, format string, args ...any) {
+	f.output(v, emoji, fmt.Sprintf(format, args...))
 }
 
-func (f *formatter) Infof(emoji Emoji, format string, args ...any) {
+func (f formatter) Infof(emoji Emoji, format string, args ...any) {
 	f.printf(Info, emoji, format, args...)
 }
 
-func (f *formatter) Noticef(emoji Emoji, format string, args ...any) {
+func (f formatter) Noticef(emoji Emoji, format string, args ...any) {
 	f.printf(Notice, emoji, format, args...)
 }
 
-func (f *formatter) Warningf(emoji Emoji, format string, args ...any) {
+func (f formatter) Warningf(emoji Emoji, format string, args ...any) {
 	f.printf(Warning, emoji, format, args...)
 }
 
-func (f *formatter) Errorf(emoji Emoji, format string, args ...any) {
+func (f formatter) Errorf(emoji Emoji, format string, args ...any) {
 	f.printf(Error, emoji, format, args...)
 }
diff --git a/internal/pp/level.go b/internal/pp/level.go
deleted file mode 100644
index c9baa6d..0000000
--- a/internal/pp/level.go
+++ /dev/null
@@ -1,15 +0,0 @@
-package pp
-
-// Level is the type of message levels.
-type Level int
-
-const (
-	Debug        Level = iota // debugging info, currently not used
-	Info                      // additional information that is not an action, a warning, or an error
-	Notice                    // an action (e.g., changing the IP) has happened and it is not an error
-	Warning                   // non-fatal errors where the updater should continue updating IP addresses
-	Error                     // fatal errors where the updater should stop
-	DefaultLevel = Info
-	Verbose      = Info
-	Quiet        = Notice
-)
diff --git a/internal/pp/verbosity.go b/internal/pp/verbosity.go
new file mode 100644
index 0000000..d8a997b
--- /dev/null
+++ b/internal/pp/verbosity.go
@@ -0,0 +1,15 @@
+package pp
+
+// Level is the type of message levels.
+type Verbosity int
+
+const (
+	Debug            Verbosity = iota // debugging info, currently not used
+	Info                              // additional information that is not an action, a warning, or an error
+	Notice                            // an action (e.g., changing the IP) has happened and it is not an error
+	Warning                           // non-fatal errors where the updater should continue updating IP addresses
+	Error                             // fatal errors where the updater should stop
+	DefaultVerbosity Verbosity = Info
+	Verbose          Verbosity = Info
+	Quiet            Verbosity = Notice
+)


Test patch:
diff --git a/internal/config/config_print_test.go b/internal/config/config_print_test.go
index 4aac287..ad15607 100644
--- a/internal/config/config_print_test.go
+++ b/internal/config/config_print_test.go
@@ -42,7 +42,7 @@ func TestPrintDefault(t *testing.T) {
 		printItem(innerMockPP, "Update on start?", "true"),
 		printItem(innerMockPP, "Delete on stop?", "false"),
 		printItem(innerMockPP, "Cache expiration:", "6h0m0s"),
-		mockPP.EXPECT().Infof(pp.EmojiConfig, "New DNS records:"),
+		mockPP.EXPECT().Infof(pp.EmojiConfig, "Parameters of new DNS records:"),
 		printItem(innerMockPP, "TTL:", "1 (auto)"),
 		printItem(innerMockPP, "Proxied domains:", "(none)"),
 		printItem(innerMockPP, "Unproxied domains:", "(none)"),
@@ -78,7 +78,7 @@ func TestPrintValues(t *testing.T) {
 		printItem(innerMockPP, "Update on start?", "true"),
 		printItem(innerMockPP, "Delete on stop?", "false"),
 		printItem(innerMockPP, "Cache expiration:", "6h0m0s"),
-		mockPP.EXPECT().Infof(pp.EmojiConfig, "New DNS records:"),
+		mockPP.EXPECT().Infof(pp.EmojiConfig, "Parameters of new DNS records:"),
 		printItem(innerMockPP, "TTL:", "30000"),
 		printItem(innerMockPP, "Proxied domains:", "a, b"),
 		printItem(innerMockPP, "Unproxied domains:", "c, d"),
@@ -88,7 +88,7 @@ func TestPrintValues(t *testing.T) {
 		printItem(innerMockPP, "Record updating:", "30s"),
 		mockPP.EXPECT().Infof(pp.EmojiConfig, "Monitors:"),
 		printItem(innerMockPP, "Meow:", "purrrr"),
-		mockPP.EXPECT().Infof(pp.EmojiConfig, "Notifiers (via shoutrrr):"),
+		mockPP.EXPECT().Infof(pp.EmojiConfig, "Notification services (via shoutrrr):"),
 		printItem(innerMockPP, "Snake:", "hissss"),
 	)
 
@@ -144,7 +144,7 @@ func TestPrintEmpty(t *testing.T) {
 		printItem(innerMockPP, "Update on start?", "false"),
 		printItem(innerMockPP, "Delete on stop?", "false"),
 		printItem(innerMockPP, "Cache expiration:", "0s"),
-		mockPP.EXPECT().Infof(pp.EmojiConfig, "New DNS records:"),
+		mockPP.EXPECT().Infof(pp.EmojiConfig, "Parameters of new DNS records:"),
 		printItem(innerMockPP, "TTL:", "0"),
 		printItem(innerMockPP, "Proxied domains:", "(none)"),
 		printItem(innerMockPP, "Unproxied domains:", "(none)"),
diff --git a/internal/config/env_base_test.go b/internal/config/env_base_test.go
index 5731732..637e5ce 100644
--- a/internal/config/env_base_test.go
+++ b/internal/config/env_base_test.go
@@ -186,13 +186,13 @@ func TestReadQuiet(t *testing.T) {
 		"true": {
 			true, " true", true,
 			func(m *mocks.MockPP) {
-				m.EXPECT().SetLevel(pp.Notice)
+				m.EXPECT().SetVerbosity(pp.Notice)
 			},
 		},
 		"false": {
 			true, "    false ", true,
 			func(m *mocks.MockPP) {
-				m.EXPECT().SetLevel(pp.Info)
+				m.EXPECT().SetVerbosity(pp.Info)
 			},
 		},
 		"illform": {
diff --git a/internal/pp/fmt_test.go b/internal/pp/fmt_test.go
index cbbc932..d52ff97 100644
--- a/internal/pp/fmt_test.go
+++ b/internal/pp/fmt_test.go
@@ -13,8 +13,8 @@ func TestIsEnabledFor(t *testing.T) {
 	t.Parallel()
 
 	for name, tc := range map[string]struct {
-		set      pp.Level
-		test     pp.Level
+		set      pp.Verbosity
+		test     pp.Verbosity
 		expected bool
 	}{
 		"info-notice": {pp.Info, pp.Notice, true},
@@ -24,7 +24,7 @@ func TestIsEnabledFor(t *testing.T) {
 			t.Parallel()
 
 			var buf strings.Builder
-			fmt := pp.New(&buf).SetLevel(tc.set)
+			fmt := pp.New(&buf).SetVerbosity(tc.set)
 
 			require.Equal(t, tc.expected, fmt.IsEnabledFor(tc.test))
 		})
@@ -59,9 +59,9 @@ func TestPrint(t *testing.T) {
 	t.Parallel()
 
 	for name, tc := range map[string]struct {
-		emoji    bool
-		level    pp.Level
-		expected string
+		emoji     bool
+		verbosity pp.Verbosity
+		expected  string
 	}{
 		"info":              {true, pp.Info, "🌟 info\n🌟 notice\n🌟 warning\n🌟 error\n"},
 		"notice":            {true, pp.Notice, "🌟 notice\n🌟 warning\n🌟 error\n"},
@@ -76,7 +76,7 @@ func TestPrint(t *testing.T) {
 			t.Parallel()
 
 			var buf strings.Builder
-			fmt := pp.New(&buf).SetEmoji(tc.emoji).SetLevel(tc.level)
+			fmt := pp.New(&buf).SetEmoji(tc.emoji).SetVerbosity(tc.verbosity)
 
 			fmt.Infof(pp.EmojiStar, "info")
 			fmt.Noticef(pp.EmojiStar, "notice")