Move to Go 1.27, and fix initials for non-ASCII names

Initials() capped the loop with len(out) == 2, which counts bytes: a name
starting with Ä, Ö or Å filled the budget on its own and returned a single
letter. Count the initials taken instead.

go fix also wanted a strings.Builder here, but that allocates a string per
iteration to measure a two-character result. Took its SplitSeq suggestion
in lyrics.go, which drops an intermediate slice.
This commit is contained in:
Esa Kataja
2026-09-05 12:46:08 +03:00
parent 992caa4eb1
commit 10ec9d1d6e
5 changed files with 20 additions and 5 deletions
+1 -1
View File
@@ -1,4 +1,4 @@
FROM golang:1.26-alpine AS build
FROM golang:1.27-alpine AS build
# CalVer, injected at build so no file needs bumping by hand: docker build --build-arg VERSION=…
ARG VERSION=dev
WORKDIR /src
+3 -2
View File
@@ -35,10 +35,11 @@ type member struct {
// Initials for the avatar circle: no default image on disk, no identicon generator.
func (m *member) Initials() string {
out := ""
out, n := "", 0
for _, f := range strings.Fields(m.Name) {
out += strings.ToUpper(string([]rune(f)[0]))
if len(out) == 2 {
// ponytail: count runes taken, not bytes — "Ä" is 2 bytes and used to end the loop early.
if n++; n == 2 {
break
}
}
+14
View File
@@ -230,3 +230,17 @@ func TestBanDropsSessionsAndBlocksLogin(t *testing.T) {
t.Fatalf("login after unban: status = %d, want 303", w.Code)
}
}
func TestInitials(t *testing.T) {
for name, want := range map[string]string{
"Esa Kataja": "EK",
"Ärväs Öhman": "ÄÖ", // multi-byte initials must not end the loop early
"Åke": "Å",
"": "",
"a b c": "AB",
} {
if got := (&member{Name: name}).Initials(); got != want {
t.Errorf("Initials(%q) = %q, want %q", name, got, want)
}
}
}
+1 -1
View File
@@ -1,6 +1,6 @@
module git.kessinen.com/kessinen/levyraati26-go
go 1.25.0
go 1.27.0
require (
golang.org/x/crypto v0.32.0
+1 -1
View File
@@ -67,7 +67,7 @@ func parseLRC(s string) []lyricLine {
return nil
}
var out []lyricLine
for _, raw := range strings.Split(s, "\n") {
for raw := range strings.SplitSeq(s, "\n") {
stamps := lrcOne.FindAllStringSubmatch(raw, -1)
if len(stamps) == 0 {
continue