chore: make use of go1.26 features (#12369)

Allows us to make use of Go features introduced in v1.26.

I require a feature from v1.26 for a PR I want to make later.

Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/12369
Reviewed-by: Mathieu Fenniak <mfenniak@noreply.codeberg.org>
This commit is contained in:
Gusted 2026-05-01 22:51:48 +02:00 committed by Gusted
parent c1dc213c9b
commit 07a6b6ce82
17 changed files with 66 additions and 100 deletions

2
go.mod
View file

@ -1,6 +1,6 @@
module forgejo.org module forgejo.org
go 1.25.0 go 1.26.0
toolchain go1.26.2 toolchain go1.26.2

View file

@ -11,7 +11,6 @@ import (
"forgejo.org/models/unittest" "forgejo.org/models/unittest"
user_model "forgejo.org/models/user" user_model "forgejo.org/models/user"
"forgejo.org/modules/timeutil" "forgejo.org/modules/timeutil"
"forgejo.org/modules/util"
"github.com/ProtonMail/go-crypto/openpgp/packet" "github.com/ProtonMail/go-crypto/openpgp/packet"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
@ -458,7 +457,7 @@ epiDVQ==
func TestTryGetKeyIDFromSignature(t *testing.T) { func TestTryGetKeyIDFromSignature(t *testing.T) {
assert.Empty(t, tryGetKeyIDFromSignature(&packet.Signature{})) assert.Empty(t, tryGetKeyIDFromSignature(&packet.Signature{}))
assert.Equal(t, "038D1A3EADDBEA9C", tryGetKeyIDFromSignature(&packet.Signature{ assert.Equal(t, "038D1A3EADDBEA9C", tryGetKeyIDFromSignature(&packet.Signature{
IssuerKeyId: util.ToPointer(uint64(0x38D1A3EADDBEA9C)), IssuerKeyId: new(uint64(0x38D1A3EADDBEA9C)),
})) }))
assert.Equal(t, "038D1A3EADDBEA9C", tryGetKeyIDFromSignature(&packet.Signature{ assert.Equal(t, "038D1A3EADDBEA9C", tryGetKeyIDFromSignature(&packet.Signature{
IssuerFingerprint: []uint8{0xb, 0x23, 0x24, 0xc7, 0xe6, 0xfe, 0x4f, 0x3a, 0x6, 0x26, 0xc1, 0x21, 0x3, 0x8d, 0x1a, 0x3e, 0xad, 0xdb, 0xea, 0x9c}, IssuerFingerprint: []uint8{0xb, 0x23, 0x24, 0xc7, 0xe6, 0xfe, 0x4f, 0x3a, 0x6, 0x26, 0xc1, 0x21, 0x3, 0x8d, 0x1a, 0x3e, 0xad, 0xdb, 0xea, 0x9c},

View file

@ -89,8 +89,8 @@ var userDataColumnNames = sync.OnceValue(func() []string {
mapper := new(names.GonicMapper) mapper := new(names.GonicMapper)
udType := reflect.TypeFor[UserData]() udType := reflect.TypeFor[UserData]()
columnNames := make([]string, 0, udType.NumField()) columnNames := make([]string, 0, udType.NumField())
for i := 0; i < udType.NumField(); i++ { for field := range udType.Fields() {
columnNames = append(columnNames, mapper.Obj2Table(udType.Field(i).Name)) columnNames = append(columnNames, mapper.Obj2Table(field.Name))
} }
return columnNames return columnNames
}) })

View file

@ -207,5 +207,5 @@ func tryCreateBlameIgnoreRevsFile(commit *Commit) *string {
return nil return nil
} }
return util.ToPointer(f.Name()) return new(f.Name())
} }

View file

@ -253,8 +253,8 @@ func (key ecdsaSigningKey) ToJWK() (map[string]string, error) {
"alg": key.SigningMethod().Alg(), "alg": key.SigningMethod().Alg(),
"kid": key.id, "kid": key.id,
"crv": pubKey.Params().Name, "crv": pubKey.Params().Name,
"x": base64.RawURLEncoding.EncodeToString(pubKey.X.Bytes()), "x": base64.RawURLEncoding.EncodeToString(pubKey.X.Bytes()), //nolint:staticcheck // no easy replacement. JWTX specification mandates marshalling to x, even if unsafe.
"y": base64.RawURLEncoding.EncodeToString(pubKey.Y.Bytes()), "y": base64.RawURLEncoding.EncodeToString(pubKey.Y.Bytes()), //nolint:staticcheck // no easy replacement. JWTX specification mandates marshalling to y, even if unsafe.
}, nil }, nil
} }

View file

@ -215,11 +215,6 @@ func ToFloat64(number any) (float64, error) {
return value, nil return value, nil
} }
// ToPointer returns the pointer of a copy of any given value
func ToPointer[T any](val T) *T {
return &val
}
// Iif is an "inline-if", it returns "trueVal" if "condition" is true, otherwise "falseVal" // Iif is an "inline-if", it returns "trueVal" if "condition" is true, otherwise "falseVal"
func Iif[T any](condition bool, trueVal, falseVal T) T { func Iif[T any](condition bool, trueVal, falseVal T) T {
if condition { if condition {

View file

@ -5,10 +5,10 @@
package util_test package util_test
import ( import (
"bytes"
"crypto/rand" "crypto/rand"
"strings" "strings"
"testing" "testing"
"testing/cryptotest"
"forgejo.org/modules/test" "forgejo.org/modules/test"
"forgejo.org/modules/util" "forgejo.org/modules/util"
@ -211,42 +211,25 @@ func TestToTitleCase(t *testing.T) {
assert.Equal(t, `Foo Bar Baz`, util.ToTitleCase(`FOO BAR BAZ`)) assert.Equal(t, `Foo Bar Baz`, util.ToTitleCase(`FOO BAR BAZ`))
} }
func TestToPointer(t *testing.T) {
assert.Equal(t, "abc", *util.ToPointer("abc"))
assert.Equal(t, 123, *util.ToPointer(123))
abc := "abc"
assert.NotSame(t, &abc, util.ToPointer(abc))
val123 := 123
assert.NotSame(t, &val123, util.ToPointer(val123))
}
func TestReserveLineBreakForTextarea(t *testing.T) { func TestReserveLineBreakForTextarea(t *testing.T) {
assert.Equal(t, "test\ndata", util.ReserveLineBreakForTextarea("test\r\ndata")) assert.Equal(t, "test\ndata", util.ReserveLineBreakForTextarea("test\r\ndata"))
assert.Equal(t, "test\ndata\n", util.ReserveLineBreakForTextarea("test\r\ndata\r\n")) assert.Equal(t, "test\ndata\n", util.ReserveLineBreakForTextarea("test\r\ndata\r\n"))
} }
const ( const (
testPublicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAOhB7/zzhC+HXDdGOdLwJln5NYwm6UNXx3chmQSVTG4\n" testPublicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHX8yEKexoMqBPPwG4pGAhhjo5CyiHLiJZ7p3jg0aJZM\n"
testPrivateKey = `-----BEGIN OPENSSH PRIVATE KEY----- testPrivateKey = `-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtz b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtz
c2gtZWQyNTUxOQAAACADoQe/884Qvh1w3RjnS8CZZ+TWMJulDV8d3IZkElUxuAAA c2gtZWQyNTUxOQAAACB1/MhCnsaDKgTz8BuKRgIYY6OQsohy4iWe6d44NGiWTAAA
AIggISIjICEiIwAAAAtzc2gtZWQyNTUxOQAAACADoQe/884Qvh1w3RjnS8CZZ+TW AIhNLlZvTS5WbwAAAAtzc2gtZWQyNTUxOQAAACB1/MhCnsaDKgTz8BuKRgIYY6OQ
MJulDV8d3IZkElUxuAAAAEAAAQIDBAUGBwgJCgsMDQ4PEBESExQVFhcYGRobHB0e sohy4iWe6d44NGiWTAAAAEDZh37ObTaKrBpvQZ7GJ8drG/sfo3xBoR6kat1qSNiU
HwOhB7/zzhC+HXDdGOdLwJln5NYwm6UNXx3chmQSVTG4AAAAAAECAwQF dHX8yEKexoMqBPPwG4pGAhhjo5CyiHLiJZ7p3jg0aJZMAAAAAAECAwQF
-----END OPENSSH PRIVATE KEY-----` + "\n" -----END OPENSSH PRIVATE KEY-----` + "\n"
) )
func TestGeneratingEd25519Keypair(t *testing.T) { func TestGeneratingEd25519Keypair(t *testing.T) {
defer test.MockProtect(&rand.Reader)() defer test.MockProtect(&rand.Reader)()
cryptotest.SetGlobalRandom(t, 0)
// Only 32 bytes needs to be provided to generate a ed25519 keypair.
// And another 32 bytes are required, which is included as random value
// in the OpenSSH format.
b := make([]byte, 64)
for i := range 64 {
b[i] = byte(i)
}
rand.Reader = bytes.NewReader(b)
publicKey, privateKey, err := util.GenerateSSHKeypair() publicKey, privateKey, err := util.GenerateSSHKeypair()
require.NoError(t, err) require.NoError(t, err)

View file

@ -562,7 +562,7 @@ func (r *artifactV4Routes) downloadArtifact(ctx *ArtifactContext) {
return return
} }
common.ServeContentByReadSeeker(ctx.Base, artifactName, util.ToPointer(artifact.UpdatedUnix.AsTime()), file) common.ServeContentByReadSeeker(ctx.Base, artifactName, new(artifact.UpdatedUnix.AsTime()), file)
} }
func (r *artifactV4Routes) deleteArtifact(ctx *ArtifactContext) { func (r *artifactV4Routes) deleteArtifact(ctx *ArtifactContext) {

View file

@ -103,8 +103,7 @@ func OIDCRoutes(prefix string) *web.Route {
// and inspecting the names of the json struct tags // and inspecting the names of the json struct tags
rt := reflect.TypeFor[actions_service.IDTokenCustomClaims]() rt := reflect.TypeFor[actions_service.IDTokenCustomClaims]()
for i := 0; i < rt.NumField(); i++ { for f := range rt.Fields() {
f := rt.Field(i)
v := strings.Split(f.Tag.Get("json"), ",")[0] v := strings.Split(f.Tag.Get("json"), ",")[0]
if v == "" || v == "-" { if v == "" || v == "-" {
continue continue

View file

@ -13,7 +13,6 @@ import (
"forgejo.org/modules/log" "forgejo.org/modules/log"
"forgejo.org/modules/setting" "forgejo.org/modules/setting"
"forgejo.org/modules/storage" "forgejo.org/modules/storage"
"forgejo.org/modules/util"
"forgejo.org/routers/common" "forgejo.org/routers/common"
"forgejo.org/services/attachment" "forgejo.org/services/attachment"
"forgejo.org/services/context" "forgejo.org/services/context"
@ -154,7 +153,7 @@ func ServeAttachment(ctx *context.Context, uuid string) {
} }
defer fr.Close() defer fr.Close()
common.ServeContentByReadSeeker(ctx.Base, attach.Name, util.ToPointer(attach.CreatedUnix.AsTime()), fr) common.ServeContentByReadSeeker(ctx.Base, attach.Name, new(attach.CreatedUnix.AsTime()), fr)
} }
// GetAttachment serve attachments // GetAttachment serve attachments

View file

@ -15,7 +15,6 @@ import (
"forgejo.org/modules/httplib" "forgejo.org/modules/httplib"
"forgejo.org/modules/setting" "forgejo.org/modules/setting"
"forgejo.org/modules/storage" "forgejo.org/modules/storage"
"forgejo.org/modules/util"
"forgejo.org/services/context" "forgejo.org/services/context"
) )
@ -51,7 +50,7 @@ func serveV4Artifact(base *context.Base, art *actions_model.ActionArtifact) erro
if err != nil { if err != nil {
return err return err
} }
httplib.ServeContentByReadSeeker(base.Req, base.Resp, art.ArtifactName+".zip", util.ToPointer(art.UpdatedUnix.AsTime()), f) httplib.ServeContentByReadSeeker(base.Req, base.Resp, art.ArtifactName+".zip", new(art.UpdatedUnix.AsTime()), f)
return nil return nil
} }

View file

@ -55,12 +55,12 @@ func TestCodebaseDownloadRepo(t *testing.T) {
assertMilestonesEqual(t, []*base.Milestone{ assertMilestonesEqual(t, []*base.Milestone{
{ {
Title: "Milestone1", Title: "Milestone1",
Deadline: timePtr(time.Date(2021, time.September, 16, 0, 0, 0, 0, time.UTC)), Deadline: new(time.Date(2021, time.September, 16, 0, 0, 0, 0, time.UTC)),
}, },
{ {
Title: "Milestone2", Title: "Milestone2",
Deadline: timePtr(time.Date(2021, time.September, 17, 0, 0, 0, 0, time.UTC)), Deadline: new(time.Date(2021, time.September, 17, 0, 0, 0, 0, time.UTC)),
Closed: timePtr(time.Date(2021, time.September, 17, 0, 0, 0, 0, time.UTC)), Closed: new(time.Date(2021, time.September, 17, 0, 0, 0, 0, time.UTC)),
State: "closed", State: "closed",
}, },
}, milestones) }, milestones)

View file

@ -93,16 +93,16 @@ func TestGiteaDownloadRepo(t *testing.T) {
{ {
Title: "V2 Finalize", Title: "V2 Finalize",
Created: time.Unix(0, 0), Created: time.Unix(0, 0),
Deadline: timePtr(time.Unix(1599263999, 0)), Deadline: new(time.Unix(1599263999, 0)),
Updated: timePtr(time.Date(2022, 11, 13, 5, 29, 15, 0, time.UTC)), Updated: new(time.Date(2022, 11, 13, 5, 29, 15, 0, time.UTC)),
State: "open", State: "open",
}, },
{ {
Title: "V1", Title: "V1",
Description: "Generate Content", Description: "Generate Content",
Created: time.Unix(0, 0), Created: time.Unix(0, 0),
Updated: timePtr(time.Unix(0, 0)), Updated: new(time.Unix(0, 0)),
Closed: timePtr(time.Unix(1598985406, 0)), Closed: new(time.Unix(1598985406, 0)),
State: "closed", State: "closed",
}, },
}, milestones) }, milestones)
@ -178,7 +178,7 @@ func TestGiteaDownloadRepo(t *testing.T) {
Content: "laugh", Content: "laugh",
}, },
}, },
Closed: timePtr(time.Date(2020, 9, 1, 15, 49, 34, 0, time.UTC)), Closed: new(time.Date(2020, 9, 1, 15, 49, 34, 0, time.UTC)),
}, },
{ {
Number: 2, Number: 2,
@ -197,7 +197,7 @@ func TestGiteaDownloadRepo(t *testing.T) {
Color: "d4c5f9", Color: "d4c5f9",
Description: "", Description: "",
}}, }},
Closed: timePtr(time.Unix(1598969497, 0)), Closed: new(time.Unix(1598969497, 0)),
}, },
}, issues) }, issues)
@ -244,7 +244,7 @@ func TestGiteaDownloadRepo(t *testing.T) {
IsLocked: false, IsLocked: false,
Created: time.Unix(1598982759, 0), Created: time.Unix(1598982759, 0),
Updated: time.Unix(1599023425, 0), Updated: time.Unix(1599023425, 0),
Closed: timePtr(time.Date(2020, 9, 1, 17, 55, 33, 0, time.UTC)), Closed: new(time.Date(2020, 9, 1, 17, 55, 33, 0, time.UTC)),
Assignees: []string{"techknowlogick"}, Assignees: []string{"techknowlogick"},
Base: base.PullRequestBranch{ Base: base.PullRequestBranch{
CloneURL: "", CloneURL: "",
@ -261,7 +261,7 @@ func TestGiteaDownloadRepo(t *testing.T) {
OwnerName: "6543-forks", OwnerName: "6543-forks",
}, },
Merged: true, Merged: true,
MergedTime: timePtr(time.Unix(1598982934, 0)), MergedTime: new(time.Unix(1598982934, 0)),
MergeCommitSHA: "827aa28a907853e5ddfa40c8f9bc52471a2685fd", MergeCommitSHA: "827aa28a907853e5ddfa40c8f9bc52471a2685fd",
PatchURL: server.URL + "/gitea/test_repo/pulls/12.patch", PatchURL: server.URL + "/gitea/test_repo/pulls/12.patch",
}, prs[1]) }, prs[1])

View file

@ -163,24 +163,24 @@ func TestGitHubDownloadRepo(t *testing.T) {
Title: "1.0.0", Title: "1.0.0",
Description: "Version 1", Description: "Version 1",
Created: time.Date(2025, 8, 7, 12, 48, 56, 0, time.UTC), Created: time.Date(2025, 8, 7, 12, 48, 56, 0, time.UTC),
Updated: timePtr(time.Date(2025, time.August, 12, 12, 34, 20, 0, time.UTC)), Updated: new(time.Date(2025, time.August, 12, 12, 34, 20, 0, time.UTC)),
State: "open", State: "open",
}, },
{ {
Title: "0.9.0", Title: "0.9.0",
Description: "A milestone", Description: "A milestone",
Deadline: timePtr(time.Date(2025, 8, 1, 7, 0, 0, 0, time.UTC)), Deadline: new(time.Date(2025, 8, 1, 7, 0, 0, 0, time.UTC)),
Created: time.Date(2025, 8, 7, 12, 54, 20, 0, time.UTC), Created: time.Date(2025, 8, 7, 12, 54, 20, 0, time.UTC),
Updated: timePtr(time.Date(2025, 8, 12, 11, 29, 52, 0, time.UTC)), Updated: new(time.Date(2025, 8, 12, 11, 29, 52, 0, time.UTC)),
Closed: timePtr(time.Date(2025, 8, 7, 12, 54, 38, 0, time.UTC)), Closed: new(time.Date(2025, 8, 7, 12, 54, 38, 0, time.UTC)),
State: "closed", State: "closed",
}, },
{ {
Title: "1.1.0", Title: "1.1.0",
Description: "We can do that", Description: "We can do that",
Deadline: timePtr(time.Date(2025, 8, 31, 7, 0, 0, 0, time.UTC)), Deadline: new(time.Date(2025, 8, 31, 7, 0, 0, 0, time.UTC)),
Created: time.Date(2025, 8, 7, 12, 50, 58, 0, time.UTC), Created: time.Date(2025, 8, 7, 12, 50, 58, 0, time.UTC),
Updated: timePtr(time.Date(2025, 8, 7, 12, 53, 15, 0, time.UTC)), Updated: new(time.Date(2025, 8, 7, 12, 53, 15, 0, time.UTC)),
State: "open", State: "open",
}, },
}, milestones) }, milestones)
@ -372,8 +372,8 @@ func TestGitHubDownloadRepo(t *testing.T) {
State: "closed", State: "closed",
Created: time.Date(2025, time.August, 7, 13, 1, 36, 0, time.UTC), Created: time.Date(2025, time.August, 7, 13, 1, 36, 0, time.UTC),
Updated: time.Date(2025, time.August, 12, 12, 47, 35, 0, time.UTC), Updated: time.Date(2025, time.August, 12, 12, 47, 35, 0, time.UTC),
Closed: timePtr(time.Date(2025, time.August, 7, 13, 2, 19, 0, time.UTC)), Closed: new(time.Date(2025, time.August, 7, 13, 2, 19, 0, time.UTC)),
MergedTime: timePtr(time.Date(2025, time.August, 7, 13, 2, 19, 0, time.UTC)), MergedTime: new(time.Date(2025, time.August, 7, 13, 2, 19, 0, time.UTC)),
Labels: []*base.Label{ Labels: []*base.Label{
{ {
Name: "bug", Name: "bug",

View file

@ -57,14 +57,14 @@ func TestGitlabDownloadRepo(t *testing.T) {
{ {
Title: "1.0.0", Title: "1.0.0",
Created: time.Date(2024, 9, 3, 13, 53, 8, 516000000, time.UTC), Created: time.Date(2024, 9, 3, 13, 53, 8, 516000000, time.UTC),
Updated: timePtr(time.Date(2024, 9, 3, 20, 3, 57, 786000000, time.UTC)), Updated: new(time.Date(2024, 9, 3, 20, 3, 57, 786000000, time.UTC)),
Closed: timePtr(time.Date(2024, 9, 3, 20, 3, 57, 786000000, time.UTC)), Closed: new(time.Date(2024, 9, 3, 20, 3, 57, 786000000, time.UTC)),
State: "closed", State: "closed",
}, },
{ {
Title: "1.1.0", Title: "1.1.0",
Created: time.Date(2024, 9, 3, 13, 52, 48, 414000000, time.UTC), Created: time.Date(2024, 9, 3, 13, 52, 48, 414000000, time.UTC),
Updated: timePtr(time.Date(2024, 9, 3, 14, 52, 14, 93000000, time.UTC)), Updated: new(time.Date(2024, 9, 3, 14, 52, 14, 93000000, time.UTC)),
State: "active", State: "active",
}, },
}, milestones) }, milestones)
@ -260,7 +260,7 @@ func TestGitlabDownloadRepo(t *testing.T) {
Content: "hearts", Content: "hearts",
}, },
}, },
Closed: timePtr(time.Date(2024, 9, 3, 14, 43, 10, 906000000, time.UTC)), Closed: new(time.Date(2024, 9, 3, 14, 43, 10, 906000000, time.UTC)),
}, },
}, issues) }, issues)
issues, isEnd, err = downloader.GetIssues(2, 3) issues, isEnd, err = downloader.GetIssues(2, 3)
@ -297,7 +297,7 @@ func TestGitlabDownloadRepo(t *testing.T) {
Content: "open_mouth", Content: "open_mouth",
}, },
}, },
Closed: timePtr(time.Date(2024, 9, 3, 14, 43, 10, 708000000, time.UTC)), Closed: new(time.Date(2024, 9, 3, 14, 43, 10, 708000000, time.UTC)),
}, },
}, issues) }, issues)

View file

@ -19,10 +19,6 @@ func TestMain(m *testing.M) {
unittest.MainTest(m) unittest.MainTest(m)
} }
func timePtr(t time.Time) *time.Time {
return &t
}
func assertTimeEqual(t *testing.T, expected, actual time.Time) { func assertTimeEqual(t *testing.T, expected, actual time.Time) {
assert.Equal(t, expected.UTC(), actual.UTC()) assert.Equal(t, expected.UTC(), actual.UTC())
} }

View file

@ -85,7 +85,7 @@ func TestPagureDownloadRepoWithPublicIssues(t *testing.T) {
Milestone: "Milestone BBBB", Milestone: "Milestone BBBB",
Created: time.Date(2023, time.October, 13, 4, 1, 16, 0, time.UTC), Created: time.Date(2023, time.October, 13, 4, 1, 16, 0, time.UTC),
Updated: time.Date(2025, time.June, 25, 6, 25, 57, 0, time.UTC), Updated: time.Date(2025, time.June, 25, 6, 25, 57, 0, time.UTC),
Closed: timePtr(time.Date(2025, time.June, 25, 6, 22, 59, 0, time.UTC)), Closed: new(time.Date(2025, time.June, 25, 6, 22, 59, 0, time.UTC)),
Labels: []*base.Label{ Labels: []*base.Label{
{ {
Name: "cccc", Name: "cccc",
@ -111,7 +111,7 @@ func TestPagureDownloadRepoWithPublicIssues(t *testing.T) {
Milestone: "Milestone AAAA", Milestone: "Milestone AAAA",
Created: time.Date(2023, time.October, 13, 3, 57, 42, 0, time.UTC), Created: time.Date(2023, time.October, 13, 3, 57, 42, 0, time.UTC),
Updated: time.Date(2025, time.June, 25, 6, 25, 45, 0, time.UTC), Updated: time.Date(2025, time.June, 25, 6, 25, 45, 0, time.UTC),
Closed: timePtr(time.Date(1, time.January, 1, 0, 0, 0, 0, time.UTC)), Closed: new(time.Date(1, time.January, 1, 0, 0, 0, 0, time.UTC)),
Labels: []*base.Label{ Labels: []*base.Label{
{ {
Name: "aaaa", Name: "aaaa",
@ -219,8 +219,8 @@ func TestPagureDownloadRepoWithPublicIssues(t *testing.T) {
State: "closed", State: "closed",
Created: time.Date(2025, time.May, 19, 6, 12, 45, 0, time.UTC), Created: time.Date(2025, time.May, 19, 6, 12, 45, 0, time.UTC),
Updated: time.Date(2025, time.May, 19, 6, 17, 11, 0, time.UTC), Updated: time.Date(2025, time.May, 19, 6, 17, 11, 0, time.UTC),
Closed: timePtr(time.Date(2025, time.May, 19, 6, 17, 11, 0, time.UTC)), Closed: new(time.Date(2025, time.May, 19, 6, 17, 11, 0, time.UTC)),
MergedTime: timePtr(time.Date(2025, time.May, 19, 6, 17, 11, 0, time.UTC)), MergedTime: new(time.Date(2025, time.May, 19, 6, 17, 11, 0, time.UTC)),
Merged: true, Merged: true,
PatchURL: server.URL + "/protop2g-test-srce/pull-request/10.patch", PatchURL: server.URL + "/protop2g-test-srce/pull-request/10.patch",
Labels: []*base.Label{ Labels: []*base.Label{
@ -249,8 +249,8 @@ func TestPagureDownloadRepoWithPublicIssues(t *testing.T) {
State: "closed", State: "closed",
Created: time.Date(2025, time.May, 19, 6, 12, 41, 0, time.UTC), Created: time.Date(2025, time.May, 19, 6, 12, 41, 0, time.UTC),
Updated: time.Date(2025, time.May, 19, 6, 14, 3, 0, time.UTC), Updated: time.Date(2025, time.May, 19, 6, 14, 3, 0, time.UTC),
Closed: timePtr(time.Date(2025, time.May, 19, 6, 14, 3, 0, time.UTC)), Closed: new(time.Date(2025, time.May, 19, 6, 14, 3, 0, time.UTC)),
MergedTime: timePtr(time.Date(2025, time.May, 19, 6, 14, 3, 0, time.UTC)), MergedTime: new(time.Date(2025, time.May, 19, 6, 14, 3, 0, time.UTC)),
Merged: true, Merged: true,
PatchURL: server.URL + "/protop2g-test-srce/pull-request/9.patch", PatchURL: server.URL + "/protop2g-test-srce/pull-request/9.patch",
Labels: []*base.Label{ Labels: []*base.Label{
@ -279,8 +279,8 @@ func TestPagureDownloadRepoWithPublicIssues(t *testing.T) {
State: "closed", State: "closed",
Created: time.Date(2025, time.May, 5, 6, 45, 32, 0, time.UTC), Created: time.Date(2025, time.May, 5, 6, 45, 32, 0, time.UTC),
Updated: time.Date(2025, time.May, 5, 6, 54, 13, 0, time.UTC), Updated: time.Date(2025, time.May, 5, 6, 54, 13, 0, time.UTC),
Closed: timePtr(time.Date(2025, time.May, 5, 6, 54, 13, 0, time.UTC)), Closed: new(time.Date(2025, time.May, 5, 6, 54, 13, 0, time.UTC)),
MergedTime: timePtr(time.Date(2025, time.May, 5, 6, 54, 13, 0, time.UTC)), // THIS IS WRONG MergedTime: new(time.Date(2025, time.May, 5, 6, 54, 13, 0, time.UTC)), // THIS IS WRONG
Merged: false, Merged: false,
PatchURL: server.URL + "/protop2g-test-srce/pull-request/8.patch", PatchURL: server.URL + "/protop2g-test-srce/pull-request/8.patch",
Labels: []*base.Label{ Labels: []*base.Label{
@ -309,8 +309,8 @@ func TestPagureDownloadRepoWithPublicIssues(t *testing.T) {
State: "closed", State: "closed",
Created: time.Date(2025, time.May, 5, 6, 45, 6, 0, time.UTC), Created: time.Date(2025, time.May, 5, 6, 45, 6, 0, time.UTC),
Updated: time.Date(2025, time.May, 5, 6, 54, 3, 0, time.UTC), // IT SHOULD BE NIL Updated: time.Date(2025, time.May, 5, 6, 54, 3, 0, time.UTC), // IT SHOULD BE NIL
Closed: timePtr(time.Date(2025, time.May, 5, 6, 54, 3, 0, time.UTC)), // IT is CLOSED, Not MERGED so SHOULD NOT BE NIL Closed: new(time.Date(2025, time.May, 5, 6, 54, 3, 0, time.UTC)), // IT is CLOSED, Not MERGED so SHOULD NOT BE NIL
MergedTime: timePtr(time.Date(2025, time.May, 5, 6, 54, 3, 0, time.UTC)), // THIS IS WRONG MergedTime: new(time.Date(2025, time.May, 5, 6, 54, 3, 0, time.UTC)), // THIS IS WRONG
Merged: false, Merged: false,
PatchURL: server.URL + "/protop2g-test-srce/pull-request/7.patch", PatchURL: server.URL + "/protop2g-test-srce/pull-request/7.patch",
Labels: []*base.Label{ Labels: []*base.Label{
@ -339,8 +339,8 @@ func TestPagureDownloadRepoWithPublicIssues(t *testing.T) {
State: "open", State: "open",
Created: time.Date(2025, time.May, 5, 6, 44, 30, 0, time.UTC), Created: time.Date(2025, time.May, 5, 6, 44, 30, 0, time.UTC),
Updated: time.Date(2025, time.May, 19, 8, 30, 50, 0, time.UTC), Updated: time.Date(2025, time.May, 19, 8, 30, 50, 0, time.UTC),
Closed: timePtr(time.Date(1, time.January, 1, 0, 0, 0, 0, time.UTC)), Closed: new(time.Date(1, time.January, 1, 0, 0, 0, 0, time.UTC)),
MergedTime: timePtr(time.Date(1, time.January, 1, 0, 0, 0, 0, time.UTC)), MergedTime: new(time.Date(1, time.January, 1, 0, 0, 0, 0, time.UTC)),
Merged: false, Merged: false,
PatchURL: server.URL + "/protop2g-test-srce/pull-request/6.patch", PatchURL: server.URL + "/protop2g-test-srce/pull-request/6.patch",
Labels: []*base.Label{ Labels: []*base.Label{
@ -369,8 +369,8 @@ func TestPagureDownloadRepoWithPublicIssues(t *testing.T) {
State: "open", State: "open",
Created: time.Date(2025, time.May, 5, 6, 43, 57, 0, time.UTC), Created: time.Date(2025, time.May, 5, 6, 43, 57, 0, time.UTC),
Updated: time.Date(2025, time.May, 19, 6, 29, 45, 0, time.UTC), Updated: time.Date(2025, time.May, 19, 6, 29, 45, 0, time.UTC),
Closed: timePtr(time.Date(1, time.January, 1, 0, 0, 0, 0, time.UTC)), Closed: new(time.Date(1, time.January, 1, 0, 0, 0, 0, time.UTC)),
MergedTime: timePtr(time.Date(1, time.January, 1, 0, 0, 0, 0, time.UTC)), MergedTime: new(time.Date(1, time.January, 1, 0, 0, 0, 0, time.UTC)),
Merged: false, Merged: false,
PatchURL: server.URL + "/protop2g-test-srce/pull-request/5.patch", PatchURL: server.URL + "/protop2g-test-srce/pull-request/5.patch",
Labels: []*base.Label{ Labels: []*base.Label{
@ -428,22 +428,22 @@ func TestPagureDownloadRepoWithPublicIssues(t *testing.T) {
dict := map[string]*base.Milestone{ dict := map[string]*base.Milestone{
"Milestone AAAA": { "Milestone AAAA": {
Title: "Milestone AAAA", Title: "Milestone AAAA",
Deadline: timePtr(time.Date(2025, time.December, 12, 0, 0, 0, 0, time.UTC)), Deadline: new(time.Date(2025, time.December, 12, 0, 0, 0, 0, time.UTC)),
State: "open", State: "open",
}, },
"Milestone BBBB": { "Milestone BBBB": {
Title: "Milestone BBBB", Title: "Milestone BBBB",
Deadline: timePtr(time.Date(2025, time.December, 12, 0, 0, 0, 0, time.UTC)), Deadline: new(time.Date(2025, time.December, 12, 0, 0, 0, 0, time.UTC)),
State: "closed", State: "closed",
}, },
"Milestone CCCC": { "Milestone CCCC": {
Title: "Milestone CCCC", Title: "Milestone CCCC",
Deadline: timePtr(time.Date(2025, time.December, 12, 0, 0, 0, 0, time.UTC)), Deadline: new(time.Date(2025, time.December, 12, 0, 0, 0, 0, time.UTC)),
State: "open", State: "open",
}, },
"Milestone DDDD": { "Milestone DDDD": {
Title: "Milestone DDDD", Title: "Milestone DDDD",
Deadline: timePtr(time.Date(2025, time.December, 12, 0, 0, 0, 0, time.UTC)), Deadline: new(time.Date(2025, time.December, 12, 0, 0, 0, 0, time.UTC)),
State: "closed", State: "closed",
}, },
} }
@ -524,7 +524,7 @@ func TestPagureDownloadRepoWithPrivateIssues(t *testing.T) {
Milestone: "Milestone DDDD", Milestone: "Milestone DDDD",
Created: time.Date(2023, time.November, 21, 8, 6, 56, 0, time.UTC), Created: time.Date(2023, time.November, 21, 8, 6, 56, 0, time.UTC),
Updated: time.Date(2025, time.June, 25, 6, 26, 26, 0, time.UTC), Updated: time.Date(2025, time.June, 25, 6, 26, 26, 0, time.UTC),
Closed: timePtr(time.Date(2025, time.June, 25, 6, 23, 51, 0, time.UTC)), Closed: new(time.Date(2025, time.June, 25, 6, 23, 51, 0, time.UTC)),
Labels: []*base.Label{ Labels: []*base.Label{
{ {
Name: "gggg", Name: "gggg",
@ -550,7 +550,7 @@ func TestPagureDownloadRepoWithPrivateIssues(t *testing.T) {
Milestone: "Milestone CCCC", Milestone: "Milestone CCCC",
Created: time.Date(2023, time.November, 21, 8, 3, 57, 0, time.UTC), Created: time.Date(2023, time.November, 21, 8, 3, 57, 0, time.UTC),
Updated: time.Date(2025, time.June, 25, 6, 26, 7, 0, time.UTC), Updated: time.Date(2025, time.June, 25, 6, 26, 7, 0, time.UTC),
Closed: timePtr(time.Date(1, time.January, 1, 0, 0, 0, 0, time.UTC)), Closed: new(time.Date(1, time.January, 1, 0, 0, 0, 0, time.UTC)),
Labels: []*base.Label{ Labels: []*base.Label{
{ {
Name: "eeee", Name: "eeee",
@ -649,17 +649,17 @@ func TestProcessDate(t *testing.T) {
}, },
{ {
name: "empty string", name: "empty string",
input: strPtr(""), input: new(""),
expected: time.Time{}, expected: time.Time{},
}, },
{ {
name: "unix timestamp", name: "unix timestamp",
input: strPtr("1609459200"), input: new("1609459200"),
expected: time.Unix(1609459200, 0), expected: time.Unix(1609459200, 0),
}, },
{ {
name: "YYYY-MM-DD format", name: "YYYY-MM-DD format",
input: strPtr("2025-12-12"), input: new("2025-12-12"),
expected: time.Date(2025, time.December, 12, 0, 0, 0, 0, time.UTC), expected: time.Date(2025, time.December, 12, 0, 0, 0, 0, time.UTC),
}, },
} }
@ -671,7 +671,3 @@ func TestProcessDate(t *testing.T) {
}) })
} }
} }
func strPtr(s string) *string {
return &s
}