refactor: replace karma-go with standard error handling

This commit is contained in:
Manuel Rüger
2026-03-28 10:16:29 +01:00
parent e160121005
commit 0859bf4d08
12 changed files with 69 additions and 215 deletions

View File

@@ -4,6 +4,7 @@ import (
"bytes"
"crypto/sha256"
"encoding/hex"
"fmt"
"image"
_ "image/gif"
_ "image/jpeg"
@@ -18,7 +19,6 @@ import (
"github.com/kovetskiy/mark/v16/confluence"
"github.com/kovetskiy/mark/v16/vfs"
"github.com/reconquest/karma-go"
"github.com/rs/zerolog/log"
)
@@ -50,10 +50,7 @@ func ResolveAttachments(
for i := range attachments {
checksum, err := GetChecksum(bytes.NewReader(attachments[i].FileBytes))
if err != nil {
return nil, karma.Format(
err,
"unable to get checksum for attachment: %q", attachments[i].Name,
)
return nil, fmt.Errorf("unable to get checksum for attachment %q: %w", attachments[i].Name, err)
}
attachments[i].Checksum = checksum
@@ -61,7 +58,7 @@ func ResolveAttachments(
remotes, err := api.GetAttachments(page.ID)
if err != nil {
return nil, karma.Format(err, "unable to get attachments for page %s", page.ID)
return nil, fmt.Errorf("unable to get attachments for page %s: %w", page.ID, err)
}
existing := []Attachment{}
@@ -110,11 +107,7 @@ func ResolveAttachments(
bytes.NewReader(attachment.FileBytes),
)
if err != nil {
return nil, karma.Format(
err,
"unable to create attachment %q",
attachment.Name,
)
return nil, fmt.Errorf("unable to create attachment %q: %w", attachment.Name, err)
}
attachment.ID = info.ID
@@ -137,11 +130,7 @@ func ResolveAttachments(
bytes.NewReader(attachment.FileBytes),
)
if err != nil {
return nil, karma.Format(
err,
"unable to update attachment %q",
attachment.Name,
)
return nil, fmt.Errorf("unable to update attachment %q: %w", attachment.Name, err)
}
attachment.Link = path.Join(
@@ -173,10 +162,7 @@ func ResolveLocalAttachments(opener vfs.Opener, base string, replacements []stri
for i := range attachments {
checksum, err := GetChecksum(bytes.NewReader(attachments[i].FileBytes))
if err != nil {
return nil, karma.Format(
err,
"unable to get checksum for attachment: %q", attachments[i].Name,
)
return nil, fmt.Errorf("unable to get checksum for attachment %q: %w", attachments[i].Name, err)
}
attachments[i].Checksum = checksum
@@ -204,7 +190,7 @@ func prepareAttachment(opener vfs.Opener, base, name string) (Attachment, error)
attachmentPath := filepath.Join(base, name)
file, err := opener.Open(attachmentPath)
if err != nil {
return Attachment{}, karma.Format(err, "unable to open file: %q", attachmentPath)
return Attachment{}, fmt.Errorf("unable to open file %q: %w", attachmentPath, err)
}
defer func() {
_ = file.Close()
@@ -212,7 +198,7 @@ func prepareAttachment(opener vfs.Opener, base, name string) (Attachment, error)
fileBytes, err := io.ReadAll(file)
if err != nil {
return Attachment{}, karma.Format(err, "unable to read file: %q", attachmentPath)
return Attachment{}, fmt.Errorf("unable to read file %q: %w", attachmentPath, err)
}
attachment := Attachment{

View File

@@ -13,7 +13,6 @@ import (
"unicode/utf8"
"github.com/kovetskiy/gopencils"
"github.com/reconquest/karma-go"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
)
@@ -147,11 +146,7 @@ func NewAPI(baseURL string, username string, password string, insecureSkipVerify
func (api *API) FindRootPage(space string) (*PageInfo, error) {
page, err := api.FindPage(space, ``, "page")
if err != nil {
return nil, karma.Format(
err,
"can't obtain first page from space %q",
space,
)
return nil, fmt.Errorf("can't obtain first page from space %q: %w", space, err)
}
if page == nil {
@@ -353,11 +348,7 @@ func (api *API) UpdateAttachment(
err = json.Unmarshal(result, &extendedResponse)
if err != nil {
return info, karma.Format(
err,
"unable to unmarshal JSON response as full response format: %s",
string(result),
)
return info, fmt.Errorf("unable to unmarshal JSON response as full response format (JSON=%s): %w", string(result), err)
}
if len(extendedResponse.Results) > 0 {
@@ -377,11 +368,7 @@ func (api *API) UpdateAttachment(
var shortResponse AttachmentInfo
err = json.Unmarshal(result, &shortResponse)
if err != nil {
return info, karma.Format(
err,
"unable to unmarshal JSON response as short response format: %s",
string(result),
)
return info, fmt.Errorf("unable to unmarshal JSON response as short response format (JSON=%s): %w", string(result), err)
}
return shortResponse, nil
@@ -395,42 +382,27 @@ func getAttachmentPayload(name, comment string, reader io.Reader) (*form, error)
content, err := writer.CreateFormFile("file", name)
if err != nil {
return nil, karma.Format(
err,
"unable to create form file",
)
return nil, fmt.Errorf("unable to create form file: %w", err)
}
_, err = io.Copy(content, reader)
if err != nil {
return nil, karma.Format(
err,
"unable to copy i/o between form-file and file",
)
return nil, fmt.Errorf("unable to copy i/o between form-file and file: %w", err)
}
commentWriter, err := writer.CreateFormField("comment")
if err != nil {
return nil, karma.Format(
err,
"unable to create form field for comment",
)
return nil, fmt.Errorf("unable to create form field for comment: %w", err)
}
_, err = commentWriter.Write([]byte(comment))
if err != nil {
return nil, karma.Format(
err,
"unable to write comment in form-field",
)
return nil, fmt.Errorf("unable to write comment in form-field: %w", err)
}
err = writer.Close()
if err != nil {
return nil, karma.Format(
err,
"unable to close form-writer",
)
return nil, fmt.Errorf("unable to close form-writer: %w", err)
}
return &form{
@@ -753,11 +725,7 @@ func (api *API) GetUserByName(name string) (*User, error) {
if len(response.Results) == 0 {
return nil, karma.
Describe("name", name).
Reason(
"user with given name is not found",
)
return nil, fmt.Errorf("user with name %q is not found", name)
}
return &response.Results[0].User, nil

1
go.mod
View File

@@ -8,7 +8,6 @@ require (
github.com/chromedp/chromedp v0.15.1
github.com/dreampuf/mermaid.go v0.0.40
github.com/kovetskiy/gopencils v0.0.0-20250404051442-0b776066936a
github.com/reconquest/karma-go v1.5.0
github.com/rs/zerolog v1.35.0
github.com/stefanfritsch/goldmark-admonitions v1.1.1
github.com/stretchr/testify v1.11.1

2
go.sum
View File

@@ -73,8 +73,6 @@ github.com/orisano/pixelmatch v0.0.0-20230914042517-fa304d1dc785/go.mod h1:nZgzb
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/reconquest/karma-go v1.5.0 h1:Chn4LtauwnvKfz13ZbmGNrRLKO1NciExHQSOBOsQqt4=
github.com/reconquest/karma-go v1.5.0/go.mod h1:52XRXXa2ec/VNrlCirwasdJfNmjI1O87q098gmqILh0=
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=

View File

@@ -11,7 +11,6 @@ import (
"go.yaml.in/yaml/v3"
"github.com/reconquest/karma-go"
"github.com/rs/zerolog/log"
)
@@ -35,8 +34,7 @@ func LoadTemplate(
templates *template.Template,
) (*template.Template, error) {
var (
name = strings.TrimSuffix(path, filepath.Ext(path))
facts = karma.Describe("name", name)
name = strings.TrimSuffix(path, filepath.Ext(path))
)
if template := templates.Lookup(name); template != nil {
@@ -51,11 +49,7 @@ func LoadTemplate(
body, err = os.ReadFile(filepath.Join(includePath, path))
}
if err != nil {
err = facts.Format(
err,
"unable to read template file",
)
return nil, err
return nil, fmt.Errorf("unable to read template file %q: %w", path, err)
}
}
@@ -68,12 +62,7 @@ func LoadTemplate(
templates, err = templates.New(name).Delims(left, right).Parse(string(body))
if err != nil {
err = facts.Format(
err,
"unable to parse template",
)
return nil, err
return nil, fmt.Errorf("unable to parse template %q: %w", name, err)
}
return templates, nil
@@ -85,23 +74,15 @@ func ProcessIncludes(
contents []byte,
templates *template.Template,
) (*template.Template, []byte, bool, error) {
vardump := func(
facts *karma.Context,
formatVardump := func(
data map[string]interface{},
) *karma.Context {
) string {
var parts []string
for key, value := range data {
key = "var " + key
facts = facts.Describe(
key,
strings.ReplaceAll(
fmt.Sprint(value),
"\n",
"\n"+strings.Repeat(" ", len(key)+2),
),
)
parts = append(parts, fmt.Sprintf("%s=%v", key, value))
}
return facts
return strings.Join(parts, ", ")
}
var (
@@ -125,8 +106,6 @@ func ProcessIncludes(
right = string(groups[4])
config = groups[5]
data = map[string]interface{}{}
facts = karma.Describe("path", path)
)
if delimsNone == "none" {
@@ -136,21 +115,16 @@ func ProcessIncludes(
err = yaml.Unmarshal(config, &data)
if err != nil {
err = facts.
Describe("config", string(config)).
Format(
err,
"unable to unmarshal template data config",
)
err = fmt.Errorf("unable to unmarshal template data config (path=%q, config=%q): %w", path, string(config), err)
return spec
}
log.Trace().Interface("vardump", vardump(facts, data)).Msgf("including template %q", path)
log.Trace().Interface("vardump", data).Msgf("including template %q", path)
templates, err = LoadTemplate(base, includePath, path, left, right, templates)
if err != nil {
err = facts.Format(err, "unable to load template")
err = fmt.Errorf("unable to load template %q: %w", path, err)
return spec
}
@@ -158,10 +132,7 @@ func ProcessIncludes(
err = templates.Execute(&buffer, data)
if err != nil {
err = vardump(facts, data).Format(
err,
"unable to execute template",
)
err = fmt.Errorf("unable to execute template %q (vars: %s): %w", path, formatVardump(data), err)
return spec
}

View File

@@ -41,10 +41,7 @@ func (macro *Macro) Apply(
err = yaml.Unmarshal([]byte(macro.Config), &config)
if err != nil {
err = karma.Format(
err,
"unable to unmarshal macros config template",
)
err = fmt.Errorf("unable to unmarshal macros config template: %w", err)
return match
}
@@ -55,10 +52,7 @@ func (macro *Macro) Apply(
macro.Regexp.FindSubmatch(match),
))
if err != nil {
err = karma.Format(
err,
"unable to execute macros template",
)
err = fmt.Errorf("unable to execute macros template: %w", err)
return match
}
@@ -136,10 +130,7 @@ func ExtractMacros(
err = yaml.Unmarshal([]byte(config), &cfg)
if err != nil {
err = karma.Format(
err,
"unable to unmarshal macros config template",
)
err = fmt.Errorf("unable to unmarshal macros config template: %w", err)
return nil
}
@@ -156,33 +147,22 @@ func ExtractMacros(
macro.Template, err = templates.New(template).Parse(body)
if err != nil {
err = karma.Format(
err,
"unable to parse template",
)
err = fmt.Errorf("unable to parse template: %w", err)
return nil
}
} else {
macro.Template, err = includes.LoadTemplate(base, includePath, template, "{{", "}}", templates)
if err != nil {
err = karma.Format(err, "unable to load template")
err = fmt.Errorf("unable to load template: %w", err)
return nil
}
}
facts := karma.
Describe("template", template).
Describe("expr", expr)
macro.Regexp, err = regexp.Compile(expr)
if err != nil {
err = facts.
Format(
err,
"unable to compile macros regexp",
)
err = fmt.Errorf("unable to compile macros regexp (expr=%q, template=%q): %w", expr, template, err)
return nil
}
@@ -190,7 +170,11 @@ func ExtractMacros(
macro.Config = config
log.Trace().
Interface("vardump", facts.Describe("config", macro.Config)).
Interface("vardump", map[string]interface{}{
"expr": expr,
"template": template,
"config": macro.Config,
}).
Msgf("loaded macro %q", expr)
macros = append(macros, macro)

View File

@@ -24,7 +24,6 @@ import (
"github.com/kovetskiy/mark/v16/stdlib"
"github.com/kovetskiy/mark/v16/types"
"github.com/kovetskiy/mark/v16/vfs"
"github.com/reconquest/karma-go"
"github.com/rs/zerolog/log"
)
@@ -286,7 +285,7 @@ func ProcessFile(file string, api *confluence.API, config Config) (*confluence.P
if meta != nil {
parent, pg, err := page.ResolvePage(false, api, meta)
if err != nil {
return nil, karma.Describe("title", meta.Title).Reason(err)
return nil, fmt.Errorf("error resolving page %q: %w", meta.Title, err)
}
if pg == nil {

View File

@@ -5,7 +5,6 @@ import (
"strings"
"github.com/kovetskiy/mark/v16/confluence"
"github.com/reconquest/karma-go"
"github.com/rs/zerolog/log"
)
@@ -22,11 +21,7 @@ func EnsureAncestry(
for i, title := range ancestry {
page, err := api.FindPage(space, title, "page")
if err != nil {
return nil, karma.Format(
err,
`error during finding parent page with title %q`,
title,
)
return nil, fmt.Errorf("error during finding parent page with title %q: %w", title, err)
}
if page == nil {
@@ -44,11 +39,7 @@ func EnsureAncestry(
} else {
page, err := api.FindRootPage(space)
if err != nil {
return nil, karma.Format(
err,
"can't find root page for space %q",
space,
)
return nil, fmt.Errorf("can't find root page for space %q: %w", space, err)
}
parent = page
@@ -68,11 +59,7 @@ func EnsureAncestry(
for _, title := range rest {
page, err := api.CreatePage(space, "page", parent, title, ``)
if err != nil {
return nil, karma.Format(
err,
`error during creating parent page with title %q`,
title,
)
return nil, fmt.Errorf("error during creating parent page with title %q: %w", title, err)
}
parent = page
@@ -108,11 +95,7 @@ func ValidateAncestry(
if len(page.Ancestors) < 1 {
homepage, err := api.FindHomePage(space)
if err != nil {
return nil, karma.Format(
err,
"can't obtain home page from space %q",
space,
)
return nil, fmt.Errorf("can't obtain home page from space %q: %w", space, err)
}
if page.ID == homepage.ID {
@@ -148,10 +131,10 @@ func ValidateAncestry(
}
if !valid {
return nil, karma.Describe("title", page.Title).
Describe("actual", strings.Join(actual, " > ")).
Describe("expected", strings.Join(ancestry, " > ")).
Format(nil, "the page has fewer parents than expected")
return nil, fmt.Errorf(
"the page has fewer parents than expected: title=%q, actual=[%s], expected=[%s]",
page.Title, strings.Join(actual, " > "), strings.Join(ancestry, " > "),
)
}
}
@@ -173,12 +156,10 @@ func ValidateAncestry(
list = append(list, ancestor.Title)
}
return nil, karma.Describe("expected parent", parent).
Describe("list", strings.Join(list, "; ")).
Format(
nil,
"unexpected ancestry tree, did not find expected parent page in the tree",
)
return nil, fmt.Errorf(
"unexpected ancestry tree, did not find expected parent page %q in the tree: actual=[%s]",
parent, strings.Join(list, "; "),
)
}
}

View File

@@ -14,7 +14,6 @@ import (
"github.com/kovetskiy/mark/v16/confluence"
"github.com/kovetskiy/mark/v16/metadata"
"github.com/reconquest/karma-go"
"github.com/rs/zerolog/log"
)
@@ -60,7 +59,7 @@ func ResolveRelativeLinks(
)
resolved, err := resolveLink(api, base, match, spaceForLinks, titleFromH1, titleFromFilename, parents, titleAppendGeneratedHash)
if err != nil {
return nil, karma.Format(err, "resolve link: %q", match.full)
return nil, fmt.Errorf("resolve link %q: %w", match.full, err)
}
if resolved == "" {
@@ -103,7 +102,7 @@ func resolveLink(
linkContents, err := os.ReadFile(filepath)
if err != nil {
return "", karma.Format(err, "read file: %s", filepath)
return "", fmt.Errorf("read file %s: %w", filepath, err)
}
contentType := http.DetectContentType(linkContents)
@@ -146,13 +145,7 @@ func resolveLink(
result, err = getConfluenceLink(api, linkMeta.Space, linkMeta.Title)
if err != nil {
return "", karma.Format(
err,
"find confluence page: %s / %s / %s",
filepath,
linkMeta.Space,
linkMeta.Title,
)
return "", fmt.Errorf("find confluence page (file=%s, space=%s, title=%s): %w", filepath, linkMeta.Space, linkMeta.Title, err)
}
if result == "" {
@@ -217,14 +210,14 @@ func getConfluenceLink(
// Try to find as a page first
page, err := api.FindPage(space, title, "page")
if err != nil {
return "", karma.Format(err, "api: find page")
return "", fmt.Errorf("api: find page %q in space %q: %w", title, space, err)
}
// If not found as a page, try to find as a blog post
if page == nil {
page, err = api.FindPage(space, title, "blogpost")
if err != nil {
return "", karma.Format(err, "api: find blogpost")
return "", fmt.Errorf("api: find blogpost %q in space %q: %w", title, space, err)
}
}
@@ -242,7 +235,7 @@ func getConfluenceLink(
tiny, err := GenerateTinyLink(baseURL, page.ID)
if err != nil {
return "", karma.Format(err, "generate tiny link for page %s", page.ID)
return "", fmt.Errorf("generate tiny link for page %s: %w", page.ID, err)
}
return tiny, nil

View File

@@ -1,11 +1,11 @@
package page
import (
"fmt"
"strings"
"github.com/kovetskiy/mark/v16/confluence"
"github.com/kovetskiy/mark/v16/metadata"
"github.com/reconquest/karma-go"
"github.com/rs/zerolog/log"
)
@@ -15,15 +15,11 @@ func ResolvePage(
meta *metadata.Meta,
) (*confluence.PageInfo, *confluence.PageInfo, error) {
if meta == nil {
return nil, nil, karma.Format(nil, "metadata is empty")
return nil, nil, fmt.Errorf("metadata is empty")
}
page, err := api.FindPage(meta.Space, meta.Title, meta.Type)
if err != nil {
return nil, nil, karma.Format(
err,
"error while finding page %q",
meta.Title,
)
return nil, nil, fmt.Errorf("error while finding page %q: %w", meta.Title, err)
}
if meta.Type == "blogpost" {
@@ -39,11 +35,7 @@ func ResolvePage(
// check to see if home page is in Parents
homepage, err := api.FindHomePage(meta.Space)
if err != nil {
return nil, nil, karma.Format(
err,
"can't obtain home page from space %q",
meta.Space,
)
return nil, nil, fmt.Errorf("can't obtain home page from space %q: %w", meta.Space, err)
}
skipHomeAncestry := false
@@ -93,11 +85,7 @@ func ResolvePage(
meta.Parents,
)
if err != nil {
return nil, nil, karma.Format(
err,
"can't create ancestry tree: %s",
strings.Join(meta.Parents, ` > `),
)
return nil, nil, fmt.Errorf("can't create ancestry tree %q: %w", strings.Join(meta.Parents, ` > `), err)
}
titles := []string{}

View File

@@ -1,14 +1,13 @@
package stdlib
import (
"fmt"
"html"
"strings"
"text/template"
"github.com/kovetskiy/mark/v16/confluence"
"github.com/rs/zerolog/log"
"github.com/reconquest/karma-go"
)
type Lib struct {
@@ -445,12 +444,7 @@ func templates(api *confluence.API) (*template.Template, error) {
} {
templates, err = templates.New(name).Parse(body)
if err != nil {
return nil, karma.
Describe("template", body).
Format(
err,
"unable to parse template",
)
return nil, fmt.Errorf("unable to parse template %q (body=%s): %w", name, body, err)
}
}

View File

@@ -2,12 +2,11 @@ package util
import (
"errors"
"fmt"
"io"
"net/url"
"os"
"strings"
"github.com/reconquest/karma-go"
)
type Credentials struct {
@@ -40,10 +39,7 @@ func GetCredentials(
if password == "-" {
stdin, err := io.ReadAll(os.Stdin)
if err != nil {
return nil, karma.Format(
err,
"unable to read password from stdin",
)
return nil, fmt.Errorf("unable to read password from stdin: %w", err)
}
password = strings.TrimSpace(string(stdin))
@@ -55,10 +51,7 @@ func GetCredentials(
url, err := url.Parse(targetURL)
if err != nil {
return nil, karma.Format(
err,
"unable to parse %q as url", targetURL,
)
return nil, fmt.Errorf("unable to parse %q as url: %w", targetURL, err)
}
if url.Host == "" && baseURL == "" {