Skip to content

Commit 5ee14e2

Browse files
authored
Merge pull request #124 from wendal/copilot/review-golang-compatibility
Modernize Go compatibility: modules, deprecated APIs, unit tests, CI matrix
2 parents e1b4750 + 6cab6d8 commit 5ee14e2

File tree

13 files changed

+276
-36
lines changed

13 files changed

+276
-36
lines changed

.github/workflows/go.yml

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,28 @@
11
name: Go
2-
on: [push]
2+
on: [push, pull_request]
33
jobs:
44

55
build:
66
name: Build
77
runs-on: ubuntu-latest
8+
strategy:
9+
matrix:
10+
go-version: ['1.21', '1.22', '1.23']
11+
812
steps:
13+
- name: Check out code
14+
uses: actions/checkout@v4
915

10-
- name: Set up Go 1.12
11-
uses: actions/setup-go@v1
16+
- name: Set up Go ${{ matrix.go-version }}
17+
uses: actions/setup-go@v5
1218
with:
13-
go-version: 1.12
14-
id: go
19+
go-version: ${{ matrix.go-version }}
1520

16-
- name: Check out code into the Go module directory
17-
uses: actions/checkout@v1
21+
- name: Build
22+
run: go build -v ./...
1823

19-
- name: Get dependencies
20-
run: |
21-
go get -v -t -d ./...
22-
if [ -f Gopkg.toml ]; then
23-
curl https://raw.githubusercontent.com/golang/dep/master/install.sh | sh
24-
dep ensure
25-
fi
24+
- name: Test
25+
run: go test -v ./...
2626

27-
- name: Build
28-
run: go build -v .
27+
- name: Vet
28+
run: go vet ./...

compile.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import (
77
"github.com/wendal/errors"
88
"github.com/wendal/mustache"
99
"io"
10-
"io/ioutil"
1110
"log"
1211
"os"
1312
"path/filepath"
@@ -433,7 +432,9 @@ func WriteTo(url string, content string) {
433432
if HTML_EXT != "" {
434433
content += HTML_EXT
435434
}
436-
ioutil.WriteFile(dstPath, []byte(content), os.ModePerm)
435+
if err := os.WriteFile(dstPath, []byte(content), os.ModePerm); err != nil {
436+
log.Println("ERR WriteTo", dstPath, err)
437+
}
437438
}
438439

439440
func PrapareAssets(theme string, layoutName string, topCtx mustache.Context) string {
@@ -526,7 +527,7 @@ func copyDir(src string, target string) error {
526527
if !fst.IsDir() {
527528
return nil
528529
}
529-
finfos, err := ioutil.ReadDir(src)
530+
finfos, err := os.ReadDir(src)
530531
if err != nil {
531532
log.Println(err)
532533
return err

config.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import (
55
"encoding/json"
66
"github.com/wendal/goyaml2"
77
"io"
8-
"io/ioutil"
98
"log"
109
"os"
1110
)
@@ -37,7 +36,7 @@ func ReadYml(path string) (cnf map[string]interface{}, err error) {
3736
func ReadYmlReader(r io.Reader) (cnf map[string]interface{}, err error) {
3837

3938
err = nil
40-
buf, err := ioutil.ReadAll(r)
39+
buf, err := io.ReadAll(r)
4140
if err != nil || len(buf) < 3 {
4241
return
4342
}

go.mod

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
module github.com/wendal/gor
2+
3+
go 1.24.13
4+
5+
require (
6+
github.com/howeyc/fsnotify v0.9.0
7+
github.com/russross/blackfriday v1.6.0
8+
github.com/wendal/errors v0.0.0-20181209125328-7f31f4b264ec
9+
github.com/wendal/goyaml2 v0.0.0-20190215120833-ee753311eeae
10+
github.com/wendal/mustache v0.0.0-20130201095610-61b948aeb760
11+
)

go.sum

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
github.com/howeyc/fsnotify v0.9.0 h1:0gtV5JmOKH4A8SsFxG2BczSeXWWPvcMT0euZt5gDAxY=
2+
github.com/howeyc/fsnotify v0.9.0/go.mod h1:41HzSPxBGeFRQKEEwgh49TRw/nKBsYZ2cF1OzPjSJsA=
3+
github.com/russross/blackfriday v1.6.0 h1:KqfZb0pUVN2lYqZUYRddxF4OR8ZMURnJIG5Y3VRLtww=
4+
github.com/russross/blackfriday v1.6.0/go.mod h1:ti0ldHuxg49ri4ksnFxlkCfN+hvslNlmVHqNRXXJNAY=
5+
github.com/wendal/errors v0.0.0-20181209125328-7f31f4b264ec h1:bua919NvciYmjqfeZMsVkXTny1QvXMrri0X6NlqILRs=
6+
github.com/wendal/errors v0.0.0-20181209125328-7f31f4b264ec/go.mod h1:Q12BUT7DqIlHRmgv3RskH+UCM/4eqVMgI0EMmlSpAXc=
7+
github.com/wendal/goyaml2 v0.0.0-20190215120833-ee753311eeae h1:ke3nvVbPZDAsGLqBukiPAPdzgllyrQAZ4OtdzTf3z5U=
8+
github.com/wendal/goyaml2 v0.0.0-20190215120833-ee753311eeae/go.mod h1:CoOAlRIb5zPgRa7NEsqTVNu/26+FJ1jrIj3/NWU3hM8=
9+
github.com/wendal/mustache v0.0.0-20130201095610-61b948aeb760 h1:yBVQh3XiGSrCTosbppoAmxpCV2fnqE0bUjxVF9iqVdc=
10+
github.com/wendal/mustache v0.0.0-20130201095610-61b948aeb760/go.mod h1:e+ZfVXOi5GtWL3bAoE3ErzEnNyguYqHVegUqgbFtMZM=

gor/gor.go

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import (
77
"fmt"
88
"github.com/howeyc/fsnotify"
99
"github.com/wendal/gor"
10-
"io/ioutil"
1110
"log"
1211
"net/http"
1312
"os"
@@ -125,8 +124,14 @@ func main() {
125124
_compile()
126125
}
127126
case ".update.zip.go":
128-
d, _ := ioutil.ReadFile("gor-content.zip")
129-
_zip, _ := os.OpenFile("zip.go", os.O_WRONLY|os.O_TRUNC|os.O_CREATE, os.ModePerm)
127+
d, err := os.ReadFile("gor-content.zip")
128+
if err != nil {
129+
log.Fatal("failed to read gor-content.zip:", err)
130+
}
131+
_zip, err := os.OpenFile("zip.go", os.O_WRONLY|os.O_TRUNC|os.O_CREATE, os.ModePerm)
132+
if err != nil {
133+
log.Fatal("failed to open zip.go for writing:", err)
134+
}
130135
header := `package main
131136
const INIT_ZIP="`
132137
_zip.Write([]byte(header))

gor/new.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import (
55
"bytes"
66
"encoding/base64"
77
"io"
8-
"io/ioutil"
98
"log"
109
"os"
1110
"path/filepath"
@@ -23,7 +22,10 @@ func CmdInit(path string) {
2322
}
2423

2524
decoder := base64.NewDecoder(base64.StdEncoding, bytes.NewBufferString(INIT_ZIP))
26-
b, _ := ioutil.ReadAll(decoder)
25+
b, err := io.ReadAll(decoder)
26+
if err != nil {
27+
log.Fatalf("failed to read embedded init zip data: %v", err)
28+
}
2729

2830
z, err := zip.NewReader(bytes.NewReader(b), int64(len(b)))
2931
if err != nil {

gor_test.go

Lines changed: 207 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,207 @@
1+
package gor
2+
3+
import (
4+
"testing"
5+
"time"
6+
)
7+
8+
func TestEncodePathInfo(t *testing.T) {
9+
tests := []struct {
10+
input string
11+
expected string
12+
}{
13+
{"hello world", "hello-world"},
14+
{"go:lang", "go-lang"},
15+
{"simple", "simple"},
16+
{"a b:c", "a-b-c"},
17+
}
18+
for _, tt := range tests {
19+
got := EncodePathInfo(tt.input)
20+
if got != tt.expected {
21+
t.Errorf("EncodePathInfo(%q) = %q, want %q", tt.input, got, tt.expected)
22+
}
23+
}
24+
}
25+
26+
func TestDecodePathInfo(t *testing.T) {
27+
tests := []struct {
28+
input string
29+
expected string
30+
}{
31+
{"hello%20world", "hello world"},
32+
{"go-lang", "go-lang"},
33+
{"simple", "simple"},
34+
}
35+
for _, tt := range tests {
36+
got := DecodePathInfo(tt.input)
37+
if got != tt.expected {
38+
t.Errorf("DecodePathInfo(%q) = %q, want %q", tt.input, got, tt.expected)
39+
}
40+
}
41+
}
42+
43+
func TestEncodeDecodePathInfo(t *testing.T) {
44+
original := "hello world"
45+
encoded := EncodePathInfo(original)
46+
// EncodePathInfo replaces spaces with dashes, not url-encode, so round-trip differs
47+
if encoded == original {
48+
t.Errorf("EncodePathInfo should transform %q", original)
49+
}
50+
}
51+
52+
func TestAsStrings(t *testing.T) {
53+
tests := []struct {
54+
name string
55+
input interface{}
56+
expected []string
57+
}{
58+
{"nil", nil, []string{}},
59+
{"string", "hello", []string{"hello"}},
60+
{"string slice", []string{"a", "b"}, []string{"a", "b"}},
61+
{"interface slice", []interface{}{"x", "y"}, []string{"x", "y"}},
62+
}
63+
for _, tt := range tests {
64+
got := AsStrings(tt.input)
65+
if len(got) != len(tt.expected) {
66+
t.Errorf("[%s] AsStrings(%v) len=%d, want %d", tt.name, tt.input, len(got), len(tt.expected))
67+
continue
68+
}
69+
for i := range got {
70+
if got[i] != tt.expected[i] {
71+
t.Errorf("[%s] AsStrings(%v)[%d] = %q, want %q", tt.name, tt.input, i, got[i], tt.expected[i])
72+
}
73+
}
74+
}
75+
}
76+
77+
func TestCreatePostURL(t *testing.T) {
78+
db := make(map[string]interface{})
79+
date := time.Date(2023, 5, 15, 0, 0, 0, 0, time.Local)
80+
post := map[string]interface{}{
81+
"permalink": "/:year/:month/:title/",
82+
"_date": date,
83+
"title": "Hello World",
84+
"id": "posts/2023-05-15-hello-world.md",
85+
"categories": []string{"go"},
86+
}
87+
CreatePostURL(db, "/", post)
88+
url, ok := post["url"].(string)
89+
if !ok {
90+
t.Fatal("post[url] should be a string")
91+
}
92+
if url != "/2023/05/Hello-World/" {
93+
t.Errorf("unexpected url: %q", url)
94+
}
95+
}
96+
97+
func TestCreatePostURL_StaticPermalink(t *testing.T) {
98+
db := make(map[string]interface{})
99+
date := time.Date(2023, 1, 1, 0, 0, 0, 0, time.Local)
100+
post := map[string]interface{}{
101+
"permalink": "/about/",
102+
"_date": date,
103+
"title": "About",
104+
"id": "pages/about.md",
105+
"categories": []string{},
106+
}
107+
CreatePostURL(db, "/", post)
108+
url, ok := post["url"].(string)
109+
if !ok {
110+
t.Fatal("post[url] should be a string")
111+
}
112+
if url != "/about/" {
113+
t.Errorf("unexpected url: %q", url)
114+
}
115+
}
116+
117+
func TestMarkdownToHtml(t *testing.T) {
118+
tests := []struct {
119+
name string
120+
input string
121+
contains string
122+
}{
123+
{"bold", "**hello**", "<strong>hello</strong>"},
124+
{"header", "# Title", "<h1>Title</h1>"},
125+
{"paragraph", "simple text", "simple text"},
126+
}
127+
for _, tt := range tests {
128+
got := MarkdownToHtml(tt.input)
129+
if len(got) == 0 {
130+
t.Errorf("[%s] MarkdownToHtml(%q) returned empty string", tt.name, tt.input)
131+
continue
132+
}
133+
found := false
134+
for i := 0; i <= len(got)-len(tt.contains); i++ {
135+
if got[i:i+len(tt.contains)] == tt.contains {
136+
found = true
137+
break
138+
}
139+
}
140+
if !found {
141+
t.Errorf("[%s] MarkdownToHtml(%q) = %q, want it to contain %q", tt.name, tt.input, got, tt.contains)
142+
}
143+
}
144+
}
145+
146+
func TestSortPosts(t *testing.T) {
147+
date1 := time.Date(2023, 1, 1, 0, 0, 0, 0, time.Local)
148+
date2 := time.Date(2023, 6, 1, 0, 0, 0, 0, time.Local)
149+
dict := map[string]Mapper{
150+
"posts/older.md": {"id": "posts/older.md", "_date": date1},
151+
"posts/newer.md": {"id": "posts/newer.md", "_date": date2},
152+
}
153+
ids := []string{"posts/older.md", "posts/newer.md"}
154+
sorted := SortPosts(dict, ids)
155+
if sorted[0] != "posts/newer.md" {
156+
t.Errorf("SortPosts: expected newer post first, got %v", sorted)
157+
}
158+
}
159+
160+
func TestMapperGetString(t *testing.T) {
161+
m := Mapper{"key": "value", "num": 42}
162+
if m.GetString("key") != "value" {
163+
t.Errorf("GetString(key) should return 'value'")
164+
}
165+
if m.GetString("missing") != "" {
166+
t.Errorf("GetString(missing) should return ''")
167+
}
168+
if m.GetString("num") != "42" {
169+
t.Errorf("GetString(num) should return '42'")
170+
}
171+
}
172+
173+
func TestMapperGetInt(t *testing.T) {
174+
m := Mapper{"a": int64(5), "b": 10, "c": "x"}
175+
if m.GetInt("a") != 5 {
176+
t.Errorf("GetInt(a) should return 5")
177+
}
178+
if m.GetInt("b") != 10 {
179+
t.Errorf("GetInt(b) should return 10")
180+
}
181+
if m.GetInt("missing") != 0 {
182+
t.Errorf("GetInt(missing) should return 0")
183+
}
184+
}
185+
186+
func TestPostPath(t *testing.T) {
187+
tests := []struct {
188+
title string
189+
contains string
190+
}{
191+
{"my post", "my-post"},
192+
{"hello-world", "hello-world"},
193+
}
194+
for _, tt := range tests {
195+
got := postPath(tt.title)
196+
found := false
197+
for i := 0; i <= len(got)-len(tt.contains); i++ {
198+
if got[i:i+len(tt.contains)] == tt.contains {
199+
found = true
200+
break
201+
}
202+
}
203+
if !found {
204+
t.Errorf("postPath(%q) = %q, want it to contain %q", tt.title, got, tt.contains)
205+
}
206+
}
207+
}

map2struct.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ func ToStruct(m map[string]interface{}, val reflect.Value) {
4040
if _str, ok := v.(string); ok {
4141
field.SetString(_str)
4242
} else {
43-
field.SetString(fmt.Sprint("%v", v))
43+
field.SetString(fmt.Sprintf("%v", v))
4444
}
4545
case reflect.Int:
4646
fallthrough

0 commit comments

Comments
 (0)