From a43f5fec2e524f9b208fc98aa71b7804177d880a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20R=C3=BCger?= Date: Wed, 8 Apr 2026 01:34:06 +0200 Subject: [PATCH] refactor: modernize Go primitives - Replace interface{} with any (Go 1.18) across confluence/api.go, macro/macro.go, util/cli.go, util/error_handler.go, includes/templates.go - Replace sort.SliceStable with slices.SortStableFunc + cmp.Compare (Go 1.21) in attachment/attachment.go, consistent with existing slices usage - Replace fmt.Errorf("%s", msg) with errors.New(msg) in mark.go Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- attachment/attachment.go | 7 +++-- confluence/api.go | 60 ++++++++++++++++++++-------------------- includes/templates.go | 4 +-- macro/macro.go | 14 +++++----- mark.go | 3 +- util/cli.go | 10 +++---- util/error_handler.go | 2 +- 7 files changed, 51 insertions(+), 49 deletions(-) diff --git a/attachment/attachment.go b/attachment/attachment.go index 0f8a376..df25f60 100644 --- a/attachment/attachment.go +++ b/attachment/attachment.go @@ -13,7 +13,8 @@ import ( "net/url" "path" "path/filepath" - "sort" + "cmp" + "slices" "strconv" "strings" @@ -235,8 +236,8 @@ func CompileAttachmentLinks(markdown []byte, attachments []Attachment) []byte { // attachments/a.jpg // attachments/a.jpg.jpg // so we replace longer and then shorter - sort.SliceStable(replaces, func(i, j int) bool { - return len(replaces[i]) > len(replaces[j]) + slices.SortStableFunc(replaces, func(a, b string) int { + return cmp.Compare(len(b), len(a)) }) for _, replace := range replaces { diff --git a/confluence/api.go b/confluence/api.go index e0f17e1..d3a4e43 100644 --- a/confluence/api.go +++ b/confluence/api.go @@ -94,7 +94,7 @@ type tracer struct { prefix string } -func (tracer *tracer) Printf(format string, args ...interface{}) { +func (tracer *tracer) Printf(format string, args ...any) { log.Trace().Msgf(tracer.prefix+" "+format, args...) } @@ -485,21 +485,21 @@ func (api *API) CreatePage( title string, body string, ) (*PageInfo, error) { - payload := map[string]interface{}{ + payload := map[string]any{ "type": pageType, "title": title, - "space": map[string]interface{}{ + "space": map[string]any{ "key": space, }, - "body": map[string]interface{}{ - "storage": map[string]interface{}{ + "body": map[string]any{ + "storage": map[string]any{ "representation": "storage", "value": body, }, }, - "metadata": map[string]interface{}{ - "properties": map[string]interface{}{ - "editor": map[string]interface{}{ + "metadata": map[string]any{ + "properties": map[string]any{ + "editor": map[string]any{ "value": "v2", }, }, @@ -507,7 +507,7 @@ func (api *API) CreatePage( } if parent != nil { - payload["ancestors"] = []map[string]interface{}{ + payload["ancestors"] = []map[string]any{ {"id": parent.ID}, } } @@ -528,20 +528,20 @@ func (api *API) CreatePage( func (api *API) UpdatePage(page *PageInfo, newContent string, minorEdit bool, versionMessage string, appearance string, emojiString string) error { nextPageVersion := page.Version.Number + 1 - oldAncestors := []map[string]interface{}{} + oldAncestors := []map[string]any{} if page.Type != "blogpost" && len(page.Ancestors) > 0 { // picking only the last one, which is required by confluence - oldAncestors = []map[string]interface{}{ + oldAncestors = []map[string]any{ {"id": page.Ancestors[len(page.Ancestors)-1].ID}, } } - properties := map[string]interface{}{ + properties := map[string]any{ // Fix to set full-width as has changed on Confluence APIs again. // https://jira.atlassian.com/browse/CONFCLOUD-65447 // - "content-appearance-published": map[string]interface{}{ + "content-appearance-published": map[string]any{ "value": appearance, }, // content-appearance-draft should not be set as this is impacted by @@ -555,37 +555,37 @@ func (api *API) UpdatePage(page *PageInfo, newContent string, minorEdit bool, ve } unicodeHex := fmt.Sprintf("%x", r) - properties["emoji-title-draft"] = map[string]interface{}{ + properties["emoji-title-draft"] = map[string]any{ "value": unicodeHex, } - properties["emoji-title-published"] = map[string]interface{}{ + properties["emoji-title-published"] = map[string]any{ "value": unicodeHex, } } - payload := map[string]interface{}{ + payload := map[string]any{ "id": page.ID, "type": page.Type, "title": page.Title, - "version": map[string]interface{}{ + "version": map[string]any{ "number": nextPageVersion, "minorEdit": minorEdit, "message": versionMessage, }, "ancestors": oldAncestors, - "body": map[string]interface{}{ - "storage": map[string]interface{}{ + "body": map[string]any{ + "storage": map[string]any{ "value": newContent, "representation": "storage", }, }, - "metadata": map[string]interface{}{ + "metadata": map[string]any{ "properties": properties, }, } request, err := api.rest.Res( - "content/"+page.ID, &map[string]interface{}{}, + "content/"+page.ID, &map[string]any{}, ).Put(payload) if err != nil { return err @@ -600,10 +600,10 @@ func (api *API) UpdatePage(page *PageInfo, newContent string, minorEdit bool, ve func (api *API) AddPageLabels(page *PageInfo, newLabels []string) (*LabelInfo, error) { - labels := []map[string]interface{}{} + labels := []map[string]any{} for _, label := range newLabels { if label != "" { - item := map[string]interface{}{ + item := map[string]any{ "prefix": "global", "name": label, } @@ -765,17 +765,17 @@ func (api *API) RestrictPageUpdatesCloud( user = currentUser } - var result interface{} + var result any request, err := api.rest. Res("content"). Id(page.ID). Res("restriction", &result). - Post([]map[string]interface{}{ + Post([]map[string]any{ { "operation": "update", - "restrictions": map[string]interface{}{ - "user": []map[string]interface{}{ + "restrictions": map[string]any{ + "user": []map[string]any{ { "type": "known", "accountId": user.AccountID, @@ -801,15 +801,15 @@ func (api *API) RestrictPageUpdatesServer( ) error { var ( err error - result interface{} + result any ) request, err := api.json.Res( "setContentPermissions", &result, - ).Post([]interface{}{ + ).Post([]any{ page.ID, "Edit", - []map[string]interface{}{ + []map[string]any{ { "userName": allowedUser, }, diff --git a/includes/templates.go b/includes/templates.go index 7ed1dff..e7be99c 100644 --- a/includes/templates.go +++ b/includes/templates.go @@ -75,7 +75,7 @@ func ProcessIncludes( templates *template.Template, ) (*template.Template, []byte, bool, error) { formatVardump := func( - data map[string]interface{}, + data map[string]any, ) string { var parts []string for key, value := range data { @@ -105,7 +105,7 @@ func ProcessIncludes( left = string(groups[3]) right = string(groups[4]) config = groups[5] - data = map[string]interface{}{} + data = map[string]any{} ) if delimsNone == "none" { diff --git a/macro/macro.go b/macro/macro.go index 92339e9..7a845b0 100644 --- a/macro/macro.go +++ b/macro/macro.go @@ -37,7 +37,7 @@ func (macro *Macro) Apply( content = macro.Regexp.ReplaceAllFunc( content, func(match []byte) []byte { - config := map[string]interface{}{} + config := map[string]any{} err = yaml.Unmarshal([]byte(macro.Config), &config) if err != nil { @@ -63,21 +63,21 @@ func (macro *Macro) Apply( return content, err } -func (macro *Macro) configure(node interface{}, groups [][]byte) interface{} { +func (macro *Macro) configure(node any, groups [][]byte) any { switch node := node.(type) { - case map[interface{}]interface{}: + case map[any]any: for key, value := range node { node[key] = macro.configure(value, groups) } return node - case map[string]interface{}: + case map[string]any: for key, value := range node { node[key] = macro.configure(value, groups) } return node - case []interface{}: + case []any: for key, value := range node { node[key] = macro.configure(value, groups) } @@ -126,7 +126,7 @@ func ExtractMacros( var macro Macro if strings.HasPrefix(template, "#") { - cfg := map[string]interface{}{} + cfg := map[string]any{} err = yaml.Unmarshal([]byte(config), &cfg) if err != nil { @@ -170,7 +170,7 @@ func ExtractMacros( macro.Config = config log.Trace(). - Interface("vardump", map[string]interface{}{ + Interface("vardump", map[string]any{ "expr": expr, "template": template, "config": macro.Config, diff --git a/mark.go b/mark.go index a621f0d..b5b5598 100644 --- a/mark.go +++ b/mark.go @@ -4,6 +4,7 @@ import ( "bytes" "crypto/sha1" "encoding/hex" + "errors" "fmt" "io" "os" @@ -97,7 +98,7 @@ func Run(config Config) error { if config.CI { log.Warn().Msg(msg) } else { - return fmt.Errorf("%s", msg) + return errors.New(msg) } } diff --git a/util/cli.go b/util/cli.go index 7e8ff6c..8eb315d 100644 --- a/util/cli.go +++ b/util/cli.go @@ -23,7 +23,7 @@ func RunMark(ctx context.Context, cmd *cli.Command) error { output := zerolog.ConsoleWriter{ Out: os.Stderr, TimeFormat: "2006-01-02 15:04:05.000", - FormatLevel: func(i interface{}) string { + FormatLevel: func(i any) string { var l string if ll, ok := i.(string); ok { switch ll { @@ -49,16 +49,16 @@ func RunMark(ctx context.Context, cmd *cli.Command) error { } return l }, - FormatFieldName: func(i interface{}) string { + FormatFieldName: func(i any) string { return "" }, - FormatFieldValue: func(i interface{}) string { + FormatFieldValue: func(i any) string { return fmt.Sprintf("%s", i) }, - FormatErrFieldName: func(i interface{}) string { + FormatErrFieldName: func(i any) string { return "" }, - FormatErrFieldValue: func(i interface{}) string { + FormatErrFieldValue: func(i any) string { return fmt.Sprintf("%s", i) }, } diff --git a/util/error_handler.go b/util/error_handler.go index 7182c3a..fcbb01e 100644 --- a/util/error_handler.go +++ b/util/error_handler.go @@ -14,7 +14,7 @@ func NewErrorHandler(continueOnError bool) *FatalErrorHandler { } } -func (h *FatalErrorHandler) Handle(err error, format string, args ...interface{}) { +func (h *FatalErrorHandler) Handle(err error, format string, args ...any) { if err == nil { if h.ContinueOnError {