import (
"context"
"fmt"
+ "slices"
"strings"
"time"
// It's impossible that the run is not found, since Gitea never deletes runs.
}
- if run.Status != 0 || util.SliceContains(cols, "status") {
+ if run.Status != 0 || slices.Contains(cols, "status") {
if run.RepoID == 0 {
run, err = GetRunByID(ctx, run.ID)
if err != nil {
import (
"context"
"fmt"
+ "slices"
"time"
"code.gitea.io/gitea/models/db"
return 0, err
}
- if affected == 0 || (!util.SliceContains(cols, "status") && job.Status == 0) {
+ if affected == 0 || (!slices.Contains(cols, "status") && job.Status == 0) {
return affected, nil
}
- if affected != 0 && util.SliceContains(cols, "status") && job.Status.IsWaiting() {
+ if affected != 0 && slices.Contains(cols, "status") && job.Status.IsWaiting() {
// if the status of job changes to waiting again, increase tasks version.
if err := IncreaseTaskVersion(ctx, job.OwnerID, job.RepoID); err != nil {
return 0, err
"context"
"errors"
"fmt"
+ "slices"
"strings"
"code.gitea.io/gitea/models/db"
whitelist = make([]int64, 0, len(teams))
for i := range teams {
- if util.SliceContains(newWhitelist, teams[i].ID) {
+ if slices.Contains(newWhitelist, teams[i].ID) {
whitelist = append(whitelist, teams[i].ID)
}
}
"context"
"fmt"
"regexp"
+ "slices"
"code.gitea.io/gitea/models/db"
project_model "code.gitea.io/gitea/models/project"
log.Error(err.Error())
return false
}
- return util.SliceContains(userIDs, user.ID)
+ return slices.Contains(userIDs, user.ID)
}
// DependencyInfo represents high level information about an issue which is a dependency of another issue.
Find(&userIDs); err != nil {
return nil, fmt.Errorf("get poster IDs: %w", err)
}
- if !util.SliceContains(userIDs, issue.PosterID) {
+ if !slices.Contains(userIDs, issue.PosterID) {
return append(userIDs, issue.PosterID), nil
}
return userIDs, nil
import (
"context"
"fmt"
+ "slices"
"strings"
"code.gitea.io/gitea/models/db"
}
func (cfg *ActionsConfig) IsWorkflowDisabled(file string) bool {
- return util.SliceContains(cfg.DisabledWorkflows, file)
+ return slices.Contains(cfg.DisabledWorkflows, file)
}
func (cfg *ActionsConfig) DisableWorkflow(file string) {
"context"
"os"
"runtime/pprof"
+ "slices"
"sync/atomic"
"time"
"code.gitea.io/gitea/modules/process"
"code.gitea.io/gitea/modules/queue"
"code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/util"
)
var (
}
// skip forks from being indexed if unit is not present
- if !util.SliceContains(repoTypes, "forks") && repo.IsFork {
+ if !slices.Contains(repoTypes, "forks") && repo.IsFork {
return nil
}
// skip mirrors from being indexed if unit is not present
- if !util.SliceContains(repoTypes, "mirrors") && repo.IsMirror {
+ if !slices.Contains(repoTypes, "mirrors") && repo.IsMirror {
return nil
}
// skip templates from being indexed if unit is not present
- if !util.SliceContains(repoTypes, "templates") && repo.IsTemplate {
+ if !slices.Contains(repoTypes, "templates") && repo.IsTemplate {
return nil
}
// skip regular repos from being indexed if unit is not present
- if !util.SliceContains(repoTypes, "sources") && !repo.IsFork && !repo.IsMirror && !repo.IsTemplate {
+ if !slices.Contains(repoTypes, "sources") && !repo.IsFork && !repo.IsMirror && !repo.IsTemplate {
return nil
}
import (
"context"
"fmt"
+ "slices"
"testing"
"time"
assert.Contains(t, data[v.ID].MentionIDs, int64(1))
}
assert.Equal(t, countIndexerData(data, func(v *internal.IndexerData) bool {
- return util.SliceContains(v.MentionIDs, 1)
+ return slices.Contains(v.MentionIDs, 1)
}), result.Total)
},
},
assert.Contains(t, data[v.ID].ReviewedIDs, int64(1))
}
assert.Equal(t, countIndexerData(data, func(v *internal.IndexerData) bool {
- return util.SliceContains(v.ReviewedIDs, 1)
+ return slices.Contains(v.ReviewedIDs, 1)
}), result.Total)
},
},
assert.Contains(t, data[v.ID].ReviewRequestedIDs, int64(1))
}
assert.Equal(t, countIndexerData(data, func(v *internal.IndexerData) bool {
- return util.SliceContains(v.ReviewRequestedIDs, 1)
+ return slices.Contains(v.ReviewRequestedIDs, 1)
}), result.Total)
},
},
assert.Contains(t, data[v.ID].SubscriberIDs, int64(1))
}
assert.Equal(t, countIndexerData(data, func(v *internal.IndexerData) bool {
- return util.SliceContains(v.SubscriberIDs, 1)
+ return slices.Contains(v.SubscriberIDs, 1)
}), result.Total)
},
},
package templates
import (
+ "slices"
"strings"
"code.gitea.io/gitea/modules/assetfs"
"code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/util"
)
func AssetFS() *assetfs.LayeredFS {
if err != nil {
return nil, err
}
- return util.SliceRemoveAllFunc(files, func(file string) bool {
+ return slices.DeleteFunc(files, func(file string) bool {
return strings.HasPrefix(file, "mail/") || !strings.HasSuffix(file, ".tmpl")
}), nil
}
if err != nil {
return nil, err
}
- return util.SliceRemoveAllFunc(files, func(file string) bool {
+ return slices.DeleteFunc(files, func(file string) bool {
return !strings.HasPrefix(file, "mail/") || !strings.HasSuffix(file, ".tmpl")
}), nil
}
// Copyright 2022 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-// Most of the functions in this file can have better implementations with "golang.org/x/exp/slices".
-// However, "golang.org/x/exp" is experimental and unreliable, we shouldn't use it.
-// So lets waiting for the "slices" has be promoted to the main repository one day.
-
package util
-import "strings"
-
-// SliceContains returns true if the target exists in the slice.
-func SliceContains[T comparable](slice []T, target T) bool {
- return SliceContainsFunc(slice, func(t T) bool { return t == target })
-}
-
-// SliceContainsFunc returns true if any element in the slice satisfies the targetFunc.
-func SliceContainsFunc[T any](slice []T, targetFunc func(T) bool) bool {
- for _, v := range slice {
- if targetFunc(v) {
- return true
- }
- }
- return false
-}
+import (
+ "slices"
+ "strings"
+)
// SliceContainsString sequential searches if string exists in slice.
func SliceContainsString(slice []string, target string, insensitive ...bool) bool {
if len(insensitive) != 0 && insensitive[0] {
target = strings.ToLower(target)
- return SliceContainsFunc(slice, func(t string) bool { return strings.ToLower(t) == target })
+ return slices.ContainsFunc(slice, func(t string) bool { return strings.ToLower(t) == target })
}
- return SliceContains(slice, target)
+ return slices.Contains(slice, target)
}
// SliceSortedEqual returns true if the two slices will be equal when they get sorted.
return true
}
-// SliceEqual returns true if the two slices are equal.
-func SliceEqual[T comparable](s1, s2 []T) bool {
- if len(s1) != len(s2) {
- return false
- }
-
- for i, v := range s1 {
- if s2[i] != v {
- return false
- }
- }
- return true
-}
-
// SliceRemoveAll removes all the target elements from the slice.
func SliceRemoveAll[T comparable](slice []T, target T) []T {
- return SliceRemoveAllFunc(slice, func(t T) bool { return t == target })
-}
-
-// SliceRemoveAllFunc removes all elements which satisfy the targetFunc from the slice.
-func SliceRemoveAllFunc[T comparable](slice []T, targetFunc func(T) bool) []T {
- idx := 0
- for _, v := range slice {
- if targetFunc(v) {
- continue
- }
- slice[idx] = v
- idx++
- }
- return slice[:idx]
+ return slices.DeleteFunc(slice, func(t T) bool { return t == target })
}
"github.com/stretchr/testify/assert"
)
-func TestSliceContains(t *testing.T) {
- assert.True(t, SliceContains([]int{2, 0, 2, 3}, 2))
- assert.True(t, SliceContains([]int{2, 0, 2, 3}, 0))
- assert.True(t, SliceContains([]int{2, 0, 2, 3}, 3))
-
- assert.True(t, SliceContains([]string{"2", "0", "2", "3"}, "0"))
- assert.True(t, SliceContains([]float64{2, 0, 2, 3}, 0))
- assert.True(t, SliceContains([]bool{false, true, false}, true))
-
- assert.False(t, SliceContains([]int{2, 0, 2, 3}, 4))
- assert.False(t, SliceContains([]int{}, 4))
- assert.False(t, SliceContains(nil, 4))
-}
-
func TestSliceContainsString(t *testing.T) {
assert.True(t, SliceContainsString([]string{"c", "b", "a", "b"}, "a"))
assert.True(t, SliceContainsString([]string{"c", "b", "a", "b"}, "b"))
assert.False(t, SliceSortedEqual([]int{2, 0, 0, 3}, []int{2, 0, 2, 3}))
}
-func TestSliceEqual(t *testing.T) {
- assert.True(t, SliceEqual([]int{2, 0, 2, 3}, []int{2, 0, 2, 3}))
- assert.True(t, SliceEqual([]int{}, []int{}))
- assert.True(t, SliceEqual([]int(nil), nil))
- assert.True(t, SliceEqual([]int(nil), []int{}))
- assert.True(t, SliceEqual([]int{}, []int{}))
-
- assert.True(t, SliceEqual([]string{"2", "0", "2", "3"}, []string{"2", "0", "2", "3"}))
- assert.True(t, SliceEqual([]float64{2, 0, 2, 3}, []float64{2, 0, 2, 3}))
- assert.True(t, SliceEqual([]bool{false, true, false}, []bool{false, true, false}))
-
- assert.False(t, SliceEqual([]int{3, 0, 2, 2}, []int{2, 0, 2, 3}))
- assert.False(t, SliceEqual([]int{2, 0, 2}, []int{2, 0, 2, 3}))
- assert.False(t, SliceEqual([]int{}, []int{2, 0, 2, 3}))
- assert.False(t, SliceEqual(nil, []int{2, 0, 2, 3}))
- assert.False(t, SliceEqual([]int{2, 0, 2, 4}, []int{2, 0, 2, 3}))
- assert.False(t, SliceEqual([]int{2, 0, 0, 3}, []int{2, 0, 2, 3}))
-}
-
func TestSliceRemoveAll(t *testing.T) {
assert.ElementsMatch(t, []int{2, 2, 3}, SliceRemoveAll([]int{2, 0, 2, 3}, 0))
assert.ElementsMatch(t, []int{0, 3}, SliceRemoveAll([]int{2, 0, 2, 3}, 2))
"net/http"
"path"
"regexp"
+ "slices"
"strconv"
"strings"
"time"
}
}
- if !util.SliceEqual(out[skip:], data) {
+ if !slices.Equal(out[skip:], data) {
return fmt.Errorf("could not verify signature")
}
import (
"fmt"
"net/http"
+ "slices"
"strings"
"time"
}
// If the readme template does not exist, a 400 will be returned.
- if opt.AutoInit && len(opt.Readme) > 0 && !util.SliceContains(repo_module.Readmes, opt.Readme) {
+ if opt.AutoInit && len(opt.Readme) > 0 && !slices.Contains(repo_module.Readmes, opt.Readme) {
ctx.Error(http.StatusBadRequest, "", fmt.Errorf("readme template does not exist, available templates: %v", repo_module.Readmes))
return
}
"math/big"
"net/http"
"net/url"
+ "slices"
"sort"
"strconv"
"strings"
if search == "" && ctx.Doer != nil {
// the returned posters slice only contains limited number of users,
// to make the current user (doer) can quickly filter their own issues, always add doer to the posters slice
- if !util.SliceContainsFunc(posters, func(user *user_model.User) bool { return user.ID == ctx.Doer.ID }) {
+ if !slices.ContainsFunc(posters, func(user *user_model.User) bool { return user.ID == ctx.Doer.ID }) {
posters = append(posters, ctx.Doer)
}
}
"errors"
"fmt"
"net/http"
+ "slices"
"strings"
"code.gitea.io/gitea/models"
}
resp := &branchTagSearchResponse{}
// always put default branch on the top if it exists
- if util.SliceContains(branches, ctx.Repo.Repository.DefaultBranch) {
+ if slices.Contains(branches, ctx.Repo.Repository.DefaultBranch) {
branches = util.SliceRemoveAll(branches, ctx.Repo.Repository.DefaultBranch)
branches = append([]string{ctx.Repo.Repository.DefaultBranch}, branches...)
}
return
}
// always put default branch on the top if it exists
- if util.SliceContains(brs, ctx.Repo.Repository.DefaultBranch) {
+ if slices.Contains(brs, ctx.Repo.Repository.DefaultBranch) {
brs = util.SliceRemoveAll(brs, ctx.Repo.Repository.DefaultBranch)
brs = append([]string{ctx.Repo.Repository.DefaultBranch}, brs...)
}
"net/http"
"net/url"
"path"
+ "slices"
"strings"
"time"
if workFlowErr != nil {
ctx.Data["FileError"] = ctx.Locale.Tr("actions.runs.invalid_workflow_helper", workFlowErr.Error())
}
- } else if util.SliceContains([]string{"CODEOWNERS", "docs/CODEOWNERS", ".gitea/CODEOWNERS"}, ctx.Repo.TreePath) {
+ } else if slices.Contains([]string{"CODEOWNERS", "docs/CODEOWNERS", ".gitea/CODEOWNERS"}, ctx.Repo.TreePath) {
if data, err := blob.GetBlobContent(setting.UI.MaxDisplayFileSize); err == nil {
_, warnings := issue_model.GetCodeOwnersFromContent(ctx, data)
if len(warnings) > 0 {
"fmt"
"net/http"
"regexp"
+ "slices"
"sort"
"strconv"
"strings"
if len(repoIDs) == 0 {
repoIDs = showRepoIds.Values()
}
- repoIDs = util.SliceRemoveAllFunc(repoIDs, func(v int64) bool {
+ repoIDs = slices.DeleteFunc(repoIDs, func(v int64) bool {
return !showRepoIds.Contains(v)
})
// Gets set when clicking filters on the issues overview page.
selectedRepoIDs := getRepoIDs(ctx.FormString("repos"))
// Remove repo IDs that are not accessible to the user.
- selectedRepoIDs = util.SliceRemoveAllFunc(selectedRepoIDs, func(v int64) bool {
+ selectedRepoIDs = slices.DeleteFunc(selectedRepoIDs, func(v int64) bool {
return !accessibleRepos.Contains(v)
})
if len(selectedRepoIDs) > 0 {