diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 7dfe9552..4c3d8bde 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -19,7 +19,7 @@ jobs: - name: "setup go" uses: "actions/setup-go@v3" with: - go-version: "1.20" + go-version: "1.21" - name: "install python3-pytest" run: "sudo apt install -y python3-pytest" - name: "make install" diff --git a/Dockerfile b/Dockerfile index 06cc93f1..5eaec3ec 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ ## build ergo binary -FROM golang:1.20-alpine AS build-env +FROM golang:1.21-alpine AS build-env RUN apk upgrade -U --force-refresh --no-cache && apk add --no-cache --purge --clean-protected -l -u make git diff --git a/go.mod b/go.mod index 73fedb42..90422a6a 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/ergochat/ergo -go 1.20 +go 1.21 require ( code.cloudfoundry.org/bytefmt v0.0.0-20200131002437-cf55d5288a48 diff --git a/irc/channel.go b/irc/channel.go index 4680958c..4dc5bccb 100644 --- a/irc/channel.go +++ b/irc/channel.go @@ -7,6 +7,7 @@ package irc import ( "fmt" + "maps" "strconv" "strings" "time" @@ -158,7 +159,7 @@ func (channel *Channel) ExportRegistration() (info RegisteredChannel) { info.Bans = channel.lists[modes.BanMask].Masks() info.Invites = channel.lists[modes.InviteMask].Masks() info.Excepts = channel.lists[modes.ExceptMask].Masks() - info.AccountToUMode = utils.CopyMap(channel.accountToUMode) + info.AccountToUMode = maps.Clone(channel.accountToUMode) info.Settings = channel.settings diff --git a/irc/chanserv.go b/irc/chanserv.go index 6e8389ab..a8360c03 100644 --- a/irc/chanserv.go +++ b/irc/chanserv.go @@ -6,6 +6,7 @@ package irc import ( "fmt" "regexp" + "slices" "sort" "strings" "time" @@ -218,7 +219,7 @@ func csAmodeHandler(service *ircService, server *Server, client *Client, command // check for anything valid as a channel mode change that is not valid // as an AMODE change for _, modeChange := range modeChanges { - if !utils.SliceContains(modes.ChannelUserModes, modeChange.Mode) { + if !slices.Contains(modes.ChannelUserModes, modeChange.Mode) { invalid = true } } diff --git a/irc/client.go b/irc/client.go index 237b5aad..80a60a23 100644 --- a/irc/client.go +++ b/irc/client.go @@ -8,6 +8,7 @@ package irc import ( "crypto/x509" "fmt" + "maps" "net" "runtime/debug" "strconv" @@ -1743,7 +1744,7 @@ func (client *Client) handleRegisterTimeout() { func (client *Client) copyLastSeen() (result map[string]time.Time) { client.stateMutex.RLock() defer client.stateMutex.RUnlock() - return utils.CopyMap(client.lastSeen) + return maps.Clone(client.lastSeen) } // these are bit flags indicating what part of the client status is "dirty" diff --git a/irc/fakelag.go b/irc/fakelag.go index 25ef0609..4a533981 100644 --- a/irc/fakelag.go +++ b/irc/fakelag.go @@ -4,9 +4,8 @@ package irc import ( + "maps" "time" - - "github.com/ergochat/ergo/irc/utils" ) // fakelag is a system for artificially delaying commands when a user issues @@ -40,7 +39,7 @@ func (fl *Fakelag) Initialize(config FakelagConfig) { fl.config = config // XXX don't share mutable member CommandBudgets: if config.CommandBudgets != nil { - fl.config.CommandBudgets = utils.CopyMap(config.CommandBudgets) + fl.config.CommandBudgets = maps.Clone(config.CommandBudgets) } fl.nowFunc = time.Now fl.sleepFunc = time.Sleep diff --git a/irc/getters.go b/irc/getters.go index 19b162f4..baf86cc6 100644 --- a/irc/getters.go +++ b/irc/getters.go @@ -5,6 +5,7 @@ package irc import ( "fmt" + "maps" "net" "time" @@ -515,7 +516,7 @@ func (client *Client) GetReadMarker(cfname string) (result string) { func (client *Client) copyReadMarkers() (result map[string]time.Time) { client.stateMutex.RLock() defer client.stateMutex.RUnlock() - return utils.CopyMap(client.readMarkers) + return maps.Clone(client.readMarkers) } func (client *Client) SetReadMarker(cfname string, now time.Time) (result time.Time) { diff --git a/irc/history/history.go b/irc/history/history.go index 75d6298d..ef7e4d9f 100644 --- a/irc/history/history.go +++ b/irc/history/history.go @@ -4,6 +4,7 @@ package history import ( + "slices" "sync" "time" @@ -155,7 +156,7 @@ func (list *Buffer) betweenHelper(start, end Selector, cutoff time.Time, pred Pr defer func() { if !ascending { - utils.ReverseSlice(results) + slices.Reverse(results) } }() @@ -262,7 +263,7 @@ func (list *Buffer) listCorrespondents(start, end Selector, cutoff time.Time, li } if !ascending { - utils.ReverseSlice(results) + slices.Reverse(results) } return diff --git a/irc/history/targets.go b/irc/history/targets.go index 39a8c635..d2fdf67c 100644 --- a/irc/history/targets.go +++ b/irc/history/targets.go @@ -4,10 +4,9 @@ package history import ( + "slices" "sort" "time" - - "github.com/ergochat/ergo/irc/utils" ) type TargetListing struct { @@ -35,8 +34,8 @@ func MergeTargets(base []TargetListing, extra []TargetListing, start, end time.T results = make([]TargetListing, 0, prealloc) if !ascending { - utils.ReverseSlice(base) - utils.ReverseSlice(extra) + slices.Reverse(base) + slices.Reverse(extra) } for len(results) < limit { @@ -66,7 +65,7 @@ func MergeTargets(base []TargetListing, extra []TargetListing, start, end time.T } if !ascending { - utils.ReverseSlice(results) + slices.Reverse(results) } return } diff --git a/irc/mysql/history.go b/irc/mysql/history.go index 4cb985f4..4b967104 100644 --- a/irc/mysql/history.go +++ b/irc/mysql/history.go @@ -11,6 +11,7 @@ import ( "fmt" "io" "runtime/debug" + "slices" "strings" "sync" "sync/atomic" @@ -917,7 +918,7 @@ func (mysql *MySQL) betweenTimestamps(ctx context.Context, target, correspondent results, err = mysql.selectItems(ctx, queryBuf.String(), args...) if err == nil && !ascending { - utils.ReverseSlice(results) + slices.Reverse(results) } return } @@ -965,7 +966,7 @@ func (mysql *MySQL) listCorrespondentsInternal(ctx context.Context, target strin } if !ascending { - utils.ReverseSlice(results) + slices.Reverse(results) } return diff --git a/irc/utils/types.go b/irc/utils/types.go index 8c2ca4eb..8d136f34 100644 --- a/irc/utils/types.go +++ b/irc/utils/types.go @@ -27,27 +27,3 @@ func SetLiteral[T comparable](elems ...T) HashSet[T] { } return result } - -func CopyMap[K comparable, V any](input map[K]V) (result map[K]V) { - result = make(map[K]V, len(input)) - for key, value := range input { - result[key] = value - } - return -} - -// reverse the order of a slice in place -func ReverseSlice[T any](results []T) { - for i, j := 0, len(results)-1; i < j; i, j = i+1, j-1 { - results[i], results[j] = results[j], results[i] - } -} - -func SliceContains[T comparable](slice []T, elem T) (result bool) { - for _, t := range slice { - if elem == t { - return true - } - } - return false -}