5 Commits
v0.1.1 ... main

Author SHA1 Message Date
T. von Dein
6fed3af065 move to codeberg (#15) 2025-12-06 20:56:16 +01:00
ee3b4e8e9b fix linting errors 2024-02-14 13:14:21 +01:00
9d34e78475 fix #12: unquote eventually quoted keys generated by yaml.Marshall() 2024-02-14 13:06:30 +01:00
e9af16a8a2 bump version 2024-02-10 13:17:57 +01:00
9ede62037a fix #10: check group length before manipulation 2024-02-10 13:17:57 +01:00
11 changed files with 200 additions and 64 deletions

View File

@@ -1,47 +0,0 @@
name: build-and-test
on: [push, pull_request]
jobs:
build:
strategy:
matrix:
version: [1.21]
os: [ubuntu-latest, windows-latest, macos-latest]
name: Build
runs-on: ${{ matrix.os }}
steps:
- name: Set up Go
uses: actions/setup-go@v3
with:
go-version: ${{ matrix.version }}
id: go
- name: checkout
uses: actions/checkout@v3
- name: build
run: go build
- name: test
run: make test
- name: Update coverage report
uses: ncruces/go-coverage-report@main
with:
report: true
chart: true
amend: true
if: |
matrix.os == 'ubuntu-latest' &&
github.event_name == 'push'
continue-on-error: true
golangci:
name: lint
runs-on: ubuntu-latest
steps:
- uses: actions/setup-go@v3
with:
go-version: 1.21
- uses: actions/checkout@v3
- name: golangci-lint
uses: golangci/golangci-lint-action@v3

65
.goreleaser.yaml Normal file
View File

@@ -0,0 +1,65 @@
# vim: set ts=2 sw=2 tw=0 fo=cnqoj
version: 2
before:
hooks:
- go mod tidy
gitea_urls:
api: https://codeberg.org/api/v1
download: https://codeberg.org
builds:
- env:
- CGO_ENABLED=0
goos:
- linux
- freebsd
archives:
- formats: [tar.gz]
# this name template makes the OS and Arch compatible with the results of `uname`.
name_template: >-
{{ .ProjectName }}_
{{- title .Os }}_
{{- if eq .Arch "amd64" }}x86_64
{{- else if eq .Arch "386" }}i386
{{- else }}{{ .Arch }}{{ end }}
{{- if .Arm }}v{{ .Arm }}{{ end }}_{{ .Tag }}
# use zip for windows archives
format_overrides:
- goos: windows
formats: [zip]
- goos: linux
formats: [tar.gz,binary]
files:
- src: "*.md"
strip_parent: true
- src: Makefile.dist
dst: Makefile
wrap_in_directory: true
changelog:
sort: asc
filters:
exclude:
- "^docs:"
- "^test:"
groups:
- title: Improved
regexp: '^.*?(feat|add|new)(\([[:word:]]+\))??!?:.+$'
order: 0
- title: Fixed
regexp: '^.*?(bug|fix)(\([[:word:]]+\))??!?:.+$'
order: 1
- title: Changed
order: 999
release:
header: "# Release Notes"
footer: >-
---
Full Changelog: [{{ .PreviousTag }}...{{ .Tag }}](https://codeberg.org/scip/yadu/compare/{{ .PreviousTag }}...{{ .Tag }})

36
.woodpecker/build.yaml Normal file
View File

@@ -0,0 +1,36 @@
matrix:
platform:
- linux/amd64
goversion:
- 1.24
labels:
platform: ${platform}
steps:
build:
when:
event: [push]
image: golang:${goversion}
commands:
- go get
- go build
linter:
when:
event: [push]
image: golang:${goversion}
commands:
- curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/HEAD/install.sh | sh -s -- -b $(go env GOPATH)/bin v2.5.0
- golangci-lint --version
- golangci-lint run ./...
depends_on: [build]
test:
when:
event: [push]
image: golang:${goversion}
commands:
- go get
- go test -v -cover
depends_on: [build,linter]

View File

@@ -11,7 +11,7 @@ VERSION = $(shell grep VERSION handler.go | head -1 | cut -d '"' -f2)
all: buildlocal
buildlocal:
go build
go build -o example/example example/example.go
clean:
rm -rf $(tool) coverage.out testdata t/out example/example

18
Makefile.dist Normal file
View File

@@ -0,0 +1,18 @@
# -*-make-*-
.PHONY: install all
tool = rpn
PREFIX = /usr/local
UID = root
GID = 0
all:
@echo "Type 'sudo make install' to install the tool."
@echo "To change prefix, type 'sudo make install PREFIX=/opt'"
install:
install -d -o $(UID) -g $(GID) $(PREFIX)/bin
install -d -o $(UID) -g $(GID) $(PREFIX)/share/doc
install -o $(UID) -g $(GID) -m 555 $(tool) $(PREFIX)/sbin/
install -o $(UID) -g $(GID) -m 444 *.md $(PREFIX)/share/doc/

View File

@@ -1,7 +1,6 @@
[![Go Report Card](https://goreportcard.com/badge/github.com/tlinden/yadu)](https://goreportcard.com/report/github.com/tlinden/yadu)
[![Actions](https://github.com/tlinden/yadu/actions/workflows/ci.yaml/badge.svg)](https://github.com/tlinden/yadu/actions)
[![Go Coverage](https://github.com/tlinden/yadu/wiki/coverage.svg)](https://raw.githack.com/wiki/tlinden/yadu/coverage.html)
![GitHub License](https://img.shields.io/github/license/tlinden/yadu)
[![status-badge](https://ci.codeberg.org/api/badges/15686/status.svg)](https://ci.codeberg.org/repos/15686)
[![Go Report Card](https://goreportcard.com/badge/github.com/tlinden/yadu)](https://goreportcard.com/report/github.com/tlinden/yadu)
[![License](https://img.shields.io/badge/license-GPL-blue.svg)](https://codeberg.org/scip/yadu/raw/branch/main/LICENSE)
[![GoDoc](https://godoc.org/github.com/tlinden/yadu?status.svg)](https://godoc.org/github.com/tlinden/yadu)
# yadu - a human readable yaml based slog.Handler
@@ -74,7 +73,7 @@ See `example/example.go` for usage.
Execute this to add the module to your project:
```sh
go get github.com/tlinden/yadu
go get github.com/tlinden/yadu/v2
```
## Configuration

View File

@@ -4,7 +4,7 @@ import (
"log/slog"
"os"
"github.com/tlinden/yadu"
"github.com/tlinden/yadu/v2"
)
type body string

6
go.mod
View File

@@ -1,4 +1,4 @@
module github.com/tlinden/yadu
module github.com/tlinden/yadu/v2
go 1.21
@@ -8,7 +8,7 @@ require (
)
require (
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-colorable v0.1.14 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
golang.org/x/sys v0.14.0 // indirect
golang.org/x/sys v0.29.0 // indirect
)

6
go.sum
View File

@@ -2,13 +2,19 @@ github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=
github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=
github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/tlinden/yadu v0.1.3 h1:5cRCUmj+l5yvlM2irtpFBIJwVV2DPEgYSaWvF19FtcY=
github.com/tlinden/yadu v0.1.3/go.mod h1:l3bRmHKL9zGAR6pnBHY2HRPxBecf7L74BoBgOOpTcUA=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q=
golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU=
golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=

View File

@@ -17,7 +17,7 @@ import (
"github.com/fatih/color"
)
const VERSION = "0.1.1"
const VERSION = "0.1.3"
// We use RFC datestring by default
const DefaultTimeFormat = "2006-01-02T03:04.05 MST"
@@ -38,6 +38,35 @@ type Handler struct {
replaceAttr func(groups []string, a slog.Attr) slog.Attr
addSource bool
indenter *regexp.Regexp
/*
This is being used in Postprocess() to fix
https://github.com/go-yaml/yaml/issues/1020 and
https://github.com/tlinden/yadu/issues/12 respectively.
yaml.v3 follows the YAML standard and quotes all keys and values
matching this regex (see https://yaml.org/type/bool.html):
`y|Y|yes|Yes|YES|n|N|no|No|NO|true|True|TRUE|false|False|FALSE|on|On|ON|off|Off|OFF`
The problem is, that the YAML "standard" does not state wether
this applies to values or keys or values&keys and most
implementors, as gopkg.in/yaml.v3, do it just for keys and values.
Therefore if we dump a struct containing a key "Y" it ends up
being quoted, while any other keys remain unquoted, which looks
pretty ugly, makes evaluating the output harder, especially in
game development where you have to dump coordinates, points etc,
all containing X,Y with X unquoted and Y quoted.
To fix this utter nonsence, I just replace all quotes in all
keys. Period. This is just a logging module, nobody will and can
use its output to postprocess it with some yaml parser, because
we not only dump the structs as yaml, we also write a one liner
in front of it with the timestamp and the message. So, we don't
output valid YAML anyway and we don't give a shit about
compliance because of this. AND because this rule is bullshit.
*/
yamlcleaner *regexp.Regexp
}
// Options are options for the Yadu [log/slog.Handler].
@@ -150,7 +179,9 @@ func (h *Handler) getSource(pc uintptr) string {
}
func (h *Handler) Postprocess(yamlstr []byte) string {
return "\n " + strings.TrimSpace(h.indenter.ReplaceAllString(string(yamlstr), " "))
tree := string(yamlstr)
clean := h.yamlcleaner.ReplaceAllString(tree, "$1$2:")
return "\n " + strings.TrimSpace(h.indenter.ReplaceAllString(clean, " "))
}
// NewHandler returns a [log/slog.Handler] using the receiver's options.
@@ -168,6 +199,7 @@ func NewHandler(out io.Writer, opts *Options) *Handler {
replaceAttr: opts.ReplaceAttr,
addSource: opts.AddSource,
indenter: regexp.MustCompile(`(?m)^`),
yamlcleaner: regexp.MustCompile("(?m)^( *)\"([^\"]*)\":"),
}
if opts.Level == nil {
@@ -212,7 +244,7 @@ func (h *Handler) appendAttr(wa map[string]interface{}, a slog.Attr) {
}
wa[name] = innerwa
if a.Key != "" {
if a.Key != "" && len(h.groups) > 0 {
h.groups = h.groups[:len(h.groups)-1]
}
@@ -269,5 +301,6 @@ func (h *Handler) clone() *Handler {
replaceAttr: h.replaceAttr,
addSource: h.addSource,
indenter: h.indenter,
yamlcleaner: h.yamlcleaner,
}
}

View File

@@ -8,7 +8,7 @@ import (
"time"
"github.com/fatih/color"
"github.com/tlinden/yadu"
"github.com/tlinden/yadu/v2"
)
type body string
@@ -34,6 +34,10 @@ type Enemy struct {
Ammo []Ammo
}
type Point struct {
Y, N, True, False int
}
type Tests struct {
name string
want string
@@ -166,6 +170,9 @@ func GetAmmo() *Ammo {
return &Ammo{Forweapon: "Axe", Range: 50, Impact: 1, Cost: 50}
}
func GetPoint() *Point {
return &Point{}
}
func removeTime(_ []string, a slog.Attr) slog.Attr {
if a.Key == slog.TimeKey {
return slog.Attr{}
@@ -173,13 +180,13 @@ func removeTime(_ []string, a slog.Attr) slog.Attr {
return a
}
func Test(t *testing.T) {
func TestLogger(t *testing.T) {
t.Parallel()
for _, tt := range tests {
var buf bytes.Buffer
logger := slog.New(yadu.NewHandler(&buf, &tt.opts))
ttopts := tt.opts
logger := slog.New(yadu.NewHandler(&buf, &ttopts))
if !tt.with.Equal(slog.Attr{}) {
logger = logger.With(tt.with)
@@ -211,3 +218,22 @@ func Test(t *testing.T) {
buf.Reset()
}
}
func TestYamlCleaner(t *testing.T) {
t.Parallel()
var buf bytes.Buffer
logger := slog.New(yadu.NewHandler(&buf, &yadu.Options{}))
slog.SetDefault(logger)
logger.Info("got a point", "point", GetPoint())
got := buf.String()
bools := []string{"y:", "n:", "true:", "false:"}
for _, want := range bools {
if !strings.Contains(got, want) {
t.Errorf("test TestYamlCleaner failed.\n want: %s:\n got: %s\n", want, got)
}
}
}